coa.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. var assert = require('chai').assert,
  2. COA = require('..');
  3. /**
  4. * Mocha BDD interface.
  5. */
  6. /** @name describe @function */
  7. /** @name it @function */
  8. /** @name before @function */
  9. /** @name after @function */
  10. /** @name beforeEach @function */
  11. /** @name afterEach @function */
  12. describe('Opt', function() {
  13. describe('Unknown option', function() {
  14. var cmd = COA.Cmd();
  15. it('should fail', function() {
  16. return cmd.do(['-a'])
  17. .then(assert.fail, emptyFn);
  18. });
  19. });
  20. describe('Short options', function() {
  21. var cmd = COA.Cmd()
  22. .opt()
  23. .name('a')
  24. .short('a')
  25. .end()
  26. .opt()
  27. .name('b')
  28. .short('b')
  29. .end()
  30. .act(function(opts) {
  31. return opts;
  32. });
  33. it('should return passed values', function() {
  34. return cmd.do(['-a', 'a', '-b', 'b'])
  35. .then(function(res) {
  36. assert.deepEqual(res, { a: 'a', b: 'b' });
  37. });
  38. });
  39. });
  40. describe('Long options', function() {
  41. var cmd = COA.Cmd()
  42. .opt()
  43. .name('long1')
  44. .long('long1')
  45. .end()
  46. .opt()
  47. .name('long2')
  48. .long('long2')
  49. .end()
  50. .act(function(opts) {
  51. return opts;
  52. });
  53. it('should return passed values', function() {
  54. return cmd.do(['--long1', 'long value', '--long2=another long value'])
  55. .then(function(res) {
  56. assert.deepEqual(res, { long1: 'long value', long2: 'another long value' });
  57. });
  58. });
  59. });
  60. describe('Array option', function() {
  61. var cmd = COA.Cmd()
  62. .opt()
  63. .name('a')
  64. .short('a')
  65. .arr()
  66. .end()
  67. .act(function(opts) {
  68. return opts;
  69. });
  70. it('should return array of passed values', function() {
  71. return cmd.do(['-a', '1', '-a', '2'])
  72. .then(function(res) {
  73. assert.deepEqual(res, { a: ['1', '2'] });
  74. });
  75. });
  76. });
  77. describe('Required option', function() {
  78. var cmd = COA.Cmd()
  79. .opt()
  80. .name('a')
  81. .short('a')
  82. .req()
  83. .end()
  84. .act(function(opts) {
  85. return opts;
  86. });
  87. it('should fail if not specified', function() {
  88. return cmd.do()
  89. .then(assert.fail, emptyFn);
  90. });
  91. it('should return passed value if specified', function() {
  92. return cmd.do(['-a', 'test'])
  93. .then(function(opts) {
  94. assert.equal(opts.a, 'test');
  95. });
  96. });
  97. });
  98. describe('Option with default value', function() {
  99. var cmd = COA.Cmd()
  100. .opt()
  101. .name('a')
  102. .short('a')
  103. .def('aaa')
  104. .end()
  105. .act(function(opts) {
  106. return opts;
  107. });
  108. it('should return default value if not specified', function() {
  109. return cmd.do()
  110. .then(function(opts) {
  111. assert.equal(opts.a, 'aaa');
  112. });
  113. });
  114. it('should return passed value if specified', function() {
  115. return cmd.do(['-a', 'test'])
  116. .then(function(opts) {
  117. assert.equal(opts.a, 'test');
  118. });
  119. });
  120. });
  121. describe('Validated / transformed option', function() {
  122. var cmd = COA.Cmd()
  123. .opt()
  124. .name('a')
  125. .short('a')
  126. .val(function(v) {
  127. if (v === 'invalid') return this.reject('fail');
  128. return { value: v };
  129. })
  130. .end()
  131. .act(function(opts) {
  132. return opts;
  133. });
  134. it('should fail if custom checks suppose to do so', function() {
  135. return cmd.do(['-a', 'invalid'])
  136. .then(assert.fail, emptyFn);
  137. });
  138. it('should return transformed value', function() {
  139. return cmd.do(['-a', 'test'])
  140. .then(function(opts) {
  141. assert.deepEqual(opts.a, { value: 'test' });
  142. });
  143. });
  144. });
  145. describe('Only option (--version case)', function() {
  146. var ver = require('../package.json').version,
  147. cmd = COA.Cmd()
  148. .opt()
  149. .name('version')
  150. .long('version')
  151. .flag()
  152. .only()
  153. .act(function() {
  154. return ver;
  155. })
  156. .end()
  157. .opt()
  158. .name('req')
  159. .short('r')
  160. .req()
  161. .end();
  162. it('should process the only() option', function() {
  163. return cmd.do(['--version'])
  164. .then(assert.fail, function(res) {
  165. assert.equal(res, ver);
  166. });
  167. });
  168. });
  169. it('input()');
  170. it('output()');
  171. });
  172. describe('Arg', function() {
  173. describe('Unknown arg', function() {
  174. var cmd = COA.Cmd();
  175. it('should fail', function() {
  176. return cmd.do(['test'])
  177. .then(assert.fail, emptyFn);
  178. });
  179. });
  180. describe('Unknown arg after known', function() {
  181. var cmd = COA.Cmd()
  182. .arg()
  183. .name('a')
  184. .end();
  185. it('should fail', function() {
  186. return cmd.do(['test', 'unknown'])
  187. .then(assert.fail, emptyFn);
  188. });
  189. });
  190. describe('Array arg', function() {
  191. var cmd = COA.Cmd()
  192. .arg()
  193. .name('a')
  194. .arr()
  195. .end()
  196. .act(function(opts, args) {
  197. return args;
  198. });
  199. it('should return array of passed values', function() {
  200. return cmd.do(['value 1', 'value 2'])
  201. .then(function(args) {
  202. assert.deepEqual(args, { a: ['value 1', 'value 2'] });
  203. });
  204. });
  205. });
  206. describe('Required arg', function() {
  207. var cmd = COA.Cmd()
  208. .arg()
  209. .name('a')
  210. .req()
  211. .end()
  212. .act(function(opts, args) {
  213. return args;
  214. });
  215. it('should fail if not specified', function() {
  216. return cmd.do()
  217. .then(assert.fail, emptyFn);
  218. });
  219. it('should return passed value if specified', function() {
  220. return cmd.do(['value'])
  221. .then(function(args) {
  222. assert.equal(args.a, 'value');
  223. });
  224. });
  225. });
  226. describe('Args after options', function() {
  227. var cmd = COA.Cmd()
  228. .opt()
  229. .name('opt')
  230. .long('opt')
  231. .end()
  232. .arg()
  233. .name('arg1')
  234. .end()
  235. .arg()
  236. .name('arg2')
  237. .arr()
  238. .end()
  239. .act(function(opts, args) {
  240. return { opts: opts, args: args };
  241. });
  242. it('should return passed values', function() {
  243. return cmd.do(['--opt', 'value', 'value', 'value 1', 'value 2'])
  244. .then(function(o) {
  245. assert.deepEqual(o, {
  246. opts: { opt: 'value' },
  247. args: {
  248. arg1: 'value',
  249. arg2: ['value 1', 'value 2']
  250. }
  251. });
  252. });
  253. });
  254. });
  255. describe('Raw args', function() {
  256. var cmd = COA.Cmd()
  257. .arg()
  258. .name('raw')
  259. .arr()
  260. .end()
  261. .act(function(opts, args) {
  262. return args;
  263. });
  264. it('should return passed arg values', function() {
  265. return cmd.do(['--', 'raw', 'arg', 'values'])
  266. .then(function(args) {
  267. assert.deepEqual(args, { raw: ['raw', 'arg', 'values'] });
  268. });
  269. });
  270. });
  271. });
  272. describe('Cmd', function() {
  273. var doTest = function(o) {
  274. assert.deepEqual(o, {
  275. opts: { opt: 'value' },
  276. args: {
  277. arg1: 'value',
  278. arg2: ['value 1', 'value 2']
  279. }
  280. });
  281. },
  282. invokeOpts = { opt: 'value' },
  283. invokeArgs = {
  284. arg1: 'value',
  285. arg2: ['value 1', 'value 2']
  286. };
  287. describe('Subcommand', function() {
  288. var cmd = COA.Cmd()
  289. .cmd()
  290. .name('command')
  291. .opt()
  292. .name('opt')
  293. .long('opt')
  294. .end()
  295. .arg()
  296. .name('arg1')
  297. .end()
  298. .arg()
  299. .name('arg2')
  300. .arr()
  301. .end()
  302. .act(function(opts, args) {
  303. return { opts: opts, args: args };
  304. })
  305. .end();
  306. describe('when specified on command line', function() {
  307. it('should be invoked and accept passed opts and args', function() {
  308. return cmd.do(['command', '--opt', 'value', 'value', 'value 1', 'value 2'])
  309. .then(doTest);
  310. });
  311. });
  312. describe('when invoked using api', function() {
  313. it('should be invoked and accept passed opts and args', function() {
  314. return cmd.api.command(invokeOpts, invokeArgs)
  315. .then(doTest);
  316. });
  317. });
  318. describe('when invoked using invoke()', function() {
  319. it('should be invoked and accept passed opts and args', function() {
  320. return cmd.invoke('command', invokeOpts, invokeArgs)
  321. .then(doTest);
  322. });
  323. });
  324. describe('when unexisting command invoked using invoke()', function() {
  325. it('should fail', function() {
  326. return cmd.invoke('unexistent')
  327. .then(assert.fail, emptyFn);
  328. });
  329. });
  330. });
  331. describe('External subcommand', function() {
  332. describe('default scheme: cmd.extendable()', function() {
  333. describe('when described as a function', function() {
  334. var cmd = COA.Cmd()
  335. .name('coa')
  336. .extendable();
  337. it('should be invoked and accept passed opts and args', function() {
  338. return cmd.do(['test', '--opt', 'value', 'value', 'value 1', 'value 2'])
  339. .then(doTest);
  340. });
  341. });
  342. describe('when described as an COA.Cmd() object', function() {
  343. var cmd = COA.Cmd()
  344. .name('coa')
  345. .extendable();
  346. it('should be invoked and accept passed opts and args', function() {
  347. return cmd.do(['test-obj', '--opt', 'value', 'value', 'value 1', 'value 2'])
  348. .then(doTest);
  349. });
  350. });
  351. describe('2nd level subcommand', function() {
  352. var cmd = COA.Cmd()
  353. .name('coa')
  354. .cmd()
  355. .name('test')
  356. .extendable()
  357. .end();
  358. it('should be invoked and accept passed opts and args', function() {
  359. return cmd.do(['test', 'obj', '--opt', 'value', 'value', 'value 1', 'value 2'])
  360. .then(doTest);
  361. });
  362. });
  363. });
  364. describe("common prefix: cmd.extendable('coa-')", function() {
  365. describe('when described as a function', function() {
  366. var cmd = COA.Cmd()
  367. .name('coa')
  368. .extendable('coa-');
  369. it('should be invoked and accept passed opts and args', function() {
  370. return cmd.do(['test', '--opt', 'value', 'value', 'value 1', 'value 2'])
  371. .then(doTest);
  372. });
  373. });
  374. });
  375. describe("format string: cmd.extendable('coa-%s')", function() {
  376. describe('when described as a function', function() {
  377. var cmd = COA.Cmd()
  378. .name('coa')
  379. .extendable('coa-%s');
  380. it('should be invoked and accept passed opts and args', function() {
  381. return cmd.do(['test', '--opt', 'value', 'value', 'value 1', 'value 2'])
  382. .then(doTest);
  383. });
  384. });
  385. });
  386. });
  387. it('helpful(), name(), title()');
  388. });
  389. function emptyFn() {
  390. // empty function
  391. }