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