Skip to content
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
57 changes: 30 additions & 27 deletions src/harness/fourslash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
namespace FourSlash {
ts.disableIncrementalParsing = false;

import Many = FourSlashInterface.Many;
import ArrayOrSingle = FourSlashInterface.Many;

// Represents a parsed source file with metadata
interface FourSlashFile {
Expand Down Expand Up @@ -627,11 +627,11 @@ namespace FourSlash {
}
}

public verifyGoToDefinitionIs(endMarker: Many<string>) {
public verifyGoToDefinitionIs(endMarker: ArrayOrSingle<string>) {
this.verifyGoToXWorker(toArray(endMarker), () => this.getGoToDefinition());
}

public verifyGoToDefinition(arg0: any, endMarkerNames?: Many<string>) {
public verifyGoToDefinition(arg0: any, endMarkerNames?: ArrayOrSingle<string>) {
this.verifyGoToX(arg0, endMarkerNames, () => this.getGoToDefinitionAndBoundSpan());
}

Expand All @@ -643,23 +643,23 @@ namespace FourSlash {
return this.languageService.getDefinitionAndBoundSpan(this.activeFile.fileName, this.currentCaretPosition);
}

public verifyGoToType(arg0: any, endMarkerNames?: Many<string>) {
public verifyGoToType(arg0: any, endMarkerNames?: ArrayOrSingle<string>) {
this.verifyGoToX(arg0, endMarkerNames, () =>
this.languageService.getTypeDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition));
}

private verifyGoToX(arg0: any, endMarkerNames: Many<string> | undefined, getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) {
private verifyGoToX(arg0: any, endMarkerNames: ArrayOrSingle<string> | undefined, getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) {
if (endMarkerNames) {
this.verifyGoToXPlain(arg0, endMarkerNames, getDefs);
}
else if (ts.isArray(arg0)) {
const pairs = arg0 as ReadonlyArray<[Many<string>, Many<string>]>;
const pairs = arg0 as ReadonlyArray<[ArrayOrSingle<string>, ArrayOrSingle<string>]>;
for (const [start, end] of pairs) {
this.verifyGoToXPlain(start, end, getDefs);
}
}
else {
const obj: { [startMarkerName: string]: Many<string> } = arg0;
const obj: { [startMarkerName: string]: ArrayOrSingle<string> } = arg0;
for (const startMarkerName in obj) {
if (ts.hasProperty(obj, startMarkerName)) {
this.verifyGoToXPlain(startMarkerName, obj[startMarkerName], getDefs);
Expand All @@ -668,7 +668,7 @@ namespace FourSlash {
}
}

private verifyGoToXPlain(startMarkerNames: Many<string>, endMarkerNames: Many<string>, getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) {
private verifyGoToXPlain(startMarkerNames: ArrayOrSingle<string>, endMarkerNames: ArrayOrSingle<string>, getDefs: () => ts.DefinitionInfo[] | ts.DefinitionInfoAndBoundSpan | undefined) {
for (const start of toArray(startMarkerNames)) {
this.verifyGoToXSingle(start, endMarkerNames, getDefs);
}
Expand All @@ -680,7 +680,7 @@ namespace FourSlash {
}
}

private verifyGoToXSingle(startMarkerName: string, endMarkerNames: Many<string>, getDefs: () => ReadonlyArray<ts.DefinitionInfo> | ts.DefinitionInfoAndBoundSpan | undefined) {
private verifyGoToXSingle(startMarkerName: string, endMarkerNames: ArrayOrSingle<string>, getDefs: () => ReadonlyArray<ts.DefinitionInfo> | ts.DefinitionInfoAndBoundSpan | undefined) {
this.goToMarker(startMarkerName);
this.verifyGoToXWorker(toArray(endMarkerNames), getDefs, startMarkerName);
}
Expand Down Expand Up @@ -843,19 +843,21 @@ namespace FourSlash {
}

public verifyCompletions(options: FourSlashInterface.VerifyCompletionsOptions) {
if (options.at !== undefined) {
if (typeof options.at === "string") {
this.goToMarker(options.at);
}
else {
for (const a of options.at) this.verifyCompletions({ ...options, at: a });
return;
if (options.marker === undefined) {
this.verifyCompletionsWorker(options);
}
else {
for (const marker of toArray(options.marker)) {
this.goToMarker(marker);
this.verifyCompletionsWorker(options);
}
}
}

private verifyCompletionsWorker(options: FourSlashInterface.VerifyCompletionsOptions): void {
const actualCompletions = this.getCompletionListAtCaret({ ...options.preferences, triggerCharacter: options.triggerCharacter });
if (!actualCompletions) {
if (options.are === undefined) return;
if (options.exact === undefined) return;
this.raiseError(`No completions at position '${this.currentCaretPosition}'.`);
}

Expand All @@ -874,9 +876,10 @@ namespace FourSlash {
}
}

if ("are" in options) {
if (options.are === undefined) this.raiseError("Expected no completions");
this.verifyCompletionsAreExactly(actualCompletions.entries, toArray(options.are));
if ("exact" in options) {
ts.Debug.assert(!("includes" in options) && !("excludes" in options));
if (options.exact === undefined) this.raiseError("Expected no completions");
this.verifyCompletionsAreExactly(actualCompletions.entries, toArray(options.exact));
}
else {
if (options.includes) {
Expand All @@ -887,7 +890,7 @@ namespace FourSlash {
this.verifyCompletionEntry(found, include);
}
}
else {
if (options.excludes) {
for (const exclude of toArray(options.excludes)) {
if (typeof exclude === "string") {
if (actualByName.has(exclude)) {
Expand Down Expand Up @@ -954,7 +957,7 @@ namespace FourSlash {
}

public verifyCompletionsAt(markerName: string | ReadonlyArray<string>, expected: ReadonlyArray<FourSlashInterface.ExpectedCompletionEntry>, options?: FourSlashInterface.CompletionsAtOptions) {
this.verifyCompletions({ at: markerName, are: expected, isNewIdentifierLocation: options && options.isNewIdentifierLocation, preferences: options, triggerCharacter: options && options.triggerCharacter });
this.verifyCompletions({ marker: markerName, exact: expected, isNewIdentifierLocation: options && options.isNewIdentifierLocation, preferences: options, triggerCharacter: options && options.triggerCharacter });
}

public verifyCompletionListContains(entryId: ts.Completions.CompletionEntryIdentifier, text?: string, documentation?: string, kind?: string | { kind?: string, kindModifiers?: string }, spanIndex?: number, hasAction?: boolean, options?: FourSlashInterface.VerifyCompletionListContainsOptions) {
Expand Down Expand Up @@ -1190,7 +1193,7 @@ namespace FourSlash {
}
}

public verifyReferenceGroups(starts: Many<string> | Many<Range>, parts: ReadonlyArray<FourSlashInterface.ReferenceGroup> | undefined): void {
public verifyReferenceGroups(starts: ArrayOrSingle<string> | ArrayOrSingle<Range>, parts: ReadonlyArray<FourSlashInterface.ReferenceGroup> | undefined): void {
interface ReferenceGroupJson {
definition: string | { text: string, range: ts.TextSpan };
references: ts.ReferenceEntry[];
Expand Down Expand Up @@ -1425,7 +1428,7 @@ Actual: ${stringify(fullActual)}`);
}
}

public verifyRenameLocations(startRanges: Many<Range>, options: Range[] | { findInStrings?: boolean, findInComments?: boolean, ranges: Range[] }) {
public verifyRenameLocations(startRanges: ArrayOrSingle<Range>, options: Range[] | { findInStrings?: boolean, findInComments?: boolean, ranges: Range[] }) {
let findInStrings: boolean, findInComments: boolean, ranges: Range[];
if (ts.isArray(options)) {
findInStrings = findInComments = false;
Expand Down Expand Up @@ -3815,7 +3818,7 @@ ${code}
return ts.arrayFrom(set.keys());
}

function toArray<T>(x: Many<T>): ReadonlyArray<T> {
function toArray<T>(x: ArrayOrSingle<T>): ReadonlyArray<T> {
return ts.isArray(x) ? x : [x];
}

Expand Down Expand Up @@ -4763,9 +4766,9 @@ namespace FourSlashInterface {
}

export interface VerifyCompletionsOptions {
readonly at?: Many<string>;
readonly marker?: Many<string>;
readonly isNewIdentifierLocation?: boolean;
readonly are?: Many<ExpectedCompletionEntry>;
readonly exact?: Many<ExpectedCompletionEntry>;
readonly includes?: Many<ExpectedCompletionEntry>;
readonly excludes?: Many<string | { readonly name: string, readonly source: string }>;
readonly preferences: ts.UserPreferences;
Expand Down
4 changes: 2 additions & 2 deletions tests/cases/fourslash/augmentedTypesClass1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
////var r = new c5b();
////r./*2*/

verify.completions({ at: "1", includes: { name: "prototype", text: '(property) c5b.prototype: c5b' } });
verify.completions({ marker: "1", includes: { name: "prototype", text: '(property) c5b.prototype: c5b' } });
edit.insert('y;');
verify.completions({ at: "2", includes: { name: "foo", text: '(method) c5b.foo(): void' } });
verify.completions({ marker: "2", includes: { name: "foo", text: '(method) c5b.foo(): void' } });
8 changes: 4 additions & 4 deletions tests/cases/fourslash/augmentedTypesModule6.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@
////var r2: m3f.I = r;
////r2./*6*/

verify.completions({ at: "1", includes: "I", excludes: "foo" });
verify.completions({ marker: "1", includes: "I", excludes: "foo" });
edit.insert('I;');

verify.completions({ at: "2", includes: "m3f" });
verify.completions({ marker: "2", includes: "m3f" });

goTo.marker('3');
verify.currentSignatureHelpIs('m3f(): m3f');

verify.quickInfoAt("4", "var r: m3f");

verify.completions({ at: "5", includes: "foo" });
verify.completions({ marker: "5", includes: "foo" });
edit.insert('foo(1)');

verify.completions({ at: "6", includes: "foo" });
verify.completions({ marker: "6", includes: "foo" });
edit.insert('foo(');
verify.currentSignatureHelpIs('foo(): void');
4 changes: 2 additions & 2 deletions tests/cases/fourslash/cloduleAsBaseClass2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@
////d./*1*/
////D./*2*/

verify.completions({ at: "1", are: ["foo2", "foo"] });
verify.completions({ marker: "1", exact: ["foo2", "foo"] });
edit.insert('foo()');

verify.completions({ at: "2", includes: ["bar", "bar2", "baz", "x"], excludes: ["foo", "foo2"] });
verify.completions({ marker: "2", includes: ["bar", "bar2", "baz", "x"], excludes: ["foo", "foo2"] });
edit.insert('bar()');

verify.noErrors();
6 changes: 3 additions & 3 deletions tests/cases/fourslash/cloduleTypeOf1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@
//// }
////}

verify.completions({ at: "1", includes: ["f", "foo"] });
verify.completions({ marker: "1", includes: ["f", "foo"] });
edit.insert('foo(1);');

verify.completions({ at: "2", includes: "x" });
verify.completions({ marker: "2", includes: "x" });

verify.quickInfoAt("3", "(local var) r: C<number>");

verify.completions({ at: "4", includes: "x" });
verify.completions({ marker: "4", includes: "x" });
edit.insert('x;');

verify.quickInfoAt("5", "(local var) r2: number");
Expand Down
6 changes: 3 additions & 3 deletions tests/cases/fourslash/commentsEnums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ verify.quickInfos({
});

verify.completions({
at: "5",
marker: "5",
includes: { name: "Colors", text: "enum Colors", documentation: "Enum of colors" },
isNewIdentifierLocation: true,
});
Expand All @@ -28,8 +28,8 @@ const completions = [
{ name: "Cornflower", text: "(enum member) Colors.Cornflower = 0", documentation: "Fancy name for 'blue'" },
{ name: "FancyPink", text: "(enum member) Colors.FancyPink = 1", documentation: "Fancy name for 'pink'" },
];
verify.completions({ at: "6", includes: completions });
verify.completions({ marker: "6", includes: completions });
verify.quickInfoIs("(enum member) Colors.Cornflower = 0", "Fancy name for 'blue'");

verify.completions({ at: "7", includes: completions });
verify.completions({ marker: "7", includes: completions });
verify.quickInfoIs("(enum member) Colors.FancyPink = 1", "Fancy name for 'pink'");
10 changes: 5 additions & 5 deletions tests/cases/fourslash/commentsImportDeclaration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ verify.quickInfos({
3: ['import extMod = require("./commentsImportDeclaration_file0")', "Import declaration"]
});

verify.completions({ at: "6", are: [{ name: "m1", text: "namespace extMod.m1", documentation: "NamespaceComment" }] });
verify.completions({ marker: "6", exact: [{ name: "m1", text: "namespace extMod.m1", documentation: "NamespaceComment" }] });

verify.completions({
at: "7",
are: [
marker: "7",
exact: [
{ name: "fooExport", text: "function extMod.m1.fooExport(): number", documentation: "exported function" },
{ name: "b", text: "var extMod.m1.b: number", documentation: "b's comment" },
{ name: "m2", text: "namespace extMod.m1.m2", documentation: "m2 comments" },
Expand All @@ -48,8 +48,8 @@ verify.quickInfos({
});

verify.completions({
at: "10",
are: [
marker: "10",
exact: [
{ name: "c", text: "constructor extMod.m1.m2.c(): extMod.m1.m2.c" },
{ name: "i", text: "var extMod.m1.m2.i: extMod.m1.m2.c", documentation: "i" },
],
Expand Down
12 changes: 6 additions & 6 deletions tests/cases/fourslash/commentsVariables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,18 @@ verify.quickInfoAt("1", "var myVariable: number", "This is my variable");

verify.completions(
{
at: "2",
marker: "2",
includes: { name: "myVariable", text: "var myVariable: number", documentation: "This is my variable" },
},
{
at: "3",
marker: "3",
includes: [
{ name: "myVariable", text: "var myVariable: number", documentation: "This is my variable" },
{ name: "d", text: "var d: number", documentation: "d variable" }
],
},
{
at: "4",
marker: "4",
includes: [
{ name: "foo", text: "function foo(): void", documentation: "foos comment" },
{ name: "fooVar", text: "var fooVar: () => void", documentation:"fooVar comment" },
Expand All @@ -73,7 +73,7 @@ verify.currentSignatureHelpDocCommentIs("fooVar comment");
verify.quickInfoAt("6q", "var fooVar: () => void", "fooVar comment");

verify.completions({
at: "7",
marker: "7",
includes: [
{ name: "foo", text: "function foo(): void", documentation: "foos comment" },
{ name: "fooVar", text: "var fooVar: () => void", documentation:"fooVar comment" },
Expand All @@ -91,8 +91,8 @@ verify.quickInfos({
"9aq": ["var fooVar: () => void", "fooVar comment"]
});

verify.completions({ at: "10", includes: { name: "i", text: "var i: c", documentation: "instance comment" } });
verify.completions({ at: "11", includes: { name: "i1_i", text: "var i1_i: i1", documentation: "interface instance comments" } });
verify.completions({ marker: "10", includes: { name: "i", text: "var i: c", documentation: "instance comment" } });
verify.completions({ marker: "11", includes: { name: "i1_i", text: "var i1_i: i1", documentation: "interface instance comments" } });

verify.quickInfos({
12: ["var fooVar: () => void", "fooVar comment"],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@
// @Filename: dir1/dir2/dir3/node_modules/fake-module3/ts.ts
////

verify.completions({ at: test.markerNames(), are: [], isNewIdentifierLocation: true });
verify.completions({ marker: test.markerNames(), exact: [], isNewIdentifierLocation: true });
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@
const kinds = ["import_as", "import_equals", "require"];
verify.completions(
{
at: kinds.map(k => `${k}0`),
are: "module",
marker: kinds.map(k => `${k}0`),
exact: "module",
isNewIdentifierLocation: true,
},
{
at: kinds.map(k => `${k}1`),
are: "index",
marker: kinds.map(k => `${k}1`),
exact: "index",
isNewIdentifierLocation: true,
},
)
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
//// }

verify.completions({
at: test.markerNames(),
are: ["module", "dev-module", "peer-module", "optional-module"],
marker: test.markerNames(),
exact: ["module", "dev-module", "peer-module", "optional-module"],
isNewIdentifierLocation: true,
});
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
////

verify.completions({
at: test.markerNames(),
are: ["fake-module3", "fake-module2", "fake-module"],
marker: test.markerNames(),
exact: ["fake-module3", "fake-module2", "fake-module"],
isNewIdentifierLocation: true,
});
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@
//// declare module "otherOtherAmbientModule" {}

verify.completions({
at: test.markerNames().filter(k => k.endsWith("0")),
are: ["ambientModule", "otherAmbientModule", "otherOtherAmbientModule"],
marker: test.markerNames().filter(k => k.endsWith("0")),
exact: ["ambientModule", "otherAmbientModule", "otherOtherAmbientModule"],
isNewIdentifierLocation: true,
});
verify.completions({
at: test.markerNames().filter(k => !k.endsWith("0")),
are: "ambientModule",
marker: test.markerNames().filter(k => !k.endsWith("0")),
exact: "ambientModule",
isNewIdentifierLocation: true,
});
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
////

verify.completions({
at: test.markerNames(),
are: ["module", "module-from-node"],
marker: test.markerNames(),
exact: ["module", "module-from-node"],
isNewIdentifierLocation: true,
});
Loading