Skip to content

Commit ec1a434

Browse files
authored
Port verify.quickInfo... tests (#1494)
1 parent 6f385fd commit ec1a434

File tree

300 files changed

+9943
-6
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

300 files changed

+9943
-6
lines changed

internal/fourslash/_scripts/convertFourslash.mts

Lines changed: 167 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -144,16 +144,30 @@ function parseFourslashStatement(statement: ts.Statement): Cmd[] | undefined {
144144
}
145145
const namespace = callExpression.expression.expression;
146146
const func = callExpression.expression.name;
147-
if (!ts.isIdentifier(namespace) || !ts.isIdentifier(func)) {
147+
if (!(ts.isIdentifier(namespace) || namespace.getText() === "verify.not") || !ts.isIdentifier(func)) {
148148
console.error(`Expected identifiers for namespace and function, got ${namespace.getText()} and ${func.getText()}`);
149149
return undefined;
150150
}
151+
if (!ts.isIdentifier(namespace)) {
152+
switch (func.text) {
153+
case "quickInfoExists":
154+
return parseQuickInfoArgs("notQuickInfoExists", callExpression.arguments);
155+
}
156+
console.error(`Unrecognized fourslash statement: ${statement.getText()}`);
157+
return undefined;
158+
}
151159
// `verify.(...)`
152160
if (namespace.text === "verify") {
153161
switch (func.text) {
154162
case "completions":
155163
// `verify.completions(...)`
156164
return parseVerifyCompletionsArgs(callExpression.arguments);
165+
case "quickInfoAt":
166+
case "quickInfoExists":
167+
case "quickInfoIs":
168+
case "quickInfos":
169+
// `verify.quickInfo...(...)`
170+
return parseQuickInfoArgs(func.text, callExpression.arguments);
157171
case "baselineFindAllReferences":
158172
// `verify.baselineFindAllReferences(...)`
159173
return [parseBaselineFindAllReferencesArgs(callExpression.arguments)];
@@ -721,6 +735,127 @@ function parseBaselineQuickInfo(args: ts.NodeArray<ts.Expression>): Cmd {
721735
};
722736
}
723737

738+
function parseQuickInfoArgs(funcName: string, args: readonly ts.Expression[]): VerifyQuickInfoCmd[] | undefined {
739+
// We currently don't support 'expectedTags'.
740+
switch (funcName) {
741+
case "quickInfoAt": {
742+
if (args.length < 1 || args.length > 3) {
743+
console.error(`Expected 1 or 2 arguments in quickInfoIs, got ${args.map(arg => arg.getText()).join(", ")}`);
744+
return undefined;
745+
}
746+
if (!ts.isStringLiteralLike(args[0])) {
747+
console.error(`Expected string literal for first argument in quickInfoAt, got ${args[0].getText()}`);
748+
return undefined;
749+
}
750+
const marker = getGoStringLiteral(args[0].text);
751+
let text: string | undefined;
752+
if (args[1]) {
753+
if (!ts.isStringLiteralLike(args[1])) {
754+
console.error(`Expected string literal for second argument in quickInfoAt, got ${args[1].getText()}`);
755+
return undefined;
756+
}
757+
text = getGoStringLiteral(args[1].text);
758+
}
759+
let docs: string | undefined;
760+
if (args[2]) {
761+
if (!ts.isStringLiteralLike(args[2]) && args[2].getText() !== "undefined") {
762+
console.error(`Expected string literal or undefined for third argument in quickInfoAt, got ${args[2].getText()}`);
763+
return undefined;
764+
}
765+
if (ts.isStringLiteralLike(args[2])) {
766+
docs = getGoStringLiteral(args[1].text);
767+
}
768+
}
769+
return [{
770+
kind: "quickInfoAt",
771+
marker,
772+
text,
773+
docs,
774+
}];
775+
}
776+
case "quickInfos": {
777+
const cmds: VerifyQuickInfoCmd[] = [];
778+
if (args.length !== 1 || !ts.isObjectLiteralExpression(args[0])) {
779+
console.error(`Expected a single object literal argument in quickInfos, got ${args.map(arg => arg.getText()).join(", ")}`);
780+
return undefined;
781+
}
782+
for (const prop of args[0].properties) {
783+
if (!ts.isPropertyAssignment(prop)) {
784+
console.error(`Expected property assignment in quickInfos, got ${prop.getText()}`);
785+
return undefined;
786+
}
787+
if (!(ts.isIdentifier(prop.name) || ts.isStringLiteralLike(prop.name) || ts.isNumericLiteral(prop.name))) {
788+
console.error(`Expected identifier or literal for property name in quickInfos, got ${prop.name.getText()}`);
789+
return undefined;
790+
}
791+
const marker = getGoStringLiteral(prop.name.text);
792+
let text: string | undefined;
793+
let docs: string | undefined;
794+
if (ts.isArrayLiteralExpression(prop.initializer)) {
795+
if (prop.initializer.elements.length !== 2) {
796+
console.error(`Expected two elements in array literal for quickInfos property, got ${prop.initializer.getText()}`);
797+
return undefined;
798+
}
799+
if (!ts.isStringLiteralLike(prop.initializer.elements[0]) || !ts.isStringLiteralLike(prop.initializer.elements[1])) {
800+
console.error(`Expected string literals in array literal for quickInfos property, got ${prop.initializer.getText()}`);
801+
return undefined;
802+
}
803+
text = getGoStringLiteral(prop.initializer.elements[0].text);
804+
docs = getGoStringLiteral(prop.initializer.elements[1].text);
805+
}
806+
else if (ts.isStringLiteralLike(prop.initializer)) {
807+
text = getGoStringLiteral(prop.initializer.text);
808+
}
809+
else {
810+
console.error(`Expected string literal or array literal for quickInfos property, got ${prop.initializer.getText()}`);
811+
return undefined;
812+
}
813+
cmds.push({
814+
kind: "quickInfoAt",
815+
marker,
816+
text,
817+
docs,
818+
});
819+
}
820+
return cmds;
821+
}
822+
case "quickInfoExists":
823+
return [{
824+
kind: "quickInfoExists",
825+
}];
826+
case "notQuickInfoExists":
827+
return [{
828+
kind: "notQuickInfoExists",
829+
}];
830+
case "quickInfoIs": {
831+
if (args.length < 1 || args.length > 2) {
832+
console.error(`Expected 1 or 2 arguments in quickInfoIs, got ${args.map(arg => arg.getText()).join(", ")}`);
833+
return undefined;
834+
}
835+
if (!ts.isStringLiteralLike(args[0])) {
836+
console.error(`Expected string literal for first argument in quickInfoIs, got ${args[0].getText()}`);
837+
return undefined;
838+
}
839+
const text = getGoStringLiteral(args[0].text);
840+
let docs: string | undefined;
841+
if (args[1]) {
842+
if (!ts.isStringLiteralLike(args[1])) {
843+
console.error(`Expected string literal for second argument in quickInfoIs, got ${args[1].getText()}`);
844+
return undefined;
845+
}
846+
docs = getGoStringLiteral(args[1].text);
847+
}
848+
return [{
849+
kind: "quickInfoIs",
850+
text,
851+
docs,
852+
}];
853+
}
854+
}
855+
console.error(`Unrecognized quick info function: ${funcName}`);
856+
return undefined;
857+
}
858+
724859
function parseKind(expr: ts.Expression): string | undefined {
725860
if (!ts.isStringLiteral(expr)) {
726861
console.error(`Expected string literal for kind, got ${expr.getText()}`);
@@ -884,13 +1019,21 @@ interface EditCmd {
8841019
goStatement: string;
8851020
}
8861021

1022+
interface VerifyQuickInfoCmd {
1023+
kind: "quickInfoIs" | "quickInfoAt" | "quickInfoExists" | "notQuickInfoExists";
1024+
marker?: string;
1025+
text?: string;
1026+
docs?: string;
1027+
}
1028+
8871029
type Cmd =
8881030
| VerifyCompletionsCmd
8891031
| VerifyBaselineFindAllReferencesCmd
8901032
| VerifyBaselineGoToDefinitionCmd
8911033
| VerifyBaselineQuickInfoCmd
8921034
| GoToCmd
893-
| EditCmd;
1035+
| EditCmd
1036+
| VerifyQuickInfoCmd;
8941037

8951038
function generateVerifyCompletions({ marker, args, isNewIdentifierLocation }: VerifyCompletionsCmd): string {
8961039
let expectedList: string;
@@ -938,21 +1081,39 @@ function generateGoToCommand({ funcName, args }: GoToCmd): string {
9381081
return `f.GoTo${funcNameCapitalized}(t, ${args.join(", ")})`;
9391082
}
9401083

1084+
function generateQuickInfoCommand({ kind, marker, text, docs }: VerifyQuickInfoCmd): string {
1085+
switch (kind) {
1086+
case "quickInfoIs":
1087+
return `f.VerifyQuickInfoIs(t, ${text!}, ${docs ? docs : `""`})`;
1088+
case "quickInfoAt":
1089+
return `f.VerifyQuickInfoAt(t, ${marker!}, ${text ? text : `""`}, ${docs ? docs : `""`})`;
1090+
case "quickInfoExists":
1091+
return `f.VerifyQuickInfoExists(t)`;
1092+
case "notQuickInfoExists":
1093+
return `f.VerifyNotQuickInfoExists(t)`;
1094+
}
1095+
}
1096+
9411097
function generateCmd(cmd: Cmd): string {
9421098
switch (cmd.kind) {
9431099
case "verifyCompletions":
944-
return generateVerifyCompletions(cmd as VerifyCompletionsCmd);
1100+
return generateVerifyCompletions(cmd);
9451101
case "verifyBaselineFindAllReferences":
946-
return generateBaselineFindAllReferences(cmd as VerifyBaselineFindAllReferencesCmd);
1102+
return generateBaselineFindAllReferences(cmd);
9471103
case "verifyBaselineGoToDefinition":
948-
return generateBaselineGoToDefinition(cmd as VerifyBaselineGoToDefinitionCmd);
1104+
return generateBaselineGoToDefinition(cmd);
9491105
case "verifyBaselineQuickInfo":
9501106
// Quick Info -> Hover
9511107
return `f.VerifyBaselineHover(t)`;
9521108
case "goTo":
953-
return generateGoToCommand(cmd as GoToCmd);
1109+
return generateGoToCommand(cmd);
9541110
case "edit":
9551111
return cmd.goStatement;
1112+
case "quickInfoAt":
1113+
case "quickInfoIs":
1114+
case "quickInfoExists":
1115+
case "notQuickInfoExists":
1116+
return generateQuickInfoCommand(cmd);
9561117
default:
9571118
let neverCommand: never = cmd;
9581119
throw new Error(`Unknown command kind: ${neverCommand as Cmd["kind"]}`);

0 commit comments

Comments
 (0)