clamp 1.3.2 → 1.3.3
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.
- checksums.yaml +4 -4
- data/.editorconfig +1 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +12 -8
- data/.travis.yml +2 -1
- data/CHANGES.md +4 -0
- data/CODEOWNERS +1 -0
- data/Gemfile +8 -5
- data/Guardfile +2 -2
- data/Rakefile +1 -3
- data/clamp.gemspec +2 -1
- data/lib/clamp/attribute/declaration.rb +1 -0
- data/lib/clamp/attribute/definition.rb +4 -2
- data/lib/clamp/attribute/instance.rb +2 -1
- data/lib/clamp/help.rb +4 -5
- data/lib/clamp/messages.rb +3 -3
- data/lib/clamp/option/declaration.rb +2 -0
- data/lib/clamp/option/definition.rb +10 -5
- data/lib/clamp/option/parsing.rb +8 -3
- data/lib/clamp/parameter/declaration.rb +3 -0
- data/lib/clamp/parameter/definition.rb +8 -5
- data/lib/clamp/parameter/parsing.rb +4 -6
- data/lib/clamp/subcommand/declaration.rb +3 -1
- data/lib/clamp/subcommand/execution.rb +2 -0
- data/lib/clamp/subcommand/parsing.rb +1 -0
- data/lib/clamp/truthy.rb +1 -1
- data/lib/clamp/version.rb +1 -1
- data/spec/clamp/command_group_spec.rb +64 -45
- data/spec/clamp/{option_module_spec.rb → command_option_module_spec.rb} +2 -1
- data/spec/clamp/{option_reordering_spec.rb → command_option_reordering_spec.rb} +3 -3
- data/spec/clamp/command_spec.rb +364 -148
- data/spec/clamp/{help_spec.rb → help/builder_spec.rb} +22 -4
- data/spec/clamp/messages_spec.rb +11 -6
- data/spec/clamp/option/definition_spec.rb +92 -40
- data/spec/clamp/parameter/definition_spec.rb +120 -50
- data/spec/spec_helper.rb +5 -6
- metadata +14 -21
data/spec/clamp/command_spec.rb
CHANGED
@@ -31,18 +31,35 @@ describe Clamp::Command do
|
|
31
31
|
end
|
32
32
|
|
33
33
|
it "executes the #execute method" do
|
34
|
-
expect(stdout).
|
34
|
+
expect(stdout).not_to be_empty
|
35
35
|
end
|
36
36
|
|
37
37
|
end
|
38
38
|
|
39
39
|
describe ".option" do
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
41
|
+
context "when regular" do
|
42
|
+
|
43
|
+
before do
|
44
|
+
command.class.option "--flavour", "FLAVOUR", "Flavour of the month"
|
45
|
+
end
|
46
|
+
|
47
|
+
context "when not set" do
|
48
|
+
it "equals nil" do
|
49
|
+
expect(command.flavour).to be_nil
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context "when set" do
|
54
|
+
before do
|
55
|
+
command.flavour = "chocolate"
|
56
|
+
end
|
57
|
+
|
58
|
+
it "equals the value" do
|
59
|
+
expect(command.flavour).to eq "chocolate"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
46
63
|
end
|
47
64
|
|
48
65
|
context "with type :flag" do
|
@@ -51,9 +68,20 @@ describe Clamp::Command do
|
|
51
68
|
command.class.option "--verbose", :flag, "Be heartier"
|
52
69
|
end
|
53
70
|
|
54
|
-
|
55
|
-
|
56
|
-
|
71
|
+
describe "predicate-style reader" do
|
72
|
+
|
73
|
+
it "exists" do
|
74
|
+
expect(command).to respond_to(:verbose?)
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "regular reader" do
|
80
|
+
|
81
|
+
it "does not exist" do
|
82
|
+
expect(command).not_to respond_to(:verbose)
|
83
|
+
end
|
84
|
+
|
57
85
|
end
|
58
86
|
|
59
87
|
end
|
@@ -66,12 +94,19 @@ describe Clamp::Command do
|
|
66
94
|
|
67
95
|
it "uses the specified attribute_name name to name accessors" do
|
68
96
|
command.bar = "chocolate"
|
69
|
-
expect(command.bar).to
|
97
|
+
expect(command.bar).to eq "chocolate"
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "default reader" do
|
101
|
+
it "does not exist" do
|
102
|
+
expect(command).not_to respond_to(:foo)
|
103
|
+
end
|
70
104
|
end
|
71
105
|
|
72
|
-
|
73
|
-
|
74
|
-
|
106
|
+
describe "default writer" do
|
107
|
+
it "does not exist" do
|
108
|
+
expect(command).not_to respond_to(:foo=)
|
109
|
+
end
|
75
110
|
end
|
76
111
|
|
77
112
|
end
|
@@ -88,7 +123,7 @@ describe Clamp::Command do
|
|
88
123
|
end
|
89
124
|
|
90
125
|
it "sets the specified default value" do
|
91
|
-
expect(command.port).to
|
126
|
+
expect(command.port).to eq 4321
|
92
127
|
end
|
93
128
|
|
94
129
|
end
|
@@ -100,7 +135,7 @@ describe Clamp::Command do
|
|
100
135
|
end
|
101
136
|
|
102
137
|
it "declares default method" do
|
103
|
-
expect(command.default_port).to
|
138
|
+
expect(command.default_port).to eq 4321
|
104
139
|
end
|
105
140
|
|
106
141
|
describe "#help" do
|
@@ -120,7 +155,7 @@ describe Clamp::Command do
|
|
120
155
|
end
|
121
156
|
|
122
157
|
it "does not declare default method" do
|
123
|
-
expect(command).
|
158
|
+
expect(command).not_to respond_to(:default_port)
|
124
159
|
end
|
125
160
|
|
126
161
|
end
|
@@ -132,24 +167,24 @@ describe Clamp::Command do
|
|
132
167
|
end
|
133
168
|
|
134
169
|
it "defaults to empty array" do
|
135
|
-
expect(command.flavours).to
|
170
|
+
expect(command.flavours).to be_empty
|
136
171
|
end
|
137
172
|
|
138
173
|
it "supports multiple values" do
|
139
174
|
command.parse(%w[--flavour chocolate --flavour vanilla])
|
140
|
-
expect(command.flavours).to
|
175
|
+
expect(command.flavours).to eq %w[chocolate vanilla]
|
141
176
|
end
|
142
177
|
|
143
178
|
it "generates a single-value appender method" do
|
144
179
|
command.append_to_flavours("mud")
|
145
180
|
command.append_to_flavours("pie")
|
146
|
-
expect(command.flavours).to
|
181
|
+
expect(command.flavours).to eq %w[mud pie]
|
147
182
|
end
|
148
183
|
|
149
184
|
it "generates a multi-value setter method" do
|
150
185
|
command.append_to_flavours("replaceme")
|
151
186
|
command.flavours = %w[mud pie]
|
152
|
-
expect(command.flavours).to
|
187
|
+
expect(command.flavours).to eq %w[mud pie]
|
153
188
|
end
|
154
189
|
|
155
190
|
it "does not require a value" do
|
@@ -177,7 +212,7 @@ describe Clamp::Command do
|
|
177
212
|
context "when no environment variable is present" do
|
178
213
|
|
179
214
|
it "uses the default" do
|
180
|
-
expect(command.port).to
|
215
|
+
expect(command.port).to eq 4321
|
181
216
|
end
|
182
217
|
|
183
218
|
end
|
@@ -187,15 +222,15 @@ describe Clamp::Command do
|
|
187
222
|
let(:environment_value) { "12345" }
|
188
223
|
|
189
224
|
it "uses the environment variable" do
|
190
|
-
expect(command.port).to
|
225
|
+
expect(command.port).to eq 12_345
|
191
226
|
end
|
192
227
|
|
193
|
-
context "
|
228
|
+
context "when a value is specified on the command-line" do
|
194
229
|
|
195
230
|
let(:args) { %w[--port 1500] }
|
196
231
|
|
197
232
|
it "uses command-line value" do
|
198
|
-
expect(command.port).to
|
233
|
+
expect(command.port).to eq 1500
|
199
234
|
end
|
200
235
|
|
201
236
|
end
|
@@ -225,7 +260,7 @@ describe Clamp::Command do
|
|
225
260
|
context "when no environment variable is present" do
|
226
261
|
|
227
262
|
it "uses the default" do
|
228
|
-
expect(command.enable?).to
|
263
|
+
expect(command.enable?).to be false
|
229
264
|
end
|
230
265
|
|
231
266
|
end
|
@@ -237,7 +272,7 @@ describe Clamp::Command do
|
|
237
272
|
let(:environment_value) { truthy_value }
|
238
273
|
|
239
274
|
it "sets the flag" do
|
240
|
-
expect(command.enable?).to
|
275
|
+
expect(command.enable?).to be true
|
241
276
|
end
|
242
277
|
|
243
278
|
end
|
@@ -251,7 +286,7 @@ describe Clamp::Command do
|
|
251
286
|
let(:environment_value) { falsey_value }
|
252
287
|
|
253
288
|
it "clears the flag" do
|
254
|
-
expect(command.enable?).to
|
289
|
+
expect(command.enable?).to be false
|
255
290
|
end
|
256
291
|
|
257
292
|
end
|
@@ -332,12 +367,23 @@ describe Clamp::Command do
|
|
332
367
|
end
|
333
368
|
end
|
334
369
|
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
370
|
+
context "when value is incorrect" do
|
371
|
+
|
372
|
+
it "raises an error" do
|
373
|
+
expect do
|
374
|
+
command.port = "blah"
|
375
|
+
end.to raise_error(ArgumentError)
|
376
|
+
end
|
377
|
+
|
378
|
+
end
|
379
|
+
|
380
|
+
context "when value is convertible" do
|
381
|
+
|
382
|
+
it "uses the block to validate and convert the option argument" do
|
383
|
+
command.port = "1234"
|
384
|
+
expect(command.port).to eq 1234
|
385
|
+
end
|
386
|
+
|
341
387
|
end
|
342
388
|
|
343
389
|
end
|
@@ -376,10 +422,22 @@ describe Clamp::Command do
|
|
376
422
|
command.parse(%w[--flavour strawberry --nuts --color blue])
|
377
423
|
end
|
378
424
|
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
425
|
+
describe "flavour" do
|
426
|
+
it "maps the option value onto the command object" do
|
427
|
+
expect(command.flavour).to eq "strawberry"
|
428
|
+
end
|
429
|
+
end
|
430
|
+
|
431
|
+
describe "color" do
|
432
|
+
it "maps the option value onto the command object" do
|
433
|
+
expect(command.color).to eq "blue"
|
434
|
+
end
|
435
|
+
end
|
436
|
+
|
437
|
+
describe "nuts?" do
|
438
|
+
it "maps the option value onto the command object" do
|
439
|
+
expect(command.nuts?).to be true
|
440
|
+
end
|
383
441
|
end
|
384
442
|
|
385
443
|
end
|
@@ -390,9 +448,16 @@ describe Clamp::Command do
|
|
390
448
|
command.parse(%w[-f strawberry -c blue])
|
391
449
|
end
|
392
450
|
|
393
|
-
|
394
|
-
|
395
|
-
|
451
|
+
describe "flavour" do
|
452
|
+
it "recognizes short options as aliases" do
|
453
|
+
expect(command.flavour).to eq "strawberry"
|
454
|
+
end
|
455
|
+
end
|
456
|
+
|
457
|
+
describe "color" do
|
458
|
+
it "recognizes short options as aliases" do
|
459
|
+
expect(command.color).to eq "blue"
|
460
|
+
end
|
396
461
|
end
|
397
462
|
|
398
463
|
end
|
@@ -404,7 +469,7 @@ describe Clamp::Command do
|
|
404
469
|
end
|
405
470
|
|
406
471
|
it "works as though the value were separated" do
|
407
|
-
expect(command.flavour).to
|
472
|
+
expect(command.flavour).to eq "strawberry"
|
408
473
|
end
|
409
474
|
|
410
475
|
end
|
@@ -415,9 +480,16 @@ describe Clamp::Command do
|
|
415
480
|
command.parse(%w[-nf strawberry])
|
416
481
|
end
|
417
482
|
|
418
|
-
|
419
|
-
|
420
|
-
|
483
|
+
describe "flavour" do
|
484
|
+
it "works as though the options were separate" do
|
485
|
+
expect(command.flavour).to eq "strawberry"
|
486
|
+
end
|
487
|
+
end
|
488
|
+
|
489
|
+
describe "nuts?" do
|
490
|
+
it "works as though the options were separate" do
|
491
|
+
expect(command.nuts?).to be true
|
492
|
+
end
|
421
493
|
end
|
422
494
|
|
423
495
|
end
|
@@ -428,9 +500,16 @@ describe Clamp::Command do
|
|
428
500
|
command.parse(%w[--flavour=strawberry --color=blue])
|
429
501
|
end
|
430
502
|
|
431
|
-
|
432
|
-
|
433
|
-
|
503
|
+
describe "flavour" do
|
504
|
+
it "maps the option value onto the command object" do
|
505
|
+
expect(command.flavour).to eq "strawberry"
|
506
|
+
end
|
507
|
+
end
|
508
|
+
|
509
|
+
describe "color" do
|
510
|
+
it "maps the option value onto the command object" do
|
511
|
+
expect(command.color).to eq "blue"
|
512
|
+
end
|
434
513
|
end
|
435
514
|
|
436
515
|
end
|
@@ -441,9 +520,16 @@ describe Clamp::Command do
|
|
441
520
|
command.parse(%w[--flavour=-dashing- --scoops -1])
|
442
521
|
end
|
443
522
|
|
444
|
-
|
445
|
-
|
446
|
-
|
523
|
+
describe "flavour" do
|
524
|
+
it "sets the options" do
|
525
|
+
expect(command.flavour).to eq("-dashing-")
|
526
|
+
end
|
527
|
+
end
|
528
|
+
|
529
|
+
describe "scoops" do
|
530
|
+
it "sets the options" do
|
531
|
+
expect(command.scoops).to eq(-1)
|
532
|
+
end
|
447
533
|
end
|
448
534
|
|
449
535
|
end
|
@@ -452,7 +538,7 @@ describe Clamp::Command do
|
|
452
538
|
|
453
539
|
it "treats them as positional arguments" do
|
454
540
|
command.parse(%w[a b c --flavour strawberry])
|
455
|
-
expect(command.arguments).to
|
541
|
+
expect(command.arguments).to eq %w[a b c --flavour strawberry]
|
456
542
|
end
|
457
543
|
|
458
544
|
end
|
@@ -463,10 +549,22 @@ describe Clamp::Command do
|
|
463
549
|
command.parse(["foo\n--flavour=strawberry", "bar\n-cblue"])
|
464
550
|
end
|
465
551
|
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
552
|
+
describe "arguments" do
|
553
|
+
it "treats them as positional arguments" do
|
554
|
+
expect(command.arguments).to eq ["foo\n--flavour=strawberry", "bar\n-cblue"]
|
555
|
+
end
|
556
|
+
end
|
557
|
+
|
558
|
+
describe "flavour" do
|
559
|
+
it "treats them as positional arguments" do
|
560
|
+
expect(command.flavour).to be_nil
|
561
|
+
end
|
562
|
+
end
|
563
|
+
|
564
|
+
describe "color" do
|
565
|
+
it "treats them as positional arguments" do
|
566
|
+
expect(command.color).to be_nil
|
567
|
+
end
|
470
568
|
end
|
471
569
|
|
472
570
|
end
|
@@ -475,7 +573,7 @@ describe Clamp::Command do
|
|
475
573
|
|
476
574
|
it "considers everything after the terminator to be an argument" do
|
477
575
|
command.parse(%w[--color blue -- --flavour strawberry])
|
478
|
-
expect(command.arguments).to
|
576
|
+
expect(command.arguments).to eq %w[--flavour strawberry]
|
479
577
|
end
|
480
578
|
|
481
579
|
end
|
@@ -525,6 +623,16 @@ describe Clamp::Command do
|
|
525
623
|
|
526
624
|
end
|
527
625
|
|
626
|
+
context "when no option value is provided" do
|
627
|
+
|
628
|
+
it "signals a UsageError" do
|
629
|
+
expect do
|
630
|
+
command.parse(%w[--flavour])
|
631
|
+
end.to raise_error(Clamp::UsageError, /^option '--flavour': no value provided/)
|
632
|
+
end
|
633
|
+
|
634
|
+
end
|
635
|
+
|
528
636
|
context "when a bad option value is specified on the command-line" do
|
529
637
|
|
530
638
|
it "signals a UsageError" do
|
@@ -555,8 +663,10 @@ describe Clamp::Command do
|
|
555
663
|
end
|
556
664
|
|
557
665
|
it "includes option details" do
|
558
|
-
|
559
|
-
|
666
|
+
flavour_help = "-f, --flavour FLAVOUR +Flavour of the month"
|
667
|
+
color_help = "-c, --color COLOR +Preferred hue"
|
668
|
+
|
669
|
+
expect(command.help).to match(/#{flavour_help}\n +#{color_help}/)
|
560
670
|
end
|
561
671
|
|
562
672
|
it "handles new lines in option descriptions" do
|
@@ -573,11 +683,22 @@ describe Clamp::Command do
|
|
573
683
|
command.class.option ["--help"], :flag, "help wanted"
|
574
684
|
end
|
575
685
|
|
576
|
-
|
577
|
-
|
686
|
+
describe "parsing" do
|
687
|
+
it "does not generate implicit help option" do
|
688
|
+
expect do
|
689
|
+
command.parse(%w[--help])
|
690
|
+
end.not_to raise_error
|
691
|
+
end
|
692
|
+
end
|
693
|
+
|
694
|
+
describe "help?" do
|
695
|
+
before do
|
578
696
|
command.parse(%w[--help])
|
579
|
-
end
|
580
|
-
|
697
|
+
end
|
698
|
+
|
699
|
+
it "generates custom help option" do
|
700
|
+
expect(command.help?).to be true
|
701
|
+
end
|
581
702
|
end
|
582
703
|
|
583
704
|
it "does not recognise -h" do
|
@@ -597,10 +718,10 @@ describe Clamp::Command do
|
|
597
718
|
end
|
598
719
|
|
599
720
|
it "does not map -h to help" do
|
600
|
-
expect(command.help).
|
721
|
+
expect(command.help).not_to match(/-h[, ].*help/)
|
601
722
|
end
|
602
723
|
|
603
|
-
it "still
|
724
|
+
it "still recognizes --help" do
|
604
725
|
expect do
|
605
726
|
command.parse(%w[--help])
|
606
727
|
end.to raise_error(Clamp::HelpWanted)
|
@@ -610,11 +731,28 @@ describe Clamp::Command do
|
|
610
731
|
|
611
732
|
describe ".parameter" do
|
612
733
|
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
734
|
+
context "when regular" do
|
735
|
+
|
736
|
+
before do
|
737
|
+
command.class.parameter "FLAVOUR", "flavour of the month"
|
738
|
+
end
|
739
|
+
|
740
|
+
context "when not set" do
|
741
|
+
it "equals nil" do
|
742
|
+
expect(command.flavour).to be_nil
|
743
|
+
end
|
744
|
+
end
|
745
|
+
|
746
|
+
context "when set" do
|
747
|
+
before do
|
748
|
+
command.flavour = "chocolate"
|
749
|
+
end
|
750
|
+
|
751
|
+
it "equals the value" do
|
752
|
+
expect(command.flavour).to eq "chocolate"
|
753
|
+
end
|
754
|
+
end
|
755
|
+
|
618
756
|
end
|
619
757
|
|
620
758
|
context "with explicit :attribute_name" do
|
@@ -625,7 +763,7 @@ describe Clamp::Command do
|
|
625
763
|
|
626
764
|
it "uses the specified attribute_name name to name accessors" do
|
627
765
|
command.bar = "chocolate"
|
628
|
-
expect(command.bar).to
|
766
|
+
expect(command.bar).to eq "chocolate"
|
629
767
|
end
|
630
768
|
|
631
769
|
end
|
@@ -637,7 +775,7 @@ describe Clamp::Command do
|
|
637
775
|
end
|
638
776
|
|
639
777
|
it "sets the specified default value" do
|
640
|
-
expect(command.orientation).to
|
778
|
+
expect(command.orientation).to eq "west"
|
641
779
|
end
|
642
780
|
|
643
781
|
describe "#help" do
|
@@ -658,12 +796,23 @@ describe Clamp::Command do
|
|
658
796
|
end
|
659
797
|
end
|
660
798
|
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
799
|
+
context "when value is incorrect" do
|
800
|
+
|
801
|
+
it "raises an error" do
|
802
|
+
expect do
|
803
|
+
command.port = "blah"
|
804
|
+
end.to raise_error(ArgumentError)
|
805
|
+
end
|
806
|
+
|
807
|
+
end
|
808
|
+
|
809
|
+
context "when value is convertible" do
|
810
|
+
|
811
|
+
it "uses the block to validate and convert the argument" do
|
812
|
+
command.port = "1234"
|
813
|
+
expect(command.port).to eq 1234
|
814
|
+
end
|
815
|
+
|
667
816
|
end
|
668
817
|
|
669
818
|
end
|
@@ -676,27 +825,45 @@ describe Clamp::Command do
|
|
676
825
|
|
677
826
|
it "accepts multiple arguments" do
|
678
827
|
command.parse(%w[X Y Z])
|
679
|
-
expect(command.file_list).to
|
828
|
+
expect(command.file_list).to eq %w[X Y Z]
|
680
829
|
end
|
681
830
|
|
682
831
|
end
|
683
832
|
|
684
|
-
context "optional, with ellipsis" do
|
833
|
+
context "when optional, with ellipsis" do
|
685
834
|
|
686
835
|
before do
|
687
836
|
command.class.parameter "[FILE] ...", "files"
|
688
|
-
end
|
689
837
|
|
690
|
-
it "defaults to an empty list" do
|
691
838
|
command.parse([])
|
692
|
-
expect(command.default_file_list).to eql []
|
693
|
-
expect(command.file_list).to eql []
|
694
839
|
end
|
695
840
|
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
841
|
+
describe "default_file_list" do
|
842
|
+
|
843
|
+
it "defaults to an empty list" do
|
844
|
+
expect(command.default_file_list).to be_empty
|
845
|
+
end
|
846
|
+
|
847
|
+
end
|
848
|
+
|
849
|
+
describe "file_list" do
|
850
|
+
|
851
|
+
it "defaults to an empty list" do
|
852
|
+
expect(command.file_list).to be_empty
|
853
|
+
end
|
854
|
+
|
855
|
+
end
|
856
|
+
|
857
|
+
describe "mutation" do
|
858
|
+
|
859
|
+
before do
|
860
|
+
command.file_list << "treasure"
|
861
|
+
end
|
862
|
+
|
863
|
+
it "is mutable" do
|
864
|
+
expect(command.file_list).to eq ["treasure"]
|
865
|
+
end
|
866
|
+
|
700
867
|
end
|
701
868
|
|
702
869
|
end
|
@@ -706,20 +873,18 @@ describe Clamp::Command do
|
|
706
873
|
before do
|
707
874
|
command.class.parameter "[FILE]", "a file", environment_variable: "FILE",
|
708
875
|
default: "/dev/null"
|
709
|
-
end
|
710
|
-
|
711
|
-
let(:args) { [] }
|
712
|
-
let(:environment_value) { nil }
|
713
876
|
|
714
|
-
before do
|
715
877
|
set_env("FILE", environment_value)
|
716
878
|
command.parse(args)
|
717
879
|
end
|
718
880
|
|
881
|
+
let(:args) { [] }
|
882
|
+
let(:environment_value) { nil }
|
883
|
+
|
719
884
|
context "when neither argument nor environment variable are present" do
|
720
885
|
|
721
886
|
it "uses the default" do
|
722
|
-
expect(command.file).to
|
887
|
+
expect(command.file).to eq File::NULL
|
723
888
|
end
|
724
889
|
|
725
890
|
end
|
@@ -731,7 +896,7 @@ describe Clamp::Command do
|
|
731
896
|
describe "and no argument is provided" do
|
732
897
|
|
733
898
|
it "uses the environment variable" do
|
734
|
-
expect(command.file).to
|
899
|
+
expect(command.file).to eq "/etc/motd"
|
735
900
|
end
|
736
901
|
|
737
902
|
end
|
@@ -741,7 +906,7 @@ describe Clamp::Command do
|
|
741
906
|
let(:args) { ["/dev/null"] }
|
742
907
|
|
743
908
|
it "uses the argument" do
|
744
|
-
expect(command.file).to
|
909
|
+
expect(command.file).to eq File::NULL
|
745
910
|
end
|
746
911
|
|
747
912
|
end
|
@@ -794,10 +959,22 @@ describe Clamp::Command do
|
|
794
959
|
command.parse(["crash", "bang", "wallop"])
|
795
960
|
end
|
796
961
|
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
962
|
+
describe "x" do
|
963
|
+
it "maps arguments onto the command object" do
|
964
|
+
expect(command.x).to eq "crash"
|
965
|
+
end
|
966
|
+
end
|
967
|
+
|
968
|
+
describe "y" do
|
969
|
+
it "maps arguments onto the command object" do
|
970
|
+
expect(command.y).to eq "bang"
|
971
|
+
end
|
972
|
+
end
|
973
|
+
|
974
|
+
describe "z" do
|
975
|
+
it "maps arguments onto the command object" do
|
976
|
+
expect(command.z).to eq "wallop"
|
977
|
+
end
|
801
978
|
end
|
802
979
|
|
803
980
|
end
|
@@ -814,22 +991,52 @@ describe Clamp::Command do
|
|
814
991
|
|
815
992
|
context "with optional argument omitted" do
|
816
993
|
|
817
|
-
|
994
|
+
before do
|
818
995
|
command.parse(["crash", "bang"])
|
819
|
-
|
820
|
-
|
821
|
-
|
996
|
+
end
|
997
|
+
|
998
|
+
describe "x" do
|
999
|
+
it "defaults the optional argument" do
|
1000
|
+
expect(command.x).to eq "crash"
|
1001
|
+
end
|
1002
|
+
end
|
1003
|
+
|
1004
|
+
describe "y" do
|
1005
|
+
it "defaults the optional argument" do
|
1006
|
+
expect(command.y).to eq "bang"
|
1007
|
+
end
|
1008
|
+
end
|
1009
|
+
|
1010
|
+
describe "z" do
|
1011
|
+
it "defaults the optional argument" do
|
1012
|
+
expect(command.z).to eq "ZZZ"
|
1013
|
+
end
|
822
1014
|
end
|
823
1015
|
|
824
1016
|
end
|
825
1017
|
|
826
1018
|
context "with multi-line arguments" do
|
827
1019
|
|
828
|
-
|
1020
|
+
before do
|
829
1021
|
command.parse(["foo\nhi", "bar", "baz"])
|
830
|
-
|
831
|
-
|
832
|
-
|
1022
|
+
end
|
1023
|
+
|
1024
|
+
describe "x" do
|
1025
|
+
it "parses them correctly" do
|
1026
|
+
expect(command.x).to eq "foo\nhi"
|
1027
|
+
end
|
1028
|
+
end
|
1029
|
+
|
1030
|
+
describe "y" do
|
1031
|
+
it "parses them correctly" do
|
1032
|
+
expect(command.y).to eq "bar"
|
1033
|
+
end
|
1034
|
+
end
|
1035
|
+
|
1036
|
+
describe "z" do
|
1037
|
+
it "parses them correctly" do
|
1038
|
+
expect(command.z).to eq "baz"
|
1039
|
+
end
|
833
1040
|
end
|
834
1041
|
|
835
1042
|
end
|
@@ -853,9 +1060,7 @@ describe Clamp::Command do
|
|
853
1060
|
end
|
854
1061
|
|
855
1062
|
it "includes parameter details" do
|
856
|
-
expect(command.help).to match(/X +x/)
|
857
|
-
expect(command.help).to match(/Y +y/)
|
858
|
-
expect(command.help).to match(/\[Z\] +z \(default: "ZZZ"\)/)
|
1063
|
+
expect(command.help).to match(/X +x\n[\s\S]* +Y +y\n[\s\S]* +\[Z\] +z \(default: "ZZZ"\)/)
|
859
1064
|
end
|
860
1065
|
|
861
1066
|
it "handles new lines in option descriptions" do
|
@@ -868,13 +1073,19 @@ describe Clamp::Command do
|
|
868
1073
|
|
869
1074
|
describe ".execute" do
|
870
1075
|
|
871
|
-
|
1076
|
+
before do
|
1077
|
+
|
872
1078
|
command_class.class_eval do
|
873
1079
|
execute do
|
874
1080
|
puts "using execute DSL"
|
875
1081
|
end
|
876
1082
|
end
|
1083
|
+
|
877
1084
|
command.run([])
|
1085
|
+
|
1086
|
+
end
|
1087
|
+
|
1088
|
+
it "provides an alternative way to declare execute method" do
|
878
1089
|
expect(stdout).to eq("using execute DSL\n")
|
879
1090
|
end
|
880
1091
|
|
@@ -910,8 +1121,7 @@ describe Clamp::Command do
|
|
910
1121
|
describe "#help" do
|
911
1122
|
|
912
1123
|
it "includes both potential usages" do
|
913
|
-
expect(command.help).to
|
914
|
-
expect(command.help).to include("put THAT THERE\n")
|
1124
|
+
expect(command.help).to match(/put THIS HERE\n +put THAT THERE/)
|
915
1125
|
end
|
916
1126
|
|
917
1127
|
end
|
@@ -934,8 +1144,7 @@ describe Clamp::Command do
|
|
934
1144
|
describe "#help" do
|
935
1145
|
|
936
1146
|
it "includes the banner" do
|
937
|
-
expect(command.help).to match(/^ Punt is an example command/)
|
938
|
-
expect(command.help).to match(/^ The prefix/)
|
1147
|
+
expect(command.help).to match(/^ Punt is an example command.+\n^ \n^ The prefix/)
|
939
1148
|
end
|
940
1149
|
|
941
1150
|
end
|
@@ -944,28 +1153,42 @@ describe Clamp::Command do
|
|
944
1153
|
|
945
1154
|
describe ".run" do
|
946
1155
|
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
1156
|
+
context "when regular" do
|
1157
|
+
|
1158
|
+
before do
|
1159
|
+
|
1160
|
+
command.class.class_eval do
|
1161
|
+
parameter "WORD ...", "words"
|
1162
|
+
def execute
|
1163
|
+
print word_list.inspect
|
1164
|
+
end
|
952
1165
|
end
|
1166
|
+
|
953
1167
|
end
|
954
|
-
|
955
|
-
|
956
|
-
|
1168
|
+
|
1169
|
+
it "creates a new Command instance and runs it" do
|
1170
|
+
xyz = %w[x y z]
|
1171
|
+
command.class.run("cmd", xyz)
|
1172
|
+
expect(stdout).to eq xyz.inspect
|
1173
|
+
end
|
1174
|
+
|
957
1175
|
end
|
958
1176
|
|
959
|
-
context "invoked with a context hash" do
|
1177
|
+
context "when invoked with a context hash" do
|
1178
|
+
|
1179
|
+
before do
|
960
1180
|
|
961
|
-
it "makes the context available within the command" do
|
962
1181
|
command.class.class_eval do
|
963
1182
|
def execute
|
964
1183
|
print context[:foo]
|
965
1184
|
end
|
966
1185
|
end
|
1186
|
+
|
1187
|
+
end
|
1188
|
+
|
1189
|
+
it "makes the context available within the command" do
|
967
1190
|
command.class.run("xyz", [], foo: "bar")
|
968
|
-
expect(stdout).to
|
1191
|
+
expect(stdout).to eq "bar"
|
969
1192
|
end
|
970
1193
|
|
971
1194
|
end
|
@@ -980,20 +1203,15 @@ describe Clamp::Command do
|
|
980
1203
|
end
|
981
1204
|
end
|
982
1205
|
|
983
|
-
begin
|
984
|
-
command.class.run("cmd", [])
|
985
|
-
rescue SystemExit => e
|
986
|
-
@system_exit = e
|
987
|
-
end
|
988
|
-
|
989
1206
|
end
|
990
1207
|
|
991
|
-
it "outputs the error message" do
|
992
|
-
expect
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
1208
|
+
it "outputs the error message and exits with the specified status" do # rubocop:disable RSpec/ExampleLength
|
1209
|
+
expect { command.class.run("cmd", []) }
|
1210
|
+
.to raise_error(
|
1211
|
+
an_instance_of(SystemExit).and(having_attributes(status: 456))
|
1212
|
+
).and output(<<~TEXT).to_stderr
|
1213
|
+
ERROR: Oh crap!
|
1214
|
+
TEXT
|
997
1215
|
end
|
998
1216
|
|
999
1217
|
end
|
@@ -1016,17 +1234,15 @@ describe Clamp::Command do
|
|
1016
1234
|
|
1017
1235
|
end
|
1018
1236
|
|
1019
|
-
it "outputs the error message" do
|
1020
|
-
expect
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
end
|
1237
|
+
it "outputs the error message and help" do # rubocop:disable RSpec/ExampleLength
|
1238
|
+
expect { command.class.run("cmd", []) }
|
1239
|
+
.to raise_error(
|
1240
|
+
an_instance_of(SystemExit).and(having_attributes(status: 1))
|
1241
|
+
).and output(<<~TEXT).to_stderr
|
1242
|
+
ERROR: bad dog!
|
1026
1243
|
|
1027
|
-
|
1028
|
-
|
1029
|
-
expect(@system_exit.status).to eql 1
|
1244
|
+
See: 'cmd --help'
|
1245
|
+
TEXT
|
1030
1246
|
end
|
1031
1247
|
|
1032
1248
|
end
|