command_mapper 0.1.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
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 +25 -0
  7. data/Gemfile +15 -0
  8. data/LICENSE.txt +20 -0
  9. data/README.md +369 -0
  10. data/Rakefile +12 -0
  11. data/commnad_mapper.gemspec +61 -0
  12. data/gemspec.yml +23 -0
  13. data/lib/command_mapper/arg.rb +75 -0
  14. data/lib/command_mapper/argument.rb +142 -0
  15. data/lib/command_mapper/command.rb +606 -0
  16. data/lib/command_mapper/exceptions.rb +19 -0
  17. data/lib/command_mapper/option.rb +282 -0
  18. data/lib/command_mapper/option_value.rb +21 -0
  19. data/lib/command_mapper/sudo.rb +73 -0
  20. data/lib/command_mapper/types/enum.rb +35 -0
  21. data/lib/command_mapper/types/hex.rb +82 -0
  22. data/lib/command_mapper/types/input_dir.rb +35 -0
  23. data/lib/command_mapper/types/input_file.rb +35 -0
  24. data/lib/command_mapper/types/input_path.rb +29 -0
  25. data/lib/command_mapper/types/key_value.rb +131 -0
  26. data/lib/command_mapper/types/key_value_list.rb +45 -0
  27. data/lib/command_mapper/types/list.rb +90 -0
  28. data/lib/command_mapper/types/map.rb +64 -0
  29. data/lib/command_mapper/types/num.rb +50 -0
  30. data/lib/command_mapper/types/str.rb +85 -0
  31. data/lib/command_mapper/types/type.rb +102 -0
  32. data/lib/command_mapper/types.rb +6 -0
  33. data/lib/command_mapper/version.rb +4 -0
  34. data/lib/command_mapper.rb +2 -0
  35. data/spec/arg_spec.rb +137 -0
  36. data/spec/argument_spec.rb +513 -0
  37. data/spec/commnad_spec.rb +1175 -0
  38. data/spec/exceptions_spec.rb +14 -0
  39. data/spec/option_spec.rb +882 -0
  40. data/spec/option_value_spec.rb +17 -0
  41. data/spec/spec_helper.rb +6 -0
  42. data/spec/sudo_spec.rb +24 -0
  43. data/spec/types/enum_spec.rb +31 -0
  44. data/spec/types/hex_spec.rb +158 -0
  45. data/spec/types/input_dir_spec.rb +30 -0
  46. data/spec/types/input_file_spec.rb +34 -0
  47. data/spec/types/input_path_spec.rb +32 -0
  48. data/spec/types/key_value_list_spec.rb +100 -0
  49. data/spec/types/key_value_spec.rb +272 -0
  50. data/spec/types/list_spec.rb +143 -0
  51. data/spec/types/map_spec.rb +62 -0
  52. data/spec/types/num_spec.rb +90 -0
  53. data/spec/types/str_spec.rb +232 -0
  54. data/spec/types/type_spec.rb +59 -0
  55. metadata +118 -0
data/spec/arg_spec.rb ADDED
@@ -0,0 +1,137 @@
1
+ require 'spec_helper'
2
+ require 'command_mapper/arg'
3
+ require 'command_mapper/types/list'
4
+
5
+ describe CommandMapper::Arg do
6
+ describe "#initialize" do
7
+ it "must default #type to a Types::Str object" do
8
+ expect(subject.type).to be_kind_of(Types::Str)
9
+ end
10
+
11
+ context "when given the type: keyword argument" do
12
+ context "and it's a Types::Type object" do
13
+ let(:type) { Types::List.new(separator: ',') }
14
+
15
+ subject { described_class.new(type: type) }
16
+
17
+ it "must set #type" do
18
+ expect(subject.type).to eq(type)
19
+ end
20
+ end
21
+
22
+ context "but it's nil" do
23
+ it do
24
+ expect {
25
+ described_class.new(type: nil)
26
+ }.to raise_error(ArgumentError,"type: keyword cannot be nil")
27
+ end
28
+ end
29
+ end
30
+
31
+ context "when given the required: true keyword argument" do
32
+ subject { described_class.new(required: true) }
33
+
34
+ it "type's #required? must be true" do
35
+ expect(subject.required?).to be(true)
36
+ end
37
+ end
38
+
39
+ context "when given the required: false keyword argument" do
40
+ subject { described_class.new(required: false) }
41
+
42
+ it "the #type's #required? must be false" do
43
+ expect(subject.required?).to be(false)
44
+ end
45
+ end
46
+ end
47
+
48
+ let(:required) { true }
49
+ let(:type) { Types::Str.new }
50
+
51
+ subject do
52
+ described_class.new(
53
+ required: required,
54
+ type: type
55
+ )
56
+ end
57
+
58
+ describe "#required?" do
59
+ context "when initialized with required: true" do
60
+ subject { described_class.new(required: true) }
61
+
62
+ it "must be true" do
63
+ expect(subject.required?).to be(true)
64
+ end
65
+ end
66
+
67
+ context "when initialized with required: true" do
68
+ subject { described_class.new(required: false) }
69
+
70
+ it "must be false" do
71
+ expect(subject.required?).to be(false)
72
+ end
73
+ end
74
+ end
75
+
76
+ describe "#optional?" do
77
+ context "when initialized with required: false" do
78
+ subject { described_class.new(required: false) }
79
+
80
+ it "must be true" do
81
+ expect(subject.optional?).to be(true)
82
+ end
83
+ end
84
+
85
+ context "when initialized with required: true" do
86
+ subject { described_class.new(required: true) }
87
+
88
+ it "must be false" do
89
+ expect(subject.optional?).to be(false)
90
+ end
91
+ end
92
+ end
93
+
94
+ describe "#validate" do
95
+ context "when the argument requires a value" do
96
+ let(:required) { true }
97
+
98
+ context "is given a String" do
99
+ let(:value) { "foo" }
100
+
101
+ it "must return true" do
102
+ expect(subject.validate(value)).to be(true)
103
+ end
104
+ end
105
+
106
+ context "and is given nil" do
107
+ let(:value) { nil }
108
+
109
+ it "must return true" do
110
+ expect(subject.validate(value)).to eq(
111
+ [false, "does not accept a nil value"]
112
+ )
113
+ end
114
+ end
115
+ end
116
+
117
+ context "when the argument does not require a value" do
118
+ let(:required) { false }
119
+
120
+ context "is given a String" do
121
+ let(:value) { "foo" }
122
+
123
+ it "must return true" do
124
+ expect(subject.validate(value)).to be(true)
125
+ end
126
+ end
127
+
128
+ context "and is given nil" do
129
+ let(:value) { nil }
130
+
131
+ it "must return true" do
132
+ expect(subject.validate(value)).to be(true)
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,513 @@
1
+ require 'spec_helper'
2
+ require 'command_mapper/argument'
3
+ require 'command_mapper/types/list'
4
+ require 'command_mapper/types/key_value'
5
+
6
+ describe CommandMapper::Argument do
7
+ let(:name) { :foo }
8
+
9
+ describe "#initialize" do
10
+ subject { described_class.new(name) }
11
+
12
+ it "must set #name" do
13
+ expect(subject.name).to eq(name)
14
+ end
15
+
16
+ it "must default #required? to true" do
17
+ expect(subject.required?).to be(true)
18
+ end
19
+
20
+ it "must default #type to a Types::Str object" do
21
+ expect(subject.type).to be_kind_of(Types::Str)
22
+ end
23
+
24
+ it "must default #repeats? to false" do
25
+ expect(subject.repeats?).to be(false)
26
+ end
27
+
28
+ context "when given the required: false keyword argument" do
29
+ subject { described_class.new(name, required: false) }
30
+
31
+ it "must set #required? to false" do
32
+ expect(subject.required?).to be(false)
33
+ end
34
+ end
35
+
36
+ context "when given the type: keyword argument" do
37
+ context "and it's a Types::Type object" do
38
+ let(:type) { Types::KeyValue.new }
39
+
40
+ subject { described_class.new(name, type: type) }
41
+
42
+ it "must set #type" do
43
+ expect(subject.type).to eq(type)
44
+ end
45
+ end
46
+ end
47
+
48
+ context "when given the repeats: true keyword argument" do
49
+ subject { described_class.new(name, repeats: true) }
50
+
51
+ it "#repeats? must be true" do
52
+ expect(subject.repeats?).to be(true)
53
+ end
54
+ end
55
+ end
56
+
57
+ let(:required) { true }
58
+ let(:repeats) { false }
59
+ let(:value_allows_empty) { false }
60
+ let(:value_allows_blank) { false }
61
+ let(:type) do
62
+ {
63
+ allow_empty: value_allows_empty,
64
+ allow_blank: value_allows_blank
65
+ }
66
+ end
67
+
68
+ subject do
69
+ described_class.new(name, required: required,
70
+ type: type,
71
+ repeats: repeats)
72
+ end
73
+
74
+ describe "#validate" do
75
+ context "when the argument requires a value" do
76
+ let(:required) { true }
77
+
78
+ context "when the argument can be specified multiple times" do
79
+ let(:repeats) { true }
80
+
81
+ context "and it's given an Array" do
82
+ context "and all elements of the Array are Strings" do
83
+ let(:value) { %w[foo bar baz] }
84
+
85
+ it "must return true" do
86
+ expect(subject.validate(value)).to be(true)
87
+ end
88
+ end
89
+
90
+ context "but one of the Array's elements is nil" do
91
+ let(:values) { ["foo", nil, "bar"] }
92
+
93
+ it "must return [false, \"cannot be nil\"]" do
94
+ expect(subject.validate(values)).to eq(
95
+ [false, "cannot be nil"]
96
+ )
97
+ end
98
+ end
99
+
100
+ context "but the Array contains Hashes" do
101
+ let(:values) do
102
+ [{"foo" => 1}, {"bar" => 2 }]
103
+ end
104
+
105
+ it "must return [false, \"cannot convert a Hash into a String (...)\"]" do
106
+ expect(subject.validate(values)).to eq(
107
+ [false, "cannot convert a Hash into a String (#{values[0].inspect})"]
108
+ )
109
+ end
110
+
111
+ context "but #type is a Types::KeyValue object" do
112
+ let(:type) { Types::KeyValue.new }
113
+
114
+ let(:values) do
115
+ [{"foo" => 1}, {"bar" => 2 }]
116
+ end
117
+
118
+ it "must return true" do
119
+ expect(subject.validate(values)).to be(true)
120
+ end
121
+
122
+ context "but one of the Hashes is empty" do
123
+ let(:values) do
124
+ [{"foo" => 1}, {}]
125
+ end
126
+
127
+ it "must return [false, \"requires at least one value\"]" do
128
+ expect(subject.validate(values)).to eq(
129
+ [false, "cannot be empty"]
130
+ )
131
+ end
132
+ end
133
+ end
134
+ end
135
+
136
+ context "but it's empty" do
137
+ let(:value) { [] }
138
+
139
+ it "must return [false, \"requires at least one value\"]" do
140
+ expect(subject.validate(value)).to eq(
141
+ [false, "requires at least one value"]
142
+ )
143
+ end
144
+ end
145
+ end
146
+
147
+ context "is given a String" do
148
+ let(:value) { "foo" }
149
+
150
+ it "must return true" do
151
+ expect(subject.validate(value)).to be(true)
152
+ end
153
+ end
154
+
155
+ context "and it's only given one value" do
156
+ context "and it's a String" do
157
+ let(:value) { "foo" }
158
+
159
+ it "must return true" do
160
+ expect(subject.validate(value)).to be(true)
161
+ end
162
+ end
163
+
164
+ context "and it's a Hash" do
165
+ let(:value) do
166
+ {"foo" => "bar"}
167
+ end
168
+
169
+ it "must return [false, \"cannot convert a Hash into a String (...)\"]" do
170
+ expect(subject.validate(value)).to eq(
171
+ [false, "cannot convert a Hash into a String (#{value.inspect})"]
172
+ )
173
+ end
174
+
175
+ context "but #type is a Types::KeyValue object" do
176
+ let(:type) { Types::KeyValue.new }
177
+
178
+ it "must return true" do
179
+ expect(subject.validate(value)).to be(true)
180
+ end
181
+
182
+ context "but it's empty" do
183
+ let(:value) { {} }
184
+
185
+ it "must return [false, \"cannot be empty\"]" do
186
+ expect(subject.validate(value)).to eq(
187
+ [false, "cannot be empty"]
188
+ )
189
+ end
190
+ end
191
+ end
192
+ end
193
+ end
194
+ end
195
+
196
+ context "but the argument can only be specified once" do
197
+ let(:repeats) { false }
198
+
199
+ context "and is given a String" do
200
+ let(:value) { "foo" }
201
+
202
+ it "must return true" do
203
+ expect(subject.validate(value)).to be(true)
204
+ end
205
+ end
206
+
207
+ context "and is given an Array" do
208
+ let(:value) { [1,2,3,4] }
209
+
210
+ it "must return [false, \"cannot convert a Array into a String (...)\"]" do
211
+ expect(subject.validate(value)).to eq(
212
+ [false, "cannot convert a Array into a String (#{value.inspect})"]
213
+ )
214
+ end
215
+
216
+ context "when #type is a Types::List object" do
217
+ let(:type) { Types::List.new }
218
+
219
+ it "must return true" do
220
+ expect(subject.validate(value)).to be(true)
221
+ end
222
+
223
+ context "but one of the Array elements is nil" do
224
+ let(:value) { [1,2,nil,4] }
225
+
226
+ it "must return [false, \"element cannot be nil\"]" do
227
+ expect(subject.validate(value)).to eq(
228
+ [false, "element cannot be nil"]
229
+ )
230
+ end
231
+ end
232
+
233
+ context "but it's empty" do
234
+ let(:value) { [] }
235
+
236
+ it "must return [false, \"cannot be empty\"]" do
237
+ expect(subject.validate(value)).to eq(
238
+ [false, "cannot be empty"]
239
+ )
240
+ end
241
+ end
242
+ end
243
+ end
244
+
245
+ context "and it's a Hash" do
246
+ let(:value) do
247
+ {"foo" => "bar"}
248
+ end
249
+
250
+ it "must return [false, \"cannot convert a Hash into a String (...)\"]" do
251
+ expect(subject.validate(value)).to eq(
252
+ [false, "cannot convert a Hash into a String (#{value.inspect})"]
253
+ )
254
+ end
255
+
256
+ context "but #type is a Types::KeyValue object" do
257
+ let(:type) { Types::KeyValue.new }
258
+
259
+ it "must return true" do
260
+ expect(subject.validate(value)).to be(true)
261
+ end
262
+
263
+ context "but it's empty" do
264
+ let(:value) { {} }
265
+
266
+ it "must return [false, \"cannot be empty\"]" do
267
+ expect(subject.validate(value)).to eq(
268
+ [false, "cannot be empty"]
269
+ )
270
+ end
271
+ end
272
+ end
273
+ end
274
+ end
275
+ end
276
+ end
277
+
278
+ describe "#argv" do
279
+ context "when the argument can be specified multiple times" do
280
+ let(:repeats) { true }
281
+
282
+ context "and it's given an Array" do
283
+ context "and all elements of the Array are Strings" do
284
+ let(:values) { %w[foo bar baz] }
285
+
286
+ it "must return an argv of the values" do
287
+ expect(subject.argv(values)).to eq(values)
288
+ end
289
+
290
+ context "but one of the Array's elements is nil" do
291
+ let(:values) { ["foo", nil, "bar"] }
292
+
293
+ it do
294
+ expect {
295
+ subject.argv(values)
296
+ }.to raise_error(ValidationError,"argument #{name} was given an invalid value (#{values.inspect}): cannot be nil")
297
+ end
298
+ end
299
+
300
+ context "but one of the Array's elements is invalid" do
301
+ let(:value) { ["foo", " ", "baz"] }
302
+
303
+ it do
304
+ expect {
305
+ subject.argv(value)
306
+ }.to raise_error(ValidationError,"argument #{name} was given an invalid value (#{value.inspect}): does not allow a blank value (#{value[1].inspect})")
307
+ end
308
+ end
309
+
310
+ context "but the Array contains Hashes" do
311
+ let(:values) do
312
+ [{"foo" => 1}, {"bar" => 2 }]
313
+ end
314
+
315
+ it do
316
+ expect {
317
+ subject.argv(values)
318
+ }.to raise_error(ValidationError,"argument #{name} was given an invalid value (#{values.inspect}): cannot convert a Hash into a String (#{values[0].inspect})")
319
+ end
320
+
321
+ context "but #type is a Types::KeyValue object" do
322
+ let(:type) { Types::KeyValue.new }
323
+
324
+ it "must format each value using #type.format" do
325
+ expect(subject.argv(values)).to eq(
326
+ [
327
+ subject.type.format(values[0]),
328
+ subject.type.format(values[1])
329
+ ]
330
+ )
331
+ end
332
+
333
+ context "but one of the Hashes is empty" do
334
+ let(:values) do
335
+ [{"foo" => 1}, {}]
336
+ end
337
+
338
+ it do
339
+ expect {
340
+ subject.argv(values)
341
+ }.to raise_error(ValidationError,"argument #{name} was given an invalid value (#{values.inspect}): cannot be empty")
342
+ end
343
+ end
344
+ end
345
+ end
346
+
347
+ context "but it's empty" do
348
+ let(:value) { [] }
349
+
350
+ it do
351
+ expect {
352
+ subject.argv(value)
353
+ }.to raise_error(ValidationError,"argument #{name} was given an invalid value (#{value.inspect}): requires at least one value")
354
+ end
355
+ end
356
+ end
357
+ end
358
+ end
359
+
360
+ context "and it's only given one value" do
361
+ context "and it's a String" do
362
+ let(:value) { "foo" }
363
+
364
+ it "must return an argv only containing the value" do
365
+ expect(subject.argv(value)).to eq([value])
366
+ end
367
+
368
+ context "but the String is invalid" do
369
+ let(:value) { " " }
370
+
371
+ it do
372
+ expect {
373
+ subject.argv(value)
374
+ }.to raise_error(ValidationError,"argument #{name} was given an invalid value (#{value.inspect}): does not allow a blank value (#{value.inspect})")
375
+ end
376
+ end
377
+ end
378
+
379
+ context "and it's a Hash" do
380
+ let(:value) do
381
+ {"foo" => "bar"}
382
+ end
383
+
384
+ context "but #type is a Types::KeyValue object" do
385
+ let(:type) { Types::KeyValue.new }
386
+
387
+ it "must format the value using #type.format" do
388
+ expect(subject.argv(value)).to eq(
389
+ [subject.type.format(value)]
390
+ )
391
+ end
392
+
393
+ context "but it's empty" do
394
+ let(:value) { {} }
395
+
396
+ it do
397
+ expect {
398
+ subject.argv(value)
399
+ }.to raise_error(ValidationError,"argument #{name} was given an invalid value (#{value.inspect}): cannot be empty")
400
+ end
401
+ end
402
+ end
403
+ end
404
+ end
405
+ end
406
+
407
+ context "when the argument can only be specified once" do
408
+ let(:repeats) { false }
409
+
410
+ context "and it's a String" do
411
+ let(:value) { "foo" }
412
+
413
+ it "must return an argv only containing the value" do
414
+ expect(subject.argv(value)).to eq([value])
415
+ end
416
+ end
417
+
418
+ context "and it's an Array" do
419
+ let(:value) { %w[foo bar baz] }
420
+
421
+ it do
422
+ expect {
423
+ subject.argv(value)
424
+ }.to raise_error(ValidationError,"argument #{name} was given an invalid value (#{value.inspect}): cannot convert a Array into a String (#{value.inspect})")
425
+ end
426
+
427
+ context "but #type is a Types::List object" do
428
+ let(:type) { Types::List.new }
429
+
430
+ it "must format the value using #type.format" do
431
+ expect(subject.argv(value)).to eq(
432
+ [subject.type.format(value)]
433
+ )
434
+ end
435
+
436
+ context "but one of the Array elements is nil" do
437
+ let(:value) { [1,2,nil,4] }
438
+
439
+ it do
440
+ expect {
441
+ subject.argv(value)
442
+ }.to raise_error(ValidationError,"argument #{name} was given an invalid value (#{value.inspect}): element cannot be nil")
443
+ end
444
+ end
445
+
446
+ context "but one of the Array's elements is invalid" do
447
+ let(:value) { ["foo", " ", "baz"] }
448
+ let(:message) { "does not allow a blank value" }
449
+
450
+ it do
451
+ expect {
452
+ subject.argv(value)
453
+ }.to raise_error(ValidationError,"argument #{name} was given an invalid value (#{value.inspect}): element does not allow a blank value (#{value[1].inspect})")
454
+ end
455
+ end
456
+
457
+ context "but it's empty" do
458
+ let(:value) { [] }
459
+
460
+ it do
461
+ expect {
462
+ subject.argv(value)
463
+ }.to raise_error(ValidationError,"argument #{name} was given an invalid value (#{value.inspect}): cannot be empty")
464
+ end
465
+ end
466
+ end
467
+ end
468
+
469
+ context "and it's a Hash" do
470
+ let(:value) do
471
+ {"foo" => "bar"}
472
+ end
473
+
474
+ it do
475
+ expect {
476
+ subject.argv(value)
477
+ }.to raise_error(ValidationError,"argument #{name} was given an invalid value (#{value.inspect}): cannot convert a Hash into a String (#{value.inspect})")
478
+ end
479
+
480
+ context "but #type is a Types::KeyValue object" do
481
+ let(:type) { Types::KeyValue.new }
482
+
483
+ it "must format the value using #type.format" do
484
+ expect(subject.argv(value)).to eq(
485
+ [subject.type.format(value)]
486
+ )
487
+ end
488
+
489
+ context "but it's empty" do
490
+ let(:value) { {} }
491
+
492
+ it do
493
+ expect {
494
+ subject.argv(value)
495
+ }.to raise_error(ValidationError,"argument #{name} was given an invalid value (#{value.inspect}): cannot be empty")
496
+ end
497
+ end
498
+ end
499
+ end
500
+
501
+ context "when given an argv array and a value" do
502
+ let(:value) { "foo" }
503
+
504
+ let(:argv) { [] }
505
+
506
+ before { subject.argv(argv,value) }
507
+
508
+ it "must concat the args to the argv array" do
509
+ expect(argv).to eq([value])
510
+ end
511
+ end
512
+ end
513
+ end