mirror of https://github.com/webpack/webpack.git
				
				
				
			Merge pull request #3510 from webpack/test/watch-tests
add infrastructure for watch tests
This commit is contained in:
		
						commit
						ea46fdac08
					
				|  | @ -178,6 +178,7 @@ NormalModule.prototype.build = function build(options, compilation, resolver, fs | ||||||
| 	_this.error = null; | 	_this.error = null; | ||||||
| 	_this.errors.length = 0; | 	_this.errors.length = 0; | ||||||
| 	_this.warnings.length = 0; | 	_this.warnings.length = 0; | ||||||
|  | 	_this.meta = {}; | ||||||
| 	return _this.doBuild(options, compilation, resolver, fs, function(err) { | 	return _this.doBuild(options, compilation, resolver, fs, function(err) { | ||||||
| 		_this.dependencies.length = 0; | 		_this.dependencies.length = 0; | ||||||
| 		_this.variables.length = 0; | 		_this.variables.length = 0; | ||||||
|  |  | ||||||
|  | @ -0,0 +1,175 @@ | ||||||
|  | var should = require("should"); | ||||||
|  | var path = require("path"); | ||||||
|  | var fs = require("fs"); | ||||||
|  | var vm = require("vm"); | ||||||
|  | var Test = require("mocha/lib/test"); | ||||||
|  | var checkArrayExpectation = require("./checkArrayExpectation"); | ||||||
|  | 
 | ||||||
|  | var Stats = require("../lib/Stats"); | ||||||
|  | var webpack = require("../lib/webpack"); | ||||||
|  | 
 | ||||||
|  | function copyDiff(src, dest) { | ||||||
|  | 	if(!fs.existsSync(dest)) | ||||||
|  | 		fs.mkdirSync(dest); | ||||||
|  | 	var files = fs.readdirSync(src); | ||||||
|  | 	files.forEach(function(filename) { | ||||||
|  | 		var srcFile = path.join(src, filename); | ||||||
|  | 		var destFile = path.join(dest, filename); | ||||||
|  | 		var directory = fs.statSync(srcFile).isDirectory(); | ||||||
|  | 		if(directory) { | ||||||
|  | 			copyDiff(srcFile, destFile); | ||||||
|  | 		} else { | ||||||
|  | 			fs.writeFileSync(destFile, fs.readFileSync(srcFile)); | ||||||
|  | 		} | ||||||
|  | 	}); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function remove(src) { | ||||||
|  | 	if(!fs.existsSync(src)) | ||||||
|  | 		return; | ||||||
|  | 	var files = fs.readdirSync(src); | ||||||
|  | 	files.forEach(function(filename) { | ||||||
|  | 		var srcFile = path.join(src, filename); | ||||||
|  | 		var directory = fs.statSync(srcFile).isDirectory(); | ||||||
|  | 		if(directory) { | ||||||
|  | 			remove(srcFile); | ||||||
|  | 		} else { | ||||||
|  | 			fs.unlinkSync(srcFile); | ||||||
|  | 		} | ||||||
|  | 	}); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | describe("WatchTestCases", function() { | ||||||
|  | 	var casesPath = path.join(__dirname, "watchCases"); | ||||||
|  | 	var categories = fs.readdirSync(casesPath); | ||||||
|  | 
 | ||||||
|  | 	categories = categories.map(function(cat) { | ||||||
|  | 		return { | ||||||
|  | 			name: cat, | ||||||
|  | 			tests: fs.readdirSync(path.join(casesPath, cat)).filter(function(folder) { | ||||||
|  | 				return folder.indexOf("_") < 0; | ||||||
|  | 			}).sort() | ||||||
|  | 		}; | ||||||
|  | 	}); | ||||||
|  | 	before(function() { | ||||||
|  | 		var dest = path.join(__dirname, "js"); | ||||||
|  | 		if(!fs.existsSync(dest)) | ||||||
|  | 			fs.mkdirSync(dest); | ||||||
|  | 		dest = path.join(__dirname, "js", "watch-src"); | ||||||
|  | 		if(!fs.existsSync(dest)) | ||||||
|  | 			fs.mkdirSync(dest); | ||||||
|  | 	}); | ||||||
|  | 	categories.forEach(function(category) { | ||||||
|  | 		before(function() { | ||||||
|  | 			var dest = path.join(__dirname, "js", "watch-src", category.name); | ||||||
|  | 			if(!fs.existsSync(dest)) | ||||||
|  | 				fs.mkdirSync(dest); | ||||||
|  | 		}) | ||||||
|  | 		describe(category.name, function() { | ||||||
|  | 			category.tests.forEach(function(testName) { | ||||||
|  | 				describe(testName, function() { | ||||||
|  | 					var tempDirectory = path.join(__dirname, "js", "watch-src", category.name, testName); | ||||||
|  | 					var testDirectory = path.join(casesPath, category.name, testName); | ||||||
|  | 					var runs = fs.readdirSync(testDirectory).sort().map(function(name) { | ||||||
|  | 						return { | ||||||
|  | 							name: name, | ||||||
|  | 							suite: describe(name, function() {}) | ||||||
|  | 						} | ||||||
|  | 					}); | ||||||
|  | 					before(function() { | ||||||
|  | 						remove(tempDirectory); | ||||||
|  | 					}); | ||||||
|  | 					it("should compile", function(done) { | ||||||
|  | 						this.timeout(30000); | ||||||
|  | 						var outputDirectory = path.join(__dirname, "js", "watch", category.name, testName); | ||||||
|  | 
 | ||||||
|  | 						var options = { | ||||||
|  | 							context: tempDirectory, | ||||||
|  | 							entry: "./index.js", | ||||||
|  | 							output: { | ||||||
|  | 								path: outputDirectory, | ||||||
|  | 								pathinfo: true, | ||||||
|  | 								filename: "bundle.js" | ||||||
|  | 							} | ||||||
|  | 						}; | ||||||
|  | 
 | ||||||
|  | 						var runIdx = 0; | ||||||
|  | 						var run = runs[runIdx]; | ||||||
|  | 						var lastHash = ""; | ||||||
|  | 						copyDiff(path.join(testDirectory, run.name), tempDirectory); | ||||||
|  | 
 | ||||||
|  | 						var compiler = webpack(options); | ||||||
|  | 						compiler.watch({}, function(err, stats) { | ||||||
|  | 							if(stats.hash === lastHash) | ||||||
|  | 								return; | ||||||
|  | 							lastHash = stats.hash; | ||||||
|  | 							if(run.done) | ||||||
|  | 								return done(new Error("Compilation changed but no change was issued " + lastHash + " != " + stats.hash + " (run " + runIdx + ")")); | ||||||
|  | 							run.done = true; | ||||||
|  | 							if(err) return done(err); | ||||||
|  | 							var statOptions = Stats.presetToOptions("verbose"); | ||||||
|  | 							statOptions.colors = false; | ||||||
|  | 							fs.writeFileSync(path.join(outputDirectory, "stats.txt"), stats.toString(statOptions), "utf-8"); | ||||||
|  | 							var jsonStats = stats.toJson({ | ||||||
|  | 								errorDetails: true | ||||||
|  | 							}); | ||||||
|  | 							if(checkArrayExpectation(testDirectory, jsonStats, "error", "Error", done)) return; | ||||||
|  | 							if(checkArrayExpectation(testDirectory, jsonStats, "warning", "Warning", done)) return; | ||||||
|  | 							var exportedTests = 0; | ||||||
|  | 
 | ||||||
|  | 							function _it(title, fn) { | ||||||
|  | 								var test = new Test(title, fn); | ||||||
|  | 								run.suite.addTest(test); | ||||||
|  | 								exportedTests++; | ||||||
|  | 								return test; | ||||||
|  | 							} | ||||||
|  | 
 | ||||||
|  | 							function _require(currentDirectory, module) { | ||||||
|  | 								if(Array.isArray(module) || /^\.\.?\//.test(module)) { | ||||||
|  | 									var fn; | ||||||
|  | 									var content; | ||||||
|  | 									if(Array.isArray(module)) { | ||||||
|  | 										var p = path.join(currentDirectory, module[0]); | ||||||
|  | 										content = module.map(function(p) { | ||||||
|  | 											var p = path.join(currentDirectory, p); | ||||||
|  | 											return fs.readFileSync(p, "utf-8"); | ||||||
|  | 										}).join("\n"); | ||||||
|  | 									} else { | ||||||
|  | 										var p = path.join(currentDirectory, module); | ||||||
|  | 										content = fs.readFileSync(p, "utf-8"); | ||||||
|  | 									} | ||||||
|  | 									fn = vm.runInThisContext("(function(require, module, exports, __dirname, __filename, it, WATCH_STEP) {" + content + "\n})", p); | ||||||
|  | 									var module = { | ||||||
|  | 										exports: {} | ||||||
|  | 									}; | ||||||
|  | 									fn.call(module.exports, _require.bind(null, path.dirname(p)), module, module.exports, path.dirname(p), p, _it, run.name); | ||||||
|  | 									return module.exports; | ||||||
|  | 								} else if(testConfig.modules && module in testConfig.modules) { | ||||||
|  | 									return testConfig.modules[module]; | ||||||
|  | 								} else return require(module); | ||||||
|  | 							} | ||||||
|  | 
 | ||||||
|  | 							var testConfig = {}; | ||||||
|  | 							try { | ||||||
|  | 								// try to load a test file
 | ||||||
|  | 								testConfig = require(path.join(testDirectory, "test.config.js")); | ||||||
|  | 							} catch(e) {} | ||||||
|  | 
 | ||||||
|  | 							if(testConfig.noTests) return process.nextTick(done); | ||||||
|  | 							_require(outputDirectory, "./bundle.js"); | ||||||
|  | 
 | ||||||
|  | 							if(exportedTests < 1) return done(new Error("No tests exported by test case")); | ||||||
|  | 							runIdx++; | ||||||
|  | 							if(runIdx < runs.length) { | ||||||
|  | 								run = runs[runIdx]; | ||||||
|  | 								copyDiff(path.join(testDirectory, run.name), tempDirectory); | ||||||
|  | 							} else { | ||||||
|  | 								process.nextTick(done); | ||||||
|  | 							} | ||||||
|  | 						}); | ||||||
|  | 					}); | ||||||
|  | 				}); | ||||||
|  | 			}); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | }); | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | export default "original"; | ||||||
|  | @ -0,0 +1,14 @@ | ||||||
|  | import m from "./module"; | ||||||
|  | import cm from "./changing-module"; | ||||||
|  | 
 | ||||||
|  | it("should flag harmony modules correctly", function() { | ||||||
|  | 	m.should.be.eql("module" + WATCH_STEP); | ||||||
|  | 	switch(WATCH_STEP) { | ||||||
|  | 		case 0: | ||||||
|  | 			cm.should.be.eql("original"); | ||||||
|  | 			break; | ||||||
|  | 		case 1: | ||||||
|  | 			cm.should.be.eql("change"); | ||||||
|  | 			break; | ||||||
|  | 	} | ||||||
|  | }); | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | export default "module" + WATCH_STEP; | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | export default "change"; | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | module.exports = "cc0"; | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | module.exports = "ch0"; | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | export default "hc0"; | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | export default "hh0"; | ||||||
|  | @ -0,0 +1,23 @@ | ||||||
|  | import hh from "./hh"; | ||||||
|  | import hc from "./hc"; | ||||||
|  | import ch from "./ch"; | ||||||
|  | import cc from "./cc"; | ||||||
|  | 
 | ||||||
|  | it("should flag modules correctly", function() { | ||||||
|  | 	hh.should.be.eql("hh" + WATCH_STEP); | ||||||
|  | 	cc.should.be.eql("cc" + WATCH_STEP); | ||||||
|  | 	hc.should.be.eql("hc" + WATCH_STEP); | ||||||
|  | 	ch.should.be.eql("ch" + WATCH_STEP); | ||||||
|  | 	require("./hh").default.should.be.eql("hh" + WATCH_STEP); | ||||||
|  | 	require("./cc").should.be.eql("cc" + WATCH_STEP); | ||||||
|  | 	switch(WATCH_STEP) { | ||||||
|  | 		case 0: | ||||||
|  | 			require("./hc").default.should.be.eql("hc0"); | ||||||
|  | 			require("./ch").should.be.eql("ch0"); | ||||||
|  | 			break; | ||||||
|  | 		case 1: | ||||||
|  | 			require("./hc").should.be.eql("hc1"); | ||||||
|  | 			require("./ch").default.should.be.eql("ch1"); | ||||||
|  | 			break; | ||||||
|  | 	} | ||||||
|  | }); | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | module.exports = "cc1"; | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | export default "ch1"; | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | module.exports = "hc1"; | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | export default "hh1"; | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | module.exports = "0"; | ||||||
|  | @ -0,0 +1,3 @@ | ||||||
|  | it("should watch for changes", function() { | ||||||
|  | 	require("./changing-file").should.be.eql(WATCH_STEP); | ||||||
|  | }) | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | module.exports = "1"; | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | module.exports = "2"; | ||||||
		Loading…
	
		Reference in New Issue