ratatouille 1.3.8 → 1.4.0

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