parse.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. var parse = require('../');
  2. var test = require('tape');
  3. test('parse args', function (t) {
  4. t.deepEqual(
  5. parse([ '--no-moo' ]),
  6. { moo : false, _ : [] },
  7. 'no'
  8. );
  9. t.deepEqual(
  10. parse([ '-v', 'a', '-v', 'b', '-v', 'c' ]),
  11. { v : ['a','b','c'], _ : [] },
  12. 'multi'
  13. );
  14. t.end();
  15. });
  16. test('comprehensive', function (t) {
  17. t.deepEqual(
  18. parse([
  19. '--name=meowmers', 'bare', '-cats', 'woo',
  20. '-h', 'awesome', '--multi=quux',
  21. '--key', 'value',
  22. '-b', '--bool', '--no-meep', '--multi=baz',
  23. '--', '--not-a-flag', 'eek'
  24. ]),
  25. {
  26. c : true,
  27. a : true,
  28. t : true,
  29. s : 'woo',
  30. h : 'awesome',
  31. b : true,
  32. bool : true,
  33. key : 'value',
  34. multi : [ 'quux', 'baz' ],
  35. meep : false,
  36. name : 'meowmers',
  37. _ : [ 'bare', '--not-a-flag', 'eek' ]
  38. }
  39. );
  40. t.end();
  41. });
  42. test('nums', function (t) {
  43. var argv = parse([
  44. '-x', '1234',
  45. '-y', '5.67',
  46. '-z', '1e7',
  47. '-w', '10f',
  48. '--hex', '0xdeadbeef',
  49. '789'
  50. ]);
  51. t.deepEqual(argv, {
  52. x : 1234,
  53. y : 5.67,
  54. z : 1e7,
  55. w : '10f',
  56. hex : 0xdeadbeef,
  57. _ : [ 789 ]
  58. });
  59. t.deepEqual(typeof argv.x, 'number');
  60. t.deepEqual(typeof argv.y, 'number');
  61. t.deepEqual(typeof argv.z, 'number');
  62. t.deepEqual(typeof argv.w, 'string');
  63. t.deepEqual(typeof argv.hex, 'number');
  64. t.deepEqual(typeof argv._[0], 'number');
  65. t.end();
  66. });
  67. test('flag boolean', function (t) {
  68. var argv = parse([ '-t', 'moo' ], { boolean: 't' });
  69. t.deepEqual(argv, { t : true, _ : [ 'moo' ] });
  70. t.deepEqual(typeof argv.t, 'boolean');
  71. t.end();
  72. });
  73. test('flag boolean value', function (t) {
  74. var argv = parse(['--verbose', 'false', 'moo', '-t', 'true'], {
  75. boolean: [ 't', 'verbose' ],
  76. default: { verbose: true }
  77. });
  78. t.deepEqual(argv, {
  79. verbose: false,
  80. t: true,
  81. _: ['moo']
  82. });
  83. t.deepEqual(typeof argv.verbose, 'boolean');
  84. t.deepEqual(typeof argv.t, 'boolean');
  85. t.end();
  86. });
  87. test('flag boolean default false', function (t) {
  88. var argv = parse(['moo'], {
  89. boolean: ['t', 'verbose'],
  90. default: { verbose: false, t: false }
  91. });
  92. t.deepEqual(argv, {
  93. verbose: false,
  94. t: false,
  95. _: ['moo']
  96. });
  97. t.deepEqual(typeof argv.verbose, 'boolean');
  98. t.deepEqual(typeof argv.t, 'boolean');
  99. t.end();
  100. });
  101. test('boolean groups', function (t) {
  102. var argv = parse([ '-x', '-z', 'one', 'two', 'three' ], {
  103. boolean: ['x','y','z']
  104. });
  105. t.deepEqual(argv, {
  106. x : true,
  107. y : false,
  108. z : true,
  109. _ : [ 'one', 'two', 'three' ]
  110. });
  111. t.deepEqual(typeof argv.x, 'boolean');
  112. t.deepEqual(typeof argv.y, 'boolean');
  113. t.deepEqual(typeof argv.z, 'boolean');
  114. t.end();
  115. });
  116. test('newlines in params' , function (t) {
  117. var args = parse([ '-s', "X\nX" ])
  118. t.deepEqual(args, { _ : [], s : "X\nX" });
  119. // reproduce in bash:
  120. // VALUE="new
  121. // line"
  122. // node program.js --s="$VALUE"
  123. args = parse([ "--s=X\nX" ])
  124. t.deepEqual(args, { _ : [], s : "X\nX" });
  125. t.end();
  126. });
  127. test('strings' , function (t) {
  128. var s = parse([ '-s', '0001234' ], { string: 's' }).s;
  129. t.equal(s, '0001234');
  130. t.equal(typeof s, 'string');
  131. var x = parse([ '-x', '56' ], { string: 'x' }).x;
  132. t.equal(x, '56');
  133. t.equal(typeof x, 'string');
  134. t.end();
  135. });
  136. test('stringArgs', function (t) {
  137. var s = parse([ ' ', ' ' ], { string: '_' })._;
  138. t.same(s.length, 2);
  139. t.same(typeof s[0], 'string');
  140. t.same(s[0], ' ');
  141. t.same(typeof s[1], 'string');
  142. t.same(s[1], ' ');
  143. t.end();
  144. });
  145. test('empty strings', function(t) {
  146. var s = parse([ '-s' ], { string: 's' }).s;
  147. t.equal(s, '');
  148. t.equal(typeof s, 'string');
  149. var str = parse([ '--str' ], { string: 'str' }).str;
  150. t.equal(str, '');
  151. t.equal(typeof str, 'string');
  152. var letters = parse([ '-art' ], {
  153. string: [ 'a', 't' ]
  154. });
  155. t.equal(letters.a, '');
  156. t.equal(letters.r, true);
  157. t.equal(letters.t, '');
  158. t.end();
  159. });
  160. test('slashBreak', function (t) {
  161. t.same(
  162. parse([ '-I/foo/bar/baz' ]),
  163. { I : '/foo/bar/baz', _ : [] }
  164. );
  165. t.same(
  166. parse([ '-xyz/foo/bar/baz' ]),
  167. { x : true, y : true, z : '/foo/bar/baz', _ : [] }
  168. );
  169. t.end();
  170. });
  171. test('alias', function (t) {
  172. var argv = parse([ '-f', '11', '--zoom', '55' ], {
  173. alias: { z: 'zoom' }
  174. });
  175. t.equal(argv.zoom, 55);
  176. t.equal(argv.z, argv.zoom);
  177. t.equal(argv.f, 11);
  178. t.end();
  179. });
  180. test('multiAlias', function (t) {
  181. var argv = parse([ '-f', '11', '--zoom', '55' ], {
  182. alias: { z: [ 'zm', 'zoom' ] }
  183. });
  184. t.equal(argv.zoom, 55);
  185. t.equal(argv.z, argv.zoom);
  186. t.equal(argv.z, argv.zm);
  187. t.equal(argv.f, 11);
  188. t.end();
  189. });
  190. test('nested dotted objects', function (t) {
  191. var argv = parse([
  192. '--foo.bar', '3', '--foo.baz', '4',
  193. '--foo.quux.quibble', '5', '--foo.quux.o_O',
  194. '--beep.boop'
  195. ]);
  196. t.same(argv.foo, {
  197. bar : 3,
  198. baz : 4,
  199. quux : {
  200. quibble : 5,
  201. o_O : true
  202. }
  203. });
  204. t.same(argv.beep, { boop : true });
  205. t.end();
  206. });
  207. test('boolean and alias with chainable api', function (t) {
  208. var aliased = [ '-h', 'derp' ];
  209. var regular = [ '--herp', 'derp' ];
  210. var opts = {
  211. herp: { alias: 'h', boolean: true }
  212. };
  213. var aliasedArgv = parse(aliased, {
  214. boolean: 'herp',
  215. alias: { h: 'herp' }
  216. });
  217. var propertyArgv = parse(regular, {
  218. boolean: 'herp',
  219. alias: { h: 'herp' }
  220. });
  221. var expected = {
  222. herp: true,
  223. h: true,
  224. '_': [ 'derp' ]
  225. };
  226. t.same(aliasedArgv, expected);
  227. t.same(propertyArgv, expected);
  228. t.end();
  229. });
  230. test('boolean and alias with options hash', function (t) {
  231. var aliased = [ '-h', 'derp' ];
  232. var regular = [ '--herp', 'derp' ];
  233. var opts = {
  234. alias: { 'h': 'herp' },
  235. boolean: 'herp'
  236. };
  237. var aliasedArgv = parse(aliased, opts);
  238. var propertyArgv = parse(regular, opts);
  239. var expected = {
  240. herp: true,
  241. h: true,
  242. '_': [ 'derp' ]
  243. };
  244. t.same(aliasedArgv, expected);
  245. t.same(propertyArgv, expected);
  246. t.end();
  247. });
  248. test('boolean and alias using explicit true', function (t) {
  249. var aliased = [ '-h', 'true' ];
  250. var regular = [ '--herp', 'true' ];
  251. var opts = {
  252. alias: { h: 'herp' },
  253. boolean: 'h'
  254. };
  255. var aliasedArgv = parse(aliased, opts);
  256. var propertyArgv = parse(regular, opts);
  257. var expected = {
  258. herp: true,
  259. h: true,
  260. '_': [ ]
  261. };
  262. t.same(aliasedArgv, expected);
  263. t.same(propertyArgv, expected);
  264. t.end();
  265. });
  266. // regression, see https://github.com/substack/node-optimist/issues/71
  267. test('boolean and --x=true', function(t) {
  268. var parsed = parse(['--boool', '--other=true'], {
  269. boolean: 'boool'
  270. });
  271. t.same(parsed.boool, true);
  272. t.same(parsed.other, 'true');
  273. parsed = parse(['--boool', '--other=false'], {
  274. boolean: 'boool'
  275. });
  276. t.same(parsed.boool, true);
  277. t.same(parsed.other, 'false');
  278. t.end();
  279. });