qualitysmith_extensions 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/Readme +72 -0
  2. data/lib/qualitysmith_extensions/all.rb +2 -0
  3. data/lib/qualitysmith_extensions/array/all.rb +2 -0
  4. data/lib/qualitysmith_extensions/array/average.rb +42 -0
  5. data/lib/qualitysmith_extensions/array/expand_ranges.rb +48 -0
  6. data/lib/qualitysmith_extensions/array/group_by.rb +112 -0
  7. data/lib/qualitysmith_extensions/array/sequence.rb +64 -0
  8. data/lib/qualitysmith_extensions/array/shell_escape.rb +34 -0
  9. data/lib/qualitysmith_extensions/array/to_a_recursive.rb +39 -0
  10. data/lib/qualitysmith_extensions/array/to_query_string.rb +94 -0
  11. data/lib/qualitysmith_extensions/collection_extensions_for_cgi.rb +2 -0
  12. data/lib/qualitysmith_extensions/console/command.facets.1.8.51.rb +749 -0
  13. data/lib/qualitysmith_extensions/console/command.rb +940 -0
  14. data/lib/qualitysmith_extensions/date/all.rb +2 -0
  15. data/lib/qualitysmith_extensions/date/deprecated.rb +38 -0
  16. data/lib/qualitysmith_extensions/date/iso8601.rb +29 -0
  17. data/lib/qualitysmith_extensions/date/month_ranges.rb +120 -0
  18. data/lib/qualitysmith_extensions/enumerable/enum.rb +72 -0
  19. data/lib/qualitysmith_extensions/file/exact_match_regexp.rb +32 -0
  20. data/lib/qualitysmith_extensions/file_test/binary_file.rb +108 -0
  21. data/lib/qualitysmith_extensions/filter_output.rb +107 -0
  22. data/lib/qualitysmith_extensions/global_variable_set.rb +151 -0
  23. data/lib/qualitysmith_extensions/hash/all.rb +2 -0
  24. data/lib/qualitysmith_extensions/hash/to_date.rb +32 -0
  25. data/lib/qualitysmith_extensions/hash/to_query_string.rb +119 -0
  26. data/lib/qualitysmith_extensions/kernel/all.rb +2 -0
  27. data/lib/qualitysmith_extensions/kernel/backtrace.rb +69 -0
  28. data/lib/qualitysmith_extensions/kernel/capture_output.rb +113 -0
  29. data/lib/qualitysmith_extensions/kernel/die.rb +34 -0
  30. data/lib/qualitysmith_extensions/kernel/require_all.rb +118 -0
  31. data/lib/qualitysmith_extensions/kernel/require_once.rb +16 -0
  32. data/lib/qualitysmith_extensions/month.rb +62 -0
  33. data/lib/qualitysmith_extensions/object/singleton.rb +95 -0
  34. data/lib/qualitysmith_extensions/simulate_input.rb +51 -0
  35. data/lib/qualitysmith_extensions/string/all.rb +2 -0
  36. data/lib/qualitysmith_extensions/string/digits_only.rb +25 -0
  37. data/lib/qualitysmith_extensions/string/md5.rb +27 -0
  38. data/lib/qualitysmith_extensions/string/shell_escape.rb +41 -0
  39. data/lib/qualitysmith_extensions/string/to_underscored_label.rb +35 -0
  40. data/lib/qualitysmith_extensions/test/assert_changed.rb +64 -0
  41. data/lib/qualitysmith_extensions/test/assert_exception.rb +63 -0
  42. data/lib/qualitysmith_extensions/test/assert_includes.rb +34 -0
  43. data/lib/qualitysmith_extensions/test/assert_user_error.rb +34 -0
  44. data/lib/qualitysmith_extensions/time/all.rb +2 -0
  45. data/lib/qualitysmith_extensions/time/deprecated.rb +29 -0
  46. data/test/all.rb +16 -0
  47. metadata +94 -0
@@ -0,0 +1,749 @@
1
+ # = command.rb
2
+ #
3
+ # == Copyright (c) 2005 Thomas Sawyer
4
+ #
5
+ # Ruby License
6
+ #
7
+ # This module is free software. You may use, modify, and/or
8
+ # redistribute this software under the same terms as Ruby.
9
+ #
10
+ # This program is distributed in the hope that it will be
11
+ # useful, but WITHOUT ANY WARRANTY; without even the implied
12
+ # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13
+ # PURPOSE.
14
+ #
15
+ # == Author(s)
16
+ #
17
+ # CREDIT Thomas Sawyer
18
+ # CREDIT Tyler Rick
19
+ #
20
+ # == Developer Notes
21
+ #
22
+ # TODO Add help/documentation features.
23
+ #
24
+ # TODO Move to console/command.rb, but I'm not sure yet if
25
+ # adding subdirectories to more/ is a good idea.
26
+ #
27
+
28
+ # Author:: Thomas Sawyer, Tyler Rick
29
+ # Copyright:: Copyright (c) 2005-2007
30
+ # License:: Ruby License
31
+
32
+ require 'shellwords'
33
+
34
+ # = Console
35
+ #
36
+ # Console namespace for use by tools specifically designed
37
+ # for command line interfaces.
38
+
39
+ module Console ; end
40
+
41
+ # = Console Command
42
+ #
43
+ # Console::Command provides a clean and easy way
44
+ # to create a command line interface for your program.
45
+ # The unique technique utlizes a Commandline to Object
46
+ # Mapping (COM) to make it quick and easy.
47
+ #
48
+ # == Synopsis
49
+ #
50
+ # Let's make an executable called 'mycmd'.
51
+ #
52
+ # #!/usr/bin/env ruby
53
+ #
54
+ # require 'facets'
55
+ # require 'command'
56
+ #
57
+ # MyCmd << Console::Command
58
+ #
59
+ # def _v
60
+ # $VERBOSE = true
61
+ # end
62
+ #
63
+ # def jump
64
+ # if $VERBOSE
65
+ # puts "JUMP! JUMP! JUMP!"
66
+ # else
67
+ # puts "Jump"
68
+ # end
69
+ # end
70
+ #
71
+ # end
72
+ #
73
+ # MyCmd.execute
74
+ #
75
+ # Then on the command line:
76
+ #
77
+ # % mycmd jump
78
+ # Jump
79
+ #
80
+ # % mycmd -v jump
81
+ # JUMP! JUMP! JUMP!
82
+ #
83
+ # == Subcommands
84
+ #
85
+ # Commands can take subcommand and suboptions. To do this
86
+ # simply add a module to your class with the same name
87
+ # as the subcommand, in which the suboption methods are defined.
88
+ #
89
+ # MyCmd << Console::Command
90
+ #
91
+ # def initialize
92
+ # @height = 1
93
+ # end
94
+ #
95
+ # def _v
96
+ # $VERBOSE = true
97
+ # end
98
+ #
99
+ # def jump
100
+ # if $VERBOSE
101
+ # puts "JUMP!" * @height
102
+ # else
103
+ # puts "Jump" * @height
104
+ # end
105
+ # end
106
+ #
107
+ # module Jump
108
+ # def __height(h)
109
+ # @height = h.to_i
110
+ # end
111
+ # end
112
+ #
113
+ # end
114
+ #
115
+ # MyCmd.start
116
+ #
117
+ # Then on the command line:
118
+ #
119
+ # % mycmd jump -h 2
120
+ # Jump Jump
121
+ #
122
+ # % mycmd -v jump -h 3
123
+ # JUMP! JUMP! JUMP!
124
+ #
125
+ # Another thing to notice about this example is that #start is an alias
126
+ # for #execute.
127
+ #
128
+ # == Missing Subcommands
129
+ #
130
+ # You can use #method_missing to catch missing subcommand calls.
131
+ #
132
+ # == Main and Default
133
+ #
134
+ # If your command does not take subcommands then simply define
135
+ # a #main method to dispatch action. All options will be treated globablly
136
+ # in this case and any remaining comman-line arguments will be passed
137
+ # to #main.
138
+ #
139
+ # If on the other hand your command does take subcommands but none is given,
140
+ # the #default method will be called, if defined. If not defined
141
+ # an error will be raised (but only reported if $DEBUG is true).
142
+ #
143
+ # == Global Options
144
+ #
145
+ # You can define <i>global options</i> which are options that will be
146
+ # processed no matter where they occur in the command line. In the above
147
+ # examples only the options occuring before the subcommand are processed
148
+ # globally. Anything occuring after the subcommand belonds strictly to
149
+ # the subcommand. For instance, if we had added the following to the above
150
+ # example:
151
+ #
152
+ # global_option :_v
153
+ #
154
+ # Then -v could appear anywhere in the command line, even on the end,
155
+ # and still work as expected.
156
+ #
157
+ # % mycmd jump -h 3 -v
158
+ #
159
+ # == Missing Options
160
+ #
161
+ # You can use #option_missing to catch any options that are not explicility
162
+ # defined.
163
+ #
164
+ # The method signature should look like:
165
+ #
166
+ # option_missing(option_name, args)
167
+ #
168
+ # Example:
169
+ # def option_missing(option_name, args)
170
+ # p args if $debug
171
+ # case option_name
172
+ # when 'p'
173
+ # @a = args[0].to_i
174
+ # @b = args[1].to_i
175
+ # 2
176
+ # else
177
+ # raise InvalidOptionError(option_name, args)
178
+ # end
179
+ # end
180
+ #
181
+ # Its return value should be the effective "arity" of that options -- that is,
182
+ # how many arguments it consumed ("-p a b", for example, would consume 2 args:
183
+ # "a" and "b"). An arity of 1 is assumed if nil or false is returned.
184
+ #
185
+ # Be aware that when using subcommand modules, the same option_missing
186
+ # method will catch missing options for global options and subcommand
187
+ # options too unless an option_missing method is also defined in the
188
+ # subcommand module.
189
+ #
190
+ #--
191
+ #
192
+ # == Help Documentation
193
+ #
194
+ # You can also add help information quite easily. If the following code
195
+ # is saved as 'foo' for instance.
196
+ #
197
+ # MyCmd << Console::Command
198
+ #
199
+ # help "Dispays the word JUMP!"
200
+ #
201
+ # def jump
202
+ # if $VERBOSE
203
+ # puts "JUMP! JUMP! JUMP!"
204
+ # else
205
+ # puts "Jump"
206
+ # end
207
+ # end
208
+ #
209
+ # end
210
+ #
211
+ # MyCmd.execute
212
+ #
213
+ # then by running 'foo help' on the command line, standard help information
214
+ # will be displayed.
215
+ #
216
+ # foo
217
+ #
218
+ # jump Displays the word JUMP!
219
+ #
220
+ #++
221
+
222
+ class Console::Command
223
+
224
+ class << self
225
+ # Starts the command execution.
226
+
227
+ def execute( *args )
228
+ new(global_options).execute( *args )
229
+ end
230
+
231
+ # Alias for #execute.
232
+
233
+ alias_method :start, :execute
234
+
235
+ # Change the option mode.
236
+
237
+ def global_option( *names )
238
+ names.each{ |name| global_options << name.to_sym }
239
+ end
240
+
241
+ def global_options
242
+ @global_options ||= []
243
+ end
244
+ end
245
+
246
+ # Do not let this pass through to
247
+ # any included module.
248
+
249
+ def initialize(global_options)
250
+ @global_options = global_options
251
+ end
252
+
253
+ # Execute the command.
254
+
255
+ def execute( line=nil )
256
+ case line
257
+ when String
258
+ arguments = Shellwords.shellwords(line)
259
+ when Array
260
+ arguments = line
261
+ else
262
+ arguments = ARGV
263
+ end
264
+
265
+ # duplicate arguments to work on them in-place.
266
+
267
+ argv = arguments.dup
268
+
269
+ # Split single letter option groupings into separate options.
270
+ # ie. -xyz => -x -y -z
271
+
272
+ argv = argv.collect { |arg|
273
+ if md = /^-(\w{2,})/.match( arg )
274
+ md[1].split(//).collect { |c| "-#{c}" }
275
+ else
276
+ arg
277
+ end
278
+ }.flatten
279
+
280
+ # process global options
281
+ global_options.each do |name|
282
+ o = name.to_s.sub('__','--').sub('_','-')
283
+ m = method(name)
284
+ c = m.arity
285
+ while i = argv.index(o)
286
+ args = argv.slice!(i,c+1)
287
+ args.shift
288
+ m.call(*args)
289
+ end
290
+ end
291
+
292
+ # Does this command take subcommands?
293
+ subcommand = !respond_to?(:main)
294
+
295
+ # process primary options
296
+ argv = execute_options( argv, subcommand )
297
+
298
+ # If this command doesn't take subcommands, then the remaining arguments are arguments for main().
299
+ return send(:main, *argv) unless subcommand
300
+
301
+ # What to do if there is nothing else?
302
+ if argv.empty?
303
+ if respond_to?(:default)
304
+ return __send__(:default)
305
+ else
306
+ $stderr << "Nothing to do."
307
+ return
308
+ end
309
+ end
310
+
311
+ # Remaining arguments are subcommand and suboptions.
312
+
313
+ subcmd = argv.shift.gsub('-','_')
314
+ #puts "subcmd = #{subcmd}"
315
+
316
+ # Extend subcommand option module
317
+ subconst = subcmd.gsub(/\W/,'_').capitalize
318
+ #puts self.class.name
319
+ if self.class.const_defined?(subconst)
320
+ puts "Extending self (#{self.class}) with subcommand module #{subconst}" if $debug
321
+ submod = self.class.const_get(subconst)
322
+ self.extend submod
323
+ end
324
+
325
+ # process subcommand options
326
+ #puts "Treating the rest of the args as subcommand options:"
327
+ #p argv
328
+ argv = execute_options( argv )
329
+
330
+ # This is a little tricky. The method has to be defined by a subclass.
331
+ if self.respond_to?( subcmd ) and not Console::Command.public_instance_methods.include?( subcmd.to_s )
332
+ puts "Calling #{subcmd}(#{argv.inspect})" if $debug
333
+ __send__(subcmd, *argv)
334
+ else
335
+ #begin
336
+ puts "Calling method_missing with #{subcmd}, #{argv.inspect}" if $debug
337
+ method_missing(subcmd, *argv)
338
+ #rescue NoMethodError => e
339
+ #if self.private_methods.include?( "no_command_error" )
340
+ # no_command_error( *args )
341
+ #else
342
+ # $stderr << "Non-applicable command -- #{argv.join(' ')}\n"
343
+ # exit -1
344
+ #end
345
+ #end
346
+ end
347
+
348
+ # rescue => err
349
+ # if $DEBUG
350
+ # raise err
351
+ # else
352
+ # msg = err.message.chomp('.') + '.'
353
+ # msg[0,1] = msg[0,1].capitalize
354
+ # msg << " (#{err.class})" if $VERBOSE
355
+ # $stderr << msg
356
+ # end
357
+ end
358
+
359
+ private
360
+
361
+ #
362
+
363
+ def global_options
364
+ @global_options
365
+ end
366
+
367
+ #
368
+
369
+ def execute_options( argv, subcmd=false )
370
+ puts "in execute_options:" if $debug
371
+ argv = argv.dup
372
+ args_to_return = []
373
+ until argv.empty?
374
+ arg = argv.first
375
+ if arg[0,1] == '-'
376
+ puts "'#{arg}' -- is an option" if $debug
377
+
378
+ name = arg.gsub('-','_')
379
+ puts " responds_to(#{name})?" if $debug
380
+ if respond_to?(name)
381
+ m = method(name)
382
+ arity = m.arity
383
+ #puts "{argv before slice: #{argv.inspect}" if $debug
384
+ args_for_current_option = argv.slice!(0, arity+1)
385
+ #puts "}argv after slice: #{argv.inspect}" if $debug
386
+ #puts "{args_for_current_option before shift: #{args_for_current_option.inspect}" if $debug
387
+ args_for_current_option.shift
388
+ #puts "}args_for_current_option after shift: #{args_for_current_option.inspect}" if $debug
389
+ #puts " arity=#{m.arity}" if $debug
390
+ #puts " calling #{name} with #{args_for_current_option.inspect}" if $debug
391
+ m.call(*args_for_current_option)
392
+ elsif respond_to?(:option_missing)
393
+ puts " option_missing(#{argv.inspect})" if $debug
394
+ arity = option_missing(arg.gsub(/^[-]+/,''), argv[1..-1]) || 1
395
+ puts " arity == #{arity}" if $debug
396
+ argv.slice!(0, arity)
397
+ argv.shift # Get rid of the *name* of the option
398
+ else
399
+ $stderr << "Unknown option '#{arg}'.\n"
400
+ exit -1
401
+ end
402
+ else
403
+ puts "'#{arg}' -- not an option. Adding to args_to_return..." if $debug
404
+ if subcmd
405
+ args_to_return = argv
406
+ #puts "subcommand. args_to_return=#{args_to_return.inspect}" if $debug
407
+ break
408
+ else
409
+ args_to_return << argv.shift
410
+ puts "args_to_return=#{args_to_return.inspect}" if $debug
411
+ end
412
+ end
413
+ end
414
+ puts "Returning #{args_to_return.inspect}" if $debug
415
+ return args_to_return
416
+ end
417
+
418
+ public
419
+
420
+ =begin
421
+ # We include a module here so you can define your own help
422
+ # command and call #super to utilize this one.
423
+
424
+ module Help
425
+
426
+ def help
427
+ opts = help_options
428
+ s = ""
429
+ s << "#{File.basename($0)}\n\n"
430
+ unless opts.empty?
431
+ s << "OPTIONS\n"
432
+ s << help_options
433
+ s << "\n"
434
+ end
435
+ s << "COMMANDS\n"
436
+ s << help_commands
437
+ puts s
438
+ end
439
+
440
+ private
441
+
442
+ def help_commands
443
+ help = self.class.help
444
+ bufs = help.keys.collect{ |a| a.to_s.size }.max + 3
445
+ lines = []
446
+ help.each { |cmd, str|
447
+ cmd = cmd.to_s
448
+ if cmd !~ /^_/
449
+ lines << " " + cmd + (" " * (bufs - cmd.size)) + str
450
+ end
451
+ }
452
+ lines.join("\n")
453
+ end
454
+
455
+ def help_options
456
+ help = self.class.help
457
+ bufs = help.keys.collect{ |a| a.to_s.size }.max + 3
458
+ lines = []
459
+ help.each { |cmd, str|
460
+ cmd = cmd.to_s
461
+ if cmd =~ /^_/
462
+ lines << " " + cmd.gsub(/_/,'-') + (" " * (bufs - cmd.size)) + str
463
+ end
464
+ }
465
+ lines.join("\n")
466
+ end
467
+
468
+ module ClassMethods
469
+
470
+ def help( str=nil )
471
+ return (@help ||= {}) unless str
472
+ @current_help = str
473
+ end
474
+
475
+ def method_added( meth )
476
+ if @current_help
477
+ @help ||= {}
478
+ @help[meth] = @current_help
479
+ @current_help = nil
480
+ end
481
+ end
482
+
483
+ end
484
+
485
+ end
486
+
487
+ include Help
488
+ extend Help::ClassMethods
489
+ =end
490
+
491
+ end
492
+
493
+
494
+
495
+ # _____ _
496
+ # |_ _|__ ___| |_
497
+ # | |/ _ \/ __| __|
498
+ # | | __/\__ \ |_
499
+ # |_|\___||___/\__|
500
+ #
501
+
502
+ =begin test
503
+
504
+ require 'test/unit'
505
+ require 'stringio'
506
+
507
+ class TestCommand < Test::Unit::TestCase
508
+ def setup
509
+ $output = nil
510
+ $stderr = StringIO.new
511
+ end
512
+
513
+ #
514
+
515
+ class SimpleCommand < Console::Command
516
+ def __here ; @here = true ; end
517
+
518
+ def main(*args)
519
+ $output = [@here] | args
520
+ end
521
+ end
522
+
523
+ def test_SimpleCommand
524
+ SimpleCommand.execute( '--here file1 file2' )
525
+ assert_equal( [true, 'file1', 'file2'], $output )
526
+ end
527
+
528
+ #
529
+
530
+ class CommandWithMethodMissingSubcommand < Console::Command
531
+ def __here ; @here = true ; end
532
+
533
+ def method_missing(subcommand, *args)
534
+ $output = [@here, subcommand] | args
535
+ end
536
+ end
537
+
538
+ def test_CommandWithMethodMissingSubcommand
539
+ CommandWithMethodMissingSubcommand.execute( '--here go file1' )
540
+ assert_equal( [true, 'go', 'file1'], $output )
541
+ end
542
+
543
+ #
544
+
545
+ class CommandWithSimpleSubcommand < Console::Command
546
+ def __here ; @here = true ; end
547
+
548
+ # subcommand
549
+
550
+ module Go
551
+ def _p(n)
552
+ @p = n.to_i
553
+ end
554
+ end
555
+
556
+ def go ; $output = [@here, @p] ; end
557
+ end
558
+
559
+ def test_CommandWithSimpleSubcommand
560
+ CommandWithSimpleSubcommand.execute( '--here go -p 1' )
561
+ assert_equal( [true, 1], $output )
562
+ end
563
+
564
+ #
565
+
566
+ # Global options can be anywhere, right? Even after subcommands? Let's find out.
567
+ class CommandWithGlobalOptionsAfterSubcommand < Console::Command
568
+ def _x ; @x = true ; end
569
+ global_option :_x
570
+
571
+ def go ; $output = [@x, @p] ; end
572
+
573
+ module Go
574
+ def _p(n)
575
+ @p = n.to_i
576
+ end
577
+ end
578
+ end
579
+
580
+ def test_CommandWithGlobalOptionsAfterSubcommand
581
+ CommandWithGlobalOptionsAfterSubcommand.execute( 'go -x -p 1' )
582
+ assert_equal( [true, 1], $output )
583
+
584
+ CommandWithGlobalOptionsAfterSubcommand.execute( 'go -p 1 -x' )
585
+ assert_equal( [true, 1], $output )
586
+ end
587
+
588
+ #
589
+
590
+ class GivingUnrecognizedOptions < Console::Command
591
+ def _x ; @x = true ; end
592
+ def go ; $output = [@x, @p] ; end
593
+ end
594
+
595
+ def test_GivingUnrecognizedOptions
596
+ assert_raise(SystemExit) do
597
+ GivingUnrecognizedOptions.execute( '--an-option-that-wont-be-recognized -x go' )
598
+ end
599
+ assert_equal "Unknown option '--an-option-that-wont-be-recognized'.\n", $stderr.string
600
+ assert_equal( nil, $output )
601
+ end
602
+ #
603
+
604
+ class PassingMultipleSingleCharOptionsAsOneOption < Console::Command
605
+ def _x ; @x = true ; end
606
+ def _y ; @y = true ; end
607
+ def _z(n) ; @z = n ; end
608
+
609
+ global_option :_x
610
+
611
+ def go ; $output = [@x, @y, @z, @p] ; end
612
+
613
+ module Go
614
+ def _p(n)
615
+ @p = n.to_i
616
+ end
617
+ end
618
+ end
619
+
620
+ def test_PassingMultipleSingleCharOptionsAsOneOption
621
+ PassingMultipleSingleCharOptionsAsOneOption.execute( '-xy -z HERE go -p 1' )
622
+ assert_equal( [true, true, 'HERE', 1], $output )
623
+ end
624
+
625
+ #
626
+
627
+ class CommandWithOptionUsingEquals < Console::Command
628
+ module Go
629
+ def __mode(mode) ; @mode = mode ; end
630
+ end
631
+ def go ; $output = [@mode] ; end
632
+ end
633
+
634
+ def test_CommandWithOptionUsingEquals
635
+ CommandWithOptionUsingEquals.execute( 'go --mode smart' )
636
+ assert_equal( ['smart'], $output )
637
+
638
+ # I would expect this to work too, but currently it doesn't.
639
+ #assert_nothing_raised { CommandWithOptionUsingEquals.execute( 'go --mode=smart' ) }
640
+ #assert_equal( ['smart'], $output )
641
+ end
642
+
643
+ #
644
+
645
+ class CommandWithSubcommandThatTakesArgs < Console::Command
646
+ def go(arg1, *args) ; $output = [arg1] | args ; end
647
+ end
648
+
649
+ def test_CommandWithSubcommandThatTakesArgs
650
+ CommandWithSubcommandThatTakesArgs.execute( 'go file1 file2 file3' )
651
+ assert_equal( ['file1', 'file2', 'file3'], $output )
652
+ end
653
+
654
+ #
655
+
656
+ class CommandWith2OptionalArgs < Console::Command
657
+ def __here ; @here = true ; end
658
+
659
+ module Go
660
+ def _p(n)
661
+ @p = n.to_i
662
+ end
663
+ end
664
+
665
+ def go(required1 = nil, optional2 = nil) ; $output = [@here, @p, required1, optional2 ] ; end
666
+ end
667
+
668
+ def test_CommandWith2OptionalArgs
669
+ CommandWith2OptionalArgs.execute( '--here go -p 1 to' )
670
+ assert_equal( [true, 1, 'to', nil], $output )
671
+ end
672
+
673
+ #
674
+
675
+ class CommandWithVariableArgs < Console::Command
676
+ def __here ; @here = true ; end
677
+
678
+ module Go
679
+ def _p(n)
680
+ @p = n.to_i
681
+ end
682
+ end
683
+
684
+ def go(*args) ; $output = [@here, @p] | args ; end
685
+ end
686
+
687
+ def test_CommandWithVariableArgs
688
+ CommandWithVariableArgs.execute( '--here go -p 1 to bed' )
689
+ assert_equal( [true, 1, 'to', 'bed'], $output )
690
+ end
691
+
692
+ #
693
+
694
+ class CommandWithOptionMissing < Console::Command
695
+ def __here ; @here = true ; end
696
+
697
+ module Go
698
+ def option_missing(option_name, args)
699
+ p args if $debug
700
+ case option_name
701
+ when 'p'
702
+ @p = args[0].to_i
703
+ 1
704
+ else
705
+ raise InvalidOptionError(option_name, args)
706
+ end
707
+ end
708
+ end
709
+
710
+ def go(*args) ; $output = [@here, @p] | args ; end
711
+ end
712
+
713
+ def test_CommandWithOptionMissing
714
+ CommandWithOptionMissing.execute( '--here go -p 1 to bed right now' )
715
+ assert_equal( [true, 1, 'to', 'bed', 'right', 'now'], $output )
716
+ end
717
+
718
+ #
719
+
720
+ class CommandWithOptionMissingArityOf2 < Console::Command
721
+ def __here ; @here = true ; end
722
+
723
+ module Go
724
+ def option_missing(option_name, args)
725
+ p args if $debug
726
+ case option_name
727
+ when 'p'
728
+ @p1 = args[0].to_i
729
+ @p2 = args[1].to_i
730
+ 2
731
+ when 'q'
732
+ @q = args[0].to_i
733
+ nil # Test default arity
734
+ else
735
+ raise InvalidOptionError(option_name, args)
736
+ end
737
+ end
738
+ end
739
+
740
+ def go(*args) ; $output = [@here, @p1, @p2, @q] | args ; end
741
+ end
742
+
743
+ def test_CommandWithOptionMissingArityOf2
744
+ CommandWithOptionMissingArityOf2.execute( '--here go -p 1 2 -q 3 to bed right now' )
745
+ assert_equal( [true, 1, 2, 3, 'to', 'bed', 'right', 'now'], $output )
746
+ end
747
+ end
748
+
749
+ =end