| 
									
										
										
										
											2019-06-01 01:05:10 +08:00
										 |  |  | "use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-15 20:51:52 +08:00
										 |  |  | 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", () => {}); | 
					
						
							| 
									
										
										
										
											2025-07-02 20:10:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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"); | 
					
						
							| 
									
										
										
										
											2021-05-17 22:36:11 +08:00
										 |  |  | 		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 { | 
					
						
							| 
									
										
										
										
											2025-07-02 20:10:54 +08:00
										 |  |  | 				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
 | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2025-07-02 20:10:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-15 20:51:52 +08:00
										 |  |  | 			const webpack = require("../"); | 
					
						
							| 
									
										
										
										
											2025-07-02 20:10:54 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 }, () => {}); | 
					
						
							| 
									
										
										
										
											2021-05-17 22:36:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
 | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-17 00:13:14 +08:00
										 |  |  | 		it("should compile successfully", (done) => { | 
					
						
							| 
									
										
										
										
											2019-06-03 23:49:22 +08:00
										 |  |  | 			onChange = () => { | 
					
						
							| 
									
										
										
										
											2025-07-02 20:10:54 +08:00
										 |  |  | 				expect(fs.readFileSync(outputFile, "utf8")).toContain("'foo'"); | 
					
						
							| 
									
										
										
										
											2019-06-03 23:49:22 +08:00
										 |  |  | 				onChange = null; | 
					
						
							|  |  |  | 				done(); | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-17 00:13:14 +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(); | 
					
						
							| 
									
										
										
										
											2025-07-02 20:10:54 +08:00
										 |  |  | 			fs.writeFileSync(filePath, "'bar'", "utf8"); | 
					
						
							| 
									
										
										
										
											2019-06-01 01:05:10 +08:00
										 |  |  | 			setTimeout(() => { | 
					
						
							| 
									
										
										
										
											2025-07-02 20:10:54 +08:00
										 |  |  | 				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
										 |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-17 00:13:14 +08:00
										 |  |  | 		it("should resume compilation", (done) => { | 
					
						
							| 
									
										
										
										
											2019-06-03 23:49:22 +08:00
										 |  |  | 			onChange = () => { | 
					
						
							| 
									
										
										
										
											2025-07-02 20:10:54 +08:00
										 |  |  | 				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(); | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2021-05-17 22:36:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-02 20:10:54 +08:00
										 |  |  | 		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
 | 
					
						
							| 
									
										
										
										
											2025-07-17 00:13:14 +08:00
										 |  |  | 					await new Promise((resolve) => { | 
					
						
							| 
									
										
										
										
											2021-05-18 19:25:27 +08:00
										 |  |  | 						watching.close(() => { | 
					
						
							|  |  |  | 							watching = compiler.watch({ aggregateTimeout: 1000 }, () => { | 
					
						
							|  |  |  | 								resolve(); | 
					
						
							|  |  |  | 							}); | 
					
						
							|  |  |  | 						}); | 
					
						
							|  |  |  | 					}); | 
					
						
							| 
									
										
										
										
											2025-07-17 00:13:14 +08:00
										 |  |  | 					return new Promise((resolve) => { | 
					
						
							| 
									
										
										
										
											2025-07-02 20:10:54 +08:00
										 |  |  | 						if (changeBefore) fs.writeFileSync(filePath, "'bar'", "utf8"); | 
					
						
							| 
									
										
										
										
											2021-05-18 19:25:27 +08:00
										 |  |  | 						setTimeout(() => { | 
					
						
							|  |  |  | 							watching.suspend(); | 
					
						
							| 
									
										
										
										
											2025-07-02 20:10:54 +08:00
										 |  |  | 							fs.writeFileSync(filePath, "'baz'", "utf8"); | 
					
						
							| 
									
										
										
										
											2021-05-18 19:25:27 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 							onChange = "throw"; | 
					
						
							|  |  |  | 							setTimeout(() => { | 
					
						
							|  |  |  | 								onChange = () => { | 
					
						
							| 
									
										
										
										
											2025-07-02 20:10:54 +08:00
										 |  |  | 									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); | 
					
						
							|  |  |  | 					}); | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2025-07-02 20:10:54 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2021-05-17 22:36:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-17 00:13:14 +08:00
										 |  |  | 		it("should not drop changes when suspended", (done) => { | 
					
						
							| 
									
										
										
										
											2021-05-17 22:36:11 +08:00
										 |  |  | 			const aggregateTimeout = 50; | 
					
						
							|  |  |  | 			// Trigger initial compilation with file2.js (assuming correct)
 | 
					
						
							|  |  |  | 			fs.writeFileSync( | 
					
						
							|  |  |  | 				filePath, | 
					
						
							|  |  |  | 				'require("./file2.js"); require("./file3.js")', | 
					
						
							| 
									
										
										
										
											2025-07-02 20:10:54 +08:00
										 |  |  | 				"utf8" | 
					
						
							| 
									
										
										
										
											2021-05-17 22:36:11 +08:00
										 |  |  | 			); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			onChange = () => { | 
					
						
							|  |  |  | 				// Initial compilation is done, start the test
 | 
					
						
							|  |  |  | 				watching.suspend(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// Trigger the first change (works as expected):
 | 
					
						
							| 
									
										
										
										
											2025-07-02 20:10:54 +08:00
										 |  |  | 				fs.writeFileSync(file2Path, "'foo'", "utf8"); | 
					
						
							| 
									
										
										
										
											2021-05-17 22:36:11 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				// Trigger the second change _after_ aggregation timeout of the first
 | 
					
						
							|  |  |  | 				setTimeout(() => { | 
					
						
							| 
									
										
										
										
											2025-07-02 20:10:54 +08:00
										 |  |  | 					fs.writeFileSync(file3Path, "'bar'", "utf8"); | 
					
						
							| 
									
										
										
										
											2021-05-17 22:36:11 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					// Wait when the file3 edit is settled and re-compile
 | 
					
						
							|  |  |  | 					setTimeout(() => { | 
					
						
							|  |  |  | 						watching.resume(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						onChange = () => { | 
					
						
							|  |  |  | 							onChange = null; | 
					
						
							| 
									
										
										
										
											2025-07-02 20:10:54 +08:00
										 |  |  | 							expect(fs.readFileSync(outputFile, "utf8")).toContain("'bar'"); | 
					
						
							| 
									
										
										
										
											2021-05-17 22:36:11 +08:00
										 |  |  | 							done(); | 
					
						
							|  |  |  | 						}; | 
					
						
							|  |  |  | 					}, 200); | 
					
						
							|  |  |  | 				}, aggregateTimeout + 50); | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 		}); | 
					
						
							| 
									
										
										
										
											2019-06-01 01:05:10 +08:00
										 |  |  | 	}); | 
					
						
							|  |  |  | }); |