amp-front 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. data/.document +5 -0
  2. data/.gitignore +24 -0
  3. data/Ampfile +3 -0
  4. data/Gemfile +10 -0
  5. data/Gemfile.lock +36 -0
  6. data/LICENSE +20 -0
  7. data/README.md +50 -0
  8. data/Rakefile +64 -0
  9. data/VERSION +1 -0
  10. data/design_docs/commands.md +91 -0
  11. data/design_docs/dependencies.md +35 -0
  12. data/design_docs/plugins.md +47 -0
  13. data/features/amp.feature +8 -0
  14. data/features/amp_help.feature +36 -0
  15. data/features/amp_plugin_list.feature +10 -0
  16. data/features/step_definitions/amp-front_steps.rb +23 -0
  17. data/features/support/env.rb +4 -0
  18. data/lib/amp-front.rb +30 -0
  19. data/lib/amp-front/dispatch/commands/base.rb +158 -0
  20. data/lib/amp-front/dispatch/commands/builtin/help.rb +23 -0
  21. data/lib/amp-front/dispatch/commands/builtin/plugin.rb +24 -0
  22. data/lib/amp-front/dispatch/commands/validations.rb +171 -0
  23. data/lib/amp-front/dispatch/runner.rb +86 -0
  24. data/lib/amp-front/help/entries/__default__.erb +31 -0
  25. data/lib/amp-front/help/entries/ampfiles.md +42 -0
  26. data/lib/amp-front/help/entries/commands.erb +6 -0
  27. data/lib/amp-front/help/entries/new-commands.md +81 -0
  28. data/lib/amp-front/help/help.rb +312 -0
  29. data/lib/amp-front/plugins/base.rb +87 -0
  30. data/lib/amp-front/support/module_extensions.rb +92 -0
  31. data/lib/amp-front/third_party/maruku.rb +136 -0
  32. data/lib/amp-front/third_party/maruku/attributes.rb +227 -0
  33. data/lib/amp-front/third_party/maruku/defaults.rb +71 -0
  34. data/lib/amp-front/third_party/maruku/errors_management.rb +92 -0
  35. data/lib/amp-front/third_party/maruku/helpers.rb +260 -0
  36. data/lib/amp-front/third_party/maruku/input/charsource.rb +326 -0
  37. data/lib/amp-front/third_party/maruku/input/extensions.rb +69 -0
  38. data/lib/amp-front/third_party/maruku/input/html_helper.rb +189 -0
  39. data/lib/amp-front/third_party/maruku/input/linesource.rb +111 -0
  40. data/lib/amp-front/third_party/maruku/input/parse_block.rb +615 -0
  41. data/lib/amp-front/third_party/maruku/input/parse_doc.rb +234 -0
  42. data/lib/amp-front/third_party/maruku/input/parse_span_better.rb +746 -0
  43. data/lib/amp-front/third_party/maruku/input/rubypants.rb +225 -0
  44. data/lib/amp-front/third_party/maruku/input/type_detection.rb +147 -0
  45. data/lib/amp-front/third_party/maruku/input_textile2/t2_parser.rb +163 -0
  46. data/lib/amp-front/third_party/maruku/maruku.rb +33 -0
  47. data/lib/amp-front/third_party/maruku/output/to_ansi.rb +223 -0
  48. data/lib/amp-front/third_party/maruku/output/to_html.rb +991 -0
  49. data/lib/amp-front/third_party/maruku/output/to_markdown.rb +164 -0
  50. data/lib/amp-front/third_party/maruku/output/to_s.rb +56 -0
  51. data/lib/amp-front/third_party/maruku/string_utils.rb +191 -0
  52. data/lib/amp-front/third_party/maruku/structures.rb +167 -0
  53. data/lib/amp-front/third_party/maruku/structures_inspect.rb +87 -0
  54. data/lib/amp-front/third_party/maruku/structures_iterators.rb +61 -0
  55. data/lib/amp-front/third_party/maruku/textile2.rb +1 -0
  56. data/lib/amp-front/third_party/maruku/toc.rb +199 -0
  57. data/lib/amp-front/third_party/maruku/usage/example1.rb +33 -0
  58. data/lib/amp-front/third_party/maruku/version.rb +40 -0
  59. data/lib/amp-front/third_party/trollop.rb +766 -0
  60. data/spec/amp-front_spec.rb +25 -0
  61. data/spec/command_specs/base_spec.rb +123 -0
  62. data/spec/command_specs/command_spec.rb +97 -0
  63. data/spec/command_specs/help_spec.rb +33 -0
  64. data/spec/command_specs/spec_helper.rb +37 -0
  65. data/spec/command_specs/validations_spec.rb +267 -0
  66. data/spec/dispatch_specs/runner_spec.rb +116 -0
  67. data/spec/dispatch_specs/spec_helper.rb +15 -0
  68. data/spec/help_specs/help_entry_spec.rb +78 -0
  69. data/spec/help_specs/help_registry_spec.rb +77 -0
  70. data/spec/help_specs/spec_helper.rb +15 -0
  71. data/spec/plugin_specs/base_spec.rb +36 -0
  72. data/spec/plugin_specs/spec_helper.rb +15 -0
  73. data/spec/spec.opts +1 -0
  74. data/spec/spec_helper.rb +33 -0
  75. data/spec/support_specs/module_extensions_spec.rb +104 -0
  76. data/spec/support_specs/spec_helper.rb +15 -0
  77. data/test/third_party_tests/test_trollop.rb +1181 -0
  78. metadata +192 -0
@@ -0,0 +1,15 @@
1
+ ##################################################################
2
+ # Licensing Information #
3
+ # #
4
+ # The following code is licensed, as standalone code, under #
5
+ # the Ruby License, unless otherwise directed within the code. #
6
+ # #
7
+ # For information on the license of this code when distributed #
8
+ # with and used in conjunction with the other modules in the #
9
+ # Amp project, please see the root-level LICENSE file. #
10
+ # #
11
+ # © Michael J. Edgar and Ari Brown, 2009-2010 #
12
+ # #
13
+ ##################################################################
14
+
15
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
@@ -0,0 +1,1181 @@
1
+ ## test/test_trollop.rb -- unit tests for trollop
2
+ ## Author:: William Morgan (mailto: wmorgan-trollop@masanjin.net)
3
+ ## Copyright:: Copyright 2007 William Morgan
4
+ ## License:: GNU GPL version 2
5
+
6
+ require 'test/unit'
7
+ require 'stringio'
8
+ require 'amp-front/third_party/trollop'
9
+
10
+ module Trollop
11
+ module Test
12
+
13
+ class Trollop < ::Test::Unit::TestCase
14
+ def setup
15
+ @p = Parser.new
16
+ end
17
+
18
+ def test_die_without_options_ever_run
19
+ ::Trollop.send(:instance_variable_set, "@last_parser", nil)
20
+ assert_raise(ArgumentError) { ::Trollop.die 'hello' }
21
+ end
22
+
23
+ def test_unknown_arguments
24
+ assert_raise(CommandlineError) { @p.parse(%w(--arg)) }
25
+ @p.opt "arg"
26
+ assert_nothing_raised { @p.parse(%w(--arg)) }
27
+ assert_raise(CommandlineError) { @p.parse(%w(--arg2)) }
28
+ end
29
+
30
+ def test_syntax_check
31
+ @p.opt "arg"
32
+
33
+ assert_nothing_raised { @p.parse(%w(--arg)) }
34
+ assert_nothing_raised { @p.parse(%w(arg)) }
35
+ assert_raise(CommandlineError) { @p.parse(%w(---arg)) }
36
+ assert_raise(CommandlineError) { @p.parse(%w(-arg)) }
37
+ end
38
+
39
+ def test_required_flags_are_required
40
+ @p.opt "arg", "desc", :required => true
41
+ @p.opt "arg2", "desc", :required => false
42
+ @p.opt "arg3", "desc", :required => false
43
+
44
+ assert_nothing_raised { @p.parse(%w(--arg)) }
45
+ assert_nothing_raised { @p.parse(%w(--arg --arg2)) }
46
+ assert_raise(CommandlineError) { @p.parse(%w(--arg2)) }
47
+ assert_raise(CommandlineError) { @p.parse(%w(--arg2 --arg3)) }
48
+ end
49
+
50
+ ## flags that take an argument error unless given one
51
+ def test_argflags_demand_args
52
+ @p.opt "goodarg", "desc", :type => String
53
+ @p.opt "goodarg2", "desc", :type => String
54
+
55
+ assert_nothing_raised { @p.parse(%w(--goodarg goat)) }
56
+ assert_raise(CommandlineError) { @p.parse(%w(--goodarg --goodarg2 goat)) }
57
+ assert_raise(CommandlineError) { @p.parse(%w(--goodarg)) }
58
+ end
59
+
60
+ ## flags that don't take arguments ignore them
61
+ def test_arglessflags_refuse_args
62
+ @p.opt "goodarg"
63
+ @p.opt "goodarg2"
64
+ assert_nothing_raised { @p.parse(%w(--goodarg)) }
65
+ assert_nothing_raised { @p.parse(%w(--goodarg --goodarg2)) }
66
+ opts = @p.parse %w(--goodarg a)
67
+ assert_equal true, opts["goodarg"]
68
+ assert_equal ["a"], @p.leftovers
69
+ end
70
+
71
+ ## flags that require args of a specific type refuse args of other
72
+ ## types
73
+ def test_typed_args_refuse_args_of_other_types
74
+ assert_nothing_raised { @p.opt "goodarg", "desc", :type => :int }
75
+ assert_raise(ArgumentError) { @p.opt "badarg", "desc", :type => :asdf }
76
+
77
+ assert_nothing_raised { @p.parse(%w(--goodarg 3)) }
78
+ assert_raise(CommandlineError) { @p.parse(%w(--goodarg 4.2)) }
79
+ assert_raise(CommandlineError) { @p.parse(%w(--goodarg hello)) }
80
+ end
81
+
82
+ ## type is correctly derived from :default
83
+ def test_type_correctly_derived_from_default
84
+ assert_raise(ArgumentError) { @p.opt "badarg", "desc", :default => [] }
85
+ assert_raise(ArgumentError) { @p.opt "badarg3", "desc", :default => [{1 => 2}] }
86
+ assert_raise(ArgumentError) { @p.opt "badarg4", "desc", :default => Hash.new }
87
+
88
+ opts = nil
89
+
90
+ # single arg: int
91
+ assert_nothing_raised { @p.opt "argsi", "desc", :default => 0 }
92
+ assert_nothing_raised { opts = @p.parse(%w(--)) }
93
+ assert_equal 0, opts["argsi"]
94
+ assert_nothing_raised { opts = @p.parse(%w(--argsi 4)) }
95
+ assert_equal 4, opts["argsi"]
96
+ assert_raise(CommandlineError) { @p.parse(%w(--argsi 4.2)) }
97
+ assert_raise(CommandlineError) { @p.parse(%w(--argsi hello)) }
98
+
99
+ # single arg: float
100
+ assert_nothing_raised { @p.opt "argsf", "desc", :default => 3.14 }
101
+ assert_nothing_raised { opts = @p.parse(%w(--)) }
102
+ assert_equal 3.14, opts["argsf"]
103
+ assert_nothing_raised { opts = @p.parse(%w(--argsf 2.41)) }
104
+ assert_equal 2.41, opts["argsf"]
105
+ assert_nothing_raised { opts = @p.parse(%w(--argsf 2)) }
106
+ assert_equal 2, opts["argsf"]
107
+ assert_nothing_raised { opts = @p.parse(%w(--argsf 1.0e-2)) }
108
+ assert_equal 1.0e-2, opts["argsf"]
109
+ assert_raise(CommandlineError) { @p.parse(%w(--argsf hello)) }
110
+
111
+ # single arg: date
112
+ date = Date.today
113
+ assert_nothing_raised { @p.opt "argsd", "desc", :default => date }
114
+ assert_nothing_raised { opts = @p.parse(%w(--)) }
115
+ assert_equal Date.today, opts["argsd"]
116
+ assert_nothing_raised { opts = @p.parse(['--argsd', 'Jan 4, 2007']) }
117
+ assert_equal Date.civil(2007, 1, 4), opts["argsd"]
118
+ assert_raise(CommandlineError) { @p.parse(%w(--argsd hello)) }
119
+
120
+ # single arg: string
121
+ assert_nothing_raised { @p.opt "argss", "desc", :default => "foobar" }
122
+ assert_nothing_raised { opts = @p.parse(%w(--)) }
123
+ assert_equal "foobar", opts["argss"]
124
+ assert_nothing_raised { opts = @p.parse(%w(--argss 2.41)) }
125
+ assert_equal "2.41", opts["argss"]
126
+ assert_nothing_raised { opts = @p.parse(%w(--argss hello)) }
127
+ assert_equal "hello", opts["argss"]
128
+
129
+ # multi args: ints
130
+ assert_nothing_raised { @p.opt "argmi", "desc", :default => [3, 5] }
131
+ assert_nothing_raised { opts = @p.parse(%w(--)) }
132
+ assert_equal [3, 5], opts["argmi"]
133
+ assert_nothing_raised { opts = @p.parse(%w(--argmi 4)) }
134
+ assert_equal [4], opts["argmi"]
135
+ assert_raise(CommandlineError) { @p.parse(%w(--argmi 4.2)) }
136
+ assert_raise(CommandlineError) { @p.parse(%w(--argmi hello)) }
137
+
138
+ # multi args: floats
139
+ assert_nothing_raised { @p.opt "argmf", "desc", :default => [3.34, 5.21] }
140
+ assert_nothing_raised { opts = @p.parse(%w(--)) }
141
+ assert_equal [3.34, 5.21], opts["argmf"]
142
+ assert_nothing_raised { opts = @p.parse(%w(--argmf 2)) }
143
+ assert_equal [2], opts["argmf"]
144
+ assert_nothing_raised { opts = @p.parse(%w(--argmf 4.0)) }
145
+ assert_equal [4.0], opts["argmf"]
146
+ assert_raise(CommandlineError) { @p.parse(%w(--argmf hello)) }
147
+
148
+ # multi args: dates
149
+ dates = [Date.today, Date.civil(2007, 1, 4)]
150
+ assert_nothing_raised { @p.opt "argmd", "desc", :default => dates }
151
+ assert_nothing_raised { opts = @p.parse(%w(--)) }
152
+ assert_equal dates, opts["argmd"]
153
+ assert_nothing_raised { opts = @p.parse(['--argmd', 'Jan 4, 2007']) }
154
+ assert_equal [Date.civil(2007, 1, 4)], opts["argmd"]
155
+ assert_raise(CommandlineError) { @p.parse(%w(--argmd hello)) }
156
+
157
+ # multi args: strings
158
+ assert_nothing_raised { @p.opt "argmst", "desc", :default => %w(hello world) }
159
+ assert_nothing_raised { opts = @p.parse(%w(--)) }
160
+ assert_equal %w(hello world), opts["argmst"]
161
+ assert_nothing_raised { opts = @p.parse(%w(--argmst 3.4)) }
162
+ assert_equal ["3.4"], opts["argmst"]
163
+ assert_nothing_raised { opts = @p.parse(%w(--argmst goodbye)) }
164
+ assert_equal ["goodbye"], opts["argmst"]
165
+ end
166
+
167
+ ## :type and :default must match if both are specified
168
+ def test_type_and_default_must_match
169
+ assert_raise(ArgumentError) { @p.opt "badarg", "desc", :type => :int, :default => "hello" }
170
+ assert_raise(ArgumentError) { @p.opt "badarg2", "desc", :type => :String, :default => 4 }
171
+ assert_raise(ArgumentError) { @p.opt "badarg2", "desc", :type => :String, :default => ["hi"] }
172
+ assert_raise(ArgumentError) { @p.opt "badarg2", "desc", :type => :ints, :default => [3.14] }
173
+
174
+ assert_nothing_raised { @p.opt "argsi", "desc", :type => :int, :default => 4 }
175
+ assert_nothing_raised { @p.opt "argsf", "desc", :type => :float, :default => 3.14 }
176
+ assert_nothing_raised { @p.opt "argsd", "desc", :type => :date, :default => Date.today }
177
+ assert_nothing_raised { @p.opt "argss", "desc", :type => :string, :default => "yo" }
178
+ assert_nothing_raised { @p.opt "argmi", "desc", :type => :ints, :default => [4] }
179
+ assert_nothing_raised { @p.opt "argmf", "desc", :type => :floats, :default => [3.14] }
180
+ assert_nothing_raised { @p.opt "argmd", "desc", :type => :dates, :default => [Date.today] }
181
+ assert_nothing_raised { @p.opt "argmst", "desc", :type => :strings, :default => ["yo"] }
182
+ end
183
+
184
+ def test_long_detects_bad_names
185
+ assert_nothing_raised { @p.opt "goodarg", "desc", :long => "none" }
186
+ assert_nothing_raised { @p.opt "goodarg2", "desc", :long => "--two" }
187
+ assert_raise(ArgumentError) { @p.opt "badarg", "desc", :long => "" }
188
+ assert_raise(ArgumentError) { @p.opt "badarg2", "desc", :long => "--" }
189
+ assert_raise(ArgumentError) { @p.opt "badarg3", "desc", :long => "-one" }
190
+ assert_raise(ArgumentError) { @p.opt "badarg4", "desc", :long => "---toomany" }
191
+ end
192
+
193
+ def test_short_detects_bad_names
194
+ assert_nothing_raised { @p.opt "goodarg", "desc", :short => "a" }
195
+ assert_nothing_raised { @p.opt "goodarg2", "desc", :short => "-b" }
196
+ assert_raise(ArgumentError) { @p.opt "badarg", "desc", :short => "" }
197
+ assert_raise(ArgumentError) { @p.opt "badarg2", "desc", :short => "-ab" }
198
+ assert_raise(ArgumentError) { @p.opt "badarg3", "desc", :short => "--t" }
199
+ end
200
+
201
+ def test_short_names_created_automatically
202
+ @p.opt "arg"
203
+ @p.opt "arg2"
204
+ @p.opt "arg3"
205
+ opts = @p.parse %w(-a -g)
206
+ assert_equal true, opts["arg"]
207
+ assert_equal false, opts["arg2"]
208
+ assert_equal true, opts["arg3"]
209
+ end
210
+
211
+ def test_short_autocreation_skips_dashes_and_numbers
212
+ @p.opt :arg # auto: a
213
+ @p.opt :arg_potato # auto: r
214
+ @p.opt :arg_muffin # auto: g
215
+ assert_nothing_raised { @p.opt :arg_daisy } # auto: d (not _)!
216
+ assert_nothing_raised { @p.opt :arg_r2d2f } # auto: f (not 2)!
217
+
218
+ opts = @p.parse %w(-f -d)
219
+ assert_equal true, opts[:arg_daisy]
220
+ assert_equal true, opts[:arg_r2d2f]
221
+ assert_equal false, opts[:arg]
222
+ assert_equal false, opts[:arg_potato]
223
+ assert_equal false, opts[:arg_muffin]
224
+ end
225
+
226
+ def test_short_autocreation_is_ok_with_running_out_of_chars
227
+ @p.opt :arg1 # auto: a
228
+ @p.opt :arg2 # auto: r
229
+ @p.opt :arg3 # auto: g
230
+ @p.opt :arg4 # auto: uh oh!
231
+ assert_nothing_raised { @p.parse [] }
232
+ end
233
+
234
+ def test_short_can_be_nothing
235
+ assert_nothing_raised do
236
+ @p.opt "arg", "desc", :short => :none
237
+ @p.parse []
238
+ end
239
+
240
+ sio = StringIO.new "w"
241
+ @p.educate sio
242
+ assert sio.string =~ /--arg:\s+desc/
243
+
244
+ assert_raise(CommandlineError) { @p.parse %w(-a) }
245
+ end
246
+
247
+ ## two args can't have the same name
248
+ def test_conflicting_names_are_detected
249
+ assert_nothing_raised { @p.opt "goodarg" }
250
+ assert_raise(ArgumentError) { @p.opt "goodarg" }
251
+ end
252
+
253
+ ## two args can't have the same :long
254
+ def test_conflicting_longs_detected
255
+ assert_nothing_raised { @p.opt "goodarg", "desc", :long => "--goodarg" }
256
+ assert_raise(ArgumentError) { @p.opt "badarg", "desc", :long => "--goodarg" }
257
+ end
258
+
259
+ ## two args can't have the same :short
260
+ def test_conflicting_shorts_detected
261
+ assert_nothing_raised { @p.opt "goodarg", "desc", :short => "-g" }
262
+ assert_raise(ArgumentError) { @p.opt "badarg", "desc", :short => "-g" }
263
+ end
264
+
265
+ def test_flag_defaults
266
+ @p.opt "defaultfalse", "desc"
267
+ @p.opt "defaulttrue", "desc", :default => true
268
+ opts = @p.parse []
269
+ assert_equal false, opts["defaultfalse"]
270
+ assert_equal true, opts["defaulttrue"]
271
+
272
+ opts = @p.parse %w(--defaultfalse --defaulttrue)
273
+ assert_equal true, opts["defaultfalse"]
274
+ assert_equal false, opts["defaulttrue"]
275
+ end
276
+
277
+ def test_special_flags_work
278
+ @p.version "asdf fdas"
279
+ assert_raise(VersionNeeded) { @p.parse(%w(-v)) }
280
+ assert_raise(HelpNeeded) { @p.parse(%w(-h)) }
281
+ end
282
+
283
+ def test_short_options_combine
284
+ @p.opt :arg1, "desc", :short => "a"
285
+ @p.opt :arg2, "desc", :short => "b"
286
+ @p.opt :arg3, "desc", :short => "c", :type => :int
287
+
288
+ opts = nil
289
+ assert_nothing_raised { opts = @p.parse %w(-a -b) }
290
+ assert_equal true, opts[:arg1]
291
+ assert_equal true, opts[:arg2]
292
+ assert_equal nil, opts[:arg3]
293
+
294
+ assert_nothing_raised { opts = @p.parse %w(-ab) }
295
+ assert_equal true, opts[:arg1]
296
+ assert_equal true, opts[:arg2]
297
+ assert_equal nil, opts[:arg3]
298
+
299
+ assert_nothing_raised { opts = @p.parse %w(-ac 4 -b) }
300
+ assert_equal true, opts[:arg1]
301
+ assert_equal true, opts[:arg2]
302
+ assert_equal 4, opts[:arg3]
303
+
304
+ assert_raises(CommandlineError) { @p.parse %w(-cab 4) }
305
+ assert_raises(CommandlineError) { @p.parse %w(-cba 4) }
306
+ end
307
+
308
+ def test_version_only_appears_if_set
309
+ @p.opt "arg"
310
+ assert_raise(CommandlineError) { @p.parse %w(-v) }
311
+ @p.version "trollop 1.2.3.4"
312
+ assert_raise(VersionNeeded) { @p.parse %w(-v) }
313
+ end
314
+
315
+ def test_doubledash_ends_option_processing
316
+ @p.opt :arg1, "desc", :short => "a", :default => 0
317
+ @p.opt :arg2, "desc", :short => "b", :default => 0
318
+ opts = nil
319
+ assert_nothing_raised { opts = @p.parse %w(-- -a 3 -b 2) }
320
+ assert_equal opts[:arg1], 0
321
+ assert_equal opts[:arg2], 0
322
+ assert_equal %w(-a 3 -b 2), @p.leftovers
323
+ assert_nothing_raised { opts = @p.parse %w(-a 3 -- -b 2) }
324
+ assert_equal opts[:arg1], 3
325
+ assert_equal opts[:arg2], 0
326
+ assert_equal %w(-b 2), @p.leftovers
327
+ assert_nothing_raised { opts = @p.parse %w(-a 3 -b 2 --) }
328
+ assert_equal opts[:arg1], 3
329
+ assert_equal opts[:arg2], 2
330
+ assert_equal %w(), @p.leftovers
331
+ end
332
+
333
+ def test_wrap
334
+ assert_equal [""], @p.wrap("")
335
+ assert_equal ["a"], @p.wrap("a")
336
+ assert_equal ["one two", "three"], @p.wrap("one two three", :width => 8)
337
+ assert_equal ["one two three"], @p.wrap("one two three", :width => 80)
338
+ assert_equal ["one", "two", "three"], @p.wrap("one two three", :width => 3)
339
+ assert_equal ["onetwothree"], @p.wrap("onetwothree", :width => 3)
340
+ assert_equal [
341
+ "Test is an awesome program that does something very, very important.",
342
+ "",
343
+ "Usage:",
344
+ " test [options] <filenames>+",
345
+ "where [options] are:"], @p.wrap(<<EOM, :width => 100)
346
+ Test is an awesome program that does something very, very important.
347
+
348
+ Usage:
349
+ test [options] <filenames>+
350
+ where [options] are:
351
+ EOM
352
+ end
353
+
354
+ def test_floating_point_formatting
355
+ @p.opt :arg, "desc", :type => :float, :short => "f"
356
+ opts = nil
357
+ assert_nothing_raised { opts = @p.parse %w(-f 1) }
358
+ assert_equal 1.0, opts[:arg]
359
+ assert_nothing_raised { opts = @p.parse %w(-f 1.0) }
360
+ assert_equal 1.0, opts[:arg]
361
+ assert_nothing_raised { opts = @p.parse %w(-f 0.1) }
362
+ assert_equal 0.1, opts[:arg]
363
+ assert_nothing_raised { opts = @p.parse %w(-f .1) }
364
+ assert_equal 0.1, opts[:arg]
365
+ assert_nothing_raised { opts = @p.parse %w(-f .99999999999999999999) }
366
+ assert_equal 1.0, opts[:arg]
367
+ assert_nothing_raised { opts = @p.parse %w(-f -1) }
368
+ assert_equal(-1.0, opts[:arg])
369
+ assert_nothing_raised { opts = @p.parse %w(-f -1.0) }
370
+ assert_equal(-1.0, opts[:arg])
371
+ assert_nothing_raised { opts = @p.parse %w(-f -0.1) }
372
+ assert_equal(-0.1, opts[:arg])
373
+ assert_nothing_raised { opts = @p.parse %w(-f -.1) }
374
+ assert_equal(-0.1, opts[:arg])
375
+ assert_raises(CommandlineError) { @p.parse %w(-f a) }
376
+ assert_raises(CommandlineError) { @p.parse %w(-f 1a) }
377
+ assert_raises(CommandlineError) { @p.parse %w(-f 1.a) }
378
+ assert_raises(CommandlineError) { @p.parse %w(-f a.1) }
379
+ assert_raises(CommandlineError) { @p.parse %w(-f 1.0.0) }
380
+ assert_raises(CommandlineError) { @p.parse %w(-f .) }
381
+ assert_raises(CommandlineError) { @p.parse %w(-f -.) }
382
+ end
383
+
384
+ def test_date_formatting
385
+ @p.opt :arg, "desc", :type => :date, :short => 'd'
386
+ opts = nil
387
+ assert_nothing_raised { opts = @p.parse(['-d', 'Jan 4, 2007']) }
388
+ assert_equal Date.civil(2007, 1, 4), opts[:arg]
389
+ end
390
+
391
+ def test_short_options_cant_be_numeric
392
+ assert_raises(ArgumentError) { @p.opt :arg, "desc", :short => "-1" }
393
+ @p.opt :a1b, "desc"
394
+ @p.opt :a2b, "desc"
395
+ assert_not_equal "2", @p.specs[:a2b][:short]
396
+ end
397
+
398
+ def test_short_options_can_be_weird
399
+ assert_nothing_raised { @p.opt :arg1, "desc", :short => "#" }
400
+ assert_nothing_raised { @p.opt :arg2, "desc", :short => "." }
401
+ assert_raises(ArgumentError) { @p.opt :arg3, "desc", :short => "-" }
402
+ end
403
+
404
+ def test_options_cant_be_set_multiple_times_if_not_specified
405
+ @p.opt :arg, "desc", :short => "-x"
406
+ assert_nothing_raised { @p.parse %w(-x) }
407
+ assert_raises(CommandlineError) { @p.parse %w(-x -x) }
408
+ assert_raises(CommandlineError) { @p.parse %w(-xx) }
409
+ end
410
+
411
+ def test_options_can_be_set_multiple_times_if_specified
412
+ assert_nothing_raised do
413
+ @p.opt :arg, "desc", :short => "-x", :multi => true
414
+ end
415
+ assert_nothing_raised { @p.parse %w(-x) }
416
+ assert_nothing_raised { @p.parse %w(-x -x) }
417
+ assert_nothing_raised { @p.parse %w(-xx) }
418
+ end
419
+
420
+ def test_short_options_with_multiple_options
421
+ opts = nil
422
+
423
+ assert_nothing_raised do
424
+ @p.opt :xarg, "desc", :short => "-x", :type => String, :multi => true
425
+ end
426
+ assert_nothing_raised { opts = @p.parse %w(-x a -x b) }
427
+ assert_equal %w(a b), opts[:xarg]
428
+ assert_equal [], @p.leftovers
429
+ end
430
+
431
+ def short_options_with_multiple_options_does_not_affect_flags_type
432
+ opts = nil
433
+
434
+ assert_nothing_raised do
435
+ @p.opt :xarg, "desc", :short => "-x", :type => :flag, :multi => true
436
+ end
437
+
438
+ assert_nothing_raised { opts = @p.parse %w(-x a) }
439
+ assert_equal true, opts[:xarg]
440
+ assert_equal %w(a), @p.leftovers
441
+
442
+ assert_nothing_raised { opts = @p.parse %w(-x a -x b) }
443
+ assert_equal true, opts[:xarg]
444
+ assert_equal %w(a b), @p.leftovers
445
+
446
+ assert_nothing_raised { opts = @p.parse %w(-xx a -x b) }
447
+ assert_equal true, opts[:xarg]
448
+ assert_equal %w(a b), @p.leftovers
449
+ end
450
+
451
+ def test_short_options_with_multiple_arguments
452
+ opts = nil
453
+
454
+ @p.opt :xarg, "desc", :type => :ints
455
+ assert_nothing_raised { opts = @p.parse %w(-x 3 4 0) }
456
+ assert_equal [3, 4, 0], opts[:xarg]
457
+ assert_equal [], @p.leftovers
458
+
459
+ @p.opt :yarg, "desc", :type => :floats
460
+ assert_nothing_raised { opts = @p.parse %w(-y 3.14 4.21 0.66) }
461
+ assert_equal [3.14, 4.21, 0.66], opts[:yarg]
462
+ assert_equal [], @p.leftovers
463
+
464
+ @p.opt :zarg, "desc", :type => :strings
465
+ assert_nothing_raised { opts = @p.parse %w(-z a b c) }
466
+ assert_equal %w(a b c), opts[:zarg]
467
+ assert_equal [], @p.leftovers
468
+ end
469
+
470
+ def test_short_options_with_multiple_options_and_arguments
471
+ opts = nil
472
+
473
+ @p.opt :xarg, "desc", :type => :ints, :multi => true
474
+ assert_nothing_raised { opts = @p.parse %w(-x 3 4 5 -x 6 7) }
475
+ assert_equal [[3, 4, 5], [6, 7]], opts[:xarg]
476
+ assert_equal [], @p.leftovers
477
+
478
+ @p.opt :yarg, "desc", :type => :floats, :multi => true
479
+ assert_nothing_raised { opts = @p.parse %w(-y 3.14 4.21 5.66 -y 6.99 7.01) }
480
+ assert_equal [[3.14, 4.21, 5.66], [6.99, 7.01]], opts[:yarg]
481
+ assert_equal [], @p.leftovers
482
+
483
+ @p.opt :zarg, "desc", :type => :strings, :multi => true
484
+ assert_nothing_raised { opts = @p.parse %w(-z a b c -z d e) }
485
+ assert_equal [%w(a b c), %w(d e)], opts[:zarg]
486
+ assert_equal [], @p.leftovers
487
+ end
488
+
489
+ def test_combined_short_options_with_multiple_arguments
490
+ @p.opt :arg1, "desc", :short => "a"
491
+ @p.opt :arg2, "desc", :short => "b"
492
+ @p.opt :arg3, "desc", :short => "c", :type => :ints
493
+ @p.opt :arg4, "desc", :short => "d", :type => :floats
494
+
495
+ opts = nil
496
+
497
+ assert_nothing_raised { opts = @p.parse %w(-abc 4 6 9) }
498
+ assert_equal true, opts[:arg1]
499
+ assert_equal true, opts[:arg2]
500
+ assert_equal [4, 6, 9], opts[:arg3]
501
+
502
+ assert_nothing_raised { opts = @p.parse %w(-ac 4 6 9 -bd 3.14 2.41) }
503
+ assert_equal true, opts[:arg1]
504
+ assert_equal true, opts[:arg2]
505
+ assert_equal [4, 6, 9], opts[:arg3]
506
+ assert_equal [3.14, 2.41], opts[:arg4]
507
+
508
+ assert_raises(CommandlineError) { opts = @p.parse %w(-abcd 3.14 2.41) }
509
+ end
510
+
511
+ def test_long_options_with_multiple_options
512
+ @p.opt :xarg, "desc", :type => String, :multi => true
513
+ opts = nil
514
+ assert_nothing_raised { opts = @p.parse %w(--xarg=a --xarg=b) }
515
+ assert_equal %w(a b), opts[:xarg]
516
+ assert_equal [], @p.leftovers
517
+ assert_nothing_raised { opts = @p.parse %w(--xarg a --xarg b) }
518
+ assert_equal %w(a b), opts[:xarg]
519
+ assert_equal [], @p.leftovers
520
+ end
521
+
522
+ def test_long_options_with_multiple_arguments
523
+ opts = nil
524
+
525
+ @p.opt :xarg, "desc", :type => :ints
526
+ assert_nothing_raised { opts = @p.parse %w(--xarg 3 2 5) }
527
+ assert_equal [3, 2, 5], opts[:xarg]
528
+ assert_equal [], @p.leftovers
529
+ assert_nothing_raised { opts = @p.parse %w(--xarg=3) }
530
+ assert_equal [3], opts[:xarg]
531
+ assert_equal [], @p.leftovers
532
+
533
+ @p.opt :yarg, "desc", :type => :floats
534
+ assert_nothing_raised { opts = @p.parse %w(--yarg 3.14 2.41 5.66) }
535
+ assert_equal [3.14, 2.41, 5.66], opts[:yarg]
536
+ assert_equal [], @p.leftovers
537
+ assert_nothing_raised { opts = @p.parse %w(--yarg=3.14) }
538
+ assert_equal [3.14], opts[:yarg]
539
+ assert_equal [], @p.leftovers
540
+
541
+ @p.opt :zarg, "desc", :type => :strings
542
+ assert_nothing_raised { opts = @p.parse %w(--zarg a b c) }
543
+ assert_equal %w(a b c), opts[:zarg]
544
+ assert_equal [], @p.leftovers
545
+ assert_nothing_raised { opts = @p.parse %w(--zarg=a) }
546
+ assert_equal %w(a), opts[:zarg]
547
+ assert_equal [], @p.leftovers
548
+ end
549
+
550
+ def test_long_options_with_multiple_options_and_arguments
551
+ opts = nil
552
+
553
+ @p.opt :xarg, "desc", :type => :ints, :multi => true
554
+ assert_nothing_raised { opts = @p.parse %w(--xarg 3 2 5 --xarg 2 1) }
555
+ assert_equal [[3, 2, 5], [2, 1]], opts[:xarg]
556
+ assert_equal [], @p.leftovers
557
+ assert_nothing_raised { opts = @p.parse %w(--xarg=3 --xarg=2) }
558
+ assert_equal [[3], [2]], opts[:xarg]
559
+ assert_equal [], @p.leftovers
560
+
561
+ @p.opt :yarg, "desc", :type => :floats, :multi => true
562
+ assert_nothing_raised { opts = @p.parse %w(--yarg 3.14 2.72 5 --yarg 2.41 1.41) }
563
+ assert_equal [[3.14, 2.72, 5], [2.41, 1.41]], opts[:yarg]
564
+ assert_equal [], @p.leftovers
565
+ assert_nothing_raised { opts = @p.parse %w(--yarg=3.14 --yarg=2.41) }
566
+ assert_equal [[3.14], [2.41]], opts[:yarg]
567
+ assert_equal [], @p.leftovers
568
+
569
+ @p.opt :zarg, "desc", :type => :strings, :multi => true
570
+ assert_nothing_raised { opts = @p.parse %w(--zarg a b c --zarg d e) }
571
+ assert_equal [%w(a b c), %w(d e)], opts[:zarg]
572
+ assert_equal [], @p.leftovers
573
+ assert_nothing_raised { opts = @p.parse %w(--zarg=a --zarg=d) }
574
+ assert_equal [%w(a), %w(d)], opts[:zarg]
575
+ assert_equal [], @p.leftovers
576
+ end
577
+
578
+ def test_long_options_also_take_equals
579
+ @p.opt :arg, "desc", :long => "arg", :type => String, :default => "hello"
580
+ opts = nil
581
+ assert_nothing_raised { opts = @p.parse %w() }
582
+ assert_equal "hello", opts[:arg]
583
+ assert_nothing_raised { opts = @p.parse %w(--arg goat) }
584
+ assert_equal "goat", opts[:arg]
585
+ assert_nothing_raised { opts = @p.parse %w(--arg=goat) }
586
+ assert_equal "goat", opts[:arg]
587
+ ## actually, this next one is valid. empty string for --arg, and goat as a
588
+ ## leftover.
589
+ ## assert_raises(CommandlineError) { opts = @p.parse %w(--arg= goat) }
590
+ end
591
+
592
+ def test_auto_generated_long_names_convert_underscores_to_hyphens
593
+ @p.opt :hello_there
594
+ assert_equal "hello-there", @p.specs[:hello_there][:long]
595
+ end
596
+
597
+ def test_arguments_passed_through_block
598
+ @goat = 3
599
+ boat = 4
600
+ Parser.new(@goat) do |goat|
601
+ boat = goat
602
+ end
603
+ assert_equal @goat, boat
604
+ end
605
+
606
+ def test_help_has_default_banner
607
+ @p = Parser.new
608
+ sio = StringIO.new "w"
609
+ @p.parse []
610
+ @p.educate sio
611
+ help = sio.string.split "\n"
612
+ assert help[0] =~ /options/i
613
+ assert_equal 2, help.length # options, then -h
614
+
615
+ @p = Parser.new
616
+ @p.version "my version"
617
+ sio = StringIO.new "w"
618
+ @p.parse []
619
+ @p.educate sio
620
+ help = sio.string.split "\n"
621
+ assert help[0] =~ /my version/i
622
+ assert_equal 4, help.length # version, options, -h, -v
623
+
624
+ @p = Parser.new
625
+ @p.banner "my own banner"
626
+ sio = StringIO.new "w"
627
+ @p.parse []
628
+ @p.educate sio
629
+ help = sio.string.split "\n"
630
+ assert help[0] =~ /my own banner/i
631
+ assert_equal 2, help.length # banner, -h
632
+ end
633
+
634
+ def test_help_preserves_positions
635
+ @p.opt :zzz, "zzz"
636
+ @p.opt :aaa, "aaa"
637
+ sio = StringIO.new "w"
638
+ @p.educate sio
639
+
640
+ help = sio.string.split "\n"
641
+ assert help[1] =~ /zzz/
642
+ assert help[2] =~ /aaa/
643
+ end
644
+
645
+ def test_help_includes_option_types
646
+ @p.opt :arg1, 'arg', :type => :int
647
+ @p.opt :arg2, 'arg', :type => :ints
648
+ @p.opt :arg3, 'arg', :type => :string
649
+ @p.opt :arg4, 'arg', :type => :strings
650
+ @p.opt :arg5, 'arg', :type => :float
651
+ @p.opt :arg6, 'arg', :type => :floats
652
+ @p.opt :arg7, 'arg', :type => :io
653
+ @p.opt :arg8, 'arg', :type => :ios
654
+ @p.opt :arg9, 'arg', :type => :date
655
+ @p.opt :arg10, 'arg', :type => :dates
656
+ sio = StringIO.new "w"
657
+ @p.educate sio
658
+
659
+ help = sio.string.split "\n"
660
+ assert help[1] =~ /<i>/
661
+ assert help[2] =~ /<i\+>/
662
+ assert help[3] =~ /<s>/
663
+ assert help[4] =~ /<s\+>/
664
+ assert help[5] =~ /<f>/
665
+ assert help[6] =~ /<f\+>/
666
+ assert help[7] =~ /<filename\/uri>/
667
+ assert help[8] =~ /<filename\/uri\+>/
668
+ assert help[9] =~ /<date>/
669
+ assert help[10] =~ /<date\+>/
670
+ end
671
+
672
+ def test_help_has_grammatical_default_text
673
+ @p.opt :arg1, 'description with period.', :default => 'hello'
674
+ @p.opt :arg2, 'description without period', :default => 'world'
675
+ sio = StringIO.new 'w'
676
+ @p.educate sio
677
+
678
+ help = sio.string.split "\n"
679
+ assert help[1] =~ /Default/
680
+ assert help[2] =~ /default/
681
+ end
682
+
683
+ def test_version_and_help_short_args_can_be_overridden
684
+ @p.opt :verbose, "desc", :short => "-v"
685
+ @p.opt :hello, "desc", :short => "-h"
686
+ @p.version "version"
687
+
688
+ assert_nothing_raised { @p.parse(%w(-v)) }
689
+ assert_raises(VersionNeeded) { @p.parse(%w(--version)) }
690
+ assert_nothing_raised { @p.parse(%w(-h)) }
691
+ assert_raises(HelpNeeded) { @p.parse(%w(--help)) }
692
+ end
693
+
694
+ def test_version_and_help_long_args_can_be_overridden
695
+ @p.opt :asdf, "desc", :long => "help"
696
+ @p.opt :asdf2, "desc2", :long => "version"
697
+ assert_nothing_raised { @p.parse %w() }
698
+ assert_nothing_raised { @p.parse %w(--help) }
699
+ assert_nothing_raised { @p.parse %w(--version) }
700
+ assert_nothing_raised { @p.parse %w(-h) }
701
+ assert_nothing_raised { @p.parse %w(-v) }
702
+ end
703
+
704
+ def test_version_and_help_override_errors
705
+ @p.opt :asdf, "desc", :type => String
706
+ @p.version "version"
707
+ assert_nothing_raised { @p.parse %w(--asdf goat) }
708
+ assert_raises(CommandlineError) { @p.parse %w(--asdf) }
709
+ assert_raises(HelpNeeded) { @p.parse %w(--asdf --help) }
710
+ assert_raises(VersionNeeded) { @p.parse %w(--asdf --version) }
711
+ end
712
+
713
+ def test_conflicts
714
+ @p.opt :one
715
+ assert_raises(ArgumentError) { @p.conflicts :one, :two }
716
+ @p.opt :two
717
+ assert_nothing_raised { @p.conflicts :one, :two }
718
+ assert_nothing_raised { @p.parse %w(--one) }
719
+ assert_nothing_raised { @p.parse %w(--two) }
720
+ assert_raises(CommandlineError) { opts = @p.parse %w(--one --two) }
721
+
722
+ @p.opt :hello
723
+ @p.opt :yellow
724
+ @p.opt :mellow
725
+ @p.opt :jello
726
+ @p.conflicts :hello, :yellow, :mellow, :jello
727
+ assert_raises(CommandlineError) { opts = @p.parse %w(--hello --yellow --mellow --jello) }
728
+ assert_raises(CommandlineError) { opts = @p.parse %w(--hello --mellow --jello) }
729
+ assert_raises(CommandlineError) { opts = @p.parse %w(--hello --jello) }
730
+
731
+ assert_nothing_raised { opts = @p.parse %w(--hello) }
732
+ assert_nothing_raised { opts = @p.parse %w(--jello) }
733
+ assert_nothing_raised { opts = @p.parse %w(--yellow) }
734
+ assert_nothing_raised { opts = @p.parse %w(--mellow) }
735
+
736
+ assert_nothing_raised { opts = @p.parse %w(--mellow --one) }
737
+ assert_nothing_raised { opts = @p.parse %w(--mellow --two) }
738
+
739
+ assert_raises(CommandlineError) { opts = @p.parse %w(--mellow --two --jello) }
740
+ assert_raises(CommandlineError) { opts = @p.parse %w(--one --mellow --two --jello) }
741
+ end
742
+
743
+ def test_conflict_error_messages
744
+ @p.opt :one
745
+ @p.opt "two"
746
+ @p.conflicts :one, "two"
747
+
748
+ begin
749
+ @p.parse %w(--one --two)
750
+ flunk "no error thrown"
751
+ rescue CommandlineError => e
752
+ assert_match(/--one/, e.message)
753
+ assert_match(/--two/, e.message)
754
+ end
755
+ end
756
+
757
+ def test_depends
758
+ @p.opt :one
759
+ assert_raises(ArgumentError) { @p.depends :one, :two }
760
+ @p.opt :two
761
+ assert_nothing_raised { @p.depends :one, :two }
762
+ assert_nothing_raised { opts = @p.parse %w(--one --two) }
763
+ assert_raises(CommandlineError) { @p.parse %w(--one) }
764
+ assert_raises(CommandlineError) { @p.parse %w(--two) }
765
+
766
+ @p.opt :hello
767
+ @p.opt :yellow
768
+ @p.opt :mellow
769
+ @p.opt :jello
770
+ @p.depends :hello, :yellow, :mellow, :jello
771
+ assert_nothing_raised { opts = @p.parse %w(--hello --yellow --mellow --jello) }
772
+ assert_raises(CommandlineError) { opts = @p.parse %w(--hello --mellow --jello) }
773
+ assert_raises(CommandlineError) { opts = @p.parse %w(--hello --jello) }
774
+
775
+ assert_raises(CommandlineError) { opts = @p.parse %w(--hello) }
776
+ assert_raises(CommandlineError) { opts = @p.parse %w(--mellow) }
777
+
778
+ assert_nothing_raised { opts = @p.parse %w(--hello --yellow --mellow --jello --one --two) }
779
+ assert_nothing_raised { opts = @p.parse %w(--hello --yellow --mellow --jello --one --two a b c) }
780
+
781
+ assert_raises(CommandlineError) { opts = @p.parse %w(--mellow --two --jello --one) }
782
+ end
783
+
784
+ def test_depend_error_messages
785
+ @p.opt :one
786
+ @p.opt "two"
787
+ @p.depends :one, "two"
788
+
789
+ assert_nothing_raised { @p.parse %w(--one --two) }
790
+
791
+ begin
792
+ @p.parse %w(--one)
793
+ flunk "no error thrown"
794
+ rescue CommandlineError => e
795
+ assert_match(/--one/, e.message)
796
+ assert_match(/--two/, e.message)
797
+ end
798
+
799
+ begin
800
+ @p.parse %w(--two)
801
+ flunk "no error thrown"
802
+ rescue CommandlineError => e
803
+ assert_match(/--one/, e.message)
804
+ assert_match(/--two/, e.message)
805
+ end
806
+ end
807
+
808
+ ## courtesy neill zero
809
+ def test_two_required_one_missing_accuses_correctly
810
+ @p.opt "arg1", "desc1", :required => true
811
+ @p.opt "arg2", "desc2", :required => true
812
+
813
+ begin
814
+ @p.parse(%w(--arg1))
815
+ flunk "should have failed on a missing req"
816
+ rescue CommandlineError => e
817
+ assert e.message =~ /arg2/, "didn't mention arg2 in the error msg: #{e.message}"
818
+ end
819
+
820
+ begin
821
+ @p.parse(%w(--arg2))
822
+ flunk "should have failed on a missing req"
823
+ rescue CommandlineError => e
824
+ assert e.message =~ /arg1/, "didn't mention arg1 in the error msg: #{e.message}"
825
+ end
826
+
827
+ assert_nothing_raised { @p.parse(%w(--arg1 --arg2)) }
828
+ end
829
+
830
+ def test_stopwords_mixed
831
+ @p.opt "arg1", :default => false
832
+ @p.opt "arg2", :default => false
833
+ @p.stop_on %w(happy sad)
834
+
835
+ opts = @p.parse %w(--arg1 happy --arg2)
836
+ assert_equal true, opts["arg1"]
837
+ assert_equal false, opts["arg2"]
838
+
839
+ ## restart parsing
840
+ @p.leftovers.shift
841
+ opts = @p.parse @p.leftovers
842
+ assert_equal false, opts["arg1"]
843
+ assert_equal true, opts["arg2"]
844
+ end
845
+
846
+ def test_stopwords_no_stopwords
847
+ @p.opt "arg1", :default => false
848
+ @p.opt "arg2", :default => false
849
+ @p.stop_on %w(happy sad)
850
+
851
+ opts = @p.parse %w(--arg1 --arg2)
852
+ assert_equal true, opts["arg1"]
853
+ assert_equal true, opts["arg2"]
854
+
855
+ ## restart parsing
856
+ @p.leftovers.shift
857
+ opts = @p.parse @p.leftovers
858
+ assert_equal false, opts["arg1"]
859
+ assert_equal false, opts["arg2"]
860
+ end
861
+
862
+ def test_stopwords_multiple_stopwords
863
+ @p.opt "arg1", :default => false
864
+ @p.opt "arg2", :default => false
865
+ @p.stop_on %w(happy sad)
866
+
867
+ opts = @p.parse %w(happy sad --arg1 --arg2)
868
+ assert_equal false, opts["arg1"]
869
+ assert_equal false, opts["arg2"]
870
+
871
+ ## restart parsing
872
+ @p.leftovers.shift
873
+ opts = @p.parse @p.leftovers
874
+ assert_equal false, opts["arg1"]
875
+ assert_equal false, opts["arg2"]
876
+
877
+ ## restart parsing again
878
+ @p.leftovers.shift
879
+ opts = @p.parse @p.leftovers
880
+ assert_equal true, opts["arg1"]
881
+ assert_equal true, opts["arg2"]
882
+ end
883
+
884
+ def test_stopwords_with_short_args
885
+ @p.opt :global_option, "This is a global option", :short => "-g"
886
+ @p.stop_on %w(sub-command-1 sub-command-2)
887
+
888
+ global_opts = @p.parse %w(-g sub-command-1 -c)
889
+ cmd = @p.leftovers.shift
890
+
891
+ @q = Parser.new
892
+ @q.opt :cmd_option, "This is an option only for the subcommand", :short => "-c"
893
+ cmd_opts = @q.parse @p.leftovers
894
+
895
+ assert_equal true, global_opts[:global_option]
896
+ assert_nil global_opts[:cmd_option]
897
+
898
+ assert_equal true, cmd_opts[:cmd_option]
899
+ assert_nil cmd_opts[:global_option]
900
+
901
+ assert_equal cmd, "sub-command-1"
902
+ assert_equal @q.leftovers, []
903
+ end
904
+
905
+ def assert_parses_correctly(parser, commandline, expected_opts,
906
+ expected_leftovers)
907
+ opts = parser.parse commandline
908
+ assert_equal expected_opts, opts
909
+ assert_equal expected_leftovers, parser.leftovers
910
+ end
911
+
912
+ def test_unknown_subcommand
913
+ @p.opt :global_flag, "Global flag", :short => "-g", :type => :flag
914
+ @p.opt :global_param, "Global parameter", :short => "-p", :default => 5
915
+ @p.stop_on_unknown
916
+
917
+ expected_opts = { :global_flag => true, :help => false, :global_param => 5, :global_flag_given => true }
918
+ expected_leftovers = [ "my_subcommand", "-c" ]
919
+
920
+ assert_parses_correctly @p, %w(--global-flag my_subcommand -c), \
921
+ expected_opts, expected_leftovers
922
+ assert_parses_correctly @p, %w(-g my_subcommand -c), \
923
+ expected_opts, expected_leftovers
924
+
925
+ expected_opts = { :global_flag => false, :help => false, :global_param => 5, :global_param_given => true }
926
+ expected_leftovers = [ "my_subcommand", "-c" ]
927
+
928
+ assert_parses_correctly @p, %w(-p 5 my_subcommand -c), \
929
+ expected_opts, expected_leftovers
930
+ assert_parses_correctly @p, %w(--global-param 5 my_subcommand -c), \
931
+ expected_opts, expected_leftovers
932
+ end
933
+
934
+ def test_alternate_args
935
+ args = %w(-a -b -c)
936
+
937
+ _, opts = ::Trollop.options(args) do
938
+ opt :alpher, "Ralph Alpher", :short => "-a"
939
+ opt :bethe, "Hans Bethe", :short => "-b"
940
+ opt :gamow, "George Gamow", :short => "-c"
941
+ end
942
+
943
+ physicists_with_humor = [:alpher, :bethe, :gamow]
944
+ physicists_with_humor.each do |physicist|
945
+ assert_equal true, opts[physicist]
946
+ end
947
+ end
948
+
949
+ def test_date_arg_type
950
+ temp = Date.new
951
+ @p.opt :arg, 'desc', :type => :date
952
+ @p.opt :arg2, 'desc', :type => Date
953
+ @p.opt :arg3, 'desc', :default => temp
954
+
955
+ opts = nil
956
+ assert_nothing_raised { opts = @p.parse }
957
+ assert_equal temp, opts[:arg3]
958
+
959
+ assert_nothing_raised { opts = @p.parse %w(--arg 5/1/2010) }
960
+ assert_kind_of Date, opts[:arg]
961
+ assert_equal Date.parse('5/1/2010'), opts[:arg]
962
+
963
+ assert_nothing_raised { opts = @p.parse %w(--arg2 5/1/2010) }
964
+ assert_kind_of Date, opts[:arg2]
965
+ assert_equal Date.parse('5/1/2010'), opts[:arg2]
966
+ end
967
+
968
+ def test_unknown_arg_class_type
969
+ assert_raise ArgumentError do
970
+ @p.opt :arg, 'desc', :type => Hash
971
+ end
972
+ end
973
+
974
+ def test_io_arg_type
975
+ @p.opt :arg, "desc", :type => :io
976
+ @p.opt :arg2, "desc", :type => IO
977
+ @p.opt :arg3, "desc", :default => $stdout
978
+
979
+ opts = nil
980
+ assert_nothing_raised { opts = @p.parse() }
981
+ assert_equal $stdout, opts[:arg3]
982
+
983
+ assert_nothing_raised { opts = @p.parse %w(--arg /dev/null) }
984
+ assert_kind_of File, opts[:arg]
985
+ assert_equal "/dev/null", opts[:arg].path
986
+
987
+ #TODO: move to mocks
988
+ #assert_nothing_raised { opts = @p.parse %w(--arg2 http://google.com/) }
989
+ #assert_kind_of StringIO, opts[:arg2]
990
+
991
+ assert_nothing_raised { opts = @p.parse %w(--arg3 stdin) }
992
+ assert_equal $stdin, opts[:arg3]
993
+
994
+ assert_raises(CommandlineError) { opts = @p.parse %w(--arg /fdasfasef/fessafef/asdfasdfa/fesasf) }
995
+ end
996
+
997
+ def test_openstruct_style_access
998
+ @p.opt "arg1", "desc", :type => :int
999
+ @p.opt :arg2, "desc", :type => :int
1000
+
1001
+ opts = @p.parse(%w(--arg1 3 --arg2 4))
1002
+
1003
+ assert_nothing_raised { opts.arg1 }
1004
+ assert_nothing_raised { opts.arg2 }
1005
+ assert_equal 3, opts.arg1
1006
+ assert_equal 4, opts.arg2
1007
+ end
1008
+
1009
+ def test_multi_args_autobox_defaults
1010
+ @p.opt :arg1, "desc", :default => "hello", :multi => true
1011
+ @p.opt :arg2, "desc", :default => ["hello"], :multi => true
1012
+
1013
+ opts = @p.parse
1014
+ assert_equal ["hello"], opts[:arg1]
1015
+ assert_equal ["hello"], opts[:arg2]
1016
+
1017
+ opts = @p.parse %w(--arg1 hello)
1018
+ assert_equal ["hello"], opts[:arg1]
1019
+ assert_equal ["hello"], opts[:arg2]
1020
+
1021
+ opts = @p.parse %w(--arg1 hello --arg1 there)
1022
+ assert_equal ["hello", "there"], opts[:arg1]
1023
+ end
1024
+
1025
+ def test_ambigious_multi_plus_array_default_resolved_as_specified_by_documentation
1026
+ @p.opt :arg1, "desc", :default => ["potato"], :multi => true
1027
+ @p.opt :arg2, "desc", :default => ["potato"], :multi => true, :type => :strings
1028
+ @p.opt :arg3, "desc", :default => ["potato"]
1029
+ @p.opt :arg4, "desc", :default => ["potato", "rhubarb"], :short => :none, :multi => true
1030
+
1031
+ ## arg1 should be multi-occurring but not multi-valued
1032
+ opts = @p.parse %w(--arg1 one two)
1033
+ assert_equal ["one"], opts[:arg1]
1034
+ assert_equal ["two"], @p.leftovers
1035
+
1036
+ opts = @p.parse %w(--arg1 one --arg1 two)
1037
+ assert_equal ["one", "two"], opts[:arg1]
1038
+ assert_equal [], @p.leftovers
1039
+
1040
+ ## arg2 should be multi-valued and multi-occurring
1041
+ opts = @p.parse %w(--arg2 one two)
1042
+ assert_equal [["one", "two"]], opts[:arg2]
1043
+ assert_equal [], @p.leftovers
1044
+
1045
+ ## arg3 should be multi-valued but not multi-occurring
1046
+ opts = @p.parse %w(--arg3 one two)
1047
+ assert_equal ["one", "two"], opts[:arg3]
1048
+ assert_equal [], @p.leftovers
1049
+
1050
+ ## arg4 should be multi-valued but not multi-occurring
1051
+ opts = @p.parse %w()
1052
+ assert_equal ["potato", "rhubarb"], opts[:arg4]
1053
+ end
1054
+
1055
+ def test_given_keys
1056
+ @p.opt :arg1
1057
+ @p.opt :arg2
1058
+
1059
+ opts = @p.parse %w(--arg1)
1060
+ assert opts[:arg1_given]
1061
+ assert !opts[:arg2_given]
1062
+
1063
+ opts = @p.parse %w(--arg2)
1064
+ assert !opts[:arg1_given]
1065
+ assert opts[:arg2_given]
1066
+
1067
+ opts = @p.parse []
1068
+ assert !opts[:arg1_given]
1069
+ assert !opts[:arg2_given]
1070
+
1071
+ opts = @p.parse %w(--arg1 --arg2)
1072
+ assert opts[:arg1_given]
1073
+ assert opts[:arg2_given]
1074
+ end
1075
+
1076
+ def test_default_shorts_assigned_only_after_user_shorts
1077
+ @p.opt :aab, "aaa" # should be assigned to -b
1078
+ @p.opt :ccd, "bbb" # should be assigned to -d
1079
+ @p.opt :user1, "user1", :short => 'a'
1080
+ @p.opt :user2, "user2", :short => 'c'
1081
+
1082
+ opts = @p.parse %w(-a -b)
1083
+ assert opts[:user1]
1084
+ assert !opts[:user2]
1085
+ assert opts[:aab]
1086
+ assert !opts[:ccd]
1087
+
1088
+ opts = @p.parse %w(-c -d)
1089
+ assert !opts[:user1]
1090
+ assert opts[:user2]
1091
+ assert !opts[:aab]
1092
+ assert opts[:ccd]
1093
+ end
1094
+
1095
+ def test_accepts_arguments_with_spaces
1096
+ @p.opt :arg1, "arg", :type => String
1097
+ @p.opt :arg2, "arg2", :type => String
1098
+
1099
+ opts = @p.parse ["--arg1", "hello there", "--arg2=hello there"]
1100
+ assert_equal "hello there", opts[:arg1]
1101
+ assert_equal "hello there", opts[:arg2]
1102
+ assert_equal 0, @p.leftovers.size
1103
+ end
1104
+
1105
+ def test_multi_args_default_to_empty_array
1106
+ @p.opt :arg1, "arg", :multi => true
1107
+ opts = @p.parse []
1108
+ assert_equal [], opts[:arg1]
1109
+ end
1110
+
1111
+ def test_simple_interface_handles_help
1112
+ ARGV.clear
1113
+ ARGV.unshift "-h"
1114
+ assert_raises(SystemExit) do
1115
+ opts = ::Trollop::options do
1116
+ opt :potato
1117
+ end
1118
+ raise "broken"
1119
+ end
1120
+ end
1121
+
1122
+ def test_simple_interface_handles_version
1123
+ ARGV.clear
1124
+ ARGV.unshift "-v"
1125
+ assert_raises(SystemExit) do
1126
+ opts = ::Trollop::options do
1127
+ version "1.2"
1128
+ opt :potato
1129
+ end
1130
+ raise "broken"
1131
+ end
1132
+ end
1133
+
1134
+ def test_simple_interface_handles_regular_usage
1135
+ ARGV.clear
1136
+ ARGV.unshift "--potato"
1137
+ opts = nil
1138
+ assert_nothing_raised do
1139
+ _, opts = ::Trollop::options do
1140
+ opt :potato
1141
+ end
1142
+ end
1143
+ assert opts[:potato]
1144
+ end
1145
+
1146
+ def test_simple_interface_handles_die
1147
+ old_stderr, $stderr = $stderr, StringIO.new('w')
1148
+ ARGV.clear
1149
+ ARGV.unshift "--potato"
1150
+ opts = ::Trollop::options do
1151
+ opt :potato
1152
+ end
1153
+ assert_raises(SystemExit) { ::Trollop::die :potato, "is invalid" }
1154
+ ensure
1155
+ $stderr = old_stderr
1156
+ end
1157
+
1158
+ def test_simple_interface_handles_die_without_message
1159
+ old_stderr, $stderr = $stderr, StringIO.new('w')
1160
+ ARGV.clear
1161
+ ARGV.unshift "--potato"
1162
+ opts = ::Trollop::options do
1163
+ opt :potato
1164
+ end
1165
+ assert_raises(SystemExit) { ::Trollop::die :potato }
1166
+ assert $stderr.string =~ /Error:/
1167
+ ensure
1168
+ $stderr = old_stderr
1169
+ end
1170
+
1171
+ def test_with_standard_exception_handling
1172
+ assert_raise(SystemExit) do
1173
+ ::Trollop.with_standard_exception_handling(@p) do
1174
+ raise ::Trollop::CommandlineError.new('cl error')
1175
+ end
1176
+ end
1177
+ end
1178
+ end
1179
+
1180
+ end
1181
+ end