ratatouille 1.0.0 → 1.2.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/.gitignore +1 -0
- data/.travis-yml +2 -2
- data/README.md +4 -1
- data/lib/ratatouille/array.rb +10 -4
- data/lib/ratatouille/hash.rb +44 -10
- data/lib/ratatouille/ratifier.rb +26 -3
- data/lib/ratatouille/version.rb +1 -1
- data/lib/ratatouille.rb +3 -2
- data/spec/lib/ratatouille/hash_spec.rb +46 -2
- data/spec/lib/ratatouille/ratifier_spec.rb +30 -0
- metadata +3 -4
- data/.rvmrc +0 -1
data/.gitignore
CHANGED
data/.travis-yml
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,10 @@
|
|
1
|
-
# Ratatouille
|
1
|
+
# Ratatouille
|
2
2
|
|
3
3
|
DSL for validation of complex Hashes
|
4
4
|
|
5
|
+
## Travis CI Status:
|
6
|
+
[](http://travis-ci.org/CITguy/ratatouille)
|
7
|
+
|
5
8
|
## Installation
|
6
9
|
|
7
10
|
Add this line to your application's Gemfile:
|
data/lib/ratatouille/array.rb
CHANGED
@@ -5,22 +5,26 @@ module Ratatouille
|
|
5
5
|
# @return [void]
|
6
6
|
def is_empty(&block)
|
7
7
|
unless @ratifiable_object.empty?
|
8
|
-
validation_error("
|
8
|
+
validation_error("not empty")
|
9
9
|
return
|
10
10
|
end
|
11
11
|
|
12
12
|
instance_eval(&block) if block_given?
|
13
|
+
rescue Exception => e
|
14
|
+
validation_error("#{e.message}")
|
13
15
|
end#is_empty
|
14
16
|
|
15
17
|
|
16
18
|
# @return [void]
|
17
19
|
def is_not_empty(&block)
|
18
20
|
if @ratifiable_object.empty?
|
19
|
-
validation_error("
|
21
|
+
validation_error("empty")
|
20
22
|
return
|
21
23
|
end
|
22
24
|
|
23
25
|
instance_eval(&block) if block_given?
|
26
|
+
rescue Exception => e
|
27
|
+
validation_error("#{e.message}")
|
24
28
|
end#is_not_empty
|
25
29
|
|
26
30
|
|
@@ -78,6 +82,8 @@ module Ratatouille
|
|
78
82
|
end
|
79
83
|
|
80
84
|
instance_eval(&block) if block_given?
|
85
|
+
rescue Exception => e
|
86
|
+
validation_error("#{e.message}")
|
81
87
|
end#length_between
|
82
88
|
private
|
83
89
|
|
@@ -89,7 +95,7 @@ module Ratatouille
|
|
89
95
|
end
|
90
96
|
|
91
97
|
unless @ratifiable_object.size >= min_size.to_i
|
92
|
-
validation_error("
|
98
|
+
validation_error("length must be #{min_size} or more")
|
93
99
|
return false
|
94
100
|
end
|
95
101
|
return true
|
@@ -106,7 +112,7 @@ module Ratatouille
|
|
106
112
|
end
|
107
113
|
|
108
114
|
if @ratifiable_object.size > max_size.to_i
|
109
|
-
validation_error("
|
115
|
+
validation_error("length must be less than #{max_size.to_i}")
|
110
116
|
return false
|
111
117
|
end
|
112
118
|
|
data/lib/ratatouille/hash.rb
CHANGED
@@ -5,33 +5,42 @@ module Ratatouille
|
|
5
5
|
# Runs validation in block against object for the given key.
|
6
6
|
#
|
7
7
|
# @param [String, Symbol] key
|
8
|
-
|
8
|
+
# @param [Hash] options
|
9
|
+
def given_key(key, options={}, &block)
|
10
|
+
options[:name] = options.fetch(:name, (Symbol === key ? ":#{key}" : key.to_s) )
|
11
|
+
|
9
12
|
if @ratifiable_object.has_key?(key) && block_given?
|
10
|
-
child_object = Ratatouille::Ratifier.new(@ratifiable_object[key], &block)
|
13
|
+
child_object = Ratatouille::Ratifier.new(@ratifiable_object[key], options, &block)
|
11
14
|
@errors[key] = child_object.errors unless child_object.valid?
|
12
15
|
end
|
16
|
+
rescue Exception => e
|
17
|
+
validation_error("#{e.message}")
|
13
18
|
end#given_key
|
14
19
|
|
15
20
|
|
16
21
|
# @return [void]
|
17
22
|
def is_empty(&block)
|
18
23
|
unless @ratifiable_object.empty?
|
19
|
-
validation_error("
|
24
|
+
validation_error("not empty")
|
20
25
|
return
|
21
26
|
end
|
22
27
|
|
23
28
|
instance_eval(&block) if block_given?
|
29
|
+
rescue Exception => e
|
30
|
+
validation_error("#{e.message}")
|
24
31
|
end#is_empty
|
25
32
|
|
26
33
|
|
27
34
|
# @return [void]
|
28
35
|
def is_not_empty(&block)
|
29
36
|
if @ratifiable_object.empty?
|
30
|
-
validation_error("
|
37
|
+
validation_error("empty")
|
31
38
|
return
|
32
39
|
end
|
33
40
|
|
34
41
|
instance_eval(&block) if block_given?
|
42
|
+
rescue Exception => e
|
43
|
+
validation_error("#{e.message}")
|
35
44
|
end#is_not_empty
|
36
45
|
|
37
46
|
|
@@ -44,12 +53,12 @@ module Ratatouille
|
|
44
53
|
common_keys = (@ratifiable_object.keys & req_keys)
|
45
54
|
|
46
55
|
if @ratifiable_object.empty?
|
47
|
-
validation_error("Cannot find required keys
|
56
|
+
validation_error("Cannot find required keys")
|
48
57
|
return
|
49
58
|
end
|
50
59
|
|
51
60
|
if req_keys.nil? || req_keys.empty?
|
52
|
-
validation_error("No required keys given to compare
|
61
|
+
validation_error("No required keys given to compare against.")
|
53
62
|
return
|
54
63
|
end
|
55
64
|
|
@@ -66,6 +75,8 @@ module Ratatouille
|
|
66
75
|
end
|
67
76
|
|
68
77
|
instance_eval(&block) if block_given?
|
78
|
+
rescue Exception => e
|
79
|
+
validation_error("#{e.message}")
|
69
80
|
end#required_keys
|
70
81
|
|
71
82
|
|
@@ -79,13 +90,29 @@ module Ratatouille
|
|
79
90
|
# All other values are ignored.
|
80
91
|
# @return [void]
|
81
92
|
def choice_of(choice_size=1, *key_list, &block)
|
82
|
-
|
93
|
+
if key_list.nil? || key_list.empty?
|
83
94
|
validation_error("choice_of requires a key list to choose from")
|
84
95
|
return
|
85
96
|
end
|
97
|
+
key_list.flatten!
|
98
|
+
|
99
|
+
# I can work with a non-zero integer or any object that responds
|
100
|
+
case choice_size
|
101
|
+
when Integer
|
102
|
+
unless choice_size > 0
|
103
|
+
validation_error("choice_of requires a positive integer for choice size")
|
104
|
+
return
|
105
|
+
end
|
106
|
+
else
|
107
|
+
unless choice_size.respond_to?(:to_i)
|
108
|
+
validation_error("choice_of requires an object that responds to :to_i for choice size")
|
109
|
+
return
|
110
|
+
end
|
111
|
+
choice_size = choice_size.to_i
|
112
|
+
end
|
86
113
|
|
87
|
-
unless choice_size
|
88
|
-
validation_error("choice_of
|
114
|
+
unless choice_size > 0
|
115
|
+
validation_error("choice size for choice_of must be positive non-zero number")
|
89
116
|
return
|
90
117
|
end
|
91
118
|
|
@@ -96,12 +123,19 @@ module Ratatouille
|
|
96
123
|
|
97
124
|
common_keys = (@ratifiable_object.keys & key_list)
|
98
125
|
unless common_keys.size == choice_size
|
99
|
-
choices = key_list.collect{|a|
|
126
|
+
choices = key_list.collect{|a|
|
127
|
+
case a
|
128
|
+
when Symbol then ":#{a}"
|
129
|
+
when String then "#{a}"
|
130
|
+
end
|
131
|
+
}
|
100
132
|
validation_error("Require #{choice_size} of the following: #{choices.join(', ')}")
|
101
133
|
return
|
102
134
|
end
|
103
135
|
|
104
136
|
instance_eval(&block) if block_given?
|
137
|
+
rescue Exception => e
|
138
|
+
validation_error("#{e.message}")
|
105
139
|
end#choice_of
|
106
140
|
end#HashMethods
|
107
141
|
|
data/lib/ratatouille/ratifier.rb
CHANGED
@@ -7,9 +7,11 @@ module Ratatouille
|
|
7
7
|
|
8
8
|
# A new instance of Ratifier
|
9
9
|
# @param [Hash, Array] obj Object to validate
|
10
|
+
# @param [Hash] options
|
10
11
|
def initialize(obj, options={}, &block)
|
11
12
|
@errors = { "/" => [] }
|
12
13
|
@ratifiable_object = obj
|
14
|
+
self.name = options[:name]
|
13
15
|
|
14
16
|
case obj
|
15
17
|
when Hash then extend Ratatouille::HashMethods
|
@@ -24,6 +26,27 @@ module Ratatouille
|
|
24
26
|
end#initialize
|
25
27
|
|
26
28
|
|
29
|
+
# Name of instance
|
30
|
+
#
|
31
|
+
# @return [String]
|
32
|
+
def name
|
33
|
+
@name ||= @ratifiable_object.class.to_s
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
# Set name of instance
|
38
|
+
#
|
39
|
+
# @param [String] namein
|
40
|
+
# @return [String] name of Ratatouille::Ratifier instance
|
41
|
+
def name=(namein)
|
42
|
+
case namein
|
43
|
+
when String
|
44
|
+
@name = namein unless namein.blank?
|
45
|
+
end
|
46
|
+
@name
|
47
|
+
end
|
48
|
+
|
49
|
+
|
27
50
|
# Add validation error. Useful for custom validations.
|
28
51
|
# @param [String] str
|
29
52
|
# @param [String] context
|
@@ -33,10 +56,10 @@ module Ratatouille
|
|
33
56
|
when String
|
34
57
|
return if err_in.blank?
|
35
58
|
@errors[context] = [] unless @errors[context]
|
36
|
-
@errors[context] << err_in
|
59
|
+
@errors[context] << "#{@name}: #{err_in}"
|
37
60
|
end
|
38
61
|
rescue Exception => e
|
39
|
-
@errors["/"] << e.message
|
62
|
+
@errors["/"] << "#{@name}: #{e.message}"
|
40
63
|
end#validation_error
|
41
64
|
|
42
65
|
|
@@ -54,7 +77,7 @@ module Ratatouille
|
|
54
77
|
def cleanup_errors
|
55
78
|
@errors = {} if errors_array.empty?
|
56
79
|
rescue Exception => e
|
57
|
-
|
80
|
+
validation_error("#{e.message}", '/')
|
58
81
|
end#cleanup_errors
|
59
82
|
|
60
83
|
|
data/lib/ratatouille/version.rb
CHANGED
data/lib/ratatouille.rb
CHANGED
@@ -10,9 +10,10 @@ require "ratatouille/string"
|
|
10
10
|
module Ratatouille
|
11
11
|
|
12
12
|
# @param [Hash, Array] obj Object to validate
|
13
|
+
# @param [Hash] options
|
13
14
|
# @return [Validatable::Ratifier]
|
14
|
-
def ratify(obj, &block)
|
15
|
-
Ratatouille::Ratifier.new(obj, &block)
|
15
|
+
def ratify(obj, options={}, &block)
|
16
|
+
Ratatouille::Ratifier.new(obj, options, &block)
|
16
17
|
end#ratify
|
17
18
|
|
18
19
|
end
|
@@ -33,14 +33,28 @@ describe "Ratatouille::HashMethods" do
|
|
33
33
|
it "should be invalid if choice list is not 1 more than choice size" do
|
34
34
|
RatifierTest.new({}) { choice_of(1, [:foo]) }.should_not be_valid
|
35
35
|
end
|
36
|
+
|
37
|
+
it "should be valid when given hash has 1 key in a choice list of 2 or more" do
|
38
|
+
RatifierTest.new({:foo => "bar"}){ choice_of(1, [:foo, :bar]) }.should be_valid
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should be valid when given hash has 2 keys in choice list of 3 or more" do
|
42
|
+
RatifierTest.new({:foo => "foo", :bar => "bar"}){
|
43
|
+
choice_of(2, [:foo, :bar, :biz])
|
44
|
+
}.should be_valid
|
45
|
+
|
46
|
+
RatifierTest.new({:foo => "foo", :bar => "bar"}){
|
47
|
+
choice_of(2, [:foo, :bar, :biz, :bang])
|
48
|
+
}.should be_valid
|
49
|
+
end
|
36
50
|
end
|
37
51
|
|
38
52
|
describe "required_keys" do
|
39
|
-
it "should be valid if
|
53
|
+
it "should be valid if Hash contains all required keys" do
|
40
54
|
RatifierTest.new({:foo => "foo"}) { required_keys(:foo, :bar) }.should_not be_valid
|
41
55
|
end
|
42
56
|
|
43
|
-
it "should be invalid if
|
57
|
+
it "should be invalid if Hash is empty and key list is not" do
|
44
58
|
RatifierTest.new({}) { required_keys(:foo) }.should_not be_valid
|
45
59
|
end
|
46
60
|
|
@@ -48,4 +62,34 @@ describe "Ratatouille::HashMethods" do
|
|
48
62
|
RatifierTest.new({:foo => "foo"}) { required_keys(:foo, :bar) }.should_not be_valid
|
49
63
|
end
|
50
64
|
end
|
65
|
+
|
66
|
+
describe "given_key" do
|
67
|
+
it "should change the scope name to default to the key if no name passed as option" do
|
68
|
+
n = ""
|
69
|
+
RatifierTest.new({:foo => "bar"}) do
|
70
|
+
given_key(:foo) { n = name }
|
71
|
+
end
|
72
|
+
n.should == ":foo"
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should change the scope name when passed as an option" do
|
76
|
+
o = n = ""
|
77
|
+
RatifierTest.new({:foo => "bar"}, :name => "Outer") do
|
78
|
+
o = name
|
79
|
+
given_key(:foo, :name => "None") { n = name }
|
80
|
+
end
|
81
|
+
o.should == "Outer"
|
82
|
+
n.should == "None"
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should not change the outer scope's name" do
|
86
|
+
o = n = ""
|
87
|
+
RatifierTest.new({:foo => "bar"}) do
|
88
|
+
given_key(:foo) { n = name }
|
89
|
+
o = name
|
90
|
+
end
|
91
|
+
o.should == "Hash"
|
92
|
+
n.should == ":foo"
|
93
|
+
end
|
94
|
+
end
|
51
95
|
end
|
@@ -120,4 +120,34 @@ describe Ratatouille::Ratifier do
|
|
120
120
|
end
|
121
121
|
end
|
122
122
|
end
|
123
|
+
|
124
|
+
describe "name" do
|
125
|
+
it "should return the same value if called twice in a row" do
|
126
|
+
r = RatifierTest.new({})
|
127
|
+
r.name.should == r.name
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should always return a String" do
|
131
|
+
RatifierTest.new({}).name.should be_a String
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should return the class of the object if :name isn't passed into options" do
|
135
|
+
RatifierTest.new({}).name.should == "Hash"
|
136
|
+
RatifierTest.new(Object.new).name.should == "Object"
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should return the name as passed into options of new instance" do
|
140
|
+
RatifierTest.new({}, :name => "Foo").name.should == "Foo"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
describe "name=" do
|
145
|
+
it "should not change the name if passed a non-string name" do
|
146
|
+
r = RatifierTest.new({})
|
147
|
+
r.name = NilClass
|
148
|
+
r.name = Object.new
|
149
|
+
r.name = nil
|
150
|
+
r.name.should == 'Hash'
|
151
|
+
end
|
152
|
+
end
|
123
153
|
end
|
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:
|
4
|
+
hash: 31
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
|
+
- 2
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 1.0.0
|
10
|
+
version: 1.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Ryan Johnson
|
@@ -58,7 +58,6 @@ extra_rdoc_files: []
|
|
58
58
|
|
59
59
|
files:
|
60
60
|
- .gitignore
|
61
|
-
- .rvmrc
|
62
61
|
- .travis-yml
|
63
62
|
- .yardopts
|
64
63
|
- Gemfile
|
data/.rvmrc
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
rvm --create use 1.8.7@ratatouille
|