Skip to content

Instantly share code, notes, and snippets.

@donocode
Last active May 19, 2017 19:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save donocode/6fe4409dad199185ba3550af30fcdf77 to your computer and use it in GitHub Desktop.
Save donocode/6fe4409dad199185ba3550af30fcdf77 to your computer and use it in GitHub Desktop.
Generate batched tests for karma-webpack
const path = require('path');
const Promise = require('bluebird');
const readdir = Promise.promisify(require('fs').readdir);
const stat = Promise.promisify(require('fs').stat);
const writeFile = Promise.promisify(require('fs').writeFile);
const recurse = Promise.promisify(require('recursive-readdir'));
const backSlashRegex = /\\{1,2}/g;
// A list of files that should always be included in the test files
// these will be included before the tests so you can register setup and
// teardown functions
const includes = [
'../setup.js',
];
function getPath(relative) {
return path.resolve(__dirname, relative);
}
function getRelativeFilePath(dir, file) {
if (file.startsWith('.')) {
return file;
}
// replace backslash with forward slash when using windows systems
return `./${path.relative(dir, file).replace(backSlashRegex, '/')}`;
}
function getRequires(dir, paths) {
// Generate a list of require calls
return paths.map(item => `require('${getRelativeFilePath(dir, item)}');`)
.join(' ');
}
function writeTestFile(relativeDir, files) {
const dir = getPath(relativeDir);
// The name of the file to generate, this is passed to karma
// This should also be added to .gitignore
const writeFilePath = path.join(dir, 'generated_test.js');
// group the tests in a mocha describe
const content =
`/* eslint-disable */
describe('${relativeDir}', function tests() {
${getRequires(dir, includes)}
${getRequires(dir, files)}
});
/* eslint-enable */`;
console.log(`Writing test file - ${writeFilePath}`);
return writeFile(writeFilePath, content);
}
function build() {
// Read the test directory and find all child directories
return readdir(__dirname)
.filter(item => {
// Skip any directories that don't contain test files
// this could be done with a glob or regex for more complex setups
if (item === 'helpers') {
return false;
}
// Check if the path is a directory
return stat(getPath(item))
.then(file => file.isDirectory());
})
.then(items => {
// Build up a map of promises for lists of javascript files
// Whatever pattern test files take in the system could be used here
const dirs = {};
items.forEach(item => {
dirs[item] = recurse(getPath(item), ['!*.js']);
});
// resolve the file path lists
return Promise.props(dirs);
})
.then(dirs => {
// Asynchronously write the test files
// This could also be done using map with concurrency to increase speed
const keys = Object.keys(dirs);
return Promise.each(keys, item => writeTestFile(item, dirs[item]));
});
}
module.exports = build().tap(files => console.log(`${files.length} test files created`));
{
"dependencies": {
"bluebird": "3.5.0",
},
"devDependencies": {
"recursive-readdir": "2.2.1",
},
"scripts": {
"build": "node ./test/build-tests.js",
"test": "npm run build && karma start"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment