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.
@@ -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