yargs 1.2.2 → 1.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.travis.yml CHANGED
@@ -1,4 +1,3 @@
1
1
  language: node_js
2
2
  node_js:
3
3
  - "0.10"
4
- - "0.8"
package/README.md CHANGED
@@ -9,7 +9,9 @@ With yargs, ye be havin' a map that leads straight to yer treasure! Treasure of
9
9
  [![Dependency Status](https://gemnasium.com/chevex/yargs.png)](https://gemnasium.com/chevex/yargs)
10
10
  [![NPM version](https://badge.fury.io/js/yargs.png)](http://badge.fury.io/js/yargs)
11
11
 
12
- > NOTE: Yargs is a fork of [optimist](https://github.com/substack/node-optimist) by [substack (James Halliday)](https://github.com/substack). It is obvious that substack is stretched pretty thin maintaining over 300 modules on npm at the time of this writing. So rather than complain in the project issue tracker I thought I'd just pick up the torch and maintain a proper fork. Currently the project is totally backward compatible with optimist but this may change in the future (if it does I will update this notice to inform you of this). For now though, enjoy optimist with about 5 months worth of fixes and updates rolled in, most of them pulled from optimist's own [stale pull requests](https://github.com/substack/node-optimist/pulls).
12
+ > ~~NOTE: Yargs is a fork of [optimist](https://github.com/substack/node-optimist) by [substack (James Halliday)](https://github.com/substack). It is obvious that substack is stretched pretty thin maintaining over 300 modules on npm at the time of this writing. So rather than complain in the project issue tracker I thought I'd just pick up the torch and maintain a proper fork. Currently the project is totally backward compatible with optimist but this may change in the future (if it does I will update this notice to inform you of this). For now though, enjoy optimist with about 5 months worth of fixes and updates rolled in, most of them pulled from optimist's own [stale pull requests](https://github.com/substack/node-optimist/pulls).~~
13
+
14
+ > UPDATE: Yargs is now the official successor to optimist. Please feel free to submit issues and pull requests. While I personally don't have the time to pour over all the issues and fix all of them on a regular basis, I'm more than happy to look over pull requests, test them, and merge them in. If you'd like to contribute and don't know where to start, have a look at [the issue list](https://github.com/chevex/yargs/issues) :)
13
15
 
14
16
  examples
15
17
  ========
@@ -384,6 +386,16 @@ If `key` is an Array, demand each element.
384
386
  If `msg` is supplied, it will be printed when the argument is missing,
385
387
  instead of the standard error message. This is especially helpful for the non-option arguments in `argv._`.
386
388
 
389
+ .requiresArg(key)
390
+ -----------------
391
+
392
+ Specifies either a single option key (string), or an array of options that
393
+ must be followed by option values. If any option value is missing, show the
394
+ usage information and exit.
395
+
396
+ The default behaviour is to set the value of any key not followed by an
397
+ option value to `true`.
398
+
387
399
  .describe(key, desc)
388
400
  --------------------
389
401
 
@@ -421,13 +433,15 @@ var argv = require('yargs')
421
433
 
422
434
  Optionally `.options()` can take an object that maps keys to `opt` parameters.
423
435
 
424
- .usage(message)
425
- ---------------
436
+ .usage(message, opts)
437
+ ---------------------
426
438
 
427
439
  Set a usage message to show which commands to use. Inside `message`, the string
428
440
  `$0` will get interpolated to the current script name or node command for the
429
441
  present script similar to how `$0` works in bash or perl.
430
442
 
443
+ `opts` is optional and acts like calling `.options(opts)`.
444
+
431
445
  .example(cmd, desc)
432
446
  -------------------
433
447
 
@@ -476,6 +490,12 @@ is loaded and parsed, and its properties are set as arguments.
476
490
 
477
491
  Format usage output to wrap at `columns` many columns.
478
492
 
493
+ .strict()
494
+ ---------
495
+
496
+ Any command-line argument given that is not demanded, or does not have a
497
+ corresponding description, will be reported as an error.
498
+
479
499
  .help()
480
500
  -------
481
501
 
package/example/bool.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  var util = require('util');
3
- var argv = require('optimist').argv;
3
+ var argv = require('yargs').argv;
4
4
 
5
5
  if (argv.s) {
6
6
  util.print(argv.fr ? 'Le chat dit: ' : 'The cat says: ');
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- var argv = require('optimist')
2
+ var argv = require('yargs')
3
3
  .boolean(['x','y','z'])
4
4
  .argv
5
5
  ;
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- var argv = require('optimist')
2
+ var argv = require('yargs')
3
3
  .boolean('v')
4
4
  .argv
5
5
  ;
package/example/count.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- var argv = require('optimist')
2
+ var argv = require('yargs')
3
3
  .count('verbose')
4
4
  .alias('v', 'verbose')
5
5
  .argv;
@@ -12,4 +12,4 @@ function DEBUG() { VERBOSE_LEVEL >= 2 && console.log.apply(console, arguments);
12
12
 
13
13
  WARN("Showing only important stuff");
14
14
  INFO("Showing semi-important stuff too");
15
- DEBUG("Extra chatty mode");
15
+ DEBUG("Extra chatty mode");
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- var argv = require('optimist')
3
+ var argv = require('yargs')
4
4
  .default({ x : 10, y : 10 })
5
5
  .argv
6
6
  ;
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- var argv = require('optimist')
2
+ var argv = require('yargs')
3
3
  .default('x', 10)
4
4
  .default('y', 10)
5
5
  .argv
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- var argv = require('optimist')
2
+ var argv = require('yargs')
3
3
  .demand(2)
4
4
  .argv;
5
5
  console.dir(argv)
package/example/divide.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- var argv = require('optimist')
3
+ var argv = require('yargs')
4
4
  .usage('Usage: $0 -x [num] -y [num]')
5
5
  .demand(['x','y'])
6
6
  .argv;
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- var argv = require('../index')
3
+ var argv = require('yargs')
4
4
  .usage('Usage: $0 -x [num] -y [num]')
5
5
  .implies('x', 'y')
6
6
  .argv;
7
7
 
8
8
  if (argv.x) {
9
9
  console.log(argv.x / argv.y);
10
- }
10
+ }
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- var argv = require('../index')
3
+ var argv = require('yargs')
4
4
  .usage('Usage: $0 -x [num] -y [num] -w [msg] -h [msg]')
5
5
  .implies({
6
6
  x: 'y',
@@ -23,4 +23,4 @@ if (argv.w) {
23
23
 
24
24
  if (argv.h) {
25
25
  console.log('h: ' +argv.h);
26
- }
26
+ }
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- var argv = require('optimist')
2
+ var argv = require('yargs')
3
3
  .usage('Count the lines in a file.\nUsage: $0')
4
4
  .demand('f')
5
5
  .alias('f', 'file')
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- var argv = require('optimist')
2
+ var argv = require('yargs')
3
3
  .usage('Count the lines in a file.\nUsage: $0')
4
4
  .options({
5
5
  file : {
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- var argv = require('optimist')
2
+ var argv = require('yargs')
3
3
  .usage('Count the lines in a file.\nUsage: $0')
4
4
  .wrap(80)
5
5
  .demand('f')
package/example/nonopt.js CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- var argv = require('optimist').argv;
2
+ var argv = require('yargs').argv;
3
3
  console.log('(%d,%d)', argv.x, argv.y);
4
4
  console.log(argv._);
@@ -0,0 +1,19 @@
1
+ var yargs = require('yargs');
2
+
3
+ var argv = yargs.usage('This is my awesome program', {
4
+ 'input': {
5
+ description: 'Input file name',
6
+ requiresArg: true,
7
+ short: 'i',
8
+ },
9
+ 'output': {
10
+ description: 'Output file name',
11
+ requiresArg: true,
12
+ short: 'o'
13
+ }
14
+ }).argv;
15
+
16
+ yargs.showHelp();
17
+
18
+ console.log('\n\nInspecting options');
19
+ console.dir(argv);
package/example/short.js CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- var argv = require('optimist').argv;
2
+ var argv = require('yargs').argv;
3
3
  console.log('(%d,%d)', argv.x, argv.y);
@@ -0,0 +1,19 @@
1
+ var yargs = require('yargs');
2
+
3
+ var argv = yargs.usage('This is my awesome program', {
4
+ 'about': {
5
+ description: 'Provide some details about the author of this program',
6
+ boolean: true,
7
+ short: 'a',
8
+ },
9
+ 'info': {
10
+ description: 'Provide some information about this program',
11
+ boolean: true,
12
+ short: 'i'
13
+ }
14
+ }).strict().argv;
15
+
16
+ yargs.showHelp();
17
+
18
+ console.log('\n\nInspecting options');
19
+ console.dir(argv);
package/example/string.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- var argv = require('optimist')
2
+ var argv = require('yargs')
3
3
  .string('x', 'y')
4
4
  .argv
5
5
  ;
@@ -1,6 +1,6 @@
1
- var optimist = require('./../index');
1
+ var yargs = require('yargs');
2
2
 
3
- var argv = optimist.usage('This is my awesome program', {
3
+ var argv = yargs.usage('This is my awesome program', {
4
4
  'about': {
5
5
  description: 'Provide some details about the author of this program',
6
6
  required: true,
@@ -13,7 +13,7 @@ var argv = optimist.usage('This is my awesome program', {
13
13
  }
14
14
  }).argv;
15
15
 
16
- optimist.showHelp();
16
+ yargs.showHelp();
17
17
 
18
18
  console.log('\n\nInspecting options');
19
- console.dir(argv);
19
+ console.dir(argv);
package/example/xup.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- var argv = require('optimist').argv;
2
+ var argv = require('yargs').argv;
3
3
 
4
4
  if (argv.rif - 5 * argv.xup > 7.138) {
5
5
  console.log('Buy more riffiwobbles');
@@ -7,4 +7,3 @@ if (argv.rif - 5 * argv.xup > 7.138) {
7
7
  else {
8
8
  console.log('Sell the xupptumblers');
9
9
  }
10
-
package/index.js CHANGED
@@ -45,6 +45,7 @@ function Argv (processArgs, cwd) {
45
45
  string: [],
46
46
  alias: {},
47
47
  default: [],
48
+ requiresArg: [],
48
49
  count: [],
49
50
  normalize: [],
50
51
  config: []
@@ -127,6 +128,11 @@ function Argv (processArgs, cwd) {
127
128
  return self;
128
129
  };
129
130
 
131
+ self.requiresArg = function (requiresArgs) {
132
+ options.requiresArg.push.apply(options.requiresArg, [].concat(requiresArgs));
133
+ return self;
134
+ };
135
+
130
136
  var implied = {};
131
137
  self.implies = function (key, value) {
132
138
  if (typeof key === 'object') {
@@ -225,6 +231,10 @@ function Argv (processArgs, cwd) {
225
231
  if (desc) {
226
232
  self.describe(key, desc);
227
233
  }
234
+
235
+ if (opt.requiresArg) {
236
+ self.requiresArg(key);
237
+ }
228
238
  }
229
239
 
230
240
  return self;
@@ -235,6 +245,12 @@ function Argv (processArgs, cwd) {
235
245
  wrap = cols;
236
246
  return self;
237
247
  };
248
+
249
+ var strict = false;
250
+ self.strict = function () {
251
+ strict = true;
252
+ return self;
253
+ };
238
254
 
239
255
  self.showHelp = function (fn) {
240
256
  if (!fn) fn = console.error.bind(console);
@@ -281,6 +297,11 @@ function Argv (processArgs, cwd) {
281
297
  help.unshift(usage.replace(/\$0/g, self.$0), '');
282
298
  }
283
299
 
300
+ keys = keys.filter(function(key) {
301
+ return Object.keys(options.alias).every(function(alias) {
302
+ return -1 == options.alias[alias].indexOf(key);
303
+ });
304
+ });
284
305
  var switches = keys.reduce(function (acc, key) {
285
306
  acc[key] = [ key ].concat(options.alias[key] || [])
286
307
  .map(function (sw) {
@@ -290,7 +311,7 @@ function Argv (processArgs, cwd) {
290
311
  ;
291
312
  return acc;
292
313
  }, {});
293
-
314
+
294
315
  var switchlen = longest(Object.keys(switches).map(function (s) {
295
316
  return switches[s] || '';
296
317
  }));
@@ -385,6 +406,27 @@ function Argv (processArgs, cwd) {
385
406
  );
386
407
  }
387
408
  }
409
+
410
+ if (options.requiresArg.length > 0) {
411
+ var missingRequiredArgs = [];
412
+
413
+ options.requiresArg.forEach(function(key) {
414
+ var value = argv[key];
415
+
416
+ // minimist sets --foo value to true / --no-foo to false
417
+ if (value === true || value === false) {
418
+ missingRequiredArgs.push(key);
419
+ }
420
+ });
421
+
422
+ if (missingRequiredArgs.length == 1) {
423
+ fail("Missing argument value: " + missingRequiredArgs[0]);
424
+ }
425
+ else if (missingRequiredArgs.length > 1) {
426
+ message = "Missing argument values: " + missingRequiredArgs.join(", ");
427
+ fail(message);
428
+ }
429
+ }
388
430
 
389
431
  var missing = null;
390
432
  Object.keys(demanded).forEach(function (key) {
@@ -406,7 +448,35 @@ function Argv (processArgs, cwd) {
406
448
 
407
449
  fail('Missing required arguments: ' + Object.keys(missing).join(', ') + customMsg);
408
450
  }
409
-
451
+
452
+ if (strict) {
453
+ var unknown = [];
454
+
455
+ var aliases = {};
456
+
457
+ Object.keys(options.alias).forEach(function (key) {
458
+ options.alias[key].forEach(function (alias) {
459
+ aliases[alias] = key;
460
+ });
461
+ });
462
+
463
+ Object.keys(argv).forEach(function (key) {
464
+ if (key !== "$0" && key !== "_" &&
465
+ !descriptions.hasOwnProperty(key) &&
466
+ !demanded.hasOwnProperty(key) &&
467
+ !aliases.hasOwnProperty(key)) {
468
+ unknown.push(key);
469
+ }
470
+ });
471
+
472
+ if (unknown.length == 1) {
473
+ fail("Unknown argument: " + unknown[0]);
474
+ }
475
+ else if (unknown.length > 1) {
476
+ fail("Unknown arguments: " + unknown.join(", "));
477
+ }
478
+ }
479
+
410
480
  checks.forEach(function (f) {
411
481
  try {
412
482
  var result = f(argv, aliases);
package/lib/minimist.js CHANGED
@@ -50,6 +50,15 @@ module.exports = function (args, opts) {
50
50
 
51
51
  var defaults = opts['default'] || {};
52
52
 
53
+ Object.keys(defaults || {}).forEach(function (key) {
54
+ if (/-/.test(key) && !opts.alias[key]) {
55
+ aliases[key] = (aliases[key] || []).concat(toCamelCase(key));
56
+ }
57
+ (aliases[key] || []).forEach(function (alias) {
58
+ defaults[alias] = defaults[key];
59
+ });
60
+ });
61
+
53
62
  var argv = { _ : [] };
54
63
  Object.keys(flags.bools).forEach(function (key) {
55
64
  setArg(key, defaults[key] === undefined ? false : defaults[key]);
@@ -76,7 +85,6 @@ module.exports = function (args, opts) {
76
85
  if (flags.configs[key]) {
77
86
  try {
78
87
  var config = JSON.parse(fs.readFileSync(val, 'utf8'));
79
- console.warn(config);
80
88
  Object.keys(config).forEach(function (key) {
81
89
  setArg(key, config[key]);
82
90
  });
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "yargs",
3
- "version": "1.2.2",
3
+ "version": "1.2.6",
4
4
  "description": "Light-weight option parsing with an argv hash. No optstrings attached.",
5
5
  "main": "./index.js",
6
6
  "dependencies": {
7
- "minimist": "~0.0.1"
7
+ "minimist": "^0.1.0"
8
8
  },
9
9
  "devDependencies": {
10
10
  "hashish": "*",
@@ -34,6 +34,41 @@ describe('parse', function () {
34
34
  result.should.have.property('someOption').that.is.a('boolean').and.is.true;
35
35
  });
36
36
 
37
+ it('should provide defaults of options with dashes as camelCase properties', function() {
38
+ var result = yargs()
39
+ .option('some-option', {
40
+ describe : 'some option',
41
+ default : 'asdf'
42
+ })
43
+ .parse([ ]);
44
+
45
+ result.should.have.property('someOption', 'asdf');
46
+ });
47
+
48
+ it('should provide aliases of options with dashes as camelCase properties', function() {
49
+ var result = yargs()
50
+ .option('some-option', {
51
+ alias : 'o',
52
+ describe : 'some option',
53
+ default : 'asdf'
54
+ })
55
+ .parse([ ]);
56
+
57
+ result.should.have.property('o', 'asdf');
58
+ });
59
+
60
+ it('should provide aliases of options with dashes as camelCase properties', function() {
61
+ var result = yargs()
62
+ .option('o', {
63
+ alias : 'some-option',
64
+ describe : 'some option',
65
+ default : 'asdf'
66
+ })
67
+ .parse([ ]);
68
+
69
+ result.should.have.property('someOption', 'asdf');
70
+ });
71
+
37
72
  it('should provide aliases with dashes as camelCase properties', function() {
38
73
  var result = yargs()
39
74
  .option('o', {
@@ -0,0 +1,82 @@
1
+ var should = require('chai').should(),
2
+ yargs = require('../');
3
+
4
+ describe('parse', function () {
5
+
6
+ describe('defaults', function () {
7
+ function checkNoArgs(argv, hasAlias) {
8
+ it('should set defaults if no args', function() {
9
+ var result = argv.parse([ ]);
10
+ result.should.have.property('flag', true);
11
+ if (hasAlias) {
12
+ result.should.have.property('f', true);
13
+ }
14
+ });
15
+ }
16
+
17
+ function checkExtraArg(argv, hasAlias) {
18
+ it('should set defaults if one extra arg', function() {
19
+ var result = argv.parse([ 'extra' ]);
20
+ result.should.have.property('flag', true);
21
+ result.should.have.property('_').and.deep.equal(['extra']);
22
+ if (hasAlias) {
23
+ result.should.have.property('f', true);
24
+ }
25
+ });
26
+ }
27
+
28
+ function checkStringArg(argv, hasAlias) {
29
+ it('should set defaults even if arg looks like a string', function() {
30
+ var result = argv.parse([ '--flag', 'extra' ]);
31
+ result.should.have.property('flag', true);
32
+ result.should.have.property('_').and.deep.equal(['extra']);
33
+ if (hasAlias) {
34
+ result.should.have.property('f', true);
35
+ }
36
+ });
37
+ }
38
+
39
+ describe('for options with aliases', function () {
40
+ var args = yargs().options({
41
+ flag : {
42
+ alias : 'f',
43
+ default : true
44
+ }
45
+ });
46
+
47
+ checkNoArgs(args, true);
48
+ checkExtraArg(args, true);
49
+ // This test case should fail, because we didn't specify that the
50
+ // option is a boolean
51
+ // checkStringArg(args, true);
52
+ });
53
+
54
+ describe('for typed options without aliases', function () {
55
+ var args = yargs().options({
56
+ flag : {
57
+ type : 'boolean',
58
+ default : true
59
+ }
60
+ });
61
+
62
+ checkNoArgs(args);
63
+ checkExtraArg(args);
64
+ checkStringArg(args);
65
+ });
66
+
67
+ describe('for typed options with aliases', function () {
68
+ var args = yargs().options({
69
+ flag : {
70
+ alias : 'f',
71
+ type : 'boolean',
72
+ default : true
73
+ }
74
+ });
75
+
76
+ checkNoArgs(args, true);
77
+ checkExtraArg(args, true);
78
+ checkStringArg(args, true);
79
+ });
80
+ });
81
+
82
+ });
package/test/usage.js CHANGED
@@ -275,6 +275,22 @@ describe('usage', function () {
275
275
  r.result.should.have.property('_').with.length(0);
276
276
  });
277
277
 
278
+ it('should print a single line when failing and default is set for an alias', function() {
279
+ var r = checkUsage(function() {
280
+ return yargs('')
281
+ .alias('f', 'foo')
282
+ .default('f', 5)
283
+ .demand(1)
284
+ .argv
285
+ ;
286
+ });
287
+ r.errors.join('\n').split(/\n+/).should.deep.equal([
288
+ 'Options:',
289
+ ' -f, --foo [default: 5]',
290
+ 'Not enough non-option arguments: got 0, need at least 1',
291
+ ]);
292
+ });
293
+
278
294
  it('should allow you to set default values for a hash of options', function () {
279
295
  var r = checkUsage(function () {
280
296
  return yargs('--foo 50 --baz 70'.split(' '))
@@ -290,6 +306,209 @@ describe('usage', function () {
290
306
  r.result.should.have.property('quux', 30);
291
307
  });
292
308
 
309
+ describe('required arguments', function () {
310
+ describe('with options object', function () {
311
+ it('should show a failure message if a required option is missing', function () {
312
+ var r = checkUsage(function () {
313
+ var opts = {
314
+ foo: { description: 'foo option', alias: 'f', requiresArg: true },
315
+ bar: { description: 'bar option', alias: 'b', requiresArg: true }
316
+ };
317
+
318
+ return yargs('-f --bar 20'.split(' '))
319
+ .usage('Usage: $0 [options]', opts)
320
+ .argv;
321
+ });
322
+ r.should.have.property('result');
323
+ r.result.should.have.property('_').with.length(0);
324
+ r.should.have.property('errors');
325
+ r.should.have.property('logs').with.length(0);
326
+ r.should.have.property('exit').and.be.ok;
327
+ r.errors.join('\n').split(/\n+/).should.deep.equal([
328
+ 'Usage: ./usage [options]',
329
+ 'Options:',
330
+ ' --foo, -f foo option',
331
+ ' --bar, -b bar option',
332
+ 'Missing argument value: foo',
333
+ ]);
334
+ });
335
+
336
+ it('should show a failure message if more than one required option is missing', function () {
337
+ var r = checkUsage(function () {
338
+ var opts = {
339
+ foo: { description: 'foo option', alias: 'f', requiresArg: true },
340
+ bar: { description: 'bar option', alias: 'b', requiresArg: true }
341
+ };
342
+
343
+ return yargs('-f --bar'.split(' '))
344
+ .usage('Usage: $0 [options]', opts)
345
+ .argv;
346
+ });
347
+ r.should.have.property('result');
348
+ r.result.should.have.property('_').with.length(0);
349
+ r.should.have.property('errors');
350
+ r.should.have.property('logs').with.length(0);
351
+ r.should.have.property('exit').and.be.ok;
352
+ r.errors.join('\n').split(/\n+/).should.deep.equal([
353
+ 'Usage: ./usage [options]',
354
+ 'Options:',
355
+ ' --foo, -f foo option',
356
+ ' --bar, -b bar option',
357
+ 'Missing argument values: foo, bar',
358
+ ]);
359
+ });
360
+ });
361
+
362
+ describe('with requiresArg method', function () {
363
+ it('should show a failure message if a required option is missing', function () {
364
+ var r = checkUsage(function () {
365
+ var opts = {
366
+ foo: { description: 'foo option', alias: 'f' },
367
+ bar: { description: 'bar option', alias: 'b' }
368
+ };
369
+
370
+ return yargs('-f --bar 20'.split(' '))
371
+ .usage('Usage: $0 [options]', opts)
372
+ .requiresArg(['foo', 'bar'])
373
+ .argv;
374
+ });
375
+ r.should.have.property('result');
376
+ r.result.should.have.property('_').with.length(0);
377
+ r.should.have.property('errors');
378
+ r.should.have.property('logs').with.length(0);
379
+ r.should.have.property('exit').and.be.ok;
380
+ r.errors.join('\n').split(/\n+/).should.deep.equal([
381
+ 'Usage: ./usage [options]',
382
+ 'Options:',
383
+ ' --foo, -f foo option',
384
+ ' --bar, -b bar option',
385
+ 'Missing argument value: foo',
386
+ ]);
387
+ });
388
+ });
389
+ });
390
+
391
+ context("with strict() option set", function () {
392
+ it('should fail given an option argument that is not demanded', function () {
393
+ var r = checkUsage(function () {
394
+ opts = {
395
+ foo: { demand: 'foo option', alias: 'f' },
396
+ bar: { demand: 'bar option', alias: 'b' }
397
+ };
398
+
399
+ return yargs('-f 10 --bar 20 --baz 30'.split(' '))
400
+ .usage('Usage: $0 [options]', opts)
401
+ .strict()
402
+ .argv;
403
+ });
404
+
405
+ r.should.have.property('result');
406
+ r.result.should.have.property('_').with.length(0);
407
+ r.result.should.have.property('f', 10);
408
+ r.result.should.have.property('foo', 10);
409
+ r.result.should.have.property('b', 20);
410
+ r.result.should.have.property('bar', 20);
411
+ r.result.should.have.property('baz', 30);
412
+ r.should.have.property('errors');
413
+ r.errors.join('\n').split(/\n+/).should.deep.equal([
414
+ 'Usage: ./usage [options]',
415
+ 'Options:',
416
+ ' --foo, -f [required]',
417
+ ' --bar, -b [required]',
418
+ 'Unknown argument: baz',
419
+ ]);
420
+ r.should.have.property('logs').with.length(0);
421
+ r.should.have.property('exit').and.be.ok;
422
+ });
423
+
424
+ it('should fail given an option argument without a corresponding description', function () {
425
+ var r = checkUsage(function () {
426
+ opts = {
427
+ foo: { description: 'foo option', alias: 'f' },
428
+ bar: { description: 'bar option', alias: 'b' }
429
+ };
430
+
431
+ return yargs('-f 10 --bar 20 --baz 30'.split(' '))
432
+ .usage('Usage: $0 [options]', opts)
433
+ .strict()
434
+ .argv;
435
+ });
436
+
437
+ r.should.have.property('result');
438
+ r.result.should.have.property('_').with.length(0);
439
+ r.result.should.have.property('f', 10);
440
+ r.result.should.have.property('foo', 10);
441
+ r.result.should.have.property('b', 20);
442
+ r.result.should.have.property('bar', 20);
443
+ r.result.should.have.property('baz', 30);
444
+ r.should.have.property('errors');
445
+ r.errors.join('\n').split(/\n+/).should.deep.equal([
446
+ 'Usage: ./usage [options]',
447
+ 'Options:',
448
+ ' --foo, -f foo option',
449
+ ' --bar, -b bar option',
450
+ 'Unknown argument: baz',
451
+ ]);
452
+ r.should.have.property('logs').with.length(0);
453
+ r.should.have.property('exit').and.be.ok;
454
+ });
455
+
456
+ it('should fail given multiple option arguments without corresponding descriptions', function () {
457
+ var r = checkUsage(function () {
458
+ opts = {
459
+ foo: { description: 'foo option', alias: 'f' },
460
+ bar: { description: 'bar option', alias: 'b' }
461
+ };
462
+
463
+ return yargs('-f 10 --bar 20 --baz 30 -q 40'.split(' '))
464
+ .usage('Usage: $0 [options]', opts)
465
+ .strict()
466
+ .argv;
467
+ });
468
+
469
+ r.should.have.property('result');
470
+ r.result.should.have.property('_').with.length(0);
471
+ r.result.should.have.property('f', 10);
472
+ r.result.should.have.property('foo', 10);
473
+ r.result.should.have.property('b', 20);
474
+ r.result.should.have.property('bar', 20);
475
+ r.result.should.have.property('baz', 30);
476
+ r.result.should.have.property('q', 40);
477
+ r.should.have.property('errors');
478
+ r.errors.join('\n').split(/\n+/).should.deep.equal([
479
+ 'Usage: ./usage [options]',
480
+ 'Options:',
481
+ ' --foo, -f foo option',
482
+ ' --bar, -b bar option',
483
+ 'Unknown arguments: baz, q',
484
+ ]);
485
+ r.should.have.property('logs').with.length(0);
486
+ r.should.have.property('exit').and.be.ok;
487
+ });
488
+
489
+ it('should pass given option arguments with corresponding descriptions', function () {
490
+ var r = checkUsage(function () {
491
+ opts = {
492
+ foo: { description: 'foo option' },
493
+ bar: { description: 'bar option' }
494
+ };
495
+
496
+ return yargs('--foo 10 --bar 20'.split(' '))
497
+ .usage('Usage: $0 [options]', opts)
498
+ .strict()
499
+ .argv;
500
+ });
501
+
502
+ r.should.have.property('result');
503
+ r.result.should.have.property('foo', 10);
504
+ r.result.should.have.property('bar', 20)
505
+ r.result.should.have.property('_').with.length(0);
506
+ r.should.have.property('errors').with.length(0);
507
+ r.should.have.property('logs').with.length(0);
508
+ r.should.have.property('exit', false);
509
+ });
510
+ });
511
+
293
512
  it('should display example on fail', function () {
294
513
  var r = checkUsage(function () {
295
514
  return yargs('')