|
1 | 1 | import * as assert from "assert"; |
2 | 2 | import { before } from "mocha"; |
| 3 | +import * as path from "path"; |
3 | 4 |
|
4 | 5 | // You can import and use all API from the 'vscode' module |
5 | 6 | // as well as import your extension to test it |
6 | | -import { window, extensions } from "vscode"; |
7 | | -import { extensionId, smExtensionId } from "../../extension"; |
| 7 | +import * as vscode from "vscode"; |
| 8 | +import { extensionId, smExtensionId, OBJECTSCRIPT_FILE_SCHEMA } from "../../extension"; |
| 9 | +import { getUrisForDocument } from "../../utils/documentIndex"; |
| 10 | + |
| 11 | +async function waitForIndexedDocument(documentName: string, workspaceFolderName: string): Promise<void> { |
| 12 | + const workspaceFolder = vscode.workspace.workspaceFolders?.find((wf) => wf.name === workspaceFolderName); |
| 13 | + assert.ok(workspaceFolder, `Workspace folder '${workspaceFolderName}' was not found.`); |
| 14 | + const start = Date.now(); |
| 15 | + while (Date.now() - start < 10000) { |
| 16 | + if (getUrisForDocument(documentName, workspaceFolder).length > 0) { |
| 17 | + return; |
| 18 | + } |
| 19 | + await new Promise((resolve) => setTimeout(resolve, 100)); |
| 20 | + } |
| 21 | + assert.fail(`Timed out waiting for '${documentName}' to be indexed in workspace folder '${workspaceFolderName}'.`); |
| 22 | +} |
| 23 | + |
| 24 | +function getDefinitionTargets(definitions: (vscode.Location | vscode.DefinitionLink)[]): vscode.Uri[] { |
| 25 | + return definitions |
| 26 | + .map((definition) => ("targetUri" in definition ? definition.targetUri : definition.uri)) |
| 27 | + .filter((uri): uri is vscode.Uri => !!uri); |
| 28 | +} |
8 | 29 |
|
9 | 30 | suite("Extension Test Suite", () => { |
10 | 31 | suiteSetup(async function () { |
11 | 32 | // make sure extension is activated |
12 | | - const serverManager = extensions.getExtension(smExtensionId); |
| 33 | + const serverManager = vscode.extensions.getExtension(smExtensionId); |
13 | 34 | await serverManager?.activate(); |
14 | | - const ext = extensions.getExtension(extensionId); |
| 35 | + const ext = vscode.extensions.getExtension(extensionId); |
15 | 36 | await ext?.activate(); |
16 | 37 | }); |
17 | 38 |
|
18 | 39 | before(() => { |
19 | | - window.showInformationMessage("Start all tests."); |
| 40 | + vscode.window.showInformationMessage("Start all tests."); |
20 | 41 | }); |
21 | 42 |
|
22 | 43 | test("Sample test", () => { |
23 | 44 | assert.ok("All good"); |
24 | 45 | }); |
| 46 | + |
| 47 | + test("Go to Definition resolves to sibling workspace folder", async function () { |
| 48 | + this.timeout(10000); |
| 49 | + await waitForIndexedDocument("MultiRoot.Shared.cls", "shared"); |
| 50 | + const clientFolder = vscode.workspace.workspaceFolders?.find((wf) => wf.name === "client"); |
| 51 | + assert.ok(clientFolder, "Client workspace folder not available."); |
| 52 | + const callerUri = vscode.Uri.joinPath(clientFolder.uri, "src", "MultiRoot", "Caller.cls"); |
| 53 | + const document = await vscode.workspace.openTextDocument(callerUri); |
| 54 | + await vscode.window.showTextDocument(document); |
| 55 | + |
| 56 | + const target = "MultiRoot.Shared"; |
| 57 | + const sharedOffset = document.getText().indexOf(target); |
| 58 | + assert.notStrictEqual(sharedOffset, -1, "Shared class reference not found in Caller.cls"); |
| 59 | + const position = document.positionAt(sharedOffset + target.indexOf("Shared") + 1); |
| 60 | + const definitions = (await vscode.commands.executeCommand( |
| 61 | + "vscode.executeDefinitionProvider", |
| 62 | + callerUri, |
| 63 | + position |
| 64 | + )) as (vscode.Location | vscode.DefinitionLink)[]; |
| 65 | + assert.ok(definitions?.length, "Expected at least one definition result"); |
| 66 | + const targetUris = getDefinitionTargets(definitions); |
| 67 | + const sharedTargetSuffix = path.join("shared", "src", "MultiRoot", "Shared.cls"); |
| 68 | + assert.ok( |
| 69 | + targetUris.some((uri) => uri.scheme === "file" && uri.fsPath.endsWith(sharedTargetSuffix)), |
| 70 | + "Expected Go to Definition to resolve to the shared workspace folder" |
| 71 | + ); |
| 72 | + }); |
| 73 | + |
| 74 | + test("Go to Definition falls back to server URI when local copy missing", async function () { |
| 75 | + this.timeout(10000); |
| 76 | + await waitForIndexedDocument("MultiRoot.Shared.cls", "shared"); |
| 77 | + const clientFolder = vscode.workspace.workspaceFolders?.find((wf) => wf.name === "client"); |
| 78 | + assert.ok(clientFolder, "Client workspace folder not available."); |
| 79 | + const callerUri = vscode.Uri.joinPath(clientFolder.uri, "src", "MultiRoot", "Caller.cls"); |
| 80 | + const document = await vscode.workspace.openTextDocument(callerUri); |
| 81 | + await vscode.window.showTextDocument(document); |
| 82 | + |
| 83 | + const target = "MultiRoot.ServerOnly"; |
| 84 | + const offset = document.getText().indexOf(target); |
| 85 | + assert.notStrictEqual(offset, -1, "Server-only class reference not found in Caller.cls"); |
| 86 | + const position = document.positionAt(offset + target.indexOf("ServerOnly") + 1); |
| 87 | + const definitions = (await vscode.commands.executeCommand( |
| 88 | + "vscode.executeDefinitionProvider", |
| 89 | + callerUri, |
| 90 | + position |
| 91 | + )) as (vscode.Location | vscode.DefinitionLink)[]; |
| 92 | + assert.ok(definitions?.length, "Expected definition result when resolving missing class"); |
| 93 | + const targetUris = getDefinitionTargets(definitions); |
| 94 | + assert.ok( |
| 95 | + targetUris.some((uri) => uri.scheme === OBJECTSCRIPT_FILE_SCHEMA), |
| 96 | + "Expected Go to Definition to return a server URI when no local copy exists" |
| 97 | + ); |
| 98 | + }); |
25 | 99 | }); |
0 commit comments