command_mapper-gen 0.1.0.pre1

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.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ruby.yml +27 -0
  3. data/.gitignore +10 -0
  4. data/.rspec +1 -0
  5. data/.yardopts +1 -0
  6. data/ChangeLog.md +20 -0
  7. data/Gemfile +17 -0
  8. data/LICENSE.txt +20 -0
  9. data/README.md +145 -0
  10. data/Rakefile +15 -0
  11. data/bin/command_mapper-gen +7 -0
  12. data/commnad_mapper-gen.gemspec +61 -0
  13. data/examples/grep.rb +63 -0
  14. data/gemspec.yml +26 -0
  15. data/lib/command_mapper/gen/arg.rb +43 -0
  16. data/lib/command_mapper/gen/argument.rb +53 -0
  17. data/lib/command_mapper/gen/cli.rb +233 -0
  18. data/lib/command_mapper/gen/command.rb +202 -0
  19. data/lib/command_mapper/gen/exceptions.rb +9 -0
  20. data/lib/command_mapper/gen/option.rb +66 -0
  21. data/lib/command_mapper/gen/option_value.rb +23 -0
  22. data/lib/command_mapper/gen/parsers/common.rb +49 -0
  23. data/lib/command_mapper/gen/parsers/help.rb +351 -0
  24. data/lib/command_mapper/gen/parsers/man.rb +80 -0
  25. data/lib/command_mapper/gen/parsers/options.rb +127 -0
  26. data/lib/command_mapper/gen/parsers/usage.rb +141 -0
  27. data/lib/command_mapper/gen/parsers.rb +2 -0
  28. data/lib/command_mapper/gen/task.rb +90 -0
  29. data/lib/command_mapper/gen/types/enum.rb +30 -0
  30. data/lib/command_mapper/gen/types/key_value.rb +34 -0
  31. data/lib/command_mapper/gen/types/list.rb +34 -0
  32. data/lib/command_mapper/gen/types/map.rb +36 -0
  33. data/lib/command_mapper/gen/types/num.rb +18 -0
  34. data/lib/command_mapper/gen/types/str.rb +48 -0
  35. data/lib/command_mapper/gen/types.rb +6 -0
  36. data/lib/command_mapper/gen/version.rb +6 -0
  37. data/lib/command_mapper/gen.rb +2 -0
  38. data/spec/argument_spec.rb +92 -0
  39. data/spec/cli_spec.rb +269 -0
  40. data/spec/command_spec.rb +316 -0
  41. data/spec/option_spec.rb +85 -0
  42. data/spec/option_value_spec.rb +20 -0
  43. data/spec/parsers/common_spec.rb +616 -0
  44. data/spec/parsers/help_spec.rb +612 -0
  45. data/spec/parsers/man_spec.rb +158 -0
  46. data/spec/parsers/options_spec.rb +802 -0
  47. data/spec/parsers/usage_spec.rb +1175 -0
  48. data/spec/spec_helper.rb +6 -0
  49. data/spec/task_spec.rb +69 -0
  50. data/spec/types/enum_spec.rb +45 -0
  51. data/spec/types/key_value_spec.rb +36 -0
  52. data/spec/types/list_spec.rb +36 -0
  53. data/spec/types/map_spec.rb +48 -0
  54. data/spec/types/str_spec.rb +70 -0
  55. metadata +133 -0
@@ -0,0 +1,1175 @@
1
+ require 'spec_helper'
2
+ require 'command_mapper/gen/parsers/usage'
3
+
4
+ describe CommandMapper::Gen::Parsers::Usage do
5
+ describe "#capitalized_word" do
6
+ subject { super().capitalized_word }
7
+
8
+ context "when given a single lowercase character" do
9
+ let(:string) { 'a' }
10
+
11
+ it "must not parse it" do
12
+ expect { subject.parse(string) }.to raise_error(Parslet::ParseFailed)
13
+ end
14
+ end
15
+
16
+ context "when given a '_' character" do
17
+ let(:string) { '_' }
18
+
19
+ it "must not parse it" do
20
+ expect { subject.parse(string) }.to raise_error(Parslet::ParseFailed)
21
+ end
22
+ end
23
+
24
+ context "when given one uppercase character" do
25
+ let(:string) { 'A' }
26
+
27
+ it "must not parse it" do
28
+ expect { subject.parse(string) }.to raise_error(Parslet::ParseFailed)
29
+ end
30
+ end
31
+
32
+ context "when given one uppercase character and a lowercase character" do
33
+ let(:string) { 'Ab' }
34
+
35
+ it "must parse it" do
36
+ expect(subject.parse(string)).to eq(string)
37
+ end
38
+ end
39
+
40
+ context "when given one uppercase character followed by multiple lowercase characters" do
41
+ let(:string) { 'Abbbb' }
42
+
43
+ it "must parse it" do
44
+ expect(subject.parse(string)).to eq(string)
45
+ end
46
+
47
+ context "and it contains a '_' character" do
48
+ let(:string) { 'Abb_bb' }
49
+
50
+ it "must not parse it" do
51
+ expect { subject.parse(string) }.to raise_error(Parslet::ParseFailed)
52
+ end
53
+ end
54
+
55
+ context "and it contains a '-' character" do
56
+ let(:string) { 'Abb-bb' }
57
+
58
+ it "must not parse it" do
59
+ expect { subject.parse(string) }.to raise_error(Parslet::ParseFailed)
60
+ end
61
+ end
62
+ end
63
+
64
+ context "when given two uppercase characters" do
65
+ let(:string) { 'AB' }
66
+
67
+ it "must not parse it" do
68
+ expect { subject.parse(string) }.to raise_error(Parslet::ParseFailed)
69
+ end
70
+ end
71
+ end
72
+
73
+ describe "#lowercase_word" do
74
+ subject { super().lowercase_word }
75
+
76
+ context "when given a '_' character" do
77
+ let(:string) { '_' }
78
+
79
+ it "must not parse it" do
80
+ expect { subject.parse(string) }.to raise_error(Parslet::ParseFailed)
81
+ end
82
+ end
83
+
84
+ context "when given one lowercase character" do
85
+ let(:string) { 'a' }
86
+
87
+ it "must parse it" do
88
+ expect(subject.parse(string)).to eq(string)
89
+ end
90
+ end
91
+
92
+ context "when given multiple lowercase characters" do
93
+ let(:string) { 'ab' }
94
+
95
+ it "must parse it" do
96
+ expect(subject.parse(string)).to eq(string)
97
+ end
98
+
99
+ context "and it contains a '_' character" do
100
+ let(:string) { 'abb_bb' }
101
+
102
+ it "must not parse it" do
103
+ expect { subject.parse(string) }.to raise_error(Parslet::ParseFailed)
104
+ end
105
+ end
106
+
107
+ context "and it contains a '-' character" do
108
+ let(:string) { 'Abb-bb' }
109
+
110
+ it "must not parse it" do
111
+ expect { subject.parse(string) }.to raise_error(Parslet::ParseFailed)
112
+ end
113
+ end
114
+ end
115
+
116
+ context "when given a single uppercase characters" do
117
+ let(:string) { 'A' }
118
+
119
+ it "must not parse it" do
120
+ expect { subject.parse(string) }.to raise_error(Parslet::ParseFailed)
121
+ end
122
+ end
123
+
124
+ context "when it contains a uppercase character" do
125
+ let(:string) { 'aaaaBaaaa' }
126
+
127
+ it "must not parse it" do
128
+ expect { subject.parse(string) }.to raise_error(Parslet::ParseFailed)
129
+ end
130
+ end
131
+ end
132
+
133
+ describe "#word" do
134
+ subject { super().word }
135
+
136
+ context "when given a lowercase word" do
137
+ let(:string) { "foo" }
138
+
139
+ it "must parse it" do
140
+ expect(subject.parse(string)).to eq(string)
141
+ end
142
+ end
143
+
144
+ context "when given a capitalized word" do
145
+ let(:string) { "Foo" }
146
+
147
+ it "must parse it" do
148
+ expect(subject.parse(string)).to eq(string)
149
+ end
150
+ end
151
+ end
152
+
153
+ describe "#words" do
154
+ subject { super().words }
155
+
156
+ context "when given one word" do
157
+ let(:word) { "foo" }
158
+ let(:string) { word }
159
+
160
+ it "must not parse it" do
161
+ expect { subject.parse(string) }.to raise_error(Parslet::ParseFailed)
162
+ end
163
+ end
164
+
165
+ context "when given two words" do
166
+ let(:words) { "foo bar" }
167
+ let(:string) { words }
168
+
169
+ it "must capture the word" do
170
+ expect(subject.parse(string)).to eq({words: words})
171
+ end
172
+ end
173
+
174
+ context "when given more than two words separated by a space" do
175
+ let(:words) { "foo Bar baz" }
176
+ let(:string) { words }
177
+
178
+ it "must capture the multiple words" do
179
+ expect(subject.parse(string)).to eq({words: words})
180
+ end
181
+ end
182
+
183
+ context "when the words end with '...'" do
184
+ let(:words) { "foo bar baz" }
185
+ let(:string) { "#{words} ..." }
186
+
187
+ it "must capture the words and the ellipsis" do
188
+ expect(subject.parse(string)).to eq({words: words, repeats: "..."})
189
+ end
190
+ end
191
+ end
192
+
193
+ describe "#argument_name" do
194
+ subject { super().argument_name }
195
+
196
+ context "when given a lowercase name" do
197
+ let(:name) { "foo" }
198
+ let(:string) { name }
199
+
200
+ it "must capture the name" do
201
+ expect(subject.parse(string)).to eq(
202
+ {
203
+ argument: {name: name}
204
+ }
205
+ )
206
+ end
207
+
208
+ context "and the string ends with a '...'" do
209
+ let(:string) { "#{name} ..." }
210
+
211
+ it "must capture the name and the ellipsis" do
212
+ expect(subject.parse(string)).to eq(
213
+ {
214
+ argument: {
215
+ name: name,
216
+ repeats: "..."
217
+ }
218
+ }
219
+ )
220
+ end
221
+ end
222
+ end
223
+
224
+ context "when given an uppercase name" do
225
+ let(:name) { "FOO" }
226
+ let(:string) { name }
227
+
228
+ it "must capture the name" do
229
+ expect(subject.parse(string)).to eq(
230
+ {
231
+ argument: {name: name}
232
+ }
233
+ )
234
+ end
235
+
236
+ context "and the string ends with a '...'" do
237
+ let(:string) { "#{name} ..." }
238
+
239
+ it "must capture the name and the ellipsis" do
240
+ expect(subject.parse(string)).to eq(
241
+ {
242
+ argument: {
243
+ name: name,
244
+ repeats: "..."
245
+ }
246
+ }
247
+ )
248
+ end
249
+ end
250
+ end
251
+ end
252
+
253
+ describe "#short_flags" do
254
+ subject { super().short_flags }
255
+
256
+ context "when given a short flag (ex: '-o')" do
257
+ let(:short_flag) { "-o" }
258
+ let(:string) { short_flag }
259
+
260
+ it "must not parse it" do
261
+ expect { subject.parse(string) }.to raise_error(Parslet::ParseFailed)
262
+ end
263
+ end
264
+
265
+ context "when given an amalgamation of short flags (ex: '-xyz')" do
266
+ let(:short_flags) { "-xyz" }
267
+ let(:string) { short_flags }
268
+
269
+ it "must capture the short flags" do
270
+ expect(subject.parse(string)).to eq({short_flags: short_flags})
271
+ end
272
+ end
273
+ end
274
+
275
+ describe "#flag" do
276
+ subject { super().flag }
277
+
278
+ context "when given a long flag (ex: '--opt')" do
279
+ let(:long_flag) { "--opt" }
280
+ let(:string) { long_flag }
281
+
282
+ it "must capture the long flag" do
283
+ expect(subject.parse(string)).to eq({long_flag: long_flag})
284
+ end
285
+ end
286
+
287
+ context "when given a short flag (ex: '-o')" do
288
+ let(:short_flag) { "-o" }
289
+ let(:string) { short_flag }
290
+
291
+ it "must capture the short flag" do
292
+ expect(subject.parse(string)).to eq({short_flag: short_flag})
293
+ end
294
+ end
295
+
296
+ context "when given an amalgamation of short flags (ex: '-xyz')" do
297
+ let(:short_flags) { "-xyz" }
298
+ let(:string) { short_flags }
299
+
300
+ it "must capture the short flags" do
301
+ expect(subject.parse(string)).to eq({short_flags: short_flags})
302
+ end
303
+ end
304
+ end
305
+
306
+ describe "#option_value_string" do
307
+ subject { super().option_value_string }
308
+
309
+ context "when given an empty string" do
310
+ let(:string) { "" }
311
+
312
+ it "must not parse it" do
313
+ expect { subject.parse(string) }.to raise_error(Parslet::ParseFailed)
314
+ end
315
+ end
316
+
317
+ context "when given one lowercase character" do
318
+ let(:string) { 'a' }
319
+
320
+ it "must capture the string" do
321
+ expect(subject.parse(string)).to eq({string: string})
322
+ end
323
+ end
324
+
325
+ context "when given multiple lowercase characters" do
326
+ let(:string) { 'ab' }
327
+
328
+ it "must capture the string" do
329
+ expect(subject.parse(string)).to eq({string: string})
330
+ end
331
+
332
+ context "and it contains a '_' character" do
333
+ let(:string) { 'a_b' }
334
+
335
+ it "must capture the string" do
336
+ expect(subject.parse(string)).to eq({string: string})
337
+ end
338
+ end
339
+
340
+ context "and it contains a '-' character" do
341
+ let(:string) { 'a-b' }
342
+
343
+ it "must capture the string" do
344
+ expect(subject.parse(string)).to eq({string: string})
345
+ end
346
+ end
347
+
348
+ context "and when it contains an uppercase character" do
349
+ let(:string) { 'aB' }
350
+
351
+ it "must capture the string" do
352
+ expect { subject.parse(string) }.to raise_error(Parslet::ParseFailed)
353
+ end
354
+ end
355
+ end
356
+ end
357
+
358
+ describe "#option_value_strings" do
359
+ subject { super().option_value_strings }
360
+
361
+ context "when given a single value string" do
362
+ let(:string) { "foo" }
363
+
364
+ it "must not parse it" do
365
+ expect { subject.parse(string) }.to raise_error(Parslet::ParseFailed)
366
+ end
367
+ end
368
+
369
+ let(:value_string1) { "foo" }
370
+ let(:value_string2) { "bar" }
371
+
372
+ context "when given two value strings" do
373
+ context "and it's separated by a ','" do
374
+ let(:string) { "#{value_string1},#{value_string2}" }
375
+
376
+ it "must capture the strings" do
377
+ expect(subject.parse(string)).to eq(
378
+ [
379
+ {string: value_string1},
380
+ {string: value_string2}
381
+ ]
382
+ )
383
+ end
384
+ end
385
+
386
+ context "and it's separated by a '|'" do
387
+ let(:string) { "#{value_string1}|#{value_string2}" }
388
+
389
+ it "must capture the strings" do
390
+ expect(subject.parse(string)).to eq(
391
+ [
392
+ {string: value_string1},
393
+ {string: value_string2}
394
+ ]
395
+ )
396
+ end
397
+ end
398
+ end
399
+
400
+ context "when given more than two value strings" do
401
+ let(:value_string3) { "baz" }
402
+
403
+ context "and it's separated by a ','" do
404
+ let(:string) { "#{value_string1},#{value_string2},#{value_string3}" }
405
+
406
+ it "must capture the strings" do
407
+ expect(subject.parse(string)).to eq(
408
+ [
409
+ {string: value_string1},
410
+ {string: value_string2},
411
+ {string: value_string3}
412
+ ]
413
+ )
414
+ end
415
+ end
416
+
417
+ context "and it's separated by a '|'" do
418
+ let(:string) { "#{value_string1}|#{value_string2}|#{value_string3}" }
419
+
420
+ it "must capture the strings" do
421
+ expect(subject.parse(string)).to eq(
422
+ [
423
+ {string: value_string1},
424
+ {string: value_string2},
425
+ {string: value_string3}
426
+ ]
427
+ )
428
+ end
429
+ end
430
+
431
+ context "but it's separated by a combination of ',' and '|'" do
432
+ let(:string) { "#{value_string1},#{value_string2}|#{value_string3}" }
433
+
434
+ it "must capture the strings" do
435
+ expect { subject.parse(string) }.to raise_error(Parslet::ParseFailed)
436
+ end
437
+ end
438
+ end
439
+ end
440
+
441
+ describe "#option_value_name" do
442
+ subject { super().option_value_name }
443
+
444
+ context "when given a lowercase name" do
445
+ let(:string) { 'foo' }
446
+
447
+ it "must capture it" do
448
+ expect(subject.parse(string)).to eq({name: string})
449
+ end
450
+ end
451
+
452
+ context "when given a capitalized name" do
453
+ let(:string) { 'Foo' }
454
+
455
+ it "must capture it" do
456
+ expect(subject.parse(string)).to eq({name: string})
457
+ end
458
+ end
459
+
460
+ context "when given a camelCase name" do
461
+ let(:string) { 'fooBar' }
462
+
463
+ it "must capture it" do
464
+ expect(subject.parse(string)).to eq({name: string})
465
+ end
466
+ end
467
+ end
468
+
469
+ describe "#option_value" do
470
+ subject { super().option_value }
471
+
472
+ context "when given multiple option value strings" do
473
+ let(:value_string1) { "foo" }
474
+ let(:value_string2) { "bar" }
475
+ let(:value_string3) { "baz" }
476
+
477
+ let(:string) { "#{value_string1},#{value_string2},#{value_string3}" }
478
+
479
+ it "must capture the option value strings" do
480
+ expect(subject.parse(string)).to eq(
481
+ [
482
+ {string: value_string1},
483
+ {string: value_string2},
484
+ {string: value_string3}
485
+ ]
486
+ )
487
+ end
488
+ end
489
+
490
+ context "when given a single option value name" do
491
+ let(:name) { "foo" }
492
+ let(:string) { name }
493
+
494
+ it "must capture the option value name" do
495
+ expect(subject.parse(string)).to eq({name: name})
496
+ end
497
+ end
498
+ end
499
+
500
+ describe "#optional_option_value" do
501
+ subject { super().optional_option_value }
502
+
503
+ context "and the contents is an option value name" do
504
+ let(:option_value_name) { "Foo" }
505
+ let(:string) { "[#{option_value_name}]" }
506
+
507
+ it "must parse the contents and mark it as optional" do
508
+ expect(subject.parse(string)).to eq(
509
+ {
510
+ optional: {
511
+ name: option_value_name
512
+ }
513
+ }
514
+ )
515
+ end
516
+ end
517
+
518
+ context "and the contents is an option value strings" do
519
+ let(:value_string1) { "foo" }
520
+ let(:value_string2) { "bar" }
521
+ let(:value_string3) { "baz" }
522
+
523
+ let(:option_value_strings) do
524
+ "#{value_string1},#{value_string2},#{value_string3}"
525
+ end
526
+
527
+ let(:string) { "[#{option_value_strings}]" }
528
+
529
+ it "must parse the contents and mark it as optional" do
530
+ expect(subject.parse(string)).to eq(
531
+ {
532
+ optional: [
533
+ {string: value_string1},
534
+ {string: value_string2},
535
+ {string: value_string3}
536
+ ]
537
+ }
538
+ )
539
+ end
540
+ end
541
+ end
542
+
543
+ describe "#option_value_container" do
544
+ subject { super().option_value_container }
545
+
546
+ let(:value_string1) { "foo" }
547
+ let(:value_string2) { "bar" }
548
+ let(:value_string3) { "baz" }
549
+
550
+ let(:option_value_strings) do
551
+ "#{value_string1},#{value_string2},#{value_string3}"
552
+ end
553
+
554
+ let(:option_value_name) { "Foo" }
555
+
556
+ context "when given a '{...}' string" do
557
+ context "and the contents is an option value name" do
558
+ let(:string) { "{#{option_value_name}}" }
559
+
560
+ it "must parse the contents" do
561
+ expect(subject.parse(string)).to eq({name: option_value_name})
562
+ end
563
+ end
564
+
565
+ context "and the contents is an option value strings" do
566
+ let(:string) { "{#{option_value_strings}}" }
567
+
568
+ it "must parse the contents" do
569
+ expect(subject.parse(string)).to eq(
570
+ [
571
+ {string: value_string1},
572
+ {string: value_string2},
573
+ {string: value_string3}
574
+ ]
575
+ )
576
+ end
577
+ end
578
+ end
579
+
580
+ context "when given a '<...>' string" do
581
+ context "and the contents is an option value name" do
582
+ let(:string) { "<#{option_value_name}>" }
583
+
584
+ it "must parse the contents" do
585
+ expect(subject.parse(string)).to eq({name: option_value_name})
586
+ end
587
+ end
588
+
589
+ context "and the contents is an option value strings" do
590
+ let(:string) { "<#{option_value_strings}>" }
591
+
592
+ it "must parse the contents" do
593
+ expect(subject.parse(string)).to eq(
594
+ [
595
+ {string: value_string1},
596
+ {string: value_string2},
597
+ {string: value_string3}
598
+ ]
599
+ )
600
+ end
601
+ end
602
+ end
603
+
604
+ context "when given a '[...]' string" do
605
+ context "and the contents is an option value name" do
606
+ let(:string) { "[#{option_value_name}]" }
607
+
608
+ it "must parse the contents and mark it as optional" do
609
+ expect(subject.parse(string)).to eq(
610
+ {
611
+ optional: {
612
+ name: option_value_name
613
+ }
614
+ }
615
+ )
616
+ end
617
+ end
618
+
619
+ context "and the contents is an option value strings" do
620
+ let(:string) { "[#{option_value_strings}]" }
621
+
622
+ it "must parse the contents" do
623
+ expect(subject.parse(string)).to eq(
624
+ {
625
+ optional: [
626
+ {string: value_string1},
627
+ {string: value_string2},
628
+ {string: value_string3}
629
+ ]
630
+ }
631
+ )
632
+ end
633
+ end
634
+ end
635
+
636
+ context "when given multiple option value strings" do
637
+ let(:value_string1) { "foo" }
638
+ let(:value_string2) { "bar" }
639
+ let(:value_string3) { "baz" }
640
+
641
+ let(:string) { "#{value_string1},#{value_string2},#{value_string3}" }
642
+
643
+ it "must capture the option value strings" do
644
+ expect(subject.parse(string)).to eq(
645
+ [
646
+ {string: value_string1},
647
+ {string: value_string2},
648
+ {string: value_string3}
649
+ ]
650
+ )
651
+ end
652
+ end
653
+
654
+ context "when given a single option value name" do
655
+ let(:name) { "foo" }
656
+ let(:string) { name }
657
+
658
+ it "must capture the option value name" do
659
+ expect(subject.parse(string)).to eq({name: name})
660
+ end
661
+ end
662
+ end
663
+
664
+ describe "#option" do
665
+ subject { super().option }
666
+
667
+ context "when given an option flag" do
668
+ let(:flag) { "--opt" }
669
+ let(:string) { flag }
670
+
671
+ it "must capture the option flag" do
672
+ expect(subject.parse(string)).to eq(
673
+ {
674
+ option: {long_flag: flag}
675
+ }
676
+ )
677
+ end
678
+
679
+ context "and a value name separated by a space" do
680
+ let(:name) { 'value' }
681
+ let(:string) { "#{flag} #{name}" }
682
+
683
+ it "must capture the option flag and option value name" do
684
+ expect(subject.parse(string)).to eq(
685
+ {
686
+ option: {
687
+ long_flag: flag,
688
+ value: {name: name}
689
+ }
690
+ }
691
+ )
692
+ end
693
+ end
694
+
695
+ context "and a value name separated by a '='" do
696
+ let(:name) { 'value' }
697
+ let(:string) { "#{flag}=#{name}" }
698
+
699
+ it "must capture the option flag, equals, and the option value name" do
700
+ expect(subject.parse(string)).to eq(
701
+ {
702
+ option: {
703
+ long_flag: flag,
704
+ value: {
705
+ equals: '=',
706
+ name: name
707
+ }
708
+ }
709
+ }
710
+ )
711
+ end
712
+
713
+ context "but the '=' and value are wrapped in '[' and ']'" do
714
+ let(:string) { "#{flag}[=#{name}]" }
715
+
716
+ it "must mark the option value name and equals as being optional" do
717
+ expect(subject.parse(string)).to eq(
718
+ {
719
+ option: {
720
+ long_flag: flag,
721
+ value: {
722
+ optional: {
723
+ equals: '=',
724
+ name: name
725
+ }
726
+ }
727
+ }
728
+ }
729
+ )
730
+ end
731
+ end
732
+ end
733
+
734
+ context "and an option value name wrapped in '[' ']'" do
735
+ let(:name) { 'value' }
736
+ let(:string) { "#{flag}[#{name}]" }
737
+
738
+ it "must mark the option value name and equals as being optional" do
739
+ expect(subject.parse(string)).to eq(
740
+ {
741
+ option: {
742
+ long_flag: flag,
743
+ value: {
744
+ optional: {name: name}
745
+ }
746
+ }
747
+ }
748
+ )
749
+ end
750
+ end
751
+ end
752
+ end
753
+
754
+ describe "#angle_brackets_group" do
755
+ subject { super().angle_brackets_group }
756
+
757
+ context "when given a string wrapped in '<' '>'" do
758
+ context "and it contains a list of more than one word" do
759
+ let(:words) { "foo bar baz" }
760
+ let(:string) { "<#{words}>" }
761
+
762
+ it "must capture the words as a single argument" do
763
+ expect(subject.parse(string)).to eq(
764
+ {
765
+ argument: {words: words}
766
+ }
767
+ )
768
+ end
769
+ end
770
+
771
+ context "and it contains more than one argument" do
772
+ let(:arg1) { "FOO" }
773
+ let(:arg2) { "BAR" }
774
+ let(:arg3) { "BAZ" }
775
+ let(:string) { "<#{arg1} #{arg2} #{arg3}>" }
776
+
777
+ it "must capture the arguments" do
778
+ expect(subject.parse(string)).to eq(
779
+ [
780
+ {argument: {name: arg1}},
781
+ {argument: {name: arg2}},
782
+ {argument: {name: arg3}},
783
+ ]
784
+ )
785
+ end
786
+ end
787
+ end
788
+
789
+ context "otherwise" do
790
+ let(:string) { "foo bar" }
791
+
792
+ it "must not parse it" do
793
+ expect { subject.parse(string) }.to raise_error(Parslet::ParseFailed)
794
+ end
795
+ end
796
+ end
797
+
798
+ describe "#curly_braces_group" do
799
+ subject { super().curly_braces_group }
800
+
801
+ context "when given a string wrapped in '{' '}'" do
802
+ context "and it contains a list of more than one word" do
803
+ let(:words) { "foo bar baz" }
804
+ let(:string) { "{#{words}}" }
805
+
806
+ it "must capture the words" do
807
+ expect(subject.parse(string)).to eq(
808
+ {
809
+ argument: {words: words}
810
+ }
811
+ )
812
+ end
813
+ end
814
+
815
+ context "and it contains more than one argument" do
816
+ let(:arg1) { "FOO" }
817
+ let(:arg2) { "BAR" }
818
+ let(:arg3) { "BAZ" }
819
+ let(:string) { "{#{arg1} #{arg2} #{arg3}}" }
820
+
821
+ it "must capture the arguments" do
822
+ expect(subject.parse(string)).to eq(
823
+ [
824
+ {argument: {name: arg1}},
825
+ {argument: {name: arg2}},
826
+ {argument: {name: arg3}},
827
+ ]
828
+ )
829
+ end
830
+ end
831
+ end
832
+
833
+ context "otherwise" do
834
+ let(:string) { "foo bar" }
835
+
836
+ it "must not parse it" do
837
+ expect { subject.parse(string) }.to raise_error(Parslet::ParseFailed)
838
+ end
839
+ end
840
+ end
841
+
842
+ describe "#optional_group" do
843
+ subject { super().optional_group }
844
+
845
+ context "when given a string wrapped in '[' ']'" do
846
+ context "and it contains more than one argument" do
847
+ let(:arg1) { "FOO" }
848
+ let(:arg2) { "BAR" }
849
+ let(:arg3) { "BAZ" }
850
+ let(:string) { "[#{arg1} #{arg2} #{arg3}]" }
851
+
852
+ it "must capture the arguments and mark them as optional" do
853
+ expect(subject.parse(string)).to eq(
854
+ {
855
+ optional: [
856
+ {argument: {name: arg1}},
857
+ {argument: {name: arg2}},
858
+ {argument: {name: arg3}}
859
+ ]
860
+ }
861
+ )
862
+ end
863
+
864
+ context "and ends with a '...'" do
865
+ let(:string) { "[#{arg1} #{arg2} #{arg3}]..." }
866
+
867
+ it "must capture the arguments and mark them as optional" do
868
+ expect(subject.parse(string)).to eq(
869
+ {
870
+ optional: [
871
+ {argument: {name: arg1}},
872
+ {argument: {name: arg2}},
873
+ {argument: {name: arg3}},
874
+ {repeats: '...'}
875
+ ]
876
+ }
877
+ )
878
+ end
879
+ end
880
+ end
881
+ end
882
+
883
+ context "otherwise" do
884
+ let(:string) { "foo bar" }
885
+
886
+ it "must not parse it" do
887
+ expect { subject.parse(string) }.to raise_error(Parslet::ParseFailed)
888
+ end
889
+ end
890
+ end
891
+
892
+ describe "#arg" do
893
+ subject { super().arg }
894
+
895
+ context "when given an --option" do
896
+ let(:flag) { '--opt' }
897
+ let(:string) { flag }
898
+
899
+ it "must capture the option" do
900
+ expect(subject.parse(string)).to eq(
901
+ {
902
+ option: {long_flag: flag}
903
+ }
904
+ )
905
+ end
906
+ end
907
+
908
+ context "when given an ARG name" do
909
+ let(:name) { 'ARG' }
910
+ let(:string) { name }
911
+
912
+ it "must capture the argument name" do
913
+ expect(subject.parse(string)).to eq(
914
+ {
915
+ argument: {name: name}
916
+ }
917
+ )
918
+ end
919
+ end
920
+
921
+ let(:arg1) { "FOO" }
922
+ let(:arg2) { "BAR" }
923
+ let(:arg3) { "BAZ" }
924
+
925
+ context "when given a <...> group of arguments" do
926
+ let(:string) { "<#{arg1} #{arg2} #{arg3}>" }
927
+
928
+ it "must capture the arguments" do
929
+ expect(subject.parse(string)).to eq(
930
+ [
931
+ {argument: {name: arg1}},
932
+ {argument: {name: arg2}},
933
+ {argument: {name: arg3}},
934
+ ]
935
+ )
936
+ end
937
+ end
938
+
939
+ context "when gvien a {...} group of arguments" do
940
+ let(:string) { "{#{arg1} #{arg2} #{arg3}}" }
941
+
942
+ it "must capture the arguments" do
943
+ expect(subject.parse(string)).to eq(
944
+ [
945
+ {argument: {name: arg1}},
946
+ {argument: {name: arg2}},
947
+ {argument: {name: arg3}},
948
+ ]
949
+ )
950
+ end
951
+ end
952
+
953
+ context "when given a [...] group of arguments" do
954
+ let(:string) { "[#{arg1} #{arg2} #{arg3}]" }
955
+
956
+ it "must parse the contents" do
957
+ expect(subject.parse(string)).to eq(
958
+ {
959
+ optional: [
960
+ {argument: {name: arg1}},
961
+ {argument: {name: arg2}},
962
+ {argument: {name: arg3}}
963
+ ]
964
+ }
965
+ )
966
+ end
967
+ end
968
+
969
+ context "when given a single '...'" do
970
+ let(:string) { "..." }
971
+
972
+ it "must parse the '...'" do
973
+ expect(subject.parse(string)).to eq(string)
974
+ end
975
+ end
976
+ end
977
+
978
+ describe "#arg_separator" do
979
+ subject { super().arg_separator }
980
+
981
+ context "when given a ' '" do
982
+ let(:string) { ' ' }
983
+
984
+ it "must parse it" do
985
+ expect(subject.parse(string)).to eq(string)
986
+ end
987
+ end
988
+
989
+ context "when given a ' | '" do
990
+ let(:string) { ' | ' }
991
+
992
+ it "must parse it" do
993
+ expect(subject.parse(string)).to eq(string)
994
+ end
995
+ end
996
+
997
+ context "when given a '|'" do
998
+ let(:string) { '|' }
999
+
1000
+ it "must parse it" do
1001
+ expect(subject.parse(string)).to eq(string)
1002
+ end
1003
+ end
1004
+ end
1005
+
1006
+ describe "#args" do
1007
+ subject { super().args }
1008
+
1009
+ context "when given one argument" do
1010
+ let(:arg) { "ARG" }
1011
+ let(:string) { arg }
1012
+
1013
+ it "must parse the argument" do
1014
+ expect(subject.parse(string)).to eq({argument: {name: arg}})
1015
+ end
1016
+ end
1017
+
1018
+ context "when given multiple arguments separated by a ' '" do
1019
+ let(:arg1) { "ARG1" }
1020
+ let(:arg2) { "ARG2" }
1021
+ let(:arg3) { "ARG3" }
1022
+ let(:string) { "#{arg1} #{arg2} #{arg3}" }
1023
+
1024
+ it "must parse the argument" do
1025
+ expect(subject.parse(string)).to eq(
1026
+ [
1027
+ {argument: {name: arg1}},
1028
+ {argument: {name: arg2}},
1029
+ {argument: {name: arg3}}
1030
+ ]
1031
+ )
1032
+ end
1033
+ end
1034
+
1035
+ context "when given multiple arguments separated by a ' | '" do
1036
+ let(:arg1) { "ARG1" }
1037
+ let(:arg2) { "ARG2" }
1038
+ let(:arg3) { "ARG3" }
1039
+ let(:string) { "#{arg1} | #{arg2} | #{arg3}" }
1040
+
1041
+ it "must parse the argument" do
1042
+ expect(subject.parse(string)).to eq(
1043
+ [
1044
+ {argument: {name: arg1}},
1045
+ {argument: {name: arg2}},
1046
+ {argument: {name: arg3}}
1047
+ ]
1048
+ )
1049
+ end
1050
+ end
1051
+ end
1052
+
1053
+ describe "#command_name" do
1054
+ subject { super().command_name }
1055
+
1056
+ context "when the command name starts with a '_'" do
1057
+ let(:string) { '_foo' }
1058
+
1059
+ it "must not parse it" do
1060
+ expect { subject.parse(string) }.to raise_error(Parslet::ParseFailed)
1061
+ end
1062
+ end
1063
+
1064
+ context "when the command name starts with a '-'" do
1065
+ let(:string) { '-foo' }
1066
+
1067
+ it "must not parse it" do
1068
+ expect { subject.parse(string) }.to raise_error(Parslet::ParseFailed)
1069
+ end
1070
+ end
1071
+
1072
+ context "when the command name starts with a digit" do
1073
+ let(:string) { '0foo' }
1074
+
1075
+ it "must not parse it" do
1076
+ expect { subject.parse(string) }.to raise_error(Parslet::ParseFailed)
1077
+ end
1078
+ end
1079
+
1080
+ context "when the command name starts with a lowercase letter" do
1081
+ let(:string) { 'foo' }
1082
+
1083
+ it "must capture the command name" do
1084
+ expect(subject.parse(string)).to eq(string)
1085
+ end
1086
+ end
1087
+
1088
+ context "when the command name starts with a uppercase letter" do
1089
+ let(:string) { 'Foo' }
1090
+
1091
+ it "must capture the command name" do
1092
+ expect(subject.parse(string)).to eq(string)
1093
+ end
1094
+ end
1095
+
1096
+ context "when the command name contains a '_'" do
1097
+ let(:string) { 'foo_bar' }
1098
+
1099
+ it "must capture the command name" do
1100
+ expect(subject.parse(string)).to eq(string)
1101
+ end
1102
+ end
1103
+
1104
+ context "when the command name contains a '-'" do
1105
+ let(:string) { 'foo-bar' }
1106
+
1107
+ it "must capture the command name" do
1108
+ expect(subject.parse(string)).to eq(string)
1109
+ end
1110
+ end
1111
+ end
1112
+
1113
+ describe "#usage" do
1114
+ subject { super().usage }
1115
+
1116
+ let(:command_name) { "foo" }
1117
+
1118
+ context "when given only a command name" do
1119
+ let(:string) { command_name }
1120
+
1121
+ it "must capture the command name" do
1122
+ expect(subject.parse(string)).to eq({command_name: command_name})
1123
+ end
1124
+ end
1125
+
1126
+ context "when given a command name and a sub-command name" do
1127
+ let(:subcommand_name) { "bar" }
1128
+
1129
+ let(:string) { "#{command_name} #{subcommand_name}" }
1130
+
1131
+ it "must capture both the command name and sub-command name" do
1132
+ expect(subject.parse(string)).to eq(
1133
+ {
1134
+ command_name: command_name,
1135
+ subcommand_name: subcommand_name
1136
+ }
1137
+ )
1138
+ end
1139
+ end
1140
+
1141
+ context "when given a command name and a single argument" do
1142
+ let(:arg1) { "ARG1" }
1143
+ let(:string) { "#{command_name} #{arg1}" }
1144
+
1145
+ it "must capture the command name and argument" do
1146
+ expect(subject.parse(string)).to eq(
1147
+ {
1148
+ command_name: command_name,
1149
+ arguments: {argument: {name: arg1}}
1150
+ }
1151
+ )
1152
+ end
1153
+ end
1154
+
1155
+ context "when given a command name and arguments" do
1156
+ let(:arg1) { "ARG1" }
1157
+ let(:arg2) { "ARG2" }
1158
+ let(:arg3) { "ARG3" }
1159
+ let(:string) { "#{command_name} #{arg1} #{arg2} #{arg3}" }
1160
+
1161
+ it "must capture the command name and arguments" do
1162
+ expect(subject.parse(string)).to eq(
1163
+ {
1164
+ command_name: command_name,
1165
+ arguments: [
1166
+ {argument: {name: arg1}},
1167
+ {argument: {name: arg2}},
1168
+ {argument: {name: arg3}}
1169
+ ]
1170
+ }
1171
+ )
1172
+ end
1173
+ end
1174
+ end
1175
+ end