quality_extensions 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. data/Readme +54 -0
  2. data/lib/qualitysmith_extensions/all.rb +4 -0
  3. data/lib/qualitysmith_extensions/array/all.rb +2 -0
  4. data/lib/qualitysmith_extensions/array/average.rb +44 -0
  5. data/lib/qualitysmith_extensions/array/classify.rb +97 -0
  6. data/lib/qualitysmith_extensions/array/expand_ranges.rb +52 -0
  7. data/lib/qualitysmith_extensions/array/group_by.rb +134 -0
  8. data/lib/qualitysmith_extensions/array/sequence.rb +66 -0
  9. data/lib/qualitysmith_extensions/array/shell_escape.rb +36 -0
  10. data/lib/qualitysmith_extensions/array/to_a_recursive.rb +41 -0
  11. data/lib/qualitysmith_extensions/array/to_query_string.rb +96 -0
  12. data/lib/qualitysmith_extensions/collection_extensions_for_cgi.rb +2 -0
  13. data/lib/qualitysmith_extensions/colored/toggleability.rb +62 -0
  14. data/lib/qualitysmith_extensions/console/command.facets.1.8.51.rb +749 -0
  15. data/lib/qualitysmith_extensions/console/command.facets.1.8.54.rb +748 -0
  16. data/lib/qualitysmith_extensions/console/command.rb +944 -0
  17. data/lib/qualitysmith_extensions/date/all.rb +2 -0
  18. data/lib/qualitysmith_extensions/date/deprecated.rb +40 -0
  19. data/lib/qualitysmith_extensions/date/iso8601.rb +31 -0
  20. data/lib/qualitysmith_extensions/date/month_ranges.rb +122 -0
  21. data/lib/qualitysmith_extensions/dir/each_child.rb +58 -0
  22. data/lib/qualitysmith_extensions/enumerable/enum.rb +69 -0
  23. data/lib/qualitysmith_extensions/enumerable/select_until.rb +4 -0
  24. data/lib/qualitysmith_extensions/enumerable/select_while.rb +109 -0
  25. data/lib/qualitysmith_extensions/exception/inspect_with_backtrace.rb +65 -0
  26. data/lib/qualitysmith_extensions/file/exact_match_regexp.rb +34 -0
  27. data/lib/qualitysmith_extensions/file_test/binary_file.rb +110 -0
  28. data/lib/qualitysmith_extensions/find/select.rb +68 -0
  29. data/lib/qualitysmith_extensions/global_variable_set.rb +153 -0
  30. data/lib/qualitysmith_extensions/hash/all.rb +2 -0
  31. data/lib/qualitysmith_extensions/hash/to_date.rb +34 -0
  32. data/lib/qualitysmith_extensions/hash/to_query_string.rb +121 -0
  33. data/lib/qualitysmith_extensions/kernel/all.rb +2 -0
  34. data/lib/qualitysmith_extensions/kernel/autoreload.rb +128 -0
  35. data/lib/qualitysmith_extensions/kernel/backtrace.rb +71 -0
  36. data/lib/qualitysmith_extensions/kernel/capture_output.rb +115 -0
  37. data/lib/qualitysmith_extensions/kernel/die.rb +49 -0
  38. data/lib/qualitysmith_extensions/kernel/example_printer.rb +81 -0
  39. data/lib/qualitysmith_extensions/kernel/filter_output.rb +108 -0
  40. data/lib/qualitysmith_extensions/kernel/remove_const.rb +178 -0
  41. data/lib/qualitysmith_extensions/kernel/remove_module.rb +127 -0
  42. data/lib/qualitysmith_extensions/kernel/require_all.rb +186 -0
  43. data/lib/qualitysmith_extensions/kernel/require_local_all.rb +4 -0
  44. data/lib/qualitysmith_extensions/kernel/require_once.rb +18 -0
  45. data/lib/qualitysmith_extensions/kernel/simulate_input.rb +52 -0
  46. data/lib/qualitysmith_extensions/kernel/trap_chain.rb +61 -0
  47. data/lib/qualitysmith_extensions/kernel/windows_platform.rb +46 -0
  48. data/lib/qualitysmith_extensions/module/alias_method.rb +6 -0
  49. data/lib/qualitysmith_extensions/module/alias_method_chain.rb +165 -0
  50. data/lib/qualitysmith_extensions/module/ancestry_of_instance_method.rb +43 -0
  51. data/lib/qualitysmith_extensions/module/attribute_accessors.rb +49 -0
  52. data/lib/qualitysmith_extensions/module/basename.rb +76 -0
  53. data/lib/qualitysmith_extensions/module/bool_attr_accessor.rb +497 -0
  54. data/lib/qualitysmith_extensions/module/class_methods.rb +87 -0
  55. data/lib/qualitysmith_extensions/module/create.rb +315 -0
  56. data/lib/qualitysmith_extensions/module/create_setter.rb +9 -0
  57. data/lib/qualitysmith_extensions/module/dirname.rb +4 -0
  58. data/lib/qualitysmith_extensions/module/guard_method.rb +312 -0
  59. data/lib/qualitysmith_extensions/module/includable_once.rb +10 -0
  60. data/lib/qualitysmith_extensions/module/join.rb +66 -0
  61. data/lib/qualitysmith_extensions/module/malias_method_chain.rb +92 -0
  62. data/lib/qualitysmith_extensions/module/module_methods.rb +4 -0
  63. data/lib/qualitysmith_extensions/module/namespace.rb +112 -0
  64. data/lib/qualitysmith_extensions/module/parents.rb +61 -0
  65. data/lib/qualitysmith_extensions/module/remove_const.rb +117 -0
  66. data/lib/qualitysmith_extensions/module/split.rb +55 -0
  67. data/lib/qualitysmith_extensions/month.rb +66 -0
  68. data/lib/qualitysmith_extensions/mutex/if_available.rb +75 -0
  69. data/lib/qualitysmith_extensions/object/ancestry_of_method.rb +257 -0
  70. data/lib/qualitysmith_extensions/object/default.rb +69 -0
  71. data/lib/qualitysmith_extensions/object/if_else.rb +157 -0
  72. data/lib/qualitysmith_extensions/object/ignore_access.rb +84 -0
  73. data/lib/qualitysmith_extensions/object/mcall.rb +92 -0
  74. data/lib/qualitysmith_extensions/object/methods.rb +63 -0
  75. data/lib/qualitysmith_extensions/object/send_if.rb +151 -0
  76. data/lib/qualitysmith_extensions/object/send_if_not_nil.rb +35 -0
  77. data/lib/qualitysmith_extensions/object/singleton_send.rb +129 -0
  78. data/lib/qualitysmith_extensions/regexp/join.rb +111 -0
  79. data/lib/qualitysmith_extensions/string/all.rb +2 -0
  80. data/lib/qualitysmith_extensions/string/constantize.rb +4 -0
  81. data/lib/qualitysmith_extensions/string/digits_only.rb +27 -0
  82. data/lib/qualitysmith_extensions/string/each_char_with_index.rb +41 -0
  83. data/lib/qualitysmith_extensions/string/md5.rb +29 -0
  84. data/lib/qualitysmith_extensions/string/shell_escape.rb +43 -0
  85. data/lib/qualitysmith_extensions/string/to_underscored_label.rb +37 -0
  86. data/lib/qualitysmith_extensions/string/with_knowledge_of_color.rb +64 -0
  87. data/lib/qualitysmith_extensions/symbol/constantize.rb +69 -0
  88. data/lib/qualitysmith_extensions/symbol/match.rb +157 -0
  89. data/lib/qualitysmith_extensions/template.rb +33 -0
  90. data/lib/qualitysmith_extensions/test/all.rb +2 -0
  91. data/lib/qualitysmith_extensions/test/assert_anything.rb +93 -0
  92. data/lib/qualitysmith_extensions/test/assert_changed.rb +66 -0
  93. data/lib/qualitysmith_extensions/test/assert_exception.rb +66 -0
  94. data/lib/qualitysmith_extensions/test/assert_includes.rb +36 -0
  95. data/lib/qualitysmith_extensions/test/assert_user_error.rb +37 -0
  96. data/lib/qualitysmith_extensions/test/difference_highlighting.rb +323 -0
  97. data/lib/qualitysmith_extensions/time/all.rb +2 -0
  98. data/lib/qualitysmith_extensions/time/deprecated.rb +31 -0
  99. data/test/all.rb +16 -0
  100. metadata +148 -0
@@ -0,0 +1,748 @@
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
+ cmd = new()
229
+ cmd.instance_variable_set("@global_options",global_options)
230
+ cmd.execute( *args )
231
+ end
232
+ alias_method :start, :execute
233
+
234
+ # Change the option mode.
235
+
236
+ def global_option( *names )
237
+ names.each{ |name| global_options << name.to_sym }
238
+ end
239
+
240
+ def global_options
241
+ @global_options ||= []
242
+ end
243
+ end
244
+
245
+ # Do not let this pass through to
246
+ # any included module.
247
+
248
+ def initialize(global_options=[])
249
+ @global_options = global_options
250
+ end
251
+
252
+ # Execute the command.
253
+
254
+ def execute( line=nil )
255
+ case line
256
+ when String
257
+ arguments = Shellwords.shellwords(line)
258
+ when Array
259
+ arguments = line
260
+ else
261
+ arguments = ARGV
262
+ end
263
+
264
+ # duplicate arguments to work on them in-place.
265
+
266
+ argv = arguments.dup
267
+
268
+ # Split single letter option groupings into separate options.
269
+ # ie. -xyz => -x -y -z
270
+
271
+ argv = argv.collect { |arg|
272
+ if md = /^-(\w{2,})/.match( arg )
273
+ md[1].split(//).collect { |c| "-#{c}" }
274
+ else
275
+ arg
276
+ end
277
+ }.flatten
278
+
279
+ # process global options
280
+ global_options.each do |name|
281
+ o = name.to_s.sub('__','--').sub('_','-')
282
+ m = method(name)
283
+ c = m.arity
284
+ while i = argv.index(o)
285
+ args = argv.slice!(i,c+1)
286
+ args.shift
287
+ m.call(*args)
288
+ end
289
+ end
290
+
291
+ # Does this command take subcommands?
292
+ subcommand = !respond_to?(:main)
293
+
294
+ # process primary options
295
+ argv = execute_options( argv, subcommand )
296
+
297
+ # If this command doesn't take subcommands, then the remaining arguments are arguments for main().
298
+ return send(:main, *argv) unless subcommand
299
+
300
+ # What to do if there is nothing else?
301
+ if argv.empty?
302
+ if respond_to?(:default)
303
+ return __send__(:default)
304
+ else
305
+ $stderr << "Nothing to do."
306
+ return
307
+ end
308
+ end
309
+
310
+ # Remaining arguments are subcommand and suboptions.
311
+
312
+ subcmd = argv.shift.gsub('-','_')
313
+ #puts "subcmd = #{subcmd}"
314
+
315
+ # Extend subcommand option module
316
+ subconst = subcmd.gsub(/\W/,'_').capitalize
317
+ #puts self.class.name
318
+ if self.class.const_defined?(subconst)
319
+ puts "Extending self (#{self.class}) with subcommand module #{subconst}" if $debug
320
+ submod = self.class.const_get(subconst)
321
+ self.extend submod
322
+ end
323
+
324
+ # process subcommand options
325
+ #puts "Treating the rest of the args as subcommand options:"
326
+ #p argv
327
+ argv = execute_options( argv )
328
+
329
+ # This is a little tricky. The method has to be defined by a subclass.
330
+ if self.respond_to?( subcmd ) and not Console::Command.public_instance_methods.include?( subcmd.to_s )
331
+ puts "Calling #{subcmd}(#{argv.inspect})" if $debug
332
+ __send__(subcmd, *argv)
333
+ else
334
+ #begin
335
+ puts "Calling method_missing with #{subcmd}, #{argv.inspect}" if $debug
336
+ method_missing(subcmd, *argv)
337
+ #rescue NoMethodError => e
338
+ #if self.private_methods.include?( "no_command_error" )
339
+ # no_command_error( *args )
340
+ #else
341
+ # $stderr << "Non-applicable command -- #{argv.join(' ')}\n"
342
+ # exit -1
343
+ #end
344
+ #end
345
+ end
346
+
347
+ # rescue => err
348
+ # if $DEBUG
349
+ # raise err
350
+ # else
351
+ # msg = err.message.chomp('.') + '.'
352
+ # msg[0,1] = msg[0,1].capitalize
353
+ # msg << " (#{err.class})" if $VERBOSE
354
+ # $stderr << msg
355
+ # end
356
+ end
357
+
358
+ private
359
+
360
+ #
361
+
362
+ def global_options
363
+ @global_options
364
+ end
365
+
366
+ #
367
+
368
+ def execute_options( argv, subcmd=false )
369
+ puts "in execute_options:" if $debug
370
+ argv = argv.dup
371
+ args_to_return = []
372
+ until argv.empty?
373
+ arg = argv.first
374
+ if arg[0,1] == '-'
375
+ puts "'#{arg}' -- is an option" if $debug
376
+
377
+ name = arg.gsub('-','_')
378
+ puts " responds_to(#{name})?" if $debug
379
+ if respond_to?(name)
380
+ m = method(name)
381
+ arity = m.arity
382
+ #puts "{argv before slice: #{argv.inspect}" if $debug
383
+ args_for_current_option = argv.slice!(0, arity+1)
384
+ #puts "}argv after slice: #{argv.inspect}" if $debug
385
+ #puts "{args_for_current_option before shift: #{args_for_current_option.inspect}" if $debug
386
+ args_for_current_option.shift
387
+ #puts "}args_for_current_option after shift: #{args_for_current_option.inspect}" if $debug
388
+ #puts " arity=#{m.arity}" if $debug
389
+ #puts " calling #{name} with #{args_for_current_option.inspect}" if $debug
390
+ m.call(*args_for_current_option)
391
+ elsif respond_to?(:option_missing)
392
+ puts " option_missing(#{argv.inspect})" if $debug
393
+ arity = option_missing(arg.gsub(/^[-]+/,''), argv[1..-1]) || 1
394
+ puts " arity == #{arity}" if $debug
395
+ argv.slice!(0, arity)
396
+ argv.shift # Get rid of the *name* of the option
397
+ else
398
+ $stderr << "Unknown option '#{arg}'.\n"
399
+ exit -1
400
+ end
401
+ else
402
+ puts "'#{arg}' -- not an option. Adding to args_to_return..." if $debug
403
+ if subcmd
404
+ args_to_return = argv
405
+ #puts "subcommand. args_to_return=#{args_to_return.inspect}" if $debug
406
+ break
407
+ else
408
+ args_to_return << argv.shift
409
+ puts "args_to_return=#{args_to_return.inspect}" if $debug
410
+ end
411
+ end
412
+ end
413
+ puts "Returning #{args_to_return.inspect}" if $debug
414
+ return args_to_return
415
+ end
416
+
417
+ public
418
+
419
+ =begin
420
+ # We include a module here so you can define your own help
421
+ # command and call #super to utilize this one.
422
+
423
+ module Help
424
+
425
+ def help
426
+ opts = help_options
427
+ s = ""
428
+ s << "#{File.basename($0)}\n\n"
429
+ unless opts.empty?
430
+ s << "OPTIONS\n"
431
+ s << help_options
432
+ s << "\n"
433
+ end
434
+ s << "COMMANDS\n"
435
+ s << help_commands
436
+ puts s
437
+ end
438
+
439
+ private
440
+
441
+ def help_commands
442
+ help = self.class.help
443
+ bufs = help.keys.collect{ |a| a.to_s.size }.max + 3
444
+ lines = []
445
+ help.each { |cmd, str|
446
+ cmd = cmd.to_s
447
+ if cmd !~ /^_/
448
+ lines << " " + cmd + (" " * (bufs - cmd.size)) + str
449
+ end
450
+ }
451
+ lines.join("\n")
452
+ end
453
+
454
+ def help_options
455
+ help = self.class.help
456
+ bufs = help.keys.collect{ |a| a.to_s.size }.max + 3
457
+ lines = []
458
+ help.each { |cmd, str|
459
+ cmd = cmd.to_s
460
+ if cmd =~ /^_/
461
+ lines << " " + cmd.gsub(/_/,'-') + (" " * (bufs - cmd.size)) + str
462
+ end
463
+ }
464
+ lines.join("\n")
465
+ end
466
+
467
+ module ClassMethods
468
+
469
+ def help( str=nil )
470
+ return (@help ||= {}) unless str
471
+ @current_help = str
472
+ end
473
+
474
+ def method_added( meth )
475
+ if @current_help
476
+ @help ||= {}
477
+ @help[meth] = @current_help
478
+ @current_help = nil
479
+ end
480
+ end
481
+
482
+ end
483
+
484
+ end
485
+
486
+ include Help
487
+ extend Help::ClassMethods
488
+ =end
489
+
490
+ end
491
+
492
+
493
+
494
+ # _____ _
495
+ # |_ _|__ ___| |_
496
+ # | |/ _ \/ __| __|
497
+ # | | __/\__ \ |_
498
+ # |_|\___||___/\__|
499
+ #
500
+
501
+ =begin test
502
+
503
+ require 'test/unit'
504
+ require 'stringio'
505
+
506
+ class TestCommand < Test::Unit::TestCase
507
+ def setup
508
+ $output = nil
509
+ $stderr = StringIO.new
510
+ end
511
+
512
+ #
513
+
514
+ class SimpleCommand < Console::Command
515
+ def __here ; @here = true ; end
516
+
517
+ def main(*args)
518
+ $output = [@here] | args
519
+ end
520
+ end
521
+
522
+ def test_SimpleCommand
523
+ SimpleCommand.execute( '--here file1 file2' )
524
+ assert_equal( [true, 'file1', 'file2'], $output )
525
+ end
526
+
527
+ #
528
+
529
+ class CommandWithMethodMissingSubcommand < Console::Command
530
+ def __here ; @here = true ; end
531
+
532
+ def method_missing(subcommand, *args)
533
+ $output = [@here, subcommand] | args
534
+ end
535
+ end
536
+
537
+ def test_CommandWithMethodMissingSubcommand
538
+ CommandWithMethodMissingSubcommand.execute( '--here go file1' )
539
+ assert_equal( [true, 'go', 'file1'], $output )
540
+ end
541
+
542
+ #
543
+
544
+ class CommandWithSimpleSubcommand < Console::Command
545
+ def __here ; @here = true ; end
546
+
547
+ # subcommand
548
+
549
+ module Go
550
+ def _p(n)
551
+ @p = n.to_i
552
+ end
553
+ end
554
+
555
+ def go ; $output = [@here, @p] ; end
556
+ end
557
+
558
+ def test_CommandWithSimpleSubcommand
559
+ CommandWithSimpleSubcommand.execute( '--here go -p 1' )
560
+ assert_equal( [true, 1], $output )
561
+ end
562
+
563
+ #
564
+
565
+ # Global options can be anywhere, right? Even after subcommands? Let's find out.
566
+ class CommandWithGlobalOptionsAfterSubcommand < Console::Command
567
+ def _x ; @x = true ; end
568
+ global_option :_x
569
+
570
+ def go ; $output = [@x, @p] ; end
571
+
572
+ module Go
573
+ def _p(n)
574
+ @p = n.to_i
575
+ end
576
+ end
577
+ end
578
+
579
+ def test_CommandWithGlobalOptionsAfterSubcommand
580
+ CommandWithGlobalOptionsAfterSubcommand.execute( 'go -x -p 1' )
581
+ assert_equal( [true, 1], $output )
582
+
583
+ CommandWithGlobalOptionsAfterSubcommand.execute( 'go -p 1 -x' )
584
+ assert_equal( [true, 1], $output )
585
+ end
586
+
587
+ #
588
+
589
+ class GivingUnrecognizedOptions < Console::Command
590
+ def _x ; @x = true ; end
591
+ def go ; $output = [@x, @p] ; end
592
+ end
593
+
594
+ def test_GivingUnrecognizedOptions
595
+ assert_raise(SystemExit) do
596
+ GivingUnrecognizedOptions.execute( '--an-option-that-wont-be-recognized -x go' )
597
+ end
598
+ assert_equal "Unknown option '--an-option-that-wont-be-recognized'.\n", $stderr.string
599
+ assert_equal( nil, $output )
600
+ end
601
+ #
602
+
603
+ class PassingMultipleSingleCharOptionsAsOneOption < Console::Command
604
+ def _x ; @x = true ; end
605
+ def _y ; @y = true ; end
606
+ def _z(n) ; @z = n ; end
607
+
608
+ global_option :_x
609
+
610
+ def go ; $output = [@x, @y, @z, @p] ; end
611
+
612
+ module Go
613
+ def _p(n)
614
+ @p = n.to_i
615
+ end
616
+ end
617
+ end
618
+
619
+ def test_PassingMultipleSingleCharOptionsAsOneOption
620
+ PassingMultipleSingleCharOptionsAsOneOption.execute( '-xy -z HERE go -p 1' )
621
+ assert_equal( [true, true, 'HERE', 1], $output )
622
+ end
623
+
624
+ #
625
+
626
+ class CommandWithOptionUsingEquals < Console::Command
627
+ module Go
628
+ def __mode(mode) ; @mode = mode ; end
629
+ end
630
+ def go ; $output = [@mode] ; end
631
+ end
632
+
633
+ def test_CommandWithOptionUsingEquals
634
+ CommandWithOptionUsingEquals.execute( 'go --mode smart' )
635
+ assert_equal( ['smart'], $output )
636
+
637
+ # I would expect this to work too, but currently it doesn't.
638
+ #assert_nothing_raised { CommandWithOptionUsingEquals.execute( 'go --mode=smart' ) }
639
+ #assert_equal( ['smart'], $output )
640
+ end
641
+
642
+ #
643
+
644
+ class CommandWithSubcommandThatTakesArgs < Console::Command
645
+ def go(arg1, *args) ; $output = [arg1] | args ; end
646
+ end
647
+
648
+ def test_CommandWithSubcommandThatTakesArgs
649
+ CommandWithSubcommandThatTakesArgs.execute( 'go file1 file2 file3' )
650
+ assert_equal( ['file1', 'file2', 'file3'], $output )
651
+ end
652
+
653
+ #
654
+
655
+ class CommandWith2OptionalArgs < Console::Command
656
+ def __here ; @here = true ; end
657
+
658
+ module Go
659
+ def _p(n)
660
+ @p = n.to_i
661
+ end
662
+ end
663
+
664
+ def go(required1 = nil, optional2 = nil) ; $output = [@here, @p, required1, optional2 ] ; end
665
+ end
666
+
667
+ def test_CommandWith2OptionalArgs
668
+ CommandWith2OptionalArgs.execute( '--here go -p 1 to' )
669
+ assert_equal( [true, 1, 'to', nil], $output )
670
+ end
671
+
672
+ #
673
+
674
+ class CommandWithVariableArgs < Console::Command
675
+ def __here ; @here = true ; end
676
+
677
+ module Go
678
+ def _p(n)
679
+ @p = n.to_i
680
+ end
681
+ end
682
+
683
+ def go(*args) ; $output = [@here, @p] | args ; end
684
+ end
685
+
686
+ def test_CommandWithVariableArgs
687
+ CommandWithVariableArgs.execute( '--here go -p 1 to bed' )
688
+ assert_equal( [true, 1, 'to', 'bed'], $output )
689
+ end
690
+
691
+ #
692
+
693
+ class CommandWithOptionMissing < Console::Command
694
+ def __here ; @here = true ; end
695
+
696
+ module Go
697
+ def option_missing(option_name, args)
698
+ p args if $debug
699
+ case option_name
700
+ when 'p'
701
+ @p = args[0].to_i
702
+ 1
703
+ else
704
+ raise InvalidOptionError(option_name, args)
705
+ end
706
+ end
707
+ end
708
+
709
+ def go(*args) ; $output = [@here, @p] | args ; end
710
+ end
711
+
712
+ def test_CommandWithOptionMissing
713
+ CommandWithOptionMissing.execute( '--here go -p 1 to bed right now' )
714
+ assert_equal( [true, 1, 'to', 'bed', 'right', 'now'], $output )
715
+ end
716
+
717
+ #
718
+
719
+ class CommandWithOptionMissingArityOf2 < Console::Command
720
+ def __here ; @here = true ; end
721
+
722
+ module Go
723
+ def option_missing(option_name, args)
724
+ p args if $debug
725
+ case option_name
726
+ when 'p'
727
+ @p1 = args[0].to_i
728
+ @p2 = args[1].to_i
729
+ 2
730
+ when 'q'
731
+ @q = args[0].to_i
732
+ nil # Test default arity
733
+ else
734
+ raise InvalidOptionError(option_name, args)
735
+ end
736
+ end
737
+ end
738
+
739
+ def go(*args) ; $output = [@here, @p1, @p2, @q] | args ; end
740
+ end
741
+
742
+ def test_CommandWithOptionMissingArityOf2
743
+ CommandWithOptionMissingArityOf2.execute( '--here go -p 1 2 -q 3 to bed right now' )
744
+ assert_equal( [true, 1, 2, 3, 'to', 'bed', 'right', 'now'], $output )
745
+ end
746
+ end
747
+
748
+ =end