storybook/scripts/test.js
2017-08-28 20:49:44 +02:00

146 lines
4.2 KiB
JavaScript
Executable File

#!/usr/bin/env node
const inquirer = require('inquirer');
const program = require('commander');
const childProcess = require('child_process');
const chalk = require('chalk');
const log = require('npmlog');
log.heading = 'storybook';
const prefix = 'test';
log.addLevel('aborted', 3001, { fg: 'red', bold: true });
const spawn = command =>
childProcess.spawnSync(`${command}`, {
shell: true,
stdio: 'inherit',
});
const main = program.version('3.0.0').option('--all', `Test everything ${chalk.gray('(all)')}`);
const createProject = ({ defaultValue, option, name, projectLocation }) => ({
value: false,
defaultValue: defaultValue || false,
option: option || undefined,
name: name || 'unnamed task',
projectLocation,
});
const createOption = ({ defaultValue, option, name, extraParam }) => ({
value: false,
defaultValue: defaultValue || false,
option: option || undefined,
name: name || 'unnamed task',
extraParam,
});
const tasks = {
core: createProject({
name: `Core & React & Vue ${chalk.gray('(core)')}`,
defaultValue: true,
option: '--core',
projectLocation: './',
}),
'react-native-vanilla': createProject({
name: `React-Native example ${chalk.gray('(react-native-vanilla)')}`,
defaultValue: true,
option: '--reactnative',
projectLocation: './examples/react-native-vanilla',
}),
// 'crna-kitchen-sink': createProject({
// name: `React-Native-App example ${chalk.gray('(crna-kitchen-sink)')} ${chalk.red(
// '[not implemented yet]'
// )}`,
// defaultValue: false,
// option: '--reactnativeapp',
// projectLocation: './examples/crna-kitchen-sink',
// }),
watchmode: createOption({
name: `Run in watch-mode ${chalk.gray('(watchmode)')}`,
defaultValue: false,
option: '--watch',
extraParam: '--watch',
}),
coverage: createOption({
name: `Output coverage reports ${chalk.gray('(coverage)')}`,
defaultValue: false,
option: '--coverage',
extraParam: '--coverage',
}),
runInBand: createOption({
name: `Run all tests serially in the current process ${chalk.gray('(runInBand)')}`,
defaultValue: false,
option: '--runInBand',
extraParam: '--runInBand',
}),
};
const getProjects = list => {
const filtered = list.filter(key => key.projectLocation);
if (filtered.length > 0) {
return filtered.map(key => key.projectLocation);
}
// if list would have been empty, we run with default projects
return Object.keys(tasks)
.map(key => tasks[key])
.filter(key => key.projectLocation && key.defaultValue)
.map(key => key.projectLocation);
};
const getExtraParams = list => list.filter(key => key.extraParam).map(key => key.extraParam);
Object.keys(tasks)
.reduce((acc, key) => acc.option(tasks[key].option, tasks[key].name), main)
.parse(process.argv);
Object.keys(tasks).forEach(key => {
tasks[key].value =
program[tasks[key].option.replace('--', '')] || (program.all && tasks[key].projectLocation);
});
let selection;
if (!Object.keys(tasks).map(key => tasks[key].value).filter(Boolean).length) {
selection = inquirer
.prompt([
{
type: 'checkbox',
message: 'Select which tests to run',
name: 'todo',
choices: Object.keys(tasks)
.map(key => tasks[key])
.filter(key => key.projectLocation)
.map(key => ({
name: key.name,
checked: key.defaultValue,
}))
.concat(new inquirer.Separator())
.concat(
Object.keys(tasks).map(key => tasks[key]).filter(key => key.extraParam).map(key => ({
name: key.name,
checked: key.defaultValue,
}))
),
},
])
.then(({ todo }) =>
todo.map(name => tasks[Object.keys(tasks).find(i => tasks[i].name === name)])
);
} else {
selection = Promise.resolve(
Object.keys(tasks).map(key => tasks[key]).filter(item => item.value === true)
);
}
selection
.then(list => {
if (list.length === 0) {
log.warn(prefix, 'Nothing to test');
} else {
spawn(`jest --projects ${getProjects(list).join(' ')} ${getExtraParams(list).join(' ')}`);
process.stdout.write('\x07');
}
})
.catch(e => {
log.aborted(prefix, chalk.red(e.message));
log.silly(prefix, e);
});