main 2.5.0 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,12 +1,3 @@
1
- class ::Logger
2
- def device
3
- @logdev.instance_eval{ @dev }
4
- end
5
- def tty?
6
- device.respond_to?('tty?') and device.tty?
7
- end
8
- end
9
-
10
1
  class Object
11
2
  def singleton_class object = self, &block
12
3
  sc =
@@ -15,4 +6,33 @@ class Object
15
6
  end
16
7
  block ? sc.module_eval(&block) : sc
17
8
  end
9
+
18
10
  end
11
+
12
+ module SaneAbort
13
+ def abort message = nil
14
+ if message
15
+ message = message.to_s
16
+ message.singleton_class{ attribute 'abort' => true }
17
+ STDERR.puts message
18
+ end
19
+ exit 1
20
+ end
21
+ end
22
+
23
+ def abort message = nil
24
+ if message
25
+ message = message.to_s
26
+ message.singleton_class{ attribute 'abort' => true }
27
+ STDERR.puts message
28
+ end
29
+ exit 1
30
+ end
31
+ def Process.abort message = nil
32
+ if message
33
+ message = message.to_s
34
+ message.singleton_class{ attribute 'abort' => true }
35
+ STDERR.puts message
36
+ end
37
+ exit 1
38
+ end
@@ -42,10 +42,25 @@ module Main
42
42
  # argument info
43
43
  main.parameters.each do |p|
44
44
  if p.type == :argument
45
- if p.required?
46
- s << " #{ p.name }"
45
+ if(p.required? and p.arity != -1)
46
+ if p.arity > 0
47
+ p.arity.times{ s << " #{ p.name }" }
48
+ else
49
+ (p.arity.abs - 1).times{ s << " #{ p.name }" }
50
+ s << " #{ p.name }*"
51
+ end
47
52
  else
48
- s << " [#{ p.name }]"
53
+ #s << " [#{ p.name }]"
54
+ if p.arity > 0
55
+ a = []
56
+ p.arity.times{ a << "#{ p.name }" }
57
+ s << " [#{ a.join ' ' }]"
58
+ else
59
+ a = []
60
+ (p.arity.abs - 1).times{ a << "#{ p.name }" }
61
+ a << "#{ p.name }*"
62
+ s << " [#{ a.join ' ' }]"
63
+ end
49
64
  end
50
65
  end
51
66
  end
@@ -99,24 +114,23 @@ module Main
99
114
  s
100
115
  end
101
116
 
102
- def self.default_usage main
103
- usage = new
104
-
105
- # name
106
- usage['name'] =
107
- if main.version?
108
- "#{ main.name } v#{ main.version }"
109
- else
110
- "#{ main.name }"
111
- end
117
+ def name_section
118
+ if main.version?
119
+ "#{ main.name } v#{ main.version }"
120
+ else
121
+ "#{ main.name }"
122
+ end
123
+ end
112
124
 
113
- # synopsis
114
- usage['synopsis'] = main.synopsis
125
+ def synopsis_section
126
+ main.synopsis
127
+ end
115
128
 
116
- # description
117
- usage['description'] = main.description if main.description?
129
+ def description_section
130
+ main.description if main.description?
131
+ end
118
132
 
119
- # parameters
133
+ def parameters_section
120
134
  arguments = main.parameters.select{|p| p.type == :argument}
121
135
  keywords = main.parameters.select{|p| p.type == :keyword}
122
136
  options = main.parameters.select{|p| p.type == :option}
@@ -140,22 +154,50 @@ module Main
140
154
  #ps << "\n"
141
155
  end
142
156
  #ps << "\n"
157
+ unless(p.examples.nil? or p.examples.empty?)
158
+ p.examples.each do |example|
159
+ ps << "\n"
160
+ ps << Util.columnize("#{ example }", :indent => 8, :width => 78)
161
+ end
162
+ end
143
163
  ps
144
164
  end.join("\n")
145
- usage['parameters'] = s
146
-
147
- # author
148
- usage['author'] = main.author if main.author?
165
+ end
149
166
 
150
- usage
167
+ def author_section
168
+ main.author
151
169
  end
170
+
152
171
  class << self
172
+ def default_usage main
173
+ usage = new
174
+ usage.main = main
175
+ # HACK
176
+ %w( name synopsis description parameters author ).each do |key|
177
+ usage[key] = nil
178
+ end
179
+ usage
180
+ end
181
+
153
182
  alias_method "default", "default_usage"
154
183
  end
155
184
 
185
+ attribute "main"
186
+
187
+ def set_defaults!
188
+ usage = self
189
+ usage['name'] ||= name_section
190
+ usage['synopsis'] ||= synopsis_section
191
+ usage['description'] ||= description_section
192
+ usage['parameters'] ||= parameters_section unless main.parameters.empty?
193
+ usage['author'] ||= author_section if main.author?
194
+ end
195
+
156
196
  def to_s
197
+ set_defaults!
157
198
  s = ''
158
199
  each_pair do |key, value|
200
+ next unless(key and value)
159
201
  up, down = key.to_s.upcase, key.to_s.downcase
160
202
  if value
161
203
  s << (upcase ? up : down) << "\n"
@@ -0,0 +1,767 @@
1
+ $:.unshift '.'
2
+ $:.unshift './lib'
3
+ $:.unshift '..'
4
+ $:.unshift '../lib'
5
+
6
+ require 'stringio'
7
+ require 'test/unit'
8
+ require 'main'
9
+
10
+ class T < Test::Unit::TestCase
11
+ attribute 'status'
12
+ attribute 'logger'
13
+ attribute 'error'
14
+
15
+ def setup
16
+ @status = nil
17
+ @logger = Logger.new StringIO.new
18
+ @error = nil
19
+ end
20
+
21
+ def teardown
22
+ end
23
+
24
+ def main argv=[], env={}, &b
25
+ at_exit{ exit! }
26
+
27
+ $VERBOSE=nil
28
+ ARGV.replace argv
29
+ ENV.clear
30
+ env.each{|k,v| ENV[k.to_s]=v.to_s}
31
+
32
+ this = self
33
+
34
+ klass = ::Main.create do
35
+ module_eval &b if b
36
+
37
+ define_method :handle_exception do |e|
38
+ if e.respond_to? :status
39
+ this.status = e.status
40
+ else
41
+ raise
42
+ end
43
+ end
44
+
45
+ define_method :handle_throw do |*a|
46
+ end
47
+ end
48
+
49
+ main = klass.new argv, env
50
+
51
+ main.logger = @logger
52
+
53
+ begin
54
+ main.run
55
+ ensure
56
+ this.status ||= main.exit_status
57
+ end
58
+
59
+ main
60
+ end
61
+
62
+ #
63
+ # basic test
64
+ #
65
+ def test_0000
66
+ assert_nothing_raised{
67
+ main{
68
+ def run() end
69
+ }
70
+ }
71
+ end
72
+ def test_0010
73
+ x = nil
74
+ assert_nothing_raised{
75
+ main{
76
+ define_method(:run){ x = 42 }
77
+ }
78
+ }
79
+ assert x == 42
80
+ end
81
+ #
82
+ # exit status
83
+ #
84
+ def test_0020
85
+ assert_nothing_raised{
86
+ main{
87
+ def run() end
88
+ }
89
+ }
90
+ assert status == 0
91
+ end
92
+ def test_0030
93
+ assert_nothing_raised{
94
+ main{
95
+ def run() exit 42 end
96
+ }
97
+ }
98
+ assert status == 42
99
+ end
100
+ def test_0040
101
+ assert_nothing_raised{
102
+ fork{
103
+ main{
104
+ def run() exit! 42 end
105
+ }
106
+ }
107
+ Process.wait
108
+ assert $?.exitstatus == 42
109
+ }
110
+ end
111
+ def test_0050
112
+ assert_nothing_raised{
113
+ main{
114
+ def run() exit 42 end
115
+ }
116
+ }
117
+ assert status == 42
118
+ end
119
+ def test_0060
120
+ assert_nothing_raised{
121
+ main{
122
+ def run() raise ArgumentError end
123
+ }
124
+ }
125
+ assert status == 1
126
+ end
127
+ def test_0060
128
+ assert_raises(RuntimeError){
129
+ main{
130
+ def run() exit_status 42; raise end
131
+ }
132
+ }
133
+ assert status == 42
134
+ end
135
+ def test_0070
136
+ assert_raises(ArgumentError){
137
+ main{
138
+ def run() exit_status 42; raise ArgumentError end
139
+ }
140
+ }
141
+ assert status == 42
142
+ end
143
+ #
144
+ # parameter parsing
145
+ #
146
+ def test_0080
147
+ p = nil
148
+ assert_raises(Main::Parameter::NotGiven){
149
+ main(){
150
+ argument 'foo'
151
+ define_method('run'){ }
152
+ }
153
+ }
154
+ end
155
+ def test_0090
156
+ p = nil
157
+ m = nil
158
+ argv = %w[ 42 ]
159
+ given = nil
160
+ assert_nothing_raised{
161
+ main(argv.dup){
162
+ argument 'foo'
163
+ define_method('run'){ m = self; p = param['foo'] }
164
+ }
165
+ }
166
+ assert p.value == argv.first
167
+ assert p.values == argv
168
+ assert p.given?
169
+ assert m.argv.empty?
170
+ end
171
+ def test_0100
172
+ p = nil
173
+ argv = %w[]
174
+ given = nil
175
+ assert_nothing_raised{
176
+ main(argv){
177
+ p = argument('foo'){ optional }
178
+ define_method('run'){ p = param['foo'] }
179
+ }
180
+ }
181
+ assert p.optional?
182
+ assert !p.required?
183
+ assert p.value == nil
184
+ assert p.values == []
185
+ assert !p.given?
186
+ end
187
+ def test_0101
188
+ p = nil
189
+ argv = %w[]
190
+ given = nil
191
+ assert_nothing_raised{
192
+ main(argv){
193
+ p = argument('foo'){ required false }
194
+ define_method('run'){ p = param['foo'] }
195
+ }
196
+ }
197
+ assert p.optional?
198
+ assert !p.required?
199
+ assert p.value == nil
200
+ assert p.values == []
201
+ assert !p.given?
202
+ end
203
+ def test_0110
204
+ p = nil
205
+ argv = %w[ --foo ]
206
+ assert_nothing_raised{
207
+ main(argv){
208
+ option('foo'){ required }
209
+ define_method('run'){ p = param['foo'] }
210
+ }
211
+ }
212
+ assert p.value == true
213
+ assert p.values ==[true]
214
+ assert p.given?
215
+ end
216
+ def test_0120
217
+ p = nil
218
+ argv = []
219
+ assert_nothing_raised{
220
+ main(argv){
221
+ option 'foo'
222
+ define_method('run'){ p = param['foo'] }
223
+ }
224
+ }
225
+ assert p.value == nil
226
+ assert p.values == []
227
+ assert !p.given?
228
+ end
229
+ def test_0130
230
+ p = nil
231
+ assert_nothing_raised{
232
+ main(%w[--foo=42]){
233
+ option('foo'){ required; argument_required }
234
+ define_method('run'){ p = param['foo']}
235
+ }
236
+ }
237
+ assert p.required?
238
+ assert p.argument_required?
239
+ assert !p.optional?
240
+ end
241
+ def test_0131
242
+ assert_raises(Main::Parameter::NotGiven){
243
+ main(){
244
+ option('foo'){ required; argument_required }
245
+ define_method('run'){}
246
+ }
247
+ }
248
+ end
249
+ def test_0140
250
+ assert_raises(Main::Parameter::MissingArgument){
251
+ main(['--foo']){
252
+ option('foo'){ required; argument_required }
253
+ define_method('run'){}
254
+ }
255
+ }
256
+ end
257
+ def test_0150
258
+ param = nil
259
+ assert_nothing_raised{
260
+ main(%w[--foo=42 --bar=42.0 --foobar=true --barfoo=false --uri=http://foo --x=s]){
261
+ option('foo'){
262
+ required
263
+ argument_required
264
+ cast :int
265
+ }
266
+ option('bar'){
267
+ argument_required
268
+ cast :float
269
+ }
270
+ option('foobar'){
271
+ argument_required
272
+ cast :bool
273
+ }
274
+ option('barfoo'){
275
+ argument_required
276
+ cast :string
277
+ }
278
+ option('uri'){
279
+ argument_required
280
+ cast :uri
281
+ }
282
+ option('x'){
283
+ argument_required
284
+ cast{|x| x.to_s.upcase}
285
+ }
286
+ define_method('run'){ param = params }
287
+ }
288
+ }
289
+ assert param['foo'].value == 42
290
+ assert param['bar'].value == 42.0
291
+ assert param['foobar'].value == true
292
+ assert param['barfoo'].value == 'false'
293
+ assert param['uri'].value == URI.parse('http://foo')
294
+ assert param['x'].value == 'S'
295
+ end
296
+ def test_0160
297
+ p = nil
298
+ assert_nothing_raised{
299
+ main(%w[--foo=42]){
300
+ option('foo'){
301
+ required
302
+ argument_required
303
+ cast :int
304
+ validate{|x| x == 42}
305
+ }
306
+ define_method('run'){ p = param['foo']}
307
+ }
308
+ }
309
+ assert p.value == 42
310
+ assert p.required?
311
+ assert p.argument_required?
312
+ assert !p.optional?
313
+ end
314
+ def test_0170
315
+ assert_raises(Main::Parameter::InValid){
316
+ main(%w[--foo=40]){
317
+ option('foo'){
318
+ required
319
+ argument_required
320
+ cast :int
321
+ validate{|x| x == 42}
322
+ }
323
+ define_method('run'){ }
324
+ }
325
+ }
326
+ end
327
+ def test_0180
328
+ assert_nothing_raised{
329
+ main(%w[--foo=42]){
330
+ option('--foo=foo'){
331
+ required
332
+ # argument_required
333
+ cast :int
334
+ validate{|x| x == 42}
335
+ }
336
+ define_method('run'){ }
337
+ }
338
+ }
339
+ end
340
+ def test_0190
341
+ assert_raises(Main::Parameter::MissingArgument){
342
+ main(%w[--foo]){
343
+ option('--foo=foo'){ }
344
+ define_method('run'){ }
345
+ }
346
+ }
347
+ end
348
+ def test_0200
349
+ p = nil
350
+ assert_nothing_raised{
351
+ main(%w[--foo]){
352
+ option('--foo=[foo]'){ }
353
+ define_method('run'){ p = param['foo'] }
354
+ }
355
+ }
356
+ assert p.value == true
357
+ end
358
+ def test_0210
359
+ p = nil
360
+ assert_nothing_raised{
361
+ main(%w[--foo=42]){
362
+ option('--foo=[foo]'){
363
+ cast :int
364
+ validate{|x| x == 42}
365
+ }
366
+ define_method('run'){ p = param['foo'] }
367
+ }
368
+ }
369
+ assert p.value == 42
370
+ end
371
+ def test_0220
372
+ p = nil
373
+ assert_nothing_raised{
374
+ main(%w[--foo=40 --foo=2]){
375
+ option('--foo=foo'){
376
+ arity 2
377
+ cast :int
378
+ validate{|x| x == 40 or x == 2}
379
+ }
380
+ define_method('run'){ p = param['foo'] }
381
+ }
382
+ }
383
+ assert p.value == 40
384
+ assert p.values == [40,2]
385
+ end
386
+ def test_0230
387
+ p = nil
388
+ assert_nothing_raised{
389
+ main(%w[foo=42]){
390
+ keyword('foo'){
391
+ cast :int
392
+ validate{|x| x == 42}
393
+ }
394
+ define_method('run'){ p = param['foo'] }
395
+ }
396
+ }
397
+ assert p.value == 42
398
+ end
399
+ def test_0240
400
+ foo = nil
401
+ bar = nil
402
+ assert_nothing_raised{
403
+ main(%w[foo= bar]){
404
+ keyword 'foo'
405
+ keyword 'bar'
406
+ define_method('run'){
407
+ foo = param['foo']
408
+ bar = param['bar']
409
+ }
410
+ }
411
+ }
412
+ assert foo.value == ''
413
+ assert bar.value == nil
414
+ end
415
+ def test_0250
416
+ foo = nil
417
+ bar = nil
418
+ assert_nothing_raised{
419
+ main(%w[foo=40 bar=2]){
420
+ keyword('foo'){
421
+ cast :int
422
+ }
423
+ keyword('bar'){
424
+ cast :int
425
+ }
426
+ define_method('run'){
427
+ foo = param['foo']
428
+ bar = param['bar']
429
+ }
430
+ }
431
+ }
432
+ assert foo.value == 40
433
+ assert bar.value == 2
434
+ end
435
+ def test_0260
436
+ foo = nil
437
+ bar = nil
438
+ foobar = nil
439
+ assert_nothing_raised{
440
+ main(%w[foo=40 --bar=2 foobar foo=42]){
441
+ kw('foo'){ cast :int; arity 2 }
442
+ opt('bar='){ cast :int }
443
+ arg 'foobar'
444
+
445
+ define_method('run'){
446
+ foo = param['foo']
447
+ bar = param['bar']
448
+ foobar = param['foobar']
449
+ }
450
+ }
451
+ }
452
+ assert foo.value == 40
453
+ assert foo.values == [40, 42]
454
+ assert bar.value == 2
455
+ assert foobar.value == 'foobar'
456
+ end
457
+ def test_0270
458
+ foo = nil
459
+ assert_nothing_raised{
460
+ main([], 'foo' => '42'){
461
+ env('foo'){ cast :int }
462
+ define_method('run'){
463
+ foo = param['foo']
464
+ }
465
+ }
466
+ }
467
+ assert foo.value == 42
468
+ end
469
+ #
470
+ # usage
471
+ #
472
+ def test_0280
473
+ assert_nothing_raised{
474
+ u = Main::Usage.new
475
+ }
476
+ end
477
+ def test_0290
478
+ assert_nothing_raised{
479
+ u = Main::Usage.default Main.create
480
+ }
481
+ end
482
+ def test_0300
483
+ assert_nothing_raised{
484
+ chunk = <<-txt
485
+ a
486
+ b
487
+ c
488
+ txt
489
+ assert Main::Util.unindent(chunk) == "a\nb\nc"
490
+ chunk = <<-txt
491
+ a
492
+ b
493
+ c
494
+ txt
495
+ assert Main::Util.unindent(chunk) == "a\n b\n c"
496
+ }
497
+ end
498
+ def test_0310
499
+ assert_nothing_raised{
500
+ u = Main::Usage.new
501
+ u[:name] = 'foobar'
502
+ assert u[:name] = 'foobar'
503
+ assert u['name'] = 'foobar'
504
+ }
505
+ end
506
+ def test_0320
507
+ assert_nothing_raised{
508
+ u = Main::Usage.new
509
+ u[:name] = 'foobar'
510
+ assert u[:name] == 'foobar'
511
+ assert u['name'] == 'foobar'
512
+ u[:name2] = 'barfoo'
513
+ assert u[:name] == 'foobar'
514
+ assert u['name'] == 'foobar'
515
+ assert u[:name2] == 'barfoo'
516
+ assert u['name2'] == 'barfoo'
517
+ u.delete_at :name
518
+ assert u[:name] == nil
519
+ assert u['name'] == nil
520
+ assert u[:name2] == 'barfoo'
521
+ assert u['name2'] == 'barfoo'
522
+ u.delete_at :name2
523
+ assert u[:name] == nil
524
+ assert u['name'] == nil
525
+ assert u[:name2] == nil
526
+ assert u['name2'] == nil
527
+ }
528
+ end
529
+ #
530
+ # io redirection
531
+ #
532
+ class ::Object
533
+ require 'tempfile'
534
+ def infile buf
535
+ t = Tempfile.new rand.to_s
536
+ t << buf
537
+ t.close
538
+ open t.path, 'r+'
539
+ end
540
+ def outfile
541
+ t = Tempfile.new rand.to_s
542
+ t.close
543
+ open t.path, 'w+'
544
+ end
545
+ end
546
+ def test_0330
547
+ s = "foo\nbar\n"
548
+ sio = StringIO.new s
549
+ $buf = nil
550
+ assert_nothing_raised{
551
+ main{
552
+ stdin sio
553
+ def run
554
+ $buf = STDIN.read
555
+ end
556
+ }
557
+ }
558
+ assert $buf == s
559
+ end
560
+ def test_0340
561
+ s = "foo\nbar\n"
562
+ $sio = StringIO.new s
563
+ $buf = nil
564
+ assert_nothing_raised{
565
+ main{
566
+ def run
567
+ self.stdin = $sio
568
+ $buf = STDIN.read
569
+ end
570
+ }
571
+ }
572
+ assert $buf == s
573
+ end
574
+ def test_0350
575
+ s = "foo\nbar\n"
576
+ $buf = nil
577
+ assert_nothing_raised{
578
+ main{
579
+ stdin infile(s)
580
+ def run
581
+ $buf = STDIN.read
582
+ end
583
+ }
584
+ }
585
+ assert $buf == s
586
+ end
587
+ def test_0360
588
+ sout = outfile
589
+ assert_nothing_raised{
590
+ main{
591
+ stdout sout
592
+ def run
593
+ puts 42
594
+ end
595
+ }
596
+ }
597
+ assert test(?e, sout.path)
598
+ assert IO.read(sout.path) == "42\n"
599
+ end
600
+ def test_0370
601
+ m = nil
602
+ assert_nothing_raised{
603
+ m = main{
604
+ stdout StringIO.new
605
+ def run
606
+ puts 42
607
+ end
608
+ }
609
+ }
610
+ assert m
611
+ assert_nothing_raised{ m.stdout.rewind }
612
+ assert m.stdout.read == "42\n"
613
+ end
614
+ #
615
+ # main ctor
616
+ #
617
+ def test_0380
618
+ argv = %w( a b c )
619
+ $argv = nil
620
+ assert_nothing_raised{
621
+ main(argv){
622
+ def run
623
+ $argv = @argv
624
+ end
625
+ }
626
+ }
627
+ assert argv == $argv
628
+ end
629
+ def test_0390
630
+ argv = %w( a b c )
631
+ env = {'key' => 'val', 'foo' => 'bar'}
632
+ $argv = nil
633
+ $env = nil
634
+ assert_nothing_raised{
635
+ main(argv, env){
636
+ def run
637
+ $argv = @argv
638
+ $env = @env
639
+ end
640
+ }
641
+ }
642
+ assert argv == $argv
643
+ end
644
+
645
+ #
646
+ # negative/globbing arity
647
+ #
648
+ def test_4000
649
+ m = nil
650
+ argv = %w( a b c )
651
+ assert_nothing_raised{
652
+ main(argv.dup) {
653
+ argument('zero_or_more'){ optional; arity -1 }
654
+ run{ m = self }
655
+ }
656
+ }
657
+ assert m.param['zero_or_more'].values == argv
658
+ end
659
+ def test_4010
660
+ m = nil
661
+ argv = %w( a b c )
662
+ assert_nothing_raised{
663
+ main(argv.dup) {
664
+ argument('zero_or_more'){ optional; arity '*' }
665
+ run{ m = self }
666
+ }
667
+ }
668
+ assert m.param['zero_or_more'].values == argv
669
+ end
670
+ def test_4020
671
+ m = nil
672
+ argv = %w( a b c )
673
+ assert_nothing_raised{
674
+ main(argv.dup) {
675
+ argument('one_or_more'){ arity -2 }
676
+ run{ m = self }
677
+ }
678
+ }
679
+ assert m.param['one_or_more'].values == argv
680
+ end
681
+ def test_4030
682
+ m = nil
683
+ argv = %w( a b c )
684
+ assert_nothing_raised{
685
+ main(argv.dup) {
686
+ argument('two_or_more'){ arity -3 }
687
+ run{ m = self }
688
+ }
689
+ }
690
+ assert m.param['two_or_more'].values == argv
691
+ end
692
+ def test_4040
693
+ m = nil
694
+ argv = %w()
695
+ assert_nothing_raised{
696
+ main(argv.dup) {
697
+ argument('zero_or_more'){ optional; arity -1 }
698
+ run{ m = self }
699
+ }
700
+ }
701
+ assert m.param['zero_or_more'].values == argv
702
+ end
703
+ def test_4050
704
+ m = nil
705
+ argv = %w()
706
+ assert_raises(Main::Parameter::NotGiven){
707
+ main(argv.dup) {
708
+ argument('one_or_more'){ arity -2 }
709
+ run{ m = self }
710
+ }
711
+ }
712
+ end
713
+ def test_4060
714
+ m = nil
715
+ argv = %w( a )
716
+ assert_raises(Main::Parameter::Arity){
717
+ main(argv.dup) {
718
+ argument('two_or_more'){ arity -3 }
719
+ run{ m = self }
720
+ }
721
+ }
722
+ end
723
+ def test_4070
724
+ m = nil
725
+ argv = %w( a )
726
+ assert_raises(Main::Parameter::Arity){
727
+ main(argv.dup) {
728
+ argument('two_or_more'){ arity -4 }
729
+ run{ m = self }
730
+ }
731
+ }
732
+ end
733
+ #
734
+ # sub-command/mode functionality
735
+ #
736
+ def test_4080
737
+ m = nil
738
+ argv = %w( a b )
739
+ assert_nothing_raised{
740
+ main(argv.dup) {
741
+ mode 'a' do
742
+ argument 'b'
743
+ run{ m = self }
744
+ end
745
+ }
746
+ }
747
+ assert m.param['b'].value == 'b'
748
+ end
749
+ def test_4090
750
+ m = nil
751
+ argv = %w( a b c )
752
+ assert_nothing_raised{
753
+ main(argv.dup) {
754
+ mode 'a' do
755
+ mode 'b' do
756
+ argument 'c'
757
+ run{ m = self }
758
+ end
759
+ end
760
+ }
761
+ }
762
+ assert m.param['c'].value == 'c'
763
+ end
764
+
765
+ end
766
+
767
+