coa 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. package/.npmignore +6 -0
  2. package/.nyc_output/1f2a0db5a6d6559149db56d397f47cfc.json +1 -0
  3. package/.nyc_output/75b82d38f2186df930141082076e11c6.json +1 -0
  4. package/.travis.yml +9 -0
  5. package/GNUmakefile +34 -0
  6. package/README.md +1 -19
  7. package/coverage/base.css +212 -0
  8. package/coverage/coa/index.html +93 -0
  9. package/coverage/coa/index.js.html +68 -0
  10. package/coverage/coa/lib/arg.js.html +239 -0
  11. package/coverage/coa/lib/cmd.js.html +1556 -0
  12. package/coverage/coa/lib/coaobject.js.html +365 -0
  13. package/coverage/coa/lib/coaparam.js.html +440 -0
  14. package/coverage/coa/lib/color.js.html +131 -0
  15. package/coverage/coa/lib/completion.js.html +593 -0
  16. package/coverage/coa/lib/index.html +197 -0
  17. package/coverage/coa/lib/index.js.html +107 -0
  18. package/coverage/coa/lib/opt.js.html +524 -0
  19. package/coverage/coa/lib/shell.js.html +107 -0
  20. package/coverage/index.html +106 -0
  21. package/coverage/prettify.css +1 -0
  22. package/coverage/prettify.js +1 -0
  23. package/coverage/sort-arrow-sprite.png +0 -0
  24. package/coverage/sorter.js +158 -0
  25. package/index.js +1 -1
  26. package/lib/arg.js +161 -44
  27. package/lib/cmd.js +547 -434
  28. package/lib/color.js +22 -19
  29. package/lib/completion.js +119 -161
  30. package/lib/index.js +10 -14
  31. package/lib/opt.js +313 -130
  32. package/lib/shell.js +13 -13
  33. package/package.json +14 -19
  34. package/qq.js +17 -0
  35. package/src/arg.coffee +130 -0
  36. package/src/cmd.coffee +456 -0
  37. package/src/color.coffee +25 -0
  38. package/src/completion.coffee +156 -0
  39. package/src/index.coffee +5 -0
  40. package/src/opt.coffee +243 -0
  41. package/src/shell.coffee +10 -0
  42. package/test/coa.js +496 -0
  43. package/test/mocha.opts +2 -0
  44. package/test/shell-test.js +60 -0
  45. package/tests/api-h.js +9 -0
  46. package/tests/h.js +6 -0
  47. package/LICENSE +0 -21
  48. package/lib/coaobject.js +0 -100
  49. package/lib/coaparam.js +0 -125
package/test/coa.js ADDED
@@ -0,0 +1,496 @@
1
+ var assert = require('chai').assert,
2
+ COA = require('..');
3
+
4
+ /**
5
+ * Mocha BDD interface.
6
+ */
7
+ /** @name describe @function */
8
+ /** @name it @function */
9
+ /** @name before @function */
10
+ /** @name after @function */
11
+ /** @name beforeEach @function */
12
+ /** @name afterEach @function */
13
+
14
+ describe('Opt', function() {
15
+
16
+ describe('Unknown option', function() {
17
+
18
+ var cmd = COA.Cmd();
19
+
20
+ it('should fail', function() {
21
+ return cmd.do(['-a'])
22
+ .then(assert.fail, emptyFn);
23
+ });
24
+
25
+ });
26
+
27
+ describe('Short options', function() {
28
+
29
+ var cmd = COA.Cmd()
30
+ .opt()
31
+ .name('a')
32
+ .short('a')
33
+ .end()
34
+ .opt()
35
+ .name('b')
36
+ .short('b')
37
+ .end()
38
+ .act(function(opts) {
39
+ return opts;
40
+ });
41
+
42
+ it('should return passed values', function() {
43
+ return cmd.do(['-a', 'a', '-b', 'b'])
44
+ .then(function(res) {
45
+ assert.deepEqual(res, { a: 'a', b: 'b' });
46
+ });
47
+ });
48
+
49
+ });
50
+
51
+ describe('Long options', function() {
52
+
53
+ var cmd = COA.Cmd()
54
+ .opt()
55
+ .name('long1')
56
+ .long('long1')
57
+ .end()
58
+ .opt()
59
+ .name('long2')
60
+ .long('long2')
61
+ .end()
62
+ .act(function(opts) {
63
+ return opts;
64
+ });
65
+
66
+ it('should return passed values', function() {
67
+ return cmd.do(['--long1', 'long value', '--long2=another long value'])
68
+ .then(function(res) {
69
+ assert.deepEqual(res, { long1: 'long value', long2: 'another long value' });
70
+ });
71
+ });
72
+
73
+ });
74
+
75
+ describe('Array option', function() {
76
+
77
+ var cmd = COA.Cmd()
78
+ .opt()
79
+ .name('a')
80
+ .short('a')
81
+ .arr()
82
+ .end()
83
+ .act(function(opts) {
84
+ return opts;
85
+ });
86
+
87
+ it('should return array of passed values', function() {
88
+ return cmd.do(['-a', '1', '-a', '2'])
89
+ .then(function(res) {
90
+ assert.deepEqual(res, { a: ['1', '2'] });
91
+ });
92
+ });
93
+
94
+ });
95
+
96
+ describe('Required option', function() {
97
+
98
+ var cmd = COA.Cmd()
99
+ .opt()
100
+ .name('a')
101
+ .short('a')
102
+ .req()
103
+ .end()
104
+ .act(function(opts) {
105
+ return opts;
106
+ });
107
+
108
+ it('should fail if not specified', function() {
109
+ return cmd.do()
110
+ .then(assert.fail, emptyFn);
111
+ });
112
+
113
+ it('should return passed value if specified', function() {
114
+ return cmd.do(['-a', 'test'])
115
+ .then(function(opts) {
116
+ assert.equal(opts.a, 'test');
117
+ });
118
+ });
119
+
120
+ });
121
+
122
+ describe('Option with default value', function() {
123
+
124
+ var cmd = COA.Cmd()
125
+ .opt()
126
+ .name('a')
127
+ .short('a')
128
+ .def('aaa')
129
+ .end()
130
+ .act(function(opts) {
131
+ return opts;
132
+ });
133
+
134
+ it('should return default value if not specified', function() {
135
+ return cmd.do()
136
+ .then(function(opts) {
137
+ assert.equal(opts.a, 'aaa');
138
+ });
139
+ });
140
+
141
+ it('should return passed value if specified', function() {
142
+ return cmd.do(['-a', 'test'])
143
+ .then(function(opts) {
144
+ assert.equal(opts.a, 'test');
145
+ });
146
+ });
147
+
148
+ });
149
+
150
+ describe('Validated / transformed option', function() {
151
+
152
+ var cmd = COA.Cmd()
153
+ .opt()
154
+ .name('a')
155
+ .short('a')
156
+ .val(function(v) {
157
+ if (v === 'invalid') return this.reject('fail');
158
+ return { value: v };
159
+ })
160
+ .end()
161
+ .act(function(opts) {
162
+ return opts;
163
+ });
164
+
165
+ it('should fail if custom checks suppose to do so', function() {
166
+ return cmd.do(['-a', 'invalid'])
167
+ .then(assert.fail, emptyFn);
168
+ });
169
+
170
+ it('should return transformed value', function() {
171
+ return cmd.do(['-a', 'test'])
172
+ .then(function(opts) {
173
+ assert.deepEqual(opts.a, { value: 'test' });
174
+ });
175
+ });
176
+
177
+ });
178
+
179
+ describe('Only option (--version case)', function() {
180
+
181
+ var ver = require('../package.json').version,
182
+ cmd = COA.Cmd()
183
+ .opt()
184
+ .name('version')
185
+ .long('version')
186
+ .flag()
187
+ .only()
188
+ .act(function() {
189
+ return ver;
190
+ })
191
+ .end()
192
+ .opt()
193
+ .name('req')
194
+ .short('r')
195
+ .req()
196
+ .end();
197
+
198
+ it('should process the only() option', function() {
199
+ return cmd.do(['--version'])
200
+ .then(assert.fail, function(res) {
201
+ assert.equal(res, ver);
202
+ });
203
+ });
204
+
205
+ });
206
+
207
+ it('input()');
208
+ it('output()');
209
+
210
+ });
211
+
212
+ describe('Arg', function() {
213
+
214
+ describe('Unknown arg', function() {
215
+
216
+ var cmd = COA.Cmd();
217
+
218
+ it('should fail', function() {
219
+ return cmd.do(['test'])
220
+ .then(assert.fail, emptyFn);
221
+ });
222
+
223
+ });
224
+
225
+ describe('Unknown arg after known', function() {
226
+
227
+ var cmd = COA.Cmd()
228
+ .arg()
229
+ .name('a')
230
+ .end();
231
+
232
+ it('should fail', function() {
233
+ return cmd.do(['test', 'unknown'])
234
+ .then(assert.fail, emptyFn);
235
+ });
236
+
237
+ });
238
+
239
+ describe('Array arg', function() {
240
+
241
+ var cmd = COA.Cmd()
242
+ .arg()
243
+ .name('a')
244
+ .arr()
245
+ .end()
246
+ .act(function(opts, args) {
247
+ return args;
248
+ });
249
+
250
+ it('should return array of passed values', function() {
251
+ return cmd.do(['value 1', 'value 2'])
252
+ .then(function(args) {
253
+ assert.deepEqual(args, { a: ['value 1', 'value 2'] });
254
+ });
255
+ });
256
+
257
+ });
258
+
259
+ describe('Required arg', function() {
260
+
261
+ var cmd = COA.Cmd()
262
+ .arg()
263
+ .name('a')
264
+ .req()
265
+ .end()
266
+ .act(function(opts, args) {
267
+ return args;
268
+ });
269
+
270
+ it('should fail if not specified', function() {
271
+ return cmd.do()
272
+ .then(assert.fail, emptyFn);
273
+ });
274
+
275
+ it('should return passed value if specified', function() {
276
+ return cmd.do(['value'])
277
+ .then(function(args) {
278
+ assert.equal(args.a, 'value');
279
+ });
280
+ });
281
+
282
+ });
283
+
284
+ describe('Args after options', function() {
285
+
286
+ var cmd = COA.Cmd()
287
+ .opt()
288
+ .name('opt')
289
+ .long('opt')
290
+ .end()
291
+ .arg()
292
+ .name('arg1')
293
+ .end()
294
+ .arg()
295
+ .name('arg2')
296
+ .arr()
297
+ .end()
298
+ .act(function(opts, args) {
299
+ return { opts: opts, args: args };
300
+ });
301
+
302
+ it('should return passed values', function() {
303
+ return cmd.do(['--opt', 'value', 'value', 'value 1', 'value 2'])
304
+ .then(function(o) {
305
+ assert.deepEqual(o, {
306
+ opts: { opt: 'value' },
307
+ args: {
308
+ arg1: 'value',
309
+ arg2: ['value 1', 'value 2']
310
+ }
311
+ });
312
+ });
313
+ });
314
+
315
+ });
316
+
317
+ describe('Raw args', function() {
318
+
319
+ var cmd = COA.Cmd()
320
+ .arg()
321
+ .name('raw')
322
+ .arr()
323
+ .end()
324
+ .act(function(opts, args) {
325
+ return args;
326
+ });
327
+
328
+ it('should return passed arg values', function() {
329
+ return cmd.do(['--', 'raw', 'arg', 'values'])
330
+ .then(function(args) {
331
+ assert.deepEqual(args, { raw: ['raw', 'arg', 'values'] });
332
+ });
333
+ });
334
+
335
+ });
336
+
337
+ });
338
+
339
+ describe('Cmd', function() {
340
+
341
+ var doTest = function(o) {
342
+ assert.deepEqual(o, {
343
+ opts: { opt: 'value' },
344
+ args: {
345
+ arg1: 'value',
346
+ arg2: ['value 1', 'value 2']
347
+ }
348
+ });
349
+ },
350
+
351
+ invokeOpts = { opt: 'value' },
352
+ invokeArgs = {
353
+ arg1: 'value',
354
+ arg2: ['value 1', 'value 2']
355
+ };
356
+
357
+ describe('Subcommand', function() {
358
+
359
+ var cmd = COA.Cmd()
360
+ .cmd()
361
+ .name('command')
362
+ .opt()
363
+ .name('opt')
364
+ .long('opt')
365
+ .end()
366
+ .arg()
367
+ .name('arg1')
368
+ .end()
369
+ .arg()
370
+ .name('arg2')
371
+ .arr()
372
+ .end()
373
+ .act(function(opts, args) {
374
+ return { opts: opts, args: args };
375
+ })
376
+ .end();
377
+
378
+ describe('when specified on command line', function() {
379
+
380
+ it('should be invoked and accept passed opts and args', function() {
381
+ return cmd.do(['command', '--opt', 'value', 'value', 'value 1', 'value 2'])
382
+ .then(doTest);
383
+ });
384
+
385
+ });
386
+
387
+ describe('when invoked using api', function() {
388
+
389
+ it('should be invoked and accept passed opts and args', function() {
390
+ return cmd.api.command(invokeOpts, invokeArgs)
391
+ .then(doTest);
392
+ });
393
+
394
+ });
395
+
396
+ describe('when invoked using invoke()', function() {
397
+
398
+ it('should be invoked and accept passed opts and args', function() {
399
+ return cmd.invoke('command', invokeOpts, invokeArgs)
400
+ .then(doTest);
401
+ });
402
+
403
+ });
404
+
405
+ describe('when unexisting command invoked using invoke()', function() {
406
+
407
+ it('should fail', function() {
408
+ return cmd.invoke('unexistent')
409
+ .then(assert.fail, emptyFn);
410
+ });
411
+
412
+ });
413
+
414
+ });
415
+
416
+ describe('External subcommand', function() {
417
+
418
+ describe('default scheme: cmd.extendable()', function() {
419
+
420
+ describe('when described as a function', function() {
421
+ var cmd = COA.Cmd()
422
+ .name('coa')
423
+ .extendable();
424
+
425
+ it('should be invoked and accept passed opts and args', function() {
426
+ return cmd.do(['test', '--opt', 'value', 'value', 'value 1', 'value 2'])
427
+ .then(doTest);
428
+ });
429
+ });
430
+
431
+ describe('when described as an COA.Cmd() object', function() {
432
+ var cmd = COA.Cmd()
433
+ .name('coa')
434
+ .extendable();
435
+
436
+ it('should be invoked and accept passed opts and args', function() {
437
+ return cmd.do(['test-obj', '--opt', 'value', 'value', 'value 1', 'value 2'])
438
+ .then(doTest);
439
+ });
440
+ });
441
+
442
+ describe('2nd level subcommand', function() {
443
+ var cmd = COA.Cmd()
444
+ .name('coa')
445
+ .cmd()
446
+ .name('test')
447
+ .extendable()
448
+ .end();
449
+
450
+ it('should be invoked and accept passed opts and args', function() {
451
+ return cmd.do(['test', 'obj', '--opt', 'value', 'value', 'value 1', 'value 2'])
452
+ .then(doTest);
453
+ });
454
+ });
455
+
456
+ });
457
+
458
+ describe("common prefix: cmd.extendable('coa-')", function() {
459
+
460
+ describe('when described as a function', function() {
461
+ var cmd = COA.Cmd()
462
+ .name('coa')
463
+ .extendable('coa-');
464
+
465
+ it('should be invoked and accept passed opts and args', function() {
466
+ return cmd.do(['test', '--opt', 'value', 'value', 'value 1', 'value 2'])
467
+ .then(doTest);
468
+ });
469
+ });
470
+
471
+ });
472
+
473
+ describe("format string: cmd.extendable('coa-%s')", function() {
474
+
475
+ describe('when described as a function', function() {
476
+ var cmd = COA.Cmd()
477
+ .name('coa')
478
+ .extendable('coa-%s');
479
+
480
+ it('should be invoked and accept passed opts and args', function() {
481
+ return cmd.do(['test', '--opt', 'value', 'value', 'value 1', 'value 2'])
482
+ .then(doTest);
483
+ });
484
+ });
485
+
486
+ });
487
+
488
+ });
489
+
490
+ it('helpful(), name(), title()');
491
+
492
+ });
493
+
494
+ function emptyFn() {
495
+ // empty function
496
+ }
@@ -0,0 +1,2 @@
1
+ --reporter spec
2
+ --timeout 20
@@ -0,0 +1,60 @@
1
+ var assert = require('chai').assert,
2
+ shell = require('..').shell;
3
+
4
+ /**
5
+ * Mocha BDD interface.
6
+ */
7
+ /** @name describe @function */
8
+ /** @name it @function */
9
+ /** @name before @function */
10
+ /** @name after @function */
11
+ /** @name beforeEach @function */
12
+ /** @name afterEach @function */
13
+
14
+ describe('shell', function() {
15
+
16
+ describe('escape()', function() {
17
+
18
+ var escape = shell.escape;
19
+
20
+ it('Should wrap values with spaces in double quotes', function() {
21
+ assert.equal(escape('asd abc'), '"asd abc"');
22
+ });
23
+
24
+ it('Should escape double quote "', function() {
25
+ assert.equal(escape('"asd'), '\\"asd');
26
+ });
27
+
28
+ it("Should escape single quote '", function() {
29
+ assert.equal(escape("'asd"), "\\'asd");
30
+ });
31
+
32
+ it('Should escape backslash \\', function() {
33
+ assert.equal(escape('\\asd'), '\\\\asd');
34
+ });
35
+
36
+ it('Should escape dollar $', function() {
37
+ assert.equal(escape('$asd'), '\\$asd');
38
+ });
39
+
40
+ it('Should escape backtick `', function() {
41
+ assert.equal(escape('`asd'), '\\`asd');
42
+ });
43
+
44
+ });
45
+
46
+ describe('unescape()', function() {
47
+
48
+ var unescape = shell.unescape;
49
+
50
+ it('Should strip double quotes at the both ends', function() {
51
+ assert.equal(unescape('"asd"'), 'asd');
52
+ });
53
+
54
+ it('Should not strip escaped double quotes at the both ends', function() {
55
+ assert.equal(unescape('\\"asd\\"'), '"asd"');
56
+ });
57
+
58
+ });
59
+
60
+ });
package/tests/api-h.js ADDED
@@ -0,0 +1,9 @@
1
+ require('..').Cmd()
2
+ .name('bla')
3
+ .title('Bla bla bla')
4
+ .helpful()
5
+ .invoke({ help: true })
6
+ .then(function(res) {
7
+ console.log(res);
8
+ })
9
+ .done(); // Q.done()
package/tests/h.js ADDED
@@ -0,0 +1,6 @@
1
+ var argv = process.argv.slice(2);
2
+ require('..').Cmd()
3
+ .name('bla')
4
+ .title('Bla bla bla')
5
+ .helpful()
6
+ .run(argv.length? argv : ['-h']);
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2015-present Sergey Berezhnoy <veged@ya.ru>
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
package/lib/coaobject.js DELETED
@@ -1,100 +0,0 @@
1
- 'use strict';
2
-
3
- const Q = require('q');
4
-
5
- /**
6
- * COA Object
7
- *
8
- * Base class for all COA-related objects
9
- *
10
- * --------|-----|-----|-----
11
- * | Cmd | Opt | Arg
12
- * --------|-----|-----|-----
13
- * name | ✓ | ✓ | ✓
14
- * title | ✓ | ✓ | ✓
15
- * comp | ✓ | ✓ | ✓
16
- * reject | ✓ | ✓ | ✓
17
- * end | ✓ | ✓ | ✓
18
- * apply | ✓ | ✓ | ✓
19
- *
20
- * @class CoaObject
21
- */
22
- module.exports = class CoaObject {
23
- constructor(cmd) {
24
- this._cmd = cmd;
25
- this._name = null;
26
- this._title = null;
27
- this._comp = null;
28
- }
29
-
30
- /**
31
- * Set a canonical identifier to be used anywhere in the API.
32
- *
33
- * @param {String} name - command, option or argument name
34
- * @returns {COA.CoaObject} - this instance (for chainability)
35
- */
36
- name(name) {
37
- this._name = name;
38
- return this;
39
- }
40
-
41
- /**
42
- * Set a long description to be used anywhere in text messages.
43
- * @param {String} title - human readable entity title
44
- * @returns {COA.CoaObject} - this instance (for chainability)
45
- */
46
- title(title) {
47
- this._title = title;
48
- return this;
49
- }
50
-
51
- /**
52
- * Set custom additional completion for current object.
53
- *
54
- * @param {Function} comp - completion generation function,
55
- * invoked in the context of object instance.
56
- * Accepts parameters:
57
- * - {Object} opts - completion options
58
- * It can return promise or any other value threated as a result.
59
- * @returns {COA.CoaObject} - this instance (for chainability)
60
- */
61
- comp(comp) {
62
- this._comp = comp;
63
- return this;
64
- }
65
-
66
- /**
67
- * Apply function with arguments in a context of object instance.
68
- *
69
- * @param {Function} fn - body
70
- * @param {Array.<*>} args... - arguments
71
- * @returns {COA.CoaObject} - this instance (for chainability)
72
- */
73
- apply(fn) {
74
- arguments.length > 1?
75
- fn.apply(this, [].slice.call(arguments, 1))
76
- : fn.call(this);
77
-
78
- return this;
79
- }
80
-
81
- /**
82
- * Return reject of actions results promise with error code.
83
- * Use in .act() for return with error.
84
- * @param {Object} reason - reject reason
85
- * You can customize toString() method and exitCode property
86
- * of reason object.
87
- * @returns {Q.promise} rejected promise
88
- */
89
- reject(reason) {
90
- return Q.reject(reason);
91
- }
92
-
93
- /**
94
- * Finish chain for current subcommand and return parent command instance.
95
- * @returns {COA.Cmd} parent command
96
- */
97
- end() {
98
- return this._cmd;
99
- }
100
- };