organ 0.0.3 → 0.1.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.
- checksums.yaml +4 -4
- data/README.md +16 -0
- data/lib/organ.rb +1 -1
- data/lib/organ/coercer.rb +8 -1
- data/lib/organ/validations.rb +42 -22
- data/organ.gemspec +1 -1
- data/spec/validations_spec.rb +137 -31
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e29921771214a10a8ed0f1e36243dc60acf78091
|
4
|
+
data.tar.gz: ab43375fcb894100bea0ac235efee79e842f6386
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c591d8ca4797ab2b229daa7198d3a95a3155bca235a993637e1f97b4cc2f68eda3bd4bc0098e60cde034ed621d750df658d47ceb83953a1fe86f2492d8a67cf
|
7
|
+
data.tar.gz: 88c0dfe1e6472348d5b8025c2f8d17d1fe40c8851f32c2fffe28a241d39743e141a1621439ff308a3d6e5dad36104eec2908ef61013e3966191516154cae67ce
|
data/README.md
CHANGED
@@ -176,6 +176,22 @@ appends a `:greater_than` error to the attribute. Example:
|
|
176
176
|
validate_range(:age, :min => 18)
|
177
177
|
```
|
178
178
|
|
179
|
+
### validation_block
|
180
|
+
|
181
|
+
This is a helper method that only calls the given block if the form doesn't have
|
182
|
+
any errors. This is particularly useful when some of the validations are costly
|
183
|
+
to make and unnecessary if the form already has errors.
|
184
|
+
|
185
|
+
```ruby
|
186
|
+
validate_length(:username, :min => 7)
|
187
|
+
|
188
|
+
validation_block do # Will only get called if previous validation passed
|
189
|
+
validate_uniqueness(:username) do |username|
|
190
|
+
User.where(:username => username).empty?
|
191
|
+
end
|
192
|
+
end
|
193
|
+
```
|
194
|
+
|
179
195
|
Extensions
|
180
196
|
----------
|
181
197
|
|
data/lib/organ.rb
CHANGED
data/lib/organ/coercer.rb
CHANGED
@@ -24,11 +24,15 @@ module Organ
|
|
24
24
|
# Corce the value into true or false.
|
25
25
|
#
|
26
26
|
# @param value [Object]
|
27
|
+
# @option options [Regexp] :pattern (nil)
|
28
|
+
# Try to match regexp pattern with passed value
|
29
|
+
# and cast to Boolean this match.
|
27
30
|
#
|
28
31
|
# @return [Boolean]
|
29
32
|
#
|
30
33
|
# @api semipublic
|
31
34
|
def coerce_boolean(value, options = {})
|
35
|
+
value = value =~ options[:pattern] if options.has_key?(:pattern)
|
32
36
|
!!value
|
33
37
|
end
|
34
38
|
|
@@ -120,6 +124,9 @@ module Organ
|
|
120
124
|
#
|
121
125
|
# @param value [Object]
|
122
126
|
# The value to be coerced.
|
127
|
+
# @option options [String] :format ("%Y-%m-%d")
|
128
|
+
# Allow send format to parse date.
|
129
|
+
# See http://ruby-doc.org/stdlib-2.1.1/libdoc/date/rdoc/Date.html#method-i-strftime
|
123
130
|
#
|
124
131
|
# @return [Date, nil]
|
125
132
|
# A Date if the value can be coerced or nil otherwise.
|
@@ -128,7 +135,7 @@ module Organ
|
|
128
135
|
def coerce_date(value, options = {})
|
129
136
|
value = coerce_string(value)
|
130
137
|
begin
|
131
|
-
Date.strptime(value, "%Y-%m-%d")
|
138
|
+
Date.strptime(value, options.fetch(:format, "%Y-%m-%d"))
|
132
139
|
rescue ArgumentError
|
133
140
|
nil
|
134
141
|
end
|
data/lib/organ/validations.rb
CHANGED
@@ -39,6 +39,15 @@ module Organ
|
|
39
39
|
errors[attribute_name] << error
|
40
40
|
end
|
41
41
|
|
42
|
+
# Call the given block if there are no errors.
|
43
|
+
#
|
44
|
+
# @param block [Proc]
|
45
|
+
#
|
46
|
+
# @api public
|
47
|
+
def validation_block(&block)
|
48
|
+
block.call if errors.empty?
|
49
|
+
end
|
50
|
+
|
42
51
|
# Validate the presence of the attribute value. If the value is nil or
|
43
52
|
# false append a :blank error to the attribute.
|
44
53
|
#
|
@@ -47,14 +56,14 @@ module Organ
|
|
47
56
|
# @api public
|
48
57
|
def validate_presence(attribute_name)
|
49
58
|
value = send(attribute_name)
|
50
|
-
|
59
|
+
unless present?(value)
|
51
60
|
append_error(attribute_name, :blank)
|
52
61
|
end
|
53
62
|
end
|
54
63
|
|
55
|
-
# Validate the uniqueness of the attribute value. The
|
56
|
-
# determined by the block given. If the value is not unique,
|
57
|
-
# :taken error to the attribute.
|
64
|
+
# Validate the uniqueness of the attribute value (if present). The
|
65
|
+
# uniqueness is determined by the block given. If the value is not unique,
|
66
|
+
# append the :taken error to the attribute.
|
58
67
|
#
|
59
68
|
# @param attribute_name [Symbol]
|
60
69
|
# @param block [Proc]
|
@@ -64,13 +73,13 @@ module Organ
|
|
64
73
|
# @api public
|
65
74
|
def validate_uniqueness(attribute_name, &block)
|
66
75
|
value = send(attribute_name)
|
67
|
-
|
76
|
+
if present?(value) && !block.call(value)
|
68
77
|
append_error(attribute_name, :taken)
|
69
78
|
end
|
70
79
|
end
|
71
80
|
|
72
|
-
# Validate the email format. If the value does not match the
|
73
|
-
# append the :invalid error to the attribute.
|
81
|
+
# Validate the email format (if present). If the value does not match the
|
82
|
+
# email format, append the :invalid error to the attribute.
|
74
83
|
#
|
75
84
|
# @param attribute_name [Symbol]
|
76
85
|
#
|
@@ -79,8 +88,8 @@ module Organ
|
|
79
88
|
validate_format(attribute_name, EMAIL_FORMAT)
|
80
89
|
end
|
81
90
|
|
82
|
-
# Validate the format of the attribute value. If the value does
|
83
|
-
# the regexp given, append :invalid error to the attribute.
|
91
|
+
# Validate the format of the attribute value (if present). If the value does
|
92
|
+
# not match the regexp given, append :invalid error to the attribute.
|
84
93
|
#
|
85
94
|
# @param attribute_name [Symbol]
|
86
95
|
# @param format [Regexp]
|
@@ -88,15 +97,15 @@ module Organ
|
|
88
97
|
# @api public
|
89
98
|
def validate_format(attribute_name, format)
|
90
99
|
value = send(attribute_name)
|
91
|
-
if value && !(format =~ value)
|
100
|
+
if present?(value) && !(format =~ value)
|
92
101
|
append_error(attribute_name, :invalid)
|
93
102
|
end
|
94
103
|
end
|
95
104
|
|
96
105
|
# Validate the length of a String, Array or any other form attribute which
|
97
|
-
# responds to #size. If the value is too short, append the
|
98
|
-
# error to the attribute. If the value is too long append the
|
99
|
-
# error to the attribute.
|
106
|
+
# responds to #size (if present). If the value is too short, append the
|
107
|
+
# :too_short error to the attribute. If the value is too long append the
|
108
|
+
# :too_long error to the attribute.
|
100
109
|
#
|
101
110
|
# @param attribute_name [Symbol]
|
102
111
|
# @option options [Integer, nil] :min (nil)
|
@@ -108,7 +117,7 @@ module Organ
|
|
108
117
|
max = options.fetch(:max, nil)
|
109
118
|
value = send(attribute_name)
|
110
119
|
|
111
|
-
if value
|
120
|
+
if present?(value)
|
112
121
|
length = value.size
|
113
122
|
if min && length < min
|
114
123
|
append_error(attribute_name, :too_short)
|
@@ -119,9 +128,9 @@ module Organ
|
|
119
128
|
end
|
120
129
|
end
|
121
130
|
|
122
|
-
# Validate the value of the given attribute is included in the list
|
123
|
-
# the value is not included in the list, append the
|
124
|
-
# the attribute.
|
131
|
+
# Validate the value of the given attribute is included in the list (if
|
132
|
+
# present). If the value is not included in the list, append the
|
133
|
+
# :not_included error to the attribute.
|
125
134
|
#
|
126
135
|
# @param attribute_name [Symbol]
|
127
136
|
# @param attribute_name [Symbol]
|
@@ -130,14 +139,14 @@ module Organ
|
|
130
139
|
# @api public
|
131
140
|
def validate_inclusion(attribute_name, list)
|
132
141
|
value = send(attribute_name)
|
133
|
-
if value && !list.include?(value)
|
142
|
+
if present?(value) && !list.include?(value)
|
134
143
|
append_error(attribute_name, :not_included)
|
135
144
|
end
|
136
145
|
end
|
137
146
|
|
138
|
-
# Validate the range in which the attribute can be. If the
|
139
|
-
# than the min a :less_than_min error will be appended. If the
|
140
|
-
# greater than the max a :greater_than_max error will be appended.
|
147
|
+
# Validate the range in which the attribute can be (if present). If the
|
148
|
+
# value is less than the min a :less_than_min error will be appended. If the
|
149
|
+
# value is greater than the max a :greater_than_max error will be appended.
|
141
150
|
#
|
142
151
|
# @param attribute_name [Symbol]
|
143
152
|
# @option options [Integer] :min (nil)
|
@@ -149,7 +158,7 @@ module Organ
|
|
149
158
|
def validate_range(attribute_name, options = {})
|
150
159
|
value = send(attribute_name)
|
151
160
|
|
152
|
-
return unless value
|
161
|
+
return unless present?(value)
|
153
162
|
|
154
163
|
min = options.fetch(:min, nil)
|
155
164
|
max = options.fetch(:max, nil)
|
@@ -157,5 +166,16 @@ module Organ
|
|
157
166
|
append_error(attribute_name, :greater_than) if max && value > max
|
158
167
|
end
|
159
168
|
|
169
|
+
# Determine if the value is present (not nil, false or an empty string).
|
170
|
+
#
|
171
|
+
# @param value [Object]
|
172
|
+
#
|
173
|
+
# @return [Boolean]
|
174
|
+
#
|
175
|
+
# @api private
|
176
|
+
def present?(value)
|
177
|
+
value && !value.to_s.empty?
|
178
|
+
end
|
179
|
+
|
160
180
|
end
|
161
181
|
end
|
data/organ.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "organ"
|
3
|
-
s.version = "0.0
|
3
|
+
s.version = "0.1.0"
|
4
4
|
s.summary = "Forms with integrated validations and attribute coercing."
|
5
5
|
s.description = "A small library for manipulating form-based data with validations and attributes coercion."
|
6
6
|
s.authors = ["Sebastian Borrazas"]
|
data/spec/validations_spec.rb
CHANGED
@@ -50,7 +50,7 @@ describe Organ::Validations do
|
|
50
50
|
|
51
51
|
describe "#validate_presence" do
|
52
52
|
describe "when attribute has nil value" do
|
53
|
-
it "appends
|
53
|
+
it "appends a :blank error" do
|
54
54
|
validator.validate_presence(:username)
|
55
55
|
assert_includes(validator.errors[:username], :blank)
|
56
56
|
assert_equal(1, validator.errors[:username].size)
|
@@ -60,7 +60,7 @@ describe Organ::Validations do
|
|
60
60
|
describe "when attribute has empty string value" do
|
61
61
|
let(:username_value) { "" }
|
62
62
|
|
63
|
-
it "appends
|
63
|
+
it "appends a :blank error" do
|
64
64
|
validator.validate_presence(:username)
|
65
65
|
assert_includes(validator.errors[:username], :blank)
|
66
66
|
assert_equal(1, validator.errors[:username].size)
|
@@ -70,46 +70,96 @@ describe Organ::Validations do
|
|
70
70
|
|
71
71
|
describe "#validate_uniqueness" do
|
72
72
|
describe "when block returns false" do
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
73
|
+
describe "when value is not present" do
|
74
|
+
let(:username_value) { nil }
|
75
|
+
|
76
|
+
it "doesn't append any error" do
|
77
|
+
validator.validate_uniqueness(:username) { |u| false }
|
78
|
+
|
79
|
+
assert_equal(0, validator.errors[:username].size)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "when value is present" do
|
84
|
+
let(:username_value) { "username" }
|
85
|
+
|
86
|
+
it "appends a :taken error" do
|
87
|
+
validator.validate_uniqueness(:username) { |u| false }
|
88
|
+
assert_includes(validator.errors[:username], :taken)
|
89
|
+
assert_equal(1, validator.errors[:username].size)
|
90
|
+
end
|
77
91
|
end
|
78
92
|
end
|
79
93
|
end
|
80
94
|
|
81
95
|
describe "#validate_email_format" do
|
82
96
|
describe "when value is not an email" do
|
83
|
-
|
97
|
+
describe "when value is not present" do
|
98
|
+
let(:username_value) { nil }
|
84
99
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
100
|
+
it "doesn't append any error" do
|
101
|
+
validator.validate_email_format(:username)
|
102
|
+
|
103
|
+
assert_equal(0, validator.errors[:username].size)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "when value is present" do
|
108
|
+
let(:username_value) { "not.an@email" }
|
109
|
+
|
110
|
+
it "appends an :invalid error" do
|
111
|
+
validator.validate_email_format(:username)
|
112
|
+
assert_includes(validator.errors[:username], :invalid)
|
113
|
+
assert_equal(1, validator.errors[:username].size)
|
114
|
+
end
|
89
115
|
end
|
90
116
|
end
|
91
117
|
end
|
92
118
|
|
93
119
|
describe "#validate_format" do
|
94
120
|
describe "when value does not match the regexp" do
|
95
|
-
|
121
|
+
describe "when value is not present" do
|
122
|
+
let(:username_value) { nil }
|
96
123
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
124
|
+
it "doesn't append any error" do
|
125
|
+
validator.validate_format(:username, /\A[a-z]+\Z/)
|
126
|
+
|
127
|
+
assert_equal(0, validator.errors[:username].size)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe "when value is present" do
|
132
|
+
let(:username_value) { "ema8l" }
|
133
|
+
|
134
|
+
it "appends an :invalid error" do
|
135
|
+
validator.validate_format(:username, /\A[a-z]+\Z/)
|
136
|
+
assert_includes(validator.errors[:username], :invalid)
|
137
|
+
assert_equal(1, validator.errors[:username].size)
|
138
|
+
end
|
101
139
|
end
|
102
140
|
end
|
103
141
|
end
|
104
142
|
|
105
143
|
describe "#validate_length" do
|
106
144
|
describe "when value size is less than the min" do
|
107
|
-
|
145
|
+
describe "when value is not present" do
|
146
|
+
let(:username_value) { nil }
|
108
147
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
148
|
+
it "doesn't append any error" do
|
149
|
+
validator.validate_length(:username, :min => 8)
|
150
|
+
|
151
|
+
assert_equal(0, validator.errors[:username].size)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe "when value is present" do
|
156
|
+
let(:username_value) { "ema8l" }
|
157
|
+
|
158
|
+
it "appends a :too_short error" do
|
159
|
+
validator.validate_length(:username, :min => 8)
|
160
|
+
assert_includes(validator.errors[:username], :too_short)
|
161
|
+
assert_equal(1, validator.errors[:username].size)
|
162
|
+
end
|
113
163
|
end
|
114
164
|
end
|
115
165
|
|
@@ -126,24 +176,48 @@ describe Organ::Validations do
|
|
126
176
|
|
127
177
|
describe "#validate_inclusion" do
|
128
178
|
describe "when is not included in the list" do
|
129
|
-
|
179
|
+
describe "when value is not present" do
|
180
|
+
let(:username_value) { nil }
|
130
181
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
182
|
+
it "doesn't append any error" do
|
183
|
+
validator.validate_inclusion(:username, [2, 3])
|
184
|
+
|
185
|
+
assert_equal(0, validator.errors[:username].size)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
describe "when value is present" do
|
190
|
+
let(:username_value) { 1 }
|
191
|
+
|
192
|
+
it "appends a :not_included error" do
|
193
|
+
validator.validate_inclusion(:username, [2, 3])
|
194
|
+
assert_includes(validator.errors[:username], :not_included)
|
195
|
+
assert_equal(1, validator.errors[:username].size)
|
196
|
+
end
|
135
197
|
end
|
136
198
|
end
|
137
199
|
end
|
138
200
|
|
139
201
|
describe "#validate_range" do
|
140
202
|
describe "when value is less than the min" do
|
141
|
-
|
203
|
+
describe "when value is not present" do
|
204
|
+
let(:username_value) { nil }
|
142
205
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
206
|
+
it "doesn't append any error" do
|
207
|
+
validator.validate_range(:username, :min => 8)
|
208
|
+
|
209
|
+
assert_equal(0, validator.errors[:username].size)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
describe "when value is present" do
|
214
|
+
let(:username_value) { 5 }
|
215
|
+
|
216
|
+
it "appends a :less_than error" do
|
217
|
+
validator.validate_range(:username, :min => 8)
|
218
|
+
assert_includes(validator.errors[:username], :less_than)
|
219
|
+
assert_equal(1, validator.errors[:username].size)
|
220
|
+
end
|
147
221
|
end
|
148
222
|
end
|
149
223
|
|
@@ -158,4 +232,36 @@ describe Organ::Validations do
|
|
158
232
|
end
|
159
233
|
end
|
160
234
|
|
235
|
+
describe "#validation_block" do
|
236
|
+
describe "when form has no errors" do
|
237
|
+
let(:username_value) { "validusername" }
|
238
|
+
|
239
|
+
it "calls the given block" do
|
240
|
+
validator.validate_presence(:username)
|
241
|
+
|
242
|
+
block_called = 0
|
243
|
+
|
244
|
+
validator.validation_block do
|
245
|
+
block_called += 1
|
246
|
+
end
|
247
|
+
|
248
|
+
assert_equal(1, block_called)
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
describe "when form has errors" do
|
253
|
+
it "doesn't call the given block" do
|
254
|
+
validator.validate_presence(:username)
|
255
|
+
|
256
|
+
block_called = 0
|
257
|
+
|
258
|
+
validator.validation_block do
|
259
|
+
block_called += 1
|
260
|
+
end
|
261
|
+
|
262
|
+
assert_equal(0, block_called)
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
161
267
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: organ
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sebastian Borrazas
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-04-13 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A small library for manipulating form-based data with validations and
|
14
14
|
attributes coercion.
|