Skip to content

Commit 7a331c3

Browse files
committed
test(vscode): wait for the file event and folder save the test depends on
An edit made outside the editor reaches the language server only through a VS Code watcher event, which Linux runners occasionally drop. The test now rewrites the file until the extension host reports it, so a missing symbol means a delivered change was not indexed. A workspace configuration update also waits for the folder change to be saved, since VS Code refuses it while the workspace file is dirty. Signed-off-by: Jeremi Joslin <jeremi@joslin.fr>
1 parent 08051d3 commit 7a331c3

1 file changed

Lines changed: 37 additions & 2 deletions

File tree

‎editors/vscode/test/trusted.test.ts‎

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ suite('Registry Stack extension', () => {
140140

141141
const alphaFolder = vscode.workspace.workspaceFolders?.find((folder) => folder.name === 'alpha');
142142
assert.ok(alphaFolder, 'alpha workspace folder is available');
143-
fs.writeFileSync(
143+
await writeWatchedFile(
144144
path.join(alphaFolder.uri.fsPath, 'registry.yaml'),
145145
'apiVersion: id.registrystack.org/formats/breg/project/v1alpha1\nkind: BRegProject\nproject: { id: alpha-reloaded }\n',
146146
);
@@ -271,7 +271,7 @@ suite('Registry Stack extension', () => {
271271
await vscode.workspace.openTextDocument(retiredQuestionPath);
272272
await assertLanguageServerStartCountStable(startLog, 4);
273273

274-
assert.strictEqual(vscode.workspace.updateWorkspaceFolders(3, 3), true);
274+
await changeWorkspaceFolders(3, 3);
275275
await assertWorkspaceFolderCount(3);
276276

277277
// Deleting the installer metadata and restarting proves the PATH
@@ -335,6 +335,9 @@ async function assertWorkspaceFolderCount(expected: number): Promise<void> {
335335
// VS Code requires the workspace-change event to finish before another
336336
// updateWorkspaceFolders call, even when workspaceFolders already has its
337337
// next value. Rapid product add/remove cycles must await that event.
338+
// A workspace-scoped configuration update must also wait: it edits the same
339+
// .code-workspace file, and VS Code refuses it while the folder change is
340+
// still unsaved there.
338341
async function changeWorkspaceFolders(
339342
start: number,
340343
deleteCount: number,
@@ -352,6 +355,38 @@ async function changeWorkspaceFolders(
352355
}
353356
}
354357

358+
// An edit made outside the editor reaches the language server only as a file
359+
// event from VS Code's watcher, which does not guarantee an event for every
360+
// write. Rewrite the file until the extension host reports it, so a later
361+
// symbol assertion fails only when a delivered change was not indexed. A
362+
// string glob adds no watch request of its own and sees the same events as the
363+
// language client's watchers.
364+
async function writeWatchedFile(filePath: string, content: string): Promise<void> {
365+
const watcher = vscode.workspace.createFileSystemWatcher(`**/${path.basename(filePath)}`);
366+
let reported = false;
367+
const onEvent = (uri: vscode.Uri) => {
368+
if (uri.fsPath === filePath) {
369+
reported = true;
370+
}
371+
};
372+
watcher.onDidCreate(onEvent);
373+
watcher.onDidChange(onEvent);
374+
try {
375+
for (let write = 0; write < 3; write += 1) {
376+
fs.writeFileSync(filePath, content);
377+
for (let attempt = 0; attempt < 20; attempt += 1) {
378+
if (reported) {
379+
return;
380+
}
381+
await new Promise((resolve) => setTimeout(resolve, 100));
382+
}
383+
}
384+
assert.fail(`VS Code reported no file event for ${filePath}`);
385+
} finally {
386+
watcher.dispose();
387+
}
388+
}
389+
355390
async function assertWorkspaceSymbol(expected: string, documentPath?: string): Promise<void> {
356391
const expectedPath = documentPath === undefined ? undefined : fs.realpathSync(documentPath);
357392
for (let attempt = 0; attempt < 50; attempt += 1) {

0 commit comments

Comments
 (0)