hashmake 0.1.9 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog.rdoc +11 -2
- data/README.rdoc +11 -5
- data/lib/hashmake.rb +2 -0
- data/lib/hashmake/arg_spec.rb +28 -19
- data/lib/hashmake/array_arg_spec.rb +49 -0
- data/lib/hashmake/hash_arg_spec.rb +49 -0
- data/lib/hashmake/hash_makeable.rb +13 -148
- data/lib/hashmake/version.rb +1 -1
- data/spec/arg_spec_spec.rb +30 -14
- data/spec/array_arg_spec_spec.rb +45 -0
- data/spec/hash_arg_spec_spec.rb +45 -0
- data/spec/hash_makeable_spec.rb +3 -105
- metadata +10 -4
data/ChangeLog.rdoc
CHANGED
@@ -37,6 +37,15 @@ Add #find_arg_specs and #make_hash methods to HashMakeable.
|
|
37
37
|
|
38
38
|
In HashMakeable.make_hash, only make objects into hashes if the object class matches the arg spec type (and, still, if it is hash makeable).
|
39
39
|
|
40
|
-
=== 0.1.
|
40
|
+
=== 0.1.9 / 2013-06-21
|
41
|
+
|
42
|
+
Add :allow_nil option to ArgSpec.new. If an arg spec allows nil, it mean that if a hashed arg is nil, no ArgumentError will be raised and the validator won't be called.
|
43
|
+
|
44
|
+
=== 0.2.0 / 2013-06-21
|
41
45
|
|
42
|
-
|
46
|
+
A bit of a major release. mostly to cut back features and modify interfaces a bit.
|
47
|
+
-hash_make does not recursively build objects from hashes, even if the expected object type is hash-makeable
|
48
|
+
-removed allow_nil from arg_spec
|
49
|
+
-add separate classes for container arg specs (array and hash)
|
50
|
+
-remove make_hash
|
51
|
+
-switch order of arguments for hash_make. Hashed args come first now, and arg spec Hash comes next.
|
data/README.rdoc
CHANGED
@@ -8,11 +8,13 @@
|
|
8
8
|
|
9
9
|
Make hash-based object initialization easy!
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
There is also a make_hash method to turn an object into a representative Hash object. Any hash-makeable sub-objects can be turned into Hash objects as well.
|
11
|
+
The hash_make method checks hashed arguments against a set of specifications, then values are assigned to instance variables matching the arg keys.
|
14
12
|
|
15
13
|
== Features
|
14
|
+
Type checking via Object#is_a?. The default type is Object, allowing anything.
|
15
|
+
Mark as required/not. Set to true, by default.
|
16
|
+
Default value, for non-required args that aren't given. For default values that are mutable, make the default value a Proc that can be called to generate the mutable value.
|
17
|
+
Validation of values via a Proc.
|
16
18
|
|
17
19
|
== Examples
|
18
20
|
|
@@ -24,9 +26,10 @@ There is also a make_hash method to turn an object into a representative Hash ob
|
|
24
26
|
ARG_SPECS = {
|
25
27
|
:x => arg_spec(:reqd => true, :type => Float, :validator => ->(a){ a.between?(0.0,1.0) }),
|
26
28
|
:y => arg_spec(:reqd => false, :type => Float, :validator => ->(a){ a.between?(0.0,1.0) }, :default => 0.0),
|
29
|
+
:z => arg_spec_array(:reqd => false, :type => String, :validator => ->(a){ a.size > 0 })
|
27
30
|
}
|
28
31
|
|
29
|
-
attr_reader :x, :y
|
32
|
+
attr_reader :x, :y, :z
|
30
33
|
|
31
34
|
def initialize hashed_args
|
32
35
|
hash_make(ARG_SPECS, hashed_args)
|
@@ -37,7 +40,10 @@ There is also a make_hash method to turn an object into a representative Hash ob
|
|
37
40
|
a = MyClass.new :x => 0.5, :y => 0.2 # a.x => 0.5, a.y => 0.2
|
38
41
|
a = MyClass.new # raise ArgumentError because :x is reqd and not given
|
39
42
|
a = MyClass.new :y => 0.5 # raise ArgumentError because :x is reqd and not given
|
40
|
-
|
43
|
+
|
44
|
+
a = MyClass.new :x => 0.5, :z => ["abc", "efg"] # OK
|
45
|
+
a = MyClass.new :x => 0.5, :z => ["abc", ""] # raise ArgumentError, because validator requires str.size > 0
|
46
|
+
|
41
47
|
== Requirements
|
42
48
|
|
43
49
|
== Install
|
data/lib/hashmake.rb
CHANGED
data/lib/hashmake/arg_spec.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'set'
|
2
|
+
require 'pry'
|
3
|
+
|
1
4
|
module Hashmake
|
2
5
|
|
3
6
|
# Provides a specification of how a hashed arg is to be processed by the
|
@@ -7,28 +10,22 @@ module Hashmake
|
|
7
10
|
#
|
8
11
|
class ArgSpec
|
9
12
|
|
10
|
-
# The valid container types. If nil, indicates no container is expected,
|
11
|
-
# just a plain object of type given by :type.
|
12
|
-
CONTAINERS = [ nil, Hash, Array ]
|
13
|
-
|
14
13
|
# Defines default key/value pairs to use in initializing an instance.
|
15
14
|
# The :reqd key is set to true by default.
|
16
15
|
# The :validator key is set to a Proc that always returns true.
|
17
|
-
# The :container key is set to CONTAINER_NONE.
|
18
16
|
DEFAULT_ARGS = {
|
19
17
|
:reqd => true,
|
20
18
|
:validator => ->(a){true},
|
21
|
-
:container => nil,
|
22
19
|
:type => Object,
|
23
20
|
:allow_nil => false
|
24
21
|
}
|
25
22
|
|
26
|
-
attr_reader :type, :validator, :reqd, :default
|
23
|
+
attr_reader :type, :validator, :reqd, :default
|
27
24
|
|
28
25
|
# A new instance of ArgSpec.
|
29
26
|
#
|
30
27
|
# @param [Hash] hashed_args Hash to use in initializing an instance. Optional keys
|
31
|
-
# are :type, :reqd, :validator,
|
28
|
+
# are :type, :reqd, :validator, and :default.
|
32
29
|
# :type => the type of object expected to be paired
|
33
30
|
# with the key.
|
34
31
|
# :reqd => If true, the arg key must be in the hash
|
@@ -41,30 +38,42 @@ class ArgSpec
|
|
41
38
|
# expecting it to produce the default.
|
42
39
|
# :validator => a Proc used to check the validity of
|
43
40
|
# whatever value is paired with an arg key.
|
44
|
-
# :container => indicates whether the arg key will be paired
|
45
|
-
# with a container (array or hash) which contains
|
46
|
-
# objects of the type specified by :type. Valid values
|
47
|
-
# for this are given by ArgSpec::CONTAINERS.
|
48
41
|
def initialize hashed_args
|
49
42
|
new_args = DEFAULT_ARGS.merge(hashed_args)
|
50
43
|
|
51
44
|
@type = new_args[:type]
|
52
|
-
raise ArgumentError, "
|
45
|
+
raise ArgumentError, "#{@type} is not a Class" unless @type.is_a?(Class)
|
53
46
|
|
54
47
|
@validator = new_args[:validator]
|
55
48
|
@reqd = new_args[:reqd]
|
56
49
|
|
57
|
-
@container = new_args[:container]
|
58
|
-
raise ArgumentError, "CONTAINERS does not include container #{@container}" unless CONTAINERS.include?(@container)
|
59
|
-
|
60
|
-
@allow_nil = new_args[:allow_nil]
|
61
|
-
|
62
50
|
unless @reqd
|
63
51
|
msg = "if hashed arg is not required, a default value or value generator (proc) must be defined via :default key"
|
64
52
|
raise ArgumentError, msg unless new_args.has_key?(:default)
|
65
53
|
@default = new_args[:default]
|
66
54
|
end
|
67
55
|
end
|
68
|
-
|
56
|
+
|
57
|
+
# If the val is not of the right type, but is a Hash, attempt to
|
58
|
+
# make an object of the right type if it is hash-makeable
|
59
|
+
def hash_make_if_needed val
|
60
|
+
if Hashmake.hash_makeable?(@type) and val.is_a?(Hash)
|
61
|
+
val = @type.new val
|
62
|
+
end
|
63
|
+
return val
|
64
|
+
end
|
65
|
+
|
66
|
+
# Check the given value, and raise ArgumentError it is not valid.
|
67
|
+
def validate_value val
|
68
|
+
raise ArgumentError, "val #{val} is not a #{@type}" unless val.is_a?(@type)
|
69
|
+
raise ArgumentError, "val #{val} is not valid" unless @validator.call(val)
|
70
|
+
end
|
71
|
+
|
72
|
+
def make_hash_if_possible val
|
73
|
+
if Hashmake::hash_makeable?(val.class) and val.class.is_a?(@type)
|
74
|
+
val = val.make_hash
|
75
|
+
end
|
76
|
+
return val
|
77
|
+
end
|
69
78
|
end
|
70
79
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
|
2
|
+
module Hashmake
|
3
|
+
|
4
|
+
class ArrayArgSpec
|
5
|
+
|
6
|
+
attr_reader :arg_spec
|
7
|
+
|
8
|
+
def initialize hashed_args = {}
|
9
|
+
hashed_args = { :default => ->(){ [] } }.merge hashed_args
|
10
|
+
@arg_spec = ArgSpec.new hashed_args
|
11
|
+
end
|
12
|
+
|
13
|
+
def type
|
14
|
+
@arg_spec.type
|
15
|
+
end
|
16
|
+
|
17
|
+
def validator
|
18
|
+
@arg_spec.validator
|
19
|
+
end
|
20
|
+
|
21
|
+
def reqd
|
22
|
+
@arg_spec.reqd
|
23
|
+
end
|
24
|
+
|
25
|
+
def default
|
26
|
+
@arg_spec.default
|
27
|
+
end
|
28
|
+
|
29
|
+
def hash_make_if_needed val
|
30
|
+
val.each_index do |i|
|
31
|
+
item = val[i]
|
32
|
+
val[i] = @arg_spec.hash_make_if_needed item
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def validate_value val
|
37
|
+
val.each do |item|
|
38
|
+
@arg_spec.validate_value item
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def make_hash_if_possible ary
|
43
|
+
ary.each_index do |i|
|
44
|
+
ary[i] = @arg_spec.make_hash_if_possible ary[i]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
|
2
|
+
module Hashmake
|
3
|
+
|
4
|
+
class HashArgSpec
|
5
|
+
|
6
|
+
attr_reader :arg_spec
|
7
|
+
|
8
|
+
def initialize hashed_args = {}
|
9
|
+
hashed_args = { :default => ->(){ {} } }.merge hashed_args
|
10
|
+
@arg_spec = ArgSpec.new hashed_args
|
11
|
+
end
|
12
|
+
|
13
|
+
def type
|
14
|
+
@arg_spec.type
|
15
|
+
end
|
16
|
+
|
17
|
+
def validator
|
18
|
+
@arg_spec.validator
|
19
|
+
end
|
20
|
+
|
21
|
+
def reqd
|
22
|
+
@arg_spec.reqd
|
23
|
+
end
|
24
|
+
|
25
|
+
def default
|
26
|
+
@arg_spec.default
|
27
|
+
end
|
28
|
+
|
29
|
+
def hash_make_if_needed val
|
30
|
+
val.each_key do |item_key|
|
31
|
+
item = val[item_key]
|
32
|
+
val[item_key] = @arg_spec.hash_make_if_needed item
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def validate_value val
|
37
|
+
val.each do |key, item|
|
38
|
+
@arg_spec.validate_value item
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def make_hash_if_possible hash
|
43
|
+
hash.each_key do |key|
|
44
|
+
hash[key] = @arg_spec.make_hash_if_possible hash[key]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -20,47 +20,21 @@ module HashMakeable
|
|
20
20
|
# Process a hash that contains 'hashed args'. Each hashed arg is intended to
|
21
21
|
# be used in initializing an object instance.
|
22
22
|
#
|
23
|
-
# @param [Enumerable] arg_specs An enumerable of ArgSpec objects. Each object
|
24
|
-
# details an arg key that might be expected in the
|
25
|
-
# args hash.
|
26
23
|
# @param [Hash] hashed_args A hash that should contain at least all the required
|
27
24
|
# keys and valid values, according to the arg_specs passed in.
|
28
25
|
# Nonrequired keys can be given as well, but if they are
|
29
26
|
# not then a default value is assigned (again, according to
|
30
27
|
# arg_specs passed in).
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
28
|
+
# @param [Hash] arg_specs A hash of ArgSpec objects. An ArgSpec object details
|
29
|
+
# what to expect from the hashed argument with a
|
30
|
+
# matching same key.
|
31
|
+
# @param [true/false] assign_args If true, the hashed args will be assigned to
|
32
|
+
# instance variables. If false, the hashed args
|
33
|
+
# will still be checked, but not assigned.
|
34
|
+
def hash_make hashed_args, arg_specs = find_arg_specs, assign_args = true
|
37
35
|
arg_specs.each do |key, arg_spec|
|
38
36
|
if hashed_args.has_key?(key)
|
39
37
|
val = hashed_args[key]
|
40
|
-
|
41
|
-
if Hashmake::hash_makeable?(arg_spec.type)
|
42
|
-
# If the val is not of the right type, but is a Hash, attempt to
|
43
|
-
# make an object of the right type if it is hash-makeable
|
44
|
-
if arg_spec.container == Array && val.is_a?(Array)
|
45
|
-
val.each_index do |i|
|
46
|
-
item = val[i]
|
47
|
-
if !item.is_a?(arg_spec.type) && item.is_a?(Hash)
|
48
|
-
val[i] = arg_spec.type.new item
|
49
|
-
end
|
50
|
-
end
|
51
|
-
elsif arg_spec.container == Hash && val.is_a?(Hash)
|
52
|
-
val.each_key do |item_key|
|
53
|
-
item = val[item_key]
|
54
|
-
if !item.is_a?(arg_spec.type) && item.is_a?(Hash)
|
55
|
-
val[item_key] = arg_spec.type.new item
|
56
|
-
end
|
57
|
-
end
|
58
|
-
else
|
59
|
-
if !val.is_a?(arg_spec.type) && val.is_a?(Hash)
|
60
|
-
val = arg_spec.type.new val
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
38
|
else
|
65
39
|
if arg_spec.reqd
|
66
40
|
raise ArgumentError, "hashed_args does not have required key #{key}"
|
@@ -73,50 +47,14 @@ module HashMakeable
|
|
73
47
|
end
|
74
48
|
end
|
75
49
|
|
76
|
-
|
50
|
+
arg_spec.validate_value val
|
51
|
+
|
77
52
|
if assign_args
|
78
53
|
self.instance_variable_set("@#{key.to_s}".to_sym, val)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
# Check the given value, using the given ArgSpec object. An ArgumentError
|
84
|
-
# exception will be raised if the value is not valid.
|
85
|
-
def validate_arg arg_spec, val
|
86
|
-
if arg_spec.container == Array
|
87
|
-
raise ArgumentError, "val #{val} is not an array" unless val.is_a?(Array)
|
88
|
-
val.each do |item|
|
89
|
-
if item.nil?
|
90
|
-
raise ArgumentError, "nil was given" unless arg_spec.allow_nil
|
91
|
-
else
|
92
|
-
raise ArgumentError, "array item #{item} is not a #{arg_spec.type}" unless item.is_a?(arg_spec.type)
|
93
|
-
raise ArgumentError, "array item #{item} is not valid" unless arg_spec.validator.call(item)
|
94
|
-
end
|
95
54
|
end
|
96
|
-
elsif arg_spec.container == Hash
|
97
|
-
raise ArgumentError, "val #{val} is not a hash" unless val.is_a?(Hash)
|
98
|
-
val.values.each do |item|
|
99
|
-
if item.nil?
|
100
|
-
raise ArgumentError, "nil was given" unless arg_spec.allow_nil
|
101
|
-
else
|
102
|
-
raise ArgumentError, "hash item #{item} is not a #{arg_spec.type}" unless item.is_a?(arg_spec.type)
|
103
|
-
raise ArgumentError, "hash item #{item} is not valid" unless arg_spec.validator.call(item)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
elsif arg_spec.container.nil?
|
107
|
-
if val.nil?
|
108
|
-
raise ArgumentError, "nil was given" unless arg_spec.allow_nil
|
109
|
-
else
|
110
|
-
raise ArgumentError, "val #{val} is not a #{arg_spec.type}" unless val.is_a?(arg_spec.type)
|
111
|
-
raise ArgumentError, "val #{val} is not valid" unless arg_spec.validator.call(val)
|
112
|
-
end
|
113
|
-
else
|
114
|
-
raise ArgumentError, "arg_spec.container #{arg_spec.container} is not valid"
|
115
55
|
end
|
116
|
-
|
117
|
-
return true
|
118
56
|
end
|
119
|
-
|
57
|
+
|
120
58
|
# Look in the current class for a constant that is a Hash containing (only)
|
121
59
|
# ArgSpec objects. Returns the first constant matching this criteria, or nil
|
122
60
|
# if none was found.
|
@@ -126,7 +64,7 @@ module HashMakeable
|
|
126
64
|
if val.is_a? Hash
|
127
65
|
all_arg_specs = true
|
128
66
|
val.each do |key,value|
|
129
|
-
unless value.is_a? ArgSpec
|
67
|
+
unless value.is_a? ArgSpec or value.is_a? ArrayArgSpec or value.is_a?(HashArgSpec)
|
130
68
|
all_arg_specs = false
|
131
69
|
break
|
132
70
|
end
|
@@ -140,76 +78,6 @@ module HashMakeable
|
|
140
78
|
|
141
79
|
return nil
|
142
80
|
end
|
143
|
-
|
144
|
-
# Produce a hash that contains 'hashed args'. Each hashed arg is intended to
|
145
|
-
# be used in initializing an object instance.
|
146
|
-
#
|
147
|
-
# @param [Enumerable] arg_specs An enumerable of ArgSpec objects. Each one
|
148
|
-
# details an arg key that might be expected in the
|
149
|
-
# args hash. This param is nil by default. If the param
|
150
|
-
# is nil, this method will attempt to locate arg specs
|
151
|
-
# using find_arg_specs.
|
152
|
-
#
|
153
|
-
def make_hash arg_specs = nil
|
154
|
-
if arg_specs.nil?
|
155
|
-
arg_specs = self.find_arg_specs
|
156
|
-
raise "No arg specs given, and no class constant that is a Hash containing only ArgSpec objects was found" if arg_specs.nil?
|
157
|
-
end
|
158
|
-
|
159
|
-
arg_specs.each do |key, arg_spec|
|
160
|
-
raise ArgumentError, "arg_specs item #{arg_spec} is not a ArgSpec" unless arg_spec.is_a?(ArgSpec)
|
161
|
-
end
|
162
|
-
|
163
|
-
hash = {}
|
164
|
-
|
165
|
-
arg_specs.each do |key, arg_spec|
|
166
|
-
sym = "@#{key}".to_sym
|
167
|
-
raise ArgumentError, "current obj #{self} does not include instance variable #{sym}" if !self.instance_variables.include?(sym)
|
168
|
-
val = self.instance_variable_get(sym)
|
169
|
-
|
170
|
-
should_assign = false
|
171
|
-
|
172
|
-
if arg_spec.reqd
|
173
|
-
should_assign = true
|
174
|
-
else
|
175
|
-
if arg_spec.default.is_a?(Proc)
|
176
|
-
should_assign = (val != arg_spec.default.call)
|
177
|
-
else
|
178
|
-
should_assign = (val != arg_spec.default)
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
if should_assign
|
183
|
-
if val.is_a?(Array) && arg_spec.container == Array
|
184
|
-
ary = val
|
185
|
-
val = []
|
186
|
-
ary.each do |item|
|
187
|
-
if Hashmake::hash_makeable?(item.class) and item.class == arg_spec.type
|
188
|
-
val << item.make_hash
|
189
|
-
else
|
190
|
-
val << item
|
191
|
-
end
|
192
|
-
end
|
193
|
-
elsif val.is_a?(Hash) && arg_spec.container == Hash
|
194
|
-
hsh = val
|
195
|
-
val = {}
|
196
|
-
hsh.each do |hsh_key,item|
|
197
|
-
if Hashmake::hash_makeable? item.class and item.class == arg_spec.type
|
198
|
-
val[hsh_key] = item.make_hash
|
199
|
-
else
|
200
|
-
val[hsh_key] = item
|
201
|
-
end
|
202
|
-
end
|
203
|
-
elsif Hashmake::hash_makeable?(val.class) and val.class == arg_spec.type
|
204
|
-
val = val.make_hash
|
205
|
-
end
|
206
|
-
|
207
|
-
hash[key] = val
|
208
|
-
end
|
209
|
-
end
|
210
|
-
|
211
|
-
return hash
|
212
|
-
end
|
213
81
|
|
214
82
|
# Contains class methods to be added to a class that includes the
|
215
83
|
# HashMakeable module.
|
@@ -222,17 +90,14 @@ module HashMakeable
|
|
222
90
|
# Helper method to make a ArgSpec object where the container is an Array.
|
223
91
|
# Set :default to a Proc that generates an empty array.
|
224
92
|
def arg_spec_array args
|
225
|
-
|
226
|
-
ArgSpec.new args
|
93
|
+
ArrayArgSpec.new args
|
227
94
|
end
|
228
95
|
|
229
96
|
# Helper method to make a ArgSpec object where the container is an Hash.
|
230
97
|
# Set :default to a Proc that generates an empty hash.
|
231
98
|
def arg_spec_hash args
|
232
|
-
|
233
|
-
ArgSpec.new args
|
99
|
+
HashArgSpec.new args
|
234
100
|
end
|
235
101
|
end
|
236
|
-
|
237
102
|
end
|
238
103
|
end
|
data/lib/hashmake/version.rb
CHANGED
data/spec/arg_spec_spec.rb
CHANGED
@@ -16,22 +16,38 @@ describe Hashmake::ArgSpec do
|
|
16
16
|
|
17
17
|
lambda { Hashmake::ArgSpec.new hash }.should_not raise_error(ArgumentError)
|
18
18
|
end
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
19
|
+
|
20
|
+
context '#validate_value' do
|
21
|
+
before :each do
|
22
|
+
@arg_spec = ArgSpec.new(:reqd => true, :type => Fixnum, :validator => ->(a){ a > 0})
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'value given is correct type' do
|
26
|
+
context 'value given is valid' do
|
27
|
+
it 'should not raise ArgumentError' do
|
28
|
+
lambda { @arg_spec.validate_value 1 }.should_not raise_error
|
29
|
+
end
|
30
|
+
end
|
25
31
|
|
26
|
-
|
32
|
+
context 'value given is not valid' do
|
33
|
+
it 'should raise ArgumentError' do
|
34
|
+
lambda { @arg_spec.validate_value 0 }.should raise_error(ArgumentError)
|
35
|
+
end
|
36
|
+
end
|
27
37
|
end
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'should raise ArgumentError if invalid container is given' do
|
31
|
-
hash = {
|
32
|
-
:reqd => true, :key => :stuff, :type => String, :container => Fixnum
|
33
|
-
}
|
34
38
|
|
35
|
-
|
39
|
+
context 'value given is not correct type' do
|
40
|
+
context 'value given is valid' do
|
41
|
+
it 'should raise ArgumentError' do
|
42
|
+
lambda { @arg_spec.validate_value 1.0 }.should raise_error(ArgumentError)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'value given is not valid' do
|
47
|
+
it 'should raise ArgumentError' do
|
48
|
+
lambda { @arg_spec.validate_value 0.0 }.should raise_error(ArgumentError)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
36
52
|
end
|
37
53
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Hashmake::ArrayArgSpec do
|
4
|
+
it 'should not raise ArgumentError if :reqd is false and a :default value is given' do
|
5
|
+
hash = {
|
6
|
+
:reqd => false, :key => :some_variable, :type => String, :default => ""
|
7
|
+
}
|
8
|
+
|
9
|
+
lambda { Hashmake::ArrayArgSpec.new hash }.should_not raise_error(ArgumentError)
|
10
|
+
end
|
11
|
+
|
12
|
+
context '#validate_value' do
|
13
|
+
before :each do
|
14
|
+
@arg_spec = ArrayArgSpec.new(:reqd => true, :type => Fixnum, :validator => ->(a){ a > 0})
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'value given is correct type' do
|
18
|
+
context 'value given is valid' do
|
19
|
+
it 'should not raise ArgumentError' do
|
20
|
+
lambda { @arg_spec.validate_value([1, 2]) }.should_not raise_error
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'value given is not valid' do
|
25
|
+
it 'should raise ArgumentError' do
|
26
|
+
lambda { @arg_spec.validate_value([0, 2]) }.should raise_error(ArgumentError)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'value given is not correct type' do
|
32
|
+
context 'value given is valid' do
|
33
|
+
it 'should raise ArgumentError' do
|
34
|
+
lambda { @arg_spec.validate_value([1.0, 2]) }.should raise_error(ArgumentError)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'value given is not valid' do
|
39
|
+
it 'should raise ArgumentError' do
|
40
|
+
lambda { @arg_spec.validate_value([0.0, 2]) }.should raise_error(ArgumentError)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Hashmake::HashArgSpec do
|
4
|
+
it 'should not raise ArgumentError if :reqd is false and a :default value is given' do
|
5
|
+
hash = {
|
6
|
+
:reqd => false, :key => :some_variable, :type => String, :default => ""
|
7
|
+
}
|
8
|
+
|
9
|
+
lambda { Hashmake::HashArgSpec.new hash }.should_not raise_error(ArgumentError)
|
10
|
+
end
|
11
|
+
|
12
|
+
context '#validate_value' do
|
13
|
+
before :each do
|
14
|
+
@arg_spec = HashArgSpec.new(:reqd => true, :type => Fixnum, :validator => ->(a){ a > 0})
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'value given is correct type' do
|
18
|
+
context 'value given is valid' do
|
19
|
+
it 'should not raise ArgumentError' do
|
20
|
+
lambda { @arg_spec.validate_value(:a => 1, :b => 2) }.should_not raise_error
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'value given is not valid' do
|
25
|
+
it 'should raise ArgumentError' do
|
26
|
+
lambda { @arg_spec.validate_value(:a => 0, :b => 2) }.should raise_error(ArgumentError)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'value given is not correct type' do
|
32
|
+
context 'value given is valid' do
|
33
|
+
it 'should raise ArgumentError' do
|
34
|
+
lambda { @arg_spec.validate_value(:a => 1.0, :b => 2) }.should raise_error(ArgumentError)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'value given is not valid' do
|
39
|
+
it 'should raise ArgumentError' do
|
40
|
+
lambda { @arg_spec.validate_value(:a => 0.0, :b => 2) }.should raise_error(ArgumentError)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/spec/hash_makeable_spec.rb
CHANGED
@@ -2,25 +2,6 @@ require 'pry'
|
|
2
2
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
3
3
|
|
4
4
|
describe Hashmake::HashMakeable do
|
5
|
-
class AlsoHashMakeable
|
6
|
-
include Comparable
|
7
|
-
include HashMakeable
|
8
|
-
|
9
|
-
ARG_SPECS = {
|
10
|
-
:a_number => arg_spec(:reqd => false, :type => Numeric, :default => 1.0)
|
11
|
-
}
|
12
|
-
|
13
|
-
attr_accessor :a_number
|
14
|
-
|
15
|
-
def initialize args = {}
|
16
|
-
hash_make ARG_SPECS, args
|
17
|
-
end
|
18
|
-
|
19
|
-
def <=>(other)
|
20
|
-
a_number <=> other.a_number
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
5
|
class MyTestClass
|
25
6
|
include HashMakeable
|
26
7
|
|
@@ -31,29 +12,13 @@ describe Hashmake::HashMakeable do
|
|
31
12
|
:not_reqd_float => arg_spec(:reqd => false, :type => Float, :default => NON_REQD_FLOAT_DEFAULT, :validator => ->(a){ a.between?(0.0,1.0) }),
|
32
13
|
:not_reqd_array_of_float => arg_spec_array(:reqd => false, :type => Float, :validator => ->(a){ a.between?(0.0,1.0) }),
|
33
14
|
:not_reqd_hash_of_float => arg_spec_hash(:reqd => false, :type => Float, :validator => ->(a){ a.between?(0.0,1.0) }),
|
34
|
-
:also_hash_makeable => arg_spec(:reqd => false, :type => AlsoHashMakeable, :default => ->(){ AlsoHashMakeable.new }),
|
35
|
-
:ary_of_also_hash_makeables => arg_spec_array(:reqd => false, :type => AlsoHashMakeable)
|
36
15
|
}
|
37
16
|
|
38
|
-
attr_accessor :not_reqd_float
|
39
|
-
attr_reader :reqd_string, :not_reqd_array_of_float, :not_reqd_hash_of_float
|
17
|
+
attr_accessor :not_reqd_float
|
18
|
+
attr_reader :reqd_string, :not_reqd_array_of_float, :not_reqd_hash_of_float
|
40
19
|
|
41
20
|
def initialize hashed_args = {}
|
42
|
-
hash_make
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
class TestAllowNil
|
47
|
-
include HashMakeable
|
48
|
-
|
49
|
-
ARG_SPECS = {
|
50
|
-
:allows_nil => arg_spec(:reqd => false, :default => ->(){ "123" }, :type => String, :allow_nil => true),
|
51
|
-
:disallows_nil => arg_spec(:reqd => false, :default => ->(){ "123" }, :type => String, :allow_nil => false)
|
52
|
-
}
|
53
|
-
|
54
|
-
attr_reader :allows_nil, :disallows_nil
|
55
|
-
def initialize args
|
56
|
-
hash_make ARG_SPECS, args
|
21
|
+
hash_make hashed_args, ARG_SPECS
|
57
22
|
end
|
58
23
|
end
|
59
24
|
|
@@ -142,72 +107,5 @@ describe Hashmake::HashMakeable do
|
|
142
107
|
end.should raise_error(ArgumentError)
|
143
108
|
end
|
144
109
|
end
|
145
|
-
|
146
|
-
context 'hash-makeable arg' do
|
147
|
-
it 'should construct the hash-makeable arg from just a Hash' do
|
148
|
-
a_number = 5
|
149
|
-
a = MyTestClass.new(:reqd_string => "ok", :also_hash_makeable => { :a_number => a_number })
|
150
|
-
a.also_hash_makeable.a_number.should eq(a_number)
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
it 'should not raise ArgumentError if nil is given when nil is allowed' do
|
155
|
-
lambda { TestAllowNil.new(:allows_nil => nil) }.should_not raise_error
|
156
|
-
end
|
157
|
-
|
158
|
-
it 'should raise ArgumentError if nil is given when nil is not allowed' do
|
159
|
-
lambda { TestAllowNil.new(:disallows_nil => nil) }.should raise_error(ArgumentError)
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
describe '#make_hash' do
|
164
|
-
before :each do
|
165
|
-
@reqd_string = "okeydoke"
|
166
|
-
@obj = MyTestClass.new :reqd_string => @reqd_string, :non_reqd_float => MyTestClass::NON_REQD_FLOAT_DEFAULT
|
167
|
-
@hash = @obj.make_hash
|
168
|
-
end
|
169
|
-
|
170
|
-
it 'should produce a Hash' do
|
171
|
-
@hash.should be_a Hash
|
172
|
-
end
|
173
|
-
|
174
|
-
it "should always include req'd values" do
|
175
|
-
@hash.should include(:reqd_string)
|
176
|
-
@hash[:reqd_string].should eq(@reqd_string)
|
177
|
-
end
|
178
|
-
|
179
|
-
it "should never include non-req'd default values" do
|
180
|
-
@hash.should_not include(:non_reqd_float)
|
181
|
-
end
|
182
|
-
|
183
|
-
it "should always include non-req'd non-default values" do
|
184
|
-
@obj.not_reqd_float = 2.0
|
185
|
-
hash = @obj.make_hash
|
186
|
-
hash.should include(:not_reqd_float)
|
187
|
-
hash[:not_reqd_float].should eq(2.0)
|
188
|
-
end
|
189
|
-
|
190
|
-
it "should turn any hash-makeable objects into Hash objects" do
|
191
|
-
@obj.also_hash_makeable.a_number = 2.0
|
192
|
-
hash = @obj.make_hash
|
193
|
-
hash.should include(:also_hash_makeable)
|
194
|
-
hash[:also_hash_makeable].should be_a Hash
|
195
|
-
hash[:also_hash_makeable].should include(:a_number)
|
196
|
-
hash[:also_hash_makeable][:a_number].should eq(2.0)
|
197
|
-
end
|
198
|
-
|
199
|
-
it "should turn an array of hash-makeable objects into an array of Hash objects" do
|
200
|
-
obj2 = MyTestClass.new @obj.make_hash
|
201
|
-
@obj.ary_of_also_hash_makeables = [
|
202
|
-
AlsoHashMakeable.new(:a_number => 1),
|
203
|
-
AlsoHashMakeable.new(:a_number => 2),
|
204
|
-
AlsoHashMakeable.new(:a_number => 3),
|
205
|
-
]
|
206
|
-
obj2 = MyTestClass.new @obj.make_hash
|
207
|
-
obj2.ary_of_also_hash_makeables.count.should be(3)
|
208
|
-
obj2.ary_of_also_hash_makeables[0].a_number.should eq(1)
|
209
|
-
obj2.ary_of_also_hash_makeables[1].a_number.should eq(2)
|
210
|
-
obj2.ary_of_also_hash_makeables[2].a_number.should eq(3)
|
211
|
-
end
|
212
110
|
end
|
213
111
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hashmake
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-07-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -112,9 +112,13 @@ files:
|
|
112
112
|
- hashmake.gemspec
|
113
113
|
- lib/hashmake.rb
|
114
114
|
- lib/hashmake/arg_spec.rb
|
115
|
+
- lib/hashmake/array_arg_spec.rb
|
116
|
+
- lib/hashmake/hash_arg_spec.rb
|
115
117
|
- lib/hashmake/hash_makeable.rb
|
116
118
|
- lib/hashmake/version.rb
|
117
119
|
- spec/arg_spec_spec.rb
|
120
|
+
- spec/array_arg_spec_spec.rb
|
121
|
+
- spec/hash_arg_spec_spec.rb
|
118
122
|
- spec/hash_makeable_spec.rb
|
119
123
|
- spec/hashmake_spec.rb
|
120
124
|
- spec/spec_helper.rb
|
@@ -133,7 +137,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
133
137
|
version: '0'
|
134
138
|
segments:
|
135
139
|
- 0
|
136
|
-
hash: -
|
140
|
+
hash: -4514910862506440485
|
137
141
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
142
|
none: false
|
139
143
|
requirements:
|
@@ -142,7 +146,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
142
146
|
version: '0'
|
143
147
|
segments:
|
144
148
|
- 0
|
145
|
-
hash: -
|
149
|
+
hash: -4514910862506440485
|
146
150
|
requirements: []
|
147
151
|
rubyforge_project:
|
148
152
|
rubygems_version: 1.8.23
|
@@ -151,6 +155,8 @@ specification_version: 3
|
|
151
155
|
summary: Make hashed-based object initialization easy!
|
152
156
|
test_files:
|
153
157
|
- spec/arg_spec_spec.rb
|
158
|
+
- spec/array_arg_spec_spec.rb
|
159
|
+
- spec/hash_arg_spec_spec.rb
|
154
160
|
- spec/hash_makeable_spec.rb
|
155
161
|
- spec/hashmake_spec.rb
|
156
162
|
- spec/spec_helper.rb
|