option_list 0.2.0 → 1.0.3
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.
- 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:
|