Skip to content

Commit

Permalink
test: unit tests for basic configurations
Browse files Browse the repository at this point in the history
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"
  • Loading branch information
ekulabuhov authored and joshwiens committed Mar 15, 2017
1 parent 38a7be7 commit 43910f3
Show file tree
Hide file tree
Showing 6 changed files with 2,329 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Treats the lock file as binary & prevents conflict hell
yarn.lock -diff
33 changes: 33 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
sudo: false
language: node_js
branches:
only:
- master
matrix:
fast_finish: true
include:
# - os: linux
# node_js: '7'
# env: WEBPACK_VERSION="2.2.0" BITHOUND_CHECK=true JOB_PART=lint
- os: linux
node_js: '7'
env: WEBPACK_VERSION="2.2.0" JOB_PART=test
- os: linux
node_js: '4.3'
env: WEBPACK_VERSION="2.2.0" JOB_PART=test
- os: linux
node_js: '6'
env: WEBPACK_VERSION="2.2.0" JOB_PART=test
# - os: linux
# node_js: '7'
# env: WEBPACK_VERSION="2.2.0" JOB_PART=coverage
before_install:
- nvm --version
- node --version
before_script:
- if [ "$WEBPACK_VERSION" ]; then yarn add webpack@^$WEBPACK_VERSION; fi
# - if [ "$BITHOUND_CHECK" ]; then npm install -g bithound; bithound check [email protected]:$TRAVIS_REPO_SLUG.git; fi
script:
- yarn run travis:$JOB_PART
after_success:
- bash <(curl -s https://codecov.io/bash)
11 changes: 10 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@
"author": "Tobias Koppers @sokra",
"description": "style loader module for webpack",
"devDependencies": {
"css-loader": "~0.8.0"
"css-loader": "~0.8.0",
"file-loader": "^0.10.1",
"jsdom": "^9.11.0",
"memory-fs": "^0.4.1",
"mocha": "^3.2.0",
"webpack": "^2.2.1"
},
"repository": {
"type": "git",
Expand All @@ -13,5 +18,9 @@
"license": "MIT",
"dependencies": {
"loader-utils": "^1.0.2"
},
"scripts": {
"test": "mocha",
"travis:test": "yarn run test"
}
}
151 changes: 151 additions & 0 deletions test/basicTest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
// Node v4 requires "use strict" to allow block scoped let & const
"use strict";

describe("basic tests", function() {
var path = require("path");

var utils = require("./utils"),
runCompilerTest = utils.runCompilerTest;

var fs;

var requiredCss = ".required { color: blue }",
requiredCssTwo = ".requiredTwo { color: cyan }",
requiredStyle = `<style type="text/css">${requiredCss}</style>`,
existingStyle = "<style>.existing { color: yellow }</style>",
rootDir = path.resolve(__dirname + "/../") + "/",
jsdomHtml = [
"<html>",
"<head>",
existingStyle,
"</head>",
"<body>",
"</body>",
"</html>"
].join("\n");

var styleLoaderOptions = {};
var cssRule = {};

var defaultCssRule = {
test: /\.css?$/,
use: [
{
loader: "style-loader",
options: styleLoaderOptions
},
"css-loader"
]
};

var webpackConfig = {
entry: "./main.js",
output: {
filename: "bundle.js"
},
module: {
rules: [cssRule]
}
};

beforeEach(function() {
// Reset all style-loader options
for (var member in styleLoaderOptions) {
delete styleLoaderOptions[member];
}

for (var member in defaultCssRule) {
cssRule[member] = defaultCssRule[member];
}

fs = utils.setup(webpackConfig, jsdomHtml);

// Create a tiny file system. rootDir is used because loaders are refering to absolute paths.
fs.mkdirpSync(rootDir);
fs.writeFileSync(rootDir + "main.js", "var css = require('./style.css');");
fs.writeFileSync(rootDir + "style.css", requiredCss);
fs.writeFileSync(rootDir + "styleTwo.css", requiredCssTwo);
}); // before each

it("insert at bottom", function(done) {
let expected = [existingStyle, requiredStyle].join("\n");

runCompilerTest(expected, done);
}); // it insert at bottom

it("insert at top", function(done) {
styleLoaderOptions.insertAt = "top";

let expected = [requiredStyle, existingStyle].join("\n");

runCompilerTest(expected, done);
}); // it insert at top

it("singleton", function(done) {
// Setup
styleLoaderOptions.singleton = true;

fs.writeFileSync(
rootDir + "main.js",
[
"var a = require('./style.css');",
"var b = require('./styleTwo.css');"
].join("\n")
);

// Run
let expected = [
existingStyle,
`<style type="text/css">${requiredCss}${requiredCssTwo}</style>`
].join("\n");

runCompilerTest(expected, done);
}); // it singleton

it("url", function(done) {
cssRule.use = [
{
loader: "style-loader/url",
options: {}
},
"file-loader"
];

// Run
let expected = [
existingStyle,
'<link rel="stylesheet" type="text/css" href="ec9d4f4f24028c3d51bf1e7728e632ff.css">'
].join("\n");

runCompilerTest(expected, done);
}); // it url

it("useable", function(done) {
cssRule.use = [
{
loader: "style-loader/useable",
options: {}
},
"css-loader"
];

fs.writeFileSync(
rootDir + "main.js",
[
"var css = require('./style.css');",
"var cssTwo = require('./styleTwo.css');",
"css.use();",
"cssTwo.use();",
"css.unuse();"
].join("\n")
);

// Run
let expected = [
existingStyle,
`<style type="text/css">${requiredCssTwo}</style>`
].join("\n");

runCompilerTest(expected, done);
}); // it useable
}); // describe
75 changes: 75 additions & 0 deletions test/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Node v4 requires "use strict" to allow block scoped let & const
"use strict";

var MemoryFS = require("memory-fs");
var realFs = require("fs");
var webpack = require("webpack");
var path = require("path");
var jsdom = require("jsdom");

var assert = require("assert");

var compiler;
var jsdomHtml;

module.exports = {
setup: function(webpackConfig, _jsdomHtml) {
let fs = new MemoryFS();

jsdomHtml = _jsdomHtml;

// Makes webpack resolve style-loader to local folder instead of node_modules
Object.assign(webpackConfig, {
resolveLoader: {
alias: {
"style-loader": path.resolve(__dirname, "../")
}
}
});

compiler = webpack(webpackConfig);

// Tell webpack to use our in-memory FS
compiler.inputFileSystem = fs;
compiler.outputFileSystem = fs;
compiler.resolvers.normal.fileSystem = fs;
compiler.resolvers.context.fileSystem = fs;

["readFileSync", "statSync"].forEach(fn => {
// Preserve the reference to original function
fs["mem" + fn] = fs[fn];

compiler.inputFileSystem[fn] = function(_path) {
// Fallback to real FS if file is not in the memoryFS
if (fs.existsSync(_path)) {
return fs["mem" + fn].apply(fs, arguments);
} else {
return realFs[fn].apply(realFs, arguments);
}
};
});

return fs;
},
runCompilerTest: function(expected, done) {
compiler.run(function(err, stats) {
if (stats.compilation.errors.length) {
throw new Error(stats.compilation.errors);
}

const bundleJs = stats.compilation.assets["bundle.js"].source();

jsdom.env({
html: jsdomHtml,
src: [bundleJs],
done: function(err, window) {
assert.equal(window.document.head.innerHTML.trim(), expected);
// free memory associated with the window
window.close();

done();
}
});
});
}
};
Loading

0 comments on commit 43910f3

Please sign in to comment.