Skip to content

Commit ae8fd30

Browse files
author
Andy
authored
Merge pull request #13546 from Microsoft/test_document_highlights
Update document highlight tests: Use ranges to represent expected highlights
2 parents 381960f + d1fb894 commit ae8fd30

14 files changed

+135
-193
lines changed

src/harness/fourslash.ts

Lines changed: 51 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -859,9 +859,8 @@ namespace FourSlash {
859859
}
860860
}
861861

862-
public verifyReferencesOf({fileName, start}: Range, references: Range[]) {
863-
this.openFile(fileName);
864-
this.goToPosition(start);
862+
public verifyReferencesOf(range: Range, references: Range[]) {
863+
this.goToRangeStart(range);
865864
this.verifyReferencesAre(references);
866865
}
867866

@@ -1669,6 +1668,11 @@ namespace FourSlash {
16691668
this.goToPosition(len);
16701669
}
16711670

1671+
private goToRangeStart({fileName, start}: Range) {
1672+
this.openFile(fileName);
1673+
this.goToPosition(start);
1674+
}
1675+
16721676
public goToTypeDefinition(definitionIndex: number) {
16731677
const definitions = this.languageService.getTypeDefinitionAtPosition(this.activeFile.fileName, this.currentCaretPosition);
16741678
if (!definitions || !definitions.length) {
@@ -2361,40 +2365,45 @@ namespace FourSlash {
23612365
return this.languageService.getDocumentHighlights(this.activeFile.fileName, this.currentCaretPosition, filesToSearch);
23622366
}
23632367

2364-
public verifyDocumentHighlightsAtPositionListContains(fileName: string, start: number, end: number, fileNamesToSearch: string[], kind?: string) {
2365-
const documentHighlights = this.getDocumentHighlightsAtCurrentPosition(fileNamesToSearch);
2368+
public verifyRangesWithSameTextAreDocumentHighlights() {
2369+
this.rangesByText().forEach(ranges => this.verifyRangesAreDocumentHighlights(ranges));
2370+
}
23662371

2367-
if (!documentHighlights || documentHighlights.length === 0) {
2368-
this.raiseError("verifyDocumentHighlightsAtPositionListContains failed - found 0 highlights, expected at least one.");
2372+
public verifyRangesAreDocumentHighlights(ranges?: Range[]) {
2373+
ranges = ranges || this.getRanges();
2374+
const fileNames = unique(ranges, range => range.fileName);
2375+
for (const range of ranges) {
2376+
this.goToRangeStart(range);
2377+
this.verifyDocumentHighlights(ranges, fileNames);
23692378
}
2379+
}
23702380

2371-
for (const documentHighlight of documentHighlights) {
2372-
if (documentHighlight.fileName === fileName) {
2373-
const { highlightSpans } = documentHighlight;
2381+
private verifyDocumentHighlights(expectedRanges: Range[], fileNames: string[] = [this.activeFile.fileName]) {
2382+
const documentHighlights = this.getDocumentHighlightsAtCurrentPosition(fileNames) || [];
23742383

2375-
for (const highlight of highlightSpans) {
2376-
if (highlight && highlight.textSpan.start === start && ts.textSpanEnd(highlight.textSpan) === end) {
2377-
if (typeof kind !== "undefined" && highlight.kind !== kind) {
2378-
this.raiseError(`verifyDocumentHighlightsAtPositionListContains failed - item "kind" value does not match, actual: ${highlight.kind}, expected: ${kind}.`);
2379-
}
2380-
return;
2381-
}
2382-
}
2384+
for (const dh of documentHighlights) {
2385+
if (fileNames.indexOf(dh.fileName) === -1) {
2386+
this.raiseError(`verifyDocumentHighlights failed - got highlights in unexpected file name ${dh.fileName}`);
23832387
}
23842388
}
23852389

2386-
const missingItem = { fileName: fileName, start: start, end: end, kind: kind };
2387-
this.raiseError(`verifyDocumentHighlightsAtPositionListContains failed - could not find the item: ${stringify(missingItem)} in the returned list: (${stringify(documentHighlights)})`);
2388-
}
2390+
for (const fileName of fileNames) {
2391+
const expectedRangesInFile = expectedRanges.filter(r => r.fileName === fileName);
2392+
const highlights = ts.find(documentHighlights, dh => dh.fileName === fileName);
2393+
if (!highlights) {
2394+
this.raiseError(`verifyDocumentHighlights failed - found no highlights in ${fileName}`);
2395+
}
2396+
const spansInFile = highlights.highlightSpans.sort((s1, s2) => s1.textSpan.start - s2.textSpan.start);
23892397

2390-
public verifyDocumentHighlightsAtPositionListCount(expectedCount: number, fileNamesToSearch: string[]) {
2391-
const documentHighlights = this.getDocumentHighlightsAtCurrentPosition(fileNamesToSearch);
2392-
const actualCount = documentHighlights
2393-
? documentHighlights.reduce((currentCount, { highlightSpans }) => currentCount + highlightSpans.length, 0)
2394-
: 0;
2398+
if (expectedRangesInFile.length !== spansInFile.length) {
2399+
this.raiseError(`verifyDocumentHighlights failed - In ${fileName}, expected ${expectedRangesInFile.length} highlights, got ${spansInFile.length}`);
2400+
}
23952401

2396-
if (expectedCount !== actualCount) {
2397-
this.raiseError("verifyDocumentHighlightsAtPositionListCount failed - actual: " + actualCount + ", expected:" + expectedCount);
2402+
ts.zipWith(expectedRangesInFile, spansInFile, (expectedRange, span) => {
2403+
if (span.textSpan.start !== expectedRange.start || ts.textSpanEnd(span.textSpan) !== expectedRange.end) {
2404+
this.raiseError(`verifyDocumentHighlights failed - span does not match, actual: ${JSON.stringify(span.textSpan)}, expected: ${expectedRange.start}--${expectedRange.end}`);
2405+
}
2406+
});
23982407
}
23992408
}
24002409

@@ -3021,6 +3030,16 @@ ${code}
30213030
function stringify(data: any, replacer?: (key: string, value: any) => any): string {
30223031
return JSON.stringify(data, replacer, 2);
30233032
}
3033+
3034+
/** Collects an array of unique outputs. */
3035+
function unique<T>(inputs: T[], getOutput: (t: T) => string): string[] {
3036+
const set = ts.createMap<true>();
3037+
for (const input of inputs) {
3038+
const out = getOutput(input);
3039+
set.set(out, true);
3040+
}
3041+
return ts.arrayFrom(set.keys());
3042+
}
30243043
}
30253044

30263045
namespace FourSlashInterface {
@@ -3413,12 +3432,12 @@ namespace FourSlashInterface {
34133432
this.state.verifyOccurrencesAtPositionListCount(expectedCount);
34143433
}
34153434

3416-
public documentHighlightsAtPositionContains(range: FourSlash.Range, fileNamesToSearch: string[], kind?: string) {
3417-
this.state.verifyDocumentHighlightsAtPositionListContains(range.fileName, range.start, range.end, fileNamesToSearch, kind);
3435+
public rangesAreDocumentHighlights(ranges?: FourSlash.Range[]) {
3436+
this.state.verifyRangesAreDocumentHighlights(ranges);
34183437
}
34193438

3420-
public documentHighlightsAtPositionCount(expectedCount: number, fileNamesToSearch: string[]) {
3421-
this.state.verifyDocumentHighlightsAtPositionListCount(expectedCount, fileNamesToSearch);
3439+
public rangesWithSameTextAreDocumentHighlights() {
3440+
this.state.verifyRangesWithSameTextAreDocumentHighlights();
34223441
}
34233442

34243443
public completionEntryDetailIs(entryName: string, text: string, documentation?: string, kind?: string) {

tests/cases/fourslash/documentHighlightAtInheritedProperties1.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,8 @@
22

33
// @Filename: file1.ts
44
//// interface interface1 extends interface1 {
5-
//// /*1*/doStuff(): void;
6-
//// /*2*/propName: string;
5+
//// [|doStuff|](): void;
6+
//// [|propName|]: string;
77
//// }
88

9-
let markers = test.markers()
10-
for (let marker of markers) {
11-
goTo.position(marker.position);
12-
verify.documentHighlightsAtPositionCount(1, ["file1.ts"]);
13-
}
9+
verify.rangesWithSameTextAreDocumentHighlights();

tests/cases/fourslash/documentHighlightAtInheritedProperties2.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,8 @@
22

33
// @Filename: file1.ts
44
//// class class1 extends class1 {
5-
//// /*1*/doStuff() { }
6-
//// /*2*/propName: string;
5+
//// [|doStuff|]() { }
6+
//// [|propName|]: string;
77
//// }
88

9-
let markers = test.markers()
10-
for (let marker of markers) {
11-
goTo.position(marker.position);
12-
verify.documentHighlightsAtPositionCount(1, ["file1.ts"]);
13-
}
9+
verify.rangesWithSameTextAreDocumentHighlights();

tests/cases/fourslash/documentHighlightAtInheritedProperties3.ts

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,12 @@
22

33
// @Filename: file1.ts
44
//// interface interface1 extends interface1 {
5-
//// /*1*/doStuff(): void;
6-
//// /*2*/propName: string;
5+
//// [|doStuff|](): void;
6+
//// [|propName|]: string;
77
//// }
88
////
99
//// var v: interface1;
10-
//// v./*3*/propName;
11-
//// v./*4*/doStuff();
10+
//// v.[|propName|];
11+
//// v.[|doStuff|]();
1212

13-
let markers = test.markers()
14-
for (let marker of markers) {
15-
goTo.position(marker.position);
16-
verify.documentHighlightsAtPositionCount(2, ["file1.ts"]);
17-
}
13+
verify.rangesWithSameTextAreDocumentHighlights();

tests/cases/fourslash/documentHighlightAtInheritedProperties4.ts

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,12 @@
22

33
// @Filename: file1.ts
44
//// class class1 extends class1 {
5-
//// /*1*/doStuff() { }
6-
//// /*2*/propName: string;
5+
//// [|doStuff|]() { }
6+
//// [|propName|]: string;
77
//// }
88
////
99
//// var c: class1;
10-
//// c./*3*/doStuff();
11-
//// c./*4*/propName;
10+
//// c.[|doStuff|]();
11+
//// c.[|propName|];
1212

13-
let markers = test.markers()
14-
for (let marker of markers) {
15-
goTo.position(marker.position);
16-
verify.documentHighlightsAtPositionCount(2, ["file1.ts"]);
17-
}
13+
verify.rangesWithSameTextAreDocumentHighlights();

tests/cases/fourslash/documentHighlightAtInheritedProperties5.ts

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,16 @@
22

33
// @Filename: file1.ts
44
//// interface C extends D {
5-
//// /*0*/prop0: string;
6-
//// /*1*/prop1: number;
5+
//// [|prop0|]: string;
6+
//// [|prop1|]: number;
77
//// }
8-
////
8+
////
99
//// interface D extends C {
10-
//// /*2*/prop0: string;
11-
//// /*3*/prop1: number;
10+
//// [|prop0|]: string;
11+
//// [|prop1|]: number;
1212
//// }
13-
////
13+
////
1414
//// var d: D;
15-
//// d./*4*/prop1;
15+
//// d.[|prop1|];
1616

17-
goTo.marker("0");
18-
verify.documentHighlightsAtPositionCount(2, ["file1.ts"]);
19-
20-
goTo.marker("1");
21-
verify.documentHighlightsAtPositionCount(3, ["file1.ts"]);
22-
23-
goTo.marker("2");
24-
verify.documentHighlightsAtPositionCount(2, ["file1.ts"]);
25-
26-
goTo.marker("3");
27-
verify.documentHighlightsAtPositionCount(3, ["file1.ts"]);
28-
29-
goTo.marker("4");
30-
verify.documentHighlightsAtPositionCount(3, ["file1.ts"]);
17+
verify.rangesWithSameTextAreDocumentHighlights();

tests/cases/fourslash/documentHighlightAtInheritedProperties6.ts

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,20 @@
22

33
// @Filename: file1.ts
44
//// class C extends D {
5-
//// /*0*/prop0: string;
6-
//// /*1*/prop1: string;
5+
//// [|prop0|]: string;
6+
//// [|prop1|]: string;
77
//// }
8-
////
8+
////
99
//// class D extends C {
10-
//// /*2*/prop0: string;
11-
//// /*3*/prop1: string;
10+
//// [|prop0|]: string;
11+
//// [|prop1|]: string;
1212
//// }
13-
////
13+
////
1414
//// var d: D;
15-
//// d./*4*/prop1;
15+
//// d.[|prop1|];
1616

17-
goTo.marker("0");
18-
verify.documentHighlightsAtPositionCount(1, ["file1.ts"]);
19-
20-
goTo.marker("1");
21-
verify.documentHighlightsAtPositionCount(1, ["file1.ts"]);
22-
23-
goTo.marker("2");
24-
verify.documentHighlightsAtPositionCount(1, ["file1.ts"]);
25-
26-
goTo.marker("3");
27-
verify.documentHighlightsAtPositionCount(2, ["file1.ts"]);
28-
29-
goTo.marker("4");
30-
verify.documentHighlightsAtPositionCount(2, ["file1.ts"]);
17+
const [Cprop0, Cprop1, Dprop0, Dprop1, prop1Use] = test.ranges();
18+
verify.rangesAreDocumentHighlights([Cprop0]);
19+
verify.rangesAreDocumentHighlights([Dprop0]);
20+
verify.rangesAreDocumentHighlights([Cprop1]);
21+
verify.rangesAreDocumentHighlights([Dprop1, prop1Use]);

tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration1.ts

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,19 @@
22

33
// @Filename: file1.ts
44
//// class Foo {
5-
//// constructor(private /*0*/privateParam: number,
6-
//// public /*1*/publicParam: string,
7-
//// protected /*2*/protectedParam: boolean) {
8-
////
9-
//// let localPrivate = /*3*/privateParam;
10-
//// this./*4*/privateParam += 10;
11-
////
12-
//// let localPublic = /*5*/publicParam;
13-
//// this./*6*/publicParam += " Hello!";
14-
////
15-
//// let localProtected = /*7*/protectedParam;
16-
//// this./*8*/protectedParam = false;
5+
//// constructor(private [|privateParam|]: number,
6+
//// public [|publicParam|]: string,
7+
//// protected [|protectedParam|]: boolean) {
8+
////
9+
//// let localPrivate = [|privateParam|];
10+
//// this.[|privateParam|] += 10;
11+
////
12+
//// let localPublic = [|publicParam|];
13+
//// this.[|publicParam|] += " Hello!";
14+
////
15+
//// let localProtected = [|protectedParam|];
16+
//// this.[|protectedParam|] = false;
1717
//// }
1818
//// }
1919

20-
let markers = test.markers()
21-
for (let marker of markers) {
22-
goTo.position(marker.position);
23-
verify.documentHighlightsAtPositionCount(3, ["file1.ts"]);
24-
}
20+
verify.rangesWithSameTextAreDocumentHighlights();

tests/cases/fourslash/documentHighlightAtParameterPropertyDeclaration2.ts

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,20 @@
22

33
// @Filename: file1.ts
44
//// class Foo {
5-
//// constructor(private {/*0*/privateParam}: number,
6-
//// public {/*1*/publicParam}: string,
7-
//// protected {/*2*/protectedParam}: boolean) {
8-
////
9-
//// let localPrivate = /*3*/privateParam;
10-
//// this.privateParam += 10; // this is not valid syntax
11-
////
12-
//// let localPublic = /*4*/publicParam;
13-
//// this.publicParam += " Hello!"; // this is not valid syntax
14-
////
15-
//// let localProtected = /*5*/protectedParam;
16-
//// this.protectedParam = false; // this is not valid syntax
5+
//// // This is not valid syntax: parameter property can't be binding pattern
6+
//// constructor(private {[|privateParam|]}: number,
7+
//// public {[|publicParam|]}: string,
8+
//// protected {[|protectedParam|]}: boolean) {
9+
////
10+
//// let localPrivate = [|privateParam|];
11+
//// this.privateParam += 10;
12+
////
13+
//// let localPublic = [|publicParam|];
14+
//// this.publicParam += " Hello!";
15+
////
16+
//// let localProtected = [|protectedParam|];
17+
//// this.protectedParam = false;
1718
//// }
1819
//// }
1920

20-
let markers = test.markers()
21-
for (let marker of markers) {
22-
goTo.position(marker.position);
23-
verify.documentHighlightsAtPositionCount(2, ["file1.ts"]);
24-
}
21+
verify.rangesWithSameTextAreDocumentHighlights();

0 commit comments

Comments
 (0)