From c73af610fe98b6b3a45d4c89e6122d06725ac9c5 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Mon, 16 Dec 2019 17:21:21 -0800 Subject: [PATCH] Add `ignoreInterpolations` util to fourslash for fuzzy diagnostic matching (#35652) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add ignoreInterpolations util to fourslash for fuzzy diagnostic matching * Simplify * It’s not Swift * Fix regexp * Remove unnecessary type assertion --- src/harness/fourslashImpl.ts | 15 ++++++++++++++- src/harness/fourslashInterfaceImpl.ts | 5 ++++- .../cases/fourslash/codeFixInPropertyAccess_js.ts | 6 +++--- tests/cases/fourslash/fourslash.ts | 5 ++++- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index c0894d4280444..eaa74d9dd7285 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -137,6 +137,10 @@ namespace FourSlash { throw new Error("Operation should be cancelled"); } + export function ignoreInterpolations(diagnostic: string | ts.DiagnosticMessage): FourSlashInterface.DiagnosticIgnoredInterpolations { + return { template: typeof diagnostic === "string" ? diagnostic : diagnostic.message }; + } + // This function creates IScriptSnapshot object for testing getPreProcessedFileInfo // Return object may lack some functionalities for other purposes. function createScriptSnapShot(sourceText: string): ts.IScriptSnapshot { @@ -2483,7 +2487,12 @@ namespace FourSlash { const action = actions[index]; - assert.equal(action.description, options.description); + if (typeof options.description === "string") { + assert.equal(action.description, options.description); + } + else { + assert.match(action.description, templateToRegExp(options.description.template)); + } assert.deepEqual(action.commands, options.commands); if (options.applyChanges) { @@ -3829,4 +3838,8 @@ ${code} const actualString = quoted ? "\"" + actual + "\"" : actual; return `\n${expectMsg}:\n${expectedString}\n\n${actualMsg}:\n${actualString}`; } + + function templateToRegExp(template: string) { + return new RegExp(`^${ts.regExpEscape(template).replace(/\\\{\d+\\\}/g, ".*?")}$`); + } } diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index 3ff3bef300690..b9edd175aaa28 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -1547,7 +1547,7 @@ namespace FourSlashInterface { } export interface VerifyCodeFixOptions extends NewContentOptions { - readonly description: string; + readonly description: string | DiagnosticIgnoredInterpolations; readonly errorCode?: number; readonly index?: number; readonly preferences?: ts.UserPreferences; @@ -1605,5 +1605,8 @@ namespace FourSlashInterface { readonly ranges: readonly RenameLocationOptions[]; readonly providePrefixAndSuffixTextForRename?: boolean; }; + export interface DiagnosticIgnoredInterpolations { + template: string + }; export type RenameLocationOptions = FourSlash.Range | { readonly range: FourSlash.Range, readonly prefixText?: string, readonly suffixText?: string }; } diff --git a/tests/cases/fourslash/codeFixInPropertyAccess_js.ts b/tests/cases/fourslash/codeFixInPropertyAccess_js.ts index ef69d88962660..da695bb345c0a 100644 --- a/tests/cases/fourslash/codeFixInPropertyAccess_js.ts +++ b/tests/cases/fourslash/codeFixInPropertyAccess_js.ts @@ -16,9 +16,9 @@ //// return false; //// } -verify.codeFixAll({ - fixId: "correctQualifiedNameToIndexedAccessType", - fixAllDescription: "Rewrite all as indexed access types", +verify.codeFix({ + index: 0, + description: ignoreInterpolations(ts.Diagnostics.Rewrite_as_the_indexed_access_type_0), newFileContent: `/** * @typedef Foo diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 473962e64f11a..6d6ecc0a5ade5 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -226,7 +226,7 @@ declare namespace FourSlashInterface { jsxClosingTag(map: { [markerName: string]: { readonly newText: string } | undefined }): void; isInCommentAtPosition(onlyMultiLineDiverges?: boolean): void; codeFix(options: { - description: string, + description: string | DiagnosticIgnoredInterpolations, newFileContent?: NewFileContent, newRangeContent?: string, errorCode?: number, @@ -720,7 +720,10 @@ declare namespace FourSlashInterface { readonly providePrefixAndSuffixTextForRename?: boolean; }; type RenameLocationOptions = Range | { readonly range: Range, readonly prefixText?: string, readonly suffixText?: string }; + type DiagnosticIgnoredInterpolations = { template: string } } +/** Wraps a diagnostic message to be compared ignoring interpolated strings */ +declare function ignoreInterpolations(diagnostic: string | ts.DiagnosticMessage): FourSlashInterface.DiagnosticIgnoredInterpolations; declare function verifyOperationIsCancelled(f: any): void; declare var test: FourSlashInterface.test_; declare var plugins: FourSlashInterface.plugins;