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.
- checksums.yaml +7 -0
- data/.github/workflows/ruby.yml +27 -0
- data/.gitignore +10 -0
- data/.rspec +1 -0
- data/.yardopts +1 -0
- data/ChangeLog.md +20 -0
- data/Gemfile +17 -0
- data/LICENSE.txt +20 -0
- data/README.md +145 -0
- data/Rakefile +15 -0
- data/bin/command_mapper-gen +7 -0
- data/commnad_mapper-gen.gemspec +61 -0
- data/examples/grep.rb +63 -0
- data/gemspec.yml +26 -0
- data/lib/command_mapper/gen/arg.rb +43 -0
- data/lib/command_mapper/gen/argument.rb +53 -0
- data/lib/command_mapper/gen/cli.rb +233 -0
- data/lib/command_mapper/gen/command.rb +202 -0
- data/lib/command_mapper/gen/exceptions.rb +9 -0
- data/lib/command_mapper/gen/option.rb +66 -0
- data/lib/command_mapper/gen/option_value.rb +23 -0
- data/lib/command_mapper/gen/parsers/common.rb +49 -0
- data/lib/command_mapper/gen/parsers/help.rb +351 -0
- data/lib/command_mapper/gen/parsers/man.rb +80 -0
- data/lib/command_mapper/gen/parsers/options.rb +127 -0
- data/lib/command_mapper/gen/parsers/usage.rb +141 -0
- data/lib/command_mapper/gen/parsers.rb +2 -0
- data/lib/command_mapper/gen/task.rb +90 -0
- data/lib/command_mapper/gen/types/enum.rb +30 -0
- data/lib/command_mapper/gen/types/key_value.rb +34 -0
- data/lib/command_mapper/gen/types/list.rb +34 -0
- data/lib/command_mapper/gen/types/map.rb +36 -0
- data/lib/command_mapper/gen/types/num.rb +18 -0
- data/lib/command_mapper/gen/types/str.rb +48 -0
- data/lib/command_mapper/gen/types.rb +6 -0
- data/lib/command_mapper/gen/version.rb +6 -0
- data/lib/command_mapper/gen.rb +2 -0
- data/spec/argument_spec.rb +92 -0
- data/spec/cli_spec.rb +269 -0
- data/spec/command_spec.rb +316 -0
- data/spec/option_spec.rb +85 -0
- data/spec/option_value_spec.rb +20 -0
- data/spec/parsers/common_spec.rb +616 -0
- data/spec/parsers/help_spec.rb +612 -0
- data/spec/parsers/man_spec.rb +158 -0
- data/spec/parsers/options_spec.rb +802 -0
- data/spec/parsers/usage_spec.rb +1175 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/task_spec.rb +69 -0
- data/spec/types/enum_spec.rb +45 -0
- data/spec/types/key_value_spec.rb +36 -0
- data/spec/types/list_spec.rb +36 -0
- data/spec/types/map_spec.rb +48 -0
- data/spec/types/str_spec.rb +70 -0
- 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
|