Skip to content

Commit e7e8135

Browse files
authored
Work around inconsistent recursive directory watch events (#59328)
1 parent e13ff2f commit e7e8135

File tree

1 file changed

+27
-4
lines changed

1 file changed

+27
-4
lines changed

src/testRunner/unittests/sys/symlinkWatching.ts

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ describe("unittests:: sys:: symlinkWatching::", () => {
8989
event: "rename" | "change" | readonly ["rename", "change"]; // Its expected event name or any of the event names
9090
// eslint-disable-next-line no-restricted-syntax
9191
fileName: string | null | undefined;
92+
optional?: boolean; // This event is optional and may or may not be triggered on a given OS (see https://github.com/nodejs/node/issues/53903)
9293
}
9394
type FsWatch<System extends ts.System> = (dir: string, recursive: boolean, cb: ts.FsWatchCallback, sys: System) => ts.FileWatcher;
9495
interface WatchDirectoryResult {
@@ -156,18 +157,39 @@ describe("unittests:: sys:: symlinkWatching::", () => {
156157
actual: readonly EventAndFileName[],
157158
expected: readonly ExpectedEventAndFileName[] | undefined,
158159
) {
159-
assert(actual.length >= (expected?.length ?? 0), `${prefix}:: Expected ${JSON.stringify(expected)} events, got ${JSON.stringify(actual)}`);
160+
const maxExpected = expected?.length ?? 0;
161+
const minExpected = expected?.reduce((m, e) => e.optional ? m : m + 1, 0) ?? maxExpected;
160162
const sortedActual = ts.sortAndDeduplicate(actual, compareEventAndFileName);
163+
assert(sortedActual.length >= minExpected && sortedActual.length <= maxExpected, `${prefix}:: Expected ${JSON.stringify(expected)} events, got ${JSON.stringify(actual)}`);
161164

165+
let actualIndex = 0;
162166
let expectedIndex = 0;
163-
for (const a of sortedActual) {
164-
if (isExpectedEventAndFileName(a, expected![expectedIndex])) {
167+
while (actualIndex < sortedActual.length && expectedIndex < maxExpected) {
168+
const a = sortedActual[actualIndex];
169+
const e = expected![expectedIndex];
170+
if (isExpectedEventAndFileName(a, e)) {
171+
actualIndex++;
165172
expectedIndex++;
166173
continue;
167174
}
175+
if (e.optional) {
176+
expectedIndex++;
177+
continue;
178+
}
179+
break;
180+
}
181+
if (actualIndex < sortedActual.length) {
168182
ts.Debug.fail(`${prefix}:: Expected ${JSON.stringify(expected)} events, got ${JSON.stringify(actual)} Sorted: ${JSON.stringify(sortedActual)}`);
169183
}
170-
assert(expectedIndex >= (expected?.length ?? 0), `${prefix}:: Should get all events: Expected ${JSON.stringify(expected)} events, got ${JSON.stringify(actual)} Sorted: ${JSON.stringify(sortedActual)}`);
184+
while (expectedIndex < maxExpected) {
185+
const e = expected![expectedIndex];
186+
if (e.optional) {
187+
expectedIndex++;
188+
continue;
189+
}
190+
break;
191+
}
192+
assert(expectedIndex >= maxExpected, `${prefix}:: Should get all events: Expected ${JSON.stringify(expected)} events, got ${JSON.stringify(actual)} Sorted: ${JSON.stringify(sortedActual)}`);
171193
}
172194

173195
function isExpectedEventAndFileName(actual: EventAndFileName, expected: ExpectedEventAndFileName | undefined) {
@@ -444,6 +466,7 @@ describe("unittests:: sys:: symlinkWatching::", () => {
444466
],
445467
linkFileDelete: [
446468
{ event: "rename", fileName: "sub/folder/file2.ts" },
469+
{ event: "change", fileName: "sub/folder", optional: osFlavor === TestServerHostOsFlavor.Windows },
447470
],
448471

449472
linkSubFileCreate: [

0 commit comments

Comments
 (0)