mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 16:38:05 -06:00
Improve verify.codeFixAvailable (#24325)
* Improve verify.codeFixAvailable * Revert change to `verify.not.codeFixAvailable()`, and use `assertObjectsEqual` for better errors
This commit is contained in:
parent
56f33ad3bb
commit
aed0eb6693
@ -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) {
|
||||
|
||||
@ -9,4 +9,7 @@
|
||||
////
|
||||
//// class C implements I1,I2 {[| |]}
|
||||
|
||||
verify.codeFixAvailable();
|
||||
verify.codeFixAvailable([
|
||||
{ description: "Implement interface 'I1'" },
|
||||
{ description: "Implement interface 'I2'" },
|
||||
]);
|
||||
|
||||
@ -11,4 +11,4 @@
|
||||
//// x: number;
|
||||
//// }
|
||||
|
||||
verify.not.codeFixAvailable();
|
||||
verify.not.codeFixAvailable();
|
||||
|
||||
@ -9,4 +9,7 @@
|
||||
////
|
||||
//// class C implements I1,I2 {[| |]}
|
||||
|
||||
verify.codeFixAvailable();
|
||||
verify.codeFixAvailable([
|
||||
{ description: "Implement interface 'I1'" },
|
||||
{ description: "Implement interface 'I2'" },
|
||||
]);
|
||||
|
||||
@ -11,4 +11,4 @@
|
||||
//// x: string;
|
||||
//// }
|
||||
|
||||
verify.not.codeFixAvailable();
|
||||
verify.not.codeFixAvailable();
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
////
|
||||
//// class B implements A {[| |]}
|
||||
|
||||
verify.not.codeFixAvailable();
|
||||
verify.codeFixAvailable([]);
|
||||
|
||||
// TODO: (arozga) Get this working.
|
||||
/*
|
||||
|
||||
@ -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>'" }]);
|
||||
|
||||
@ -4,6 +4,6 @@
|
||||
//// x: T;
|
||||
//// }
|
||||
////
|
||||
//// class C implements I { }
|
||||
//// class C implements I { }
|
||||
|
||||
verify.not.codeFixAvailable();
|
||||
verify.not.codeFixAvailable();
|
||||
|
||||
@ -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();
|
||||
// Should be verify.codeFixAvailable([]);
|
||||
verify.codeFixAvailable([{ description: "Implement interface 'I'" }]);
|
||||
|
||||
@ -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'" },
|
||||
]);
|
||||
|
||||
@ -9,4 +9,4 @@
|
||||
//// }
|
||||
////}
|
||||
|
||||
verify.not.codeFixAvailable();
|
||||
verify.not.codeFixAvailable();
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @jsx: react
|
||||
// @jsx: react
|
||||
// @jsxFactory: factory
|
||||
|
||||
// @Filename: /a.tsx
|
||||
@ -10,5 +10,4 @@
|
||||
//// }
|
||||
////}
|
||||
|
||||
|
||||
verify.not.codeFixAvailable();
|
||||
|
||||
@ -13,4 +13,4 @@
|
||||
////}
|
||||
|
||||
goTo.file("/b.ts");
|
||||
verify.not.codeFixAvailable();
|
||||
verify.not.codeFixAvailable();
|
||||
|
||||
@ -14,4 +14,4 @@
|
||||
//// let t: T<number>;
|
||||
//// t.x;
|
||||
|
||||
verify.not.codeFixAvailable();
|
||||
verify.not.codeFixAvailable();
|
||||
|
||||
@ -6,5 +6,4 @@
|
||||
////}
|
||||
////f(
|
||||
|
||||
verify.not.codeFixAvailable([]);
|
||||
|
||||
verify.not.codeFixAvailable();
|
||||
|
||||
@ -3,5 +3,4 @@
|
||||
// @noImplicitAny: true
|
||||
//// function ...q) {}} f(10);
|
||||
|
||||
verify.not.codeFixAvailable([]);
|
||||
|
||||
verify.not.codeFixAvailable();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user