optix 1.0.1
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.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +25 -0
- data/README.md +431 -0
- data/Rakefile +30 -0
- data/examples/filetool.rb +188 -0
- data/examples/printer.rb +43 -0
- data/lib/optix/trollop.rb +814 -0
- data/lib/optix/version.rb +3 -0
- data/lib/optix.rb +276 -0
- data/optix.gemspec +20 -0
- data/spec/optix_spec.rb +988 -0
- data/spec/spec_helper.rb +30 -0
- metadata +83 -0
data/spec/optix_spec.rb
ADDED
@@ -0,0 +1,988 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'optix'
|
3
|
+
|
4
|
+
describe Optix do
|
5
|
+
describe "with fresh context" do
|
6
|
+
before :each do
|
7
|
+
$n ||= 0
|
8
|
+
$n += 1
|
9
|
+
@context = "test#{$n}"
|
10
|
+
end
|
11
|
+
|
12
|
+
after :each do
|
13
|
+
Optix::reset!
|
14
|
+
end
|
15
|
+
|
16
|
+
it "raises ArgumentError on invalid option type" do
|
17
|
+
Optix::command('', @context) do
|
18
|
+
opt :a, '', :type => :frobnitz
|
19
|
+
end
|
20
|
+
lambda {
|
21
|
+
Optix.invoke!([], @context)
|
22
|
+
}.should raise_error(ArgumentError, "unsupported argument type 'frobnitz'")
|
23
|
+
end
|
24
|
+
|
25
|
+
it "raises RuntimeError on non existing command" do
|
26
|
+
Optix::command('', @context) do
|
27
|
+
non_existing_command
|
28
|
+
end
|
29
|
+
lambda {
|
30
|
+
Optix.invoke!([], @context)
|
31
|
+
}.should raise_error(RuntimeError, "Unknown Optix command: 'non_existing_command'")
|
32
|
+
end
|
33
|
+
|
34
|
+
it "prints basic help screen" do
|
35
|
+
Optix::command('', @context) do
|
36
|
+
opt :test
|
37
|
+
end
|
38
|
+
|
39
|
+
argv = ['--help']
|
40
|
+
|
41
|
+
out = capture_streams do
|
42
|
+
lambda {
|
43
|
+
Optix.invoke!(argv, @context)
|
44
|
+
}.should raise_error(SystemExit)
|
45
|
+
end
|
46
|
+
out[:stdout].should match /^Usage: /
|
47
|
+
out[:stdout].should match /^ --help, -h/
|
48
|
+
out[:stdout].should match /^ --test, -t/
|
49
|
+
end
|
50
|
+
|
51
|
+
it "prints complex help screen" do
|
52
|
+
Optix::command('', @context) do
|
53
|
+
opt :test, "Description", :long => 'longtest', :short => 'x', :type => :int, :default => 5, :required => true
|
54
|
+
end
|
55
|
+
|
56
|
+
argv = ['--help']
|
57
|
+
|
58
|
+
out = capture_streams do
|
59
|
+
lambda {
|
60
|
+
Optix.invoke!(argv, @context)
|
61
|
+
}.should raise_error(SystemExit)
|
62
|
+
end
|
63
|
+
out[:stdout].should match /^Usage: /
|
64
|
+
out[:stdout].should match /--help, -h/
|
65
|
+
out[:stdout].should match /^ --longtest, -x <i>: Description \(default: 5\)/
|
66
|
+
end
|
67
|
+
|
68
|
+
it "prints correct help for all known Symbol opt-types" do
|
69
|
+
Optix::command('', @context) do
|
70
|
+
opt :a, '', :type => :boolean
|
71
|
+
opt :b, '', :type => :integer
|
72
|
+
opt :c, '', :type => :integers
|
73
|
+
opt :d, '', :type => :double
|
74
|
+
opt :e, '', :type => :doubles
|
75
|
+
opt :f, '', :type => :string
|
76
|
+
end
|
77
|
+
|
78
|
+
argv = ['--help']
|
79
|
+
|
80
|
+
out = capture_streams do
|
81
|
+
lambda {
|
82
|
+
Optix.invoke!(argv, @context)
|
83
|
+
}.should raise_error(SystemExit)
|
84
|
+
end
|
85
|
+
out[:stdout].should match /^Usage: /
|
86
|
+
out[:stdout].should match /--help, -h/
|
87
|
+
out[:stdout].should match /--a, -a:/
|
88
|
+
out[:stdout].should match /--b, -b <i>:/
|
89
|
+
out[:stdout].should match /--c, -c <i\+>:/
|
90
|
+
out[:stdout].should match /--d, -d <f>:/
|
91
|
+
out[:stdout].should match /--e, -e <f\+>:/
|
92
|
+
out[:stdout].should match /--f, -f <s>:/
|
93
|
+
end
|
94
|
+
|
95
|
+
it "prints correct help for all known Class opt-types" do
|
96
|
+
Optix::command('', @context) do
|
97
|
+
opt :a, '', :type => TrueClass
|
98
|
+
opt :b, '', :type => Integer
|
99
|
+
opt :c, '', :type => Float
|
100
|
+
opt :d, '', :type => IO
|
101
|
+
opt :e, '', :type => Date
|
102
|
+
opt :f, '', :type => String
|
103
|
+
end
|
104
|
+
|
105
|
+
argv = ['--help']
|
106
|
+
|
107
|
+
out = capture_streams do
|
108
|
+
lambda {
|
109
|
+
Optix.invoke!(argv, @context)
|
110
|
+
}.should raise_error(SystemExit)
|
111
|
+
end
|
112
|
+
out[:stdout].should match /^Usage: /
|
113
|
+
out[:stdout].should match /--help, -h/
|
114
|
+
out[:stdout].should match /--a, -a:/
|
115
|
+
out[:stdout].should match /--b, -b <i>:/
|
116
|
+
out[:stdout].should match /--c, -c <f>:/
|
117
|
+
out[:stdout].should match /--d, -d <filename\/uri>:/
|
118
|
+
out[:stdout].should match /--e, -e <date>:/
|
119
|
+
out[:stdout].should match /--f, -f <s>:/
|
120
|
+
end
|
121
|
+
|
122
|
+
it "infers correct type from default for all known opt-types" do
|
123
|
+
Optix::command('', @context) do
|
124
|
+
opt :a, '', :default => true
|
125
|
+
opt :b, '', :default => 1
|
126
|
+
opt :c, '', :default => 1.0
|
127
|
+
opt :d, '', :default => File.new('/tmp')
|
128
|
+
opt :e, '', :default => Date.new
|
129
|
+
opt :f, '', :default => "foo"
|
130
|
+
end
|
131
|
+
|
132
|
+
argv = ['--help']
|
133
|
+
|
134
|
+
out = capture_streams do
|
135
|
+
lambda {
|
136
|
+
Optix.invoke!(argv, @context)
|
137
|
+
}.should raise_error(SystemExit)
|
138
|
+
end
|
139
|
+
out[:stdout].should match /^Usage: /
|
140
|
+
out[:stdout].should match /--help, -h/
|
141
|
+
out[:stdout].should match /--no-a, -a:/
|
142
|
+
out[:stdout].should match /--b, -b <i>:/
|
143
|
+
out[:stdout].should match /--c, -c <f>:/
|
144
|
+
out[:stdout].should match /--d, -d <filename\/uri>:/
|
145
|
+
out[:stdout].should match /--e, -e <date>:/
|
146
|
+
out[:stdout].should match /--f, -f <s>:/
|
147
|
+
end
|
148
|
+
|
149
|
+
it "infers correct type from Array-default for all known opt-types" do
|
150
|
+
Optix::command('', @context) do
|
151
|
+
opt :b, '', :default => [1]
|
152
|
+
opt :c, '', :default => [1.0]
|
153
|
+
opt :d, '', :default => [File.new('/tmp')]
|
154
|
+
opt :e, '', :default => [Date.new]
|
155
|
+
opt :f, '', :default => ["foo"]
|
156
|
+
end
|
157
|
+
|
158
|
+
argv = ['--help']
|
159
|
+
|
160
|
+
out = capture_streams do
|
161
|
+
lambda {
|
162
|
+
Optix.invoke!(argv, @context)
|
163
|
+
}.should raise_error(SystemExit)
|
164
|
+
end
|
165
|
+
out[:stdout].should match /^Usage: /
|
166
|
+
out[:stdout].should match /--help, -h/
|
167
|
+
out[:stdout].should match /--b, -b <i\+>:/
|
168
|
+
out[:stdout].should match /--c, -c <f\+>:/
|
169
|
+
out[:stdout].should match /--d, -d <filename\/uri\+>:/
|
170
|
+
out[:stdout].should match /--e, -e <date\+>:/
|
171
|
+
out[:stdout].should match /--f, -f <s\+>:/
|
172
|
+
end
|
173
|
+
|
174
|
+
it "prints correct help screen for composed command" do
|
175
|
+
Optix::command('', @context) do
|
176
|
+
opt :foo
|
177
|
+
end
|
178
|
+
|
179
|
+
Optix::command('', @context) do
|
180
|
+
opt :bar
|
181
|
+
end
|
182
|
+
|
183
|
+
argv = ['--help']
|
184
|
+
|
185
|
+
out = capture_streams do
|
186
|
+
lambda {
|
187
|
+
Optix.invoke!(argv, @context)
|
188
|
+
}.should raise_error(SystemExit)
|
189
|
+
end
|
190
|
+
out[:stdout].should match /^Usage: /
|
191
|
+
out[:stdout].should match /--foo, -f/
|
192
|
+
out[:stdout].should match /--bar, -b/
|
193
|
+
end
|
194
|
+
|
195
|
+
|
196
|
+
it "raises ArgumentError for unsupported argument type" do
|
197
|
+
Optix::command('', @context) do
|
198
|
+
opt :a, '', :default => Class
|
199
|
+
end
|
200
|
+
|
201
|
+
argv = ['--help']
|
202
|
+
|
203
|
+
out = capture_streams do
|
204
|
+
lambda {
|
205
|
+
Optix.invoke!(argv, @context)
|
206
|
+
}.should raise_error(ArgumentError, "unsupported argument type 'Class'")
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
it "raises ArgumentError for unsupported multi-argument type" do
|
211
|
+
Optix::command('', @context) do
|
212
|
+
opt :a, '', :default => [true]
|
213
|
+
end
|
214
|
+
|
215
|
+
argv = ['--help']
|
216
|
+
|
217
|
+
out = capture_streams do
|
218
|
+
lambda {
|
219
|
+
Optix.invoke!(argv, @context)
|
220
|
+
}.should raise_error(ArgumentError, "unsupported multiple argument type 'TrueClass'")
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
it "raises ArgumentError for opt with no type and empty array default" do
|
225
|
+
Optix::command('', @context) do
|
226
|
+
opt :a, '', :default => []
|
227
|
+
end
|
228
|
+
|
229
|
+
argv = ['--help']
|
230
|
+
|
231
|
+
out = capture_streams do
|
232
|
+
lambda {
|
233
|
+
Optix.invoke!(argv, @context)
|
234
|
+
}.should raise_error(ArgumentError, "multiple argument type cannot be deduced from an empty array for 'NilClass'")
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
it "raises ArgumentError for opt with no type and unknown type array default" do
|
239
|
+
Optix::command('', @context) do
|
240
|
+
opt :a, '', :default => [Class]
|
241
|
+
end
|
242
|
+
|
243
|
+
argv = ['--help']
|
244
|
+
|
245
|
+
out = capture_streams do
|
246
|
+
lambda {
|
247
|
+
Optix.invoke!(argv, @context)
|
248
|
+
}.should raise_error(ArgumentError, "unsupported multiple argument type 'Class'")
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
it "raises ArgumentError for unknown opt-type (Symbol)" do
|
253
|
+
Optix::command('', @context) do
|
254
|
+
opt :a, '', :type => :foobar
|
255
|
+
end
|
256
|
+
|
257
|
+
argv = ['--help']
|
258
|
+
|
259
|
+
out = capture_streams do
|
260
|
+
lambda {
|
261
|
+
Optix.invoke!(argv, @context)
|
262
|
+
}.should raise_error(ArgumentError, "unsupported argument type 'foobar'")
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
it "raises ArgumentError for unknown opt-type (Class)" do
|
267
|
+
Optix::command('', @context) do
|
268
|
+
opt :a, '', :type => Time
|
269
|
+
end
|
270
|
+
|
271
|
+
argv = ['--help']
|
272
|
+
|
273
|
+
out = capture_streams do
|
274
|
+
lambda {
|
275
|
+
Optix.invoke!(argv, @context)
|
276
|
+
}.should raise_error(ArgumentError, "unsupported argument type 'Class'")
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
it "disambiguates :multi with Array-default" do
|
281
|
+
Optix::command('', @context) do
|
282
|
+
opt :a, '', :multi => true, :default => [1,2]
|
283
|
+
end
|
284
|
+
|
285
|
+
argv = ['--help']
|
286
|
+
|
287
|
+
out = capture_streams do
|
288
|
+
lambda {
|
289
|
+
Optix.invoke!(argv, @context)
|
290
|
+
}.should raise_error(SystemExit)
|
291
|
+
end
|
292
|
+
#out[:stdout].should match /--a, -a <i\+>: \(default: 1, 2\)/
|
293
|
+
out[:stdout].should match /--a, -a <i>: \(default: 1, 2\)/
|
294
|
+
end
|
295
|
+
|
296
|
+
it "raises ArgumentError on invalid long option name" do
|
297
|
+
Optix::command('', @context) do
|
298
|
+
opt :a, '', :long => '-orr'
|
299
|
+
end
|
300
|
+
|
301
|
+
argv = ['--help']
|
302
|
+
|
303
|
+
out = capture_streams do
|
304
|
+
lambda {
|
305
|
+
Optix.invoke!(argv, @context)
|
306
|
+
}.should raise_error(ArgumentError, 'invalid long option name "-orr"')
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
it "raises ArgumentError on invalid short option name" do
|
311
|
+
Optix::command('', @context) do
|
312
|
+
opt :a, '', :short => '--orr'
|
313
|
+
end
|
314
|
+
|
315
|
+
argv = ['--help']
|
316
|
+
|
317
|
+
out = capture_streams do
|
318
|
+
lambda {
|
319
|
+
Optix.invoke!(argv, @context)
|
320
|
+
}.should raise_error(ArgumentError, 'invalid short option name \'"--orr"\'')
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
|
325
|
+
it "prepends/removes dashes on long-option as needed" do
|
326
|
+
Optix::command('', @context) do
|
327
|
+
opt :a, '', :long => 'orr'
|
328
|
+
opt :b, '', :long => '--urr'
|
329
|
+
end
|
330
|
+
|
331
|
+
argv = ['--help']
|
332
|
+
|
333
|
+
out = capture_streams do
|
334
|
+
lambda {
|
335
|
+
Optix.invoke!(argv, @context)
|
336
|
+
}.should raise_error(SystemExit)
|
337
|
+
end
|
338
|
+
out[:stdout].should match /^Usage: /
|
339
|
+
out[:stdout].should match /--orr, -o/
|
340
|
+
out[:stdout].should match /--urr, -u/
|
341
|
+
end
|
342
|
+
|
343
|
+
it "prepends/removes dash on short-option as needed" do
|
344
|
+
Optix::command('', @context) do
|
345
|
+
opt :a, '', :short => 'o'
|
346
|
+
opt :b, '', :short => '-u'
|
347
|
+
end
|
348
|
+
|
349
|
+
argv = ['--help']
|
350
|
+
|
351
|
+
out = capture_streams do
|
352
|
+
lambda {
|
353
|
+
Optix.invoke!(argv, @context)
|
354
|
+
}.should raise_error(SystemExit)
|
355
|
+
end
|
356
|
+
out[:stdout].should match /^Usage: /
|
357
|
+
out[:stdout].should match /-o/
|
358
|
+
out[:stdout].should match /-u/
|
359
|
+
end
|
360
|
+
|
361
|
+
it "raises ArgumentError on dependency towards non-existing option" do
|
362
|
+
Optix::command('', @context) do
|
363
|
+
opt :a, ''
|
364
|
+
depends :a, :b
|
365
|
+
end
|
366
|
+
|
367
|
+
argv = ['--help']
|
368
|
+
|
369
|
+
lambda {
|
370
|
+
Optix.invoke!(argv, @context)
|
371
|
+
}.should raise_error(ArgumentError, "unknown option 'b'")
|
372
|
+
end
|
373
|
+
|
374
|
+
it "enforces option inter-dependency (or displays error)" do
|
375
|
+
Optix::command('', @context) do
|
376
|
+
opt :a, ''
|
377
|
+
opt :b, ''
|
378
|
+
depends :a, :b
|
379
|
+
end
|
380
|
+
|
381
|
+
argv = ['-a']
|
382
|
+
|
383
|
+
out = capture_streams do
|
384
|
+
lambda {
|
385
|
+
Optix.invoke!(argv, @context)
|
386
|
+
}.should raise_error(SystemExit)
|
387
|
+
end
|
388
|
+
out[:stderr].should match /Error: --a requires --b/
|
389
|
+
end
|
390
|
+
|
391
|
+
it "raises ArgumentError on conflicts-declaration towards non-existing option" do
|
392
|
+
Optix::command('', @context) do
|
393
|
+
opt :a, ''
|
394
|
+
conflicts :a, :b
|
395
|
+
end
|
396
|
+
|
397
|
+
argv = ['--help']
|
398
|
+
|
399
|
+
lambda {
|
400
|
+
Optix.invoke!(argv, @context)
|
401
|
+
}.should raise_error(ArgumentError, "unknown option 'b'")
|
402
|
+
end
|
403
|
+
|
404
|
+
it "displays error upon option conflict" do
|
405
|
+
Optix::command('', @context) do
|
406
|
+
opt :a, ''
|
407
|
+
opt :b, ''
|
408
|
+
conflicts :a, :b
|
409
|
+
end
|
410
|
+
|
411
|
+
argv = ['-a', '-b']
|
412
|
+
|
413
|
+
out = capture_streams do
|
414
|
+
lambda {
|
415
|
+
Optix.invoke!(argv, @context)
|
416
|
+
}.should raise_error(SystemExit)
|
417
|
+
end
|
418
|
+
out[:stderr].should match /Error: --a conflicts with --b/
|
419
|
+
end
|
420
|
+
|
421
|
+
it "displays error on invalid argv syntax (triple-dash)" do
|
422
|
+
Optix::command('', @context) do
|
423
|
+
opt :a, ''
|
424
|
+
opt :b, ''
|
425
|
+
end
|
426
|
+
|
427
|
+
argv = ['---a']
|
428
|
+
|
429
|
+
out = capture_streams do
|
430
|
+
lambda {
|
431
|
+
Optix.invoke!(argv, @context)
|
432
|
+
}.should raise_error(SystemExit)
|
433
|
+
end
|
434
|
+
out[:stderr].should match /Error: invalid argument syntax: '---a'/
|
435
|
+
end
|
436
|
+
|
437
|
+
it "displays error on duplicate argv" do
|
438
|
+
Optix::command('', @context) do
|
439
|
+
opt :a, ''
|
440
|
+
opt :b, ''
|
441
|
+
end
|
442
|
+
|
443
|
+
argv = ['-a', '-a']
|
444
|
+
|
445
|
+
out = capture_streams do
|
446
|
+
lambda {
|
447
|
+
Optix.invoke!(argv, @context)
|
448
|
+
}.should raise_error(SystemExit)
|
449
|
+
end
|
450
|
+
out[:stderr].should match /Error: option '-a' specified multiple times/
|
451
|
+
end
|
452
|
+
|
453
|
+
it "displays :desc in help" do
|
454
|
+
Optix::command('', @context) do
|
455
|
+
end
|
456
|
+
|
457
|
+
Optix::command('sub', @context) do
|
458
|
+
desc "fancy subcommand"
|
459
|
+
end
|
460
|
+
|
461
|
+
argv = ['--help']
|
462
|
+
|
463
|
+
out = capture_streams do
|
464
|
+
lambda {
|
465
|
+
Optix.invoke!(argv, @context)
|
466
|
+
}.should raise_error(SystemExit)
|
467
|
+
end
|
468
|
+
out[:stdout].should match /^Usage: /
|
469
|
+
out[:stdout].should match /^ sub fancy subcommand/
|
470
|
+
end
|
471
|
+
|
472
|
+
it "displays :text in help" do
|
473
|
+
Optix::command('', @context) do
|
474
|
+
text "Verbose explanation"
|
475
|
+
end
|
476
|
+
|
477
|
+
Optix::command('sub', @context) do
|
478
|
+
end
|
479
|
+
|
480
|
+
argv = ['--help']
|
481
|
+
|
482
|
+
out = capture_streams do
|
483
|
+
lambda {
|
484
|
+
Optix.invoke!(argv, @context)
|
485
|
+
}.should raise_error(SystemExit)
|
486
|
+
end
|
487
|
+
out[:stdout].should match /^Usage: /
|
488
|
+
out[:stdout].should match /^Verbose explanation/
|
489
|
+
end
|
490
|
+
|
491
|
+
it "multiple :text are concatenated with newlines" do
|
492
|
+
Optix::command('', @context) do
|
493
|
+
text "Verbose explanation"
|
494
|
+
text "More text"
|
495
|
+
end
|
496
|
+
|
497
|
+
Optix::command('sub', @context) do
|
498
|
+
end
|
499
|
+
|
500
|
+
argv = ['--help']
|
501
|
+
|
502
|
+
out = capture_streams do
|
503
|
+
lambda {
|
504
|
+
Optix.invoke!(argv, @context)
|
505
|
+
}.should raise_error(SystemExit)
|
506
|
+
end
|
507
|
+
out[:stdout].should match /^Usage: /
|
508
|
+
out[:stdout].should match /^Verbose explanation\nMore text/
|
509
|
+
end
|
510
|
+
|
511
|
+
|
512
|
+
it "displays :params in help" do
|
513
|
+
Optix::command('', @context) do
|
514
|
+
params "<foo> [bar]"
|
515
|
+
end
|
516
|
+
|
517
|
+
argv = ['--help']
|
518
|
+
|
519
|
+
out = capture_streams do
|
520
|
+
lambda {
|
521
|
+
Optix.invoke!(argv, @context)
|
522
|
+
}.should raise_error(SystemExit)
|
523
|
+
end
|
524
|
+
out[:stdout].should match /^Usage: .*<foo> \[bar\]/
|
525
|
+
end
|
526
|
+
|
527
|
+
it "displays :params in help on subcommand" do
|
528
|
+
Optix::command('', @context) do
|
529
|
+
end
|
530
|
+
|
531
|
+
Optix::command('sub', @context) do
|
532
|
+
params "<foo> [bar]"
|
533
|
+
end
|
534
|
+
|
535
|
+
argv = ['sub', '--help']
|
536
|
+
|
537
|
+
out = capture_streams do
|
538
|
+
lambda {
|
539
|
+
Optix.invoke!(argv, @context)
|
540
|
+
}.should raise_error(SystemExit)
|
541
|
+
end
|
542
|
+
out[:stdout].should match /^Usage: .* sub <foo> \[bar\]/
|
543
|
+
end
|
544
|
+
|
545
|
+
#it "does not display :help-help when there is a subcommand" do
|
546
|
+
# Optix::command('', @context) do
|
547
|
+
# text "Verbose explanation"
|
548
|
+
# end
|
549
|
+
|
550
|
+
# Optix::command('sub', @context) do
|
551
|
+
# end
|
552
|
+
|
553
|
+
# argv = ['--help']
|
554
|
+
|
555
|
+
# out = capture_streams do
|
556
|
+
# lambda {
|
557
|
+
# Optix.invoke!(argv, @context)
|
558
|
+
# }.should raise_error(SystemExit)
|
559
|
+
# end
|
560
|
+
# out[:stdout].should match /^Usage: /
|
561
|
+
# out[:stdout].should_not match /--help, -h/
|
562
|
+
#end
|
563
|
+
|
564
|
+
#it "displays :help-help when there are no subcommands" do
|
565
|
+
# Optix::command('', @context) do
|
566
|
+
# text "Verbose explanation"
|
567
|
+
# end
|
568
|
+
|
569
|
+
# argv = ['--help']
|
570
|
+
|
571
|
+
# out = capture_streams do
|
572
|
+
# lambda {
|
573
|
+
# Optix.invoke!(argv, @context)
|
574
|
+
# }.should raise_error(SystemExit)
|
575
|
+
# end
|
576
|
+
# out[:stdout].should match /^Usage: /
|
577
|
+
# out[:stdout].should match /--help, -h/
|
578
|
+
#end
|
579
|
+
|
580
|
+
it "displays :help-help" do
|
581
|
+
Optix::command('', @context) do
|
582
|
+
text "Verbose explanation"
|
583
|
+
end
|
584
|
+
|
585
|
+
argv = ['--help']
|
586
|
+
|
587
|
+
out = capture_streams do
|
588
|
+
lambda {
|
589
|
+
Optix.invoke!(argv, @context)
|
590
|
+
}.should raise_error(SystemExit)
|
591
|
+
end
|
592
|
+
out[:stdout].should match /^Usage: /
|
593
|
+
out[:stdout].should match /--help, -h/
|
594
|
+
end
|
595
|
+
|
596
|
+
it "raises RuntimeError on missing exec{} block" do
|
597
|
+
Optix::command('', @context) do
|
598
|
+
end
|
599
|
+
|
600
|
+
argv = []
|
601
|
+
out = capture_streams do
|
602
|
+
lambda {
|
603
|
+
Optix.invoke!(argv, @context)
|
604
|
+
}.should raise_error(RuntimeError, "Command '' has no exec{}-block!")
|
605
|
+
end
|
606
|
+
end
|
607
|
+
|
608
|
+
it "raises RuntimeError on missing exec{} block (for subcommand)" do
|
609
|
+
Optix::command('', @context) do
|
610
|
+
end
|
611
|
+
|
612
|
+
Optix::command('sub', @context) do
|
613
|
+
end
|
614
|
+
|
615
|
+
argv = ['sub']
|
616
|
+
out = capture_streams do
|
617
|
+
lambda {
|
618
|
+
Optix.invoke!(argv, @context)
|
619
|
+
}.should raise_error(RuntimeError, "Command 'sub' has no exec{}-block!")
|
620
|
+
end
|
621
|
+
end
|
622
|
+
|
623
|
+
it "runs the exec{}-block" do
|
624
|
+
dummy = double("exec{}")
|
625
|
+
dummy.should_receive(:call).once.with([], {:help=>false}, [])
|
626
|
+
|
627
|
+
Optix::command('', @context) do
|
628
|
+
exec do |cmd,args,argv|
|
629
|
+
dummy.call(cmd, args, argv)
|
630
|
+
end
|
631
|
+
end
|
632
|
+
|
633
|
+
argv = []
|
634
|
+
Optix.invoke!(argv, @context)
|
635
|
+
end
|
636
|
+
|
637
|
+
it "runs the exec{}-block (on subcommand)" do
|
638
|
+
Optix::command('', @context) do
|
639
|
+
end
|
640
|
+
|
641
|
+
dummy = double("exec{}")
|
642
|
+
dummy.should_receive(:call).once.with(['sub'], {:help=>false}, [])
|
643
|
+
|
644
|
+
Optix::command('sub', @context) do
|
645
|
+
exec do |cmd,args,argv|
|
646
|
+
dummy.call(cmd, args, argv)
|
647
|
+
end
|
648
|
+
end
|
649
|
+
|
650
|
+
argv = ['sub']
|
651
|
+
Optix.invoke!(argv, @context)
|
652
|
+
end
|
653
|
+
|
654
|
+
it "fires :version-trigger when invoked with -v" do
|
655
|
+
exec_dummy = double('exec')
|
656
|
+
trigger_dummy = double('trigger')
|
657
|
+
trigger_dummy.should_receive(:call).once
|
658
|
+
Optix::command('', @context) do
|
659
|
+
opt :version, "Print version and exit"
|
660
|
+
trigger :version do
|
661
|
+
trigger_dummy.call(cmd, args, argv)
|
662
|
+
end
|
663
|
+
exec do |cmd,args,argv|
|
664
|
+
exec_dummy.call(cmd, args, argv)
|
665
|
+
end
|
666
|
+
end
|
667
|
+
|
668
|
+
argv = ['-v']
|
669
|
+
Optix.invoke!(argv, @context)
|
670
|
+
end
|
671
|
+
|
672
|
+
it "fires :version-trigger when invoked with --version" do
|
673
|
+
exec_dummy = double('exec')
|
674
|
+
trigger_dummy = double('trigger')
|
675
|
+
trigger_dummy.should_receive(:call).once
|
676
|
+
Optix::command('', @context) do
|
677
|
+
opt :version, "Print version and exit"
|
678
|
+
trigger :version do
|
679
|
+
trigger_dummy.call(cmd, args, argv)
|
680
|
+
end
|
681
|
+
exec do |cmd,args,argv|
|
682
|
+
exec_dummy.call(cmd, args, argv)
|
683
|
+
end
|
684
|
+
end
|
685
|
+
|
686
|
+
argv = ['--version']
|
687
|
+
Optix.invoke!(argv, @context)
|
688
|
+
end
|
689
|
+
|
690
|
+
it "fires [:version,:foobar]-trigger when invoked with --version" do
|
691
|
+
exec_dummy = double('exec')
|
692
|
+
trigger_dummy = double('trigger')
|
693
|
+
trigger_dummy.should_receive(:call).once
|
694
|
+
Optix::command('', @context) do
|
695
|
+
opt :version, "Print version and exit"
|
696
|
+
trigger [:version, :foobar] do
|
697
|
+
trigger_dummy.call(cmd, args, argv)
|
698
|
+
end
|
699
|
+
exec do |cmd,args,argv|
|
700
|
+
exec_dummy.call(cmd, args, argv)
|
701
|
+
end
|
702
|
+
end
|
703
|
+
|
704
|
+
argv = ['--version']
|
705
|
+
Optix.invoke!(argv, @context)
|
706
|
+
end
|
707
|
+
|
708
|
+
it "runs the filter{}-block on command path" do
|
709
|
+
filter_root = double()
|
710
|
+
filter_root.should_receive(:call).once.with(['a','b'], {:help=>false}, [])
|
711
|
+
exec_root = double()
|
712
|
+
Optix::command('', @context) do
|
713
|
+
filter do |cmd,args,argv|
|
714
|
+
filter_root.call(cmd, args, argv)
|
715
|
+
end
|
716
|
+
exec do |cmd,args,argv|
|
717
|
+
exec_root.call(cmd, args, argv)
|
718
|
+
end
|
719
|
+
end
|
720
|
+
|
721
|
+
filter_a = double()
|
722
|
+
filter_a.should_receive(:call).once.with(['a', 'b'], {:help=>false}, [])
|
723
|
+
filter_a2 = double()
|
724
|
+
filter_a2.should_receive(:call).once.with(['a', 'b'], {:help=>false}, [])
|
725
|
+
exec_a = double()
|
726
|
+
Optix::command('a', @context) do
|
727
|
+
filter do |cmd,args,argv|
|
728
|
+
filter_a.call(cmd, args, argv)
|
729
|
+
end
|
730
|
+
filter do |cmd,args,argv|
|
731
|
+
filter_a2.call(cmd, args, argv)
|
732
|
+
end
|
733
|
+
exec do |cmd,args,argv|
|
734
|
+
exec_a.call(cmd, args, argv)
|
735
|
+
end
|
736
|
+
end
|
737
|
+
|
738
|
+
filter_a_b = double()
|
739
|
+
exec_a_b = double()
|
740
|
+
exec_a_b.should_receive(:call).once.with(['a','b'], {:help=>false}, [])
|
741
|
+
Optix::command('a b', @context) do
|
742
|
+
exec do |cmd,args,argv|
|
743
|
+
exec_a_b.call(cmd, args, argv)
|
744
|
+
end
|
745
|
+
end
|
746
|
+
|
747
|
+
argv = ['a', 'b']
|
748
|
+
Optix.invoke!(argv, @context)
|
749
|
+
end
|
750
|
+
|
751
|
+
it "shows help-screen when HelpNeeded is raised in filter{}" do
|
752
|
+
exec_root = double()
|
753
|
+
Optix::command('', @context) do
|
754
|
+
filter do |cmd,args,argv|
|
755
|
+
raise Optix::HelpNeeded
|
756
|
+
end
|
757
|
+
exec do |cmd,args,argv|
|
758
|
+
exec_root.call(cmd, args, argv)
|
759
|
+
end
|
760
|
+
end
|
761
|
+
argv = []
|
762
|
+
out = capture_streams do
|
763
|
+
lambda {
|
764
|
+
Optix.invoke!(argv, @context)
|
765
|
+
}.should raise_error(SystemExit)
|
766
|
+
end
|
767
|
+
out[:stdout].should match /^Usage: /
|
768
|
+
out[:stdout].should match /--help, -h/
|
769
|
+
end
|
770
|
+
|
771
|
+
it "exec{} receives remaining argv" do
|
772
|
+
Optix::command('', @context) do
|
773
|
+
end
|
774
|
+
|
775
|
+
dummy = double("exec{}")
|
776
|
+
dummy.should_receive(:call).once.with(['sub'], {:help=>false}, ['foo', 'bar'])
|
777
|
+
|
778
|
+
Optix::command('sub', @context) do
|
779
|
+
exec do |cmd,args,argv|
|
780
|
+
dummy.call(cmd, args, argv)
|
781
|
+
end
|
782
|
+
end
|
783
|
+
|
784
|
+
argv = ['sub', 'foo', 'bar']
|
785
|
+
Optix.invoke!(argv, @context)
|
786
|
+
end
|
787
|
+
|
788
|
+
describe "Configurator" do
|
789
|
+
it "raises ArgumentError on unknown configuration key" do
|
790
|
+
lambda {
|
791
|
+
Optix::configure do
|
792
|
+
unknown_key
|
793
|
+
end
|
794
|
+
}.should raise_error(ArgumentError, "Unknown configuration key 'unknown_key'")
|
795
|
+
end
|
796
|
+
|
797
|
+
it "honors text_header_usage" do
|
798
|
+
Optix::configure do
|
799
|
+
text_header_usage 'Ouzo: %0 %subcommands %params'
|
800
|
+
end
|
801
|
+
|
802
|
+
Optix::command('', @context) do
|
803
|
+
opt :test
|
804
|
+
end
|
805
|
+
|
806
|
+
argv = ['--help']
|
807
|
+
|
808
|
+
out = capture_streams do
|
809
|
+
lambda {
|
810
|
+
Optix.invoke!(argv, @context)
|
811
|
+
}.should raise_error(SystemExit)
|
812
|
+
end
|
813
|
+
out[:stdout].should match /^Ouzo: /
|
814
|
+
out[:stdout].should match /--help, -h/
|
815
|
+
out[:stdout].should match /^ --test, -t/
|
816
|
+
end
|
817
|
+
|
818
|
+
it "honors text_required" do
|
819
|
+
Optix::configure do
|
820
|
+
text_required ' (mandatory)'
|
821
|
+
end
|
822
|
+
|
823
|
+
Optix::command('', @context) do
|
824
|
+
opt :test, "testing", :required => true
|
825
|
+
end
|
826
|
+
|
827
|
+
argv = ['--help']
|
828
|
+
|
829
|
+
out = capture_streams do
|
830
|
+
lambda {
|
831
|
+
Optix.invoke!(argv, @context)
|
832
|
+
}.should raise_error(SystemExit)
|
833
|
+
end
|
834
|
+
out[:stdout].should match /^ --test, -t: testing \(mandatory\)/
|
835
|
+
out[:stdout].should match /--help, -h/
|
836
|
+
end
|
837
|
+
|
838
|
+
it "honors text_help" do
|
839
|
+
Optix::configure do
|
840
|
+
text_help 'HALP!'
|
841
|
+
end
|
842
|
+
|
843
|
+
Optix::command('', @context) do
|
844
|
+
opt :test, "testing"
|
845
|
+
end
|
846
|
+
|
847
|
+
argv = ['--help']
|
848
|
+
|
849
|
+
out = capture_streams do
|
850
|
+
lambda {
|
851
|
+
Optix.invoke!(argv, @context)
|
852
|
+
}.should raise_error(SystemExit)
|
853
|
+
end
|
854
|
+
out[:stdout].should match /--help, -h: HALP/
|
855
|
+
end
|
856
|
+
|
857
|
+
it "honors text_header_topcommands" do
|
858
|
+
Optix::configure do
|
859
|
+
text_header_topcommands 'TOPCMD'
|
860
|
+
end
|
861
|
+
|
862
|
+
Optix::command('', @context) do
|
863
|
+
opt :test, "testing"
|
864
|
+
end
|
865
|
+
|
866
|
+
Optix::command('sub', @context) do
|
867
|
+
opt :test, "testing"
|
868
|
+
end
|
869
|
+
|
870
|
+
argv = ['--help']
|
871
|
+
|
872
|
+
out = capture_streams do
|
873
|
+
lambda {
|
874
|
+
Optix.invoke!(argv, @context)
|
875
|
+
}.should raise_error(SystemExit)
|
876
|
+
end
|
877
|
+
out[:stdout].should match /^TOPCMD/
|
878
|
+
end
|
879
|
+
|
880
|
+
it "honors text_header_subcommands" do
|
881
|
+
Optix::configure do
|
882
|
+
text_header_subcommands 'SUBCMD'
|
883
|
+
end
|
884
|
+
|
885
|
+
Optix::command('', @context) do
|
886
|
+
opt :test, "testing"
|
887
|
+
end
|
888
|
+
|
889
|
+
Optix::command('sub', @context) do
|
890
|
+
end
|
891
|
+
|
892
|
+
Optix::command('sub sub', @context) do
|
893
|
+
end
|
894
|
+
|
895
|
+
argv = ['sub', '--help']
|
896
|
+
|
897
|
+
out = capture_streams do
|
898
|
+
lambda {
|
899
|
+
Optix.invoke!(argv, @context)
|
900
|
+
}.should raise_error(SystemExit)
|
901
|
+
end
|
902
|
+
out[:stdout].should match /^SUBCMD/
|
903
|
+
end
|
904
|
+
end
|
905
|
+
end
|
906
|
+
|
907
|
+
describe "with shared context" do
|
908
|
+
before :all do
|
909
|
+
@context = :shared1
|
910
|
+
end
|
911
|
+
it "raises ArgumentError on duplicate option" do
|
912
|
+
Optix::command('', @context) do
|
913
|
+
opt :a, ''
|
914
|
+
end
|
915
|
+
Optix::command('', @context) do
|
916
|
+
opt :a, ''
|
917
|
+
end
|
918
|
+
lambda {
|
919
|
+
Optix.invoke!([], @context)
|
920
|
+
}.should raise_error(ArgumentError, "you already have an argument named 'a'")
|
921
|
+
end
|
922
|
+
end
|
923
|
+
|
924
|
+
it "defaults to context :default" do
|
925
|
+
lambda {
|
926
|
+
Optix.invoke!([])
|
927
|
+
}.should raise_error(RuntimeError, "Scope 'default' is not defined")
|
928
|
+
end
|
929
|
+
|
930
|
+
it "raises RuntimeError on undefined context" do
|
931
|
+
lambda {
|
932
|
+
Optix.invoke!([], :i_dont_exist)
|
933
|
+
}.should raise_error(RuntimeError, "Scope 'i_dont_exist' is not defined")
|
934
|
+
end
|
935
|
+
|
936
|
+
describe "Examples" do
|
937
|
+
before :each do
|
938
|
+
Optix::reset!
|
939
|
+
end
|
940
|
+
|
941
|
+
describe "FileTool" do
|
942
|
+
before :each do
|
943
|
+
load 'examples/filetool.rb'
|
944
|
+
end
|
945
|
+
|
946
|
+
it "prints version when invoked with -v" do
|
947
|
+
argv = ['-v']
|
948
|
+
out = capture_streams do
|
949
|
+
#lambda {
|
950
|
+
Optix.invoke!(argv)
|
951
|
+
#}.should raise_error(SystemExit)
|
952
|
+
end
|
953
|
+
#out[:stdout].should match /^Version 1.0\n/
|
954
|
+
out[:stdout].should == "Version 1.0\n"
|
955
|
+
end
|
956
|
+
|
957
|
+
it "prints version when invoked with --version" do
|
958
|
+
argv = ['--version']
|
959
|
+
out = capture_streams do
|
960
|
+
#lambda {
|
961
|
+
Optix.invoke!(argv)
|
962
|
+
#}.should raise_error(SystemExit)
|
963
|
+
end
|
964
|
+
out[:stdout].should == "Version 1.0\n"
|
965
|
+
end
|
966
|
+
|
967
|
+
it "prints help when invoked with -h" do
|
968
|
+
argv = ['-h']
|
969
|
+
out = capture_streams do
|
970
|
+
lambda {
|
971
|
+
Optix.invoke!(argv)
|
972
|
+
}.should raise_error(SystemExit)
|
973
|
+
end
|
974
|
+
out[:stdout].should match /Commands:/
|
975
|
+
end
|
976
|
+
|
977
|
+
it "prints help when invoked without arguments" do
|
978
|
+
argv = []
|
979
|
+
out = capture_streams do
|
980
|
+
lambda {
|
981
|
+
Optix.invoke!(argv)
|
982
|
+
}.should raise_error(SystemExit)
|
983
|
+
end
|
984
|
+
out[:stdout].should match /Commands:/
|
985
|
+
end
|
986
|
+
end
|
987
|
+
end
|
988
|
+
end
|