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.
Files changed (6) hide show
  1. checksums.yaml +8 -8
  2. data/license.txt +21 -0
  3. data/option_list.rb +117 -129
  4. data/option_list_test.rb +130 -181
  5. data/rakefile.rb +15 -0
  6. metadata +37 -8
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MGE1NTkyMWExYjVhYmY1MzJjZmQyOWM2ODVlNmMwNWNmNjVhM2QxYg==
4
+ NDA0MjBiNDdkNWRhMzgzMzBkYWJiMjhiOGUxNTA3YmE5ZjI3Y2Q4OA==
5
5
  data.tar.gz: !binary |-
6
- NjAyN2M4NWQ2OGRiZGRjNWY5MTU5MGE4NjMwYjUzNzYwZjNhMDI3MQ==
6
+ MmIzZGRjZDc0YWRlYTgxNWUyY2VjMWI2MTBmNjg3NGIzZjFlMmMzMg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MzljNzk3MzI0NjM5ZTM5NmZiZDY4YjlmMWUzNThiODc5ZjJmZmE5NjliMTk0
10
- NGQ3ZThjNThiNTE0ZTExNGVkYmRlMGZkNzYyNDcxZjcwOWZiMTAxMjIzYmI5
11
- YmI1OWZjNjM4MjFjNDJkMTVjM2EwNzc3NDExNDc3OWZjMTJiMTk=
9
+ MWE0ZjhiZmU0ZmMxYmUzY2VjMDFiZjM5MDU4MjQwODg2NjUwODExNzk0NWVh
10
+ NGU2ZmQ1OGU3NzRkOGQ1ZTY2ZDI2ODg2NWU3OGQ1YWU1N2E2ZGZlYTQzZWRm
11
+ NTUyYTdmM2VjYTVlOTcwYTFhODdjNTc4NzBhYjk5MDQyZWQ1MTU=
12
12
  data.tar.gz: !binary |-
13
- M2E4MmM2NjdjNjQ4MDA0ZmRjNDcyZGE1YTVmZjU0NmY4NTA4MDcxZDJkOGYy
14
- YWI5ODBiNTMzNTU4ZjIxZTQzMjI1YjNmNTkwNjc0ZDAwNWQ5ODJhOGFlNzFi
15
- YjRmMTkyYThhYTdmNDYwNThhM2ZiNDhjYWNiNTA3ODg3MzI4MjM=
13
+ NmRiN2NmMjM3OGFkYjcwMThjNjc5MzU1MjM3ODlkODIzNGE4YzZhMTliYzhh
14
+ YWNkZTNhNjE4MDgwZTc2NzE0Y2QzNzkzOWIwYTJiOWQzMmU0NGEzOTI1MTFl
15
+ ZTUxZTAwOTAzZTc0YjBmMTYyNTEyOGMxODI4NTFmYjI5ZWE2ZmI=
@@ -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.
@@ -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
- #Create an option list from an array of option specs. These specs consist of
57
- #a number of array specifications and hash specifications.
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
- #In the array form of specification, the first element of the array is the
60
- #category of the option, and the subsequent entries are the allowed values
61
- #for that category. The first of these values is the default value for the
62
- #category. This may be nil to have no default value. The symbols used in each
63
- #category must be unique. Duplicates will fail with an ArgumentError.
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
- #In the hash form of specification, the key is the category and the value
66
- #is the default value. There is no list of allowed values in this case.
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 specs, made into an array by the
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 specs are added, new methods are created to allow for easy access
78
- #to the option information. If the above example were processed, the following
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
- @selected = Hash.new
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
- spec.each do |cat, value|
147
- fAE "Found #{cat.class}, expected Symbol." unless cat.is_a?(Symbol)
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 if one was
208
- #defined in by the constructor.
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
- @selected = @default.clone
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
- #Call the selection block if one was defined in by the constructor. This
233
- #method must be used if selections are added with add_selections.
234
- def validate
235
- @select_block.call(self) unless @select_block.nil?
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
- private #Some more privacy, please!
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
- @selected[cat] = option
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] == VALUE_ENTRY) || value.nil?
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
- @selected[cat] = value
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)
@@ -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 = true
18
+ $do_this_only_one_time = ""
9
19
 
10
20
  def initialize(*all)
11
- if $do_this_only_one_time
12
- puts "Testing file: option_list.rb"
13
- $do_this_only_one_time = false
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
- assert_respond_to(@ol1, :history)
66
- assert_respond_to(@ol1, :history? )
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
- def test_that_it_rejects_bad_added_specs
77
- #reject a bad addition...
78
- assert_raises(ArgumentError) {@ol1.add_specs({:history=>'fun'})}
79
- #but don't mess up.
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
- #reject a bad addition...
86
- assert_raises(ArgumentError) {@ol1.add_specs({:pg_len=>66})}
87
- #but don't mess up.
88
- assert(@ol1.history?)
89
- refute(@ol1.nohistory?)
90
- assert_equal(@ol1.history, :history)
91
- assert_equal(@ol1.pg_len, 42)
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) { @ol1.select(45) }
88
+ assert_raises(ArgumentError) { ol1.select(45) }
97
89
 
98
90
  #Reject if the option is not a symbol.
99
- assert_raises(ArgumentError) { @ol1.select([34]) }
91
+ assert_raises(ArgumentError) { ol1.select([34]) }
100
92
 
101
93
  #Reject if the category is not a symbol.
102
- assert_raises(ArgumentError) { @ol1.select({'page_len'=>77}) }
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) { @ol1.select([:foobar]) }
106
- assert_raises(ArgumentError) { @ol1.select({:history=>:foobar}) }
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) { @ol1.select([:history, :history]) }
110
- assert_raises(ArgumentError) { @ol1.select([:history, :nohistory]) }
111
- assert_raises(ArgumentError) { @ol1.select([:history, {:history=>:nohistory}]) }
112
- assert_raises(ArgumentError) { @ol1.select([{:history=>:history}, {:history=>:nohistory}]) }
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) { @ol1.select({:zoo => 999})}
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
- assert(@ol1.history?)
121
- refute(@ol1.nohistory?)
122
- assert_equal(@ol1.history, :history)
123
- assert_equal(@ol1.pg_len, 42)
124
-
125
- @ol1.select
126
- assert(@ol1.history?)
127
- refute(@ol1.nohistory?)
128
- assert_equal(@ol1.history, :history)
129
- assert_equal(@ol1.pg_len, 42)
130
-
131
- @ol1.select([])
132
- assert(@ol1.history?)
133
- refute(@ol1.nohistory?)
134
- assert_equal(@ol1.history, :history)
135
- assert_equal(@ol1.pg_len, 42)
136
-
137
- @ol1.select([:history])
138
- assert(@ol1.history?)
139
- refute(@ol1.nohistory?)
140
- assert_equal(@ol1.history, :history)
141
- assert_equal(@ol1.pg_len, 42)
142
-
143
- @ol1.select([:nohistory])
144
- assert(@ol1.nohistory?)
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
- @ol1.select({:history=>:history})
150
- assert(@ol1.history?)
151
- refute(@ol1.nohistory?)
152
- assert_equal(@ol1.history, :history)
153
- assert_equal(@ol1.pg_len, 42)
154
-
155
- @ol1.select({:history=>:nohistory})
156
- assert(@ol1.nohistory?)
157
- refute(@ol1.history?)
158
- assert_equal(@ol1.history, :nohistory)
159
- assert_equal(@ol1.pg_len, 42)
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
- @ol1.select({:pg_len=>55})
162
- assert(@ol1.history?)
163
- refute(@ol1.nohistory?)
164
- assert_equal(@ol1.history, :history)
165
- assert_equal(@ol1.pg_len, 55)
166
-
167
- @ol1.select({:history=>:history, :pg_len=>55})
168
- assert(@ol1.history?)
169
- refute(@ol1.nohistory?)
170
- assert_equal(@ol1.history, :history)
171
- assert_equal(@ol1.pg_len, 55)
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
- @ol1.select({:history=>:nohistory, :pg_len=>55})
174
- assert(@ol1.nohistory?)
175
- refute(@ol1.history?)
176
- assert_equal(@ol1.history, :nohistory)
177
- assert_equal(@ol1.pg_len, 55)
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
- @ol1.select([:history, {:pg_len=>55}])
180
- assert(@ol1.history?)
181
- refute(@ol1.nohistory?)
182
- assert_equal(@ol1.history, :history)
183
- assert_equal(@ol1.pg_len, 55)
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
- @ol1.add_specs([:temp, nil, :hot, :nice, :cold])
192
- @ol1.select #Restore to default values.
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
- #Adding selections.
212
- @ol1.select #Restore to default values.
213
- assert(@ol1.history?)
214
- refute(@ol1.nohistory?)
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
- #ol2 test series.
241
- refute(@ol2.history?)
242
- refute(@ol2.nohistory?)
243
- assert(@ol2.history.nil?)
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
- assert_raises(ArgumentError) { @ol3.select() }
263
- assert_raises(ArgumentError) { @ol3.select({:history=>:nohistory, :fuel2=>:matter}) }
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
@@ -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.2.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-09-22 00:00:00.000000000 Z
12
- dependencies: []
13
- description: A unified handler for flexible function option parameters. Please see
14
- the homepage for docs.
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: