command_mapper 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/spec/commnad_spec.rb CHANGED
@@ -69,6 +69,20 @@ describe CommandMapper::Command do
69
69
  end
70
70
  end
71
71
 
72
+ module TestCommand
73
+ class BaseClassWithOptions < CommandMapper::Command
74
+ option "--foo"
75
+ option "--bar"
76
+ end
77
+
78
+ class InheritedOptions < BaseClassWithOptions
79
+ end
80
+
81
+ class InheritsAndDefinesOptions < BaseClassWithOptions
82
+ option "--baz"
83
+ end
84
+ end
85
+
72
86
  describe ".options" do
73
87
  subject { command_class }
74
88
 
@@ -79,16 +93,6 @@ describe CommandMapper::Command do
79
93
  end
80
94
 
81
95
  context "and when the command inherits from another command class" do
82
- module TestCommand
83
- class BaseClassWithOptions < CommandMapper::Command
84
- option "--foo"
85
- option "--bar"
86
- end
87
-
88
- class InheritedOptions < BaseClassWithOptions
89
- end
90
- end
91
-
92
96
  let(:command_class) { TestCommand::InheritedOptions }
93
97
  let(:command_superclass) { TestCommand::BaseClassWithOptions }
94
98
 
@@ -97,12 +101,6 @@ describe CommandMapper::Command do
97
101
  end
98
102
 
99
103
  context "and when the class defines options of it's own" do
100
- module TestCommand
101
- class InheritsAndDefinesOptions < BaseClassWithOptions
102
- option "--baz"
103
- end
104
- end
105
-
106
104
  let(:command_class) { TestCommand::InheritsAndDefinesOptions }
107
105
 
108
106
  it "must copy the options defined in the superclass" do
@@ -120,6 +118,38 @@ describe CommandMapper::Command do
120
118
  end
121
119
  end
122
120
 
121
+ describe ".has_option?" do
122
+ subject { command_class }
123
+
124
+ let(:name) { :bar }
125
+
126
+ context "when the command has no defined options" do
127
+ let(:command_class) { TestCommand::EmptyCommand }
128
+
129
+ it "must return false" do
130
+ expect(subject.has_option?(name)).to be(false)
131
+ end
132
+ end
133
+
134
+ context "when the command does have defined options" do
135
+ let(:command_class) { TestCommand::BaseClassWithOptions }
136
+
137
+ context "and has the option with the given name" do
138
+ it "must return true" do
139
+ expect(subject.has_option?(name)).to be(true)
140
+ end
141
+ end
142
+
143
+ context "but does not have the option with the given name" do
144
+ let(:name) { :xxx }
145
+
146
+ it "must return false" do
147
+ expect(subject.has_option?(name)).to be(false)
148
+ end
149
+ end
150
+ end
151
+ end
152
+
123
153
  describe ".option" do
124
154
  module TestCommand
125
155
  class DefinesItsOwnOptions < CommandMapper::Command
@@ -242,6 +272,55 @@ describe CommandMapper::Command do
242
272
  }.to raise_error(ArgumentError,"option #{flag.inspect} maps to method name ##{name} and cannot override the internal method with same name: ##{name}")
243
273
  end
244
274
  end
275
+
276
+ context "when the option name conflicts with another defined argument" do
277
+ let(:command_class) do
278
+ Class.new(described_class) do
279
+ argument :foo
280
+ end
281
+ end
282
+
283
+ let(:flag) { "--foo" }
284
+ let(:name) { :foo }
285
+
286
+ it do
287
+ expect {
288
+ subject.option(flag)
289
+ }.to raise_error(ArgumentError,"option #{flag.inspect} with name #{name.inspect} conflicts with another argument with the same name")
290
+ end
291
+ end
292
+
293
+ context "when the option name conflicts with another defined subcommand" do
294
+ let(:command_class) do
295
+ Class.new(described_class) do
296
+ subcommand 'foo' do
297
+ end
298
+ end
299
+ end
300
+
301
+ let(:flag) { "--foo" }
302
+ let(:name) { :foo }
303
+
304
+ it do
305
+ expect {
306
+ subject.option(flag)
307
+ }.to raise_error(ArgumentError,"option #{flag.inspect} with name #{name.inspect} conflicts with another subcommand with the same name")
308
+ end
309
+ end
310
+ end
311
+
312
+ module TestCommand
313
+ class BaseClassWithArguments < CommandMapper::Command
314
+ argument :foo
315
+ argument :bar
316
+ end
317
+
318
+ class InheritedArguments < BaseClassWithArguments
319
+ end
320
+
321
+ class InheritsAndDefinesArguments < BaseClassWithArguments
322
+ argument :baz
323
+ end
245
324
  end
246
325
 
247
326
  describe ".arguments" do
@@ -254,31 +333,15 @@ describe CommandMapper::Command do
254
333
  end
255
334
 
256
335
  context "when the comand does have defined arguments" do
257
- module TestCommand
258
- class BaseClassWithOptions < CommandMapper::Command
259
- argument :foo
260
- argument :bar
261
- end
262
-
263
- class InheritedOptions < BaseClassWithOptions
264
- end
265
- end
266
-
267
- let(:command_class) { TestCommand::InheritedOptions }
268
- let(:command_superclass) { TestCommand::BaseClassWithOptions }
336
+ let(:command_class) { TestCommand::InheritedArguments }
337
+ let(:command_superclass) { TestCommand::BaseClassWithArguments }
269
338
 
270
339
  it "must copy the arguments defined in the superclass" do
271
340
  expect(subject.arguments).to eq(command_superclass.arguments)
272
341
  end
273
342
 
274
343
  context "and when the class defines arguments of it's own" do
275
- module TestCommand
276
- class InheritsAndDefinesOptions < BaseClassWithOptions
277
- argument :baz
278
- end
279
- end
280
-
281
- let(:command_class) { TestCommand::InheritsAndDefinesOptions }
344
+ let(:command_class) { TestCommand::InheritsAndDefinesArguments }
282
345
 
283
346
  it "must copy the arguments defined in the superclass" do
284
347
  expect(subject.arguments).to include(command_superclass.arguments)
@@ -295,6 +358,38 @@ describe CommandMapper::Command do
295
358
  end
296
359
  end
297
360
 
361
+ describe ".has_argument?" do
362
+ subject { command_class }
363
+
364
+ let(:name) { :bar }
365
+
366
+ context "when the command has no defined arguments" do
367
+ let(:command_class) { TestCommand::EmptyCommand }
368
+
369
+ it "must return false" do
370
+ expect(subject.has_argument?(name)).to be(false)
371
+ end
372
+ end
373
+
374
+ context "when the command does have defined arguments" do
375
+ let(:command_class) { TestCommand::BaseClassWithArguments }
376
+
377
+ context "and has the argument with the given name" do
378
+ it "must return true" do
379
+ expect(subject.has_argument?(name)).to be(true)
380
+ end
381
+ end
382
+
383
+ context "but does not have the argument with the given name" do
384
+ let(:name) { :xxx }
385
+
386
+ it "must return false" do
387
+ expect(subject.has_argument?(name)).to be(false)
388
+ end
389
+ end
390
+ end
391
+ end
392
+
298
393
  describe ".argument" do
299
394
  module TestCommand
300
395
  class DefinesArgument < CommandMapper::Command
@@ -357,6 +452,59 @@ describe CommandMapper::Command do
357
452
  }.to raise_error(ArgumentError,"argument #{name.inspect} cannot override internal method with same name: ##{name}")
358
453
  end
359
454
  end
455
+
456
+ context "when the argument name conflicts with another defined option" do
457
+ let(:command_class) do
458
+ Class.new(described_class) do
459
+ option '--foo'
460
+ end
461
+ end
462
+
463
+ let(:name) { :foo }
464
+
465
+ it do
466
+ expect {
467
+ subject.argument(name)
468
+ }.to raise_error(ArgumentError,"argument #{name.inspect} conflicts with another option with the same name")
469
+ end
470
+ end
471
+
472
+ context "when the argument name conflicts with another defined subcommand" do
473
+ let(:command_class) do
474
+ Class.new(described_class) do
475
+ subcommand 'foo' do
476
+ end
477
+ end
478
+ end
479
+
480
+ let(:name) { :foo }
481
+
482
+ it do
483
+ expect {
484
+ subject.argument(name)
485
+ }.to raise_error(ArgumentError,"argument #{name.inspect} conflicts with another subcommand with the same name")
486
+ end
487
+ end
488
+ end
489
+
490
+ module TestCommand
491
+ class BaseClassWithSubcommands < CommandMapper::Command
492
+ subcommand :foo do
493
+ end
494
+
495
+ subcommand :bar do
496
+ end
497
+ end
498
+
499
+ class InheritedSubcommands < BaseClassWithSubcommands
500
+ end
501
+
502
+ class InheritsAndDefinesSubcommands < BaseClassWithSubcommands
503
+
504
+ subcommand :baz do
505
+ end
506
+
507
+ end
360
508
  end
361
509
 
362
510
  describe ".subcommands" do
@@ -369,37 +517,15 @@ describe CommandMapper::Command do
369
517
  end
370
518
 
371
519
  context "when the comand does have defined subcommands" do
372
- module TestCommand
373
- class BaseClassWithOptions < CommandMapper::Command
374
- subcommand :foo do
375
- end
376
-
377
- subcommand :bar do
378
- end
379
- end
380
-
381
- class InheritedOptions < BaseClassWithOptions
382
- end
383
- end
384
-
385
- let(:command_class) { TestCommand::InheritedOptions }
386
- let(:command_superclass) { TestCommand::BaseClassWithOptions }
520
+ let(:command_class) { TestCommand::InheritedSubcommands }
521
+ let(:command_superclass) { TestCommand::BaseClassWithSubcommands }
387
522
 
388
523
  it "must copy the subcommands defined in the superclass" do
389
524
  expect(subject.subcommands).to eq(command_superclass.subcommands)
390
525
  end
391
526
 
392
527
  context "and when the class defines subcommands of it's own" do
393
- module TestCommand
394
- class InheritsAndDefinesOptions < BaseClassWithOptions
395
-
396
- subcommand :baz do
397
- end
398
-
399
- end
400
- end
401
-
402
- let(:command_class) { TestCommand::InheritsAndDefinesOptions }
528
+ let(:command_class) { TestCommand::InheritsAndDefinesSubcommands }
403
529
 
404
530
  it "must copy the subcommands defined in the superclass" do
405
531
  expect(subject.subcommands).to include(command_superclass.subcommands)
@@ -416,6 +542,38 @@ describe CommandMapper::Command do
416
542
  end
417
543
  end
418
544
 
545
+ describe ".has_subcommand?" do
546
+ subject { command_class }
547
+
548
+ let(:name) { :bar }
549
+
550
+ context "when the command has no defined subcommands" do
551
+ let(:command_class) { TestCommand::EmptyCommand }
552
+
553
+ it "must return false" do
554
+ expect(subject.has_subcommand?(name)).to be(false)
555
+ end
556
+ end
557
+
558
+ context "when the command does have defined subcommands" do
559
+ let(:command_class) { TestCommand::BaseClassWithSubcommands }
560
+
561
+ context "and has the subcommand with the given name" do
562
+ it "must return true" do
563
+ expect(subject.has_subcommand?(name)).to be(true)
564
+ end
565
+ end
566
+
567
+ context "but does not have the subcommand with the given name" do
568
+ let(:name) { :xxx }
569
+
570
+ it "must return false" do
571
+ expect(subject.has_subcommand?(name)).to be(false)
572
+ end
573
+ end
574
+ end
575
+ end
576
+
419
577
  describe ".subcommand" do
420
578
  module TestCommand
421
579
  class DefinesSubcommand < CommandMapper::Command
@@ -567,11 +725,45 @@ describe CommandMapper::Command do
567
725
 
568
726
  it do
569
727
  expect {
570
- command_class.subcommand(name) do
728
+ subject.subcommand(name) do
571
729
  end
572
730
  }.to raise_error(ArgumentError,"subcommand #{name.inspect} maps to method name ##{method_name} and cannot override the internal method with same name: ##{method_name}")
573
731
  end
574
732
  end
733
+
734
+ context "when the subcommand name conflicts with another defined option" do
735
+ let(:command_class) do
736
+ Class.new(described_class) do
737
+ option '--foo'
738
+ end
739
+ end
740
+
741
+ let(:name) { 'foo' }
742
+
743
+ it do
744
+ expect {
745
+ subject.subcommand(name) do
746
+ end
747
+ }.to raise_error(ArgumentError,"subcommand #{name.inspect} conflicts with another option with the same name")
748
+ end
749
+ end
750
+
751
+ context "when the subcommand name conflicts with another defined argument" do
752
+ let(:command_class) do
753
+ Class.new(described_class) do
754
+ argument :foo
755
+ end
756
+ end
757
+
758
+ let(:name) { 'foo' }
759
+
760
+ it do
761
+ expect {
762
+ subject.subcommand(name) do
763
+ end
764
+ }.to raise_error(ArgumentError,"subcommand #{name.inspect} conflicts with another argument with the same name")
765
+ end
766
+ end
575
767
  end
576
768
 
577
769
  module TestCommand
@@ -615,8 +807,8 @@ describe CommandMapper::Command do
615
807
  {opt1: opt1, arg1: arg1}
616
808
  end
617
809
 
618
- it "must initialize a new command with the Hash of params and call #run" do
619
- if RUBY_VERSION < '3.'
810
+ it "must initialize a new command with the Hash of params and call #run_command" do
811
+ if RUBY_VERSION < '3.' || RUBY_ENGINE == 'truffleruby'
620
812
  expect(subject).to receive(:new).with({},params).and_return(command_instance)
621
813
  else
622
814
  expect(subject).to receive(:new).with(params).and_return(command_instance)
@@ -633,7 +825,7 @@ describe CommandMapper::Command do
633
825
  {opt1: opt1, arg1: arg1}
634
826
  end
635
827
 
636
- it "must initialize a new command with the keyword arguments and call #run" do
828
+ it "must initialize a new command with the keyword arguments and call #run_command" do
637
829
  expect(subject).to receive(:new).with({},**kwargs).and_return(command_instance)
638
830
  expect(command_instance).to receive(:run_command).and_return(return_value)
639
831
 
@@ -642,6 +834,44 @@ describe CommandMapper::Command do
642
834
  end
643
835
  end
644
836
 
837
+ describe ".spawn" do
838
+ let(:command_instance) { double(:command_instance) }
839
+ let(:return_value) { double(:boolean) }
840
+
841
+ subject { command_class }
842
+
843
+ context "when called with a Hash of params" do
844
+ let(:params) do
845
+ {opt1: opt1, arg1: arg1}
846
+ end
847
+
848
+ it "must initialize a new command with the Hash of params and call #spawn_command" do
849
+ if RUBY_VERSION < '3.' || RUBY_ENGINE == 'truffleruby'
850
+ expect(subject).to receive(:new).with({},params).and_return(command_instance)
851
+ else
852
+ expect(subject).to receive(:new).with(params).and_return(command_instance)
853
+ end
854
+
855
+ expect(command_instance).to receive(:spawn_command).and_return(return_value)
856
+
857
+ expect(subject.spawn(params)).to be(return_value)
858
+ end
859
+ end
860
+
861
+ context "when called with keyword aguments" do
862
+ let(:kwargs) do
863
+ {opt1: opt1, arg1: arg1}
864
+ end
865
+
866
+ it "must initialize a new command with the keyword arguments and call #spawn_command" do
867
+ expect(subject).to receive(:new).with({},**kwargs).and_return(command_instance)
868
+ expect(command_instance).to receive(:spawn_command).and_return(return_value)
869
+
870
+ expect(subject.spawn(**kwargs)).to be(return_value)
871
+ end
872
+ end
873
+ end
874
+
645
875
  describe ".capture" do
646
876
  let(:command_instance) { double(:command_instance) }
647
877
  let(:return_value) { double(:string) }
@@ -653,8 +883,8 @@ describe CommandMapper::Command do
653
883
  {opt1: opt1, arg1: arg1}
654
884
  end
655
885
 
656
- it "must initialize a new command with the Hash of params and call #capture" do
657
- if RUBY_VERSION < '3.'
886
+ it "must initialize a new command with the Hash of params and call #capture_command" do
887
+ if RUBY_VERSION < '3.' || RUBY_ENGINE == 'truffleruby'
658
888
  expect(subject).to receive(:new).with({},params).and_return(command_instance)
659
889
  else
660
890
  expect(subject).to receive(:new).with(params).and_return(command_instance)
@@ -671,7 +901,7 @@ describe CommandMapper::Command do
671
901
  {opt1: opt1, arg1: arg1}
672
902
  end
673
903
 
674
- it "must initialize a new command with the keyword arguments and call #capture" do
904
+ it "must initialize a new command with the keyword arguments and call #capture_command" do
675
905
  expect(subject).to receive(:new).with({},**kwargs).and_return(command_instance)
676
906
  expect(command_instance).to receive(:capture_command).and_return(return_value)
677
907
 
@@ -691,8 +921,8 @@ describe CommandMapper::Command do
691
921
  {opt1: opt1, arg1: arg1}
692
922
  end
693
923
 
694
- it "must initialize a new command with the Hash of params and call #popen" do
695
- if RUBY_VERSION < '3.'
924
+ it "must initialize a new command with the Hash of params and call #popen_command" do
925
+ if RUBY_VERSION < '3.' || RUBY_ENGINE == 'truffleruby'
696
926
  expect(subject).to receive(:new).with({},params).and_return(command_instance)
697
927
  else
698
928
  expect(subject).to receive(:new).with(params).and_return(command_instance)
@@ -709,7 +939,7 @@ describe CommandMapper::Command do
709
939
  {opt1: opt1, arg1: arg1}
710
940
  end
711
941
 
712
- it "must initialize a new command with the keyword arguments and call #popen" do
942
+ it "must initialize a new command with the keyword arguments and call #popen_command" do
713
943
  expect(subject).to receive(:new).with({},**kwargs).and_return(command_instance)
714
944
  expect(command_instance).to receive(:popen_command).and_return(return_value)
715
945
 
@@ -729,8 +959,8 @@ describe CommandMapper::Command do
729
959
  {opt1: opt1, arg1: arg1}
730
960
  end
731
961
 
732
- it "must initialize a new command with the Hash of params and call #sudo" do
733
- if RUBY_VERSION < '3.'
962
+ it "must initialize a new command with the Hash of params and call #sudo_command" do
963
+ if RUBY_VERSION < '3.' || RUBY_ENGINE == 'truffleruby'
734
964
  expect(subject).to receive(:new).with({},params).and_return(command_instance)
735
965
  else
736
966
  expect(subject).to receive(:new).with(params).and_return(command_instance)
@@ -747,7 +977,7 @@ describe CommandMapper::Command do
747
977
  {opt1: opt1, arg1: arg1}
748
978
  end
749
979
 
750
- it "must initialize a new command with the keyword arguments and call #sudo" do
980
+ it "must initialize a new command with the keyword arguments and call #sudo_command" do
751
981
  expect(subject).to receive(:new).with({},**kwargs).and_return(command_instance)
752
982
  expect(command_instance).to receive(:sudo_command).and_return(return_value)
753
983
 
@@ -1120,12 +1350,22 @@ describe CommandMapper::Command do
1120
1350
  subject { command_class.new({opt1: opt1, arg1: arg1}, command_env: env) }
1121
1351
 
1122
1352
  it "must pass the command's env and argv to Kenrel.system" do
1123
- expect(subject).to receive(:system).with(env,*subject.command_argv)
1353
+ expect(Kernel).to receive(:system).with(env,*subject.command_argv)
1124
1354
 
1125
1355
  subject.run_command
1126
1356
  end
1127
1357
  end
1128
1358
 
1359
+ describe "#spawn_command" do
1360
+ subject { command_class.new({opt1: opt1, arg1: arg1}, command_env: env) }
1361
+
1362
+ it "must pass the command's env and argv to Kenrel.system" do
1363
+ expect(Process).to receive(:spawn).with(env,*subject.command_argv)
1364
+
1365
+ subject.spawn_command
1366
+ end
1367
+ end
1368
+
1129
1369
  describe "#capture_command" do
1130
1370
  subject { command_class.new({opt1: opt1, arg1: arg1}, command_env: env) }
1131
1371