Skip to content

Commit 43910f3

Browse files
ekulabuhovjoshwiens
authored andcommitted
test: unit tests for basic configurations
Extracted common config code to utils.js Added travis config Added mocha as devDep Added yarn.lock. Travis CI installs yarn if the file is present. Marked yarn.lock as binary to prevent conflict hell Moved web pack back from peerDep to dep Destructuring is not supported in Node v4.3, so replaced it Node v4 requires "use strict" to allow block scoped let & const Node v4: replaced "spread" operator with "apply"
1 parent 38a7be7 commit 43910f3

File tree

6 files changed

+2329
-1
lines changed

6 files changed

+2329
-1
lines changed

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Treats the lock file as binary & prevents conflict hell
2+
yarn.lock -diff

.travis.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
sudo: false
2+
language: node_js
3+
branches:
4+
only:
5+
- master
6+
matrix:
7+
fast_finish: true
8+
include:
9+
# - os: linux
10+
# node_js: '7'
11+
# env: WEBPACK_VERSION="2.2.0" BITHOUND_CHECK=true JOB_PART=lint
12+
- os: linux
13+
node_js: '7'
14+
env: WEBPACK_VERSION="2.2.0" JOB_PART=test
15+
- os: linux
16+
node_js: '4.3'
17+
env: WEBPACK_VERSION="2.2.0" JOB_PART=test
18+
- os: linux
19+
node_js: '6'
20+
env: WEBPACK_VERSION="2.2.0" JOB_PART=test
21+
# - os: linux
22+
# node_js: '7'
23+
# env: WEBPACK_VERSION="2.2.0" JOB_PART=coverage
24+
before_install:
25+
- nvm --version
26+
- node --version
27+
before_script:
28+
- if [ "$WEBPACK_VERSION" ]; then yarn add webpack@^$WEBPACK_VERSION; fi
29+
# - if [ "$BITHOUND_CHECK" ]; then npm install -g bithound; bithound check [email protected]:$TRAVIS_REPO_SLUG.git; fi
30+
script:
31+
- yarn run travis:$JOB_PART
32+
after_success:
33+
- bash <(curl -s https://codecov.io/bash)

package.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44
"author": "Tobias Koppers @sokra",
55
"description": "style loader module for webpack",
66
"devDependencies": {
7-
"css-loader": "~0.8.0"
7+
"css-loader": "~0.8.0",
8+
"file-loader": "^0.10.1",
9+
"jsdom": "^9.11.0",
10+
"memory-fs": "^0.4.1",
11+
"mocha": "^3.2.0",
12+
"webpack": "^2.2.1"
813
},
914
"repository": {
1015
"type": "git",
@@ -13,5 +18,9 @@
1318
"license": "MIT",
1419
"dependencies": {
1520
"loader-utils": "^1.0.2"
21+
},
22+
"scripts": {
23+
"test": "mocha",
24+
"travis:test": "yarn run test"
1625
}
1726
}

test/basicTest.js

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
// Node v4 requires "use strict" to allow block scoped let & const
2+
"use strict";
3+
4+
describe("basic tests", function() {
5+
var path = require("path");
6+
7+
var utils = require("./utils"),
8+
runCompilerTest = utils.runCompilerTest;
9+
10+
var fs;
11+
12+
var requiredCss = ".required { color: blue }",
13+
requiredCssTwo = ".requiredTwo { color: cyan }",
14+
requiredStyle = `<style type="text/css">${requiredCss}</style>`,
15+
existingStyle = "<style>.existing { color: yellow }</style>",
16+
rootDir = path.resolve(__dirname + "/../") + "/",
17+
jsdomHtml = [
18+
"<html>",
19+
"<head>",
20+
existingStyle,
21+
"</head>",
22+
"<body>",
23+
"</body>",
24+
"</html>"
25+
].join("\n");
26+
27+
var styleLoaderOptions = {};
28+
var cssRule = {};
29+
30+
var defaultCssRule = {
31+
test: /\.css?$/,
32+
use: [
33+
{
34+
loader: "style-loader",
35+
options: styleLoaderOptions
36+
},
37+
"css-loader"
38+
]
39+
};
40+
41+
var webpackConfig = {
42+
entry: "./main.js",
43+
output: {
44+
filename: "bundle.js"
45+
},
46+
module: {
47+
rules: [cssRule]
48+
}
49+
};
50+
51+
beforeEach(function() {
52+
// Reset all style-loader options
53+
for (var member in styleLoaderOptions) {
54+
delete styleLoaderOptions[member];
55+
}
56+
57+
for (var member in defaultCssRule) {
58+
cssRule[member] = defaultCssRule[member];
59+
}
60+
61+
fs = utils.setup(webpackConfig, jsdomHtml);
62+
63+
// Create a tiny file system. rootDir is used because loaders are refering to absolute paths.
64+
fs.mkdirpSync(rootDir);
65+
fs.writeFileSync(rootDir + "main.js", "var css = require('./style.css');");
66+
fs.writeFileSync(rootDir + "style.css", requiredCss);
67+
fs.writeFileSync(rootDir + "styleTwo.css", requiredCssTwo);
68+
}); // before each
69+
70+
it("insert at bottom", function(done) {
71+
let expected = [existingStyle, requiredStyle].join("\n");
72+
73+
runCompilerTest(expected, done);
74+
}); // it insert at bottom
75+
76+
it("insert at top", function(done) {
77+
styleLoaderOptions.insertAt = "top";
78+
79+
let expected = [requiredStyle, existingStyle].join("\n");
80+
81+
runCompilerTest(expected, done);
82+
}); // it insert at top
83+
84+
it("singleton", function(done) {
85+
// Setup
86+
styleLoaderOptions.singleton = true;
87+
88+
fs.writeFileSync(
89+
rootDir + "main.js",
90+
[
91+
"var a = require('./style.css');",
92+
"var b = require('./styleTwo.css');"
93+
].join("\n")
94+
);
95+
96+
// Run
97+
let expected = [
98+
existingStyle,
99+
`<style type="text/css">${requiredCss}${requiredCssTwo}</style>`
100+
].join("\n");
101+
102+
runCompilerTest(expected, done);
103+
}); // it singleton
104+
105+
it("url", function(done) {
106+
cssRule.use = [
107+
{
108+
loader: "style-loader/url",
109+
options: {}
110+
},
111+
"file-loader"
112+
];
113+
114+
// Run
115+
let expected = [
116+
existingStyle,
117+
'<link rel="stylesheet" type="text/css" href="ec9d4f4f24028c3d51bf1e7728e632ff.css">'
118+
].join("\n");
119+
120+
runCompilerTest(expected, done);
121+
}); // it url
122+
123+
it("useable", function(done) {
124+
cssRule.use = [
125+
{
126+
loader: "style-loader/useable",
127+
options: {}
128+
},
129+
"css-loader"
130+
];
131+
132+
fs.writeFileSync(
133+
rootDir + "main.js",
134+
[
135+
"var css = require('./style.css');",
136+
"var cssTwo = require('./styleTwo.css');",
137+
"css.use();",
138+
"cssTwo.use();",
139+
"css.unuse();"
140+
].join("\n")
141+
);
142+
143+
// Run
144+
let expected = [
145+
existingStyle,
146+
`<style type="text/css">${requiredCssTwo}</style>`
147+
].join("\n");
148+
149+
runCompilerTest(expected, done);
150+
}); // it useable
151+
}); // describe

test/utils.js

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Node v4 requires "use strict" to allow block scoped let & const
2+
"use strict";
3+
4+
var MemoryFS = require("memory-fs");
5+
var realFs = require("fs");
6+
var webpack = require("webpack");
7+
var path = require("path");
8+
var jsdom = require("jsdom");
9+
10+
var assert = require("assert");
11+
12+
var compiler;
13+
var jsdomHtml;
14+
15+
module.exports = {
16+
setup: function(webpackConfig, _jsdomHtml) {
17+
let fs = new MemoryFS();
18+
19+
jsdomHtml = _jsdomHtml;
20+
21+
// Makes webpack resolve style-loader to local folder instead of node_modules
22+
Object.assign(webpackConfig, {
23+
resolveLoader: {
24+
alias: {
25+
"style-loader": path.resolve(__dirname, "../")
26+
}
27+
}
28+
});
29+
30+
compiler = webpack(webpackConfig);
31+
32+
// Tell webpack to use our in-memory FS
33+
compiler.inputFileSystem = fs;
34+
compiler.outputFileSystem = fs;
35+
compiler.resolvers.normal.fileSystem = fs;
36+
compiler.resolvers.context.fileSystem = fs;
37+
38+
["readFileSync", "statSync"].forEach(fn => {
39+
// Preserve the reference to original function
40+
fs["mem" + fn] = fs[fn];
41+
42+
compiler.inputFileSystem[fn] = function(_path) {
43+
// Fallback to real FS if file is not in the memoryFS
44+
if (fs.existsSync(_path)) {
45+
return fs["mem" + fn].apply(fs, arguments);
46+
} else {
47+
return realFs[fn].apply(realFs, arguments);
48+
}
49+
};
50+
});
51+
52+
return fs;
53+
},
54+
runCompilerTest: function(expected, done) {
55+
compiler.run(function(err, stats) {
56+
if (stats.compilation.errors.length) {
57+
throw new Error(stats.compilation.errors);
58+
}
59+
60+
const bundleJs = stats.compilation.assets["bundle.js"].source();
61+
62+
jsdom.env({
63+
html: jsdomHtml,
64+
src: [bundleJs],
65+
done: function(err, window) {
66+
assert.equal(window.document.head.innerHTML.trim(), expected);
67+
// free memory associated with the window
68+
window.close();
69+
70+
done();
71+
}
72+
});
73+
});
74+
}
75+
};

0 commit comments

Comments
 (0)