Work around inconsistent recursive directory watch events (#59328)

This commit is contained in:
Ron Buckton
2024-07-17 16:51:44 -04:00
committed by GitHub
parent e13ff2f26f
commit e7e813542a

View File

@@ -89,6 +89,7 @@ describe("unittests:: sys:: symlinkWatching::", () => {
event: "rename" | "change" | readonly ["rename", "change"]; // Its expected event name or any of the event names
// eslint-disable-next-line no-restricted-syntax
fileName: string | null | undefined;
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)
}
type FsWatch<System extends ts.System> = (dir: string, recursive: boolean, cb: ts.FsWatchCallback, sys: System) => ts.FileWatcher;
interface WatchDirectoryResult {
@@ -156,18 +157,39 @@ describe("unittests:: sys:: symlinkWatching::", () => {
actual: readonly EventAndFileName[],
expected: readonly ExpectedEventAndFileName[] | undefined,
) {
assert(actual.length >= (expected?.length ?? 0), `${prefix}:: Expected ${JSON.stringify(expected)} events, got ${JSON.stringify(actual)}`);
const maxExpected = expected?.length ?? 0;
const minExpected = expected?.reduce((m, e) => e.optional ? m : m + 1, 0) ?? maxExpected;
const sortedActual = ts.sortAndDeduplicate(actual, compareEventAndFileName);
assert(sortedActual.length >= minExpected && sortedActual.length <= maxExpected, `${prefix}:: Expected ${JSON.stringify(expected)} events, got ${JSON.stringify(actual)}`);
let actualIndex = 0;
let expectedIndex = 0;
for (const a of sortedActual) {
if (isExpectedEventAndFileName(a, expected![expectedIndex])) {
while (actualIndex < sortedActual.length && expectedIndex < maxExpected) {
const a = sortedActual[actualIndex];
const e = expected![expectedIndex];
if (isExpectedEventAndFileName(a, e)) {
actualIndex++;
expectedIndex++;
continue;
}
if (e.optional) {
expectedIndex++;
continue;
}
break;
}
if (actualIndex < sortedActual.length) {
ts.Debug.fail(`${prefix}:: Expected ${JSON.stringify(expected)} events, got ${JSON.stringify(actual)} Sorted: ${JSON.stringify(sortedActual)}`);
}
assert(expectedIndex >= (expected?.length ?? 0), `${prefix}:: Should get all events: Expected ${JSON.stringify(expected)} events, got ${JSON.stringify(actual)} Sorted: ${JSON.stringify(sortedActual)}`);
while (expectedIndex < maxExpected) {
const e = expected![expectedIndex];
if (e.optional) {
expectedIndex++;
continue;
}
break;
}
assert(expectedIndex >= maxExpected, `${prefix}:: Should get all events: Expected ${JSON.stringify(expected)} events, got ${JSON.stringify(actual)} Sorted: ${JSON.stringify(sortedActual)}`);
}
function isExpectedEventAndFileName(actual: EventAndFileName, expected: ExpectedEventAndFileName | undefined) {
@@ -444,6 +466,7 @@ describe("unittests:: sys:: symlinkWatching::", () => {
],
linkFileDelete: [
{ event: "rename", fileName: "sub/folder/file2.ts" },
{ event: "change", fileName: "sub/folder", optional: osFlavor === TestServerHostOsFlavor.Windows },
],
linkSubFileCreate: [