UNPKG

9.93 kBJavaScriptView Raw
1var path = require('path')
2var optimist = require('optimist')
3var fs = require('graceful-fs')
4
5var Server = require('./server')
6var helper = require('./helper')
7var constant = require('./constants')
8
9var processArgs = function (argv, options, fs, path) {
10 if (argv.help) {
11 console.log(optimist.help())
12 process.exit(0)
13 }
14
15 if (argv.version) {
16 console.log('Karma version: ' + constant.VERSION)
17 process.exit(0)
18 }
19
20 // TODO(vojta): warn/throw when unknown argument (probably mispelled)
21 Object.getOwnPropertyNames(argv).forEach(function (name) {
22 var argumentValue = argv[name]
23 if (name !== '_' && name !== '$0') {
24 if (name.indexOf('_') !== -1) {
25 throw new Error('Bad argument: ' + name + ' did you mean ' + name.replace('_', '-'))
26 }
27 if (Array.isArray(argumentValue)) {
28 // If the same argument is defined multiple times, override.
29 argumentValue = argumentValue.pop()
30 }
31 options[helper.dashToCamel(name)] = argumentValue
32 }
33 })
34
35 if (helper.isString(options.autoWatch)) {
36 options.autoWatch = options.autoWatch === 'true'
37 }
38
39 if (helper.isString(options.colors)) {
40 options.colors = options.colors === 'true'
41 }
42
43 if (helper.isString(options.failOnEmptyTestSuite)) {
44 options.failOnEmptyTestSuite = options.failOnEmptyTestSuite === 'true'
45 }
46
47 if (helper.isString(options.formatError)) {
48 try {
49 var required = require(options.formatError)
50 } catch (err) {
51 console.error('Could not require formatError: ' + options.formatError, err)
52 }
53 // support exports.formatError and module.exports = function
54 options.formatError = required.formatError || required
55 if (!helper.isFunction(options.formatError)) {
56 console.error('Format error must be a function, got: ' + typeof options.formatError)
57 process.exit(1)
58 }
59 }
60
61 if (helper.isString(options.logLevel)) {
62 var logConstant = constant['LOG_' + options.logLevel.toUpperCase()]
63 if (helper.isDefined(logConstant)) {
64 options.logLevel = logConstant
65 } else {
66 console.error('Log level must be one of disable, error, warn, info, or debug.')
67 process.exit(1)
68 }
69 } else if (helper.isDefined(options.logLevel)) {
70 console.error('Log level must be one of disable, error, warn, info, or debug.')
71 process.exit(1)
72 }
73
74 if (helper.isString(options.singleRun)) {
75 options.singleRun = options.singleRun === 'true'
76 }
77
78 if (helper.isString(options.browsers)) {
79 options.browsers = options.browsers.split(',')
80 }
81
82 if (options.reportSlowerThan === false) {
83 options.reportSlowerThan = 0
84 }
85
86 if (helper.isString(options.reporters)) {
87 options.reporters = options.reporters.split(',')
88 }
89
90 if (helper.isString(options.removedFiles)) {
91 options.removedFiles = options.removedFiles.split(',')
92 }
93
94 if (helper.isString(options.addedFiles)) {
95 options.addedFiles = options.addedFiles.split(',')
96 }
97
98 if (helper.isString(options.changedFiles)) {
99 options.changedFiles = options.changedFiles.split(',')
100 }
101
102 if (helper.isString(options.refresh)) {
103 options.refresh = options.refresh === 'true'
104 }
105
106 var configFile = argv._.shift()
107
108 if (!configFile) {
109 // default config file (if exists)
110 if (fs.existsSync('./karma.conf.js')) {
111 configFile = './karma.conf.js'
112 } else if (fs.existsSync('./karma.conf.coffee')) {
113 configFile = './karma.conf.coffee'
114 } else if (fs.existsSync('./karma.conf.ts')) {
115 configFile = './karma.conf.ts'
116 } else if (fs.existsSync('./.config/karma.conf.js')) {
117 configFile = './.config/karma.conf.js'
118 } else if (fs.existsSync('./.config/karma.conf.coffee')) {
119 configFile = './.config/karma.conf.coffee'
120 } else if (fs.existsSync('./.config/karma.conf.ts')) {
121 configFile = './.config/karma.conf.ts'
122 }
123 }
124
125 options.configFile = configFile ? path.resolve(configFile) : null
126
127 return options
128}
129
130var parseClientArgs = function (argv) {
131 // extract any args after '--' as clientArgs
132 var clientArgs = []
133 argv = argv.slice(2)
134 var idx = argv.indexOf('--')
135 if (idx !== -1) {
136 clientArgs = argv.slice(idx + 1)
137 }
138 return clientArgs
139}
140
141// return only args that occur before `--`
142var argsBeforeDoubleDash = function (argv) {
143 var idx = argv.indexOf('--')
144
145 return idx === -1 ? argv : argv.slice(0, idx)
146}
147
148var describeShared = function () {
149 optimist
150 .usage('Karma - Spectacular Test Runner for JavaScript.\n\n' +
151 'Usage:\n' +
152 ' $0 <command>\n\n' +
153 'Commands:\n' +
154 ' start [<configFile>] [<options>] Start the server / do single run.\n' +
155 ' init [<configFile>] Initialize a config file.\n' +
156 ' run [<options>] [ -- <clientArgs>] Trigger a test run.\n' +
157 ' completion Shell completion for karma.\n\n' +
158 'Run --help with particular command to see its description and available options.')
159 .describe('help', 'Print usage and options.')
160 .describe('version', 'Print current version.')
161}
162
163var describeInit = function () {
164 optimist
165 .usage('Karma - Spectacular Test Runner for JavaScript.\n\n' +
166 'INIT - Initialize a config file.\n\n' +
167 'Usage:\n' +
168 ' $0 init [<configFile>]')
169 .describe('log-level', '<disable | error | warn | info | debug> Level of logging.')
170 .describe('colors', 'Use colors when reporting and printing logs.')
171 .describe('no-colors', 'Do not use colors when reporting or printing logs.')
172 .describe('help', 'Print usage and options.')
173}
174
175var describeStart = function () {
176 optimist
177 .usage('Karma - Spectacular Test Runner for JavaScript.\n\n' +
178 'START - Start the server / do a single run.\n\n' +
179 'Usage:\n' +
180 ' $0 start [<configFile>] [<options>]')
181 .describe('port', '<integer> Port where the server is running.')
182 .describe('auto-watch', 'Auto watch source files and run on change.')
183 .describe('detached', 'Detach the server.')
184 .describe('no-auto-watch', 'Do not watch source files.')
185 .describe('log-level', '<disable | error | warn | info | debug> Level of logging.')
186 .describe('colors', 'Use colors when reporting and printing logs.')
187 .describe('no-colors', 'Do not use colors when reporting or printing logs.')
188 .describe('reporters', 'List of reporters (available: dots, progress, junit, growl, coverage).')
189 .describe('browsers', 'List of browsers to start (eg. --browsers Chrome,ChromeCanary,Firefox).')
190 .describe('capture-timeout', '<integer> Kill browser if does not capture in given time [ms].')
191 .describe('single-run', 'Run the test when browsers captured and exit.')
192 .describe('no-single-run', 'Disable single-run.')
193 .describe('report-slower-than', '<integer> Report tests that are slower than given time [ms].')
194 .describe('fail-on-empty-test-suite', 'Fail on empty test suite.')
195 .describe('no-fail-on-empty-test-suite', 'Do not fail on empty test suite.')
196 .describe('help', 'Print usage and options.')
197}
198
199var describeRun = function () {
200 optimist
201 .usage('Karma - Spectacular Test Runner for JavaScript.\n\n' +
202 'RUN - Run the tests (requires running server).\n\n' +
203 'Usage:\n' +
204 ' $0 run [<configFile>] [<options>] [ -- <clientArgs>]')
205 .describe('port', '<integer> Port where the server is listening.')
206 .describe('no-refresh', 'Do not re-glob all the patterns.')
207 .describe('fail-on-empty-test-suite', 'Fail on empty test suite.')
208 .describe('no-fail-on-empty-test-suite', 'Do not fail on empty test suite.')
209 .describe('help', 'Print usage.')
210 .describe('log-level', '<disable | error | warn | info | debug> Level of logging.')
211 .describe('colors', 'Use colors when reporting and printing logs.')
212 .describe('no-colors', 'Do not use colors when reporting or printing logs.')
213}
214
215var describeStop = function () {
216 optimist
217 .usage('Karma - Spectacular Test Runner for JavaScript.\n\n' +
218 'STOP - Stop the server (requires running server).\n\n' +
219 'Usage:\n' +
220 ' $0 run [<configFile>] [<options>]')
221 .describe('port', '<integer> Port where the server is listening.')
222 .describe('log-level', '<disable | error | warn | info | debug> Level of logging.')
223 .describe('help', 'Print usage.')
224}
225
226var describeCompletion = function () {
227 optimist
228 .usage('Karma - Spectacular Test Runner for JavaScript.\n\n' +
229 'COMPLETION - Bash/ZSH completion for karma.\n\n' +
230 'Installation:\n' +
231 ' $0 completion >> ~/.bashrc\n')
232 .describe('help', 'Print usage.')
233}
234
235exports.process = function () {
236 var argv = optimist.parse(argsBeforeDoubleDash(process.argv.slice(2)))
237 var options = {
238 cmd: argv._.shift()
239 }
240
241 switch (options.cmd) {
242 case 'start':
243 describeStart()
244 break
245
246 case 'run':
247 describeRun()
248 options.clientArgs = parseClientArgs(process.argv)
249 break
250
251 case 'stop':
252 describeStop()
253 break
254
255 case 'init':
256 describeInit()
257 break
258
259 case 'completion':
260 describeCompletion()
261 break
262
263 default:
264 describeShared()
265 if (!options.cmd) {
266 processArgs(argv, options, fs, path)
267 console.error('Command not specified.')
268 } else {
269 console.error('Unknown command "' + options.cmd + '".')
270 }
271 optimist.showHelp()
272 process.exit(1)
273 }
274
275 return processArgs(argv, options, fs, path)
276}
277
278exports.run = function () {
279 var config = exports.process()
280
281 switch (config.cmd) {
282 case 'start':
283 new Server(config).start()
284 break
285 case 'run':
286 require('./runner').run(config)
287 break
288 case 'stop':
289 require('./stopper').stop(config)
290 break
291 case 'init':
292 require('./init').init(config)
293 break
294 case 'completion':
295 require('./completion').completion(config)
296 break
297 }
298}
299
300// just for testing
301exports.processArgs = processArgs
302exports.parseClientArgs = parseClientArgs
303exports.argsBeforeDoubleDash = argsBeforeDoubleDash