import fs from 'fs'; import path from 'path'; import webpack from 'webpack'; function compareDirectory(actual, expected) { const files = fs.readdirSync(expected); for (const file of files) { const absoluteFilePath = path.resolve(expected, file); const stats = fs.lstatSync(absoluteFilePath); if (stats.isDirectory()) { compareDirectory( path.resolve(actual, file), path.resolve(expected, file) ); } else if (stats.isFile()) { const content = fs.readFileSync(path.resolve(expected, file), 'utf8'); const actualContent = fs.readFileSync(path.resolve(actual, file), 'utf8'); expect(actualContent).toEqual(content); } } } function compareWarning(actual, expectedFile) { if (!fs.existsSync(expectedFile)) { return; } // eslint-disable-next-line global-require, import/no-dynamic-require const expected = require(expectedFile); expect(actual.trim()).toBe(expected.trim()); } describe('TestCases', () => { const casesDirectory = path.resolve(__dirname, 'cases'); const outputDirectory = path.resolve(__dirname, 'js'); for (const directory of fs.readdirSync(casesDirectory)) { if (!/^(\.|_)/.test(directory)) { // eslint-disable-next-line no-loop-func it(`${directory} should compile to the expected result`, (done) => { const directoryForCase = path.resolve(casesDirectory, directory); const outputDirectoryForCase = path.resolve(outputDirectory, directory); // eslint-disable-next-line import/no-dynamic-require, global-require const webpackConfig = require(path.resolve( directoryForCase, 'webpack.config.js' )); for (const config of [].concat(webpackConfig)) { Object.assign( config, { mode: 'none', context: directoryForCase, output: Object.assign( { path: outputDirectoryForCase, }, config.output ), }, config ); } webpack(webpackConfig, (err, stats) => { if (err) { done(err); return; } done(); // eslint-disable-next-line no-console console.log( stats.toString({ context: path.resolve(__dirname, '..'), chunks: true, chunkModules: true, modules: false, }) ); if (stats.hasErrors()) { done( new Error( stats.toString({ context: path.resolve(__dirname, '..'), errorDetails: true, }) ) ); return; } const expectedDirectory = path.resolve(directoryForCase, 'expected'); const expectedDirectoryByVersion = path.join( expectedDirectory, `webpack-${webpack.version[0]}` ); if (fs.existsSync(expectedDirectoryByVersion)) { compareDirectory( outputDirectoryForCase, expectedDirectoryByVersion ); } else { compareDirectory(outputDirectoryForCase, expectedDirectory); } const expectedWarning = path.resolve(directoryForCase, 'warnings.js'); const actualWarning = stats.toString({ all: false, warnings: true, }); compareWarning(actualWarning, expectedWarning); done(); }); }, 10000); } } });