1 | const commander = require('commander');
|
2 | const {
|
3 | each,
|
4 | extend,
|
5 | isNil
|
6 | } = require('macaca-utils');
|
7 | const {
|
8 | existsSync,
|
9 | readFileSync
|
10 | } = require('fs');
|
11 | const {
|
12 | join,
|
13 | resolve
|
14 | } = require('path');
|
15 | const pkg = require('../package.json');
|
16 |
|
17 | const cwd = process.cwd();
|
18 | module.paths.push(cwd, join(cwd, 'node_modules'));
|
19 |
|
20 | function list(str) {
|
21 | return str.split(/[\s,]\s*/);
|
22 | }
|
23 | function 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 |
|
30 | module.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 |
|
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 |
|
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 |
|
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 |
|
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 | };
|