Skip to content

Commit f90257c

Browse files
committed
Better smoke test
1 parent d5da10b commit f90257c

1 file changed

Lines changed: 87 additions & 1 deletion

File tree

lib/test/smoke.test.ts

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import * as Path from 'path';
55
import * as vscode from 'vscode';
66

77
suite('Extension Smoke', () => {
8-
test('activates and publishes diagnostics for Java files', async () => {
8+
test('activates, resolves definitions, and publishes diagnostics for Java files', async () => {
99
const extension = vscode.extensions.getExtension('georgewfraser.vscode-javac');
1010
assert.ok(extension, 'Extension georgewfraser.vscode-javac was not found');
1111

@@ -28,9 +28,67 @@ suite('Extension Smoke', () => {
2828
diagnostics.some(d => d.severity === vscode.DiagnosticSeverity.Error),
2929
`Expected an error diagnostic for HelloError.java, got: ${messages || '<none>'}`
3030
);
31+
32+
const definitionUri = vscode.Uri.file(Path.join(folders[0].uri.fsPath, 'GotoDefinition.java'));
33+
const definitionDocument = await vscode.workspace.openTextDocument(definitionUri);
34+
const definitionEditor = await vscode.window.showTextDocument(definitionDocument);
35+
36+
const definitionLine = definitionDocument.lineAt(2).text;
37+
const definitionOffset = definitionLine.indexOf('goToHere');
38+
assert.ok(definitionOffset >= 0, 'Expected goToHere call in GotoDefinition.java');
39+
40+
const definitionPosition = new vscode.Position(2, definitionOffset + 2);
41+
definitionEditor.selection = new vscode.Selection(definitionPosition, definitionPosition);
42+
definitionEditor.revealRange(new vscode.Range(definitionPosition, definitionPosition));
43+
44+
const definitions = await waitForDefinitions(definitionUri, definitionPosition, 30000);
45+
const target = definitionTarget(definitions[0]);
46+
const targetDocument = target.uri.toString() === definitionDocument.uri.toString()
47+
? definitionDocument
48+
: await vscode.workspace.openTextDocument(target.uri);
49+
const targetLine = targetDocument.lineAt(target.range.start.line).text;
50+
assert.ok(
51+
targetLine.includes('void goToHere()'),
52+
`Expected definition for goToHere, got line: ${targetLine || '<none>'}`
53+
);
3154
});
3255
});
3356

57+
async function waitForDefinitions(
58+
uri: vscode.Uri,
59+
position: vscode.Position,
60+
timeoutMs: number
61+
): Promise<Array<vscode.Location | vscode.LocationLink>> {
62+
const start = Date.now();
63+
64+
while (Date.now() - start < timeoutMs) {
65+
const definitions = await withTimeout(
66+
vscode.commands.executeCommand<Array<vscode.Location | vscode.LocationLink>>(
67+
'vscode.executeDefinitionProvider',
68+
uri,
69+
position
70+
),
71+
5000,
72+
'Definition request timed out'
73+
);
74+
if ((definitions?.length ?? 0) > 0) {
75+
return definitions ?? [];
76+
}
77+
await delay(250);
78+
}
79+
80+
const definitions = await withTimeout(
81+
vscode.commands.executeCommand<Array<vscode.Location | vscode.LocationLink>>(
82+
'vscode.executeDefinitionProvider',
83+
uri,
84+
position
85+
),
86+
5000,
87+
'Definition request timed out'
88+
);
89+
return definitions ?? [];
90+
}
91+
3492
async function waitForDiagnostics(uri: vscode.Uri, timeoutMs: number): Promise<vscode.Diagnostic[]> {
3593
const start = Date.now();
3694

@@ -45,6 +103,34 @@ async function waitForDiagnostics(uri: vscode.Uri, timeoutMs: number): Promise<v
45103
return vscode.languages.getDiagnostics(uri);
46104
}
47105

106+
function definitionTarget(definition: vscode.Location | vscode.LocationLink): { uri: vscode.Uri; range: vscode.Range } {
107+
if ('targetUri' in definition) {
108+
return {
109+
uri: definition.targetUri,
110+
range: definition.targetRange
111+
};
112+
}
113+
114+
return {
115+
uri: definition.uri,
116+
range: definition.range
117+
};
118+
}
119+
48120
function delay(ms: number): Promise<void> {
49121
return new Promise(resolve => setTimeout(resolve, ms));
50122
}
123+
124+
async function withTimeout<T>(promise: Thenable<T>, timeoutMs: number, message: string): Promise<T> {
125+
let timeoutId: NodeJS.Timeout | undefined;
126+
try {
127+
return await Promise.race([
128+
promise,
129+
new Promise<T>((_, reject) => {
130+
timeoutId = setTimeout(() => reject(new Error(message)), timeoutMs);
131+
})
132+
]);
133+
} finally {
134+
if (timeoutId) clearTimeout(timeoutId);
135+
}
136+
}

0 commit comments

Comments
 (0)