parseArgv.js 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. 'use strict';
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. var _some2 = require('lodash/some');
  6. var _some3 = _interopRequireDefault(_some2);
  7. var _filter2 = require('lodash/filter');
  8. var _filter3 = _interopRequireDefault(_filter2);
  9. var _flatten2 = require('lodash/flatten');
  10. var _flatten3 = _interopRequireDefault(_flatten2);
  11. var _kebabCase2 = require('lodash/kebabCase');
  12. var _kebabCase3 = _interopRequireDefault(_kebabCase2);
  13. var _isArray2 = require('lodash/isArray');
  14. var _isArray3 = _interopRequireDefault(_isArray2);
  15. var _forOwn2 = require('lodash/forOwn');
  16. var _forOwn3 = _interopRequireDefault(_forOwn2);
  17. var _has2 = require('lodash/has');
  18. var _has3 = _interopRequireDefault(_has2);
  19. var _forEach2 = require('lodash/forEach');
  20. var _forEach3 = _interopRequireDefault(_forEach2);
  21. var _isUndefined2 = require('lodash/isUndefined');
  22. var _isUndefined3 = _interopRequireDefault(_isUndefined2);
  23. var _omitBy2 = require('lodash/omitBy');
  24. var _omitBy3 = _interopRequireDefault(_omitBy2);
  25. var _pick2 = require('lodash/pick');
  26. var _pick3 = _interopRequireDefault(_pick2);
  27. var _identity2 = require('lodash/identity');
  28. var _identity3 = _interopRequireDefault(_identity2);
  29. var _values2 = require('lodash/values');
  30. var _values3 = _interopRequireDefault(_values2);
  31. var _mapValues2 = require('lodash/mapValues');
  32. var _mapValues3 = _interopRequireDefault(_mapValues2);
  33. var _pickBy2 = require('lodash/pickBy');
  34. var _pickBy3 = _interopRequireDefault(_pickBy2);
  35. var _camelCase2 = require('lodash/camelCase');
  36. var _camelCase3 = _interopRequireDefault(_camelCase2);
  37. var _keys2 = require('lodash/keys');
  38. var _keys3 = _interopRequireDefault(_keys2);
  39. var _map2 = require('lodash/map');
  40. var _map3 = _interopRequireDefault(_map2);
  41. exports.default = parseArgv;
  42. var _yargs = require('yargs');
  43. var _yargs2 = _interopRequireDefault(_yargs);
  44. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  45. var BASIC_GROUP = 'Basic options:';
  46. var OUTPUT_GROUP = 'Output options:';
  47. var ADVANCED_GROUP = 'Advanced options:';
  48. var options = {
  49. 'async-only': {
  50. alias: 'A',
  51. type: 'boolean',
  52. describe: 'force all tests to take a callback (async) or return a promise',
  53. group: ADVANCED_GROUP
  54. },
  55. colors: {
  56. alias: 'c',
  57. type: 'boolean',
  58. default: undefined,
  59. describe: 'force enabling of colors',
  60. group: OUTPUT_GROUP
  61. },
  62. quiet: {
  63. alias: 'q',
  64. type: 'boolean',
  65. default: undefined,
  66. describe: 'does not show informational messages',
  67. group: OUTPUT_GROUP
  68. },
  69. interactive: {
  70. type: 'boolean',
  71. default: !!process.stdout.isTTY,
  72. describe: 'force interactive mode (default enabled in terminal)',
  73. group: OUTPUT_GROUP
  74. },
  75. growl: {
  76. alias: 'G',
  77. type: 'boolean',
  78. describe: 'enable growl notification support',
  79. group: OUTPUT_GROUP
  80. },
  81. recursive: {
  82. type: 'boolean',
  83. describe: 'include sub directories',
  84. group: ADVANCED_GROUP
  85. },
  86. reporter: {
  87. alias: 'R',
  88. type: 'string',
  89. describe: 'specify the reporter to use',
  90. group: OUTPUT_GROUP,
  91. default: 'spec',
  92. requiresArg: true
  93. },
  94. 'reporter-options': {
  95. alias: 'O',
  96. type: 'string',
  97. describe: 'reporter-specific options, --reporter-options <k=v,k2=v2,...>',
  98. group: OUTPUT_GROUP,
  99. requiresArg: true
  100. },
  101. bail: {
  102. alias: 'b',
  103. type: 'boolean',
  104. describe: 'bail after first test failure',
  105. group: ADVANCED_GROUP,
  106. default: false
  107. },
  108. glob: {
  109. type: 'string',
  110. describe: 'only test files matching <pattern> (only valid for directory entry)',
  111. group: ADVANCED_GROUP,
  112. requiresArg: true
  113. },
  114. grep: {
  115. alias: 'g',
  116. type: 'string',
  117. describe: 'only run tests matching <pattern>',
  118. group: ADVANCED_GROUP,
  119. requiresArg: true
  120. },
  121. fgrep: {
  122. alias: 'f',
  123. type: 'string',
  124. describe: 'only run tests containing <string>',
  125. group: ADVANCED_GROUP,
  126. requiresArg: true
  127. },
  128. invert: {
  129. alias: 'i',
  130. type: 'boolean',
  131. describe: 'inverts --grep and --fgrep matches',
  132. group: ADVANCED_GROUP,
  133. default: false
  134. },
  135. require: {
  136. alias: 'r',
  137. type: 'string',
  138. describe: 'require the given module',
  139. group: ADVANCED_GROUP,
  140. requiresArg: true,
  141. multiple: true
  142. },
  143. include: {
  144. type: 'string',
  145. describe: 'include the given module into test bundle',
  146. group: ADVANCED_GROUP,
  147. requiresArg: true,
  148. multiple: true
  149. },
  150. slow: {
  151. alias: 's',
  152. describe: '"slow" test threshold in milliseconds',
  153. group: ADVANCED_GROUP,
  154. default: 75,
  155. defaultDescription: '75 ms',
  156. requiresArg: true
  157. },
  158. timeout: {
  159. alias: 't',
  160. describe: 'set test-case timeout in milliseconds',
  161. group: ADVANCED_GROUP,
  162. default: 2000,
  163. defaultDescription: '2000 ms',
  164. requiresArg: true
  165. },
  166. ui: {
  167. alias: 'u',
  168. describe: 'specify user-interface (e.g. "bdd", "tdd", "exports", "qunit")',
  169. group: BASIC_GROUP,
  170. default: 'bdd',
  171. requiresArg: true
  172. },
  173. watch: {
  174. alias: 'w',
  175. type: 'boolean',
  176. describe: 'watch files for changes',
  177. group: BASIC_GROUP,
  178. default: false
  179. },
  180. 'check-leaks': {
  181. type: 'boolean',
  182. describe: 'check for global variable leaks',
  183. group: ADVANCED_GROUP,
  184. default: false
  185. },
  186. 'full-trace': {
  187. type: 'boolean',
  188. describe: 'display the full stack trace',
  189. group: ADVANCED_GROUP,
  190. default: false
  191. },
  192. 'inline-diffs': {
  193. type: 'boolean',
  194. describe: 'display actual/expected differences inline within each string',
  195. group: ADVANCED_GROUP,
  196. default: false
  197. },
  198. exit: {
  199. type: 'boolean',
  200. describe: 'require a clean shutdown of the event loop: mocha will not call process.exit',
  201. group: ADVANCED_GROUP,
  202. default: false
  203. },
  204. retries: {
  205. describe: 'set numbers of time to retry a failed test case',
  206. group: BASIC_GROUP,
  207. requiresArg: true
  208. },
  209. delay: {
  210. type: 'boolean',
  211. describe: 'wait for async suite definition',
  212. group: ADVANCED_GROUP,
  213. default: false
  214. },
  215. mode: {
  216. type: 'string',
  217. choices: ['development', 'production'],
  218. describe: 'webpack mode to use',
  219. group: BASIC_GROUP,
  220. requiresArg: true
  221. },
  222. 'webpack-config': {
  223. type: 'string',
  224. describe: 'path to webpack-config file',
  225. group: BASIC_GROUP,
  226. requiresArg: true,
  227. default: 'webpack.config.js'
  228. },
  229. 'webpack-env': {
  230. describe: 'environment passed to the webpack-config, when it is a function',
  231. group: BASIC_GROUP
  232. },
  233. opts: {
  234. type: 'string',
  235. describe: 'path to webpack-mocha options file',
  236. group: BASIC_GROUP,
  237. requiresArg: true
  238. }
  239. };
  240. var paramList = function paramList(opts) {
  241. return (0, _map3.default)((0, _keys3.default)(opts), _camelCase3.default);
  242. };
  243. var parameters = paramList(options); // camel case parameters
  244. var parametersWithMultipleArgs = paramList((0, _pickBy3.default)((0, _mapValues3.default)(options, function (v) {
  245. return !!v.requiresArg && v.multiple === true;
  246. }))); // eslint-disable-line max-len
  247. var groupedAliases = (0, _values3.default)((0, _mapValues3.default)(options, function (value, key) {
  248. return [(0, _camelCase3.default)(key), key, value.alias].filter(_identity3.default);
  249. })); // eslint-disable-line max-len
  250. function parseArgv(argv) {
  251. var ignoreDefaults = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  252. var parsedArgs = (0, _yargs2.default)().help('help').alias('help', 'h').version().options(options).strict().parse(argv);
  253. var files = parsedArgs._;
  254. if (!files.length) {
  255. files = ['./test'];
  256. }
  257. var parsedOptions = (0, _pick3.default)(parsedArgs, parameters); // pick all parameters as new object
  258. var validOptions = (0, _omitBy3.default)(parsedOptions, _isUndefined3.default); // remove all undefined values
  259. (0, _forEach3.default)(parametersWithMultipleArgs, function (key) {
  260. if ((0, _has3.default)(validOptions, key)) {
  261. var value = validOptions[key];
  262. if (!Array.isArray(value)) {
  263. validOptions[key] = [value];
  264. }
  265. }
  266. });
  267. (0, _forOwn3.default)(validOptions, function (value, key) {
  268. // validate all non-array options with required arg that it is not duplicated
  269. // see https://github.com/yargs/yargs/issues/229
  270. if (parametersWithMultipleArgs.indexOf(key) === -1 && (0, _isArray3.default)(value)) {
  271. var arg = (0, _kebabCase3.default)(key);
  272. var provided = value.map(function (v) {
  273. return '--' + arg + ' ' + v;
  274. }).join(' ');
  275. var expected = '--' + arg + ' ' + value[0];
  276. throw new Error('Duplicating arguments for "--' + arg + '" is not allowed. "' + provided + '" was provided, but expected "' + expected + '"'); // eslint-disable-line max-len
  277. }
  278. });
  279. validOptions.files = files;
  280. var reporterOptions = {};
  281. if (validOptions.reporterOptions) {
  282. validOptions.reporterOptions.split(',').forEach(function (opt) {
  283. var L = opt.split('=');
  284. if (L.length > 2 || L.length === 0) {
  285. throw new Error('invalid reporter option ' + opt);
  286. } else if (L.length === 2) {
  287. reporterOptions[L[0]] = L[1]; // eslint-disable-line prefer-destructuring
  288. } else {
  289. reporterOptions[L[0]] = true;
  290. }
  291. });
  292. }
  293. validOptions.reporterOptions = reporterOptions;
  294. validOptions.require = validOptions.require || [];
  295. validOptions.include = validOptions.include || [];
  296. if (ignoreDefaults) {
  297. var userOptions = (0, _yargs2.default)(argv).argv;
  298. var providedKeys = (0, _keys3.default)(userOptions);
  299. var usedAliases = (0, _flatten3.default)((0, _filter3.default)(groupedAliases, function (aliases) {
  300. return (0, _some3.default)(aliases, function (alias) {
  301. return providedKeys.indexOf(alias) !== -1;
  302. });
  303. }));
  304. if (parsedArgs._.length) {
  305. usedAliases.push('files');
  306. }
  307. return (0, _pick3.default)(validOptions, usedAliases);
  308. }
  309. return validOptions;
  310. }