Skip to content

Improve verify.codeFixAvailable #24325

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
3 commits merged into from
May 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 4 additions & 23 deletions src/harness/fourslash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 }));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about change locations?

Copy link
Author

@ghost ghost May 22, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method verify.codeFixAvailable just tests for availability -- verify.codeFix will test the actual content of the fix.

this.assertObjectsEqual(actuals, negative ? ts.emptyArray : expected);
}

public verifyApplicableRefactorAvailableAtMarker(negative: boolean, markerName: string) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,7 @@
////
//// class C implements I1,I2 {[| |]}

verify.codeFixAvailable();
verify.codeFixAvailable([
{ description: "Implement interface 'I1'" },
{ description: "Implement interface 'I2'" },
]);
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@
//// x: number;
//// }

verify.not.codeFixAvailable();
verify.not.codeFixAvailable();
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,7 @@
////
//// class C implements I1,I2 {[| |]}

verify.codeFixAvailable();
verify.codeFixAvailable([
{ description: "Implement interface 'I1'" },
{ description: "Implement interface 'I2'" },
]);
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@
//// x: string;
//// }

verify.not.codeFixAvailable();
verify.not.codeFixAvailable();
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
////
//// class B implements A {[| |]}

verify.not.codeFixAvailable();
verify.codeFixAvailable([]);

// TODO: (arozga) Get this working.
/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@
//// x: T;
//// }
////
//// class C implements I<number> { }

verify.codeFixAvailable();
//// class C implements I<number> { }

// TODO: (arozga) Don't know how to instantiate in codeFix
// if instantiation is invalid.
// verify.not.codeFixAvailable();
// Should be verify.codeFixAvailable([]);
verify.codeFixAvailable([{ description: "Implement interface 'I<number>'" }]);
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
//// x: T;
//// }
////
//// class C implements I { }
//// class C implements I { }

verify.not.codeFixAvailable();
verify.not.codeFixAvailable();
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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();
// Should be verify.codeFixAvailable([]);
verify.codeFixAvailable([{ description: "Implement interface 'I'" }]);
48 changes: 34 additions & 14 deletions tests/cases/fourslash/codeFixClassPropertyInitialization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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()
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'" },
]);
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
//// }
////}

verify.not.codeFixAvailable();
verify.not.codeFixAvailable();
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/// <reference path='fourslash.ts' />

// @jsx: react
// @jsx: react
// @jsxFactory: factory

// @Filename: /a.tsx
Expand All @@ -10,5 +10,4 @@
//// }
////}


verify.not.codeFixAvailable();
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@
////}

goTo.file("/b.ts");
verify.not.codeFixAvailable();
verify.not.codeFixAvailable();
2 changes: 1 addition & 1 deletion tests/cases/fourslash/codeFixUndeclaredPropertyAccesses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@
//// let t: T<number>;
//// t.x;

verify.not.codeFixAvailable();
verify.not.codeFixAvailable();
3 changes: 1 addition & 2 deletions tests/cases/fourslash/incompleteFunctionCallCodefix.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@
////}
////f(

verify.not.codeFixAvailable([]);

verify.not.codeFixAvailable();
3 changes: 1 addition & 2 deletions tests/cases/fourslash/incompleteFunctionCallCodefix3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@
// @noImplicitAny: true
//// function ...q) {}} f(10);

verify.not.codeFixAvailable([]);

verify.not.codeFixAvailable();