UNPKG

5.41 kBJavaScriptView Raw
1const commander = require('commander');
2const {
3 each,
4 extend,
5 isNil
6} = require('macaca-utils');
7const {
8 existsSync,
9 readFileSync
10} = require('fs');
11const {
12 join,
13 resolve
14} = require('path');
15const pkg = require('../package.json');
16
17const cwd = process.cwd();
18module.paths.push(cwd, join(cwd, 'node_modules'));
19
20function list(str) {
21 return str.split(/[\s,]\s*/);
22}
23function modules(mod, memo) {
24 const abs = existsSync(mod) || existsSync(mod + '.js');
25 if (abs) mod = resolve(mod);
26 memo.push(mod);
27 return memo;
28}
29
30module.exports = argv => {
31 commander._name = 'torch';
32 commander
33 .version(pkg.version)
34 .option('-C, --no-colors', 'force disabling of colors')
35 .option('-O, --reporter-options <k=v,k2=v2,...>', 'reporter-specific options')
36 .option('-R, --reporter <name>', 'specify the reporter to use', 'spec')
37 .option('-S, --sort', 'sort test files')
38 .option('-b, --bail', 'bail after first test failure')
39 .option('-g, --grep <pattern>', 'only run tests matching <pattern>')
40 .option('-f, --fgrep <string>', 'only run tests containing <string>')
41 .option('-i, --invert', 'inverts --grep and --fgrep matches')
42 .option('-r, --require <name>', 'require the given module', modules, [])
43 .option('-s, --slow <ms>', '"slow" test threshold in milliseconds [75]')
44 .option('-t, --timeout <ms>', 'set test-case timeout in milliseconds [2000]')
45 .option('-u, --ui <name>', 'specify user-interface (bdd|tdd|exports)', 'bdd')
46 .option('--check-leaks', 'check for global variable leaks')
47 .option('--compile', 'compile with babel')
48 .option('--compile-opts <path>', 'path of compile options')
49 .option('--compilers <ext>:<module>,...', 'use the given module(s) to compile files', list, [])
50 .option('--coverage', 'report coverage')
51 .option('--debug', 'enable Electron debugger on port [5858]; for --renderer tests show window and dev-tools')
52 .option('--debug-brk', 'like --debug but pauses the script on the first line')
53 .option('--dom-global', 'enable DOM in Node.js by using jsdom-global')
54 .option('--dom-global-loose', 'enable DOM in Node.js, while window can be modified')
55 .option('--globals <names>', 'allow the given comma-delimited global [names]', list, [])
56 .option('--inline-diffs', 'display actual/expected differences inline within each string')
57 .option('--interactive', 'run tests in renderer process in a visible window that can be reloaded to re-run tests')
58 .option('--interfaces', 'display available interfaces')
59 .option('--no-timeouts', 'disables timeouts')
60 .option('--notify-on-fail', 'notify on failures')
61 .option('--notify-on-success', 'notify on success')
62 .option('--opts <path>', 'specify opts path', './__tests__/mocha.opts')
63 .option('--preload <name>', 'preload the given script in renderer process', modules, [])
64 .option('--recursive', 'include sub directories')
65 .option('--renderer', 'run tests in renderer process')
66 .option('--require-main <name>', 'load the given script in main process before executing tests', modules, [])
67 .option('--source-pattern <sources>', 'glob pattern of source files', list, [ 'index.js', 'lib/**/*.js', 'src/**/*.js' ])
68 .option('--watch', 'watching source file changes')
69 .option('--watch-aggregate-timeout', 'delay time for re-run test cases after files changed', 1000)
70 .option('--http', 'switch it http protocol runtime');
71
72 const optsPath = process.argv.indexOf('--opts') !== -1 ?
73 process.argv[process.argv.indexOf('--opts') + 1] :
74 '__tests__/mocha.opts';
75
76 try {
77 const opts = readFileSync(optsPath, 'utf8')
78 .trim()
79 .split(/\s+/);
80 argv = argv
81 .slice(0, 2)
82 .concat(opts.concat(process.argv.slice(2)));
83 } catch (err) {
84 // console.warn(err);
85 }
86
87 commander.parse(argv);
88
89 const argData = JSON.parse(JSON.stringify(commander));
90 argData.files = argData.args;
91
92 if (argData.debugBrk) {
93 argData.debug = true;
94 }
95
96 // reporter options
97 const reporterOpts = {};
98 if (!isNil(commander.reporterOpts)) {
99 each(commander.reporterOpts.split(','), opt => {
100 const L = opt.split('=');
101 if (L.length > 2 || L.length === 0) {
102 throw new Error(`invalid reporter option '${opt}'`);
103 } else if (L.length === 2) {
104 reporterOpts[L[0]] = L[1];
105 } else {
106 reporterOpts[L[0]] = true;
107 }
108 });
109 }
110 argData.reporterOpts = reporterOpts;
111
112 // compile options
113 if (commander.compile) {
114 argData.compileOpts = {
115 babelrc: {
116 presets: [
117 'es2015',
118 'stage-0'
119 ],
120 sourceMaps: 'inline'
121 },
122 extensions: [ '.es6', '.es', '.jsx', '.js' ],
123 include: [
124 'index.js',
125 'lib/**/*.js',
126 'src/**/*.js'
127 ],
128 exclude: [
129 'bower_components/**',
130 'node_modules/**'
131 ]
132 };
133
134 const optsPathname = resolve(cwd, commander.compileOpts || './.torch.compile.opts.js');
135 let specifiedOpts;
136 try {
137 specifiedOpts = require(optsPathname);
138 } catch (e) {
139 console.warn(e);
140 }
141 extend(argData.compileOpts, specifiedOpts);
142 }
143
144 // delete unused
145 const UNUSED_KEYS = [
146 '_args',
147 '_events',
148 '_eventsCount',
149 '_execs',
150 '_name',
151 '_usage',
152 '_version',
153 'args',
154 'commands',
155 'options'
156 ];
157 each(UNUSED_KEYS, key => {
158 delete argData[key];
159 });
160
161 return argData;
162};