Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Build and run tests with webpack #770

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ node_modules
# Parcel build dirs
.cache
tests/dist
tests/dist-webpack

# nyc code coverage
.nyc_output
Expand Down
2 changes: 2 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ If you want more control over how tests are run, you can use other scripts:

* If you need to debug browser tests, or want to run them in a different browser, use `npm run test:manual`, which will start a server and you can point your browser to [http://localhost:1234](http://localhost:1234). Running the tests this way will also automatically watch your files, and hot-reload your code and tests, which is useful for debugging and trial/error testing.

* If you would like to use webpack to build your tests, use `npm run test:webpack`, which will start a server and you can point your browser to [http://localhost:8080](http://localhost:8080). Similar to `npm run test:manual`, this will watch for changes to test files and hot-reload your code and tests.

* If you need to debug node.js test runs, you can do so using `npm run test:node-debug`. Then, open Chrome and browse to [chrome://inspect](chrome://inspect) and click on your tests in the inspector. The easiest way to get a breakpoint is to manually add a `debugger` keyword to your test code where you want the tests to stop.

> Tip: you can add `skip()` to any `it()` or `describe()` in Mocha to skip a test, or `only()` to have only that test run. For example: `describe.skip(...)` or `it.only(...)`.
Expand Down
2,896 changes: 2,840 additions & 56 deletions package-lock.json

Large diffs are not rendered by default.

13 changes: 11 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"pretest:node-debug": "echo \"Open Chrome to chrome://inspect to debug tests...\"",
"test:node-debug": "mocha --timeout 5000 --inspect-brk tests",
"test:manual": "parcel tests/index.html --out-dir tests/dist",
"test:webpack": "webpack serve --config ./tests/webpack.config.js --env ignoreRequestDependancyExpressionWarnings",
"test:migrations": "mocha tests/filesystems/migrations",
"pretest": "npm run lint",
"test": "npm run karma-mocha",
Expand All @@ -46,14 +47,17 @@
},
"dependencies": {
"es6-promisify": "^6.1.0",
"path": "^0.12.7",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this, it's a node built-in module.

"minimatch": "^3.0.4"
},
"devDependencies": {
"regenerator-runtime": "^0.13.7",
"node-polyfill-webpack-plugin": "^1.0.3",
"chai": "^4.3.0",
"chai-datetime": "^1.8.0",
"css-loader": "^5.1.3",
"eslint": "^7.20.0",
"fake-indexeddb": "^3.1.2",
"html-webpack-plugin": "^5.3.1",
"karma": "^6.1.1",
"karma-chai": "^0.1.0",
"karma-chrome-launcher": "^3.1.0",
Expand All @@ -62,14 +66,19 @@
"karma-mocha-reporter": "^2.2.5",
"karma-summary-reporter": "^2.0.0",
"meow": "^9.0.0",
"mini-css-extract-plugin": "^1.3.9",
"mocha": "^8.3.0",
"nyc": "^15.1.0",
"parcel-bundler": "^1.12.4",
"pretty-bytes": "^5.5.0",
"regenerator-runtime": "^0.13.7",
"release-it": "^14.4.1",
"run.env": "^1.1.0",
"unused-filename": "^2.1.0",
"walk": "^2.3.14"
"walk": "^2.3.14",
"webpack": "^5.27.1",
"webpack-cli": "^4.5.0",
"webpack-dev-server": "^3.11.2"
},
"main": "./src/index.js",
"browser": "./dist/filer.min.js",
Expand Down
9 changes: 1 addition & 8 deletions tests/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,7 @@
<script src="../node_modules/chai/chai.js"></script>
<script src="../node_modules/mocha/mocha.js"></script>

<script>
mocha.setup('bdd').timeout(10000).slow(250);

window.onload = function() {
mocha.checkLeaks();
mocha.run();
};
</script>
<script src="./setup-mocha.js"></script>

<!-- Add any new tests to `tests/index.js` -->
<script src="./index.js"></script>
Expand Down
5 changes: 0 additions & 5 deletions tests/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@
* get them running by default.
*/

// Shims
require('./spec/shims/fs.spec');
require('./spec/shims/path.spec');
require('./spec/shims/buffer.spec');

// Filer
require('./spec/filer.spec');
require('./spec/filer.buffer.spec.js');
Expand Down
8 changes: 8 additions & 0 deletions tests/setup-mocha.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
var mocha = require('mocha');

mocha.setup('bdd').timeout(10000).slow(250);

window.onload = function() {
mocha.checkLeaks();
mocha.run();
};
2 changes: 1 addition & 1 deletion tests/spec/filer.spec.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';
const expect = require('chai').expect;
const Filer = require('../../src');
const util = require('../lib/test-utils');
const expect = require('chai').expect;

describe('Filer', function() {
it('is defined', function() {
Expand Down
10 changes: 6 additions & 4 deletions tests/spec/shims/fs.spec.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';
const expect = require('chai').expect;
const utils = require('../../lib/test-utils');
const fs = utils.shimIndexedDB(() => require('../../../shims/fs').default);
import fs from 'fs';

describe('fs shim', () => {
it('should be defined', () => {
Expand All @@ -17,10 +17,12 @@ describe('fs shim', () => {
});

it('should call callback when calling fs.writeFile', (done) => {
fs.writeFile('/test.txt', 'test', function(err) {
if(err) throw err;
utils.shimIndexedDB(() => {
fs.writeFile('/test.txt', 'test', function(err) {
if(err) throw err;

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

Expand Down
16 changes: 16 additions & 0 deletions tests/webpack-tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Include the mocha css
require('mocha/mocha.css');

// Setup mocha and set it to run tests on window load
require('./setup-mocha');

var path = require('../shims/path').default;
console.log(path.isAbsolute('/a/b'));

// Add any webpack specific tests here e.g. shim tests
require('./spec/shims/fs.spec');
require('./spec/shims/path.spec');
require('./spec/shims/buffer.spec');

// Add any other new tests to `tests/index.js`
require('./index');
61 changes: 61 additions & 0 deletions tests/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const path = require('path');

module.exports = env => ({
mode: 'development',
entry: path.resolve(__dirname, './webpack-tests.js'),
resolve: {
alias: {
'fsProvider': path.resolve(__dirname, '../shims/providers/default'),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgive my webpack ignorance here: can we not use Filer in this setup the way you're outlining in the README? It would be great if we had test code that did what the README suggests, so we know if it breaks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean aliasing fs, path and Buffer? We can definitely do that but obviously we'd need to refactor the shim tests to require fs, path and Buffer instead of the shims so those tests would have to be separated from the rest of the tests. I think that makes sense though as they're webpack specific.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, that's what I was thinking. Given that there are a few ways to do this, having adequate test coverage of all of them is my goal.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @humphd, I'm still working on this PR but found an issue with the way we're shimming the path module. In short, the alias messes up the import of the path module in filer (which I'd previously overlooked) and as such the path module ends up missing a lot of the methods (all the ones not explicitly replaced by filer). It should be possible to write a webpack plugin which resolves the path module correctly. Are you happy for me to go ahead with this and to make a separate PR for it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bcheidemann I think that sounds like a good idea. Thanks for pushing on this code a bit, it's great that testing is already discovering ways we can make it better.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No problem! I'm happy to do it and it's teaching me a lot :D I just wish I had more time to work on it at the moment!

},
},
output: {
path: path.resolve(__dirname, './dist-webpack'),
filename: 'index.js',
},
plugins: [
new webpack.ContextReplacementPlugin(
// Mocha safely uses require in such a way that webpack cannot statically extract dependancies.
// If the ignoreRequestDependancyExpressionWarnings env is set, we will aggregate these warnings
// into one summary warning to minimise spamming the console.
/\/node_modules\/mocha\/lib/,
(data) => {
if (env.ignoreRequestDependancyExpressionWarnings) {
let requestDependencyExpressionsIgnored = 0;
data.dependencies.forEach((dependancy) => {
if (dependancy.critical === 'the request of a dependency is an expression') {
dependancy.critical = undefined;
requestDependencyExpressionsIgnored += 1;
}
});
console.log(`WARNING: Ignoring ${requestDependencyExpressionsIgnored} "request of a dependency is an expression" warnings from "node_modules/mocha/lib".`);
}
return data;
},
),
new NodePolyfillPlugin(),
new MiniCssExtractPlugin(),
new HtmlWebpackPlugin({
title: 'Filer Tests - Webpack Build',
template: './tests/webpack.index.html',
}),
],
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
},
],
},
optimization: {
minimize: false,
},
devtool: 'inline-source-map',
devServer: {
contentBase: path.resolve(__dirname, './dist-webpack'),
}
});
10 changes: 10 additions & 0 deletions tests/webpack.index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<div id="mocha"></div>
</body>
</html>