webpack/test/WatchSuspend.test.js

184 lines
4.5 KiB
JavaScript
Raw Normal View History

2019-06-01 01:05:10 +08:00
"use strict";
require("./helpers/warmup-webpack");
2019-06-01 01:05:10 +08:00
const fs = require("fs");
2025-07-03 17:06:45 +08:00
const path = require("path");
2019-06-01 01:05:10 +08:00
describe("WatchSuspend", () => {
if (process.env.NO_WATCH_TESTS) {
2024-06-11 20:32:02 +08:00
// eslint-disable-next-line jest/no-disabled-tests
2019-06-01 01:05:10 +08:00
it.skip("long running tests excluded", () => {});
2019-06-01 01:05:10 +08:00
return;
}
jest.setTimeout(5000);
2019-06-03 23:49:22 +08:00
describe("suspend and resume watcher", () => {
2019-06-01 01:05:10 +08:00
const fixturePath = path.join(
__dirname,
"fixtures",
2024-07-31 10:39:30 +08:00
`temp-watch-${Date.now()}`
2019-06-01 01:05:10 +08:00
);
const filePath = path.join(fixturePath, "file.js");
const file2Path = path.join(fixturePath, "file2.js");
const file3Path = path.join(fixturePath, "file3.js");
2021-06-01 00:22:09 +08:00
const outputPath = path.join(__dirname, "js/WatchSuspend");
const outputFile = path.join(outputPath, "bundle.js");
2019-06-01 01:05:10 +08:00
let compiler = null;
let watching = null;
2019-06-03 23:49:22 +08:00
let onChange = null;
2019-06-01 01:05:10 +08:00
beforeAll(() => {
try {
fs.mkdirSync(fixturePath);
2024-07-31 15:37:05 +08:00
} catch (_err) {
2019-06-01 01:05:10 +08:00
// skip
}
try {
fs.writeFileSync(filePath, "'foo'", "utf8");
fs.writeFileSync(file2Path, "'file2'", "utf8");
fs.writeFileSync(file3Path, "'file3'", "utf8");
2024-07-31 15:37:05 +08:00
} catch (_err) {
2019-06-01 01:05:10 +08:00
// skip
}
const webpack = require("../");
2019-06-01 01:05:10 +08:00
compiler = webpack({
mode: "development",
entry: filePath,
output: {
2021-06-01 00:22:09 +08:00
path: outputPath,
2019-06-01 01:05:10 +08:00
filename: "bundle.js"
}
});
2019-06-03 23:49:22 +08:00
watching = compiler.watch({ aggregateTimeout: 50 }, () => {});
2019-06-03 23:49:22 +08:00
compiler.hooks.done.tap("WatchSuspendTest", () => {
if (onChange) onChange();
2019-06-01 01:05:10 +08:00
});
});
2019-06-03 23:49:22 +08:00
afterAll(() => {
watching.close();
compiler = null;
try {
fs.unlinkSync(filePath);
2024-07-31 15:37:05 +08:00
} catch (_err) {
2019-06-03 23:49:22 +08:00
// skip
}
try {
fs.rmdirSync(fixturePath);
2024-07-31 15:37:05 +08:00
} catch (_err) {
2019-06-03 23:49:22 +08:00
// skip
}
});
it("should compile successfully", done => {
onChange = () => {
expect(fs.readFileSync(outputFile, "utf8")).toContain("'foo'");
2019-06-03 23:49:22 +08:00
onChange = null;
done();
};
});
2019-06-01 01:05:10 +08:00
it("should suspend compilation", done => {
2019-06-03 23:49:22 +08:00
onChange = jest.fn();
2019-06-01 01:05:10 +08:00
watching.suspend();
fs.writeFileSync(filePath, "'bar'", "utf8");
2019-06-01 01:05:10 +08:00
setTimeout(() => {
expect(onChange.mock.calls).toHaveLength(0);
2019-06-03 23:49:22 +08:00
onChange = null;
2019-06-01 01:05:10 +08:00
done();
2019-06-03 23:49:22 +08:00
}, 1000);
2019-06-01 01:05:10 +08:00
});
it("should resume compilation", done => {
2019-06-03 23:49:22 +08:00
onChange = () => {
expect(fs.readFileSync(outputFile, "utf8")).toContain("'bar'");
2019-06-03 23:49:22 +08:00
onChange = null;
2019-06-01 01:05:10 +08:00
done();
2019-06-03 23:49:22 +08:00
};
2019-06-01 01:05:10 +08:00
watching.resume();
});
for (const changeBefore of [false, true]) {
2021-05-18 19:25:27 +08:00
for (const delay of [200, 1500]) {
2024-07-31 13:38:50 +08:00
// eslint-disable-next-line no-loop-func
2021-05-18 19:25:27 +08:00
it(`should not ignore changes during resumed compilation (changeBefore: ${changeBefore}, delay: ${delay}ms)`, async () => {
// aggregateTimeout must be long enough for this test
// So set-up new watcher and wait when initial compilation is done
await new Promise(resolve => {
watching.close(() => {
watching = compiler.watch({ aggregateTimeout: 1000 }, () => {
resolve();
});
});
});
return new Promise(resolve => {
if (changeBefore) fs.writeFileSync(filePath, "'bar'", "utf8");
2021-05-18 19:25:27 +08:00
setTimeout(() => {
watching.suspend();
fs.writeFileSync(filePath, "'baz'", "utf8");
2021-05-18 19:25:27 +08:00
onChange = "throw";
setTimeout(() => {
onChange = () => {
expect(fs.readFileSync(outputFile, "utf8")).toContain(
2021-05-18 19:25:27 +08:00
"'baz'"
);
expect(
2025-07-03 17:06:45 +08:00
compiler.modifiedFiles && [...compiler.modifiedFiles].sort()
2021-05-18 19:25:27 +08:00
).toEqual([filePath]);
expect(
2025-07-03 17:06:45 +08:00
compiler.removedFiles && [...compiler.removedFiles]
2021-05-18 19:25:27 +08:00
).toEqual([]);
onChange = null;
resolve();
};
watching.resume();
}, delay);
}, 200);
});
});
}
}
it("should not drop changes when suspended", done => {
const aggregateTimeout = 50;
// Trigger initial compilation with file2.js (assuming correct)
fs.writeFileSync(
filePath,
'require("./file2.js"); require("./file3.js")',
"utf8"
);
onChange = () => {
// Initial compilation is done, start the test
watching.suspend();
// Trigger the first change (works as expected):
fs.writeFileSync(file2Path, "'foo'", "utf8");
// Trigger the second change _after_ aggregation timeout of the first
setTimeout(() => {
fs.writeFileSync(file3Path, "'bar'", "utf8");
// Wait when the file3 edit is settled and re-compile
setTimeout(() => {
watching.resume();
onChange = () => {
onChange = null;
expect(fs.readFileSync(outputFile, "utf8")).toContain("'bar'");
done();
};
}, 200);
}, aggregateTimeout + 50);
};
});
2019-06-01 01:05:10 +08:00
});
});