user-choices 1.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.
- 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
|
+
|