ratatouille 1.3.8 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## 1.4.0
2
+
3
+ ### Updates
4
+
5
+ * New global :skip option allows you to programmatically skip validation by passing in a value of true.
6
+ * min\_length and max\_length now call length\_between to perform validation
7
+ * is\_boolean now accepts :unwrap\_block option in addition to new :skip option
8
+ * 12 new tests
9
+
10
+ ### Corrections
11
+
12
+ * Fixed some false negatives with Array length validation
13
+ * :unwrap\_block not applicable for given\_key if :required is set to true
14
+
1
15
  ## 1.3.8
2
16
 
3
17
  ### Updates
@@ -6,21 +6,23 @@ module Ratatouille
6
6
  # Iterator method to encapsulate validation
7
7
  #
8
8
  # @note Method will NOT work without a block
9
- # @param [Hash] options
10
- # @option options [Hash] :each
11
- # options to pass to ratifier for each item in array
12
- # @option options [Integer] :min_length
13
- # @option options [Integer] :max_length
9
+ # @param [Hash] options
10
+ # Accepts global options in addition to the following:
11
+ # @option options [Hash] :name (array_item)
12
+ # Name each ratifiable object for use in validation message.
14
13
  # @return [void]
15
14
  def ratify_each(options={}, &block)
16
- if block_given?
17
- item_name = options[:name] || "array_item"
18
- @ratifiable_object.each_with_index do |obj, i|
19
- options[:name] = "#{item_name}"
20
- child_object = Ratatouille::Ratifier.new(obj, options, &block)
21
- @errors["/"] << child_object.errors unless child_object.valid?
15
+ parse_options(options)
16
+
17
+ unless @skip
18
+ if block_given?
19
+ @ratifiable_object.each_with_index do |obj, i|
20
+ options[:name] = options.fetch(:name, "array_item")
21
+ child_object = Ratatouille::Ratifier.new(obj, options, &block)
22
+ @errors["/"] << child_object.errors unless child_object.valid?
23
+ end
22
24
  end
23
- end
25
+ end#skip
24
26
  end#ratify_each
25
27
 
26
28
 
@@ -33,14 +35,7 @@ module Ratatouille
33
35
  # Useless unless block provided
34
36
  # @return [void]
35
37
  def min_length(min_size=0, options={}, &block)
36
- parse_options(options)
37
-
38
- unless @unwrap_block == true
39
- # Wrapped Validation
40
- return unless valid_min_length?(min_size)
41
- end
42
-
43
- instance_eval(&block) if block_given?
38
+ return length_between(min_size, nil, options, &block)
44
39
  rescue Exception => e
45
40
  validation_error("#{e.message}")
46
41
  end#min_length
@@ -55,14 +50,7 @@ module Ratatouille
55
50
  # Useless unless block provided
56
51
  # @return [void]
57
52
  def max_length(max_size=0, options={}, &block)
58
- parse_options(options)
59
-
60
- unless @unwrap_block == true
61
- # Wrapped Validation
62
- return unless valid_max_length?(max_size)
63
- end
64
-
65
- instance_eval(&block) if block_given?
53
+ return length_between(0, max_size, options, &block)
66
54
  rescue Exception => e
67
55
  validation_error("#{e.message}")
68
56
  end#max_length
@@ -80,73 +68,44 @@ module Ratatouille
80
68
  def length_between(min_size=0, max_size=nil, options={}, &block)
81
69
  parse_options(options)
82
70
 
83
- unless @unwrap_block == true
84
- # Wrapped Validation
85
- return unless valid_min_length?(min_size)
86
-
87
- if max_size.nil?
88
- if min_size == 1
89
- validation_error("Consider using is_not_empty")
71
+ unless @skip == true
72
+ unless @unwrap_block == true
73
+ # Minimum Length Validation
74
+ unless min_size.to_i >= 0
75
+ validation_error("min_length must be a number greater than or equal to 0")
90
76
  return
91
77
  end
92
- else
93
- return unless valid_max_length?(max_size)
94
78
 
95
- if max_size == 0 && min_size == 0
96
- validation_error("Consider using is_empty")
79
+ unless @ratifiable_object.size >= min_size.to_i
80
+ validation_error("length must be #{min_size} or more")
97
81
  return
98
82
  end
99
83
 
100
- unless max_size > min_size
101
- validation_error("max_size must be greater than min_size")
102
- return
84
+ # Maximum Length Validation
85
+ unless max_size.nil?
86
+ unless max_size.to_i >= 0
87
+ validation_error("max_size must be a number greater than or equal to 0")
88
+ return
89
+ end
90
+
91
+ if @ratifiable_object.size > max_size.to_i
92
+ validation_error("length must be less than #{max_size.to_i}")
93
+ return
94
+ end
95
+
96
+ unless max_size > min_size
97
+ validation_error("max_size must be greater than min_size")
98
+ return
99
+ end
103
100
  end
104
- end
105
- end
101
+ end#unwrap_block
106
102
 
107
- instance_eval(&block) if block_given?
103
+ instance_eval(&block) if block_given?
104
+ end#skip
108
105
  rescue Exception => e
109
106
  validation_error("#{e.message}")
110
107
  end#length_between
111
108
 
112
- private
113
-
114
- # @note Supporting Method
115
- # @return [Boolean]
116
- def valid_min_length?(min_size)
117
- unless min_size.to_i >= 0
118
- validation_error("min_length must be a number greater than or equal to 0")
119
- return false
120
- end
121
-
122
- unless @ratifiable_object.size >= min_size.to_i
123
- validation_error("length must be #{min_size} or more")
124
- return false
125
- end
126
- return true
127
- rescue Exception => e
128
- validation_error("#{e.message}")
129
- return false
130
- end
131
-
132
- # @note Supporting Method
133
- # @return [Boolean]
134
- def valid_max_length?(max_size)
135
- unless max_size.to_i >= 0
136
- validation_error("max_size must be a number greater than or equal to 0")
137
- return false
138
- end
139
-
140
- if @ratifiable_object.size > max_size.to_i
141
- validation_error("length must be less than #{max_size.to_i}")
142
- return false
143
- end
144
-
145
- return true
146
- rescue Exception => e
147
- validation_error("#{e.message}")
148
- return false
149
- end
150
109
  end#ArrayMethods
151
110
 
152
- end
111
+ end#module
@@ -24,35 +24,33 @@ module Ratatouille
24
24
  # Name of ratifiable_object for use with validation error messages.
25
25
  # @option options [Boolean] :required (false)
26
26
  # Ensure that ratifiable_object has the given key
27
+ # @return [void]
28
+ # @note :unwrap_block option not applicable if key is required
27
29
  def given_key(key, options={}, &block)
28
30
  options[:name] = options.fetch(:name, (Symbol === key ? ":#{key}" : key.to_s) )
29
31
 
30
32
  parse_options(options)
31
33
 
32
- unless @unwrap_block == true
33
- # WRAPPED VALIDATION
34
- if @required == true
35
- unless @ratifiable_object.has_key?(key)
34
+ unless @skip == true
35
+ unless @ratifiable_object.has_key?(key) # Key Not Found
36
+ if @required == true
36
37
  validation_error("Missing key #{key.inspect}")
37
38
  return
38
39
  end
39
- end
40
- end
41
-
42
- if @ratifiable_object.has_key?(key)
43
- unless @unwrap_block == true
44
- # WRAPPED VALIDATION
45
- unless @is_a.nil?
46
- unless @is_a === @ratifiable_object[key]
47
- validation_error("key value is not of type #{@is_a}")
48
- return
40
+ else # Key Found
41
+ unless @unwrap_block == true
42
+ unless @is_a.nil?
43
+ unless @is_a === @ratifiable_object[key]
44
+ validation_error("key value is not of type #{@is_a}")
45
+ return
46
+ end
49
47
  end
50
- end
51
- end
48
+ end#unwrap_block
52
49
 
53
- if block_given?
54
- child_object = Ratatouille::Ratifier.new(@ratifiable_object[key], options, &block)
55
- @errors[key] = child_object.errors unless child_object.valid?
50
+ if block_given?
51
+ child_object = Ratatouille::Ratifier.new(@ratifiable_object[key], options, &block)
52
+ @errors[key] = child_object.errors unless child_object.valid?
53
+ end
56
54
  end
57
55
  end
58
56
  rescue Exception => e
@@ -106,31 +104,33 @@ module Ratatouille
106
104
  def required_keys(options={}, &block)
107
105
  parse_options(options)
108
106
 
109
- unless @unwrap_block == true
110
- req_keys = options.fetch(:key_list, [])
107
+ unless @skip == true
108
+ unless @unwrap_block == true
109
+ req_keys = options.fetch(:key_list, [])
111
110
 
112
- # Wrapped Validation
113
- common_keys = (@ratifiable_object.keys & req_keys)
111
+ # Wrapped Validation
112
+ common_keys = (@ratifiable_object.keys & req_keys)
114
113
 
115
- if @ratifiable_object.empty?
116
- validation_error("Cannot find required keys")
117
- return
118
- end
114
+ if @ratifiable_object.empty?
115
+ validation_error("Cannot find required keys")
116
+ return
117
+ end
119
118
 
120
- if req_keys.nil? || req_keys.empty?
121
- validation_error("No required keys given to compare against.")
122
- return
123
- end
119
+ if req_keys.nil? || req_keys.empty?
120
+ validation_error("No required keys given to compare against.")
121
+ return
122
+ end
124
123
 
125
- unless common_keys.size == req_keys.size
126
- (req_keys - common_keys).each do |missed|
127
- validation_error("Missing #{missed.inspect}")
124
+ unless common_keys.size == req_keys.size
125
+ (req_keys - common_keys).each do |missed|
126
+ validation_error("Missing #{missed.inspect}")
127
+ end
128
+ return
128
129
  end
129
- return
130
130
  end
131
- end
132
131
 
133
- instance_eval(&block) if block_given?
132
+ instance_eval(&block) if block_given?
133
+ end
134
134
  rescue Exception => e
135
135
  validation_error("#{e.message}")
136
136
  end#required_keys
@@ -164,56 +164,58 @@ module Ratatouille
164
164
  def choice_of(options={}, &block)
165
165
  parse_options(options)
166
166
 
167
- unless @unwrap_block == true
168
- choice_size = options.fetch(:choice_size, 1)
169
- key_list = options.fetch(:key_list, [])
167
+ unless @skip == true
168
+ unless @unwrap_block == true
169
+ choice_size = options.fetch(:choice_size, 1)
170
+ key_list = options.fetch(:key_list, [])
170
171
 
171
- # Wrapped Validation
172
- if key_list.nil? || key_list.empty?
173
- validation_error("choice_of requires a key list to choose from")
174
- return
175
- end
176
- key_list.flatten!
172
+ # Wrapped Validation
173
+ if key_list.nil? || key_list.empty?
174
+ validation_error("choice_of requires a key list to choose from")
175
+ return
176
+ end
177
+ key_list.flatten!
178
+
179
+ # I can work with a non-zero integer or any object that responds
180
+ case choice_size
181
+ when Integer
182
+ unless choice_size > 0
183
+ validation_error("choice_of requires a positive integer for choice size")
184
+ return
185
+ end
186
+ else
187
+ unless choice_size.respond_to?(:to_i)
188
+ validation_error("choice_of requires an object that responds to :to_i for choice size")
189
+ return
190
+ end
191
+ choice_size = choice_size.to_i
192
+ end
177
193
 
178
- # I can work with a non-zero integer or any object that responds
179
- case choice_size
180
- when Integer
181
194
  unless choice_size > 0
182
- validation_error("choice_of requires a positive integer for choice size")
195
+ validation_error("choice size for choice_of must be positive non-zero number")
196
+ return
197
+ end
198
+
199
+ unless key_list.size > choice_size
200
+ validation_error("Key list size for 'choice_of' should be larger than choice size. Consider using required_keys instead.")
183
201
  return
184
202
  end
185
- else
186
- unless choice_size.respond_to?(:to_i)
187
- validation_error("choice_of requires an object that responds to :to_i for choice size")
203
+
204
+ common_keys = (@ratifiable_object.keys & key_list)
205
+ unless common_keys.size == choice_size
206
+ choices = key_list.collect{|a|
207
+ case a
208
+ when Symbol then ":#{a}"
209
+ when String then "#{a}"
210
+ end
211
+ }
212
+ validation_error("Require #{choice_size} of the following: #{choices.join(', ')}")
188
213
  return
189
214
  end
190
- choice_size = choice_size.to_i
191
- end
192
-
193
- unless choice_size > 0
194
- validation_error("choice size for choice_of must be positive non-zero number")
195
- return
196
- end
197
-
198
- unless key_list.size > choice_size
199
- validation_error("Key list size for 'choice_of' should be larger than choice size. Consider using required_keys instead.")
200
- return
201
- end
202
-
203
- common_keys = (@ratifiable_object.keys & key_list)
204
- unless common_keys.size == choice_size
205
- choices = key_list.collect{|a|
206
- case a
207
- when Symbol then ":#{a}"
208
- when String then "#{a}"
209
- end
210
- }
211
- validation_error("Require #{choice_size} of the following: #{choices.join(', ')}")
212
- return
213
- end
214
- end
215
+ end#unwrap_block
215
216
 
216
- instance_eval(&block) if block_given?
217
+ instance_eval(&block) if block_given?
218
+ end#skip
217
219
  rescue Exception => e
218
220
  validation_error("#{e.message}")
219
221
  end#choice_of
@@ -13,7 +13,7 @@ module Ratatouille
13
13
  @ratifiable_object = obj
14
14
  self.name = options[:name]
15
15
 
16
- @is_a ||= options[:is_a]
16
+ parse_options(options)
17
17
 
18
18
  case obj
19
19
  when Hash then extend Ratatouille::HashMethods
@@ -57,7 +57,7 @@ module Ratatouille
57
57
 
58
58
 
59
59
  # Add validation error. Useful for custom validations.
60
- # @param [String] str
60
+ # @param [String] err_in
61
61
  # @param [String] context
62
62
  # @return [void]
63
63
  def validation_error(err_in, context="/")
@@ -90,7 +90,7 @@ module Ratatouille
90
90
  end#cleanup_errors
91
91
 
92
92
 
93
- # @param [Hash] hsh Hash to act upon.
93
+ # @param [Hash] item Hash to act upon.
94
94
  # @return [Array]
95
95
  def errors_array(item = @errors)
96
96
  all_errs = []
@@ -150,13 +150,21 @@ module Ratatouille
150
150
  # Any other class will result in a failed validation.
151
151
  #
152
152
  # @return [Boolean]
153
- def is_boolean(&block)
154
- case @ratifiable_object
155
- when TrueClass, FalseClass
153
+ def is_boolean(options={}, &block)
154
+ parse_options(options)
155
+
156
+ unless @skip == true
157
+ unless @unwrap_block == true
158
+ case @ratifiable_object
159
+ when TrueClass, FalseClass
160
+ # OK to enter block
161
+ else
162
+ validation_error("object is not a boolean")
163
+ return
164
+ end
165
+ end
166
+
156
167
  instance_eval(&block) if block_given?
157
- else
158
- validation_error("object is not a boolean")
159
- return
160
168
  end
161
169
  rescue Exception => e
162
170
  validation_error("#{e.message}", "/")
@@ -169,12 +177,16 @@ module Ratatouille
169
177
  # @param [Hash] options
170
178
  # @option options [Class] :is_a (nil)
171
179
  # @option options [Boolean] :required (false)
180
+ # @option options [Boolean] :skip (false)
172
181
  # @option options [Boolean] :unwrap_block (false)
173
182
  # Perform block validation only -- skip method validation logic.
174
183
  def parse_options(options={})
175
- @is_a = options.fetch(:is_a, nil)
176
- @required = options.fetch(:required, false)
177
- @unwrap_block = options.fetch(:unwrap_block, false)
184
+ if Hash === options
185
+ @is_a = options.fetch(:is_a, nil)
186
+ @required = options.fetch(:required, false)
187
+ @skip = options.fetch(:skip, false)
188
+ @unwrap_block = options.fetch(:unwrap_block, false)
189
+ end
178
190
  end#parse_options
179
191
 
180
192
 
@@ -182,43 +194,39 @@ module Ratatouille
182
194
  # methods called on incorrect objects (hash validation on arrays, etc.)
183
195
  # as well as some catch-all methods for boolean validations (is_* and is_not_*)
184
196
  def method_missing(id, *args, &block)
185
- should_unwrap = false
186
- if args.first.respond_to?(:keys)
187
- if args.first.fetch(:unwrap_block, false) == true
188
- should_unwrap = true
189
- end
190
- end
191
-
192
- case
193
- when should_unwrap == true
194
- # Perform no validation logic
195
- # Skip to block evaluation
196
- when id.to_s =~ /^is_not_(.*)$/
197
- if @ratifiable_object.respond_to?("#{$1}?")
198
- if @ratifiable_object.send("#{$1}?") == true
199
- validation_error("is #{$1}")
200
- return
197
+ parse_options(args.first)
198
+
199
+ unless @skip == true
200
+ case
201
+ when @unwrap_block == true
202
+ # Perform no validation logic
203
+ # Skip to block evaluation
204
+ when id.to_s =~ /^is_not_(.*)$/
205
+ if @ratifiable_object.respond_to?("#{$1}?")
206
+ if @ratifiable_object.send("#{$1}?") == true
207
+ validation_error("is #{$1}")
208
+ return
209
+ end
201
210
  end
202
- end
203
- when id.to_s =~ /^is_(.*)$/
204
- if @ratifiable_object.respond_to?("#{$1}?")
205
- if @ratifiable_object.send("#{$1}?") == false
206
- validation_error("is not #{$1}")
211
+ when id.to_s =~ /^is_(.*)$/
212
+ if @ratifiable_object.respond_to?("#{$1}?")
213
+ if @ratifiable_object.send("#{$1}?") == false
214
+ validation_error("is not #{$1}")
215
+ return
216
+ end
217
+ end
218
+ else
219
+ begin
220
+ super
207
221
  return
222
+ rescue Exception => e
223
+ validation_error("#{id} is not supported for the given object (#{@ratifiable_object.class})")
224
+ return e
208
225
  end
209
226
  end
210
- else
211
- begin
212
- super
213
- return
214
- rescue Exception => e
215
- validation_error("#{id} is not supported for the given object (#{@ratifiable_object.class})")
216
- return e
217
- end
218
- end
219
227
 
220
- instance_eval(&block) if block_given?
221
- return
228
+ instance_eval(&block) if block_given?
229
+ end#skip
222
230
  end#method_missing
223
231
 
224
232
 
@@ -1,4 +1,4 @@
1
1
  module Ratatouille
2
2
  # Gem Version
3
- VERSION = "1.3.8"
3
+ VERSION = "1.4.0"
4
4
  end
@@ -14,130 +14,178 @@ describe "Ratatouille::ArrayMethods" do
14
14
  end
15
15
 
16
16
  describe "ratify_each" do
17
- it "should set block name to name in options" do
18
- n = ""
19
- RatifierTest.new(['foo', 'bar']) do
20
- ratify_each { n = name }
17
+ context "with default options" do
18
+ it "should set block name to name in options" do
19
+ n = ""
20
+ RatifierTest.new(['foo', 'bar']) do
21
+ ratify_each { n = name }
22
+ end
23
+ n.should match /^(array_item)/i
24
+
25
+ RatifierTest.new(['foo', 'bar']) do
26
+ ratify_each(:name => "foo") { n = name }
27
+ end
28
+ n.should match /^foo/i
21
29
  end
22
- n.should match /^(array_item)/i
23
30
 
24
- RatifierTest.new(['foo', 'bar']) do
25
- ratify_each(:name => "foo") { n = name }
31
+ it "should be invalid for given array" do
32
+ r = RatifierTest.new(['bar', 'biz']) do
33
+ ratify_each(:is_a => String) do
34
+ validation_error("#{ro} is not 'bang'") unless ro == 'bang'
35
+ end
36
+ end
37
+ r.errors_array.length.should == 2
26
38
  end
27
- n.should match /^foo/i
28
- end
29
39
 
30
- it "should be invalid for given array" do
31
- r = RatifierTest.new(['bar', 'biz']) do
32
- ratify_each(:is_a => String) do
33
- validation_error("#{ro} is not 'bang'") unless ro == 'bang'
40
+ it "should be valid for given array" do
41
+ r = RatifierTest.new(['bar', 'biz']) do
42
+ ratify_each(:is_a => String) do
43
+ validation_error("too short") unless ro.size > 2
44
+ end
34
45
  end
46
+ r.should be_valid
35
47
  end
36
- r.errors_array.length.should == 2
37
48
  end
38
49
 
39
- it "should be valid for given array" do
40
- r = RatifierTest.new(['bar', 'biz']) do
41
- ratify_each(:is_a => String) do
42
- validation_error("too short") unless ro.size > 2
50
+ context "with :skip => true" do
51
+ it "should not enter block" do
52
+ n = false
53
+ RatifierTest.new(['foo', 'bar']) do
54
+ ratify_each(:skip => true) { n = true }
43
55
  end
56
+ n.should be_false
44
57
  end
45
- r.should be_valid
46
58
  end
47
59
  end
48
60
 
49
61
  describe "is_empty" do
50
- it "should not be valid for non-empty array" do
51
- RatifierTest.new(['bar']){ is_empty }.should_not be_valid
62
+ context "with default options" do
63
+ it "should not be valid for non-empty array" do
64
+ RatifierTest.new(['bar']){ is_empty }.should_not be_valid
65
+ end
66
+
67
+ it "should be valid for empty array" do
68
+ RatifierTest.new([]){ is_empty }.should be_valid
69
+ end
52
70
  end
53
71
 
54
- it "should be valid for empty array" do
55
- RatifierTest.new([]){ is_empty }.should be_valid
72
+ context "with :skip => true" do
73
+ it "should not run validation" do
74
+ RatifierTest.new(['bar']){ is_empty(:skip => true) }.should be_valid
75
+ end
56
76
  end
57
77
  end
58
78
 
59
79
  describe "is_not_empty" do
60
- it "should be valid for non-empty array" do
61
- RatifierTest.new(['bar']){ is_not_empty }.should be_valid
80
+ context "with default options" do
81
+ it "should be valid for non-empty array" do
82
+ RatifierTest.new(['bar']){ is_not_empty }.should be_valid
83
+ end
84
+
85
+ it "should not be valid for empty array" do
86
+ RatifierTest.new([]){ is_not_empty }.should_not be_valid
87
+ end
62
88
  end
63
89
 
64
- it "should not be valid for empty array" do
65
- RatifierTest.new([]){ is_not_empty }.should_not be_valid
90
+ context "with :skip => true" do
91
+ it "should not run validation" do
92
+ RatifierTest.new([]){ is_not_empty(:skip => true) }.should be_valid
93
+ end
66
94
  end
67
95
  end
68
96
 
69
97
  describe "length_between" do
70
- describe "for empty array" do
71
- before(:each) do
72
- @arr = []
73
- end
98
+ let(:empty_array) { [] }
99
+ let(:one_element_array) { ['foo'] }
100
+ let(:two_element_array) { ['foo', 'bar'] }
101
+
102
+ context "with default options" do
103
+ context "for an empty array" do
104
+ it "should be valid with 0 min length and any positive, non-zero max_length" do
105
+ RatifierTest.new(empty_array) { length_between(0) }.should be_valid
106
+ RatifierTest.new(empty_array) { length_between(0, 0) }.should_not be_valid
107
+ RatifierTest.new(empty_array) { length_between(0, 1) }.should be_valid
108
+ end
74
109
 
75
- it "should be valid with 0 min length and any positive, non-zero max_length" do
76
- RatifierTest.new(@arr) { length_between(0) }.should be_valid
77
- RatifierTest.new(@arr) { length_between(0, 0) }.should_not be_valid
78
- RatifierTest.new(@arr) { length_between(0, 1) }.should be_valid
110
+ it "should be invalid with 1 min_length and any max_length" do
111
+ RatifierTest.new(empty_array) { length_between(1) }.should_not be_valid
112
+ RatifierTest.new(empty_array) { length_between(1,1) }.should_not be_valid
113
+ RatifierTest.new(empty_array) { length_between(1,2) }.should_not be_valid
114
+ end
79
115
  end
80
116
 
81
- it "should be invalid with 1 min_length and any max_length" do
82
- RatifierTest.new(@arr) { length_between(1) }.should_not be_valid
83
- RatifierTest.new(@arr) { length_between(1,1) }.should_not be_valid
84
- RatifierTest.new(@arr) { length_between(1,2) }.should_not be_valid
117
+ context "for a two-element array" do
118
+ it "should be valid with 1 min_length and any max_length above 1" do
119
+ RatifierTest.new(two_element_array) { length_between(1,1) }.should_not be_valid
120
+ RatifierTest.new(two_element_array) { length_between(1,2) }.should be_valid
121
+ end
122
+
123
+ it "should be invalid with 0 min_length and any max_length less than 2" do
124
+ RatifierTest.new(two_element_array) { length_between(0,0) }.should_not be_valid
125
+ RatifierTest.new(two_element_array) { length_between(0,1) }.should_not be_valid
126
+ RatifierTest.new(two_element_array) { length_between(0,2) }.should be_valid
127
+ end
85
128
  end
86
129
  end
87
130
 
88
- describe "for Array with 2 elements" do
89
- before(:each) do
90
- @arr = ['foo', 'bar']
91
- end
92
-
93
- it "should be valid with 1 min_length and any max_length above 1" do
94
- RatifierTest.new(@arr) { length_between(1,1) }.should_not be_valid
95
- RatifierTest.new(@arr) { length_between(1,2) }.should be_valid
96
- end
97
-
98
- it "should be invalid with 0 min_length and any max_length less than 2" do
99
- RatifierTest.new(@arr) { length_between(0,0) }.should_not be_valid
100
- RatifierTest.new(@arr) { length_between(0,1) }.should_not be_valid
101
- RatifierTest.new(@arr) { length_between(0,2) }.should be_valid
131
+ context "with :skip => true" do
132
+ it "should be valid if validation says otherwise" do
133
+ RatifierTest.new(empty_array) { length_between(1,2, :skip => true) }.should be_valid
102
134
  end
103
135
  end
104
136
  end
105
137
 
106
138
  describe "max_length" do
107
- it "should be valid for proper length array with integer argument" do
108
- RatifierTest.new([]) { max_length(1) }.should be_valid
109
- RatifierTest.new(['foo']) { max_length(1) }.should be_valid
139
+ context "with default options" do
140
+ it "should be valid for proper length array with integer argument" do
141
+ RatifierTest.new([]) { max_length(1) }.should be_valid
142
+ RatifierTest.new(['foo']) { max_length(1) }.should be_valid
110
143
 
111
- RatifierTest.new(['foo']) { max_length(0) }.should_not be_valid
112
- end
144
+ RatifierTest.new(['foo']) { max_length(0) }.should_not be_valid
145
+ end
113
146
 
114
- it "should be invalid for non-numeric length" do
115
- RatifierTest.new([]) { max_length({}) }.should_not be_valid
147
+ it "should be invalid for non-numeric length" do
148
+ RatifierTest.new([]) { max_length({}) }.should_not be_valid
149
+ end
150
+
151
+ it "should be valid for properly transformed float values" do
152
+ RatifierTest.new(['foo']) { max_length(0.3) }.should_not be_valid
153
+ RatifierTest.new(['foo']) { max_length(1.3) }.should be_valid
154
+ RatifierTest.new(['foo', 'bar']) { max_length(1.3) }.should_not be_valid
155
+ end
116
156
  end
117
157
 
118
- it "should be valid for properly transformed float values" do
119
- RatifierTest.new(['foo']) { max_length(0.3) }.should_not be_valid
120
- RatifierTest.new(['foo']) { max_length(1.3) }.should be_valid
121
- RatifierTest.new(['foo', 'bar']) { max_length(1.3) }.should_not be_valid
158
+ context "with :skip => true" do
159
+ it "should be valid when validation would say otherwise" do
160
+ RatifierTest.new(['foo', 'bar']) { max_length(1, :skip => true) }.should be_valid
161
+ end
122
162
  end
123
- end
163
+ end#max_length
124
164
 
125
165
  describe "min_length" do
126
- it "should be valid for proper length array with integer argument" do
127
- RatifierTest.new([]) { min_length(0) }.should be_valid
128
- RatifierTest.new([]) { min_length(1) }.should_not be_valid
166
+ context "with default options" do
167
+ it "should be valid for proper length array with integer argument" do
168
+ RatifierTest.new([]) { min_length(0) }.should be_valid
169
+ RatifierTest.new([]) { min_length(1) }.should_not be_valid
129
170
 
130
- RatifierTest.new(['foo']) { min_length(0) }.should be_valid
131
- RatifierTest.new(['foo']) { min_length(1) }.should be_valid
132
- end
171
+ RatifierTest.new(['foo']) { min_length(0) }.should be_valid
172
+ RatifierTest.new(['foo']) { min_length(1) }.should be_valid
173
+ end
174
+
175
+ it "should be invalid for non-numeric length" do
176
+ RatifierTest.new([]) { min_length({}) }.should_not be_valid
177
+ end
133
178
 
134
- it "should be invalid for non-numeric length" do
135
- RatifierTest.new([]) { min_length({}) }.should_not be_valid
179
+ it "should be valid for properly transformed float values" do
180
+ RatifierTest.new([]) { min_length(0.3) }.should be_valid
181
+ RatifierTest.new([]) { min_length(1.3) }.should_not be_valid
182
+ end
136
183
  end
137
184
 
138
- it "should be valid for properly transformed float values" do
139
- RatifierTest.new([]) { min_length(0.3) }.should be_valid
140
- RatifierTest.new([]) { min_length(1.3) }.should_not be_valid
185
+ context "with :skip => true" do
186
+ it "should not perform validation" do
187
+ RatifierTest.new([]) { min_length(1, :skip => true) }.should be_valid
188
+ end
141
189
  end
142
- end
190
+ end#min_length
143
191
  end
@@ -1,6 +1,8 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe "Ratatouille::HashMethods" do
4
+ let(:empty_hash) { {} }
5
+
4
6
  [ :choice_of,
5
7
  :required_keys,
6
8
  :required_key,
@@ -20,7 +22,7 @@ describe "Ratatouille::HashMethods" do
20
22
  end
21
23
 
22
24
  it "should be valid for empty Hash" do
23
- RatifierTest.new({}){ is_empty }.should be_valid
25
+ RatifierTest.new(empty_hash){ is_empty }.should be_valid
24
26
  end
25
27
 
26
28
  describe "when :unwrap_block is true" do
@@ -40,12 +42,12 @@ describe "Ratatouille::HashMethods" do
40
42
  end
41
43
 
42
44
  it "should not be valid for empty hash" do
43
- RatifierTest.new({}){ is_not_empty }.should_not be_valid
45
+ RatifierTest.new(empty_hash){ is_not_empty }.should_not be_valid
44
46
  end
45
47
 
46
48
  describe "when :unwrap_block is true" do
47
49
  it "should be valid for empty hash" do
48
- RatifierTest.new({}){
50
+ RatifierTest.new(empty_hash){
49
51
  is_not_empty(:unwrap_block => true) do
50
52
  # Nothing to validate, wrapper ignored
51
53
  end
@@ -56,139 +58,163 @@ describe "Ratatouille::HashMethods" do
56
58
  end
57
59
 
58
60
  describe "choice_of" do
59
- it "should be valid with no :choice_size given" do
60
- RatifierTest.new({:foo => "bar"}) {
61
- choice_of(:key_list => [:foo, :bar])
62
- }.should be_valid
63
- end
61
+ context "with default options" do
62
+ it "should be valid with no :choice_size given" do
63
+ RatifierTest.new({:foo => "bar"}) {
64
+ choice_of(:key_list => [:foo, :bar])
65
+ }.should be_valid
66
+ end
64
67
 
65
- it "should be invalid if key list is empty" do
66
- RatifierTest.new({}) {
67
- choice_of(:choice_size => 1, :key_list => [])
68
- }.should_not be_valid
69
- end
68
+ it "should be invalid if key list is empty" do
69
+ RatifierTest.new(empty_hash) {
70
+ choice_of(:choice_size => 1, :key_list => [])
71
+ }.should_not be_valid
72
+ end
70
73
 
71
- it "should be invalid if choice size less than 1" do
72
- RatifierTest.new({}) {
73
- choice_of(:choice_size => 0, :key_list => [:foo])
74
- }.should_not be_valid
75
- end
74
+ it "should be invalid if choice size less than 1" do
75
+ RatifierTest.new(empty_hash) {
76
+ choice_of(:choice_size => 0, :key_list => [:foo])
77
+ }.should_not be_valid
78
+ end
76
79
 
77
- it "should be invalid if choice list is not 1 more than choice size" do
78
- RatifierTest.new({}) {
79
- choice_of(:choice_size => 1, :key_list => [:foo])
80
- }.should_not be_valid
81
- end
80
+ it "should be invalid if choice list is not 1 more than choice size" do
81
+ RatifierTest.new(empty_hash) {
82
+ choice_of(:choice_size => 1, :key_list => [:foo])
83
+ }.should_not be_valid
84
+ end
82
85
 
83
- it "should be valid when given hash has 1 key in a choice list of 2 or more" do
84
- RatifierTest.new({:foo => "bar"}){
85
- choice_of(:key_list => [:foo, :bar])
86
- }.should be_valid
87
- end
86
+ it "should be valid when given hash has 1 key in a choice list of 2 or more" do
87
+ RatifierTest.new({:foo => "bar"}){
88
+ choice_of(:key_list => [:foo, :bar])
89
+ }.should be_valid
90
+ end
88
91
 
89
- it "should be valid when given hash has 2 keys in choice list of 3 or more" do
90
- RatifierTest.new({:foo => "foo", :bar => "bar"}){
91
- choice_of(:choice_size => 2, :key_list => [:foo, :bar, :biz])
92
- }.should be_valid
92
+ it "should be valid when given hash has 2 keys in choice list of 3 or more" do
93
+ RatifierTest.new({:foo => "foo", :bar => "bar"}){
94
+ choice_of(:choice_size => 2, :key_list => [:foo, :bar, :biz])
95
+ }.should be_valid
93
96
 
94
- RatifierTest.new({:foo => "foo", :bar => "bar"}){
95
- choice_of(:choice_size => 2, :key_list => [:foo, :bar, :biz, :bang])
96
- }.should be_valid
97
+ RatifierTest.new({:foo => "foo", :bar => "bar"}){
98
+ choice_of(:choice_size => 2, :key_list => [:foo, :bar, :biz, :bang])
99
+ }.should be_valid
100
+ end
97
101
  end
98
102
 
99
- describe "when :unwrap_block is true" do
103
+ context "with :unwrap_block => true" do
100
104
  it "should be valid when used on empty Hash" do
101
- RatifierTest.new({}){
105
+ RatifierTest.new(empty_hash){
102
106
  choice_of(:key_list => [:foo, :bar], :unwrap_block => true) do
103
107
  # Nothing to validate, wrapper ignored
104
108
  end
105
109
  }.should be_valid
106
110
 
107
- RatifierTest.new({}){
111
+ RatifierTest.new(empty_hash){
108
112
  choice_of(:key_list => [:foo, :bar]) do
109
113
  # Nothing to validate, wrapper ignored
110
114
  end
111
115
  }.should_not be_valid
112
116
  end
113
117
  end
118
+
119
+ context "with :skip => true" do
120
+ context "with empty hash" do
121
+ it "should be valid" do
122
+ RatifierTest.new(empty_hash){
123
+ choice_of(:key_list => [:foo, :bar], :skip => true)
124
+ }.should be_valid
125
+ end
126
+ end
127
+ end
114
128
  end
115
129
 
116
130
  describe "required_keys" do
117
- it "should be valid if Hash contains all required keys" do
118
- RatifierTest.new({:foo => "foo"}) {
119
- required_keys(:key_list => [:foo, :bar])
120
- }.should_not be_valid
131
+ context "with default options" do
132
+ it "should be valid if Hash contains all required keys" do
133
+ RatifierTest.new({:foo => "foo", :bar => "bar"}) {
134
+ required_keys(:key_list => [:foo, :bar])
135
+ }.should be_valid
136
+ end
121
137
 
122
- RatifierTest.new({:foo => "foo", :bar => "bar"}) {
123
- required_keys(:key_list => [:foo, :bar])
124
- }.should be_valid
125
- end
138
+ it "should be invalid if Hash is empty and key list is not" do
139
+ RatifierTest.new(empty_hash) {
140
+ required_keys(:key_list => [:foo])
141
+ }.should_not be_valid
142
+ end
126
143
 
127
- it "should be invalid if Hash is empty and key list is not" do
128
- RatifierTest.new({}) {
129
- required_keys(:key_list => [:foo])
130
- }.should_not be_valid
144
+ it "should be invalid if Hash does not contain ALL keys in key list" do
145
+ RatifierTest.new({:foo => "foo"}) {
146
+ required_keys(:key_list => [:foo, :bar])
147
+ }.should_not be_valid
148
+ end
131
149
  end
132
150
 
133
- it "should be invalid if Hash does not contain ALL keys in key list" do
134
- RatifierTest.new({:foo => "foo"}) {
135
- required_keys(:key_list => [:foo, :bar])
136
- }.should_not be_valid
151
+ context "with :unwrap_block => true" do
152
+ context "when used on empty Hash" do
153
+ it "should be valid" do
154
+ RatifierTest.new(empty_hash){
155
+ required_keys(:key_list => [:foo, :bar], :unwrap_block => true) {}
156
+ }.should be_valid
157
+ end
158
+
159
+ it "should enter block with required keys" do
160
+ entered_block = false
161
+ RatifierTest.new(empty_hash){
162
+ required_keys(:key_list => [:foo, :bar], :unwrap_block => true) do
163
+ entered_block = true
164
+ end
165
+ }
166
+ entered_block.should be_true
167
+ end
168
+ end
137
169
  end
138
170
 
139
- describe "when :unwrap_block is true" do
140
- it "should be valid when used on empty Hash" do
141
- RatifierTest.new({}){
142
- required_keys(:key_list => [:foo, :bar], :unwrap_block => true) do
143
- # Nothing to validate, wrapper ignored
144
- end
171
+ context "with :skip => true" do
172
+ it "should be valid if Hash does not contain all required keys" do
173
+ RatifierTest.new({:foo => "foo"}) {
174
+ required_keys(:key_list => [:foo, :bar], :skip => true)
145
175
  }.should be_valid
146
-
147
- RatifierTest.new({}){
148
- required_keys(:key_list => [:foo, :bar]) do
149
- # Nothing to validate, wrapper ignored
150
- end
151
- }.should_not be_valid
152
176
  end
153
177
  end
154
178
  end
155
179
 
156
180
  describe "required_key" do
157
- it "should be invalid when given a key for an empty hash" do
158
- RatifierTest.new({}){ required_key(:foo) }.should_not be_valid
159
- end
181
+ context "with default options" do
182
+ it "should be invalid when given a key for an empty hash" do
183
+ RatifierTest.new({}){ required_key(:foo) }.should_not be_valid
184
+ end
160
185
 
161
- it "should be invalid when given a key that doesn't exist in the hash" do
162
- RatifierTest.new({:foo => "foo"}){ required_key(:bar) }.should_not be_valid
163
- end
186
+ it "should be invalid when given a key that doesn't exist in the hash" do
187
+ RatifierTest.new({:foo => "foo"}){ required_key(:bar) }.should_not be_valid
188
+ end
164
189
 
165
- it "should not progress into block if invalid" do
166
- f = false
167
- RatifierTest.new({}) do
168
- required_key(:foo) { f = true }
190
+ it "should not progress into block if invalid" do
191
+ f = false
192
+ RatifierTest.new({}) do
193
+ required_key(:foo) { f = true }
194
+ end
195
+ f.should be_false
169
196
  end
170
- f.should be_false
171
- end
172
197
 
173
- it "should change the scope name to default to the key if no name passed as option" do
174
- n = ""
175
- RatifierTest.new({:foo => "bar"}) do
176
- required_key(:foo) { n = name }
198
+ it "should change the scope name to default to the key if no name passed as option" do
199
+ n = ""
200
+ RatifierTest.new({:foo => "bar"}) do
201
+ required_key(:foo) { n = name }
202
+ end
203
+ n.should == ":foo"
177
204
  end
178
- n.should == ":foo"
179
205
  end
180
206
 
181
- describe "when :unwrap_block is true" do
182
- it "should be valid when used on empty Hash" do
207
+ context "with :unwrap_block => true" do
208
+ it "should be invalid when used on empty Hash" do
183
209
  RatifierTest.new({}){
184
210
  required_key(:foo, :unwrap_block => true) do
185
211
  # Nothing to validate, wrapper ignored
186
212
  end
187
- }.should be_valid
213
+ }.should_not be_valid
188
214
  end
189
215
  end
190
216
 
191
- describe "when :is_a is given" do
217
+ describe "with :is_a" do
192
218
  it "should be valid with matching key value class" do
193
219
  RatifierTest.new({:foo => "bar"}){
194
220
  required_key(:foo, :class => String) do
@@ -144,15 +144,43 @@ describe Ratatouille::Ratifier do
144
144
  end
145
145
 
146
146
  describe "is_boolean" do
147
- [true, false].each do |b|
148
- it "should enter block for #{b} value" do
147
+ context "with default options" do
148
+ [true, false].each do |b|
149
+ it "should enter block for #{b} value" do
150
+ block_entered = false
151
+ RatifierTest.new(b) do
152
+ is_boolean { block_entered = true }
153
+ end
154
+ block_entered.should be_true
155
+ end
156
+ end
157
+
158
+ it "should not enter block for non-boolean value" do
149
159
  block_entered = false
150
- RatifierTest.new(b) do
160
+ RatifierTest.new("foo") do
151
161
  is_boolean { block_entered = true }
152
162
  end
163
+ block_entered.should be_false
164
+ end
165
+ end
166
+
167
+ context "with :unwrap_block => true" do
168
+ it "should enter block if ratifiable object is NOT boolean" do
169
+ block_entered = false
170
+ RatifierTest.new("foo") do
171
+ is_boolean(:unwrap_block => true) { block_entered = true }
172
+ end
153
173
  block_entered.should be_true
154
174
  end
155
175
  end
176
+
177
+ context "with :skip => true" do
178
+ it "should be valid even if validation says otherwise" do
179
+ RatifierTest.new("foo") {
180
+ is_boolean(:skip => true)
181
+ }.should be_valid
182
+ end
183
+ end
156
184
  end
157
185
 
158
186
  describe "name" do
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ratatouille
3
3
  version: !ruby/object:Gem::Version
4
- hash: 11
4
+ hash: 7
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
- - 3
9
- - 8
10
- version: 1.3.8
8
+ - 4
9
+ - 0
10
+ version: 1.4.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ryan Johnson
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-05-06 00:00:00 Z
18
+ date: 2012-05-23 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: rspec
@@ -123,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
123
123
  requirements: []
124
124
 
125
125
  rubyforge_project: ratatouille
126
- rubygems_version: 1.8.10
126
+ rubygems_version: 1.8.24
127
127
  signing_key:
128
128
  specification_version: 3
129
129
  summary: DSL for validating complex hashes