option_list 0.2.0 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/license.txt +21 -0
- data/option_list.rb +117 -129
- data/option_list_test.rb +130 -181
- data/rakefile.rb +15 -0
- metadata +37 -8
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
NDA0MjBiNDdkNWRhMzgzMzBkYWJiMjhiOGUxNTA3YmE5ZjI3Y2Q4OA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MmIzZGRjZDc0YWRlYTgxNWUyY2VjMWI2MTBmNjg3NGIzZjFlMmMzMg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MWE0ZjhiZmU0ZmMxYmUzY2VjMDFiZjM5MDU4MjQwODg2NjUwODExNzk0NWVh
|
10
|
+
NGU2ZmQ1OGU3NzRkOGQ1ZTY2ZDI2ODg2NWU3OGQ1YWU1N2E2ZGZlYTQzZWRm
|
11
|
+
NTUyYTdmM2VjYTVlOTcwYTFhODdjNTc4NzBhYjk5MDQyZWQ1MTU=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NmRiN2NmMjM3OGFkYjcwMThjNjc5MzU1MjM3ODlkODIzNGE4YzZhMTliYzhh
|
14
|
+
YWNkZTNhNjE4MDgwZTc2NzE0Y2QzNzkzOWIwYTJiOWQzMmU0NGEzOTI1MTFl
|
15
|
+
ZTUxZTAwOTAzZTc0YjBmMTYyNTEyOGMxODI4NTFmYjI5ZWE2ZmI=
|
data/license.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
=== The MIT License (MIT).
|
2
|
+
|
3
|
+
Copyright (c) 2013 Peter Camilleri
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/option_list.rb
CHANGED
@@ -1,27 +1,5 @@
|
|
1
1
|
require 'set'
|
2
2
|
|
3
|
-
#=== The MIT License (MIT).
|
4
|
-
#
|
5
|
-
#Copyright (c) 2013 Peter Camilleri
|
6
|
-
#
|
7
|
-
#Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
-
#of this software and associated documentation files (the "Software"), to deal
|
9
|
-
#in the Software without restriction, including without limitation the rights
|
10
|
-
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
-
#copies of the Software, and to permit persons to whom the Software is
|
12
|
-
#furnished to do so, subject to the following conditions:
|
13
|
-
#
|
14
|
-
#The above copyright notice and this permission notice shall be included in
|
15
|
-
#all copies or substantial portions of the Software.
|
16
|
-
#
|
17
|
-
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
-
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
-
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
-
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
-
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
-
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23
|
-
#THE SOFTWARE.
|
24
|
-
#
|
25
3
|
#=== The file option_list.rb and the class \OptionList.
|
26
4
|
#This file contains the code for the \OptionList class that implements smart
|
27
5
|
#and easy options for functions. It has the virtue of defining function
|
@@ -49,34 +27,60 @@ require 'set'
|
|
49
27
|
#that the library (gem) user does not have to work hard or be lost or confused.
|
50
28
|
#Only time will tell to what extent these lofty goals have been achieved.
|
51
29
|
#Hopefully, with good feedback, this and other code libraries will improve.
|
30
|
+
#=== Version 1.0.1
|
31
|
+
#This version represents a major overhaul of the \OptionList class. In
|
32
|
+
#particular, the selected option data and the dynamic methods used to access
|
33
|
+
#that data are no longer contained in the option list object but instead in
|
34
|
+
#a singleton subclass of Hash that is returned by the select method. There
|
35
|
+
#are several advantages to this, but the main one is that since \OptionList
|
36
|
+
#objects now only contain specification and default values, they are much more
|
37
|
+
#thread safe than before. While there is nothing multi-threaded about the
|
38
|
+
#\OptionList class itself, it is reasonable to assume that a function option
|
39
|
+
#handler could very easily end up embedded in such an environment. In fact, my
|
40
|
+
#first major test of the class ran into this exact issue.
|
52
41
|
class OptionList
|
53
|
-
#An internal marker for value entries.
|
54
|
-
VALUE_ENTRY = 'A value entry.'
|
55
42
|
|
56
|
-
#
|
57
|
-
|
43
|
+
#The option list code version.
|
44
|
+
def self.version
|
45
|
+
'1.0.1'
|
46
|
+
end
|
47
|
+
|
48
|
+
#The option list code version. This is a redirect to the class method.
|
49
|
+
def version
|
50
|
+
self.class.version
|
51
|
+
end
|
52
|
+
|
53
|
+
#Create an option list from an array of option specifications. These
|
54
|
+
#specifications consist of a number of array specifications and hash
|
55
|
+
#specifications. These are described below:
|
58
56
|
#==== Array Specification
|
59
|
-
#
|
60
|
-
#
|
61
|
-
#
|
62
|
-
#
|
63
|
-
#category
|
57
|
+
#Array specifications are used in cases where an option category may be one
|
58
|
+
#of a fixed number of distinct symbol values or optionally nil to represent
|
59
|
+
#no selection.
|
60
|
+
#In this form of specification, the first element of the array is the
|
61
|
+
#category of the option, and the second and following entries are the
|
62
|
+
#allowed values for that category. The second element has a special role. It
|
63
|
+
#is the default value for the category. Only this value may be nil to have
|
64
|
+
#no default value. The symbols used in each category must be unique.
|
64
65
|
#==== Hash Specification
|
65
|
-
#
|
66
|
-
#
|
66
|
+
#Hash specifications are used to specify options that do not have a fixed set
|
67
|
+
#of possible values. In this form of specification, the hash key symbol is
|
68
|
+
#the category and the hash value is the default value for the category. It
|
69
|
+
#may be nil or any other type or value. Allowed values are not listed.
|
67
70
|
#==== Example:
|
68
71
|
# @opt_list = OptionList.new([:history, :history, :nohistory], {:page_len => 42})
|
69
72
|
#==== Parameters:
|
70
|
-
#* option_specs - The comma separated option
|
71
|
-
# splat operator.
|
73
|
+
#* option_specs - The comma separated option specifications, made into an
|
74
|
+
# array by the splat operator.
|
72
75
|
#* select_block - An optional block of code that is called when selections
|
73
76
|
# have been made. This allows for custom validations to be applied at that
|
74
77
|
# point. This block should accept one argument, a reference to the option
|
75
|
-
# list object that is calling it for validation.
|
78
|
+
# list value object that is calling it for validation.
|
76
79
|
#==== Dynamic Methods:
|
77
|
-
#As option
|
78
|
-
#to the option information. If the above
|
79
|
-
#methods would be added
|
80
|
+
#As option specifications are added, new methods are created in the value
|
81
|
+
#object to allow for easy access to the option information. If the above
|
82
|
+
#example were processed, the following methods would be added to the value
|
83
|
+
#returned by the select method:
|
80
84
|
#* history - would return the value of the :history category.
|
81
85
|
#* history? - would return true if the :history option where active.
|
82
86
|
#* nohistory? - would return true if the :nohistory option were active.
|
@@ -84,23 +88,10 @@ class OptionList
|
|
84
88
|
#==== Exceptions:
|
85
89
|
#* ArgumentError for a number of invalid argument conditions.
|
86
90
|
def initialize(*option_specs, &select_block)
|
91
|
+
fAE "Missing option specifications." if option_specs.empty?
|
87
92
|
@categories = Hash.new
|
88
93
|
@default = Hash.new
|
89
|
-
|
90
|
-
do_add_specs(option_specs)
|
91
|
-
@select_block = select_block
|
92
|
-
end
|
93
|
-
|
94
|
-
#Add additonal option specifications to the option list. See the method new
|
95
|
-
#for more information on those specifications.
|
96
|
-
def add_specs(*option_specs)
|
97
|
-
do_add_specs(option_specs)
|
98
|
-
end
|
99
|
-
|
100
|
-
private #Private methods follow.
|
101
|
-
|
102
|
-
#Iterate over the array of specs, adding them to the option list.
|
103
|
-
def do_add_specs(option_specs)
|
94
|
+
|
104
95
|
option_specs.each do |spec|
|
105
96
|
if spec.is_a?(Hash)
|
106
97
|
hash_spec(spec)
|
@@ -110,53 +101,12 @@ class OptionList
|
|
110
101
|
fAE "Found #{spec.class} instead of Hash or Array."
|
111
102
|
end
|
112
103
|
end
|
104
|
+
|
105
|
+
@select_block = select_block
|
113
106
|
end
|
114
|
-
|
115
|
-
#Process an array spec that lists all the valid values for an option. See
|
116
|
-
#the new method for more information on these specs.
|
117
|
-
def array_spec(spec)
|
118
|
-
cat = spec.delete_at(0)
|
119
|
-
fAE "Found #{cat.class}, expected Symbol." unless cat.is_a?(Symbol)
|
120
|
-
fAE "Duplicate category: #{cat}" if @default.has_key?(cat)
|
121
|
-
fAE "Invalid number of entries for #{cat}." unless spec.length > 1
|
122
|
-
define_singleton_method(cat) { @selected[cat] }
|
123
|
-
|
124
|
-
spec.each_with_index do |opt, index|
|
125
|
-
if opt != nil
|
126
|
-
fAE "Found #{opt.class}, expected Symbol." unless opt.is_a?(Symbol)
|
127
|
-
fAE "Duplicate option: #{opt}" if @categories.has_key?(opt)
|
128
|
-
|
129
|
-
@categories[opt] = cat
|
130
|
-
qry = (opt.to_s + '?').to_sym
|
131
|
-
define_singleton_method(qry) { @selected[cat] == opt }
|
132
|
-
@selected[cat] = @default[cat] = opt if index == 0
|
133
|
-
elsif index == 0
|
134
|
-
@selected[cat] = @default[cat] = nil
|
135
|
-
else
|
136
|
-
fAE "The value nil is only allowed as the default option."
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
#Process a hash spec that lists only the default value for an option. See
|
142
|
-
#the new method for more information on these specs.
|
143
|
-
def hash_spec(spec)
|
144
|
-
fAE "Hash contains no specs." unless spec.length > 0
|
145
107
|
|
146
|
-
|
147
|
-
|
148
|
-
fAE "Duplicate category: #{cat}" if @default.has_key?(cat)
|
149
|
-
|
150
|
-
define_singleton_method(cat) { @selected[cat] }
|
151
|
-
@categories[cat] = VALUE_ENTRY
|
152
|
-
@selected[cat] = @default[cat] = value
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
public #Back to public methods.
|
157
|
-
|
158
|
-
#From the possible options, select the actual, in force, options for use in
|
159
|
-
#the code. These options may take several forms:
|
108
|
+
#From the possible options, select the actual, in force, options and return
|
109
|
+
#an access object for use in the code. These options may take several forms:
|
160
110
|
#=== Types of option data:
|
161
111
|
#* A symbol - For categories with a specified symbol list, simply list one
|
162
112
|
# of the allowed symbols.
|
@@ -166,12 +116,12 @@ class OptionList
|
|
166
116
|
#* Mixed - Symbols and hashes can be mixed in an array (see below on how this
|
167
117
|
# is done) Note: Option order does not matter.
|
168
118
|
#Some examples:
|
169
|
-
# foo(:sedan, :turbo)
|
170
|
-
# foo({:style=>:sedan})
|
171
|
-
# foo({:page_len=>60})
|
172
|
-
# foo(:sedan, :turbo, {:page_len=>60})
|
173
|
-
# foo({:style=>:sedan, :page_len=>60})
|
174
|
-
# foo({:style=>:sedan}, {:page_len=>60})
|
119
|
+
# o = foo(:sedan, :turbo)
|
120
|
+
# o = foo({:style=>:sedan})
|
121
|
+
# o = foo({:page_len=>60})
|
122
|
+
# o = foo(:sedan, :turbo, {:page_len=>60})
|
123
|
+
# o = foo({:style=>:sedan, :page_len=>60})
|
124
|
+
# o = foo({:style=>:sedan}, {:page_len=>60})
|
175
125
|
#=== Passing in option data:
|
176
126
|
#The caller of this method may pass these options in a number of ways:
|
177
127
|
#==== Array (via a splat)
|
@@ -201,75 +151,113 @@ class OptionList
|
|
201
151
|
#* selections - An array of the options passed into the client function, usually
|
202
152
|
# with the splat operator. Note that if select is called with no arguments,
|
203
153
|
# all of the default values will be selected.
|
154
|
+
#==== Returns:
|
155
|
+
#An option value object wich is a singleton subclass of the Hash class.
|
204
156
|
#==== Exceptions:
|
205
157
|
#* ArgumentError for a number of invalid argument conditions.
|
206
158
|
#==== Notes:
|
207
|
-
#After processing the selections, the selection block is called
|
208
|
-
#defined
|
159
|
+
#After processing the selections, the selection validation block is called
|
160
|
+
#if one was defined for the constructor.
|
209
161
|
def select(selections=[])
|
210
|
-
|
211
|
-
add_selections(selections)
|
212
|
-
@select_block.call(self) unless @select_block.nil?
|
213
|
-
end
|
214
|
-
|
215
|
-
#Add/override additional selections to the option_list. See the select method
|
216
|
-
#for more information about those selection values.
|
217
|
-
def add_selections(selections=[])
|
162
|
+
selected = @default.clone
|
218
163
|
selections = [selections] unless selections.is_a?(Array)
|
219
164
|
dup = Set.new
|
220
165
|
|
221
166
|
selections.each do |opt|
|
222
167
|
if opt.is_a?(Symbol)
|
223
|
-
symbolic_selection(opt, dup)
|
168
|
+
symbolic_selection(opt, selected, dup)
|
224
169
|
elsif opt.is_a?(Hash)
|
225
|
-
hash_selections(opt, dup)
|
170
|
+
hash_selections(opt, selected, dup)
|
226
171
|
else
|
227
172
|
fAE "Found #{opt.class} instead of Hash or Symbol."
|
228
173
|
end
|
229
174
|
end
|
175
|
+
|
176
|
+
@select_block.call(selected) unless @select_block.nil?
|
177
|
+
selected
|
230
178
|
end
|
231
179
|
|
232
|
-
#
|
233
|
-
|
234
|
-
|
235
|
-
|
180
|
+
private #Private stuff follows.
|
181
|
+
|
182
|
+
#Return a internal category marker constant for value entries.
|
183
|
+
def value_entry
|
184
|
+
'A value entry.'
|
236
185
|
end
|
237
186
|
|
238
|
-
|
187
|
+
#Process an array spec that lists all the valid values for an option. See
|
188
|
+
#the new method for more information on these specs.
|
189
|
+
def array_spec(spec)
|
190
|
+
cat = spec.delete_at(0)
|
191
|
+
fAE "Found #{cat.class}, expected Symbol." unless cat.is_a?(Symbol)
|
192
|
+
fAE "Duplicate category: #{cat}" if @default.has_key?(cat)
|
193
|
+
fAE "Invalid number of entries for #{cat}." unless spec.length > 1
|
194
|
+
@default.define_singleton_method(cat) { self[cat] }
|
195
|
+
|
196
|
+
spec.each_with_index do |opt, index|
|
197
|
+
if opt != nil
|
198
|
+
fAE "Found #{opt.class}, expected Symbol." unless opt.is_a?(Symbol)
|
199
|
+
fAE "Duplicate option: #{opt}" if @categories.has_key?(opt)
|
200
|
+
|
201
|
+
@categories[opt] = cat
|
202
|
+
qry = (opt.to_s + '?').to_sym
|
203
|
+
@default.define_singleton_method(qry) { self[cat] == opt }
|
204
|
+
@default[cat] = opt if index == 0
|
205
|
+
elsif index == 0
|
206
|
+
@default[cat] = nil
|
207
|
+
else
|
208
|
+
fAE "The value nil is only allowed as the default option."
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
#Process a hash spec that lists only the default value for an option. See
|
214
|
+
#the new method for more information on these specs.
|
215
|
+
def hash_spec(spec)
|
216
|
+
fAE "Hash contains no specs." unless spec.length > 0
|
217
|
+
|
218
|
+
spec.each do |cat, value|
|
219
|
+
fAE "Found #{cat.class}, expected Symbol." unless cat.is_a?(Symbol)
|
220
|
+
fAE "Duplicate category: #{cat}" if @default.has_key?(cat)
|
221
|
+
|
222
|
+
@default.define_singleton_method(cat) { self[cat] }
|
223
|
+
@categories[cat] = value_entry
|
224
|
+
@default[cat] = value
|
225
|
+
end
|
226
|
+
end
|
239
227
|
|
240
228
|
#Process a symbolic option selection.
|
241
229
|
#==== Parameters:
|
242
230
|
#* option - a symbol to process.
|
231
|
+
#* selected - a hash of selected data.
|
243
232
|
#* dup - a set of categories that have been set. Used to detect duplicates.
|
244
|
-
def symbolic_selection(option, dup)
|
233
|
+
def symbolic_selection(option, selected, dup)
|
245
234
|
fAE "Unknown option: #{option}." unless @categories.has_key?(option)
|
246
235
|
cat = @categories[option]
|
247
236
|
fAE "Category #{cat} has multiple values." if dup.include?(cat)
|
248
237
|
dup.add(cat)
|
249
|
-
|
238
|
+
selected[cat] = option
|
250
239
|
end
|
251
240
|
|
252
241
|
#Process a hash of option selection values.
|
253
242
|
#==== Parameters:
|
254
243
|
#* options - a hash of options to process.
|
244
|
+
#* selected - a hash of selected data.
|
255
245
|
#* dup - a set of categories that have been set. Used to detect duplicates.
|
256
|
-
def hash_selections(options, dup)
|
246
|
+
def hash_selections(options, selected, dup)
|
257
247
|
options.each do |cat, value|
|
258
248
|
fAE "Not a category: #{cat}." unless @default.has_key?(cat)
|
259
249
|
fAE "Category #{cat} has multiple values." if dup.include?(cat)
|
260
250
|
|
261
|
-
unless (@categories[cat] ==
|
251
|
+
unless (@categories[cat] == value_entry) || value.nil?
|
262
252
|
fAE "Found #{opt.class}, expected Symbol." unless value.is_a?(Symbol)
|
263
253
|
fAE "Invalid option: #{value}." unless @categories[value] == cat
|
264
254
|
end
|
265
255
|
|
266
256
|
dup.add(cat)
|
267
|
-
|
257
|
+
selected[cat] = value
|
268
258
|
end
|
269
259
|
end
|
270
260
|
|
271
|
-
public
|
272
|
-
|
273
261
|
#Fail with an argument error.
|
274
262
|
def fAE(msg)
|
275
263
|
fail(ArgumentError, msg, caller)
|
data/option_list_test.rb
CHANGED
@@ -4,30 +4,32 @@
|
|
4
4
|
require_relative 'option_list'
|
5
5
|
require 'minitest/autorun'
|
6
6
|
|
7
|
+
class OptionTest
|
8
|
+
def initialize(opt)
|
9
|
+
@opt = opt
|
10
|
+
end
|
11
|
+
|
12
|
+
def test(*args)
|
13
|
+
o = @opt.select(args)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
7
17
|
class OptionListTester < MiniTest::Unit::TestCase
|
8
|
-
$do_this_only_one_time =
|
18
|
+
$do_this_only_one_time = ""
|
9
19
|
|
10
20
|
def initialize(*all)
|
11
|
-
if $do_this_only_one_time
|
12
|
-
puts
|
13
|
-
|
21
|
+
if $do_this_only_one_time != __FILE__
|
22
|
+
puts
|
23
|
+
puts "Running test file: #{File.split(__FILE__)[1]}"
|
24
|
+
$do_this_only_one_time = __FILE__
|
14
25
|
end
|
15
26
|
|
16
27
|
super(*all)
|
17
28
|
end
|
18
29
|
|
19
|
-
def setup
|
20
|
-
@ol1 = OptionList.new([:history, :history, :nohistory], {:pg_len => 42})
|
21
|
-
@ol2 = OptionList.new([:history, nil, :history, :nohistory])
|
22
|
-
@ol3 = OptionList.new([:history, nil, :history, :nohistory],
|
23
|
-
{:fuel1=>:matter, :fuel2=>:antimatter}) do |opt|
|
24
|
-
opt.fAE "The :history option must be set." if opt.history.nil?
|
25
|
-
opt.fAE "Improper fuel mix." unless opt.fuel1 == :matter && opt.fuel2 == :antimatter
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
30
|
def test_that_it_rejects_bad_specs
|
30
31
|
#Reject empty argument lists.
|
32
|
+
assert_raises(ArgumentError) { @x = OptionList.new }
|
31
33
|
assert_raises(ArgumentError) { @x = OptionList.new([])}
|
32
34
|
assert_raises(ArgumentError) { @x = OptionList.new({})}
|
33
35
|
|
@@ -62,204 +64,151 @@ class OptionListTester < MiniTest::Unit::TestCase
|
|
62
64
|
end
|
63
65
|
|
64
66
|
def test_that_the_methods_were_added
|
65
|
-
|
66
|
-
|
67
|
-
assert_respond_to(@ol1, :nohistory? )
|
68
|
-
assert_respond_to(@ol1, :pg_len)
|
69
|
-
|
70
|
-
assert_respond_to(@ol2, :history)
|
71
|
-
assert_respond_to(@ol2, :history? )
|
72
|
-
assert_respond_to(@ol2, :nohistory? )
|
73
|
-
assert_raises(NoMethodError) { @ol2.send((nil.to_s+'?').to_sym) }
|
74
|
-
end
|
67
|
+
ol1 = OptionList.new([:history, :history, :nohistory], {:pg_len => 42})
|
68
|
+
o = ol1.select
|
75
69
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
assert(@ol1.history?)
|
81
|
-
refute(@ol1.nohistory?)
|
82
|
-
assert_equal(@ol1.history, :history)
|
83
|
-
assert_equal(@ol1.pg_len, 42)
|
70
|
+
assert_respond_to(o, :history)
|
71
|
+
assert_respond_to(o, :history? )
|
72
|
+
assert_respond_to(o, :nohistory? )
|
73
|
+
assert_respond_to(o, :pg_len)
|
84
74
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
75
|
+
ol2 = OptionList.new([:history, nil, :history, :nohistory])
|
76
|
+
o = ol2.select
|
77
|
+
|
78
|
+
assert_respond_to(o, :history)
|
79
|
+
assert_respond_to(o, :history? )
|
80
|
+
assert_respond_to(o, :nohistory? )
|
81
|
+
assert_raises(NoMethodError) { o.send((nil.to_s+'?').to_sym) }
|
92
82
|
end
|
93
83
|
|
94
84
|
def test_that_it_rejects_bad_selections
|
85
|
+
ol1 = OptionList.new([:history, :history, :nohistory], {:pg_len => 42})
|
86
|
+
|
95
87
|
#Reject if options are not an array or a hash.
|
96
|
-
assert_raises(ArgumentError) {
|
88
|
+
assert_raises(ArgumentError) { ol1.select(45) }
|
97
89
|
|
98
90
|
#Reject if the option is not a symbol.
|
99
|
-
assert_raises(ArgumentError) {
|
91
|
+
assert_raises(ArgumentError) { ol1.select([34]) }
|
100
92
|
|
101
93
|
#Reject if the category is not a symbol.
|
102
|
-
assert_raises(ArgumentError) {
|
94
|
+
assert_raises(ArgumentError) { ol1.select({'page_len'=>77}) }
|
103
95
|
|
104
96
|
#Reject if the symbol is not one defined.
|
105
|
-
assert_raises(ArgumentError) {
|
106
|
-
assert_raises(ArgumentError) {
|
97
|
+
assert_raises(ArgumentError) { ol1.select([:foobar]) }
|
98
|
+
assert_raises(ArgumentError) { ol1.select({:history=>:foobar}) }
|
107
99
|
|
108
100
|
#Reject on duplicate symbol from the same category.
|
109
|
-
assert_raises(ArgumentError) {
|
110
|
-
assert_raises(ArgumentError) {
|
111
|
-
assert_raises(ArgumentError) {
|
112
|
-
assert_raises(ArgumentError) {
|
101
|
+
assert_raises(ArgumentError) { ol1.select([:history, :history]) }
|
102
|
+
assert_raises(ArgumentError) { ol1.select([:history, :nohistory]) }
|
103
|
+
assert_raises(ArgumentError) { ol1.select([:history, {:history=>:nohistory}]) }
|
104
|
+
assert_raises(ArgumentError) { ol1.select([{:history=>:history}, {:history=>:nohistory}]) }
|
113
105
|
|
114
106
|
#Reject on an undefined category.
|
115
|
-
assert_raises(ArgumentError) {
|
107
|
+
assert_raises(ArgumentError) { ol1.select({:zoo => 999})}
|
116
108
|
end
|
117
109
|
|
118
110
|
def test_that_it_handles_good_options
|
119
111
|
#ol1 test series.
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
refute(@ol1.history?)
|
146
|
-
assert_equal(@ol1.history, :nohistory)
|
147
|
-
assert_equal(@ol1.pg_len, 42)
|
112
|
+
ol1 = OptionList.new([:history, :history, :nohistory], {:pg_len => 42})
|
113
|
+
|
114
|
+
o = ol1.select
|
115
|
+
assert(o.history?)
|
116
|
+
refute(o.nohistory?)
|
117
|
+
assert_equal(o.history, :history)
|
118
|
+
assert_equal(o.pg_len, 42)
|
119
|
+
|
120
|
+
o = ol1.select([])
|
121
|
+
assert(o.history?)
|
122
|
+
refute(o.nohistory?)
|
123
|
+
assert_equal(o.history, :history)
|
124
|
+
assert_equal(o.pg_len, 42)
|
125
|
+
|
126
|
+
o = ol1.select([:history])
|
127
|
+
assert(o.history?)
|
128
|
+
refute(o.nohistory?)
|
129
|
+
assert_equal(o.history, :history)
|
130
|
+
assert_equal(o.pg_len, 42)
|
131
|
+
|
132
|
+
o = ol1.select([:nohistory])
|
133
|
+
refute(o.history?)
|
134
|
+
assert(o.nohistory?)
|
135
|
+
assert_equal(o.history, :nohistory)
|
136
|
+
assert_equal(o.pg_len, 42)
|
148
137
|
|
149
|
-
|
150
|
-
assert(
|
151
|
-
refute(
|
152
|
-
assert_equal(
|
153
|
-
assert_equal(
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
assert_equal(
|
159
|
-
assert_equal(
|
138
|
+
o = ol1.select({:history=>:history})
|
139
|
+
assert(o.history?)
|
140
|
+
refute(o.nohistory?)
|
141
|
+
assert_equal(o.history, :history)
|
142
|
+
assert_equal(o.pg_len, 42)
|
143
|
+
|
144
|
+
o = ol1.select({:history=>:nohistory})
|
145
|
+
refute(o.history?)
|
146
|
+
assert(o.nohistory?)
|
147
|
+
assert_equal(o.history, :nohistory)
|
148
|
+
assert_equal(o.pg_len, 42)
|
160
149
|
|
161
|
-
|
162
|
-
assert(
|
163
|
-
refute(
|
164
|
-
assert_equal(
|
165
|
-
assert_equal(
|
166
|
-
|
167
|
-
|
168
|
-
assert(
|
169
|
-
refute(
|
170
|
-
assert_equal(
|
171
|
-
assert_equal(
|
150
|
+
o = ol1.select({:pg_len=>55})
|
151
|
+
assert(o.history?)
|
152
|
+
refute(o.nohistory?)
|
153
|
+
assert_equal(o.history, :history)
|
154
|
+
assert_equal(o.pg_len, 55)
|
155
|
+
|
156
|
+
o = ol1.select({:history=>:history, :pg_len=>55})
|
157
|
+
assert(o.history?)
|
158
|
+
refute(o.nohistory?)
|
159
|
+
assert_equal(o.history, :history)
|
160
|
+
assert_equal(o.pg_len, 55)
|
172
161
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
assert_equal(
|
177
|
-
assert_equal(
|
162
|
+
o = ol1.select({:history=>:nohistory, :pg_len=>55})
|
163
|
+
refute(o.history?)
|
164
|
+
assert(o.nohistory?)
|
165
|
+
assert_equal(o.history, :nohistory)
|
166
|
+
assert_equal(o.pg_len, 55)
|
178
167
|
|
179
|
-
|
180
|
-
assert(
|
181
|
-
refute(
|
182
|
-
assert_equal(
|
183
|
-
assert_equal(
|
168
|
+
o = ol1.select([:history, {:pg_len=>55}])
|
169
|
+
assert(o.history?)
|
170
|
+
refute(o.nohistory?)
|
171
|
+
assert_equal(o.history, :history)
|
172
|
+
assert_equal(o.pg_len, 55)
|
173
|
+
|
174
|
+
o = ol1.select([:nohistory, {:pg_len=>55}])
|
175
|
+
refute(o.history?)
|
176
|
+
assert(o.nohistory?)
|
177
|
+
assert_equal(o.history, :nohistory)
|
178
|
+
assert_equal(o.pg_len, 55)
|
184
179
|
|
185
|
-
@ol1.select([:nohistory, {:pg_len=>55}])
|
186
|
-
assert(@ol1.nohistory?)
|
187
|
-
refute(@ol1.history?)
|
188
|
-
assert_equal(@ol1.history, :nohistory)
|
189
|
-
assert_equal(@ol1.pg_len, 55)
|
190
180
|
|
191
|
-
|
192
|
-
|
193
|
-
assert(@ol1.history?)
|
194
|
-
refute(@ol1.nohistory?)
|
195
|
-
assert_equal(@ol1.history, :history)
|
196
|
-
assert_equal(@ol1.pg_len, 42)
|
197
|
-
refute(@ol1.hot?)
|
198
|
-
refute(@ol1.nice?)
|
199
|
-
refute(@ol1.cold?)
|
200
|
-
assert_equal(@ol1.temp, nil)
|
201
|
-
@ol1.select(:hot)
|
202
|
-
assert(@ol1.history?)
|
203
|
-
refute(@ol1.nohistory?)
|
204
|
-
assert_equal(@ol1.history, :history)
|
205
|
-
assert_equal(@ol1.pg_len, 42)
|
206
|
-
assert(@ol1.hot?)
|
207
|
-
refute(@ol1.nice?)
|
208
|
-
refute(@ol1.cold?)
|
209
|
-
assert_equal(@ol1.temp, :hot)
|
181
|
+
#ol2 test series.
|
182
|
+
ol2 = OptionList.new([:history, nil, :history, :nohistory])
|
210
183
|
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
assert_equal(@ol1.history, :history)
|
216
|
-
assert_equal(@ol1.pg_len, 42)
|
217
|
-
refute(@ol1.hot?)
|
218
|
-
refute(@ol1.nice?)
|
219
|
-
refute(@ol1.cold?)
|
220
|
-
assert_equal(@ol1.temp, nil)
|
221
|
-
@ol1.add_selections({:temp=>:hot})
|
222
|
-
assert(@ol1.history?)
|
223
|
-
refute(@ol1.nohistory?)
|
224
|
-
assert_equal(@ol1.history, :history)
|
225
|
-
assert_equal(@ol1.pg_len, 42)
|
226
|
-
assert(@ol1.hot?)
|
227
|
-
refute(@ol1.nice?)
|
228
|
-
refute(@ol1.cold?)
|
229
|
-
assert_equal(@ol1.temp, :hot)
|
230
|
-
@ol1.add_selections([:cold, :nohistory])
|
231
|
-
assert(@ol1.nohistory?)
|
232
|
-
refute(@ol1.history?)
|
233
|
-
assert_equal(@ol1.history, :nohistory)
|
234
|
-
refute(@ol1.hot?)
|
235
|
-
refute(@ol1.nice?)
|
236
|
-
assert(@ol1.cold?)
|
237
|
-
assert_equal(@ol1.temp, :cold)
|
184
|
+
o = ol2.select([:history])
|
185
|
+
assert(o.history?)
|
186
|
+
refute(o.nohistory?)
|
187
|
+
assert_equal(o.history, :history)
|
238
188
|
|
189
|
+
o = ol2.select([:nohistory])
|
190
|
+
assert(o.nohistory?)
|
191
|
+
refute(o.history?)
|
192
|
+
assert_equal(o.history, :nohistory)
|
239
193
|
|
240
|
-
|
241
|
-
refute(
|
242
|
-
refute(
|
243
|
-
assert(
|
244
|
-
|
245
|
-
@ol2.select([:history])
|
246
|
-
assert(@ol2.history?)
|
247
|
-
refute(@ol2.nohistory?)
|
248
|
-
assert_equal(@ol2.history, :history)
|
249
|
-
|
250
|
-
@ol2.select([:nohistory])
|
251
|
-
assert(@ol2.nohistory?)
|
252
|
-
refute(@ol2.history?)
|
253
|
-
assert_equal(@ol2.history, :nohistory)
|
254
|
-
|
255
|
-
@ol2.select([])
|
256
|
-
refute(@ol2.history?)
|
257
|
-
refute(@ol2.nohistory?)
|
258
|
-
assert(@ol2.history.nil?)
|
194
|
+
o = ol2.select([])
|
195
|
+
refute(o.history?)
|
196
|
+
refute(o.nohistory?)
|
197
|
+
assert(o.history.nil?)
|
259
198
|
end
|
260
199
|
|
261
200
|
def test_that_the_select_block_works
|
262
|
-
|
263
|
-
|
201
|
+
ol3 = OptionList.new([:history, nil, :history, :nohistory],
|
202
|
+
fuel1: :matter, fuel2: :antimatter) do |opt|
|
203
|
+
fail "The :history option must be set." if opt.history.nil?
|
204
|
+
fail "Improper fuel mix." unless opt.fuel1 == :matter && opt.fuel2 == :antimatter
|
205
|
+
end
|
206
|
+
|
207
|
+
t = OptionTest.new(ol3)
|
208
|
+
|
209
|
+
assert_raises(RuntimeError) { t.test() }
|
210
|
+
assert_raises(RuntimeError) { t.test(:nohistory, fuel2: :income_tax) }
|
211
|
+
#Really though, this should work! Both anti-matter and income tax
|
212
|
+
#destroy anything that that they come into contact with.
|
264
213
|
end
|
265
214
|
end
|
data/rakefile.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rdoc/task'
|
4
|
+
|
5
|
+
RDoc::Task.new do |rdoc|
|
6
|
+
rdoc.rdoc_dir = "rdoc"
|
7
|
+
#rdoc.main = "option_list.rb"
|
8
|
+
rdoc.rdoc_files = ['option_list.rb', 'option_list_test.rb', 'license.txt']
|
9
|
+
rdoc.options << '--visibility' << 'private'
|
10
|
+
end
|
11
|
+
|
12
|
+
Rake::TestTask.new do |t|
|
13
|
+
t.test_files = ['option_list_test.rb']
|
14
|
+
t.verbose = false
|
15
|
+
end
|
metadata
CHANGED
@@ -1,24 +1,54 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: option_list
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Camilleri
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
12
|
-
dependencies:
|
13
|
-
|
14
|
-
|
11
|
+
date: 2013-10-02 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ! '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ! '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: minitest
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: ! 'A unified handler for flexible function option parameters. '
|
15
42
|
email: peter.c.camilleri@gmail.com
|
16
43
|
executables: []
|
17
44
|
extensions: []
|
18
|
-
extra_rdoc_files:
|
45
|
+
extra_rdoc_files:
|
46
|
+
- license.txt
|
19
47
|
files:
|
20
48
|
- option_list.rb
|
21
49
|
- option_list_test.rb
|
50
|
+
- rakefile.rb
|
51
|
+
- license.txt
|
22
52
|
homepage: http://teuthida-technologies.com/?p=1506
|
23
53
|
licenses:
|
24
54
|
- MIT
|
@@ -37,8 +67,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
37
67
|
- - ! '>='
|
38
68
|
- !ruby/object:Gem::Version
|
39
69
|
version: '0'
|
40
|
-
requirements:
|
41
|
-
- No special requirements.
|
70
|
+
requirements: []
|
42
71
|
rubyforge_project:
|
43
72
|
rubygems_version: 2.1.4
|
44
73
|
signing_key:
|