command_mapper 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 +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