diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 16295828d05..4bc53455c9e 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -2998,30 +2998,11 @@ Actual: ${stringify(fullActual)}`); } } - public verifyCodeFixAvailable(negative: boolean, info: FourSlashInterface.VerifyCodeFixAvailableOptions[] | undefined) { + public verifyCodeFixAvailable(negative: boolean, expected: FourSlashInterface.VerifyCodeFixAvailableOptions[] | undefined): void { + assert(!negative || !expected); const codeFixes = this.getCodeFixes(this.activeFile.fileName); - - if (negative) { - if (codeFixes.length) { - this.raiseError(`verifyCodeFixAvailable failed - expected no fixes but found ${codeFixes.map(c => c.description)}.`); - } - return; - } - - if (!codeFixes.length) { - this.raiseError(`verifyCodeFixAvailable failed - expected code fixes but none found.`); - } - codeFixes.forEach(fix => fix.changes.forEach(change => { - assert.isObject(change, `Invalid change in code fix: ${JSON.stringify(fix)}`); - change.textChanges.forEach(textChange => assert.isObject(textChange, `Invalid textChange in codeFix: ${JSON.stringify(fix)}`)); - })); - if (info) { - assert.equal(info.length, codeFixes.length); - ts.zipWith(codeFixes, info, (fix, info) => { - assert.equal(fix.description, info.description); - this.assertObjectsEqual(fix.commands, info.commands); - }); - } + const actuals = codeFixes.map((fix): FourSlashInterface.VerifyCodeFixAvailableOptions => ({ description: fix.description, commands: fix.commands })); + this.assertObjectsEqual(actuals, negative ? ts.emptyArray : expected); } public verifyApplicableRefactorAvailableAtMarker(negative: boolean, markerName: string) { diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceDuplicateMember1.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceDuplicateMember1.ts index bea14ae4040..f96186db1f0 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceDuplicateMember1.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceDuplicateMember1.ts @@ -9,4 +9,7 @@ //// //// class C implements I1,I2 {[| |]} -verify.codeFixAvailable(); \ No newline at end of file +verify.codeFixAvailable([ + { description: "Implement interface 'I1'" }, + { description: "Implement interface 'I2'" }, +]); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceDuplicateMember2.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceDuplicateMember2.ts index ac90d51b07c..9b4831e0702 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceDuplicateMember2.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceDuplicateMember2.ts @@ -11,4 +11,4 @@ //// x: number; //// } -verify.not.codeFixAvailable(); \ No newline at end of file +verify.not.codeFixAvailable(); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleImplementsIntersection1.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleImplementsIntersection1.ts index cac1038eb18..0ddce052b41 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleImplementsIntersection1.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleImplementsIntersection1.ts @@ -9,4 +9,7 @@ //// //// class C implements I1,I2 {[| |]} -verify.codeFixAvailable(); \ No newline at end of file +verify.codeFixAvailable([ + { description: "Implement interface 'I1'" }, + { description: "Implement interface 'I2'" }, +]); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleImplementsIntersection2.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleImplementsIntersection2.ts index 8f744e25cae..e43c44063e6 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleImplementsIntersection2.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceMultipleImplementsIntersection2.ts @@ -11,4 +11,4 @@ //// x: string; //// } -verify.not.codeFixAvailable(); \ No newline at end of file +verify.not.codeFixAvailable(); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfacePropertyFromParentConstructorFunction.ts b/tests/cases/fourslash/codeFixClassImplementInterfacePropertyFromParentConstructorFunction.ts index acda59513ad..7a0d801ed5d 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfacePropertyFromParentConstructorFunction.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfacePropertyFromParentConstructorFunction.ts @@ -6,7 +6,7 @@ //// //// class B implements A {[| |]} -verify.not.codeFixAvailable(); +verify.codeFixAvailable([]); // TODO: (arozga) Get this working. /* diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamInstantiateError.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamInstantiateError.ts index f4e433e9c0d..dc816ae8655 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamInstantiateError.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamInstantiateError.ts @@ -4,10 +4,9 @@ //// x: T; //// } //// -//// class C implements I { } - -verify.codeFixAvailable(); +//// class C implements I { } // TODO: (arozga) Don't know how to instantiate in codeFix // if instantiation is invalid. -// verify.not.codeFixAvailable(); \ No newline at end of file +// Should be verify.codeFixAvailable([]); +verify.codeFixAvailable([{ description: "Implement interface 'I'" }]); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamInstantiation.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamInstantiation.ts index 226aee47833..ccbbbd89522 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamInstantiation.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceTypeParamInstantiation.ts @@ -4,6 +4,6 @@ //// x: T; //// } //// -//// class C implements I { } +//// class C implements I { } -verify.not.codeFixAvailable(); \ No newline at end of file +verify.not.codeFixAvailable(); diff --git a/tests/cases/fourslash/codeFixClassImplementInterfaceUndeclaredSymbol.ts b/tests/cases/fourslash/codeFixClassImplementInterfaceUndeclaredSymbol.ts index 0acf60645c9..c5bb11e1b40 100644 --- a/tests/cases/fourslash/codeFixClassImplementInterfaceUndeclaredSymbol.ts +++ b/tests/cases/fourslash/codeFixClassImplementInterfaceUndeclaredSymbol.ts @@ -4,7 +4,7 @@ //// x: T; //// } //// -//// class C implements I { } +//// class C implements I { } // T is not a declared symbol. There are a couple fixes: // 1) Declare T. @@ -14,6 +14,6 @@ // In the latter two cases, it is premature to copy `x:T` into C. // Since we can't guess the programmer's intent here, we do nothing. -verify.codeFixAvailable(); // TODO: (aozgaa) Acknowledge other errors on class/implemented interface/extended abstract class. -// verify.not.codeFixAvailable(); \ No newline at end of file +// Should be verify.codeFixAvailable([]); +verify.codeFixAvailable([{ description: "Implement interface 'I'" }]); diff --git a/tests/cases/fourslash/codeFixClassPropertyInitialization.ts b/tests/cases/fourslash/codeFixClassPropertyInitialization.ts index 224d7dd17b9..6b7cbbc2705 100644 --- a/tests/cases/fourslash/codeFixClassPropertyInitialization.ts +++ b/tests/cases/fourslash/codeFixClassPropertyInitialization.ts @@ -7,34 +7,54 @@ //// class TT { constructor () {} } //// //// class AT extends A { a () {} } -//// +//// //// class Foo {} //// //// class T { -//// +//// //// a: string; -//// +//// //// static b: string; -//// +//// //// private c: string; -//// +//// //// d: number | undefined; -//// +//// //// e: string | number; -//// +//// //// f: 1; -//// +//// //// g: "123" | "456"; -//// +//// //// h: boolean; -//// +//// //// i: TT; -//// +//// //// j: A; -//// +//// //// k: AT; -//// +//// //// l: Foo; //// } -verify.codeFixAvailable() \ No newline at end of file +function fixes(name: string, type: string, options: { isPrivate?: boolean, noInitializer?: boolean } = {}) { + return [ + `Add 'undefined' type to property '${name}'`, + `Add definite assignment assertion to property '${options.isPrivate ? "private " : ""}${name}: ${type};'`, + ...(options.noInitializer ? [] : [`Add initializer to property '${name}'`]), + ].map(description => ({ description })); +} + +verify.codeFixAvailable([ + ...fixes("a", "string"), + ...fixes("c", "string", { isPrivate: true }), + ...fixes("e", "string | number"), + ...fixes("f", "1"), + ...fixes("g", '"123" | "456"'), + ...fixes("h", "boolean"), + ...fixes("i", "TT"), + ...fixes("j", "A", { noInitializer: true }), + ...fixes("k", "AT"), + ...fixes("l", "Foo"), + { description: "Remove declaration for: 'c'" }, +]); diff --git a/tests/cases/fourslash/codeFixClassSuperMustPrecedeThisAccess_callWithThisInside.ts b/tests/cases/fourslash/codeFixClassSuperMustPrecedeThisAccess_callWithThisInside.ts index 6660027ae00..0ffe3314ced 100644 --- a/tests/cases/fourslash/codeFixClassSuperMustPrecedeThisAccess_callWithThisInside.ts +++ b/tests/cases/fourslash/codeFixClassSuperMustPrecedeThisAccess_callWithThisInside.ts @@ -9,4 +9,4 @@ //// } ////} -verify.not.codeFixAvailable(); \ No newline at end of file +verify.not.codeFixAvailable(); diff --git a/tests/cases/fourslash/codeFixForgottenThisPropertyAccess04.ts b/tests/cases/fourslash/codeFixForgottenThisPropertyAccess04.ts index 884bad4d21a..66da5972878 100644 --- a/tests/cases/fourslash/codeFixForgottenThisPropertyAccess04.ts +++ b/tests/cases/fourslash/codeFixForgottenThisPropertyAccess04.ts @@ -1,6 +1,6 @@ /// -// @jsx: react +// @jsx: react // @jsxFactory: factory // @Filename: /a.tsx @@ -10,5 +10,4 @@ //// } ////} - verify.not.codeFixAvailable(); diff --git a/tests/cases/fourslash/codeFixInferFromUsageSetterWithInaccessibleType.ts b/tests/cases/fourslash/codeFixInferFromUsageSetterWithInaccessibleType.ts index 7a0c079799b..9e56fc70734 100644 --- a/tests/cases/fourslash/codeFixInferFromUsageSetterWithInaccessibleType.ts +++ b/tests/cases/fourslash/codeFixInferFromUsageSetterWithInaccessibleType.ts @@ -13,4 +13,4 @@ ////} goTo.file("/b.ts"); -verify.not.codeFixAvailable(); \ No newline at end of file +verify.not.codeFixAvailable(); diff --git a/tests/cases/fourslash/codeFixUndeclaredPropertyAccesses.ts b/tests/cases/fourslash/codeFixUndeclaredPropertyAccesses.ts index ee05d2c0a9c..2576dbb1fb7 100644 --- a/tests/cases/fourslash/codeFixUndeclaredPropertyAccesses.ts +++ b/tests/cases/fourslash/codeFixUndeclaredPropertyAccesses.ts @@ -14,4 +14,4 @@ //// let t: T; //// t.x; -verify.not.codeFixAvailable(); \ No newline at end of file +verify.not.codeFixAvailable(); diff --git a/tests/cases/fourslash/incompleteFunctionCallCodefix.ts b/tests/cases/fourslash/incompleteFunctionCallCodefix.ts index a84c48e3da5..9935ee854f3 100644 --- a/tests/cases/fourslash/incompleteFunctionCallCodefix.ts +++ b/tests/cases/fourslash/incompleteFunctionCallCodefix.ts @@ -6,5 +6,4 @@ ////} ////f( -verify.not.codeFixAvailable([]); - +verify.not.codeFixAvailable(); diff --git a/tests/cases/fourslash/incompleteFunctionCallCodefix3.ts b/tests/cases/fourslash/incompleteFunctionCallCodefix3.ts index 3c0261e48a7..29072c7c855 100644 --- a/tests/cases/fourslash/incompleteFunctionCallCodefix3.ts +++ b/tests/cases/fourslash/incompleteFunctionCallCodefix3.ts @@ -3,5 +3,4 @@ // @noImplicitAny: true //// function ...q) {}} f(10); -verify.not.codeFixAvailable([]); - +verify.not.codeFixAvailable();