Skip to content

Commit 1697eda

Browse files
authored
Merge pull request #7632 from dibarbet/sg_tests
Add integration test for navigating to source generated file
2 parents 85ab08b + fa877b4 commit 1697eda

File tree

4 files changed

+113
-28
lines changed

4 files changed

+113
-28
lines changed

test/lsptoolshost/integrationTests/gotoDefinition.integration.test.ts

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
activateCSharpExtension,
1111
closeAllEditorsAsync,
1212
findRangeOfString,
13+
navigate,
1314
openFileInWorkspaceAsync,
1415
testIfCSharp,
1516
testIfDevKit,
@@ -286,31 +287,3 @@ describe(`Go To Definition Tests`, () => {
286287
expect(vscode.window.activeTextEditor?.document.uri.path.toLowerCase()).toContain('symbolcache');
287288
});
288289
});
289-
290-
async function navigate(
291-
originalPosition: vscode.Position,
292-
definitionLocations: vscode.Location[],
293-
expectedFileName: string
294-
): Promise<void> {
295-
const windowChanged = new Promise<void>((resolve, _) => {
296-
vscode.window.onDidChangeActiveTextEditor((_e) => {
297-
if (_e?.document.fileName.includes(expectedFileName)) {
298-
resolve();
299-
}
300-
});
301-
});
302-
303-
await vscode.commands.executeCommand(
304-
'editor.action.goToLocations',
305-
vscode.window.activeTextEditor!.document.uri,
306-
originalPosition,
307-
definitionLocations,
308-
'goto',
309-
'Failed to navigate'
310-
);
311-
312-
// Navigation happens asynchronously when a different file is opened, so we need to wait for the window to change.
313-
await windowChanged;
314-
315-
expect(vscode.window.activeTextEditor?.document.fileName).toContain(expectedFileName);
316-
}

test/lsptoolshost/integrationTests/integrationHelpers.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,34 @@ export async function getCodeLensesAsync(): Promise<vscode.CodeLens[]> {
135135
});
136136
}
137137

138+
export async function navigate(
139+
originalPosition: vscode.Position,
140+
definitionLocations: vscode.Location[],
141+
expectedFileName: string
142+
): Promise<void> {
143+
const windowChanged = new Promise<void>((resolve, _) => {
144+
vscode.window.onDidChangeActiveTextEditor((_e) => {
145+
if (_e?.document.fileName.includes(expectedFileName)) {
146+
resolve();
147+
}
148+
});
149+
});
150+
151+
await vscode.commands.executeCommand(
152+
'editor.action.goToLocations',
153+
vscode.window.activeTextEditor!.document.uri,
154+
originalPosition,
155+
definitionLocations,
156+
'goto',
157+
'Failed to navigate'
158+
);
159+
160+
// Navigation happens asynchronously when a different file is opened, so we need to wait for the window to change.
161+
await windowChanged;
162+
163+
expect(vscode.window.activeTextEditor?.document.fileName).toContain(expectedFileName);
164+
}
165+
138166
export function sortLocations(locations: vscode.Location[]): vscode.Location[] {
139167
return locations.sort((a, b) => {
140168
const uriCompare = a.uri.fsPath.localeCompare(b.uri.fsPath);
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import * as vscode from 'vscode';
7+
import * as path from 'path';
8+
import testAssetWorkspace from './testAssets/testAssetWorkspace';
9+
import {
10+
activateCSharpExtension,
11+
closeAllEditorsAsync,
12+
navigate,
13+
openFileInWorkspaceAsync,
14+
sleep,
15+
sortLocations,
16+
} from './integrationHelpers';
17+
import { beforeAll, beforeEach, afterAll, test, expect, afterEach, describe } from '@jest/globals';
18+
19+
describe(`Source Generator Tests`, () => {
20+
beforeAll(async () => {
21+
await activateCSharpExtension();
22+
});
23+
24+
beforeEach(async () => {
25+
await openFileInWorkspaceAsync(path.join('src', 'app', 'SourceGenerator.cs'));
26+
27+
// Unfortunately, due to the way source generators work we will not necessarily have the source generated files
28+
// as soon as the project finishes loading. It may be using a partial compilation which has not run generators yet.
29+
// So we have to wait here for a bit to ensure the source generated files are available.
30+
// Once we have enabled balanced mode in the extension, we will have an explicit command to run generators which
31+
// we can use here to force the generation instead of waiting.
32+
// See https://github.com/dotnet/roslyn/issues/75152
33+
await sleep(5000);
34+
});
35+
36+
afterAll(async () => {
37+
await testAssetWorkspace.cleanupWorkspace();
38+
});
39+
40+
afterEach(async () => {
41+
await closeAllEditorsAsync();
42+
});
43+
44+
test('Navigates to reference in source generated file', async () => {
45+
const requestPosition = new vscode.Position(14, 25);
46+
const referencesList = <vscode.Location[]>(
47+
await vscode.commands.executeCommand(
48+
'vscode.executeReferenceProvider',
49+
vscode.window.activeTextEditor!.document.uri,
50+
requestPosition
51+
)
52+
);
53+
expect(referencesList.length).toEqual(8);
54+
const referencesInGeneratedFiles = sortLocations(
55+
referencesList.filter((r) => r.uri.scheme === 'roslyn-source-generated')
56+
);
57+
expect(referencesInGeneratedFiles.length).toEqual(7);
58+
const firstPath = referencesInGeneratedFiles[0].uri.path;
59+
expect(firstPath).toEqual('/SourceGenerationContext.g.cs');
60+
61+
await navigate(requestPosition, referencesInGeneratedFiles, 'SourceGenerationContext.g.cs');
62+
expect(vscode.window.activeTextEditor?.document.getText()).toContain('// <auto-generated/>');
63+
expect(vscode.window.activeTextEditor?.document.getText()).toContain(
64+
'internal partial class SourceGenerationContext'
65+
);
66+
});
67+
});
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System;
2+
using System.Text.Json.Serialization;
3+
4+
namespace SourceGeneration;
5+
6+
public class WeatherForecast
7+
{
8+
public DateTime Date { get; set; }
9+
public int TemperatureCelsius { get; set; }
10+
public string Summary { get; set; }
11+
}
12+
13+
[JsonSourceGenerationOptions(WriteIndented = true)]
14+
[JsonSerializable(typeof(WeatherForecast))]
15+
internal partial class SourceGenerationContext : JsonSerializerContext
16+
{
17+
}

0 commit comments

Comments
 (0)