mirror of https://github.com/webpack/webpack.git
				
				
				
			
		
			
	
	
		
			544 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
		
		
			
		
	
	
			544 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
|  | var should = require("should"); | ||
|  | var sinon = require("sinon"); | ||
|  | var MultiCompiler = require("../lib/MultiCompiler"); | ||
|  | 
 | ||
|  | function CompilerEnvironment() { | ||
|  | 	var pluginEvents = []; | ||
|  | 	var runCallbacks = []; | ||
|  | 	var watchCallbacks = []; | ||
|  | 
 | ||
|  | 	this.getCompilerStub = function() { | ||
|  | 		return { | ||
|  | 			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 = function() { | ||
|  | 		return pluginEvents; | ||
|  | 	}; | ||
|  | 
 | ||
|  | 	this.getRunCallbacks = function() { | ||
|  | 		return runCallbacks; | ||
|  | 	}; | ||
|  | 
 | ||
|  | 	this.getWatchCallbacks = function() { | ||
|  | 		return watchCallbacks; | ||
|  | 	}; | ||
|  | }; | ||
|  | 
 | ||
|  | var createCompiler = function(overrides) { | ||
|  | 	var compilerEnvironment = new CompilerEnvironment(); | ||
|  | 	return Object.assign({ | ||
|  | 		outputPath: "/" | ||
|  | 	}, compilerEnvironment.getCompilerStub(), overrides); | ||
|  | }; | ||
|  | 
 | ||
|  | var setupTwoCompilerEnvironment = function(env, compiler1Values, compiler2Values) { | ||
|  | 	var compilerEnvironment1 = new CompilerEnvironment(); | ||
|  | 	var compilerEnvironment2 = new CompilerEnvironment(); | ||
|  | 	var compilers = [ | ||
|  | 		Object.assign({ | ||
|  | 			name: "compiler1" | ||
|  | 		}, (compiler1Values || {}), compilerEnvironment1.getCompilerStub()), | ||
|  | 		Object.assign({ | ||
|  | 			name: "compiler2" | ||
|  | 		}, (compiler2Values || {}), compilerEnvironment2.getCompilerStub()) | ||
|  | 	]; | ||
|  | 	env.myMultiCompiler = new MultiCompiler(compilers); | ||
|  | 	env.compiler1EventBindings = compilerEnvironment1.getPluginEventBindings(); | ||
|  | 	env.compiler2EventBindings = compilerEnvironment2.getPluginEventBindings(); | ||
|  | 	env.compiler1WatchCallbacks = compilerEnvironment1.getWatchCallbacks(); | ||
|  | 	env.compiler2WatchCallbacks = compilerEnvironment2.getWatchCallbacks(); | ||
|  | 	env.compiler1RunCallbacks = compilerEnvironment1.getRunCallbacks(); | ||
|  | 	env.compiler2RunCallbacks = compilerEnvironment2.getRunCallbacks(); | ||
|  | }; | ||
|  | 
 | ||
|  | describe("MultiCompiler", function() { | ||
|  | 	var env; | ||
|  | 	beforeEach(function() { | ||
|  | 		env = {}; | ||
|  | 	}); | ||
|  | 
 | ||
|  | 	describe("constructor", function() { | ||
|  | 		describe("when provided an array of compilers", function() { | ||
|  | 			beforeEach(function() { | ||
|  | 				env.compilers = [createCompiler(), createCompiler()]; | ||
|  | 				env.myMultiCompiler = new MultiCompiler(env.compilers); | ||
|  | 			}); | ||
|  | 
 | ||
|  | 			it("sets the compilers property to the array", function() { | ||
|  | 				env.myMultiCompiler.compilers.should.be.exactly(env.compilers); | ||
|  | 			}); | ||
|  | 		}); | ||
|  | 
 | ||
|  | 		describe("when provided a compiler mapping", function() { | ||
|  | 			beforeEach(function() { | ||
|  | 				var compilers = { | ||
|  | 					compiler1: createCompiler(), | ||
|  | 					compiler2: createCompiler() | ||
|  | 				}; | ||
|  | 				env.myMultiCompiler = new MultiCompiler(compilers); | ||
|  | 			}); | ||
|  | 
 | ||
|  | 			it("sets the compilers property to an array of compilers", function() { | ||
|  | 				env.myMultiCompiler.compilers.should.deepEqual([ | ||
|  | 					Object.assign({ | ||
|  | 						name: "compiler1" | ||
|  | 					}, createCompiler()), | ||
|  | 					Object.assign({ | ||
|  | 						name: "compiler2" | ||
|  | 					}, createCompiler()) | ||
|  | 				]); | ||
|  | 			}); | ||
|  | 		}); | ||
|  | 
 | ||
|  | 		describe("defined properties", function() { | ||
|  | 			describe("outputFileSystem", function() { | ||
|  | 				beforeEach(function() { | ||
|  | 					env.compilers = [createCompiler(), createCompiler()]; | ||
|  | 					env.myMultiCompiler = new MultiCompiler(env.compilers); | ||
|  | 				}); | ||
|  | 
 | ||
|  | 				it("throws an error when reading the value", function() { | ||
|  | 					should(function() { | ||
|  | 						env.myMultiCompiler.outputFileSystem | ||
|  | 					}).throw("Cannot read outputFileSystem of a MultiCompiler"); | ||
|  | 				}); | ||
|  | 
 | ||
|  | 				it("updates all compilers when setting the value", function() { | ||
|  | 					env.myMultiCompiler.outputFileSystem = "foo"; | ||
|  | 					env.compilers[0].outputFileSystem.should.be.exactly("foo"); | ||
|  | 					env.compilers[1].outputFileSystem.should.be.exactly("foo"); | ||
|  | 				}); | ||
|  | 			}); | ||
|  | 
 | ||
|  | 			describe("inputFileSystem", function() { | ||
|  | 				beforeEach(function() { | ||
|  | 					env.compilers = [createCompiler(), createCompiler()]; | ||
|  | 					env.myMultiCompiler = new MultiCompiler(env.compilers); | ||
|  | 				}); | ||
|  | 
 | ||
|  | 				it("throws an error when reading the value", function() { | ||
|  | 					should(function() { | ||
|  | 						env.myMultiCompiler.inputFileSystem | ||
|  | 					}).throw("Cannot read inputFileSystem of a MultiCompiler"); | ||
|  | 				}); | ||
|  | 
 | ||
|  | 				it("updates all compilers when setting the value", function() { | ||
|  | 					env.myMultiCompiler.inputFileSystem = "foo"; | ||
|  | 					env.compilers[0].inputFileSystem.should.be.exactly("foo"); | ||
|  | 					env.compilers[1].inputFileSystem.should.be.exactly("foo"); | ||
|  | 				}); | ||
|  | 			}); | ||
|  | 
 | ||
|  | 			describe("outputPath", function() { | ||
|  | 				describe("when common path cannot be found and output path is absolute", function() { | ||
|  | 					beforeEach(function() { | ||
|  | 						env.compilers = [ | ||
|  | 							createCompiler({ | ||
|  | 								outputPath: "/foo/bar" | ||
|  | 							}), | ||
|  | 							createCompiler({ | ||
|  | 								outputPath: "quux" | ||
|  | 							}) | ||
|  | 						]; | ||
|  | 						env.myMultiCompiler = new MultiCompiler(env.compilers); | ||
|  | 					}); | ||
|  | 
 | ||
|  | 					it("returns the root path", function() { | ||
|  | 						env.myMultiCompiler.outputPath.should.be.exactly("/"); | ||
|  | 					}); | ||
|  | 				}); | ||
|  | 
 | ||
|  | 				describe("when common path cannot be found and output path is relative", function() { | ||
|  | 					beforeEach(function() { | ||
|  | 						env.compilers = [ | ||
|  | 							createCompiler({ | ||
|  | 								outputPath: "foo/bar/baz" | ||
|  | 							}), | ||
|  | 							createCompiler({ | ||
|  | 								outputPath: "quux" | ||
|  | 							}) | ||
|  | 						]; | ||
|  | 						env.myMultiCompiler = new MultiCompiler(env.compilers); | ||
|  | 					}); | ||
|  | 
 | ||
|  | 					it("returns the first segment of relative path", function() { | ||
|  | 						env.myMultiCompiler.outputPath.should.be.exactly("foo"); | ||
|  | 					}); | ||
|  | 				}); | ||
|  | 
 | ||
|  | 				describe("when common path can be found and output path is absolute", function() { | ||
|  | 					beforeEach(function() { | ||
|  | 						env.compilers = [ | ||
|  | 							createCompiler({ | ||
|  | 								outputPath: "/foo" | ||
|  | 							}), | ||
|  | 							createCompiler({ | ||
|  | 								outputPath: "/foo/bar/baz" | ||
|  | 							}) | ||
|  | 						]; | ||
|  | 						env.myMultiCompiler = new MultiCompiler(env.compilers); | ||
|  | 					}); | ||
|  | 
 | ||
|  | 					it("returns the shared path", function() { | ||
|  | 						env.myMultiCompiler.outputPath.should.be.exactly("/foo"); | ||
|  | 					}); | ||
|  | 				}); | ||
|  | 
 | ||
|  | 				describe("when common path can be found and output path is relative", function() { | ||
|  | 					beforeEach(function() { | ||
|  | 						env.compilers = [ | ||
|  | 							createCompiler({ | ||
|  | 								outputPath: "foo" | ||
|  | 							}), | ||
|  | 							createCompiler({ | ||
|  | 								outputPath: "foo/bar/baz" | ||
|  | 							}) | ||
|  | 						]; | ||
|  | 						env.myMultiCompiler = new MultiCompiler(env.compilers); | ||
|  | 					}); | ||
|  | 
 | ||
|  | 					it("returns the shared path", function() { | ||
|  | 						env.myMultiCompiler.outputPath.should.be.exactly("foo"); | ||
|  | 					}); | ||
|  | 				}); | ||
|  | 			}); | ||
|  | 		}); | ||
|  | 
 | ||
|  | 		describe("compiler events", function() { | ||
|  | 			beforeEach(function() { | ||
|  | 				setupTwoCompilerEnvironment(env); | ||
|  | 			}); | ||
|  | 
 | ||
|  | 			it("binds two event handler", function() { | ||
|  | 				env.compiler1EventBindings.length.should.be.exactly(2); | ||
|  | 				env.compiler2EventBindings.length.should.be.exactly(2); | ||
|  | 			}); | ||
|  | 
 | ||
|  | 			describe("done handler", function() { | ||
|  | 				beforeEach(function() { | ||
|  | 					env.doneEventBinding1 = env.compiler1EventBindings[0]; | ||
|  | 					env.doneEventBinding2 = env.compiler2EventBindings[0]; | ||
|  | 				}); | ||
|  | 
 | ||
|  | 				it("binds to done event", function() { | ||
|  | 					env.doneEventBinding1.name.should.be.exactly("done"); | ||
|  | 				}); | ||
|  | 
 | ||
|  | 				describe('when called for first compiler', function() { | ||
|  | 					beforeEach(function() { | ||
|  | 						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", function() { | ||
|  | 						env.mockDonePlugin.callCount.should.be.exactly(0); | ||
|  | 					}); | ||
|  | 
 | ||
|  | 					describe('and called for second compiler', function() { | ||
|  | 						beforeEach(function() { | ||
|  | 							env.doneEventBinding2.handler({ | ||
|  | 								hash: "bar" | ||
|  | 							}); | ||
|  | 						}); | ||
|  | 
 | ||
|  | 						it("calls the done plugin", function() { | ||
|  | 							env.mockDonePlugin.callCount.should.be.exactly(1); | ||
|  | 						}); | ||
|  | 					}); | ||
|  | 				}); | ||
|  | 			}); | ||
|  | 
 | ||
|  | 			describe("invalid handler", function() { | ||
|  | 				beforeEach(function() { | ||
|  | 					env.invalidEventBinding = env.compiler1EventBindings[1]; | ||
|  | 				}); | ||
|  | 
 | ||
|  | 				it("binds to invalid event", function() { | ||
|  | 					env.invalidEventBinding.name.should.be.exactly("invalid"); | ||
|  | 				}); | ||
|  | 
 | ||
|  | 				describe('when called', function() { | ||
|  | 					beforeEach(function() { | ||
|  | 						env.mockInvalidPlugin = sinon.spy(); | ||
|  | 						env.myMultiCompiler.plugin('invalid', env.mockInvalidPlugin); | ||
|  | 						env.invalidEventBinding.handler(); | ||
|  | 					}); | ||
|  | 
 | ||
|  | 					it("calls the invalid plugin", function() { | ||
|  | 						env.mockInvalidPlugin.callCount.should.be.exactly(1); | ||
|  | 					}); | ||
|  | 				}); | ||
|  | 			}); | ||
|  | 		}); | ||
|  | 	}); | ||
|  | 
 | ||
|  | 	describe("watch", function() { | ||
|  | 		describe("without compiler dependencies", function() { | ||
|  | 			beforeEach(function() { | ||
|  | 				setupTwoCompilerEnvironment(env); | ||
|  | 				env.callback = sinon.spy(); | ||
|  | 				env.options = { | ||
|  | 					testWatchOptions: true | ||
|  | 				}; | ||
|  | 				env.result = env.myMultiCompiler.watch(env.options, env.callback); | ||
|  | 			}); | ||
|  | 
 | ||
|  | 			it("returns a multi-watching object", function() { | ||
|  | 				var result = JSON.stringify(env.result); | ||
|  | 				result.should.be.exactly('{"watchings":["compiler1","compiler2"]}'); | ||
|  | 			}); | ||
|  | 
 | ||
|  | 			it("calls watch on each compiler with original options", function() { | ||
|  | 				env.compiler1WatchCallbacks.length.should.be.exactly(1); | ||
|  | 				env.compiler1WatchCallbacks[0].options.should.be.exactly(env.options); | ||
|  | 				env.compiler2WatchCallbacks.length.should.be.exactly(1); | ||
|  | 				env.compiler2WatchCallbacks[0].options.should.be.exactly(env.options); | ||
|  | 			}); | ||
|  | 
 | ||
|  | 			it("calls the callback when all compilers watch", function() { | ||
|  | 				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", function() { | ||
|  | 				describe("callback called with no compiler errors", function() { | ||
|  | 					beforeEach(function() { | ||
|  | 						env.compiler1WatchCallbacks[0].callback(new Error('Test error')); | ||
|  | 					}); | ||
|  | 
 | ||
|  | 					it('has failure parameters', function() { | ||
|  | 						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", function() { | ||
|  | 					beforeEach(function() { | ||
|  | 						env.compiler1WatchCallbacks[0].callback(null, { | ||
|  | 							hash: 'foo' | ||
|  | 						}); | ||
|  | 					}); | ||
|  | 
 | ||
|  | 					it('does not call the callback', function() { | ||
|  | 						env.callback.callCount.should.be.exactly(0); | ||
|  | 					}); | ||
|  | 				}); | ||
|  | 			}); | ||
|  | 
 | ||
|  | 			describe("on subsequent runs", function() { | ||
|  | 				describe("callback called with compiler errors", function() { | ||
|  | 					beforeEach(function() { | ||
|  | 						env.compiler1WatchCallbacks[0].callback(null, { | ||
|  | 							hash: 'foo' | ||
|  | 						}); | ||
|  | 						env.compiler2WatchCallbacks[0].callback(new Error('Test error')); | ||
|  | 					}); | ||
|  | 
 | ||
|  | 					it('has failure parameters', function() { | ||
|  | 						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", function() { | ||
|  | 					beforeEach(function() { | ||
|  | 						env.compiler1WatchCallbacks[0].callback(null, { | ||
|  | 							hash: 'foo' | ||
|  | 						}); | ||
|  | 						env.compiler2WatchCallbacks[0].callback(null, { | ||
|  | 							hash: 'bar' | ||
|  | 						}); | ||
|  | 					}); | ||
|  | 
 | ||
|  | 					it('has success parameters', function() { | ||
|  | 						env.callback.callCount.should.be.exactly(1); | ||
|  | 						should(env.callback.getCall(0).args[0]).be.Null(); | ||
|  | 						var stats = JSON.stringify(env.callback.getCall(0).args[1]); | ||
|  | 						stats.should.be.exactly('{"stats":[{"hash":"foo"},{"hash":"bar"}],"hash":"foobar"}'); | ||
|  | 					}); | ||
|  | 				}); | ||
|  | 			}); | ||
|  | 		}); | ||
|  | 
 | ||
|  | 		describe("with compiler dependencies", function() { | ||
|  | 			beforeEach(function() { | ||
|  | 				setupTwoCompilerEnvironment(env, { | ||
|  | 					name: "compiler1", | ||
|  | 					dependencies: ["compiler2"] | ||
|  | 				}, { | ||
|  | 					name: "compiler2" | ||
|  | 				}); | ||
|  | 				env.callback = sinon.spy(); | ||
|  | 				env.options = { | ||
|  | 					testWatchOptions: true | ||
|  | 				}; | ||
|  | 				env.result = env.myMultiCompiler.watch(env.options, env.callback); | ||
|  | 			}); | ||
|  | 
 | ||
|  | 			it("calls run on each compiler in dependency order", function() { | ||
|  | 				env.compiler1WatchCallbacks.length.should.be.exactly(0); | ||
|  | 				env.compiler2WatchCallbacks.length.should.be.exactly(1); | ||
|  | 				env.compiler2WatchCallbacks[0].options.should.be.exactly(env.options); | ||
|  | 				env.compiler2WatchCallbacks[0].callback(null, { | ||
|  | 					hash: 'bar' | ||
|  | 				}); | ||
|  | 				env.compiler1WatchCallbacks.length.should.be.exactly(1); | ||
|  | 				env.compiler1WatchCallbacks[0].options.should.be.exactly(env.options); | ||
|  | 			}); | ||
|  | 
 | ||
|  | 			it("calls the callback when all compilers run in dependency order", function() { | ||
|  | 				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("run", function() { | ||
|  | 		describe("without compiler dependencies", function() { | ||
|  | 			beforeEach(function() { | ||
|  | 				setupTwoCompilerEnvironment(env); | ||
|  | 				env.callback = sinon.spy(); | ||
|  | 				env.myMultiCompiler.run(env.callback); | ||
|  | 			}); | ||
|  | 
 | ||
|  | 			it("calls run on each compiler", function() { | ||
|  | 				env.compiler1RunCallbacks.length.should.be.exactly(1); | ||
|  | 				env.compiler2RunCallbacks.length.should.be.exactly(1); | ||
|  | 			}); | ||
|  | 
 | ||
|  | 			it("calls the callback when all compilers run", function() { | ||
|  | 				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", function() { | ||
|  | 				beforeEach(function() { | ||
|  | 					env.compiler1RunCallbacks[0].callback(null, { | ||
|  | 						hash: 'foo' | ||
|  | 					}); | ||
|  | 					env.compiler2RunCallbacks[0].callback(null, { | ||
|  | 						hash: 'bar' | ||
|  | 					}); | ||
|  | 				}); | ||
|  | 
 | ||
|  | 				it('has success parameters', function() { | ||
|  | 					env.callback.callCount.should.be.exactly(1); | ||
|  | 					should(env.callback.getCall(0).args[0]).be.Null(); | ||
|  | 					var 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", function() { | ||
|  | 				beforeEach(function() { | ||
|  | 					env.compiler1RunCallbacks[0].callback(null, { | ||
|  | 						hash: 'foo' | ||
|  | 					}); | ||
|  | 					env.compiler2RunCallbacks[0].callback(new Error('Test error')); | ||
|  | 				}); | ||
|  | 
 | ||
|  | 				it('has failure parameters', function() { | ||
|  | 					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", function() { | ||
|  | 			beforeEach(function() { | ||
|  | 				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", function() { | ||
|  | 				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", function() { | ||
|  | 				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("purgeInputFileSystem", function() { | ||
|  | 		beforeEach(function() { | ||
|  | 			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", function() { | ||
|  | 			var purgeSpy = env.compilers[0].inputFileSystem.purge; | ||
|  | 			purgeSpy.callCount.should.be.exactly(1); | ||
|  | 		}); | ||
|  | 	}); | ||
|  | }); |