hashmake 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|