Skip to content

Commit 3e9c787

Browse files
committed
Making tests more resilient to failure by fuzzy checking some hash filenames
1 parent d86e115 commit 3e9c787

File tree

2 files changed

+107
-41
lines changed

2 files changed

+107
-41
lines changed

test/functional.js

Lines changed: 30 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -418,16 +418,13 @@ describe('Functional tests using webpack', function() {
418418
config.enableVersioning(true);
419419

420420
testSetup.runWebpack(config, (webpackAssert) => {
421-
if (!process.env.DISABLE_UNSTABLE_CHECKS) {
422-
expect(config.outputPath).to.be.a.directory()
423-
.with.files([
424-
'main.8b8ca4a9.js',
425-
'styles.79943add.css',
426-
'manifest.json',
427-
'entrypoints.json',
428-
'runtime.49688a3c.js',
429-
]);
430-
}
421+
webpackAssert.assertDirectoryContents([
422+
'main.[hash:8].js',
423+
'styles.[hash:8].css',
424+
'manifest.json',
425+
'entrypoints.json',
426+
'runtime.[hash:8].js',
427+
]);
431428

432429
webpackAssert.assertOutputFileContains(
433430
'styles.79943add.css',
@@ -521,19 +518,16 @@ describe('Functional tests using webpack', function() {
521518
config.enableVersioning(true);
522519

523520
testSetup.runWebpack(config, (webpackAssert) => {
524-
if (!process.env.DISABLE_UNSTABLE_CHECKS) {
525-
expect(config.outputPath).to.be.a.directory()
526-
.with.files([
527-
'js_no_require_js-css_h1_style_css.456c237a.js', // chunks are also versioned
528-
'js_no_require_js-css_h1_style_css.79943add.css',
529-
'main.04316e30.js',
530-
'h1.79943add.css',
531-
'bg.2eff0999.css',
532-
'manifest.json',
533-
'entrypoints.json',
534-
'runtime.17e58ffe.js',
535-
]);
536-
}
521+
webpackAssert.assertDirectoryContents([
522+
'js_no_require_js-css_h1_style_css.[hash:8].js', // chunks are also versioned
523+
'js_no_require_js-css_h1_style_css.[hash:8].css',
524+
'main.[hash:8].js',
525+
'h1.[hash:8].css',
526+
'bg.[hash:8].css',
527+
'manifest.json',
528+
'entrypoints.json',
529+
'runtime.[hash:8].js',
530+
]);
537531

538532
expect(path.join(config.outputPath, 'images')).to.be.a.directory()
539533
.with.files([
@@ -2167,22 +2161,19 @@ module.exports = {
21672161
}]);
21682162

21692163
testSetup.runWebpack(config, (webpackAssert) => {
2170-
if (!process.env.DISABLE_UNSTABLE_CHECKS) {
2171-
expect(config.outputPath).to.be.a.directory()
2172-
.with.files([
2173-
'entrypoints.json',
2174-
'runtime.fbc90386.js',
2175-
'main.06a6c20f.js',
2176-
'manifest.json',
2177-
'symfony_logo.91beba37.png',
2178-
'symfony_logo_alt.f880ba14.png',
2179-
]);
2180-
2181-
webpackAssert.assertManifestPath(
2182-
'build/main.js',
2183-
'/build/main.06a6c20f.js'
2184-
);
2185-
}
2164+
webpackAssert.assertDirectoryContents([
2165+
'entrypoints.json',
2166+
'runtime.fbc90386.js',
2167+
'main.06a6c20f.js',
2168+
'manifest.json',
2169+
'symfony_logo.91beba37.png',
2170+
'symfony_logo_alt.f880ba14.png',
2171+
]);
2172+
2173+
webpackAssert.assertManifestPath(
2174+
'build/main.js',
2175+
'/build/main.[hash:8].js'
2176+
);
21862177

21872178
expect(path.join(config.outputPath, 'assets')).to.be.a.directory()
21882179
.with.files([

test/helpers/assert.js

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const path = require('path');
1313
const fs = require('fs');
1414
const chai = require('chai');
1515
const expect = chai.expect;
16+
const regexEscaper = require('../../lib/utils/regexp-escaper');
1617

1718
const loadManifest = function(webpackConfig) {
1819
return JSON.parse(
@@ -30,6 +31,27 @@ const readOutputFile = function(webpackConfig, filePath) {
3031
return fs.readFileSync(fullPath, 'utf8');
3132
};
3233

34+
/**
35+
* Returns a regex to use to match this filename
36+
*
37+
* @param {string} filename Filename with possible [hash:8] wildcard
38+
* @return {RegExp}
39+
*/
40+
const convertFilenameToMatcher = function(filename) {
41+
const hashMatch = filename.match(/\[hash:(\d+)\]/);
42+
43+
if (hashMatch === null) {
44+
return new RegExp(regexEscaper(filename));
45+
}
46+
47+
const [hashString, hashLength] = hashMatch;
48+
49+
return new RegExp(
50+
regexEscaper(filename)
51+
.replace(regexEscaper(hashString), `([a-z0-9_-]){${hashLength}}`)
52+
);
53+
};
54+
3355
class Assert {
3456
/**
3557
* @param {WebpackConfig} webpackConfig
@@ -107,8 +129,10 @@ class Assert {
107129

108130
this.assertManifestKeyExists(sourcePath);
109131

110-
if (manifestData[sourcePath] !== expectedDestinationPath) {
111-
throw new Error(`source path ${sourcePath} expected to be set to ${expectedDestinationPath}, was actually ${manifestData[sourcePath]}`);
132+
const expectedRegex = convertFilenameToMatcher(expectedDestinationPath);
133+
134+
if (!manifestData[sourcePath].match(expectedRegex)) {
135+
throw new Error(`source path ${sourcePath} expected to match pattern ${expectedDestinationPath}, was actually ${manifestData[sourcePath]}`);
112136
}
113137
}
114138

@@ -168,6 +192,57 @@ class Assert {
168192

169193
expect(JSON.stringify(actualData, null, 2)).to.equal(JSON.stringify(expectedData, null, 2));
170194
}
195+
196+
/**
197+
* Verifies that the directory contains the array of files.
198+
*
199+
* The expectedFiles can contain a [hash:8] syntax in case
200+
* the file is versioned - e.g. main.[hash:8].js, which would
201+
* match a real file like main.abcd1234.js.
202+
*
203+
* @param {Array} expectedFiles
204+
* @param {string} directory relative to output to check
205+
* @returns {void}
206+
*/
207+
assertDirectoryContents(expectedFiles, directory = '') {
208+
const targetDirectory = path.join(this.webpackConfig.outputPath, directory);
209+
210+
expect(targetDirectory).to.be.a.directory();
211+
212+
const expectedFileStrings = {};
213+
expectedFiles.forEach((expectedFile) => {
214+
expectedFileStrings[expectedFile] = convertFilenameToMatcher(expectedFile);
215+
});
216+
217+
const actualFiles = fs.readdirSync(targetDirectory);
218+
actualFiles.forEach((foundFile) => {
219+
// filter out directories
220+
if (fs.statSync(path.join(targetDirectory, foundFile)).isDirectory()) {
221+
return;
222+
}
223+
224+
let matchIsFound = false;
225+
226+
for (const originalFilename of Object.keys(expectedFileStrings)) {
227+
const filenameRegex = expectedFileStrings[originalFilename];
228+
229+
if (foundFile.match(filenameRegex)) {
230+
matchIsFound = true;
231+
delete expectedFileStrings[originalFilename];
232+
233+
break;
234+
}
235+
}
236+
237+
if (!matchIsFound) {
238+
throw new Error(`File "${foundFile}" was found in directory but was not expected. Expected patterns where ${expectedFiles.join(', ')}`);
239+
}
240+
});
241+
242+
if (Object.keys(expectedFileStrings).length > 0) {
243+
throw new Error(`Files ${Object.keys(expectedFileStrings).join(', ')} were expected to be found in the directory but were not. Actual files: ${actualFiles.join(', ')}`);
244+
}
245+
}
171246
}
172247

173248
module.exports = function(webpackConfig) {

0 commit comments

Comments
 (0)