monkeyshines 0.0.2

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 (85) hide show
  1. data/.document +4 -0
  2. data/.gitignore +43 -0
  3. data/LICENSE +20 -0
  4. data/LICENSE.textile +20 -0
  5. data/README.textile +125 -0
  6. data/Rakefile +105 -0
  7. data/VERSION +1 -0
  8. data/examples/.gitignore +4 -0
  9. data/examples/bulk_urls/scrape_bulk_urls.rb +64 -0
  10. data/examples/rename_tree/rename_hdp_tree.rb +151 -0
  11. data/examples/rename_tree/rename_ripd_tree.rb +82 -0
  12. data/examples/rss_feeds/scrape_rss_feeds.rb +52 -0
  13. data/examples/shorturls/README.textile +111 -0
  14. data/examples/shorturls/bulkdump_shorturls.rb +46 -0
  15. data/examples/shorturls/bulkload_shorturls.rb +45 -0
  16. data/examples/shorturls/extract_urls.rb +12 -0
  17. data/examples/shorturls/multiplex_shorturl_cache.rb +32 -0
  18. data/examples/shorturls/old/multidump_and_fix_shorturls.rb +66 -0
  19. data/examples/shorturls/old/shorturl_stats.rb +81 -0
  20. data/examples/shorturls/scrape_shorturls.rb +112 -0
  21. data/examples/shorturls/shorturl_request.rb +29 -0
  22. data/examples/shorturls/shorturl_sequence.rb +121 -0
  23. data/examples/shorturls/shorturl_start_tyrant.sh +16 -0
  24. data/examples/shorturls/start_shorturl_cache.sh +2 -0
  25. data/lib/monkeyshines.rb +31 -0
  26. data/lib/monkeyshines/extensions.rb +16 -0
  27. data/lib/monkeyshines/fetcher.rb +10 -0
  28. data/lib/monkeyshines/fetcher/authed_http_fetcher.rb +35 -0
  29. data/lib/monkeyshines/fetcher/base.rb +44 -0
  30. data/lib/monkeyshines/fetcher/fake_fetcher.rb +19 -0
  31. data/lib/monkeyshines/fetcher/http_fetcher.rb +127 -0
  32. data/lib/monkeyshines/fetcher/http_head_fetcher.rb +23 -0
  33. data/lib/monkeyshines/monitor.rb +7 -0
  34. data/lib/monkeyshines/monitor/chunked_store.rb +23 -0
  35. data/lib/monkeyshines/monitor/periodic_logger.rb +33 -0
  36. data/lib/monkeyshines/monitor/periodic_monitor.rb +65 -0
  37. data/lib/monkeyshines/options.rb +59 -0
  38. data/lib/monkeyshines/recursive_runner.rb +26 -0
  39. data/lib/monkeyshines/repository/base.rb +57 -0
  40. data/lib/monkeyshines/repository/s3.rb +169 -0
  41. data/lib/monkeyshines/request_stream.rb +11 -0
  42. data/lib/monkeyshines/request_stream/base.rb +32 -0
  43. data/lib/monkeyshines/request_stream/edamame_queue.rb +54 -0
  44. data/lib/monkeyshines/request_stream/klass_request_stream.rb +39 -0
  45. data/lib/monkeyshines/request_stream/simple_request_stream.rb +22 -0
  46. data/lib/monkeyshines/runner.rb +161 -0
  47. data/lib/monkeyshines/runner_core/options.rb +5 -0
  48. data/lib/monkeyshines/runner_core/parsing_runner.rb +29 -0
  49. data/lib/monkeyshines/scrape_job/old_paginated.rb +343 -0
  50. data/lib/monkeyshines/scrape_job/recursive.rb +9 -0
  51. data/lib/monkeyshines/scrape_request.rb +136 -0
  52. data/lib/monkeyshines/scrape_request/paginated.rb +290 -0
  53. data/lib/monkeyshines/scrape_request/raw_json_contents.rb +16 -0
  54. data/lib/monkeyshines/scrape_request/signed_url.rb +86 -0
  55. data/lib/monkeyshines/store.rb +14 -0
  56. data/lib/monkeyshines/store/base.rb +29 -0
  57. data/lib/monkeyshines/store/chunked_flat_file_store.rb +37 -0
  58. data/lib/monkeyshines/store/conditional_store.rb +57 -0
  59. data/lib/monkeyshines/store/factory.rb +8 -0
  60. data/lib/monkeyshines/store/flat_file_store.rb +84 -0
  61. data/lib/monkeyshines/store/key_store.rb +51 -0
  62. data/lib/monkeyshines/store/null_store.rb +15 -0
  63. data/lib/monkeyshines/store/read_thru_store.rb +22 -0
  64. data/lib/monkeyshines/store/tokyo_tdb_key_store.rb +33 -0
  65. data/lib/monkeyshines/store/tyrant_rdb_key_store.rb +56 -0
  66. data/lib/monkeyshines/store/tyrant_tdb_key_store.rb +20 -0
  67. data/lib/monkeyshines/utils/factory_module.rb +106 -0
  68. data/lib/monkeyshines/utils/filename_pattern.rb +134 -0
  69. data/lib/monkeyshines/utils/logger.rb +15 -0
  70. data/lib/monkeyshines/utils/trollop-1.14/FAQ.txt +84 -0
  71. data/lib/monkeyshines/utils/trollop-1.14/History.txt +101 -0
  72. data/lib/monkeyshines/utils/trollop-1.14/Manifest.txt +7 -0
  73. data/lib/monkeyshines/utils/trollop-1.14/README.txt +40 -0
  74. data/lib/monkeyshines/utils/trollop-1.14/Rakefile +36 -0
  75. data/lib/monkeyshines/utils/trollop-1.14/lib/trollop.rb +744 -0
  76. data/lib/monkeyshines/utils/trollop-1.14/test/test_trollop.rb +1048 -0
  77. data/lib/monkeyshines/utils/trollop.rb +744 -0
  78. data/lib/monkeyshines/utils/union_interval.rb +52 -0
  79. data/lib/monkeyshines/utils/uri.rb +70 -0
  80. data/lib/monkeyshines/utils/uuid.rb +32 -0
  81. data/monkeyshines.gemspec +147 -0
  82. data/scrape_from_file.rb +44 -0
  83. data/spec/monkeyshines_spec.rb +7 -0
  84. data/spec/spec_helper.rb +9 -0
  85. metadata +183 -0
@@ -0,0 +1,1048 @@
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 '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_unknown_arguments
19
+ assert_raise(CommandlineError) { @p.parse(%w(--arg)) }
20
+ @p.opt "arg"
21
+ assert_nothing_raised { @p.parse(%w(--arg)) }
22
+ assert_raise(CommandlineError) { @p.parse(%w(--arg2)) }
23
+ end
24
+
25
+ def test_syntax_check
26
+ @p.opt "arg"
27
+
28
+ assert_nothing_raised { @p.parse(%w(--arg)) }
29
+ assert_nothing_raised { @p.parse(%w(arg)) }
30
+ assert_raise(CommandlineError) { @p.parse(%w(---arg)) }
31
+ assert_raise(CommandlineError) { @p.parse(%w(-arg)) }
32
+ end
33
+
34
+ def test_required_flags_are_required
35
+ @p.opt "arg", "desc", :required => true
36
+ @p.opt "arg2", "desc", :required => false
37
+ @p.opt "arg3", "desc", :required => false
38
+
39
+ assert_nothing_raised { @p.parse(%w(--arg)) }
40
+ assert_nothing_raised { @p.parse(%w(--arg --arg2)) }
41
+ assert_raise(CommandlineError) { @p.parse(%w(--arg2)) }
42
+ assert_raise(CommandlineError) { @p.parse(%w(--arg2 --arg3)) }
43
+ end
44
+
45
+ ## flags that take an argument error unless given one
46
+ def test_argflags_demand_args
47
+ @p.opt "goodarg", "desc", :type => String
48
+ @p.opt "goodarg2", "desc", :type => String
49
+
50
+ assert_nothing_raised { @p.parse(%w(--goodarg goat)) }
51
+ assert_raise(CommandlineError) { @p.parse(%w(--goodarg --goodarg2 goat)) }
52
+ assert_raise(CommandlineError) { @p.parse(%w(--goodarg)) }
53
+ end
54
+
55
+ ## flags that don't take arguments ignore them
56
+ def test_arglessflags_refuse_args
57
+ @p.opt "goodarg"
58
+ @p.opt "goodarg2"
59
+ assert_nothing_raised { @p.parse(%w(--goodarg)) }
60
+ assert_nothing_raised { @p.parse(%w(--goodarg --goodarg2)) }
61
+ opts = @p.parse %w(--goodarg a)
62
+ assert_equal true, opts["goodarg"]
63
+ assert_equal ["a"], @p.leftovers
64
+ end
65
+
66
+ ## flags that require args of a specific type refuse args of other
67
+ ## types
68
+ def test_typed_args_refuse_args_of_other_types
69
+ assert_nothing_raised { @p.opt "goodarg", "desc", :type => :int }
70
+ assert_raise(ArgumentError) { @p.opt "badarg", "desc", :type => :asdf }
71
+
72
+ assert_nothing_raised { @p.parse(%w(--goodarg 3)) }
73
+ assert_raise(CommandlineError) { @p.parse(%w(--goodarg 4.2)) }
74
+ assert_raise(CommandlineError) { @p.parse(%w(--goodarg hello)) }
75
+ end
76
+
77
+ ## type is correctly derived from :default
78
+ def test_type_correctly_derived_from_default
79
+ assert_raise(ArgumentError) { @p.opt "badarg", "desc", :default => [] }
80
+
81
+ opts = nil
82
+
83
+ # single arg: int
84
+ assert_nothing_raised { @p.opt "argsi", "desc", :default => 0 }
85
+ assert_nothing_raised { opts = @p.parse("--") }
86
+ assert_equal 0, opts["argsi"]
87
+ assert_nothing_raised { opts = @p.parse(%w(--argsi 4)) }
88
+ assert_equal 4, opts["argsi"]
89
+ assert_raise(CommandlineError) { @p.parse(%w(--argsi 4.2)) }
90
+ assert_raise(CommandlineError) { @p.parse(%w(--argsi hello)) }
91
+
92
+ # single arg: float
93
+ assert_nothing_raised { @p.opt "argsf", "desc", :default => 3.14 }
94
+ assert_nothing_raised { opts = @p.parse("--") }
95
+ assert_equal 3.14, opts["argsf"]
96
+ assert_nothing_raised { opts = @p.parse(%w(--argsf 2.41)) }
97
+ assert_equal 2.41, opts["argsf"]
98
+ assert_nothing_raised { opts = @p.parse(%w(--argsf 2)) }
99
+ assert_equal 2, opts["argsf"]
100
+ assert_raise(CommandlineError) { @p.parse(%w(--argsf hello)) }
101
+
102
+ # single arg: date
103
+ date = Date.today
104
+ assert_nothing_raised { @p.opt "argsd", "desc", :default => date }
105
+ assert_nothing_raised { opts = @p.parse("--") }
106
+ assert_equal Date.today, opts["argsd"]
107
+ assert_nothing_raised { opts = @p.parse(['--argsd', 'Jan 4, 2007']) }
108
+ assert_equal Date.civil(2007, 1, 4), opts["argsd"]
109
+ assert_raise(CommandlineError) { @p.parse(%w(--argsd hello)) }
110
+
111
+ # single arg: string
112
+ assert_nothing_raised { @p.opt "argss", "desc", :default => "foobar" }
113
+ assert_nothing_raised { opts = @p.parse("--") }
114
+ assert_equal "foobar", opts["argss"]
115
+ assert_nothing_raised { opts = @p.parse(%w(--argss 2.41)) }
116
+ assert_equal "2.41", opts["argss"]
117
+ assert_nothing_raised { opts = @p.parse(%w(--argss hello)) }
118
+ assert_equal "hello", opts["argss"]
119
+
120
+ # multi args: ints
121
+ assert_nothing_raised { @p.opt "argmi", "desc", :default => [3, 5] }
122
+ assert_nothing_raised { opts = @p.parse("--") }
123
+ assert_equal [3, 5], opts["argmi"]
124
+ assert_nothing_raised { opts = @p.parse(%w(--argmi 4)) }
125
+ assert_equal [4], opts["argmi"]
126
+ assert_raise(CommandlineError) { @p.parse(%w(--argmi 4.2)) }
127
+ assert_raise(CommandlineError) { @p.parse(%w(--argmi hello)) }
128
+
129
+ # multi args: floats
130
+ assert_nothing_raised { @p.opt "argmf", "desc", :default => [3.34, 5.21] }
131
+ assert_nothing_raised { opts = @p.parse("--") }
132
+ assert_equal [3.34, 5.21], opts["argmf"]
133
+ assert_nothing_raised { opts = @p.parse(%w(--argmf 2)) }
134
+ assert_equal [2], opts["argmf"]
135
+ assert_nothing_raised { opts = @p.parse(%w(--argmf 4.0)) }
136
+ assert_equal [4.0], opts["argmf"]
137
+ assert_raise(CommandlineError) { @p.parse(%w(--argmf hello)) }
138
+
139
+ # multi args: dates
140
+ dates = [Date.today, Date.civil(2007, 1, 4)]
141
+ assert_nothing_raised { @p.opt "argmd", "desc", :default => dates }
142
+ assert_nothing_raised { opts = @p.parse("--") }
143
+ assert_equal dates, opts["argmd"]
144
+ assert_nothing_raised { opts = @p.parse(['--argmd', 'Jan 4, 2007']) }
145
+ assert_equal [Date.civil(2007, 1, 4)], opts["argmd"]
146
+ assert_raise(CommandlineError) { @p.parse(%w(--argmd hello)) }
147
+
148
+ # multi args: strings
149
+ assert_nothing_raised { @p.opt "argmst", "desc", :default => %w(hello world) }
150
+ assert_nothing_raised { opts = @p.parse("--") }
151
+ assert_equal %w(hello world), opts["argmst"]
152
+ assert_nothing_raised { opts = @p.parse(%w(--argmst 3.4)) }
153
+ assert_equal ["3.4"], opts["argmst"]
154
+ assert_nothing_raised { opts = @p.parse(%w(--argmst goodbye)) }
155
+ assert_equal ["goodbye"], opts["argmst"]
156
+ end
157
+
158
+ ## :type and :default must match if both are specified
159
+ def test_type_and_default_must_match
160
+ assert_raise(ArgumentError) { @p.opt "badarg", "desc", :type => :int, :default => "hello" }
161
+ assert_raise(ArgumentError) { @p.opt "badarg2", "desc", :type => :String, :default => 4 }
162
+ assert_raise(ArgumentError) { @p.opt "badarg2", "desc", :type => :String, :default => ["hi"] }
163
+ assert_raise(ArgumentError) { @p.opt "badarg2", "desc", :type => :ints, :default => [3.14] }
164
+
165
+ assert_nothing_raised { @p.opt "argsi", "desc", :type => :int, :default => 4 }
166
+ assert_nothing_raised { @p.opt "argsf", "desc", :type => :float, :default => 3.14 }
167
+ assert_nothing_raised { @p.opt "argsd", "desc", :type => :date, :default => Date.today }
168
+ assert_nothing_raised { @p.opt "argss", "desc", :type => :string, :default => "yo" }
169
+ assert_nothing_raised { @p.opt "argmi", "desc", :type => :ints, :default => [4] }
170
+ assert_nothing_raised { @p.opt "argmf", "desc", :type => :floats, :default => [3.14] }
171
+ assert_nothing_raised { @p.opt "argmd", "desc", :type => :dates, :default => [Date.today] }
172
+ assert_nothing_raised { @p.opt "argmst", "desc", :type => :strings, :default => ["yo"] }
173
+ end
174
+
175
+ def test_long_detects_bad_names
176
+ assert_nothing_raised { @p.opt "goodarg", "desc", :long => "none" }
177
+ assert_nothing_raised { @p.opt "goodarg2", "desc", :long => "--two" }
178
+ assert_raise(ArgumentError) { @p.opt "badarg", "desc", :long => "" }
179
+ assert_raise(ArgumentError) { @p.opt "badarg2", "desc", :long => "--" }
180
+ assert_raise(ArgumentError) { @p.opt "badarg3", "desc", :long => "-one" }
181
+ assert_raise(ArgumentError) { @p.opt "badarg4", "desc", :long => "---toomany" }
182
+ end
183
+
184
+ def test_short_detects_bad_names
185
+ assert_nothing_raised { @p.opt "goodarg", "desc", :short => "a" }
186
+ assert_nothing_raised { @p.opt "goodarg2", "desc", :short => "-b" }
187
+ assert_raise(ArgumentError) { @p.opt "badarg", "desc", :short => "" }
188
+ assert_raise(ArgumentError) { @p.opt "badarg2", "desc", :short => "-ab" }
189
+ assert_raise(ArgumentError) { @p.opt "badarg3", "desc", :short => "--t" }
190
+ end
191
+
192
+ def test_short_names_created_automatically
193
+ @p.opt "arg"
194
+ @p.opt "arg2"
195
+ @p.opt "arg3"
196
+ opts = @p.parse %w(-a -g)
197
+ assert_equal true, opts["arg"]
198
+ assert_equal false, opts["arg2"]
199
+ assert_equal true, opts["arg3"]
200
+ end
201
+
202
+ def test_short_autocreation_skips_dashes_and_numbers
203
+ @p.opt :arg # auto: a
204
+ @p.opt :arg_potato # auto: r
205
+ @p.opt :arg_muffin # auto: g
206
+ assert_nothing_raised { @p.opt :arg_daisy } # auto: d (not _)!
207
+ assert_nothing_raised { @p.opt :arg_r2d2f } # auto: f (not 2)!
208
+
209
+ opts = @p.parse %w(-f -d)
210
+ assert_equal true, opts[:arg_daisy]
211
+ assert_equal true, opts[:arg_r2d2f]
212
+ assert_equal false, opts[:arg]
213
+ assert_equal false, opts[:arg_potato]
214
+ assert_equal false, opts[:arg_muffin]
215
+ end
216
+
217
+ def test_short_autocreation_detects_running_out
218
+ @p.opt :arg1 # auto: a
219
+ @p.opt :arg2 # auto: r
220
+ @p.opt :arg3 # auto: g
221
+ @p.opt :arg4 # auto: uh oh!
222
+ assert_raises(ArgumentError) { @p.parse [] }
223
+ end
224
+
225
+ def test_short_can_be_nothing
226
+ assert_nothing_raised do
227
+ @p.opt "arg", "desc", :short => :none
228
+ @p.parse []
229
+ end
230
+
231
+ sio = StringIO.new "w"
232
+ @p.educate sio
233
+ assert sio.string =~ /--arg:\s+desc/
234
+
235
+ assert_raise(CommandlineError) { @p.parse %w(-a) }
236
+ end
237
+
238
+ ## two args can't have the same name
239
+ def test_conflicting_names_are_detected
240
+ assert_nothing_raised { @p.opt "goodarg" }
241
+ assert_raise(ArgumentError) { @p.opt "goodarg" }
242
+ end
243
+
244
+ ## two args can't have the same :long
245
+ def test_conflicting_longs_detected
246
+ assert_nothing_raised { @p.opt "goodarg", "desc", :long => "--goodarg" }
247
+ assert_raise(ArgumentError) { @p.opt "badarg", "desc", :long => "--goodarg" }
248
+ end
249
+
250
+ ## two args can't have the same :short
251
+ def test_conflicting_shorts_detected
252
+ assert_nothing_raised { @p.opt "goodarg", "desc", :short => "-g" }
253
+ assert_raise(ArgumentError) { @p.opt "badarg", "desc", :short => "-g" }
254
+ end
255
+
256
+ def test_flag_defaults
257
+ @p.opt "defaultfalse", "desc"
258
+ @p.opt "defaulttrue", "desc", :default => true
259
+ opts = @p.parse []
260
+ assert_equal false, opts["defaultfalse"]
261
+ assert_equal true, opts["defaulttrue"]
262
+
263
+ opts = @p.parse %w(--defaultfalse --defaulttrue)
264
+ assert_equal true, opts["defaultfalse"]
265
+ assert_equal false, opts["defaulttrue"]
266
+ end
267
+
268
+ def test_special_flags_work
269
+ @p.version "asdf fdas"
270
+ assert_raise(VersionNeeded) { @p.parse(%w(-v)) }
271
+ assert_raise(HelpNeeded) { @p.parse(%w(-h)) }
272
+ end
273
+
274
+ def test_short_options_combine
275
+ @p.opt :arg1, "desc", :short => "a"
276
+ @p.opt :arg2, "desc", :short => "b"
277
+ @p.opt :arg3, "desc", :short => "c", :type => :int
278
+
279
+ opts = nil
280
+ assert_nothing_raised { opts = @p.parse %w(-a -b) }
281
+ assert_equal true, opts[:arg1]
282
+ assert_equal true, opts[:arg2]
283
+ assert_equal nil, opts[:arg3]
284
+
285
+ assert_nothing_raised { opts = @p.parse %w(-ab) }
286
+ assert_equal true, opts[:arg1]
287
+ assert_equal true, opts[:arg2]
288
+ assert_equal nil, opts[:arg3]
289
+
290
+ assert_nothing_raised { opts = @p.parse %w(-ac 4 -b) }
291
+ assert_equal true, opts[:arg1]
292
+ assert_equal true, opts[:arg2]
293
+ assert_equal 4, opts[:arg3]
294
+
295
+ assert_raises(CommandlineError) { @p.parse %w(-cab 4) }
296
+ assert_raises(CommandlineError) { @p.parse %w(-cba 4) }
297
+ end
298
+
299
+ def test_version_only_appears_if_set
300
+ @p.opt "arg"
301
+ assert_raise(CommandlineError) { @p.parse %w(-v) }
302
+ @p.version "trollop 1.2.3.4"
303
+ assert_raise(VersionNeeded) { @p.parse %w(-v) }
304
+ end
305
+
306
+ def test_doubledash_ends_option_processing
307
+ @p.opt :arg1, "desc", :short => "a", :default => 0
308
+ @p.opt :arg2, "desc", :short => "b", :default => 0
309
+ opts = nil
310
+ assert_nothing_raised { opts = @p.parse %w(-- -a 3 -b 2) }
311
+ assert_equal opts[:arg1], 0
312
+ assert_equal opts[:arg2], 0
313
+ assert_equal %w(-a 3 -b 2), @p.leftovers
314
+ assert_nothing_raised { opts = @p.parse %w(-a 3 -- -b 2) }
315
+ assert_equal opts[:arg1], 3
316
+ assert_equal opts[:arg2], 0
317
+ assert_equal %w(-b 2), @p.leftovers
318
+ assert_nothing_raised { opts = @p.parse %w(-a 3 -b 2 --) }
319
+ assert_equal opts[:arg1], 3
320
+ assert_equal opts[:arg2], 2
321
+ assert_equal %w(), @p.leftovers
322
+ end
323
+
324
+ def test_wrap
325
+ assert_equal [""], @p.wrap("")
326
+ assert_equal ["a"], @p.wrap("a")
327
+ assert_equal ["one two", "three"], @p.wrap("one two three", :width => 8)
328
+ assert_equal ["one two three"], @p.wrap("one two three", :width => 80)
329
+ assert_equal ["one", "two", "three"], @p.wrap("one two three", :width => 3)
330
+ assert_equal ["onetwothree"], @p.wrap("onetwothree", :width => 3)
331
+ assert_equal [
332
+ "Test is an awesome program that does something very, very important.",
333
+ "",
334
+ "Usage:",
335
+ " test [options] <filenames>+",
336
+ "where [options] are:"], @p.wrap(<<EOM, :width => 100)
337
+ Test is an awesome program that does something very, very important.
338
+
339
+ Usage:
340
+ test [options] <filenames>+
341
+ where [options] are:
342
+ EOM
343
+ end
344
+
345
+ def test_floating_point_formatting
346
+ @p.opt :arg, "desc", :type => :float, :short => "f"
347
+ opts = nil
348
+ assert_nothing_raised { opts = @p.parse %w(-f 1) }
349
+ assert_equal 1.0, opts[:arg]
350
+ assert_nothing_raised { opts = @p.parse %w(-f 1.0) }
351
+ assert_equal 1.0, opts[:arg]
352
+ assert_nothing_raised { opts = @p.parse %w(-f 0.1) }
353
+ assert_equal 0.1, opts[:arg]
354
+ assert_nothing_raised { opts = @p.parse %w(-f .1) }
355
+ assert_equal 0.1, opts[:arg]
356
+ assert_nothing_raised { opts = @p.parse %w(-f .99999999999999999999) }
357
+ assert_equal 1.0, opts[:arg]
358
+ assert_nothing_raised { opts = @p.parse %w(-f -1) }
359
+ assert_equal(-1.0, opts[:arg])
360
+ assert_nothing_raised { opts = @p.parse %w(-f -1.0) }
361
+ assert_equal(-1.0, opts[:arg])
362
+ assert_nothing_raised { opts = @p.parse %w(-f -0.1) }
363
+ assert_equal(-0.1, opts[:arg])
364
+ assert_nothing_raised { opts = @p.parse %w(-f -.1) }
365
+ assert_equal(-0.1, opts[:arg])
366
+ assert_raises(CommandlineError) { @p.parse %w(-f a) }
367
+ assert_raises(CommandlineError) { @p.parse %w(-f 1a) }
368
+ assert_raises(CommandlineError) { @p.parse %w(-f 1.a) }
369
+ assert_raises(CommandlineError) { @p.parse %w(-f a.1) }
370
+ assert_raises(CommandlineError) { @p.parse %w(-f 1.0.0) }
371
+ assert_raises(CommandlineError) { @p.parse %w(-f .) }
372
+ assert_raises(CommandlineError) { @p.parse %w(-f -.) }
373
+ end
374
+
375
+ def test_date_formatting
376
+ @p.opt :arg, "desc", :type => :date, :short => 'd'
377
+ opts = nil
378
+ assert_nothing_raised { opts = @p.parse(['-d', 'Jan 4, 2007']) }
379
+ assert_equal Date.civil(2007, 1, 4), opts[:arg]
380
+ begin
381
+ require 'chronic'
382
+ assert_nothing_raised { opts = @p.parse(['-d', 'today']) }
383
+ assert_equal Date.today, opts[:arg]
384
+ rescue LoadError
385
+ # chronic is not available
386
+ end
387
+ end
388
+
389
+ def test_short_options_cant_be_numeric
390
+ assert_raises(ArgumentError) { @p.opt :arg, "desc", :short => "-1" }
391
+ @p.opt :a1b, "desc"
392
+ @p.opt :a2b, "desc"
393
+ assert_not_equal "2", @p.specs[:a2b][:short]
394
+ end
395
+
396
+ def test_short_options_can_be_weird
397
+ assert_nothing_raised { @p.opt :arg1, "desc", :short => "#" }
398
+ assert_nothing_raised { @p.opt :arg2, "desc", :short => "." }
399
+ assert_raises(ArgumentError) { @p.opt :arg3, "desc", :short => "-" }
400
+ end
401
+
402
+ def test_options_cant_be_set_multiple_times_if_not_specified
403
+ @p.opt :arg, "desc", :short => "-x"
404
+ assert_nothing_raised { @p.parse %w(-x) }
405
+ assert_raises(CommandlineError) { @p.parse %w(-x -x) }
406
+ assert_raises(CommandlineError) { @p.parse %w(-xx) }
407
+ end
408
+
409
+ def test_options_can_be_set_multiple_times_if_specified
410
+ assert_nothing_raised do
411
+ @p.opt :arg, "desc", :short => "-x", :multi => true
412
+ end
413
+ assert_nothing_raised { @p.parse %w(-x) }
414
+ assert_nothing_raised { @p.parse %w(-x -x) }
415
+ assert_nothing_raised { @p.parse %w(-xx) }
416
+ end
417
+
418
+ def test_short_options_with_multiple_options
419
+ opts = nil
420
+
421
+ assert_nothing_raised do
422
+ @p.opt :xarg, "desc", :short => "-x", :type => String, :multi => true
423
+ end
424
+ assert_nothing_raised { opts = @p.parse %w(-x a -x b) }
425
+ assert_equal %w(a b), opts[:xarg]
426
+ assert_equal [], @p.leftovers
427
+ end
428
+
429
+ def short_options_with_multiple_options_does_not_affect_flags_type
430
+ opts = nil
431
+
432
+ assert_nothing_raised do
433
+ @p.opt :xarg, "desc", :short => "-x", :type => :flag, :multi => true
434
+ end
435
+
436
+ assert_nothing_raised { opts = @p.parse %w(-x a) }
437
+ assert_equal true, opts[:xarg]
438
+ assert_equal %w(a), @p.leftovers
439
+
440
+ assert_nothing_raised { opts = @p.parse %w(-x a -x b) }
441
+ assert_equal true, opts[:xarg]
442
+ assert_equal %w(a b), @p.leftovers
443
+
444
+ assert_nothing_raised { opts = @p.parse %w(-xx a -x b) }
445
+ assert_equal true, opts[:xarg]
446
+ assert_equal %w(a b), @p.leftovers
447
+ end
448
+
449
+ def test_short_options_with_multiple_arguments
450
+ opts = nil
451
+
452
+ @p.opt :xarg, "desc", :type => :ints
453
+ assert_nothing_raised { opts = @p.parse %w(-x 3 4 0) }
454
+ assert_equal [3, 4, 0], opts[:xarg]
455
+ assert_equal [], @p.leftovers
456
+
457
+ @p.opt :yarg, "desc", :type => :floats
458
+ assert_nothing_raised { opts = @p.parse %w(-y 3.14 4.21 0.66) }
459
+ assert_equal [3.14, 4.21, 0.66], opts[:yarg]
460
+ assert_equal [], @p.leftovers
461
+
462
+ @p.opt :zarg, "desc", :type => :strings
463
+ assert_nothing_raised { opts = @p.parse %w(-z a b c) }
464
+ assert_equal %w(a b c), opts[:zarg]
465
+ assert_equal [], @p.leftovers
466
+ end
467
+
468
+ def test_short_options_with_multiple_options_and_arguments
469
+ opts = nil
470
+
471
+ @p.opt :xarg, "desc", :type => :ints, :multi => true
472
+ assert_nothing_raised { opts = @p.parse %w(-x 3 4 5 -x 6 7) }
473
+ assert_equal [[3, 4, 5], [6, 7]], opts[:xarg]
474
+ assert_equal [], @p.leftovers
475
+
476
+ @p.opt :yarg, "desc", :type => :floats, :multi => true
477
+ assert_nothing_raised { opts = @p.parse %w(-y 3.14 4.21 5.66 -y 6.99 7.01) }
478
+ assert_equal [[3.14, 4.21, 5.66], [6.99, 7.01]], opts[:yarg]
479
+ assert_equal [], @p.leftovers
480
+
481
+ @p.opt :zarg, "desc", :type => :strings, :multi => true
482
+ assert_nothing_raised { opts = @p.parse %w(-z a b c -z d e) }
483
+ assert_equal [%w(a b c), %w(d e)], opts[:zarg]
484
+ assert_equal [], @p.leftovers
485
+ end
486
+
487
+ def test_combined_short_options_with_multiple_arguments
488
+ @p.opt :arg1, "desc", :short => "a"
489
+ @p.opt :arg2, "desc", :short => "b"
490
+ @p.opt :arg3, "desc", :short => "c", :type => :ints
491
+ @p.opt :arg4, "desc", :short => "d", :type => :floats
492
+
493
+ opts = nil
494
+
495
+ assert_nothing_raised { opts = @p.parse %w(-abc 4 6 9) }
496
+ assert_equal true, opts[:arg1]
497
+ assert_equal true, opts[:arg2]
498
+ assert_equal [4, 6, 9], opts[:arg3]
499
+
500
+ assert_nothing_raised { opts = @p.parse %w(-ac 4 6 9 -bd 3.14 2.41) }
501
+ assert_equal true, opts[:arg1]
502
+ assert_equal true, opts[:arg2]
503
+ assert_equal [4, 6, 9], opts[:arg3]
504
+ assert_equal [3.14, 2.41], opts[:arg4]
505
+
506
+ assert_raises(CommandlineError) { opts = @p.parse %w(-abcd 3.14 2.41) }
507
+ end
508
+
509
+ def test_long_options_with_multiple_options
510
+ @p.opt :xarg, "desc", :type => String, :multi => true
511
+ opts = nil
512
+ assert_nothing_raised { opts = @p.parse %w(--xarg=a --xarg=b) }
513
+ assert_equal %w(a b), opts[:xarg]
514
+ assert_equal [], @p.leftovers
515
+ assert_nothing_raised { opts = @p.parse %w(--xarg a --xarg b) }
516
+ assert_equal %w(a b), opts[:xarg]
517
+ assert_equal [], @p.leftovers
518
+ end
519
+
520
+ def test_long_options_with_multiple_arguments
521
+ opts = nil
522
+
523
+ @p.opt :xarg, "desc", :type => :ints
524
+ assert_nothing_raised { opts = @p.parse %w(--xarg 3 2 5) }
525
+ assert_equal [3, 2, 5], opts[:xarg]
526
+ assert_equal [], @p.leftovers
527
+ assert_nothing_raised { opts = @p.parse %w(--xarg=3) }
528
+ assert_equal [3], opts[:xarg]
529
+ assert_equal [], @p.leftovers
530
+
531
+ @p.opt :yarg, "desc", :type => :floats
532
+ assert_nothing_raised { opts = @p.parse %w(--yarg 3.14 2.41 5.66) }
533
+ assert_equal [3.14, 2.41, 5.66], opts[:yarg]
534
+ assert_equal [], @p.leftovers
535
+ assert_nothing_raised { opts = @p.parse %w(--yarg=3.14) }
536
+ assert_equal [3.14], opts[:yarg]
537
+ assert_equal [], @p.leftovers
538
+
539
+ @p.opt :zarg, "desc", :type => :strings
540
+ assert_nothing_raised { opts = @p.parse %w(--zarg a b c) }
541
+ assert_equal %w(a b c), opts[:zarg]
542
+ assert_equal [], @p.leftovers
543
+ assert_nothing_raised { opts = @p.parse %w(--zarg=a) }
544
+ assert_equal %w(a), opts[:zarg]
545
+ assert_equal [], @p.leftovers
546
+ end
547
+
548
+ def test_long_options_with_multiple_options_and_arguments
549
+ opts = nil
550
+
551
+ @p.opt :xarg, "desc", :type => :ints, :multi => true
552
+ assert_nothing_raised { opts = @p.parse %w(--xarg 3 2 5 --xarg 2 1) }
553
+ assert_equal [[3, 2, 5], [2, 1]], opts[:xarg]
554
+ assert_equal [], @p.leftovers
555
+ assert_nothing_raised { opts = @p.parse %w(--xarg=3 --xarg=2) }
556
+ assert_equal [[3], [2]], opts[:xarg]
557
+ assert_equal [], @p.leftovers
558
+
559
+ @p.opt :yarg, "desc", :type => :floats, :multi => true
560
+ assert_nothing_raised { opts = @p.parse %w(--yarg 3.14 2.72 5 --yarg 2.41 1.41) }
561
+ assert_equal [[3.14, 2.72, 5], [2.41, 1.41]], opts[:yarg]
562
+ assert_equal [], @p.leftovers
563
+ assert_nothing_raised { opts = @p.parse %w(--yarg=3.14 --yarg=2.41) }
564
+ assert_equal [[3.14], [2.41]], opts[:yarg]
565
+ assert_equal [], @p.leftovers
566
+
567
+ @p.opt :zarg, "desc", :type => :strings, :multi => true
568
+ assert_nothing_raised { opts = @p.parse %w(--zarg a b c --zarg d e) }
569
+ assert_equal [%w(a b c), %w(d e)], opts[:zarg]
570
+ assert_equal [], @p.leftovers
571
+ assert_nothing_raised { opts = @p.parse %w(--zarg=a --zarg=d) }
572
+ assert_equal [%w(a), %w(d)], opts[:zarg]
573
+ assert_equal [], @p.leftovers
574
+ end
575
+
576
+ def test_long_options_also_take_equals
577
+ @p.opt :arg, "desc", :long => "arg", :type => String, :default => "hello"
578
+ opts = nil
579
+ assert_nothing_raised { opts = @p.parse %w() }
580
+ assert_equal "hello", opts[:arg]
581
+ assert_nothing_raised { opts = @p.parse %w(--arg goat) }
582
+ assert_equal "goat", opts[:arg]
583
+ assert_nothing_raised { opts = @p.parse %w(--arg=goat) }
584
+ assert_equal "goat", opts[:arg]
585
+ ## actually, this next one is valid. empty string for --arg, and goat as a
586
+ ## leftover.
587
+ ## assert_raises(CommandlineError) { opts = @p.parse %w(--arg= goat) }
588
+ end
589
+
590
+ def test_auto_generated_long_names_convert_underscores_to_hyphens
591
+ @p.opt :hello_there
592
+ assert_equal "hello-there", @p.specs[:hello_there][:long]
593
+ end
594
+
595
+ def test_arguments_passed_through_block
596
+ @goat = 3
597
+ boat = 4
598
+ Parser.new(@goat) do |goat|
599
+ boat = goat
600
+ end
601
+ assert_equal @goat, boat
602
+ end
603
+
604
+ def test_help_has_default_banner
605
+ @p = Parser.new
606
+ sio = StringIO.new "w"
607
+ @p.parse []
608
+ @p.educate sio
609
+ help = sio.string.split "\n"
610
+ assert help[0] =~ /options/i
611
+ assert_equal 2, help.length # options, then -h
612
+
613
+ @p = Parser.new
614
+ @p.version "my version"
615
+ sio = StringIO.new "w"
616
+ @p.parse []
617
+ @p.educate sio
618
+ help = sio.string.split "\n"
619
+ assert help[0] =~ /my version/i
620
+ assert_equal 4, help.length # version, options, -h, -v
621
+
622
+ @p = Parser.new
623
+ @p.banner "my own banner"
624
+ sio = StringIO.new "w"
625
+ @p.parse []
626
+ @p.educate sio
627
+ help = sio.string.split "\n"
628
+ assert help[0] =~ /my own banner/i
629
+ assert_equal 2, help.length # banner, -h
630
+ end
631
+
632
+ def test_help_preserves_positions
633
+ @p.opt :zzz, "zzz"
634
+ @p.opt :aaa, "aaa"
635
+ sio = StringIO.new "w"
636
+ @p.educate sio
637
+
638
+ help = sio.string.split "\n"
639
+ assert help[1] =~ /zzz/
640
+ assert help[2] =~ /aaa/
641
+ end
642
+
643
+ def test_version_and_help_short_args_can_be_overridden
644
+ @p.opt :verbose, "desc", :short => "-v"
645
+ @p.opt :hello, "desc", :short => "-h"
646
+ @p.version "version"
647
+
648
+ assert_nothing_raised { @p.parse(%w(-v)) }
649
+ assert_raises(VersionNeeded) { @p.parse(%w(--version)) }
650
+ assert_nothing_raised { @p.parse(%w(-h)) }
651
+ assert_raises(HelpNeeded) { @p.parse(%w(--help)) }
652
+ end
653
+
654
+ def test_version_and_help_long_args_can_be_overridden
655
+ @p.opt :asdf, "desc", :long => "help"
656
+ @p.opt :asdf2, "desc2", :long => "version"
657
+ assert_nothing_raised { @p.parse %w() }
658
+ assert_nothing_raised { @p.parse %w(--help) }
659
+ assert_nothing_raised { @p.parse %w(--version) }
660
+ assert_nothing_raised { @p.parse %w(-h) }
661
+ assert_nothing_raised { @p.parse %w(-v) }
662
+ end
663
+
664
+ def test_version_and_help_override_errors
665
+ @p.opt :asdf, "desc", :type => String
666
+ @p.version "version"
667
+ assert_nothing_raised { @p.parse %w(--asdf goat) }
668
+ assert_raises(CommandlineError) { @p.parse %w(--asdf) }
669
+ assert_raises(HelpNeeded) { @p.parse %w(--asdf --help) }
670
+ assert_raises(VersionNeeded) { @p.parse %w(--asdf --version) }
671
+ end
672
+
673
+ def test_conflicts
674
+ @p.opt :one
675
+ assert_raises(ArgumentError) { @p.conflicts :one, :two }
676
+ @p.opt :two
677
+ assert_nothing_raised { @p.conflicts :one, :two }
678
+ assert_nothing_raised { @p.parse %w(--one) }
679
+ assert_nothing_raised { @p.parse %w(--two) }
680
+ assert_raises(CommandlineError) { opts = @p.parse %w(--one --two) }
681
+
682
+ @p.opt :hello
683
+ @p.opt :yellow
684
+ @p.opt :mellow
685
+ @p.opt :jello
686
+ @p.conflicts :hello, :yellow, :mellow, :jello
687
+ assert_raises(CommandlineError) { opts = @p.parse %w(--hello --yellow --mellow --jello) }
688
+ assert_raises(CommandlineError) { opts = @p.parse %w(--hello --mellow --jello) }
689
+ assert_raises(CommandlineError) { opts = @p.parse %w(--hello --jello) }
690
+
691
+ assert_nothing_raised { opts = @p.parse %w(--hello) }
692
+ assert_nothing_raised { opts = @p.parse %w(--jello) }
693
+ assert_nothing_raised { opts = @p.parse %w(--yellow) }
694
+ assert_nothing_raised { opts = @p.parse %w(--mellow) }
695
+
696
+ assert_nothing_raised { opts = @p.parse %w(--mellow --one) }
697
+ assert_nothing_raised { opts = @p.parse %w(--mellow --two) }
698
+
699
+ assert_raises(CommandlineError) { opts = @p.parse %w(--mellow --two --jello) }
700
+ assert_raises(CommandlineError) { opts = @p.parse %w(--one --mellow --two --jello) }
701
+ end
702
+
703
+ def test_conflict_error_messages
704
+ @p.opt :one
705
+ @p.opt "two"
706
+ @p.conflicts :one, "two"
707
+
708
+ begin
709
+ @p.parse %w(--one --two)
710
+ flunk "no error thrown"
711
+ rescue CommandlineError => e
712
+ assert_match(/--one/, e.message)
713
+ assert_match(/--two/, e.message)
714
+ end
715
+ end
716
+
717
+ def test_depends
718
+ @p.opt :one
719
+ assert_raises(ArgumentError) { @p.depends :one, :two }
720
+ @p.opt :two
721
+ assert_nothing_raised { @p.depends :one, :two }
722
+ assert_nothing_raised { opts = @p.parse %w(--one --two) }
723
+ assert_raises(CommandlineError) { @p.parse %w(--one) }
724
+ assert_raises(CommandlineError) { @p.parse %w(--two) }
725
+
726
+ @p.opt :hello
727
+ @p.opt :yellow
728
+ @p.opt :mellow
729
+ @p.opt :jello
730
+ @p.depends :hello, :yellow, :mellow, :jello
731
+ assert_nothing_raised { opts = @p.parse %w(--hello --yellow --mellow --jello) }
732
+ assert_raises(CommandlineError) { opts = @p.parse %w(--hello --mellow --jello) }
733
+ assert_raises(CommandlineError) { opts = @p.parse %w(--hello --jello) }
734
+
735
+ assert_raises(CommandlineError) { opts = @p.parse %w(--hello) }
736
+ assert_raises(CommandlineError) { opts = @p.parse %w(--mellow) }
737
+
738
+ assert_nothing_raised { opts = @p.parse %w(--hello --yellow --mellow --jello --one --two) }
739
+ assert_nothing_raised { opts = @p.parse %w(--hello --yellow --mellow --jello --one --two a b c) }
740
+
741
+ assert_raises(CommandlineError) { opts = @p.parse %w(--mellow --two --jello --one) }
742
+ end
743
+
744
+ def test_depend_error_messages
745
+ @p.opt :one
746
+ @p.opt "two"
747
+ @p.depends :one, "two"
748
+
749
+ assert_nothing_raised { @p.parse %w(--one --two) }
750
+
751
+ begin
752
+ @p.parse %w(--one)
753
+ flunk "no error thrown"
754
+ rescue CommandlineError => e
755
+ assert_match(/--one/, e.message)
756
+ assert_match(/--two/, e.message)
757
+ end
758
+
759
+ begin
760
+ @p.parse %w(--two)
761
+ flunk "no error thrown"
762
+ rescue CommandlineError => e
763
+ assert_match(/--one/, e.message)
764
+ assert_match(/--two/, e.message)
765
+ end
766
+ end
767
+
768
+ ## courtesy neill zero
769
+ def test_two_required_one_missing_accuses_correctly
770
+ @p.opt "arg1", "desc1", :required => true
771
+ @p.opt "arg2", "desc2", :required => true
772
+
773
+ begin
774
+ @p.parse(%w(--arg1))
775
+ flunk "should have failed on a missing req"
776
+ rescue CommandlineError => e
777
+ assert e.message =~ /arg2/, "didn't mention arg2 in the error msg: #{e.message}"
778
+ end
779
+
780
+ begin
781
+ @p.parse(%w(--arg2))
782
+ flunk "should have failed on a missing req"
783
+ rescue CommandlineError => e
784
+ assert e.message =~ /arg1/, "didn't mention arg1 in the error msg: #{e.message}"
785
+ end
786
+
787
+ assert_nothing_raised { @p.parse(%w(--arg1 --arg2)) }
788
+ end
789
+
790
+ def test_stopwords_mixed
791
+ @p.opt "arg1", :default => false
792
+ @p.opt "arg2", :default => false
793
+ @p.stop_on %w(happy sad)
794
+
795
+ opts = @p.parse %w(--arg1 happy --arg2)
796
+ assert_equal true, opts["arg1"]
797
+ assert_equal false, opts["arg2"]
798
+
799
+ ## restart parsing
800
+ @p.leftovers.shift
801
+ opts = @p.parse @p.leftovers
802
+ assert_equal false, opts["arg1"]
803
+ assert_equal true, opts["arg2"]
804
+ end
805
+
806
+ def test_stopwords_no_stopwords
807
+ @p.opt "arg1", :default => false
808
+ @p.opt "arg2", :default => false
809
+ @p.stop_on %w(happy sad)
810
+
811
+ opts = @p.parse %w(--arg1 --arg2)
812
+ assert_equal true, opts["arg1"]
813
+ assert_equal true, opts["arg2"]
814
+
815
+ ## restart parsing
816
+ @p.leftovers.shift
817
+ opts = @p.parse @p.leftovers
818
+ assert_equal false, opts["arg1"]
819
+ assert_equal false, opts["arg2"]
820
+ end
821
+
822
+ def test_stopwords_multiple_stopwords
823
+ @p.opt "arg1", :default => false
824
+ @p.opt "arg2", :default => false
825
+ @p.stop_on %w(happy sad)
826
+
827
+ opts = @p.parse %w(happy sad --arg1 --arg2)
828
+ assert_equal false, opts["arg1"]
829
+ assert_equal false, opts["arg2"]
830
+
831
+ ## restart parsing
832
+ @p.leftovers.shift
833
+ opts = @p.parse @p.leftovers
834
+ assert_equal false, opts["arg1"]
835
+ assert_equal false, opts["arg2"]
836
+
837
+ ## restart parsing again
838
+ @p.leftovers.shift
839
+ opts = @p.parse @p.leftovers
840
+ assert_equal true, opts["arg1"]
841
+ assert_equal true, opts["arg2"]
842
+ end
843
+
844
+ def test_stopwords_with_short_args
845
+ @p.opt :global_option, "This is a global option", :short => "-g"
846
+ @p.stop_on %w(sub-command-1 sub-command-2)
847
+
848
+ global_opts = @p.parse %w(-g sub-command-1 -c)
849
+ cmd = @p.leftovers.shift
850
+
851
+ @q = Parser.new
852
+ @q.opt :cmd_option, "This is an option only for the subcommand", :short => "-c"
853
+ cmd_opts = @q.parse @p.leftovers
854
+
855
+ assert_equal true, global_opts[:global_option]
856
+ assert_nil global_opts[:cmd_option]
857
+
858
+ assert_equal true, cmd_opts[:cmd_option]
859
+ assert_nil cmd_opts[:global_option]
860
+
861
+ assert_equal cmd, "sub-command-1"
862
+ assert_equal @q.leftovers, []
863
+ end
864
+
865
+ def assert_parses_correctly(parser, commandline, expected_opts,
866
+ expected_leftovers)
867
+ opts = parser.parse commandline
868
+ assert_equal expected_opts, opts
869
+ assert_equal expected_leftovers, parser.leftovers
870
+ end
871
+
872
+ def test_unknown_subcommand
873
+ @p.opt :global_flag, "Global flag", :short => "-g", :type => :flag
874
+ @p.opt :global_param, "Global parameter", :short => "-p", :default => 5
875
+ @p.stop_on_unknown
876
+
877
+ expected_opts = { :global_flag => true, :help => false, :global_param => 5, :global_flag_given => true }
878
+ expected_leftovers = [ "my_subcommand", "-c" ]
879
+
880
+ assert_parses_correctly @p, %w(--global-flag my_subcommand -c), \
881
+ expected_opts, expected_leftovers
882
+ assert_parses_correctly @p, %w(-g my_subcommand -c), \
883
+ expected_opts, expected_leftovers
884
+
885
+ expected_opts = { :global_flag => false, :help => false, :global_param => 5, :global_param_given => true }
886
+ expected_leftovers = [ "my_subcommand", "-c" ]
887
+
888
+ assert_parses_correctly @p, %w(-p 5 my_subcommand -c), \
889
+ expected_opts, expected_leftovers
890
+ assert_parses_correctly @p, %w(--global-param 5 my_subcommand -c), \
891
+ expected_opts, expected_leftovers
892
+ end
893
+
894
+ def test_alternate_args
895
+ args = %w(-a -b -c)
896
+
897
+ opts = ::Trollop.options(args) do
898
+ opt :alpher, "Ralph Alpher", :short => "-a"
899
+ opt :bethe, "Hans Bethe", :short => "-b"
900
+ opt :gamow, "George Gamow", :short => "-c"
901
+ end
902
+
903
+ physicists_with_humor = [:alpher, :bethe, :gamow]
904
+ physicists_with_humor.each do |physicist|
905
+ assert_equal true, opts[physicist]
906
+ end
907
+ end
908
+
909
+ def test_io_arg_type
910
+ @p.opt :arg, "desc", :type => :io
911
+ @p.opt :arg2, "desc", :type => IO
912
+ @p.opt :arg3, "desc", :default => $stdout
913
+
914
+ opts = nil
915
+ assert_nothing_raised { opts = @p.parse() }
916
+ assert_equal $stdout, opts[:arg3]
917
+
918
+ assert_nothing_raised { opts = @p.parse %w(--arg /dev/null) }
919
+ assert_kind_of File, opts[:arg]
920
+ assert_equal "/dev/null", opts[:arg].path
921
+
922
+ #TODO: move to mocks
923
+ #assert_nothing_raised { opts = @p.parse %w(--arg2 http://google.com/) }
924
+ #assert_kind_of StringIO, opts[:arg2]
925
+
926
+ assert_nothing_raised { opts = @p.parse %w(--arg3 stdin) }
927
+ assert_equal $stdin, opts[:arg3]
928
+
929
+ assert_raises(CommandlineError) { opts = @p.parse %w(--arg /fdasfasef/fessafef/asdfasdfa/fesasf) }
930
+ end
931
+
932
+ def test_openstruct_style_access
933
+ @p.opt "arg1", "desc", :type => :int
934
+ @p.opt :arg2, "desc", :type => :int
935
+
936
+ opts = @p.parse(%w(--arg1 3 --arg2 4))
937
+
938
+ assert_nothing_raised { opts.arg1 }
939
+ assert_nothing_raised { opts.arg2 }
940
+ assert_equal 3, opts.arg1
941
+ assert_equal 4, opts.arg2
942
+ end
943
+
944
+ def test_multi_args_autobox_defaults
945
+ @p.opt :arg1, "desc", :default => "hello", :multi => true
946
+ @p.opt :arg2, "desc", :default => ["hello"], :multi => true
947
+
948
+ opts = @p.parse
949
+ assert_equal ["hello"], opts[:arg1]
950
+ assert_equal ["hello"], opts[:arg2]
951
+
952
+ opts = @p.parse %w(--arg1 hello)
953
+ assert_equal ["hello"], opts[:arg1]
954
+ assert_equal ["hello"], opts[:arg2]
955
+
956
+ opts = @p.parse %w(--arg1 hello --arg1 there)
957
+ assert_equal ["hello", "there"], opts[:arg1]
958
+ end
959
+
960
+ def test_ambigious_multi_plus_array_default_resolved_as_specified_by_documentation
961
+ @p.opt :arg1, "desc", :default => ["potato"], :multi => true
962
+ @p.opt :arg2, "desc", :default => ["potato"], :multi => true, :type => :strings
963
+ @p.opt :arg3, "desc", :default => ["potato"]
964
+ @p.opt :arg4, "desc", :default => ["potato", "rhubarb"], :short => :none, :multi => true
965
+
966
+ ## arg1 should be multi-occurring but not multi-valued
967
+ opts = @p.parse %w(--arg1 one two)
968
+ assert_equal ["one"], opts[:arg1]
969
+ assert_equal ["two"], @p.leftovers
970
+
971
+ opts = @p.parse %w(--arg1 one --arg1 two)
972
+ assert_equal ["one", "two"], opts[:arg1]
973
+ assert_equal [], @p.leftovers
974
+
975
+ ## arg2 should be multi-valued and multi-occurring
976
+ opts = @p.parse %w(--arg2 one two)
977
+ assert_equal [["one", "two"]], opts[:arg2]
978
+ assert_equal [], @p.leftovers
979
+
980
+ ## arg3 should be multi-valued but not multi-occurring
981
+ opts = @p.parse %w(--arg3 one two)
982
+ assert_equal ["one", "two"], opts[:arg3]
983
+ assert_equal [], @p.leftovers
984
+
985
+ ## arg4 should be multi-valued but not multi-occurring
986
+ opts = @p.parse %w()
987
+ assert_equal ["potato", "rhubarb"], opts[:arg4]
988
+ end
989
+
990
+ def test_given_keys
991
+ @p.opt :arg1
992
+ @p.opt :arg2
993
+
994
+ opts = @p.parse %w(--arg1)
995
+ assert opts[:arg1_given]
996
+ assert !opts[:arg2_given]
997
+
998
+ opts = @p.parse %w(--arg2)
999
+ assert !opts[:arg1_given]
1000
+ assert opts[:arg2_given]
1001
+
1002
+ opts = @p.parse []
1003
+ assert !opts[:arg1_given]
1004
+ assert !opts[:arg2_given]
1005
+
1006
+ opts = @p.parse %w(--arg1 --arg2)
1007
+ assert opts[:arg1_given]
1008
+ assert opts[:arg2_given]
1009
+ end
1010
+
1011
+ def test_default_shorts_assigned_only_after_user_shorts
1012
+ @p.opt :aab, "aaa" # should be assigned to -b
1013
+ @p.opt :ccd, "bbb" # should be assigned to -d
1014
+ @p.opt :user1, "user1", :short => 'a'
1015
+ @p.opt :user2, "user2", :short => 'c'
1016
+
1017
+ opts = @p.parse %w(-a -b)
1018
+ assert opts[:user1]
1019
+ assert !opts[:user2]
1020
+ assert opts[:aab]
1021
+ assert !opts[:ccd]
1022
+
1023
+ opts = @p.parse %w(-c -d)
1024
+ assert !opts[:user1]
1025
+ assert opts[:user2]
1026
+ assert !opts[:aab]
1027
+ assert opts[:ccd]
1028
+ end
1029
+
1030
+ def test_accepts_arguments_with_spaces
1031
+ @p.opt :arg1, "arg", :type => String
1032
+ @p.opt :arg2, "arg2", :type => String
1033
+
1034
+ opts = @p.parse ["--arg1", "hello there", "--arg2=hello there"]
1035
+ assert_equal "hello there", opts[:arg1]
1036
+ assert_equal "hello there", opts[:arg2]
1037
+ assert_equal 0, @p.leftovers.size
1038
+ end
1039
+
1040
+ def test_multi_args_default_to_empty_array
1041
+ @p.opt :arg1, "arg", :multi => true
1042
+ opts = @p.parse ""
1043
+ assert_equal [], opts[:arg1]
1044
+ end
1045
+ end
1046
+
1047
+ end
1048
+ end