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.
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: