Skip to content

Commit 7421d47

Browse files
committed
add unit tests for ExternalModule
1 parent 375e7d2 commit 7421d47

2 files changed

Lines changed: 190 additions & 12 deletions

File tree

lib/ExternalModule.js

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,16 @@ const WebpackMissingModule = require("./dependencies/WebpackMissingModule");
1111
class ExternalModule extends Module {
1212
constructor(request, type) {
1313
super();
14-
this.chunkCondition = function(chunk) {
15-
return chunk.hasEntryModule();
16-
};
1714
this.request = request;
1815
this.type = type;
1916
this.built = false;
2017
this.external = true;
2118
}
2219

20+
chunkCondition(chunk) {
21+
return chunk.hasEntryModule();
22+
}
23+
2324
identifier() {
2425
return "external " + JSON.stringify(this.request);
2526
}
@@ -37,23 +38,24 @@ class ExternalModule extends Module {
3738
callback();
3839
}
3940

40-
getSourceForGlobalVariableExternal(request, type) {
41-
if(!Array.isArray(request)) {
42-
return `(function() { module.exports = ${type}[${JSON.stringify(request)}]; }());`;
41+
getSourceForGlobalVariableExternal(variableName, type) {
42+
if(!Array.isArray(variableName)) {
43+
// make it an array as the look up works the same basically
44+
variableName = [variableName];
4345
}
4446

4547
// needed for e.g. window["some"]["thing"]
46-
const objectLookup = request.map(r => `[${JSON.stringify(r)}]`).join("");
48+
const objectLookup = variableName.map(r => `[${JSON.stringify(r)}]`).join("");
4749
return `(function() { module.exports = ${type}${objectLookup}; }());`;
4850
}
4951

50-
getSourceForCommonJsExternal(request) {
51-
if(!Array.isArray(request)) {
52-
return `module.exports = require(${JSON.stringify(request)});`;
52+
getSourceForCommonJsExternal(moduleAndSpecifiers) {
53+
if(!Array.isArray(moduleAndSpecifiers)) {
54+
return `module.exports = require(${JSON.stringify(moduleAndSpecifiers)});`;
5355
}
5456

55-
const moduleName = request[0];
56-
const objectLookup = request.slice(1).map(r => `[${JSON.stringify(r)}]`).join("");
57+
const moduleName = moduleAndSpecifiers[0];
58+
const objectLookup = moduleAndSpecifiers.slice(1).map(r => `[${JSON.stringify(r)}]`).join("");
5759
return `module.exports = require(${moduleName})${objectLookup};`;
5860
}
5961

test/ExternalModule.test.js

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
/* globals describe, it, beforeEach, afterEach */
2+
"use strict";
3+
require("should");
4+
const sinon = require("sinon");
5+
const ExternalModule = require("../lib/ExternalModule");
6+
const path = require("path");
7+
const SourceMapSource = require("webpack-sources").SourceMapSource;
8+
const OriginalSource = require("webpack-sources").OriginalSource;
9+
const RawSource = require("webpack-sources").RawSource;
10+
11+
describe("ExternalModule", function() {
12+
let externalModule;
13+
let request;
14+
let type;
15+
beforeEach(function() {
16+
request = "some/request";
17+
type = "some-type";
18+
externalModule = new ExternalModule(
19+
request,
20+
type
21+
);
22+
});
23+
describe("#identifier", function() {
24+
it("returns an identifier for this module", function() {
25+
const expected = `external "${request}"`;
26+
externalModule.identifier().should.eql(expected);
27+
});
28+
});
29+
30+
describe("#readableIdentifier", function() {
31+
it("returns an identifier for this module", function() {
32+
const expected = `external "${request}"`;
33+
externalModule.identifier().should.eql(expected);
34+
});
35+
});
36+
37+
describe("#needRebuild", function() {
38+
it("always returns false", function() {
39+
externalModule.needRebuild().should.eql(false);
40+
});
41+
});
42+
43+
describe("#size", function() {
44+
it("always returns 42", function() {
45+
externalModule.size().should.eql(42);
46+
});
47+
});
48+
49+
describe("#source", function() {
50+
it("calls getSource with the result of getSourceString", function() {
51+
// set up
52+
const expectedString = "something expected stringy";
53+
const expectedSource = "something expected sourcy";
54+
externalModule.getSource = sinon.stub().returns(expectedSource);
55+
externalModule.getSourceString = sinon.stub().returns(expectedString);
56+
57+
// invoke
58+
const result = externalModule.source();
59+
60+
// check
61+
externalModule.getSource.callCount.should.eql(1);
62+
externalModule.getSourceString.callCount.should.eql(1);
63+
externalModule.getSource.args[0][0].should.eql(expectedString);
64+
result.should.eql(expectedSource);
65+
});
66+
});
67+
68+
describe("#getSource", function() {
69+
describe("given it should use source maps", function() {
70+
beforeEach(function() {
71+
externalModule.useSourceMap = true;
72+
});
73+
it("returns an instance of OriginalSource", function() {
74+
// set up
75+
const someSourceString = "some source string";
76+
77+
// invoke
78+
const result = externalModule.getSource(someSourceString);
79+
80+
// check
81+
result.should.be.instanceOf(OriginalSource);
82+
});
83+
});
84+
describe("given it does not use source maps", function() {
85+
beforeEach(function() {
86+
externalModule.useSourceMap = false;
87+
});
88+
it("returns an instance of RawSource", function() {
89+
// set up
90+
const someSourceString = "some source string";
91+
92+
// invoke
93+
const result = externalModule.getSource(someSourceString);
94+
95+
// check
96+
result.should.be.instanceOf(RawSource);
97+
});
98+
});
99+
});
100+
101+
describe("#getSourceForGlobalVariableExternal", function() {
102+
describe("given an array as variable name in the global namespace", function() {
103+
it("use the array as lookup in the global object", function() {
104+
// set up
105+
const type = "window";
106+
const varName = ["foo", "bar"];
107+
const expected = "(function() { module.exports = window[\"foo\"][\"bar\"]; }());";
108+
109+
// invoke
110+
const result = externalModule.getSourceForGlobalVariableExternal(varName, type);
111+
112+
// check
113+
result.should.eql(expected);
114+
});
115+
});
116+
describe("given an single variable name", function() {
117+
it("look it up in the global namespace", function() {
118+
// set up
119+
const type = "window";
120+
const varName = "foo";
121+
const expected = "(function() { module.exports = window[\"foo\"]; }());";
122+
123+
// invoke
124+
const result = externalModule.getSourceForGlobalVariableExternal(varName, type);
125+
126+
// check
127+
result.should.eql(expected);
128+
});
129+
});
130+
});
131+
132+
describe("#getSourceForCommonJsExternal", function() {
133+
describe("given an array as names in the global namespace", function() {
134+
it("use the first to require a module and the rest as lookup on the required module", function() {
135+
// set up
136+
const varName = ["module", "look", "up"];
137+
const expected = "module.exports = require(module)[\"look\"][\"up\"];";
138+
139+
// invoke
140+
const result = externalModule.getSourceForCommonJsExternal(varName, type);
141+
142+
// check
143+
result.should.eql(expected);
144+
});
145+
});
146+
describe("given an single variable name", function() {
147+
it("require a module with that name", function() {
148+
// set up
149+
const type = "window";
150+
const varName = "foo";
151+
const expected = "module.exports = require(\"foo\");";
152+
153+
// invoke
154+
const result = externalModule.getSourceForCommonJsExternal(varName, type);
155+
156+
// check
157+
result.should.eql(expected);
158+
});
159+
});
160+
});
161+
162+
describe("#checkExternalVariable", function() {
163+
it("creates a check that fails if a variable does not exist", function() {
164+
// set up
165+
const variableToCheck = "foo";
166+
const request = "bar";
167+
const expected = "if(typeof foo === 'undefined') {var e = new Error(\"Cannot find module \\\"bar\\\"\"); e.code = 'MODULE_NOT_FOUND';; throw e;}";
168+
169+
// invoke
170+
const result = externalModule.checkExternalVariable(variableToCheck, request);
171+
172+
// check
173+
result.should.eql(expected);
174+
});
175+
});
176+
});

0 commit comments

Comments
 (0)