user-choices 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +17 -0
- data/LICENSE.txt +34 -0
- data/Manifest.txt +40 -0
- data/README.txt +1 -0
- data/Rakefile +19 -0
- data/Rakefile.hoe +24 -0
- data/examples/older/README.txt +133 -0
- data/examples/older/command-line.rb +51 -0
- data/examples/older/default-values.rb +47 -0
- data/examples/older/multiple-sources.rb +63 -0
- data/examples/older/postprocess.rb +45 -0
- data/examples/older/switches.rb +50 -0
- data/examples/older/two-args.rb +37 -0
- data/examples/older/types.rb +67 -0
- data/examples/tutorial/index.html +648 -0
- data/examples/tutorial/tutorial1.rb +48 -0
- data/examples/tutorial/tutorial2.rb +52 -0
- data/examples/tutorial/tutorial3.rb +55 -0
- data/examples/tutorial/tutorial4.rb +55 -0
- data/examples/tutorial/tutorial5.rb +42 -0
- data/examples/tutorial/tutorial6.rb +42 -0
- data/examples/tutorial/tutorial7.rb +48 -0
- data/lib/user-choices/arglist-strategies.rb +178 -0
- data/lib/user-choices/builder.rb +89 -0
- data/lib/user-choices/command-line-source.rb +220 -0
- data/lib/user-choices/command.rb +42 -0
- data/lib/user-choices/conversions.rb +154 -0
- data/lib/user-choices/ruby-extensions.rb +20 -0
- data/lib/user-choices/sources.rb +269 -0
- data/lib/user-choices/version.rb +3 -0
- data/lib/user-choices.rb +131 -0
- data/setup.rb +1585 -0
- data/test/arglist-strategy-tests.rb +42 -0
- data/test/builder-tests.rb +569 -0
- data/test/command-line-source-tests.rb +443 -0
- data/test/conversion-tests.rb +157 -0
- data/test/set-standalone-test-paths.rb +5 -0
- data/test/source-tests.rb +442 -0
- data/test/user-choices-slowtests.rb +274 -0
- data/user-choices.tmproj +575 -0
- metadata +138 -0
@@ -0,0 +1,42 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Created by Brian Marick on 2007-08-10.
|
4
|
+
# Copyright (c) 2007. All rights reserved.
|
5
|
+
|
6
|
+
load "set-standalone-test-paths.rb" unless $started_from_rakefile
|
7
|
+
require 'test/unit'
|
8
|
+
require 's4t-utils'
|
9
|
+
require 'builder'
|
10
|
+
require 'user-choices/arglist-strategies'
|
11
|
+
include S4tUtils
|
12
|
+
|
13
|
+
# Since ArglistStrategies were extracted from CommandLineSource, most
|
14
|
+
# of the testing is implicit.
|
15
|
+
|
16
|
+
class AbstractArglistStrategyTests < Test::Unit::TestCase
|
17
|
+
include UserChoices
|
18
|
+
|
19
|
+
def test_range_violation_descriptions
|
20
|
+
@arglist_handler = AbstractArglistStrategy.new('unimportant')
|
21
|
+
# Good about plurals.
|
22
|
+
assert_match(/2 arguments given, 3 expected/,
|
23
|
+
@arglist_handler.arglist_arity_error(2, 3))
|
24
|
+
|
25
|
+
assert_match(/1 argument given, 3 expected/,
|
26
|
+
@arglist_handler.arglist_arity_error(1, 3))
|
27
|
+
|
28
|
+
assert_match(/0 arguments given, 1 expected/,
|
29
|
+
@arglist_handler.arglist_arity_error(0, 1))
|
30
|
+
|
31
|
+
# Handle both types of ranges.
|
32
|
+
assert_match(/2 arguments given, 3 to 5 expected/,
|
33
|
+
@arglist_handler.arglist_arity_error(2, 3..5))
|
34
|
+
assert_match(/1 argument given, 3 to 5 expected/,
|
35
|
+
@arglist_handler.arglist_arity_error(1, 3...6))
|
36
|
+
|
37
|
+
# Use 'or' if there are only two alternatives.
|
38
|
+
assert_match(/2 arguments given, 3 or 4 expected/,
|
39
|
+
@arglist_handler.arglist_arity_error(2, 3..4))
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,569 @@
|
|
1
|
+
load "set-standalone-test-paths.rb" unless $started_from_rakefile
|
2
|
+
require 'test/unit'
|
3
|
+
require 's4t-utils'
|
4
|
+
require 'user-choices'
|
5
|
+
include S4tUtils
|
6
|
+
|
7
|
+
|
8
|
+
class TestDefaultsAndTypes < Test::Unit::TestCase
|
9
|
+
include UserChoices
|
10
|
+
|
11
|
+
def test_builder_can_add_defaults
|
12
|
+
b = ChoicesBuilder.new
|
13
|
+
b.add_choice(:trip_steps, :default => '5')
|
14
|
+
choices = b.build
|
15
|
+
assert_equal('5', choices[:trip_steps])
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_defaults_need_not_be_strings
|
19
|
+
b = ChoicesBuilder.new
|
20
|
+
b.add_choice(:trip_steps, :default => 5)
|
21
|
+
choices = b.build
|
22
|
+
assert_equal(5, choices[:trip_steps])
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_builder_can_declare_types_and_do_error_checking
|
26
|
+
b = ChoicesBuilder.new
|
27
|
+
b.add_choice(:trip_steps, :default => 'a', :type => :integer)
|
28
|
+
assert_raises_with_matching_message(StandardError,
|
29
|
+
/:trip_steps's value must be an integer, and 'a'/) {
|
30
|
+
b.build
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_builder_can_declare_types_and_do_conversions
|
35
|
+
b = ChoicesBuilder.new
|
36
|
+
b.add_choice(:csv, :default => 'true', :type => :boolean)
|
37
|
+
choices = b.build
|
38
|
+
assert_equal(true, choices[:csv])
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_some_types_cause_no_conversion
|
42
|
+
# Checking is done
|
43
|
+
b = ChoicesBuilder.new
|
44
|
+
b.add_choice(:trip_steps, :default => 'a', :type => ['b', 'c'])
|
45
|
+
assert_raises_with_matching_message(StandardError,
|
46
|
+
/'a' doesn't look right/) {
|
47
|
+
b.build
|
48
|
+
}
|
49
|
+
|
50
|
+
# ... but, if checking passes, no changes are made
|
51
|
+
b = ChoicesBuilder.new
|
52
|
+
b.add_choice(:trip_steps, :default => 'b', :type => ['b', 'c'])
|
53
|
+
assert_equal('b', b.build[:trip_steps])
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_arrays_can_be_built_from_comma_separated_list
|
57
|
+
b = ChoicesBuilder.new
|
58
|
+
b.add_choice(:targets, :default => 'a,b,cd',
|
59
|
+
:type => [:string])
|
60
|
+
assert_equal(['a', 'b', 'cd'],
|
61
|
+
b.build[:targets])
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_arrays_can_be_accepted_as_is
|
65
|
+
b = ChoicesBuilder.new
|
66
|
+
b.add_choice(:targets, :default => ['a', 'b', 'c'],
|
67
|
+
:type => [:string])
|
68
|
+
assert_equal(['a', 'b', 'c'], b.build[:targets])
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_arrays_are_constructed_from_single_elements
|
72
|
+
b = ChoicesBuilder.new
|
73
|
+
b.add_choice(:targets, :default => 'a',
|
74
|
+
:type => [:string])
|
75
|
+
assert_equal(['a'], b.build[:targets])
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_array_lengths_can_be_specified_exactly
|
79
|
+
b = ChoicesBuilder.new
|
80
|
+
b.add_choice(:targets, :length => 2, :default => ['wrong'])
|
81
|
+
assert_raises_with_matching_message(StandardError, /must be of length 2/) {
|
82
|
+
b.build
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_array_lengths_can_be_specified_by_range
|
87
|
+
b = ChoicesBuilder.new
|
88
|
+
b.add_choice(:targets, :length => 2..3, :default => ['wrong'])
|
89
|
+
assert_raises_with_matching_message(StandardError, /this range: 2..3/) {
|
90
|
+
b.build
|
91
|
+
}
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_array_lengths_apply_to_command_line_args # didn't used to, not in the same way.
|
95
|
+
with_command_args("a b c d") {
|
96
|
+
b = ChoicesBuilder.new
|
97
|
+
b.add_source(CommandLineSource, :usage, 'foo')
|
98
|
+
b.add_choice(:targets, :length => 2..3) { |command_line |
|
99
|
+
command_line.uses_arglist
|
100
|
+
}
|
101
|
+
|
102
|
+
output = capturing_stderr do
|
103
|
+
assert_wants_to_exit do
|
104
|
+
b.build
|
105
|
+
end
|
106
|
+
end
|
107
|
+
assert_match(/^Error in the command line: 4 arguments given, 2 or 3 expected/, output)
|
108
|
+
}
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_missing_required_arg_is_caught_by_command_line
|
112
|
+
with_command_args("") {
|
113
|
+
b = ChoicesBuilder.new
|
114
|
+
b.add_source(CommandLineSource, :usage, 'foo')
|
115
|
+
b.add_choice(:targets) { |command_line |
|
116
|
+
command_line.uses_arg
|
117
|
+
}
|
118
|
+
|
119
|
+
output = capturing_stderr do
|
120
|
+
assert_wants_to_exit do
|
121
|
+
b.build
|
122
|
+
end
|
123
|
+
end
|
124
|
+
assert_match(/^Error in the command line: 0 arguments given, 1 expected/, output)
|
125
|
+
}
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_extra_required_arg_is_caught_by_command_line
|
129
|
+
with_command_args("one extra") {
|
130
|
+
b = ChoicesBuilder.new
|
131
|
+
b.add_source(CommandLineSource, :usage, 'foo')
|
132
|
+
b.add_choice(:targets) { |command_line |
|
133
|
+
command_line.uses_arg
|
134
|
+
}
|
135
|
+
|
136
|
+
output = capturing_stderr do
|
137
|
+
assert_wants_to_exit do
|
138
|
+
b.build
|
139
|
+
end
|
140
|
+
end
|
141
|
+
assert_match(/^Error in the command line: 2 arguments given, 1 expected/, output)
|
142
|
+
}
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_extra_optional_arg_is_caught_by_command_line
|
146
|
+
with_command_args("one extra") {
|
147
|
+
b = ChoicesBuilder.new
|
148
|
+
b.add_source(CommandLineSource, :usage, 'foo')
|
149
|
+
b.add_choice(:targets) { |command_line |
|
150
|
+
command_line.uses_optional_arg
|
151
|
+
}
|
152
|
+
|
153
|
+
output = capturing_stderr do
|
154
|
+
assert_wants_to_exit do
|
155
|
+
b.build
|
156
|
+
end
|
157
|
+
end
|
158
|
+
assert_match(/^Error in the command line: 2 arguments given, 0 or 1 expected/, output)
|
159
|
+
}
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
class TestChainingOfSources < Test::Unit::TestCase
|
164
|
+
include UserChoices
|
165
|
+
|
166
|
+
def test_sources_are_chained_correctly
|
167
|
+
with_environment_vars("prefix_in_ecd" => "e") {
|
168
|
+
with_local_config_file(".builder_rc",
|
169
|
+
"<config>
|
170
|
+
<in_ecd>c</in_ecd>
|
171
|
+
<in_cd>c</in_cd>
|
172
|
+
</config>") {
|
173
|
+
b = ChoicesBuilder.new
|
174
|
+
b.add_source(EnvironmentSource, :with_prefix, "prefix_")
|
175
|
+
b.add_source(XmlConfigFileSource, :from_file, ".builder_rc")
|
176
|
+
|
177
|
+
b.add_choice(:in_ecd, :default => "d")
|
178
|
+
b.add_choice(:in_cd, :default => "d")
|
179
|
+
b.add_choice(:in_d, :default => "d")
|
180
|
+
|
181
|
+
choices = b.build
|
182
|
+
|
183
|
+
assert_equal('e', choices[:in_ecd])
|
184
|
+
assert_equal('c', choices[:in_cd])
|
185
|
+
assert_equal('d', choices[:in_d])
|
186
|
+
}
|
187
|
+
}
|
188
|
+
end
|
189
|
+
|
190
|
+
|
191
|
+
def test_priority_over_default
|
192
|
+
with_command_args("--option perfectly-fine --only-cmd=oc") {
|
193
|
+
b = ChoicesBuilder.new
|
194
|
+
b.add_source(CommandLineSource, :usage, "blah, blah")
|
195
|
+
b.add_choice(:option, :default => '0.3') { | command_line |
|
196
|
+
command_line.uses_option('--option VALUE')
|
197
|
+
}
|
198
|
+
b.add_choice(:only_cmd) { |command_line|
|
199
|
+
command_line.uses_option('--only-cmd VALUE')
|
200
|
+
}
|
201
|
+
b.add_choice(:only_default, :default => 'od')
|
202
|
+
choices = b.build
|
203
|
+
assert_equal("perfectly-fine", choices[:option])
|
204
|
+
assert_equal("oc", choices[:only_cmd])
|
205
|
+
assert_equal("od", choices[:only_default])
|
206
|
+
}
|
207
|
+
end
|
208
|
+
|
209
|
+
def test_checking_is_done_for_all_sources
|
210
|
+
with_command_args("--command-option perfectly-fine") {
|
211
|
+
assert_raises_with_matching_message(StandardError,
|
212
|
+
/^Error in the default values/) {
|
213
|
+
b = ChoicesBuilder.new
|
214
|
+
b.add_source(CommandLineSource, :usage, "blah")
|
215
|
+
b.add_choice(:command_option) { | command_line |
|
216
|
+
command_line.uses_option('--command-option VALUE')
|
217
|
+
}
|
218
|
+
b.add_choice(:broken, :default => '0.3', :type => :integer)
|
219
|
+
b.build
|
220
|
+
}
|
221
|
+
}
|
222
|
+
end
|
223
|
+
|
224
|
+
def test_conversions_are_done_for_all_sources
|
225
|
+
with_environment_vars("amazon_rc" => "1") {
|
226
|
+
b = ChoicesBuilder.new
|
227
|
+
b.add_source(EnvironmentSource, :with_prefix, 'amazon')
|
228
|
+
b.add_choice(:_rc, :type => :integer, :default => '3')
|
229
|
+
assert_equal(1, b.build[:_rc])
|
230
|
+
}
|
231
|
+
end
|
232
|
+
|
233
|
+
def test_unmentioned_choices_are_nil
|
234
|
+
with_environment_vars("amazon_rc" => "1") {
|
235
|
+
b = ChoicesBuilder.new
|
236
|
+
b.add_source(EnvironmentSource, :with_prefix, 'amazon_')
|
237
|
+
b.add_choice(:rc, :default => 5, :type => :integer)
|
238
|
+
choices = b.build
|
239
|
+
assert_equal(nil, choices[:unmentioned])
|
240
|
+
assert_equal(1, choices[:rc]) # for fun
|
241
|
+
}
|
242
|
+
end
|
243
|
+
|
244
|
+
def test_given_optional_args_override_lower_precedence_sources
|
245
|
+
with_command_args("override") {
|
246
|
+
b = ChoicesBuilder.new
|
247
|
+
b.add_source(CommandLineSource, :usage, "blah")
|
248
|
+
b.add_choice(:name, :default => 'default') { | command_line |
|
249
|
+
command_line.uses_optional_arg
|
250
|
+
}
|
251
|
+
choices = b.build
|
252
|
+
assert_equal('override', choices[:name])
|
253
|
+
}
|
254
|
+
end
|
255
|
+
|
256
|
+
def test_non_empty_arglists_override_lower_precedence_sources
|
257
|
+
with_command_args("1") {
|
258
|
+
b = ChoicesBuilder.new
|
259
|
+
b.add_source(CommandLineSource, :usage, 'blah')
|
260
|
+
b.add_choice(:name, :default => ['default', '1']) { |command_line|
|
261
|
+
command_line.uses_arglist
|
262
|
+
}
|
263
|
+
assert_equal(['1'], b.build[:name])
|
264
|
+
}
|
265
|
+
end
|
266
|
+
|
267
|
+
end
|
268
|
+
|
269
|
+
|
270
|
+
class TestInteractionOfArglistsWithOtherSources < Test::Unit::TestCase
|
271
|
+
include UserChoices
|
272
|
+
|
273
|
+
def test_missing_optional_args_do_not_override_lower_precedence_sources
|
274
|
+
with_command_args("") {
|
275
|
+
b = ChoicesBuilder.new
|
276
|
+
b.add_source(CommandLineSource, :usage, 'blah')
|
277
|
+
b.add_choice(:name, :default => 'default') { |command_line|
|
278
|
+
command_line.uses_optional_arg
|
279
|
+
}
|
280
|
+
assert_equal('default', b.build[:name])
|
281
|
+
}
|
282
|
+
end
|
283
|
+
|
284
|
+
def test_missing_optional_args_are_ok_if_no_lower_precedence_sources
|
285
|
+
with_command_args("") {
|
286
|
+
b = ChoicesBuilder.new
|
287
|
+
b.add_source(CommandLineSource, :usage, 'blah')
|
288
|
+
b.add_choice(:name) { |command_line|
|
289
|
+
command_line.uses_optional_arg
|
290
|
+
}
|
291
|
+
assert_false(b.build.has_key?(:name))
|
292
|
+
}
|
293
|
+
end
|
294
|
+
|
295
|
+
def test_present_optional_args_do_override_lower_precedence_sources
|
296
|
+
with_command_args("1") {
|
297
|
+
b = ChoicesBuilder.new
|
298
|
+
b.add_source(CommandLineSource, :usage, 'blah')
|
299
|
+
b.add_choice(:name, :default => 'default') { |command_line|
|
300
|
+
command_line.uses_optional_arg
|
301
|
+
}
|
302
|
+
assert_equal('1', b.build[:name])
|
303
|
+
}
|
304
|
+
end
|
305
|
+
|
306
|
+
|
307
|
+
|
308
|
+
def test_empty_arglists_do_not_override_lower_precedence_sources
|
309
|
+
# nothing / stuff
|
310
|
+
xml = "<config><names>1</names><names>2</names></config>"
|
311
|
+
with_local_config_file("test-config", xml) {
|
312
|
+
with_command_args("") {
|
313
|
+
b = ChoicesBuilder.new
|
314
|
+
b.add_source(CommandLineSource, :usage, 'blah')
|
315
|
+
b.add_source(XmlConfigFileSource, :from_file, 'test-config')
|
316
|
+
b.add_choice(:names) { |command_line|
|
317
|
+
command_line.uses_arglist
|
318
|
+
}
|
319
|
+
assert_equal(['1', '2'], b.build[:names])
|
320
|
+
}
|
321
|
+
}
|
322
|
+
end
|
323
|
+
|
324
|
+
def test_default_empty_arglist_is_empty_array
|
325
|
+
# nothing / nothing
|
326
|
+
with_command_args("") {
|
327
|
+
b = ChoicesBuilder.new
|
328
|
+
b.add_source(CommandLineSource, :usage, 'blah')
|
329
|
+
b.add_choice(:names) { |command_line|
|
330
|
+
command_line.uses_arglist
|
331
|
+
}
|
332
|
+
assert_equal([], b.build[:names])
|
333
|
+
}
|
334
|
+
end
|
335
|
+
|
336
|
+
def test_default_empty_arglist_can_be_set_explicitly
|
337
|
+
# nothing / nothing
|
338
|
+
with_command_args("") {
|
339
|
+
b = ChoicesBuilder.new
|
340
|
+
b.add_source(CommandLineSource, :usage, 'blah')
|
341
|
+
b.add_choice(:names, :default => ['fred']) { |command_line|
|
342
|
+
command_line.uses_arglist
|
343
|
+
}
|
344
|
+
assert_equal(['fred'], b.build[:names])
|
345
|
+
}
|
346
|
+
end
|
347
|
+
|
348
|
+
def test_present_arglist_does_override_lower_precedence_sources
|
349
|
+
# stuff / stuff
|
350
|
+
with_command_args("1") {
|
351
|
+
b = ChoicesBuilder.new
|
352
|
+
b.add_source(CommandLineSource, :usage, 'blah')
|
353
|
+
b.add_choice(:names, :default => ['default']) { |command_line|
|
354
|
+
command_line.uses_arglist
|
355
|
+
}
|
356
|
+
assert_equal(['1'], b.build[:names])
|
357
|
+
}
|
358
|
+
end
|
359
|
+
|
360
|
+
def test_setup_for_overridable_empty_argument_list_is_compatible_with_length
|
361
|
+
# This is an implementation-dependent test. Command-line arguments can
|
362
|
+
# be empty, yet overridden by less-important sources. This is done by
|
363
|
+
# initializing the default value to the empty list. But that must not
|
364
|
+
# trigger the length check.
|
365
|
+
with_command_args("1 2") {
|
366
|
+
b = ChoicesBuilder.new
|
367
|
+
b.add_source(CommandLineSource, :usage, 'blah')
|
368
|
+
b.add_choice(:names, :length => 2) { |command_line|
|
369
|
+
command_line.uses_arglist
|
370
|
+
}
|
371
|
+
assert_equal(['1', '2'], b.build[:names])
|
372
|
+
}
|
373
|
+
end
|
374
|
+
|
375
|
+
def test_an_empty_arglist_is_caught_by_the_length_check
|
376
|
+
with_command_args("") {
|
377
|
+
b = ChoicesBuilder.new
|
378
|
+
b.add_source(CommandLineSource, :usage, 'blah')
|
379
|
+
b.add_choice(:names, :length => 2) { |command_line|
|
380
|
+
command_line.uses_arglist
|
381
|
+
}
|
382
|
+
output = capturing_stderr do
|
383
|
+
assert_wants_to_exit do
|
384
|
+
b.build
|
385
|
+
end
|
386
|
+
end
|
387
|
+
assert_match(/command line: 0 arguments given, 2 expected/, output)
|
388
|
+
}
|
389
|
+
end
|
390
|
+
|
391
|
+
|
392
|
+
def test_choices_from_earlier_defaults_prevent_failing_arglist_arity_check
|
393
|
+
with_command_args("") {
|
394
|
+
b = ChoicesBuilder.new
|
395
|
+
b.add_source(CommandLineSource, :usage, 'blah')
|
396
|
+
b.add_choice(:names, :length => 1..2, :default => ['1']) { |command_line|
|
397
|
+
command_line.uses_arglist
|
398
|
+
}
|
399
|
+
assert_equal(['1'], b.build[:names])
|
400
|
+
}
|
401
|
+
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
class TestCommandLineConstruction < Test::Unit::TestCase
|
406
|
+
include UserChoices
|
407
|
+
|
408
|
+
def test_command_line_choices_requires_blocks_for_initialization
|
409
|
+
with_command_args("--switch -c 5 arg") {
|
410
|
+
b = ChoicesBuilder.new
|
411
|
+
b.add_source(CommandLineSource, :usage, "hi")
|
412
|
+
|
413
|
+
b.add_choice(:unused) { | command_line |
|
414
|
+
command_line.uses_switch("-u", "--unused")
|
415
|
+
}
|
416
|
+
|
417
|
+
b.add_choice(:switch, :type=>:boolean) { | command_line |
|
418
|
+
command_line.uses_switch("--switch")
|
419
|
+
}
|
420
|
+
|
421
|
+
b.add_choice(:clear, :type => :integer) { | command_line |
|
422
|
+
command_line.uses_option("-c", "--clear N",
|
423
|
+
"Clear the frobbistat N times.")
|
424
|
+
}
|
425
|
+
|
426
|
+
b.add_choice(:args) { | command_line |
|
427
|
+
command_line.uses_arglist
|
428
|
+
}
|
429
|
+
|
430
|
+
choices = b.build
|
431
|
+
|
432
|
+
assert_equal(true, choices[:switch])
|
433
|
+
assert_false(choices.has_key?(:unused))
|
434
|
+
assert_equal(5, choices[:clear])
|
435
|
+
assert_equal(['arg'], choices[:args])
|
436
|
+
}
|
437
|
+
end
|
438
|
+
|
439
|
+
def test_command_line_source_initializes_help_text
|
440
|
+
with_command_args('--help') {
|
441
|
+
output = capturing_stderr do
|
442
|
+
assert_wants_to_exit do
|
443
|
+
b = ChoicesBuilder.new
|
444
|
+
b.add_source(CommandLineSource, :usage,
|
445
|
+
"Usage: prog [options]",
|
446
|
+
"This is supplemental.")
|
447
|
+
|
448
|
+
b.add_choice(:test) { | command_line |
|
449
|
+
command_line.uses_switch("--test",
|
450
|
+
"Here's text for a switch")
|
451
|
+
command_line.uses_option("-r", "--renew VALUE",
|
452
|
+
"Here's text for an option")
|
453
|
+
}
|
454
|
+
b.build
|
455
|
+
end
|
456
|
+
end
|
457
|
+
assert(l1 = output.index("Usage: prog [options]"))
|
458
|
+
assert(l2 = output.index("This is supplemental"))
|
459
|
+
assert(l3 = output.index(/--\[no-\]test.*Here's text for a switch/))
|
460
|
+
assert(l4 = output.index(/-r.*--renew.*VALUE.*Here's text for an option/))
|
461
|
+
assert(l5 = output.index("--help"))
|
462
|
+
|
463
|
+
assert(l1 < l2)
|
464
|
+
assert(l2 < l3)
|
465
|
+
assert(l3 < l4)
|
466
|
+
assert(l4 < l5)
|
467
|
+
}
|
468
|
+
end
|
469
|
+
|
470
|
+
class TestSpecialCases < Test::Unit::TestCase
|
471
|
+
include UserChoices
|
472
|
+
|
473
|
+
def test_environment_choices_can_be_given_prefix_and_mapping
|
474
|
+
with_environment_vars("prefix_e" => "e", "HOME" => '/Users/marick') {
|
475
|
+
b = ChoicesBuilder.new
|
476
|
+
b.add_source(EnvironmentSource, :with_prefix, "prefix_", :mapping, {:home => "HOME" })
|
477
|
+
b.add_choice(:e)
|
478
|
+
b.add_choice(:home)
|
479
|
+
choices = b.build
|
480
|
+
assert_equal("e", choices[:e])
|
481
|
+
assert_equal("/Users/marick", choices[:home])
|
482
|
+
}
|
483
|
+
|
484
|
+
end
|
485
|
+
|
486
|
+
|
487
|
+
def test_required_arg_with_type_conversion
|
488
|
+
with_command_args("2") {
|
489
|
+
b = ChoicesBuilder.new
|
490
|
+
b.add_source(CommandLineSource, :usage, "blah")
|
491
|
+
b.add_choice(:e, :type => :integer) { |command_line |
|
492
|
+
command_line.uses_arg
|
493
|
+
}
|
494
|
+
choices = b.build
|
495
|
+
assert_equal(2, choices[:e])
|
496
|
+
}
|
497
|
+
end
|
498
|
+
|
499
|
+
def test_required_arg_conversion_prints_right_message
|
500
|
+
with_command_args("b") {
|
501
|
+
b = ChoicesBuilder.new
|
502
|
+
b.add_source(CommandLineSource, :usage, "blah")
|
503
|
+
b.add_choice(:e, :type => :integer) { |command_line |
|
504
|
+
command_line.uses_arg
|
505
|
+
}
|
506
|
+
output = capturing_stderr do
|
507
|
+
assert_wants_to_exit do
|
508
|
+
b.build
|
509
|
+
end
|
510
|
+
end
|
511
|
+
assert_no_match(/^Error in the command line: Error in the command line: /, output)
|
512
|
+
}
|
513
|
+
end
|
514
|
+
|
515
|
+
def test_optional_arg_with_type_conversion
|
516
|
+
with_command_args('2') {
|
517
|
+
b = ChoicesBuilder.new
|
518
|
+
b.add_source(CommandLineSource, :usage, "blah")
|
519
|
+
b.add_choice(:e, :type => :integer) { |command_line |
|
520
|
+
command_line.uses_optional_arg
|
521
|
+
}
|
522
|
+
choices = b.build
|
523
|
+
assert_equal(2, choices[:e])
|
524
|
+
}
|
525
|
+
end
|
526
|
+
|
527
|
+
def test_missing_optional_arg_with_type_conversion_is_OK
|
528
|
+
# The type check applies only if the value is given.
|
529
|
+
with_command_args('') {
|
530
|
+
b = ChoicesBuilder.new
|
531
|
+
b.add_source(CommandLineSource, :usage, "blah")
|
532
|
+
b.add_choice(:e, :type => :integer) { |command_line |
|
533
|
+
command_line.uses_optional_arg
|
534
|
+
}
|
535
|
+
assert_equal(nil, b.build[:e])
|
536
|
+
}
|
537
|
+
end
|
538
|
+
|
539
|
+
end
|
540
|
+
|
541
|
+
|
542
|
+
class TestUtilities < Test::Unit::TestCase
|
543
|
+
include UserChoices
|
544
|
+
|
545
|
+
def setup
|
546
|
+
@builder = ChoicesBuilder.new
|
547
|
+
end
|
548
|
+
|
549
|
+
def test_message_send_splitter
|
550
|
+
assert_equal([[:usage, 'arg']],
|
551
|
+
@builder.message_sends([:usage, 'arg']))
|
552
|
+
assert_equal([[:usage, 'arg1', 2]],
|
553
|
+
@builder.message_sends([:usage, 'arg1', 2]))
|
554
|
+
assert_equal([[:msg, 'arg1', 2], [:next, 1]],
|
555
|
+
@builder.message_sends([:msg, 'arg1', 2, :next, 1]))
|
556
|
+
# a common case
|
557
|
+
assert_equal([[:with_prefix, 'p_'], [:mapping, {:home => 'home'}]],
|
558
|
+
@builder.message_sends([:with_prefix, 'p_', :mapping, {:home => 'home'}]))
|
559
|
+
end
|
560
|
+
|
561
|
+
def test_symbol_indices
|
562
|
+
assert_equal([0, 3], @builder.symbol_indices([:foo, 1, 2, :bar, "quux"]))
|
563
|
+
end
|
564
|
+
end
|
565
|
+
|
566
|
+
|
567
|
+
|
568
|
+
end
|
569
|
+
|