Skip to content

Commit

Permalink
- Support multiple Webpack versions in tests
Browse files Browse the repository at this point in the history
- Fix tests to support Webpack 5
  • Loading branch information
th0r committed Nov 3, 2020
1 parent 591adf1 commit a81b7b8
Show file tree
Hide file tree
Showing 9 changed files with 3,663 additions and 67 deletions.
3 changes: 3 additions & 0 deletions bin/install-test-webpack-versions.sh
@@ -0,0 +1,3 @@
#!/usr/bin/env bash

for dir in "$(dirname "$0")"/../test/webpack-versions/*; do (cd "$dir" && npm i); done
5 changes: 3 additions & 2 deletions package.json
Expand Up @@ -23,8 +23,9 @@
"build": "gulp build",
"npm-publish": "npm run lint && npm run build && npm test && npm publish",
"lint": "eslint --ext js,jsx .",
"test": "mocha --exit --require @babel/register",
"test-dev": "mocha --watch --require @babel/register"
"install-test-webpack-versions": "./bin/install-test-webpack-versions.sh",
"test": "npm run install-test-webpack-versions && mocha --exit --require @babel/register",
"test-dev": "npm run install-test-webpack-versions && mocha --watch --require @babel/register"
},
"files": [
"public",
Expand Down
3 changes: 2 additions & 1 deletion test/.eslintrc.json
Expand Up @@ -7,6 +7,7 @@
"globals": {
"expect": true,
"makeWebpackConfig": true,
"webpackCompile": true
"webpackCompile": true,
"forEachWebpackVersion": true
}
}
63 changes: 62 additions & 1 deletion test/helpers.js
@@ -1,3 +1,4 @@
const {readdirSync} = require('fs');
const chai = require('chai');
const webpack = require('webpack');
const _ = require('lodash');
Expand All @@ -7,10 +8,70 @@ chai.use(require('chai-subset'));
global.expect = chai.expect;
global.webpackCompile = webpackCompile;
global.makeWebpackConfig = makeWebpackConfig;
global.forEachWebpackVersion = forEachWebpackVersion;

const BundleAnalyzerPlugin = require('../lib/BundleAnalyzerPlugin');

async function webpackCompile(config) {
const getAvailableWebpackVersions = _.memoize(() =>
readdirSync(`${__dirname}/webpack-versions`, {withFileTypes: true})
.filter(entry => entry.isDirectory())
.map(dir => dir.name)
);

function forEachWebpackVersion(versions, cb) {
const availableVersions = getAvailableWebpackVersions();

if (_.isFunction(versions)) {
cb = versions;
versions = availableVersions;
} else {
const notFoundVersions = versions.filter(version => !availableVersions.includes(version));

if (notFoundVersions.length) {
throw new Error(
`These Webpack versions are not currently available for testing: ${notFoundVersions.join(', ')}\n` +
'You need to install them manually into "test/webpack-versions" directory.'
);
}
}

for (const version of versions) {
const itFn = function (testDescription, ...args) {
return it.call(this, `${testDescription} (Webpack ${version})`, ...args);
};

itFn.only = function (testDescription, ...args) {
return it.only.call(this, `${testDescription} (Webpack ${version})`, ...args);
};

cb({
it: itFn,
version,
webpackCompile: _.partial(webpackCompile, _, version)
});
}
}

async function webpackCompile(config, version) {
if (version === undefined || version === null) {
throw new Error('Webpack version is not specified');
}

if (!getAvailableWebpackVersions().includes(version)) {
throw new Error(`Webpack version "${version}" is not available for testing`);
}

let webpack;

try {
webpack = require(`./webpack-versions/${version}/node_modules/webpack`);
} catch (err) {
throw new Error(
`Error requiring Webpack ${version}:\n${err}\n\n` +
'Try running "npm run install-test-webpack-versions".'
);
}

await new Promise((resolve, reject) => {
webpack(config, (err, stats) => {
if (err) {
Expand Down
143 changes: 80 additions & 63 deletions test/plugin.js
Expand Up @@ -32,110 +32,127 @@ describe('Plugin', function () {
del.sync(`${__dirname}/output`);
});

it('should support webpack config with custom `jsonpFunction` name', async function () {
const config = makeWebpackConfig({
multipleChunks: true
});

config.output.jsonpFunction = 'somethingCompletelyDifferent';
forEachWebpackVersion(['4.44.2'], ({it, webpackCompile}) => {
// Webpack 5 doesn't support `jsonpFunction` option
it('should support webpack config with custom `jsonpFunction` name', async function () {
const config = makeWebpackConfig({
multipleChunks: true
});

await webpackCompile(config);
config.output.jsonpFunction = 'somethingCompletelyDifferent';

await expectValidReport({
parsedSize: 1343,
gzipSize: 360
});
});
await webpackCompile(config);

it('should allow to generate json report', async function () {
const config = makeWebpackConfig({
analyzerOpts: {
analyzerMode: 'json'
}
await expectValidReport({
parsedSize: 1343,
gzipSize: 360
});
});

await webpackCompile(config);

const chartData = await getChartDataFromJSONReport();
expect(chartData).to.exist;
});

it('should support webpack config with `multi` module', async function () {
const config = makeWebpackConfig();
forEachWebpackVersion(({it, webpackCompile}) => {
it('should allow to generate json report', async function () {
const config = makeWebpackConfig({
analyzerOpts: {
analyzerMode: 'json'
}
});

config.entry.bundle = [
'./src/a.js',
'./src/b.js'
];
await webpackCompile(config);

await webpackCompile(config);
const chartData = await getChartDataFromJSONReport();
expect(chartData).to.exist;
});

const chartData = await getChartDataFromReport();
expect(chartData[0].groups).to.containSubset([
{
label: 'multi ./src/a.js ./src/b.js',
path: './multi ./src/a.js ./src/b.js',
groups: undefined
}
]);
it('should support webpack config with `multi` module', async function () {
const config = makeWebpackConfig();

config.entry.bundle = [
'./src/a.js',
'./src/b.js'
];

await webpackCompile(config);

const chartData = await getChartDataFromReport();
const bundleGroup = chartData.find(group => group.label === 'bundle.js');

expect(bundleGroup.groups)
.to
.containSubset([
{
label: 'src',
path: './src',
groups: [
{
label: 'a.js',
path: './src/a.js'
},
{
label: 'b.js',
path: './src/b.js'
}
]
}
]);
});
});

describe('options', function () {
describe('excludeAssets', function () {
it('should filter out assets from the report', async function () {
const config = makeWebpackConfig({
multipleChunks: true,
analyzerOpts: {
excludeAssets: 'manifest'
}
});
forEachWebpackVersion(({it, webpackCompile}) => {
it('should filter out assets from the report', async function () {
const config = makeWebpackConfig({
multipleChunks: true,
analyzerOpts: {
excludeAssets: 'manifest'
}
});

await webpackCompile(config);
await webpackCompile(config);

const chartData = await getChartDataFromReport();
expect(_.map(chartData, 'label')).to.deep.equal(['bundle.js']);
const chartData = await getChartDataFromReport();
expect(_.map(chartData, 'label'))
.to
.deep
.equal(['bundle.js']);
});
});
});

describe('reportTitle', function () {
it('should have a sensible default', async function () {
const config = makeWebpackConfig();

await webpackCompile(config);

await webpackCompile(config, '4.44.2');
const generatedReportTitle = await getTitleFromReport();

expect(generatedReportTitle).to.match(/^webpack-bundle-analyzer \[.* at \d{2}:\d{2}\]/u);
});
it('should use a string', async function () {

it('should support a string value', async function () {
const reportTitle = 'A string report title';
const config = makeWebpackConfig({
analyzerOpts: {
reportTitle
}
});

await webpackCompile(config);

await webpackCompile(config, '4.44.2');
const generatedReportTitle = await getTitleFromReport();

expect(generatedReportTitle).to.equal(reportTitle);
});
it('should use a function', async function () {

it('should support a function value', async function () {
const reportTitleResult = 'A string report title';
const config = makeWebpackConfig({
analyzerOpts: {
reportTitle: () => reportTitleResult
}
});

await webpackCompile(config);

await webpackCompile(config, '4.44.2');
const generatedReportTitle = await getTitleFromReport();

expect(generatedReportTitle).to.equal(reportTitleResult);
});
it('should propogate an error in a function', async function () {

it('should propagate an error in a function', async function () {
const reportTitleError = new Error();
const config = makeWebpackConfig({
analyzerOpts: {
Expand All @@ -145,7 +162,7 @@ describe('Plugin', function () {

let error = null;
try {
await webpackCompile(config);
await webpackCompile(config, '4.44.2');
} catch (e) {
error = e;
}
Expand Down

0 comments on commit a81b7b8

Please sign in to comment.