mirror of https://github.com/webpack/webpack.git
				
				
				
			
		
			
				
	
	
		
			283 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
			
		
		
	
	
			283 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
| "use strict";
 | |
| 
 | |
| const should = require("should");
 | |
| const sinon = require("sinon");
 | |
| const WebWorkerMainTemplatePlugin = require("../lib/webworker/WebWorkerMainTemplatePlugin");
 | |
| const applyPluginWithOptions = require("./helpers/applyPluginWithOptions");
 | |
| 
 | |
| describe("WebWorkerMainTemplatePlugin", function() {
 | |
| 	let env;
 | |
| 
 | |
| 	beforeEach(() => {
 | |
| 		env = {};
 | |
| 	});
 | |
| 
 | |
| 	it("has apply function", function() {
 | |
| 		(new WebWorkerMainTemplatePlugin()).apply.should.be.a.Function();
 | |
| 	});
 | |
| 
 | |
| 	describe("when applied", function() {
 | |
| 		beforeEach(function() {
 | |
| 			env.eventBindings = applyPluginWithOptions(WebWorkerMainTemplatePlugin);
 | |
| 			env.handlerContext = {
 | |
| 				requireFn: 'requireFn',
 | |
| 				indent: (value) => typeof value === 'string' ? value : value.join("\n"),
 | |
| 				asString: (values) => values.join("\n"),
 | |
| 				renderCurrentHashCode: (value) => value,
 | |
| 				outputOptions: {
 | |
| 					chunkFilename: 'chunkFilename'
 | |
| 				},
 | |
| 				applyPluginsWaterfall: (moduleName, fileName, data) => {
 | |
| 					return `"${moduleName}${data.hash}${data.hashWithLength()}${data.chunk && data.chunk.id || ''}"`;
 | |
| 				},
 | |
| 				renderAddModule: () => 'renderAddModuleSource();',
 | |
| 			};
 | |
| 		});
 | |
| 
 | |
| 		it("binds five event handlers", function() {
 | |
| 			env.eventBindings.length.should.be.exactly(5);
 | |
| 		});
 | |
| 
 | |
| 		describe("local-vars handler", function() {
 | |
| 			beforeEach(() => {
 | |
| 				env.eventBinding = env.eventBindings[0];
 | |
| 			});
 | |
| 
 | |
| 			it("binds to local-vars event", () => {
 | |
| 				env.eventBinding.name.should.be.exactly("local-vars");
 | |
| 			});
 | |
| 
 | |
| 			describe("when no chunks are provided", () => {
 | |
| 				beforeEach(() => {
 | |
| 					const chunk = {
 | |
| 						ids: [],
 | |
| 						chunks: []
 | |
| 					};
 | |
| 					env.source = env.eventBinding.handler.call(env.handlerContext, "moduleSource()", chunk);
 | |
| 				});
 | |
| 
 | |
| 				it("returns the original source", () => {
 | |
| 					env.source.should.be.exactly("moduleSource()")
 | |
| 				});
 | |
| 			});
 | |
| 
 | |
| 			describe("when chunks are provided", () => {
 | |
| 				beforeEach(() => {
 | |
| 					const chunk = {
 | |
| 						ids: [1, 2, 3],
 | |
| 						chunks: [
 | |
| 							'foo',
 | |
| 							'bar',
 | |
| 							'baz'
 | |
| 						]
 | |
| 					};
 | |
| 					env.source = env.eventBinding.handler.call(env.handlerContext, "moduleSource()", chunk, 'abc123');
 | |
| 				});
 | |
| 
 | |
| 				it("returns the original source with installed mapping", () => {
 | |
| 					env.source.should.be.exactly(`
 | |
| moduleSource()
 | |
| 
 | |
| // object to store loaded chunks
 | |
| // "1" means "already loaded"
 | |
| var installedChunks = {
 | |
| 1: 1,
 | |
| 2: 1,
 | |
| 3: 1
 | |
| };
 | |
| `.trim())
 | |
| 				});
 | |
| 			});
 | |
| 		});
 | |
| 
 | |
| 		describe("require-ensure handler", () => {
 | |
| 			beforeEach(() => {
 | |
| 				env.eventBinding = env.eventBindings[1];
 | |
| 			});
 | |
| 
 | |
| 			it("binds to require-ensure event", () => {
 | |
| 				env.eventBinding.name.should.be.exactly("require-ensure");
 | |
| 			});
 | |
| 
 | |
| 			describe("when called", () => {
 | |
| 				beforeEach(() => {
 | |
| 					const chunk = {};
 | |
| 					env.source = env.eventBinding.handler.call(env.handlerContext, "moduleSource()", chunk, 'abc123');
 | |
| 				});
 | |
| 
 | |
| 				it("creates import scripts call and promise resolve", () => {
 | |
| 					env.source.should.be.exactly(`
 | |
| return new Promise(function(resolve) {
 | |
| // "1" is the signal for "already loaded"
 | |
| if(!installedChunks[chunkId]) {
 | |
| importScripts("asset-path" + abc123 + "" + abc123 + "" + chunkId + "");
 | |
| }
 | |
| resolve();
 | |
| });
 | |
| `.trim())
 | |
| 				});
 | |
| 			});
 | |
| 		});
 | |
| 
 | |
| 		describe("bootstrap handler", () => {
 | |
| 			beforeEach(() => {
 | |
| 				env.eventBinding = env.eventBindings[2];
 | |
| 			});
 | |
| 
 | |
| 			it("binds to bootstrap event", () => {
 | |
| 				env.eventBinding.name.should.be.exactly("bootstrap");
 | |
| 			});
 | |
| 
 | |
| 			describe("when no chunks are provided", () => {
 | |
| 				beforeEach(() => {
 | |
| 					const chunk = {
 | |
| 						ids: [],
 | |
| 						chunks: []
 | |
| 					};
 | |
| 					env.source = env.eventBinding.handler.call(env.handlerContext, "moduleSource()", chunk);
 | |
| 				});
 | |
| 
 | |
| 				it("returns the original source", () => {
 | |
| 					env.source.should.be.exactly("moduleSource()")
 | |
| 				});
 | |
| 			});
 | |
| 
 | |
| 			describe("when chunks are provided", () => {
 | |
| 				beforeEach(() => {
 | |
| 					const chunk = {
 | |
| 						ids: [1, 2, 3],
 | |
| 						chunks: [
 | |
| 							'foo',
 | |
| 							'bar',
 | |
| 							'baz'
 | |
| 						]
 | |
| 					};
 | |
| 					env.source = env.eventBinding.handler.call(env.handlerContext, "moduleSource()", chunk);
 | |
| 				});
 | |
| 
 | |
| 				it("returns the original source with chunk callback", () => {
 | |
| 					env.source.should.be.exactly(`
 | |
| moduleSource()
 | |
| this["webpackChunk"] = function webpackChunkCallback(chunkIds, moreModules) {
 | |
| for(var moduleId in moreModules) {
 | |
| renderAddModuleSource();
 | |
| }
 | |
| while(chunkIds.length)
 | |
| installedChunks[chunkIds.pop()] = 1;
 | |
| };
 | |
| `.trim())
 | |
| 				});
 | |
| 			});
 | |
| 		});
 | |
| 
 | |
| 		describe("hot-bootstrap handler", () => {
 | |
| 			beforeEach(() => {
 | |
| 				env.eventBinding = env.eventBindings[3];
 | |
| 			});
 | |
| 
 | |
| 			it("binds to hot-bootstrap event", () => {
 | |
| 				env.eventBinding.name.should.be.exactly("hot-bootstrap");
 | |
| 			});
 | |
| 
 | |
| 			describe("when called", () => {
 | |
| 				beforeEach(() => {
 | |
| 					const chunk = {};
 | |
| 					env.source = env.eventBinding.handler.call(env.handlerContext, "moduleSource()", chunk, 'abc123');
 | |
| 				});
 | |
| 
 | |
| 				it("returns the original source with hot update callback", () => {
 | |
| 					env.source.should.be.exactly(`
 | |
| moduleSource()
 | |
| var parentHotUpdateCallback = this["webpackHotUpdate"];
 | |
| this["webpackHotUpdate"] = function webpackHotUpdateCallback(chunkId, moreModules) { // eslint-disable-line no-unused-vars
 | |
| 	hotAddUpdateChunk(chunkId, moreModules);
 | |
| 	if(parentHotUpdateCallback) parentHotUpdateCallback(chunkId, moreModules);
 | |
| } ;
 | |
| 
 | |
| function hotDownloadUpdateChunk(chunkId) { // eslint-disable-line no-unused-vars
 | |
| 	importScripts(requireFn.p + "asset-path" + abc123 + "" + abc123 + "" + chunkId + "");
 | |
| }
 | |
| 
 | |
| function hotDownloadManifest(requestTimeout) { // eslint-disable-line no-unused-vars
 | |
| 	requestTimeout = requestTimeout || 10000;
 | |
| 	return new Promise(function(resolve, reject) {
 | |
| 		if(typeof XMLHttpRequest === "undefined")
 | |
| 			return reject(new Error("No browser support"));
 | |
| 		try {
 | |
| 			var request = new XMLHttpRequest();
 | |
| 			var requestPath = requireFn.p + "asset-path" + abc123 + "" + abc123 + "";
 | |
| 			request.open("GET", requestPath, true);
 | |
| 			request.timeout = requestTimeout;
 | |
| 			request.send(null);
 | |
| 		} catch(err) {
 | |
| 			return reject(err);
 | |
| 		}
 | |
| 		request.onreadystatechange = function() {
 | |
| 			if(request.readyState !== 4) return;
 | |
| 			if(request.status === 0) {
 | |
| 				// timeout
 | |
| 				reject(new Error("Manifest request to " + requestPath + " timed out."));
 | |
| 			} else if(request.status === 404) {
 | |
| 				// no update available
 | |
| 				resolve();
 | |
| 			} else if(request.status !== 200 && request.status !== 304) {
 | |
| 				// other failure
 | |
| 				reject(new Error("Manifest request to " + requestPath + " failed."));
 | |
| 			} else {
 | |
| 				// success
 | |
| 				try {
 | |
| 					var update = JSON.parse(request.responseText);
 | |
| 				} catch(e) {
 | |
| 					reject(e);
 | |
| 					return;
 | |
| 				}
 | |
| 				resolve(update);
 | |
| 			}
 | |
| 		};
 | |
| 	});
 | |
| }
 | |
| 
 | |
| function hotDisposeChunk(chunkId) { //eslint-disable-line no-unused-vars
 | |
| 	delete installedChunks[chunkId];
 | |
| }
 | |
| `.trim())
 | |
| 				});
 | |
| 			});
 | |
| 		});
 | |
| 
 | |
| 		describe("hash handler", () => {
 | |
| 			beforeEach(() => {
 | |
| 				env.eventBinding = env.eventBindings[4];
 | |
| 				env.handlerContext = {
 | |
| 					outputOptions: {
 | |
| 						publicPath: "Alpha",
 | |
| 						filename: "Bravo",
 | |
| 						chunkFilename: "Charlie",
 | |
| 						chunkCallbackName: "Delta",
 | |
| 						library: "Echo"
 | |
| 					}
 | |
| 				};
 | |
| 				env.hashMock = {
 | |
| 					update: sinon.spy()
 | |
| 				};
 | |
| 				env.eventBinding.handler.call(env.handlerContext, env.hashMock);
 | |
| 			});
 | |
| 
 | |
| 			it("binds to hash event", () => {
 | |
| 				env.eventBinding.name.should.be.exactly("hash");
 | |
| 			});
 | |
| 
 | |
| 			it("updates hash object", () => {
 | |
| 				env.hashMock.update.callCount.should.be.exactly(7);
 | |
| 				sinon.assert.calledWith(env.hashMock.update, "webworker");
 | |
| 				sinon.assert.calledWith(env.hashMock.update, "3");
 | |
| 				sinon.assert.calledWith(env.hashMock.update, "Alpha");
 | |
| 				sinon.assert.calledWith(env.hashMock.update, "Bravo");
 | |
| 				sinon.assert.calledWith(env.hashMock.update, "Charlie");
 | |
| 				sinon.assert.calledWith(env.hashMock.update, "Delta");
 | |
| 				sinon.assert.calledWith(env.hashMock.update, "Echo");
 | |
| 			});
 | |
| 		});
 | |
| 	});
 | |
| });
 |