| 
									
										
										
										
											2017-04-06 16:19:43 +08:00
										 |  |  | "use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const should = require("should"); | 
					
						
							|  |  |  | const sinon = require("sinon"); | 
					
						
							|  |  |  | const WebWorkerMainTemplatePlugin = require("../lib/webworker/WebWorkerMainTemplatePlugin"); | 
					
						
							|  |  |  | const applyPluginWithOptions = require("./helpers/applyPluginWithOptions"); | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | describe("WebWorkerMainTemplatePlugin", function() { | 
					
						
							| 
									
										
										
										
											2017-04-06 16:19:43 +08:00
										 |  |  | 	let env; | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 16:19:43 +08:00
										 |  |  | 	beforeEach(() => { | 
					
						
							| 
									
										
										
										
											2017-04-06 17:10:43 +08:00
										 |  |  | 		env = {}; | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 	}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	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) => { | 
					
						
							| 
									
										
										
										
											2017-04-06 16:19:43 +08:00
										 |  |  | 					return `"${moduleName}${data.hash}${data.hashWithLength()}${data.chunk && data.chunk.id || ''}"`; | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 				}, | 
					
						
							|  |  |  | 				renderAddModule: () => 'renderAddModuleSource();', | 
					
						
							|  |  |  | 			}; | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		it("binds five event handlers", function() { | 
					
						
							|  |  |  | 			env.eventBindings.length.should.be.exactly(5); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		describe("local-vars handler", function() { | 
					
						
							| 
									
										
										
										
											2017-04-06 16:19:43 +08:00
										 |  |  | 			beforeEach(() => { | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 				env.eventBinding = env.eventBindings[0]; | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 16:19:43 +08:00
										 |  |  | 			it("binds to local-vars event", () => { | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 				env.eventBinding.name.should.be.exactly("local-vars"); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 16:19:43 +08:00
										 |  |  | 			describe("when no chunks are provided", () => { | 
					
						
							|  |  |  | 				beforeEach(() => { | 
					
						
							|  |  |  | 					const chunk = { | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 						ids: [], | 
					
						
							|  |  |  | 						chunks: [] | 
					
						
							|  |  |  | 					}; | 
					
						
							|  |  |  | 					env.source = env.eventBinding.handler.call(env.handlerContext, "moduleSource()", chunk); | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 16:19:43 +08:00
										 |  |  | 				it("returns the original source", () => { | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 					env.source.should.be.exactly("moduleSource()") | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 16:19:43 +08:00
										 |  |  | 			describe("when chunks are provided", () => { | 
					
						
							|  |  |  | 				beforeEach(() => { | 
					
						
							|  |  |  | 					const chunk = { | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 						ids: [1, 2, 3], | 
					
						
							|  |  |  | 						chunks: [ | 
					
						
							|  |  |  | 							'foo', | 
					
						
							|  |  |  | 							'bar', | 
					
						
							|  |  |  | 							'baz' | 
					
						
							|  |  |  | 						] | 
					
						
							|  |  |  | 					}; | 
					
						
							|  |  |  | 					env.source = env.eventBinding.handler.call(env.handlerContext, "moduleSource()", chunk, 'abc123'); | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 16:19:43 +08:00
										 |  |  | 				it("returns the original source with installed mapping", () => { | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 					env.source.should.be.exactly(`
 | 
					
						
							|  |  |  | moduleSource() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // object to store loaded chunks
 | 
					
						
							|  |  |  | // "1" means "already loaded"
 | 
					
						
							|  |  |  | var installedChunks = { | 
					
						
							|  |  |  | 1: 1, | 
					
						
							|  |  |  | 2: 1, | 
					
						
							|  |  |  | 3: 1 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | `.trim())
 | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 16:19:43 +08:00
										 |  |  | 		describe("require-ensure handler", () => { | 
					
						
							|  |  |  | 			beforeEach(() => { | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 				env.eventBinding = env.eventBindings[1]; | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 16:19:43 +08:00
										 |  |  | 			it("binds to require-ensure event", () => { | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 				env.eventBinding.name.should.be.exactly("require-ensure"); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 16:19:43 +08:00
										 |  |  | 			describe("when called", () => { | 
					
						
							|  |  |  | 				beforeEach(() => { | 
					
						
							|  |  |  | 					const chunk = {}; | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 					env.source = env.eventBinding.handler.call(env.handlerContext, "moduleSource()", chunk, 'abc123'); | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 16:19:43 +08:00
										 |  |  | 				it("creates import scripts call and promise resolve", () => { | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 					env.source.should.be.exactly(`
 | 
					
						
							| 
									
										
										
										
											2017-05-24 15:44:35 +08:00
										 |  |  | return new Promise(function(resolve) { | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | // "1" is the signal for "already loaded"
 | 
					
						
							|  |  |  | if(!installedChunks[chunkId]) { | 
					
						
							|  |  |  | importScripts("asset-path" + abc123 + "" + abc123 + "" + chunkId + ""); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-05-24 15:44:35 +08:00
										 |  |  | resolve(); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | `.trim())
 | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 16:19:43 +08:00
										 |  |  | 		describe("bootstrap handler", () => { | 
					
						
							|  |  |  | 			beforeEach(() => { | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 				env.eventBinding = env.eventBindings[2]; | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 16:19:43 +08:00
										 |  |  | 			it("binds to bootstrap event", () => { | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 				env.eventBinding.name.should.be.exactly("bootstrap"); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 16:19:43 +08:00
										 |  |  | 			describe("when no chunks are provided", () => { | 
					
						
							|  |  |  | 				beforeEach(() => { | 
					
						
							|  |  |  | 					const chunk = { | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 						ids: [], | 
					
						
							|  |  |  | 						chunks: [] | 
					
						
							|  |  |  | 					}; | 
					
						
							|  |  |  | 					env.source = env.eventBinding.handler.call(env.handlerContext, "moduleSource()", chunk); | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 16:19:43 +08:00
										 |  |  | 				it("returns the original source", () => { | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 					env.source.should.be.exactly("moduleSource()") | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 16:19:43 +08:00
										 |  |  | 			describe("when chunks are provided", () => { | 
					
						
							|  |  |  | 				beforeEach(() => { | 
					
						
							|  |  |  | 					const chunk = { | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 						ids: [1, 2, 3], | 
					
						
							|  |  |  | 						chunks: [ | 
					
						
							|  |  |  | 							'foo', | 
					
						
							|  |  |  | 							'bar', | 
					
						
							|  |  |  | 							'baz' | 
					
						
							|  |  |  | 						] | 
					
						
							|  |  |  | 					}; | 
					
						
							|  |  |  | 					env.source = env.eventBinding.handler.call(env.handlerContext, "moduleSource()", chunk); | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 16:19:43 +08:00
										 |  |  | 				it("returns the original source with chunk callback", () => { | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 					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())
 | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 16:19:43 +08:00
										 |  |  | 		describe("hot-bootstrap handler", () => { | 
					
						
							|  |  |  | 			beforeEach(() => { | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 				env.eventBinding = env.eventBindings[3]; | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 16:19:43 +08:00
										 |  |  | 			it("binds to hot-bootstrap event", () => { | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 				env.eventBinding.name.should.be.exactly("hot-bootstrap"); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 16:19:43 +08:00
										 |  |  | 			describe("when called", () => { | 
					
						
							|  |  |  | 				beforeEach(() => { | 
					
						
							|  |  |  | 					const chunk = {}; | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 					env.source = env.eventBinding.handler.call(env.handlerContext, "moduleSource()", chunk, 'abc123'); | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 16:19:43 +08:00
										 |  |  | 				it("returns the original source with hot update callback", () => { | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 					env.source.should.be.exactly(`
 | 
					
						
							|  |  |  | moduleSource() | 
					
						
							| 
									
										
										
										
											2017-10-30 15:43:56 +08:00
										 |  |  | var parentHotUpdateCallback = self["webpackHotUpdate"]; | 
					
						
							|  |  |  | self["webpackHotUpdate"] = function webpackHotUpdateCallback(chunkId, moreModules) { // eslint-disable-line no-unused-vars
 | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 	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 + ""); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-22 07:59:45 +08:00
										 |  |  | function hotDownloadManifest(requestTimeout) { // eslint-disable-line no-unused-vars
 | 
					
						
							|  |  |  | 	requestTimeout = requestTimeout || 10000; | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 	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); | 
					
						
							| 
									
										
										
										
											2017-05-22 07:59:45 +08:00
										 |  |  | 			request.timeout = requestTimeout; | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 			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())
 | 
					
						
							|  |  |  | 				}); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 16:19:43 +08:00
										 |  |  | 		describe("hash handler", () => { | 
					
						
							|  |  |  | 			beforeEach(() => { | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 				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); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 16:19:43 +08:00
										 |  |  | 			it("binds to hash event", () => { | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 				env.eventBinding.name.should.be.exactly("hash"); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-06 16:19:43 +08:00
										 |  |  | 			it("updates hash object", () => { | 
					
						
							| 
									
										
										
										
											2017-01-08 20:07:38 +08:00
										 |  |  | 				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"); | 
					
						
							|  |  |  | 			}); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	}); | 
					
						
							|  |  |  | }); |