optix 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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