organ 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f58028758f74b7ad8fdb144b5be194a4b3f3eba6
4
- data.tar.gz: 7391d92ec6d6165e58edb13b61b8290607577aba
3
+ metadata.gz: e29921771214a10a8ed0f1e36243dc60acf78091
4
+ data.tar.gz: ab43375fcb894100bea0ac235efee79e842f6386
5
5
  SHA512:
6
- metadata.gz: 657be4d73f04bd1c6a5aded0f539b2c37c39466b7f5c9879333680734137a7e7448e439c4bc9e93706b8216aab14cbc2997aca5ce50e1b219b6471f52ae7d3f6
7
- data.tar.gz: e87cd083c328bf9b62cc7ad65304ef35b2a4bbb3b5c183092fbe7b78cf60822e1cf05951648f8e059317d44c0128fdb46fd54b2f3552c1ba51f6cc2a715627fa
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
 
@@ -2,6 +2,6 @@ require_relative "organ/form"
2
2
 
3
3
  module Organ
4
4
 
5
- VERSION = "0.0.3"
5
+ VERSION = "0.1.0"
6
6
 
7
7
  end
@@ -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
@@ -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
- if !value || value.to_s.empty?
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 uniqueness is
56
- # determined by the block given. If the value is not unique, append the
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
- unless block.call(value)
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 email format,
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 not match
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 :too_short
98
- # error to the attribute. If the value is too long append the :too_long
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. If
123
- # the value is not included in the list, append the :not_included error to
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 value is less
139
- # than the min a :less_than_min error will be appended. If the value is
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
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "organ"
3
- s.version = "0.0.3"
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"]
@@ -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 an error" do
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 an error" do
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
- it "appends a :taken error" do
74
- validator.validate_uniqueness(:username) { |u| false }
75
- assert_includes(validator.errors[:username], :taken)
76
- assert_equal(1, validator.errors[:username].size)
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
- let(:username_value) { "not.an@email" }
97
+ describe "when value is not present" do
98
+ let(:username_value) { nil }
84
99
 
85
- it "appends an :invalid error" do
86
- validator.validate_email_format(:username)
87
- assert_includes(validator.errors[:username], :invalid)
88
- assert_equal(1, validator.errors[:username].size)
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
- let(:username_value) { "ema8l" }
121
+ describe "when value is not present" do
122
+ let(:username_value) { nil }
96
123
 
97
- it "appends an :invalid error" do
98
- validator.validate_format(:username, /\A[a-z]+\Z/)
99
- assert_includes(validator.errors[:username], :invalid)
100
- assert_equal(1, validator.errors[:username].size)
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
- let(:username_value) { "ema8l" }
145
+ describe "when value is not present" do
146
+ let(:username_value) { nil }
108
147
 
109
- it "appends a :too_short error" do
110
- validator.validate_length(:username, :min => 8)
111
- assert_includes(validator.errors[:username], :too_short)
112
- assert_equal(1, validator.errors[:username].size)
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
- let(:username_value) { 1 }
179
+ describe "when value is not present" do
180
+ let(:username_value) { nil }
130
181
 
131
- it "appends a :not_included error" do
132
- validator.validate_inclusion(:username, [2, 3])
133
- assert_includes(validator.errors[:username], :not_included)
134
- assert_equal(1, validator.errors[:username].size)
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
- let(:username_value) { 5 }
203
+ describe "when value is not present" do
204
+ let(:username_value) { nil }
142
205
 
143
- it "appends a :less_than error" do
144
- validator.validate_range(:username, :min => 8)
145
- assert_includes(validator.errors[:username], :less_than)
146
- assert_equal(1, validator.errors[:username].size)
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.3
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: 2015-03-02 00:00:00.000000000 Z
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.