hashmake 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.
@@ -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
@@ -42,7 +42,13 @@ class ArgSpec
42
42
  new_args = DEFAULT_ARGS.merge(hashed_args)
43
43
 
44
44
  @type = new_args[:type]
45
- raise ArgumentError, "#{@type} is not a Class" unless @type.is_a?(Class)
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
- 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
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
- return val
77
- end
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
@@ -4,5 +4,5 @@
4
4
  #
5
5
  module Hashmake
6
6
  # hashmake version
7
- VERSION = "0.2.0"
7
+ VERSION = "0.2.1"
8
8
  end
@@ -1,51 +1,74 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
3
  describe Hashmake::ArgSpec do
4
- it 'should raise ArgumentError if :reqd is false and no :default value is given' do
5
- hash = {
6
- :reqd => false, :key => :some_variable, :type => String
7
- }
8
-
9
- lambda { Hashmake::ArgSpec.new hash }.should raise_error(ArgumentError)
10
- end
11
-
12
- it 'should not raise ArgumentError if :reqd is false and a :default value is given' do
13
- hash = {
14
- :reqd => false, :key => :some_variable, :type => String, :default => ""
15
- }
16
-
17
- lambda { Hashmake::ArgSpec.new hash }.should_not raise_error(ArgumentError)
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
- 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
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 valid' do
33
- it 'should raise ArgumentError' do
34
- lambda { @arg_spec.validate_value 0 }.should raise_error(ArgumentError)
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 '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)
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 valid' do
68
+ context 'value given is not one of the correct types' do
47
69
  it 'should raise ArgumentError' do
48
- lambda { @arg_spec.validate_value 0.0 }.should raise_error(ArgumentError)
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
@@ -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.0
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-07-03 00:00:00.000000000 Z
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: -4514910862506440485
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: -4514910862506440485
149
+ hash: -549260074741909705
150
150
  requirements: []
151
151
  rubyforge_project:
152
152
  rubygems_version: 1.8.23