mirror of https://github.com/webpack/webpack.git
				
				
				
			
		
			
				
	
	
		
			678 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
			
		
		
	
	
			678 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
| "use strict";
 | |
| 
 | |
| const should = require("should");
 | |
| const sinon = require("sinon");
 | |
| const MultiCompiler = require("../lib/MultiCompiler");
 | |
| 
 | |
| function CompilerEnvironment() {
 | |
| 	const pluginEvents = [];
 | |
| 	const runCallbacks = [];
 | |
| 	const watchCallbacks = [];
 | |
| 
 | |
| 	function createFakeHook(name) {
 | |
| 		return {
 | |
| 			tap(_, handler) {
 | |
| 				pluginEvents.push({
 | |
| 					name,
 | |
| 					handler
 | |
| 				});
 | |
| 			}
 | |
| 		};
 | |
| 	}
 | |
| 
 | |
| 	this.getCompilerStub = function() {
 | |
| 		return {
 | |
| 			hooks: {
 | |
| 				done: createFakeHook("done"),
 | |
| 				invalid: createFakeHook("invalid")
 | |
| 			},
 | |
| 			plugin: function(name, handler) {
 | |
| 				pluginEvents.push({
 | |
| 					name,
 | |
| 					handler
 | |
| 				});
 | |
| 			},
 | |
| 			run: function(callback) {
 | |
| 				runCallbacks.push({
 | |
| 					callback
 | |
| 				});
 | |
| 			},
 | |
| 			watch: function(options, callback) {
 | |
| 				watchCallbacks.push({
 | |
| 					options,
 | |
| 					callback
 | |
| 				});
 | |
| 				return this.name;
 | |
| 			}
 | |
| 		};
 | |
| 	};
 | |
| 
 | |
| 	this.getPluginEventBindings = () => pluginEvents;
 | |
| 
 | |
| 	this.getRunCallbacks = () => runCallbacks;
 | |
| 
 | |
| 	this.getWatchCallbacks = () => watchCallbacks;
 | |
| }
 | |
| 
 | |
| const createCompiler = function(overrides) {
 | |
| 	const compilerEnvironment = new CompilerEnvironment();
 | |
| 	return Object.assign({
 | |
| 		outputPath: "/"
 | |
| 	}, compilerEnvironment.getCompilerStub(), overrides);
 | |
| };
 | |
| 
 | |
| const setupTwoCompilerEnvironment = function(env, compiler1Values, compiler2Values) {
 | |
| 	return setupMutliCompilerEnvironment(env, 2, [compiler1Values, compiler2Values]);
 | |
| };
 | |
| 
 | |
| const setupMutliCompilerEnvironment = function(env, count, compilerValues) {
 | |
| 	const values = Array.isArray(compilerValues) ? compilerValues : new Array(count);
 | |
| 	const environments = values.map(() => new CompilerEnvironment());
 | |
| 	const compilers = environments.map((e, i) => Object.assign({
 | |
| 		name: `compiler${i + 1}`
 | |
| 	}, (values[i] || {}), e.getCompilerStub()));
 | |
| 	env.myMultiCompiler = new MultiCompiler(compilers);
 | |
| 	environments.forEach((compilerEnvironment, i) => {
 | |
| 		env[`compiler${i + 1}EventBindings`] = compilerEnvironment.getPluginEventBindings();
 | |
| 		env[`compiler${i + 1}WatchCallbacks`] = compilerEnvironment.getWatchCallbacks();
 | |
| 		env[`compiler${i + 1}RunCallbacks`] = compilerEnvironment.getRunCallbacks();
 | |
| 	});
 | |
| };
 | |
| 
 | |
| describe("MultiCompiler", () => {
 | |
| 	let env;
 | |
| 	beforeEach(() => env = {});
 | |
| 
 | |
| 	describe("constructor", () => {
 | |
| 		describe("when provided an array of compilers", () => {
 | |
| 			beforeEach(() => {
 | |
| 				env.compilers = [createCompiler(), createCompiler()];
 | |
| 				env.myMultiCompiler = new MultiCompiler(env.compilers);
 | |
| 			});
 | |
| 
 | |
| 			it("sets the compilers property to the array", () => env.myMultiCompiler.compilers.should.be.exactly(env.compilers));
 | |
| 		});
 | |
| 
 | |
| 		describe("when provided a compiler mapping", () => {
 | |
| 			beforeEach(() => {
 | |
| 				const compilers = {
 | |
| 					compiler1: createCompiler(),
 | |
| 					compiler2: createCompiler()
 | |
| 				};
 | |
| 				env.myMultiCompiler = new MultiCompiler(compilers);
 | |
| 			});
 | |
| 
 | |
| 			it("sets the compilers property to an array of compilers", () => {
 | |
| 				env.myMultiCompiler.compilers.should.deepEqual([
 | |
| 					Object.assign({
 | |
| 						name: "compiler1"
 | |
| 					}, createCompiler()),
 | |
| 					Object.assign({
 | |
| 						name: "compiler2"
 | |
| 					}, createCompiler())
 | |
| 				]);
 | |
| 			});
 | |
| 		});
 | |
| 
 | |
| 		describe("defined properties", () => {
 | |
| 			describe("outputFileSystem", () => {
 | |
| 				beforeEach(() => {
 | |
| 					env.compilers = [createCompiler(), createCompiler()];
 | |
| 					env.myMultiCompiler = new MultiCompiler(env.compilers);
 | |
| 				});
 | |
| 
 | |
| 				it("throws an error when reading the value", () => {
 | |
| 					should(() => {
 | |
| 						env.myMultiCompiler.outputFileSystem;
 | |
| 					}).throw("Cannot read outputFileSystem of a MultiCompiler");
 | |
| 				});
 | |
| 
 | |
| 				it("updates all compilers when setting the value", () => {
 | |
| 					env.myMultiCompiler.outputFileSystem = "foo";
 | |
| 					env.compilers[0].outputFileSystem.should.be.exactly("foo");
 | |
| 					env.compilers[1].outputFileSystem.should.be.exactly("foo");
 | |
| 				});
 | |
| 			});
 | |
| 
 | |
| 			describe("inputFileSystem", () => {
 | |
| 				beforeEach(() => {
 | |
| 					env.compilers = [createCompiler(), createCompiler()];
 | |
| 					env.myMultiCompiler = new MultiCompiler(env.compilers);
 | |
| 				});
 | |
| 
 | |
| 				it("throws an error when reading the value", () => {
 | |
| 					should(() => {
 | |
| 						env.myMultiCompiler.inputFileSystem;
 | |
| 					}).throw("Cannot read inputFileSystem of a MultiCompiler");
 | |
| 				});
 | |
| 
 | |
| 				it("updates all compilers when setting the value", () => {
 | |
| 					env.myMultiCompiler.inputFileSystem = "foo";
 | |
| 					env.compilers[0].inputFileSystem.should.be.exactly("foo");
 | |
| 					env.compilers[1].inputFileSystem.should.be.exactly("foo");
 | |
| 				});
 | |
| 			});
 | |
| 
 | |
| 			describe("outputPath", () => {
 | |
| 				describe("when common path cannot be found and output path is absolute", () => {
 | |
| 					beforeEach(() => {
 | |
| 						env.compilers = [
 | |
| 							createCompiler({
 | |
| 								outputPath: "/foo/bar"
 | |
| 							}),
 | |
| 							createCompiler({
 | |
| 								outputPath: "quux"
 | |
| 							})
 | |
| 						];
 | |
| 						env.myMultiCompiler = new MultiCompiler(env.compilers);
 | |
| 					});
 | |
| 
 | |
| 					it("returns the root path", () => env.myMultiCompiler.outputPath.should.be.exactly("/"));
 | |
| 				});
 | |
| 
 | |
| 				describe("when common path cannot be found and output path is relative", () => {
 | |
| 					beforeEach(() => {
 | |
| 						env.compilers = [
 | |
| 							createCompiler({
 | |
| 								outputPath: "foo/bar/baz"
 | |
| 							}),
 | |
| 							createCompiler({
 | |
| 								outputPath: "quux"
 | |
| 							})
 | |
| 						];
 | |
| 						env.myMultiCompiler = new MultiCompiler(env.compilers);
 | |
| 					});
 | |
| 
 | |
| 					it("returns the first segment of relative path", () =>
 | |
| 						env.myMultiCompiler.outputPath.should.be.exactly("foo"));
 | |
| 				});
 | |
| 
 | |
| 				describe("when common path can be found and output path is absolute", () => {
 | |
| 					beforeEach(() => {
 | |
| 						env.compilers = [
 | |
| 							createCompiler({
 | |
| 								outputPath: "/foo"
 | |
| 							}),
 | |
| 							createCompiler({
 | |
| 								outputPath: "/foo/bar/baz"
 | |
| 							})
 | |
| 						];
 | |
| 						env.myMultiCompiler = new MultiCompiler(env.compilers);
 | |
| 					});
 | |
| 
 | |
| 					it("returns the shared path", () => env.myMultiCompiler.outputPath.should.be.exactly("/foo"));
 | |
| 				});
 | |
| 
 | |
| 				describe("when common path can be found and output path is relative", () => {
 | |
| 					beforeEach(() => {
 | |
| 						env.compilers = [
 | |
| 							createCompiler({
 | |
| 								outputPath: "foo"
 | |
| 							}),
 | |
| 							createCompiler({
 | |
| 								outputPath: "foo/bar/baz"
 | |
| 							})
 | |
| 						];
 | |
| 						env.myMultiCompiler = new MultiCompiler(env.compilers);
 | |
| 					});
 | |
| 
 | |
| 					it("returns the shared path", () => env.myMultiCompiler.outputPath.should.be.exactly("foo"));
 | |
| 				});
 | |
| 			});
 | |
| 		});
 | |
| 
 | |
| 		describe("compiler events", () => {
 | |
| 			beforeEach(() => setupTwoCompilerEnvironment(env));
 | |
| 
 | |
| 			it("binds two event handler", () => {
 | |
| 				env.compiler1EventBindings.length.should.be.exactly(2);
 | |
| 				env.compiler2EventBindings.length.should.be.exactly(2);
 | |
| 			});
 | |
| 
 | |
| 			describe("done handler", () => {
 | |
| 				beforeEach(() => {
 | |
| 					env.doneEventBinding1 = env.compiler1EventBindings[0];
 | |
| 					env.doneEventBinding2 = env.compiler2EventBindings[0];
 | |
| 				});
 | |
| 
 | |
| 				it("binds to done event", () => env.doneEventBinding1.name.should.be.exactly("done"));
 | |
| 
 | |
| 				describe("when called for first compiler", () => {
 | |
| 					beforeEach(() => {
 | |
| 						env.mockDonePlugin = sinon.spy();
 | |
| 						env.myMultiCompiler.plugin("done", env.mockDonePlugin);
 | |
| 						env.doneEventBinding1.handler({
 | |
| 							hash: "foo"
 | |
| 						});
 | |
| 					});
 | |
| 
 | |
| 					it("does not call the done plugin when not all compilers are finished", () =>
 | |
| 						env.mockDonePlugin.callCount.should.be.exactly(0));
 | |
| 
 | |
| 					describe("and called for second compiler", () => {
 | |
| 						beforeEach(() =>
 | |
| 							env.doneEventBinding2.handler({
 | |
| 								hash: "bar"
 | |
| 							}));
 | |
| 
 | |
| 						it("calls the done plugin", () => env.mockDonePlugin.callCount.should.be.exactly(1));
 | |
| 					});
 | |
| 				});
 | |
| 			});
 | |
| 
 | |
| 			describe("invalid handler", () => {
 | |
| 				beforeEach(() => env.invalidEventBinding = env.compiler1EventBindings[1]);
 | |
| 
 | |
| 				it("binds to invalid event", () => env.invalidEventBinding.name.should.be.exactly("invalid"));
 | |
| 
 | |
| 				describe("when called", () => {
 | |
| 					beforeEach(() => {
 | |
| 						env.mockInvalidPlugin = sinon.spy();
 | |
| 						env.myMultiCompiler.plugin("invalid", env.mockInvalidPlugin);
 | |
| 						env.invalidEventBinding.handler();
 | |
| 					});
 | |
| 
 | |
| 					it("calls the invalid plugin", () => env.mockInvalidPlugin.callCount.should.be.exactly(1));
 | |
| 				});
 | |
| 			});
 | |
| 		});
 | |
| 	});
 | |
| 
 | |
| 	describe("watch", () => {
 | |
| 		describe("without compiler dependencies", () => {
 | |
| 			beforeEach(() => {
 | |
| 				setupTwoCompilerEnvironment(env);
 | |
| 				env.callback = sinon.spy();
 | |
| 				env.options = [{
 | |
| 					testWatchOptions: true
 | |
| 				}, {
 | |
| 					testWatchOptions2: true
 | |
| 				}];
 | |
| 				env.result = env.myMultiCompiler.watch(env.options, env.callback);
 | |
| 			});
 | |
| 
 | |
| 			it("returns a multi-watching object", () => {
 | |
| 				const result = env.result;
 | |
| 				result.constructor.name.should.be.exactly("MultiWatching");
 | |
| 			});
 | |
| 
 | |
| 			it("calls watch on each compiler with original options", () => {
 | |
| 				env.compiler1WatchCallbacks.length.should.be.exactly(1);
 | |
| 				env.compiler1WatchCallbacks[0].options.should.be.exactly(env.options[0]);
 | |
| 				env.compiler2WatchCallbacks.length.should.be.exactly(1);
 | |
| 				env.compiler2WatchCallbacks[0].options.should.be.exactly(env.options[1]);
 | |
| 			});
 | |
| 
 | |
| 			it("calls the callback when all compilers watch", () => {
 | |
| 				env.compiler1WatchCallbacks[0].callback(null, {
 | |
| 					hash: "foo"
 | |
| 				});
 | |
| 				env.callback.callCount.should.be.exactly(0);
 | |
| 				env.compiler2WatchCallbacks[0].callback(null, {
 | |
| 					hash: "bar"
 | |
| 				});
 | |
| 				env.callback.callCount.should.be.exactly(1);
 | |
| 			});
 | |
| 
 | |
| 			describe("on first run", () => {
 | |
| 				describe("callback called with no compiler errors", () => {
 | |
| 					beforeEach(() => env.compiler1WatchCallbacks[0].callback(new Error("Test error")));
 | |
| 
 | |
| 					it("has failure parameters", () => {
 | |
| 						env.callback.callCount.should.be.exactly(1);
 | |
| 						env.callback.getCall(0).args[0].should.be.Error();
 | |
| 						should(env.callback.getCall(0).args[1]).be.undefined();
 | |
| 					});
 | |
| 				});
 | |
| 
 | |
| 				describe("callback called with no compiler errors", () => {
 | |
| 					beforeEach(() =>
 | |
| 						env.compiler1WatchCallbacks[0].callback(null, {
 | |
| 							hash: "foo"
 | |
| 						}));
 | |
| 
 | |
| 					it("does not call the callback", () => env.callback.callCount.should.be.exactly(0));
 | |
| 				});
 | |
| 			});
 | |
| 
 | |
| 			describe("on subsequent runs", () => {
 | |
| 				describe("callback called with compiler errors", () => {
 | |
| 					beforeEach(() => {
 | |
| 						env.compiler1WatchCallbacks[0].callback(null, {
 | |
| 							hash: "foo"
 | |
| 						});
 | |
| 						env.compiler2WatchCallbacks[0].callback(new Error("Test error"));
 | |
| 					});
 | |
| 
 | |
| 					it("has failure parameters", () => {
 | |
| 						env.callback.callCount.should.be.exactly(1);
 | |
| 						env.callback.getCall(0).args[0].should.be.Error();
 | |
| 						should(env.callback.getCall(0).args[1]).be.undefined();
 | |
| 					});
 | |
| 				});
 | |
| 
 | |
| 				describe("callback called with no compiler errors", () => {
 | |
| 					beforeEach(() => {
 | |
| 						env.compiler1WatchCallbacks[0].callback(null, {
 | |
| 							hash: "foo"
 | |
| 						});
 | |
| 						env.compiler2WatchCallbacks[0].callback(null, {
 | |
| 							hash: "bar"
 | |
| 						});
 | |
| 					});
 | |
| 
 | |
| 					it("has success parameters", () => {
 | |
| 						env.callback.callCount.should.be.exactly(1);
 | |
| 						should(env.callback.getCall(0).args[0]).be.Null();
 | |
| 						const stats = JSON.stringify(env.callback.getCall(0).args[1]);
 | |
| 						stats.should.be.exactly("{\"stats\":[{\"hash\":\"foo\"},{\"hash\":\"bar\"}],\"hash\":\"foobar\"}");
 | |
| 					});
 | |
| 				});
 | |
| 			});
 | |
| 		});
 | |
| 
 | |
| 		describe("with compiler dependencies", () => {
 | |
| 			beforeEach(() => {
 | |
| 				setupTwoCompilerEnvironment(env, {
 | |
| 					name: "compiler1",
 | |
| 					dependencies: ["compiler2"]
 | |
| 				}, {
 | |
| 					name: "compiler2"
 | |
| 				});
 | |
| 				env.callback = sinon.spy();
 | |
| 				env.options = [{
 | |
| 					testWatchOptions: true
 | |
| 				}, {
 | |
| 					testWatchOptions2: true
 | |
| 				}];
 | |
| 				env.result = env.myMultiCompiler.watch(env.options, env.callback);
 | |
| 			});
 | |
| 
 | |
| 			it("calls run on each compiler in dependency order", () => {
 | |
| 				env.compiler1WatchCallbacks.length.should.be.exactly(0);
 | |
| 				env.compiler2WatchCallbacks.length.should.be.exactly(1);
 | |
| 				env.compiler2WatchCallbacks[0].options.should.be.exactly(env.options[1]);
 | |
| 				env.compiler2WatchCallbacks[0].callback(null, {
 | |
| 					hash: "bar"
 | |
| 				});
 | |
| 				env.compiler1WatchCallbacks.length.should.be.exactly(1);
 | |
| 				env.compiler1WatchCallbacks[0].options.should.be.exactly(env.options[0]);
 | |
| 			});
 | |
| 
 | |
| 			it("calls the callback when all compilers run in dependency order", () => {
 | |
| 				env.compiler2WatchCallbacks[0].callback(null, {
 | |
| 					hash: "bar"
 | |
| 				});
 | |
| 				env.callback.callCount.should.be.exactly(0);
 | |
| 				env.compiler1WatchCallbacks[0].callback(null, {
 | |
| 					hash: "foo"
 | |
| 				});
 | |
| 				env.callback.callCount.should.be.exactly(1);
 | |
| 			});
 | |
| 		});
 | |
| 
 | |
| 		describe("with missing compiler dependencies", () => {
 | |
| 			beforeEach(() => {
 | |
| 				setupTwoCompilerEnvironment(env, {
 | |
| 					name: "compiler1",
 | |
| 					dependencies: ["compiler2"]
 | |
| 				}, {
 | |
| 					name: "compiler3"
 | |
| 				});
 | |
| 				env.callback = sinon.spy();
 | |
| 				env.options = [{
 | |
| 					testWatchOptions: true
 | |
| 				}, {
 | |
| 					testWatchOptions2: true
 | |
| 				}];
 | |
| 				env.result = env.myMultiCompiler.watch(env.options, env.callback);
 | |
| 			});
 | |
| 
 | |
| 			it("should call the callback with an error message", () => {
 | |
| 				env.compiler1WatchCallbacks.length.should.be.exactly(0);
 | |
| 				env.compiler2WatchCallbacks.length.should.be.exactly(0);
 | |
| 				env.callback.callCount.should.be.exactly(1);
 | |
| 				env.callback.getCall(0).args[0].should.be.Error();
 | |
| 				should(env.callback.getCall(0).args[1]).be.undefined();
 | |
| 			});
 | |
| 		});
 | |
| 
 | |
| 		describe("with circular compiler dependencies", () => {
 | |
| 			beforeEach(() => {
 | |
| 				setupTwoCompilerEnvironment(env, {
 | |
| 					name: "compiler1",
 | |
| 					dependencies: ["compiler2"]
 | |
| 				}, {
 | |
| 					name: "compiler2",
 | |
| 					dependencies: ["compiler1"]
 | |
| 				});
 | |
| 				env.callback = sinon.spy();
 | |
| 				env.options = [{
 | |
| 					testWatchOptions: true
 | |
| 				}, {
 | |
| 					testWatchOptions2: true
 | |
| 				}];
 | |
| 				env.result = env.myMultiCompiler.watch(env.options, env.callback);
 | |
| 			});
 | |
| 
 | |
| 			it("should call the callback with an error message", () => {
 | |
| 				env.compiler1WatchCallbacks.length.should.be.exactly(0);
 | |
| 				env.compiler2WatchCallbacks.length.should.be.exactly(0);
 | |
| 				env.callback.callCount.should.be.exactly(1);
 | |
| 				env.callback.getCall(0).args[0].should.be.Error();
 | |
| 				should(env.callback.getCall(0).args[1]).be.undefined();
 | |
| 			});
 | |
| 		});
 | |
| 
 | |
| 		describe("with no root compiler", () => {
 | |
| 			beforeEach(() => {
 | |
| 				setupMutliCompilerEnvironment(env, 3, [{
 | |
| 					name: "a",
 | |
| 				}, {
 | |
| 					name: "b",
 | |
| 					dependencies: ["a", "c"]
 | |
| 				}, {
 | |
| 					name: "c",
 | |
| 					dependencies: ["b"]
 | |
| 				}]);
 | |
| 				env.callback = sinon.spy();
 | |
| 				env.options = [{
 | |
| 					testWatchOptions: true
 | |
| 				}, {
 | |
| 					testWatchOptions2: true
 | |
| 				}];
 | |
| 				env.result = env.myMultiCompiler.watch(env.options, env.callback);
 | |
| 			});
 | |
| 
 | |
| 			it("should call the callback with an error message", () => {
 | |
| 				env.compiler1RunCallbacks.length.should.be.exactly(0);
 | |
| 				env.compiler2RunCallbacks.length.should.be.exactly(0);
 | |
| 				env.compiler3RunCallbacks.length.should.be.exactly(0);
 | |
| 				env.callback.callCount.should.be.exactly(1);
 | |
| 				env.callback.getCall(0).args[0].should.be.Error();
 | |
| 				should(env.callback.getCall(0).args[1]).be.undefined();
 | |
| 			});
 | |
| 		});
 | |
| 	});
 | |
| 
 | |
| 	describe("run", () => {
 | |
| 		describe("without compiler dependencies", () => {
 | |
| 			beforeEach(() => {
 | |
| 				setupTwoCompilerEnvironment(env);
 | |
| 				env.callback = sinon.spy();
 | |
| 				env.myMultiCompiler.run(env.callback);
 | |
| 			});
 | |
| 
 | |
| 			it("calls run on each compiler", () => {
 | |
| 				env.compiler1RunCallbacks.length.should.be.exactly(1);
 | |
| 				env.compiler2RunCallbacks.length.should.be.exactly(1);
 | |
| 			});
 | |
| 
 | |
| 			it("calls the callback when all compilers run", () => {
 | |
| 				env.compiler1RunCallbacks[0].callback(null, {
 | |
| 					hash: "foo"
 | |
| 				});
 | |
| 				env.callback.callCount.should.be.exactly(0);
 | |
| 				env.compiler2RunCallbacks[0].callback(null, {
 | |
| 					hash: "bar"
 | |
| 				});
 | |
| 				env.callback.callCount.should.be.exactly(1);
 | |
| 			});
 | |
| 
 | |
| 			describe("callback called with no compiler errors", () => {
 | |
| 				beforeEach(() => {
 | |
| 					env.compiler1RunCallbacks[0].callback(null, {
 | |
| 						hash: "foo"
 | |
| 					});
 | |
| 					env.compiler2RunCallbacks[0].callback(null, {
 | |
| 						hash: "bar"
 | |
| 					});
 | |
| 				});
 | |
| 
 | |
| 				it("has success parameters", () => {
 | |
| 					env.callback.callCount.should.be.exactly(1);
 | |
| 					should(env.callback.getCall(0).args[0]).be.Null();
 | |
| 					const stats = JSON.stringify(env.callback.getCall(0).args[1]);
 | |
| 					stats.should.be.exactly("{\"stats\":[{\"hash\":\"foo\"},{\"hash\":\"bar\"}],\"hash\":\"foobar\"}");
 | |
| 				});
 | |
| 			});
 | |
| 
 | |
| 			describe("callback called with compiler errors", () => {
 | |
| 				beforeEach(() => {
 | |
| 					env.compiler1RunCallbacks[0].callback(null, {
 | |
| 						hash: "foo"
 | |
| 					});
 | |
| 					env.compiler2RunCallbacks[0].callback(new Error("Test error"));
 | |
| 				});
 | |
| 
 | |
| 				it("has failure parameters", () => {
 | |
| 					env.callback.callCount.should.be.exactly(1);
 | |
| 					env.callback.getCall(0).args[0].should.be.Error();
 | |
| 					should(env.callback.getCall(0).args[1]).be.undefined();
 | |
| 				});
 | |
| 			});
 | |
| 		});
 | |
| 
 | |
| 		describe("with compiler dependencies", () => {
 | |
| 			beforeEach(() => {
 | |
| 				setupTwoCompilerEnvironment(env, {
 | |
| 					name: "compiler1",
 | |
| 					dependencies: ["compiler2"]
 | |
| 				}, {
 | |
| 					name: "compiler2"
 | |
| 				});
 | |
| 				env.callback = sinon.spy();
 | |
| 				env.myMultiCompiler.run(env.callback);
 | |
| 			});
 | |
| 
 | |
| 			it("calls run on each compiler in dependency order", () => {
 | |
| 				env.compiler1RunCallbacks.length.should.be.exactly(0);
 | |
| 				env.compiler2RunCallbacks.length.should.be.exactly(1);
 | |
| 				env.compiler2RunCallbacks[0].callback(null, {
 | |
| 					hash: "bar"
 | |
| 				});
 | |
| 				env.compiler1RunCallbacks.length.should.be.exactly(1);
 | |
| 			});
 | |
| 
 | |
| 			it("calls the callback when all compilers run in dependency order", () => {
 | |
| 				env.compiler2RunCallbacks[0].callback(null, {
 | |
| 					hash: "bar"
 | |
| 				});
 | |
| 				env.callback.callCount.should.be.exactly(0);
 | |
| 				env.compiler1RunCallbacks[0].callback(null, {
 | |
| 					hash: "foo"
 | |
| 				});
 | |
| 				env.callback.callCount.should.be.exactly(1);
 | |
| 			});
 | |
| 		});
 | |
| 
 | |
| 		describe("with missing compiler dependencies", () => {
 | |
| 			beforeEach(() => {
 | |
| 				setupTwoCompilerEnvironment(env, {
 | |
| 					name: "compiler1",
 | |
| 					dependencies: ["compiler2"]
 | |
| 				}, {
 | |
| 					name: "compiler3"
 | |
| 				});
 | |
| 				env.callback = sinon.spy();
 | |
| 				env.myMultiCompiler.run(env.callback);
 | |
| 			});
 | |
| 
 | |
| 			it("should call the callback with an error message", () => {
 | |
| 				env.compiler1RunCallbacks.length.should.be.exactly(0);
 | |
| 				env.compiler2RunCallbacks.length.should.be.exactly(0);
 | |
| 				env.callback.callCount.should.be.exactly(1);
 | |
| 				env.callback.getCall(0).args[0].should.be.Error();
 | |
| 				should(env.callback.getCall(0).args[1]).be.undefined();
 | |
| 			});
 | |
| 		});
 | |
| 
 | |
| 		describe("with circular compiler dependencies", () => {
 | |
| 			beforeEach(() => {
 | |
| 				setupTwoCompilerEnvironment(env, {
 | |
| 					name: "compiler1",
 | |
| 					dependencies: ["compiler2"]
 | |
| 				}, {
 | |
| 					name: "compiler2",
 | |
| 					dependencies: ["compiler1"]
 | |
| 				});
 | |
| 				env.callback = sinon.spy();
 | |
| 				env.myMultiCompiler.run(env.callback);
 | |
| 			});
 | |
| 
 | |
| 			it("should call the callback with an error message", () => {
 | |
| 				env.compiler1RunCallbacks.length.should.be.exactly(0);
 | |
| 				env.compiler2RunCallbacks.length.should.be.exactly(0);
 | |
| 				env.callback.callCount.should.be.exactly(1);
 | |
| 				env.callback.getCall(0).args[0].should.be.Error();
 | |
| 				should(env.callback.getCall(0).args[1]).be.undefined();
 | |
| 			});
 | |
| 		});
 | |
| 
 | |
| 		describe("with no root compiler", () => {
 | |
| 			beforeEach(() => {
 | |
| 				setupMutliCompilerEnvironment(env, 3, [{
 | |
| 					name: "a",
 | |
| 				}, {
 | |
| 					name: "b",
 | |
| 					dependencies: ["a", "c"]
 | |
| 				}, {
 | |
| 					name: "c",
 | |
| 					dependencies: ["b"]
 | |
| 				}]);
 | |
| 				env.callback = sinon.spy();
 | |
| 				env.myMultiCompiler.run(env.callback);
 | |
| 			});
 | |
| 
 | |
| 			it("should call the callback with an error message", () => {
 | |
| 				env.compiler1RunCallbacks.length.should.be.exactly(0);
 | |
| 				env.compiler2RunCallbacks.length.should.be.exactly(0);
 | |
| 				env.compiler3RunCallbacks.length.should.be.exactly(0);
 | |
| 				env.callback.callCount.should.be.exactly(1);
 | |
| 				env.callback.getCall(0).args[0].should.be.Error();
 | |
| 				should(env.callback.getCall(0).args[1]).be.undefined();
 | |
| 			});
 | |
| 		});
 | |
| 	});
 | |
| 
 | |
| 	describe("purgeInputFileSystem", () => {
 | |
| 		beforeEach(() => {
 | |
| 			env.compilers = [
 | |
| 				Object.assign({
 | |
| 					inputFileSystem: {
 | |
| 						purge: sinon.spy()
 | |
| 					}
 | |
| 				}, createCompiler()),
 | |
| 				createCompiler()
 | |
| 			];
 | |
| 			env.myMultiCompiler = new MultiCompiler(env.compilers);
 | |
| 			env.myMultiCompiler.purgeInputFileSystem();
 | |
| 		});
 | |
| 
 | |
| 		it("calls the compilers purge if available", () => {
 | |
| 			const purgeSpy = env.compilers[0].inputFileSystem.purge;
 | |
| 			purgeSpy.callCount.should.be.exactly(1);
 | |
| 		});
 | |
| 	});
 | |
| });
 |