From 6fc2e4a32e9da29bdf4e4b0fbc1616836d31db6a Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Tue, 23 Apr 2019 15:34:01 -0700 Subject: [PATCH] Add custom baseline format for smart selection --- src/harness/fourslash.ts | 52 +++++++++++++++++++++++++----- tests/cases/fourslash/fourslash.ts | 3 +- 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 9e117cdfd8f..b562f908a6c 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -1417,12 +1417,7 @@ Actual: ${stringify(fullActual)}`); } public baselineCurrentFileBreakpointLocations() { - let baselineFile = this.testData.globalOptions[MetadataOptionNames.baselineFile]; - if (!baselineFile) { - baselineFile = this.activeFile.fileName.replace(this.basePath + "/breakpointValidation", "bpSpan"); - baselineFile = baselineFile.replace(ts.Extension.Ts, ".baseline"); - - } + const baselineFile = this.getBaselineFileName().replace(this.basePath + "/breakpointValidation", "bpSpan"); Harness.Baseline.runBaseline(baselineFile, this.baselineCurrentFileLocations(pos => this.getBreakpointStatementLocation(pos)!)); } @@ -1497,8 +1492,7 @@ Actual: ${stringify(fullActual)}`); } public baselineQuickInfo() { - const baselineFile = this.testData.globalOptions[MetadataOptionNames.baselineFile] || - ts.getBaseFileName(this.activeFile.fileName).replace(ts.Extension.Ts, ".baseline"); + const baselineFile = this.getBaselineFileName(); Harness.Baseline.runBaseline( baselineFile, stringify( @@ -1508,6 +1502,39 @@ Actual: ${stringify(fullActual)}`); })))); } + public baselineSmartSelection() { + const n = ts.sys.newLine; + const baselineFile = this.getBaselineFileName(); + const markers = this.getMarkers(); + const fileContent = this.activeFile.content; + const text = markers.map(marker => { + const baselineContent = [fileContent.slice(0, marker.position) + "/**/" + fileContent.slice(marker.position) + n]; + let selectionRange: ts.SelectionRange | undefined = this.languageService.getSmartSelectionRange(this.activeFile.fileName, marker.position); + while (selectionRange) { + const { textSpan } = selectionRange; + let masked = Array.from(fileContent).map((char, index) => { + const charCode = char.charCodeAt(0); + if (index >= textSpan.start && index < ts.textSpanEnd(textSpan)) { + return char === " " ? "•" : ts.isLineBreak(charCode) ? `↲${n}` : char; + } + return ts.isLineBreak(charCode) ? char : " "; + }).join(""); + masked = masked.replace(/^\s*$\r?\n?/gm, ""); // Remove blank lines + const isRealCharacter = (char: string) => char !== "•" && char !== "↲" && !ts.isWhiteSpaceLike(char.charCodeAt(0)); + const leadingWidth = Array.from(masked).findIndex(isRealCharacter); + const trailingWidth = ts.findLastIndex(Array.from(masked), isRealCharacter); + masked = masked.slice(0, leadingWidth) + + masked.slice(leadingWidth, trailingWidth).replace(/•/g, " ").replace(/↲/g, "") + + masked.slice(trailingWidth); + baselineContent.push(masked); + selectionRange = selectionRange.parent; + } + return baselineContent.join(n); + }).join(n.repeat(2) + "=".repeat(80) + n.repeat(2)); + + Harness.Baseline.runBaseline(baselineFile, text); + } + public printBreakpointLocation(pos: number) { Harness.IO.log("\n**Pos: " + pos + " " + this.spanInfoToString(this.getBreakpointStatementLocation(pos)!, " ")); } @@ -1562,6 +1589,11 @@ Actual: ${stringify(fullActual)}`); Harness.IO.log(stringify(help.items[help.selectedItemIndex])); } + private getBaselineFileName() { + return this.testData.globalOptions[MetadataOptionNames.baselineFile] || + ts.getBaseFileName(this.activeFile.fileName).replace(ts.Extension.Ts, ".baseline"); + } + private getSignatureHelp({ triggerReason }: FourSlashInterface.VerifySignatureHelpOptions): ts.SignatureHelpItems | undefined { return this.languageService.getSignatureHelpItems(this.activeFile.fileName, this.currentCaretPosition, { triggerReason @@ -3973,6 +4005,10 @@ namespace FourSlashInterface { this.state.baselineQuickInfo(); } + public baselineSmartSelection() { + this.state.baselineSmartSelection(); + } + public nameOrDottedNameSpanTextIs(text: string) { this.state.verifyCurrentNameOrDottedNameSpanText(text); } diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 6488748b728..4252296d5da 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -244,6 +244,7 @@ declare namespace FourSlashInterface { baselineGetEmitOutput(insertResultsIntoVfs?: boolean): void; getEmitOutput(expectedOutputFiles: ReadonlyArray): void; baselineQuickInfo(): void; + baselineSmartSelection(): void; nameOrDottedNameSpanTextIs(text: string): void; outliningSpansInCurrentFile(spans: Range[]): void; todoCommentsInCurrentFile(descriptors: string[]): void; @@ -508,7 +509,7 @@ declare namespace FourSlashInterface { readonly importModuleSpecifierEnding?: "minimal" | "index" | "js"; } interface CompletionsOptions { - readonly marker?: ArrayOrSingle, + readonly marker?: ArrayOrSingle; readonly isNewIdentifierLocation?: boolean; readonly isGlobalCompletion?: boolean; readonly exact?: ArrayOrSingle;