hashmake 0.2.0 → 0.2.1
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.
- data/ChangeLog.rdoc +6 -1
- data/README.rdoc +13 -1
- data/lib/hashmake/arg_spec.rb +22 -19
- data/lib/hashmake/array_arg_spec.rb +1 -14
- data/lib/hashmake/hash_arg_spec.rb +1 -14
- data/lib/hashmake/version.rb +1 -1
- data/spec/arg_spec_spec.rb +56 -33
- data/spec/hash_makeable_spec.rb +61 -0
- metadata +4 -4
data/ChangeLog.rdoc
CHANGED
@@ -48,4 +48,9 @@ A bit of a major release. mostly to cut back features and modify interfaces a bi
|
|
48
48
|
-removed allow_nil from arg_spec
|
49
49
|
-add separate classes for container arg specs (array and hash)
|
50
50
|
-remove make_hash
|
51
|
-
-switch order of arguments for hash_make. Hashed args come first now, and arg spec Hash comes next.
|
51
|
+
-switch order of arguments for hash_make. Hashed args come first now, and arg spec Hash comes next.
|
52
|
+
|
53
|
+
=== 0.2.1 / 2013-08-07
|
54
|
+
|
55
|
+
Arg specs can support single or multiple types.
|
56
|
+
Removed unused hash_make_if_needed and make_hash_if_possible.
|
data/README.rdoc
CHANGED
@@ -11,7 +11,7 @@ Make hash-based object initialization easy!
|
|
11
11
|
The hash_make method checks hashed arguments against a set of specifications, then values are assigned to instance variables matching the arg keys.
|
12
12
|
|
13
13
|
== Features
|
14
|
-
Type checking via Object#is_a?. The default type is Object, allowing anything.
|
14
|
+
Type checking via Object#is_a?. The default type is Object, allowing anything. Can allow multiple types.
|
15
15
|
Mark as required/not. Set to true, by default.
|
16
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
17
|
Validation of values via a Proc.
|
@@ -44,6 +44,18 @@ Validation of values via a Proc.
|
|
44
44
|
a = MyClass.new :x => 0.5, :z => ["abc", "efg"] # OK
|
45
45
|
a = MyClass.new :x => 0.5, :z => ["abc", ""] # raise ArgumentError, because validator requires str.size > 0
|
46
46
|
|
47
|
+
class MultitypeDemo
|
48
|
+
include Hashmake::HashMakeable
|
49
|
+
|
50
|
+
ARG_SPECS = {
|
51
|
+
:str_or_class => arg_spec(:reqd => true, :type => [String, Class])
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
MultitypeDemo.new(:str_or_class => "") # OK
|
56
|
+
MultitypeDemo.new(:str_or_class => String) # OK
|
57
|
+
MultitypeDemo.new(:str_or_class => 1) # raise ArgumentError
|
58
|
+
|
47
59
|
== Requirements
|
48
60
|
|
49
61
|
== Install
|
data/lib/hashmake/arg_spec.rb
CHANGED
@@ -42,7 +42,13 @@ class ArgSpec
|
|
42
42
|
new_args = DEFAULT_ARGS.merge(hashed_args)
|
43
43
|
|
44
44
|
@type = new_args[:type]
|
45
|
-
|
45
|
+
if @type.is_a?(Enumerable)
|
46
|
+
@type.each do |type|
|
47
|
+
raise ArgumentError, "#{type} is not a Class" unless type.is_a?(Class)
|
48
|
+
end
|
49
|
+
else
|
50
|
+
raise ArgumentError, "#{@type} is not a Class" unless @type.is_a?(Class)
|
51
|
+
end
|
46
52
|
|
47
53
|
@validator = new_args[:validator]
|
48
54
|
@reqd = new_args[:reqd]
|
@@ -53,27 +59,24 @@ class ArgSpec
|
|
53
59
|
@default = new_args[:default]
|
54
60
|
end
|
55
61
|
end
|
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
62
|
|
66
63
|
# Check the given value, and raise ArgumentError it is not valid.
|
67
64
|
def validate_value val
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
65
|
+
if @type.is_a?(Array)
|
66
|
+
type_matched = false
|
67
|
+
@type.each do |type|
|
68
|
+
if val.is_a? type
|
69
|
+
type_matched = true
|
70
|
+
end
|
71
|
+
end
|
72
|
+
unless type_matched
|
73
|
+
raise ArgumentError, "val #{val} is not one of #{@type}"
|
74
|
+
end
|
75
|
+
else
|
76
|
+
raise ArgumentError, "val #{val} is not a #{@type}" unless val.is_a?(@type)
|
75
77
|
end
|
76
|
-
|
77
|
-
|
78
|
+
|
79
|
+
raise ArgumentError, "val #{val} is not valid" unless @validator.call(val)
|
80
|
+
end
|
78
81
|
end
|
79
82
|
end
|
@@ -26,24 +26,11 @@ class ArrayArgSpec
|
|
26
26
|
@arg_spec.default
|
27
27
|
end
|
28
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
29
|
def validate_value val
|
37
30
|
val.each do |item|
|
38
31
|
@arg_spec.validate_value item
|
39
32
|
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
|
33
|
+
end
|
47
34
|
end
|
48
35
|
|
49
36
|
end
|
@@ -26,24 +26,11 @@ class HashArgSpec
|
|
26
26
|
@arg_spec.default
|
27
27
|
end
|
28
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
29
|
def validate_value val
|
37
30
|
val.each do |key, item|
|
38
31
|
@arg_spec.validate_value item
|
39
32
|
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
|
33
|
+
end
|
47
34
|
end
|
48
35
|
|
49
36
|
end
|
data/lib/hashmake/version.rb
CHANGED
data/spec/arg_spec_spec.rb
CHANGED
@@ -1,51 +1,74 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
|
3
3
|
describe Hashmake::ArgSpec do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
4
|
+
context ':reqd is false' do
|
5
|
+
context 'no default value is given' do
|
6
|
+
it 'should raise error' do
|
7
|
+
hash = { :reqd => false, :key => :some_variable, :type => String }
|
8
|
+
expect { Hashmake::ArgSpec.new hash }.to raise_error
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'default value is given' do
|
13
|
+
it 'should not raise error' do
|
14
|
+
hash = { :reqd => false, :key => :some_variable, :type => String, :default => "" }
|
15
|
+
expect { Hashmake::ArgSpec.new hash }.not_to raise_error
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
18
19
|
end
|
19
|
-
|
20
|
+
|
20
21
|
context '#validate_value' do
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
context 'value given is
|
27
|
-
|
28
|
-
|
22
|
+
context 'single type given' do
|
23
|
+
before :all do
|
24
|
+
@arg_spec = ArgSpec.new(:reqd => true, :type => Fixnum, :validator => ->(a){ a > 0})
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'value given is correct type' do
|
28
|
+
context 'value given is valid' do
|
29
|
+
it 'should not raise ArgumentError' do
|
30
|
+
lambda { @arg_spec.validate_value 1 }.should_not raise_error
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'value given is not valid' do
|
35
|
+
it 'should raise ArgumentError' do
|
36
|
+
lambda { @arg_spec.validate_value 0 }.should raise_error(ArgumentError)
|
37
|
+
end
|
29
38
|
end
|
30
39
|
end
|
31
40
|
|
32
|
-
context 'value given is not
|
33
|
-
|
34
|
-
|
41
|
+
context 'value given is not correct type' do
|
42
|
+
context 'value given is valid' do
|
43
|
+
it 'should raise ArgumentError' do
|
44
|
+
lambda { @arg_spec.validate_value 1.0 }.should raise_error(ArgumentError)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'value given is not valid' do
|
49
|
+
it 'should raise ArgumentError' do
|
50
|
+
lambda { @arg_spec.validate_value 0.0 }.should raise_error(ArgumentError)
|
51
|
+
end
|
35
52
|
end
|
36
53
|
end
|
37
54
|
end
|
38
|
-
|
39
|
-
context '
|
40
|
-
|
41
|
-
|
42
|
-
|
55
|
+
|
56
|
+
context 'multiple types given' do
|
57
|
+
before :all do
|
58
|
+
@arg_spec = ArgSpec.new(:reqd => true, :type => [FalseClass, TrueClass])
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'value given is one of the correct types' do
|
62
|
+
it 'should not raise ArgumentError' do
|
63
|
+
expect { @arg_spec.validate_value false }.not_to raise_error
|
64
|
+
expect { @arg_spec.validate_value true }.not_to raise_error
|
43
65
|
end
|
44
66
|
end
|
45
67
|
|
46
|
-
context 'value given is not
|
68
|
+
context 'value given is not one of the correct types' do
|
47
69
|
it 'should raise ArgumentError' do
|
48
|
-
|
70
|
+
expect { @arg_spec.validate_value 1 }.to raise_error
|
71
|
+
expect { @arg_spec.validate_value 0 }.to raise_error
|
49
72
|
end
|
50
73
|
end
|
51
74
|
end
|
data/spec/hash_makeable_spec.rb
CHANGED
@@ -12,6 +12,7 @@ describe Hashmake::HashMakeable do
|
|
12
12
|
:not_reqd_float => arg_spec(:reqd => false, :type => Float, :default => NON_REQD_FLOAT_DEFAULT, :validator => ->(a){ a.between?(0.0,1.0) }),
|
13
13
|
:not_reqd_array_of_float => arg_spec_array(:reqd => false, :type => Float, :validator => ->(a){ a.between?(0.0,1.0) }),
|
14
14
|
:not_reqd_hash_of_float => arg_spec_hash(:reqd => false, :type => Float, :validator => ->(a){ a.between?(0.0,1.0) }),
|
15
|
+
:string_or_class => arg_spec(:reqd => false, :type => [String, Class], :default => "")
|
15
16
|
}
|
16
17
|
|
17
18
|
attr_accessor :not_reqd_float
|
@@ -106,6 +107,66 @@ describe Hashmake::HashMakeable do
|
|
106
107
|
a = MyTestClass.new :reqd_string => "", :not_reqd_hash_of_float => { :a => "", :b => 0.75 }
|
107
108
|
end.should raise_error(ArgumentError)
|
108
109
|
end
|
110
|
+
|
111
|
+
it 'should not care (raise error) what the hash keys are' do
|
112
|
+
expect { MyTestClass.new :reqd_string => "", :not_reqd_hash_of_float => { 0 => 0.5, "abc" => 0.75 } }.not_to raise_error
|
113
|
+
expect { MyTestClass.new :reqd_string => "", :not_reqd_hash_of_float => { Class => 0.5, Hashmake => 0.75 } }.not_to raise_error
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'multi-type arg' do
|
118
|
+
it 'should not raise error if value is one of the allowed types' do
|
119
|
+
expect { MyTestClass.new(:reqd_string => "", :string_or_class => "Hello") }.not_to raise_error
|
120
|
+
expect { MyTestClass.new(:reqd_string => "", :string_or_class => String) }.not_to raise_error
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'should raise error if value is not one of the allowed types' do
|
124
|
+
expect { MyTestClass.new(:reqd_string => "", :string_or_class => 1.2) }.to raise_error
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
context 'multi-type array container' do
|
129
|
+
it 'should not raise error if all values are one of the allowed types' do
|
130
|
+
[
|
131
|
+
["String"],
|
132
|
+
["String", String],
|
133
|
+
[String, Float, "Fixnum"],
|
134
|
+
].each do |good_values|
|
135
|
+
expect { MyTestClass.new(:reqd_string => "", :strings_or_classes => good_values) }.not_to raise_error
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'should raise error if any of the values is not one of the allowed types' do
|
140
|
+
[
|
141
|
+
[1.2],
|
142
|
+
["String", 1.2, String],
|
143
|
+
[String, 1.2, "Fixnum"],
|
144
|
+
].each do |good_values|
|
145
|
+
expect { MyTestClass.new(:reqd_string => "", :strings_or_classes => good_values) }.not_to raise_error
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
context 'multi-type hash container' do
|
151
|
+
it 'should not raise error if all values are one of the allowed types' do
|
152
|
+
[
|
153
|
+
[0 => "String"],
|
154
|
+
[0 => "String", 1 => String],
|
155
|
+
[0 => String, 1 => Float, 2 => "Fixnum"],
|
156
|
+
].each do |good_values|
|
157
|
+
expect { MyTestClass.new(:reqd_string => "", :strings_or_classes => good_values) }.not_to raise_error
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'should raise error if any of the values is not one of the allowed types' do
|
162
|
+
[
|
163
|
+
[0 => 1.2],
|
164
|
+
[0 => "String", 1 => 1.2, 2 => String],
|
165
|
+
[0 => String, 1 => 1.2, 2 => "Fixnum"],
|
166
|
+
].each do |good_values|
|
167
|
+
expect { MyTestClass.new(:reqd_string => "", :strings_or_classes => good_values) }.not_to raise_error
|
168
|
+
end
|
169
|
+
end
|
109
170
|
end
|
110
171
|
end
|
111
172
|
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.2.
|
4
|
+
version: 0.2.1
|
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-08-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -137,7 +137,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
137
137
|
version: '0'
|
138
138
|
segments:
|
139
139
|
- 0
|
140
|
-
hash: -
|
140
|
+
hash: -549260074741909705
|
141
141
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
142
|
none: false
|
143
143
|
requirements:
|
@@ -146,7 +146,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
146
146
|
version: '0'
|
147
147
|
segments:
|
148
148
|
- 0
|
149
|
-
hash: -
|
149
|
+
hash: -549260074741909705
|
150
150
|
requirements: []
|
151
151
|
rubyforge_project:
|
152
152
|
rubygems_version: 1.8.23
|