has_validated_attributes 0.0.9 → 0.0.10
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.rdoc +3 -1
- data/has_validated_attributes.gemspec +5 -4
- data/lib/has_validated_attributes.rb +4 -3
- data/lib/has_validated_attributes/rspec.rb +282 -0
- data/lib/version.rb +1 -1
- data/spec/db/schema.rb +1 -0
- data/spec/db/test.sqlite3 +0 -0
- data/spec/has_validate_fields_spec.rb +72 -363
- data/spec/spec_helper.rb +3 -0
- metadata +36 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c761c309029c68a341e56752666b57328813b3d1
|
4
|
+
data.tar.gz: 2c738c7475c92be1b079b0dfa793eb2b0332551c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f9584b22066a04733b72b7152bf5376b651b14edb8a73d500ee515447e57cd99dbad0d3b9eef4cb34da58c3fc08afba2d553f7780252ff04991a669f6e745ea9
|
7
|
+
data.tar.gz: 9032cd2eb87d20c991ce5e7d74ac63397bd7d35e8aa6829b1184f8c197b57715a24276d7a7852320b840e5e3100065bc0b0574992f5382253dfe04280bff07a2
|
data/README.rdoc
CHANGED
@@ -24,7 +24,7 @@ for example:
|
|
24
24
|
:positive_dollar_attr => {:format => :positive_dollar}, :percent_attr => {:format => :percent},
|
25
25
|
:positive_percent_attr => {:format => :positive_percent}, :url_attr => {:format => :url}, :ssn_attr => {:format => :ssn},
|
26
26
|
:taxid_attr => {:format => :taxid}, :age_attr => {:format => :age}, :number_attr => {:format => :number}
|
27
|
-
end
|
27
|
+
end
|
28
28
|
|
29
29
|
== Extra Options
|
30
30
|
You can pass extra options like
|
@@ -36,6 +36,8 @@ for example:
|
|
36
36
|
:zipcode, :dollar, :percent, :positive_percent, :middle_initial, :url,
|
37
37
|
:positive_dollar, :domain, :ssn, :taxid, :age, :number
|
38
38
|
|
39
|
+
== RSpec
|
40
|
+
Add `require "has_validated_attributes/rspec"` to your specs to include shared examples for validated fields.
|
39
41
|
|
40
42
|
== COPYRIGHT
|
41
43
|
|
@@ -18,8 +18,9 @@ Gem::Specification.new do |s|
|
|
18
18
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
19
|
s.require_paths = ["lib"]
|
20
20
|
s.add_development_dependency "rspec"
|
21
|
-
s.add_development_dependency
|
22
|
-
s.add_development_dependency
|
23
|
-
s.add_development_dependency
|
21
|
+
s.add_development_dependency "shoulda-matchers"
|
22
|
+
s.add_development_dependency "has_normalized_attributes", "~> 0.0", ">= 0.0.8"
|
23
|
+
s.add_development_dependency "activerecord", ">= 3.1.0"
|
24
|
+
s.add_development_dependency "sqlite3"
|
25
|
+
s.add_development_dependency "database_cleaner"
|
24
26
|
end
|
25
|
-
|
@@ -1,8 +1,9 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
require 'active_record'
|
2
3
|
|
3
4
|
module HasValidatedAttributes
|
4
5
|
extend ActiveSupport::Concern
|
5
|
-
NO_CONTROL_CHARS_REGEX = /\A[^[:cntrl:]]*\
|
6
|
+
NO_CONTROL_CHARS_REGEX = /\A[^[:cntrl:]]*\z/
|
6
7
|
NO_CONTROL_CHARS_ERROR_MSG = "avoid non-printing characters"
|
7
8
|
|
8
9
|
#instance methods
|
@@ -41,8 +42,8 @@ module HasValidatedAttributes
|
|
41
42
|
:middle_initial => {:format => {:with => /\A[a-zA-Z]{0,1}\z/u, :message => "accepts only one letter"}},
|
42
43
|
:dollar => {:format => {:with => /\A-?[0-9]{0,12}(\.[0-9]{0,2})?\z/, :message => "accepts only numeric characters, period, and negative sign"}, :numericality => {:greater_than => -1000000000000, :less_than => 1000000000000}, :allow_nil => true},
|
43
44
|
:positive_dollar => {:format => {:with => /\A[0-9]{0,12}(\.[0-9]{0,2})?\z/, :message => "accepts only numeric characters, period"}, :numericality => {:greater_than_or_equal_to => 0, :less_than => 1000000000000}, :allow_nil => true},
|
44
|
-
:percent => {:format => {:with => /\A-?[0-9]{0,3}(\.[0-9]{0,3})?\z/, :message => "accepts only numeric characters, period, negative sign, and must be equal/less/greater than +/- 100"}},
|
45
|
-
:positive_percent => {:format => {:with => /\A[0-9]{0,3}(\.[0-9]{0,3})?\z/, :message => "accepts only numeric characters, period, and must be less than 100"}, :numericality => {:greater_than_or_equal_to => 0, :less_than_or_equal_to => 100}, :allow_nil => true},
|
45
|
+
:percent => {:format => {:with => /\A-?[0-9]{0,3}(\.[0-9]{0,3})?\z/, :message => "accepts only numeric characters, period, negative sign, and must be equal/less/greater than +/- 100"}, :numericality => {:greater_than_or_equal_to => -100, :less_than_or_equal_to => 100} },
|
46
|
+
:positive_percent => {:format => {:with => /\A[0-9]{0,3}(\.[0-9]{0,3})?\z/, :message => "accepts only numeric characters, period, and must be equal/less than 100"}, :numericality => {:greater_than_or_equal_to => 0, :less_than_or_equal_to => 100}, :allow_nil => true},
|
46
47
|
:url => {:length => {:maximum => 255}, :format => {:with => /\A(http|https|ftp):\/\/[A-Z0-9]+([\.]{1}[a-z0-9-]{1,63})*\.[a-zA-Z]{2,5}(:[0-9]{1,5})?(\/.*)?\z/ix, :message => "web address isnt valid"}, :has_if? => true},
|
47
48
|
:social_security_number => {:length => {:is => 9}, :numericality => {:greater_than_or_equal_to => 0, :less_than => 1000000000, :message => "must be in the format 111-11-1111"}, :has_if? => true},
|
48
49
|
:taxid => {:length => {:is => 9}, :numericality => {:greater_than_or_equal_to => 9999999, :less_than => 1000000000, :message => "must be in the format 11-1111111"}, :has_if? => true},
|
@@ -0,0 +1,282 @@
|
|
1
|
+
begin
|
2
|
+
require 'rspec'
|
3
|
+
require 'shoulda-matchers'
|
4
|
+
rescue LoadError => e
|
5
|
+
raise <<-ERROR_MSG
|
6
|
+
#{ e.path } is not loaded but is required when loading "has_validated_attributes/rspec"!
|
7
|
+
|
8
|
+
Do you need to `gem install #{ e.path }`?
|
9
|
+
ERROR_MSG
|
10
|
+
end
|
11
|
+
|
12
|
+
RSpec.configure do |config|
|
13
|
+
config.extend Module.new {
|
14
|
+
def has_validated_attribute(type, attr, *args, &block)
|
15
|
+
it_behaves_like "#{ type.gsub('_', ' ') } attribute", attr, *args, &block
|
16
|
+
end
|
17
|
+
|
18
|
+
# Provide dynamic methods wrappers to shared behaviors.
|
19
|
+
#
|
20
|
+
#=== Examples
|
21
|
+
# has_validated_name_field(:first_name) # Same as `it_behaves_like "name attribute", :first_name`
|
22
|
+
# has_validated_zip_code_field(:first_name) # Same as `it_behaves_like "zip code field", :first_name`
|
23
|
+
def method_missing(name, *args, &block)
|
24
|
+
if /\Ahas_validated_(?<type>\w*)_attribute\Z/ =~ name
|
25
|
+
has_validated_attribute(type, *args, &block)
|
26
|
+
else
|
27
|
+
super
|
28
|
+
end
|
29
|
+
end
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
#= Load shared examples
|
34
|
+
# it_behaves_like "name attribute", :first_name
|
35
|
+
# it_behaves_like "name attribute", :first_name, 10
|
36
|
+
RSpec.shared_examples_for "name attribute" do |attr, length: HasValidatedAttributes.name_format[:maximum_length]|
|
37
|
+
it { should validate_length_of(attr).is_at_least(0) }
|
38
|
+
it { should validate_length_of(attr).is_at_most(length) }
|
39
|
+
|
40
|
+
[
|
41
|
+
"A", "z", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")",
|
42
|
+
"{", "}", "?", "+", "[", "]", "/", "\\", "-", "_", "<", ">",
|
43
|
+
"k c", "- H-", " t", "& u", "21 ", "brok", ">*", "< test"
|
44
|
+
].
|
45
|
+
select { |str| str.length <= length }.
|
46
|
+
each do |str|
|
47
|
+
it { should allow_value(str).for(attr) }
|
48
|
+
end
|
49
|
+
|
50
|
+
["\e1B", "\cF", "Hello\nWorld", "\eHey", "Oh\cFNo, it's a control char!"].
|
51
|
+
select { |str| str.length <= length }.
|
52
|
+
each do |str|
|
53
|
+
it { should_not allow_value(str).for(attr).with_message(HasValidatedAttributes.name_format[:format][:message]) }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
RSpec.shared_examples_for "username attribute" do |attr|
|
58
|
+
it { should validate_length_of(attr).is_at_least(HasValidatedAttributes.username_format[:length][:within].min) }
|
59
|
+
it { should validate_length_of(attr).is_at_most(HasValidatedAttributes.username_format[:length][:within].max) }
|
60
|
+
|
61
|
+
["kansascity", "kansascity@org1", "kansas.city@org1", "kansas_city@org1", "kansas-city", "1kc.-_@"].each do |value|
|
62
|
+
it { should allow_value(value).for(attr) }
|
63
|
+
end
|
64
|
+
|
65
|
+
[">*,.<><", "<<< test", "Kansas City", "-- Hey --", "& youuuu", "21 Jump"].each do |value|
|
66
|
+
it { should_not allow_value(value).for(attr).with_message(HasValidatedAttributes.username_format[:format][:message]) }
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
RSpec.shared_examples_for "email attribute" do |attr|
|
71
|
+
it { should validate_length_of(attr).is_at_most(HasValidatedAttributes.email_format[:length][:maximum]) }
|
72
|
+
|
73
|
+
["abc@example.com", "Abc@example.com", "aBC@example.com", "abc.123@example.com", "mo’reilly@example.com", "ro'sullivan@example.com"].each do |value|
|
74
|
+
it { should allow_value(value).for(attr) }
|
75
|
+
end
|
76
|
+
|
77
|
+
["Abc.example.com", "A@b@c@example.com", "()[]\;:,<>@example.com", "abc@example.comar"].each do |value|
|
78
|
+
it { should_not allow_value(value).for(attr).with_message(HasValidatedAttributes.email_format[:format][:message]) }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
RSpec.shared_examples_for "domain attribute" do |attr|
|
83
|
+
it { should validate_length_of(attr).is_at_most(HasValidatedAttributes.domain_format[:length][:maximum]) }
|
84
|
+
|
85
|
+
["test.com", "hey.com", "dynamicadvisorsgroup.com", "advisorsexcel.com"].each do |value|
|
86
|
+
it { should allow_value(value).for(attr) }
|
87
|
+
end
|
88
|
+
|
89
|
+
[">*", "<test", "test-er"].each do |value|
|
90
|
+
it { should_not allow_value(value).for(attr).with_message(HasValidatedAttributes.domain_format[:format][:message]) }
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
RSpec.shared_examples_for "middle initial attribute" do |attr|
|
95
|
+
["a", "A"].each do |value|
|
96
|
+
it { should allow_value(value).for(attr) }
|
97
|
+
end
|
98
|
+
|
99
|
+
["k c", "55555", "55555-5555", "55555 5555", "55555.5555", "(888)88-9999", " ,-99999"].each do |value|
|
100
|
+
it { should_not allow_value(value).for(attr).with_message(HasValidatedAttributes.middle_initial_format[:format][:message]) }
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
RSpec.shared_examples_for "zipcode attribute" do |attr|
|
105
|
+
["11111", "333333333"].each do |zip|
|
106
|
+
it { should allow_value(zip).for(attr) }
|
107
|
+
end
|
108
|
+
|
109
|
+
["5555", "5555555555","-99999"].each do |zip|
|
110
|
+
it { should_not allow_value(zip).for(attr).with_message(HasValidatedAttributes.zipcode_format[:format][:message]) }
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
RSpec.shared_examples_for "phone number attribute" do |attr, normalized: false|
|
115
|
+
["9134456677", "5444456677", "9134466677 ", " 2134456677 "].each do |phone|
|
116
|
+
it { should allow_value(phone).for(attr) }
|
117
|
+
end
|
118
|
+
|
119
|
+
[">*", "< test", "www.test..com", "www.test.c", "www-test.com", "abc", "123", "&*()", "www.test-com"].each do |phone|
|
120
|
+
it { should_not allow_value(phone).for(attr).with_message(HasValidatedAttributes.phone_number_format[:numericality][:message]) }
|
121
|
+
end
|
122
|
+
|
123
|
+
["913 345 6677", "613-445-6677", "983445-6677", " 913-4256677", "(888)8888888", "903-445 6627", "913-4556677", "513.445-6677", "555.555.8888"].each do |phone|
|
124
|
+
it { send(normalized ? :should : :should_not, allow_value(phone).for(attr).with_message(HasValidatedAttributes.phone_number_format[:numericality][:message])) }
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
RSpec.shared_examples_for "phone extension attribute" do |attr|
|
129
|
+
["123", "123456"].each do |ext|
|
130
|
+
it { should allow_value(ext).for(attr) }
|
131
|
+
end
|
132
|
+
|
133
|
+
["-1", "qwert"].each do |ext|
|
134
|
+
it { should_not allow_value(ext).for(attr).with_message(HasValidatedAttributes.phone_extension_format[:numericality][:message]) }
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
RSpec.shared_examples_for "url attribute" do |attr, allowed: nil, disallowed: nil|
|
139
|
+
(allowed || [
|
140
|
+
"http://www.example.com", "http://www.example.com:8001", "http://www.exmple.com/1/abc?test=test",
|
141
|
+
"http://finane.example.com", "http://www.example.com/1/abc?test=test", "http://fiance.example.com", "http://finance.example.com.ag"
|
142
|
+
]).each do |url|
|
143
|
+
it { should allow_value(url).for(attr) }
|
144
|
+
end
|
145
|
+
|
146
|
+
(disallowed || [
|
147
|
+
"finance.example.com", "www.example.com", "www.example.com:8001", ">*", "< test",
|
148
|
+
"www.test..com", "www.test.c", "www-test.com", "abc", "123", "&*()", "www.test-com"
|
149
|
+
]).each do |url|
|
150
|
+
it { should_not allow_value(url).for(attr).with_message(HasValidatedAttributes.url_format[:format][:message]) }
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
RSpec.shared_examples_for "positive percent attribute" do |attr|
|
155
|
+
["100", "99", "1", "44", "99.999", "0.001"].each do |percent|
|
156
|
+
it { should allow_value(percent).for(attr) }
|
157
|
+
end
|
158
|
+
|
159
|
+
["100.001", "0.2222", "abc", "&", "-44", "-44.4", "-44.4444"].each do |percent|
|
160
|
+
it { should_not allow_value(percent).for(attr) }
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
RSpec.shared_examples_for "percent attribute" do |attr|
|
165
|
+
["100", "99", "1", "44", "99.999", "0.001", "-100", "-99", "-1", "-44", "-99.999", "-0.001"].each do |value|
|
166
|
+
it { should allow_value(value).for(attr) }
|
167
|
+
end
|
168
|
+
|
169
|
+
["100.001", "0.2222", "-100.001", "-0.2222", "abc", "&"].each do |value|
|
170
|
+
it { should_not allow_value(value).for(attr) }
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
RSpec.shared_examples_for "age attribute" do |attr|
|
175
|
+
["100", "99", "1 ", "44", "110", "0"].each do |value|
|
176
|
+
it { should allow_value(value).for(attr) }
|
177
|
+
end
|
178
|
+
|
179
|
+
|
180
|
+
["111", "-1", "abc", "&"].each do |value|
|
181
|
+
it { should_not allow_value(value).for(attr).with_message(HasValidatedAttributes.age_format[:numericality][:message]) }
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
RSpec.shared_examples_for "positive dollar attribute" do |attr, normalized: false|
|
186
|
+
["0", "1", "100", "1000", "1000.99"].each do |value|
|
187
|
+
it { should allow_value(value).for(attr) }
|
188
|
+
end
|
189
|
+
|
190
|
+
["-1", "0.2222", "ewrt"].each do |value|
|
191
|
+
it { should_not allow_value(value).for(attr) }
|
192
|
+
end
|
193
|
+
|
194
|
+
["1,000,00", "$1,000.00", "1,000,000", "1 000 000.01"].each do |value|
|
195
|
+
it { send(normalized ? :should : :should_not, allow_value(value).for(attr)) }
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
RSpec.shared_examples_for "dollar attribute" do |attr, normalized: false|
|
200
|
+
["0", "1", "100", "1000", "1000.99", "-0", "-1", "-100", "-1000", "-1000.99"].each do |value|
|
201
|
+
it { should allow_value(value).for(attr) }
|
202
|
+
end
|
203
|
+
|
204
|
+
["0.2222", "ewrt"].each do |value|
|
205
|
+
it { should_not allow_value(value).for(attr) }
|
206
|
+
end
|
207
|
+
|
208
|
+
[
|
209
|
+
"1,000,00", "$1,000.00", "1,000,000", "1 000 000.01",
|
210
|
+
"-1,000,00", "-$1,000.00", "-1,000,000", "-1 000 000.01" # has_normalized_attributes may be used in concert with has_validated_attributes to cover these cases.
|
211
|
+
].each do |value|
|
212
|
+
it { send(normalized ? :should : :should_not, allow_value(value).for(attr)) }
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
RSpec.shared_examples_for "number attribute" do |attr, length: nil, normalized: false|
|
217
|
+
["0", "1", "100", "1000", "-1"].each do |value|
|
218
|
+
it { should allow_value(value).for(attr) }
|
219
|
+
end
|
220
|
+
|
221
|
+
["werq"].each do |value|
|
222
|
+
it { should_not allow_value(value).for(attr).with_message(HasValidatedAttributes.number_format[:numericality][:message]) }
|
223
|
+
end
|
224
|
+
|
225
|
+
[
|
226
|
+
"1,000,00", "1,000.00", "1,000,000", "1 000 000", # has_normalized_attributes may be used in concert with has_validated_attributes to cover these cases.
|
227
|
+
].each do |value|
|
228
|
+
it { send(normalized ? :should : :should_not, allow_value(value).for(attr).with_message(HasValidatedAttributes.number_format[:numericality][:message])) }
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
RSpec.shared_examples_for "rails name attribute" do |attr|
|
233
|
+
["kc_s", "hey", "yo_", "_jmp", "kc_star_what", "hey", "yo_sucka", "_jump_street"].each do |value|
|
234
|
+
it { should allow_value(value).for(attr) }
|
235
|
+
end
|
236
|
+
|
237
|
+
[">*", "< test", "test-er", "yo dude"].each do |value|
|
238
|
+
it { should_not allow_value(value).for(attr).with_message(HasValidatedAttributes.rails_name_format[:format][:message]) }
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
RSpec.shared_examples_for "taxid attribute" do |attr, normalized: false|
|
243
|
+
["010000000", " ", "545998888"].each do |value|
|
244
|
+
it { should allow_value(value).for(attr) }
|
245
|
+
end
|
246
|
+
|
247
|
+
["ab-cdefgh", "001000000", "abc", "<", "&"].each do |value|
|
248
|
+
it { should_not allow_value(value).for(attr).with_message(HasValidatedAttributes.taxid_format[:numericality][:message]) }
|
249
|
+
end
|
250
|
+
|
251
|
+
["51-5998888", "51 5998858", "44.5559999",].each do |value|
|
252
|
+
it { send(normalized ? :should : :should_not, allow_value(value).for(attr).with_message(HasValidatedAttributes.taxid_format[:numericality][:message])) }
|
253
|
+
end
|
254
|
+
|
255
|
+
it { send(normalized ? :should : :should_not, allow_value(" 514998888 ").for(attr).with_message(/is the wrong length \(should be 9 characters\)/)) }
|
256
|
+
end
|
257
|
+
|
258
|
+
RSpec.shared_examples_for "ssn attribute" do |attr, normalized: false|
|
259
|
+
["515998488", " "].each do |value|
|
260
|
+
it { should allow_value(value).for(attr) }
|
261
|
+
end
|
262
|
+
|
263
|
+
["ab-444fgh", "abc", "56599858>", "33445<", "3456356&", "/23452"].each do |value|
|
264
|
+
it { should_not allow_value(value).for(attr).with_message(HasValidatedAttributes.social_security_number_format[:numericality][:message]) }
|
265
|
+
end
|
266
|
+
|
267
|
+
["515-99-8888", "544.99 8888", "515 99 8858", "444.33.6666"].each do |value|
|
268
|
+
it { send(normalized ? :should : :should_not, allow_value(value).for(attr).with_message(HasValidatedAttributes.social_security_number_format[:numericality][:message])) }
|
269
|
+
end
|
270
|
+
|
271
|
+
it { send(normalized ? :should : :should_not, allow_value(" 514998888 ").for(attr).with_message(/is the wrong length \(should be 9 characters\)/)) }
|
272
|
+
end
|
273
|
+
|
274
|
+
RSpec.shared_examples_for "safe text attribute" do |attr|
|
275
|
+
[">*", "< test", "Hey\tWorld", "new\nline", "new\r\nline"].each do |value|
|
276
|
+
it { should allow_value(value).for(attr) }
|
277
|
+
end
|
278
|
+
|
279
|
+
["\eHey", "Oh\cFNo, it's a control char!"].each do |value|
|
280
|
+
it { should_not allow_value(value).for(attr).with_message(HasValidatedAttributes::NO_CONTROL_CHARS_ERROR_MSG) }
|
281
|
+
end
|
282
|
+
end
|
data/lib/version.rb
CHANGED
data/spec/db/schema.rb
CHANGED
data/spec/db/test.sqlite3
CHANGED
Binary file
|
@@ -3,372 +3,81 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
class Resource < ActiveRecord::Base
|
6
|
-
has_validated_attributes :name_attr => {:format => :name, :maximum_length => 10},
|
7
|
-
:
|
8
|
-
:
|
9
|
-
:
|
10
|
-
:
|
11
|
-
:
|
12
|
-
:
|
6
|
+
has_validated_attributes :name_attr => {:format => :name, :maximum_length => 10},
|
7
|
+
:safe_text_attr => { :format => :safe_text },
|
8
|
+
:username_attr => {:format => :username},
|
9
|
+
:email_attr => {:format => :email},
|
10
|
+
:phone_number_attr => {:format => :phone_number},
|
11
|
+
:phone_extension_attr => {:format => :phone_extension},
|
12
|
+
:domain_attr => {:format => :domain},
|
13
|
+
:zipcode_attr => {:format => :zipcode},
|
14
|
+
:middle_initial_attr => {:format => :middle_initial},
|
15
|
+
:dollar_attr => {:format => :dollar},
|
16
|
+
:positive_dollar_attr => {:format => :positive_dollar},
|
17
|
+
:percent_attr => {:format => :percent},
|
18
|
+
:positive_percent_attr => {:format => :positive_percent},
|
19
|
+
:url_attr => {:format => :url},
|
20
|
+
:ssn_attr => {:format => :social_security_number},
|
21
|
+
:taxid_attr => {:format => :taxid},
|
22
|
+
:age_attr => {:format => :age},
|
23
|
+
:number_attr => {:format => :number},
|
24
|
+
:rails_name_attr => {:format => :rails_name}
|
13
25
|
end
|
14
26
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
@resource.errors.full_messages.should == ["Username attr is too short (minimum is 5 characters)"]
|
37
|
-
end
|
38
|
-
|
39
|
-
it "should return error with more than 127 chars" do
|
40
|
-
@resource.username_attr = "test" * 128
|
41
|
-
@resource.valid?.should be_falsey
|
42
|
-
@resource.errors.full_messages.should == ["Username attr is too long (maximum is 127 characters)"]
|
43
|
-
end
|
44
|
-
|
45
|
-
it "should return ok" do
|
46
|
-
["kansascity", "kansascity@org1", "kansas.city@org1", "kansas_city@org1", "kansas-city", "1kc.-_@"].each do |value|
|
47
|
-
@resource.username_attr = value
|
48
|
-
@resource.valid?.should be_truthy
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
describe "#name" do
|
54
|
-
[">*", "< test"].each do |value|
|
55
|
-
it "should return error setting name to \"#{ value }\"" do
|
56
|
-
@resource.name_attr = value
|
57
|
-
expect(@resource.valid?).to be_truthy
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
["Hello\nWorld", "\eHey", "Oh\cFNo, it's a control char!"].each do |value|
|
62
|
-
it "should return error setting name to \"#{ value }\"" do
|
63
|
-
@resource.name_attr = value
|
64
|
-
expect(@resource.valid?).to be_falsey
|
65
|
-
expect(@resource.errors.full_messages).to include("Name attr avoid non-printing characters")
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
it "should return error with more than 10 chars" do
|
70
|
-
@resource.name_attr = "test" * 6
|
71
|
-
expect(@resource.valid?).to be_falsey
|
72
|
-
expect(@resource.errors.full_messages).to include("Name attr is too long (maximum is 10 characters)")
|
73
|
-
end
|
74
|
-
|
75
|
-
["k c", "- H-", " t", "& u", "21 ", "brok", nil].each do |value|
|
76
|
-
it "should return ok setting name to \"#{ value }\"" do
|
77
|
-
@resource.name_attr = value
|
78
|
-
expect(@resource.valid?).to be_truthy
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
describe "#safe_text" do
|
84
|
-
[">*", "< test", "Hey\tWorld", "new\nline", "new\r\nline"].each do |value|
|
85
|
-
it "should allow value to be set to \"#{ value.gsub("\r", "\\r").gsub("\n", "\\n") }\"" do
|
86
|
-
@resource.safe_text_attr = value
|
87
|
-
expect(@resource.valid?).to be_truthy
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
["\eHey", "Oh\cFNo, it's a control char!"].each do |value|
|
92
|
-
it "should return error setting value to \"#{ value }\"" do
|
93
|
-
@resource.safe_text_attr = value
|
94
|
-
expect(@resource.valid?).to be_falsey
|
95
|
-
expect(@resource.errors.full_messages).to include("Safe text attr avoid non-printing characters")
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
describe "#email" do
|
101
|
-
it "should return error" do
|
102
|
-
["Abc.example.com", "A@b@c@example.com", "()[]\;:,<>@example.com", "abc@example.comar"].each do |value|
|
103
|
-
@resource.email_attr = value
|
104
|
-
@resource.valid?.should be_falsey
|
105
|
-
@resource.errors.full_messages.should == ["Email attr should look like an email address."]
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
it "should return error with more than 63 chars" do
|
110
|
-
@resource.email_attr = "test@example.com" * 64
|
111
|
-
@resource.valid?.should be_falsey
|
112
|
-
@resource.errors.full_messages.should == ["Email attr is too long (maximum is 63 characters)", "Email attr should look like an email address."]
|
113
|
-
end
|
114
|
-
|
115
|
-
["abc@example.com", "Abc@example.com", "aBC@example.com", "abc.123@example.com", "mo’reilly@example.com", "ro'sullivan@example.com"].each do |value|
|
116
|
-
it "should return ok for `#{ value }`" do
|
117
|
-
@resource.email_attr = value
|
118
|
-
@resource.valid?.should be_truthy
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
describe "#phone_number" do
|
124
|
-
it "should return error" do
|
125
|
-
[">*", "< test", "www.test..com", "www.test.c", "www-test.com", "abc", "123", "&*()", "www.test-com"].each do |value|
|
126
|
-
@resource.phone_number_attr = value
|
127
|
-
@resource.valid?.should be_falsey
|
128
|
-
@resource.errors.full_messages.should == ["Phone number attr accepts only 10 numbers and (),.- characters and must not be all 0s"]
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
it "should return ok" do
|
133
|
-
["9134456677", "5444456677"].each do |value|
|
134
|
-
@resource.phone_number_attr = value
|
135
|
-
@resource.valid?.should be_truthy
|
136
|
-
end
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
describe "#phone_extension" do
|
141
|
-
it "should return error" do
|
142
|
-
["-1", "qwert"].each do |value|
|
143
|
-
@resource.phone_extension_attr = value
|
144
|
-
@resource.valid?.should be_falsey
|
145
|
-
@resource.errors.full_messages.should == ["Phone extension attr accepts only numbers (0-9)"]
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
it "should return ok" do
|
150
|
-
["123", "123456"].each do |value|
|
151
|
-
@resource.phone_extension_attr = value
|
152
|
-
@resource.valid?.should be_truthy
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
|
158
|
-
describe "#domain" do
|
159
|
-
it "should return error" do
|
160
|
-
[">*", "<test", "test-er"].each do |value|
|
161
|
-
@resource.domain_attr = value
|
162
|
-
@resource.valid?.should be_falsey
|
163
|
-
@resource.errors.full_messages.should == ["Domain attr should look like a domain name."]
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
it "should return error with more than 63 chars" do
|
168
|
-
@resource.domain_attr = "a" * 64 + ".com"
|
169
|
-
@resource.valid?.should be_falsey
|
170
|
-
@resource.errors.full_messages.should == ["Domain attr is too long (maximum is 63 characters)"]
|
171
|
-
end
|
172
|
-
|
173
|
-
|
174
|
-
it "should return ok" do
|
175
|
-
["test.com", "hey.com", "dynamicadvisorsgroup.com", "advisorsexcel.com"].each do |value|
|
176
|
-
@resource.domain_attr = value
|
177
|
-
@resource.valid?.should be_truthy
|
178
|
-
end
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
|
-
describe "#zipcode" do
|
183
|
-
it "should return error" do
|
184
|
-
["5555", "5555555555","-99999"].each do |value|
|
185
|
-
@resource.zipcode_attr = value
|
186
|
-
@resource.valid?.should be_falsey
|
187
|
-
@resource.errors.full_messages.should == ["Zipcode attr must contain 5 or 9 numbers"]
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
it "should return ok" do
|
192
|
-
["11111", "333333333"].each do |value|
|
193
|
-
@resource.zipcode_attr = value
|
194
|
-
@resource.valid?.should be_truthy
|
195
|
-
end
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
|
200
|
-
describe "#middle_initial" do
|
201
|
-
it "should return error" do
|
202
|
-
["k c", "55555", "55555-5555", "55555 5555", "55555.5555", "(888)88-9999", " ,-99999"].each do |value|
|
203
|
-
@resource.middle_initial_attr = value
|
204
|
-
@resource.valid?.should be_falsey
|
205
|
-
@resource.errors.full_messages.should == ["Middle initial attr accepts only one letter"]
|
206
|
-
end
|
207
|
-
end
|
208
|
-
|
209
|
-
it "should return ok" do
|
210
|
-
["a", "A"].each do |value|
|
211
|
-
@resource.middle_initial_attr = value
|
212
|
-
@resource.valid?.should be_truthy
|
213
|
-
end
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
|
-
describe "#dollar" do
|
218
|
-
it "should return error" do
|
219
|
-
["0.2222"].each do |value|
|
220
|
-
@resource.dollar_attr = value
|
221
|
-
@resource.valid?.should be_falsey
|
222
|
-
@resource.errors.full_messages.should == ["Dollar attr accepts only numeric characters, period, and negative sign"]
|
223
|
-
end
|
224
|
-
end
|
225
|
-
|
226
|
-
it "should return ok" do
|
227
|
-
["0", "1", "100", "1000", "-1000.99"].each do |value|
|
228
|
-
@resource.dollar_attr = value
|
229
|
-
@resource.valid?.should be_truthy
|
230
|
-
end
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
|
-
|
235
|
-
describe "#positive dollar" do
|
236
|
-
it "should return error" do
|
237
|
-
["-0.2", "-1"].each do |value|
|
238
|
-
@resource.positive_dollar_attr = value
|
239
|
-
@resource.valid?.should be_falsey
|
240
|
-
@resource.errors.full_messages.should == ["Positive dollar attr accepts only numeric characters, period", "Positive dollar attr must be greater than or equal to 0"]
|
241
|
-
end
|
242
|
-
end
|
243
|
-
|
244
|
-
it "should return ok" do
|
245
|
-
["1", "100", "1000", "1000.99"].each do |value|
|
246
|
-
@resource.positive_dollar_attr = value
|
247
|
-
@resource.valid?.should be_truthy
|
248
|
-
end
|
249
|
-
end
|
250
|
-
end
|
251
|
-
|
252
|
-
describe "#percent" do
|
253
|
-
it "should return error" do
|
254
|
-
["ewqr", "&"].each do |value|
|
255
|
-
@resource.percent_attr = value
|
256
|
-
@resource.valid?.should be_falsey
|
257
|
-
@resource.errors.full_messages.should == ["Percent attr accepts only numeric characters, period, negative sign, and must be equal/less/greater than +/- 100"]
|
258
|
-
end
|
259
|
-
end
|
260
|
-
|
261
|
-
it "should return ok" do
|
262
|
-
["99.999", "0.001", "99"].each do |value|
|
263
|
-
@resource.percent_attr = value
|
264
|
-
@resource.valid?.should be_truthy
|
265
|
-
end
|
266
|
-
end
|
267
|
-
end
|
268
|
-
|
269
|
-
|
270
|
-
describe "#positive_percent" do
|
271
|
-
it "should return error" do
|
272
|
-
["-100"].each do |value|
|
273
|
-
@resource.positive_percent_attr = value
|
274
|
-
@resource.valid?.should be_falsey
|
275
|
-
@resource.errors.full_messages.should == ["Positive percent attr accepts only numeric characters, period, and must be less than 100", "Positive percent attr must be greater than or equal to 0"]
|
276
|
-
end
|
277
|
-
end
|
278
|
-
|
279
|
-
it "should return ok" do
|
280
|
-
["99.999", "0.001", "99"].each do |value|
|
281
|
-
@resource.positive_percent_attr = value
|
282
|
-
@resource.valid?.should be_truthy
|
283
|
-
end
|
284
|
-
end
|
285
|
-
end
|
286
|
-
|
287
|
-
describe "#url" do
|
288
|
-
it "should return error" do
|
289
|
-
["ewqr", "&", "test.c", "www.test", "test.", "www-test.com"].each do |value|
|
290
|
-
@resource.url_attr = value
|
291
|
-
@resource.valid?.should be_falsey
|
292
|
-
@resource.errors.full_messages.should == ["Url attr web address isnt valid"]
|
293
|
-
end
|
294
|
-
end
|
295
|
-
|
296
|
-
it "should return ok" do
|
297
|
-
["http://www.example.com", "http://fiance.example.com"].each do |value|
|
298
|
-
@resource.url_attr = value
|
299
|
-
@resource.valid?.should be_truthy
|
300
|
-
end
|
301
|
-
end
|
302
|
-
end
|
303
|
-
|
304
|
-
describe "#ssn" do
|
305
|
-
it "should return error" do
|
306
|
-
["111-111-111"].each do |value|
|
307
|
-
@resource.ssn_attr = value
|
308
|
-
@resource.valid?.should be_falsey
|
309
|
-
@resource.errors.full_messages.should == ["Ssn attr is the wrong length (should be 9 characters)", "Ssn attr must be in the format 111-11-1111"]
|
310
|
-
end
|
311
|
-
end
|
312
|
-
|
313
|
-
it "should return ok" do
|
314
|
-
["111111111"].each do |value|
|
315
|
-
@resource.ssn_attr = value
|
316
|
-
@resource.valid?.should be_truthy
|
317
|
-
end
|
318
|
-
end
|
319
|
-
end
|
320
|
-
|
321
|
-
describe "#taxid" do
|
322
|
-
it "should return error" do
|
323
|
-
@resource.taxid_attr = "ab-cdefgh"
|
324
|
-
@resource.valid?.should be_falsey
|
325
|
-
@resource.errors.full_messages.should == ["Taxid attr must be in the format 11-1111111"]
|
326
|
-
end
|
327
|
-
|
328
|
-
it "should return error is is less or more than 9 chars" do
|
329
|
-
["111", "1111111111"].each do |value|
|
330
|
-
@resource.taxid_attr = value
|
331
|
-
@resource.valid?.should be_falsey
|
332
|
-
@resource.errors.full_messages.should == ["Taxid attr is the wrong length (should be 9 characters)", "Taxid attr must be in the format 11-1111111"]
|
333
|
-
end
|
334
|
-
end
|
335
|
-
|
336
|
-
it "should return ok" do
|
337
|
-
["111111111"].each do |value|
|
338
|
-
@resource.taxid_attr = value
|
339
|
-
@resource.valid?.should be_truthy
|
340
|
-
end
|
341
|
-
end
|
342
|
-
end
|
343
|
-
|
344
|
-
|
345
|
-
describe "#age" do
|
346
|
-
it "should return error" do
|
347
|
-
@resource.age_attr = "111"
|
348
|
-
@resource.valid?.should be_falsey
|
349
|
-
@resource.errors.full_messages.should == ["Age attr must contain only 3 numbers and less than 110"]
|
350
|
-
end
|
351
|
-
|
352
|
-
it "should return ok" do
|
353
|
-
["1", "10", "100"].each do |value|
|
354
|
-
@resource.age_attr = value
|
355
|
-
@resource.valid?.should be_truthy
|
356
|
-
end
|
357
|
-
end
|
358
|
-
end
|
359
|
-
|
360
|
-
describe "#number" do
|
361
|
-
it "should return error" do
|
362
|
-
@resource.number_attr = "aaa"
|
363
|
-
@resource.valid?.should be_falsey
|
364
|
-
@resource.errors.full_messages.should == ["Number attr accepts only numbers (0-9)"]
|
365
|
-
end
|
27
|
+
class NormalizedResource < Resource
|
28
|
+
has_normalized_attributes :name_attr => :strip,
|
29
|
+
:safe_text_attr => :strip,
|
30
|
+
:username_attr => :strip,
|
31
|
+
:email_attr => :strip,
|
32
|
+
:phone_number_attr => :phone,
|
33
|
+
:phone_extension_attr => :strip,
|
34
|
+
:domain_attr => :strip,
|
35
|
+
:zipcode_attr => :strip,
|
36
|
+
:middle_initial_attr => :strip,
|
37
|
+
:dollar_attr => :dollar,
|
38
|
+
:positive_dollar_attr => :dollar,
|
39
|
+
:percent_attr => :percent,
|
40
|
+
:positive_percent_attr => :percent,
|
41
|
+
:url_attr => :strip,
|
42
|
+
:ssn_attr => :ssn,
|
43
|
+
:taxid_attr => :taxid,
|
44
|
+
:age_attr => :number,
|
45
|
+
:number_attr => :number,
|
46
|
+
:rails_name_attr => :strip
|
47
|
+
end
|
366
48
|
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
49
|
+
describe "HasValidatedAttributes" do
|
50
|
+
context "unnormalized attributes" do
|
51
|
+
describe Resource do
|
52
|
+
has_validated_name_attribute(:name_attr, length: 10)
|
53
|
+
has_validated_username_attribute(:username_attr)
|
54
|
+
has_validated_email_attribute(:email_attr)
|
55
|
+
has_validated_zipcode_attribute(:zipcode_attr)
|
56
|
+
has_validated_phone_number_attribute(:phone_number_attr)
|
57
|
+
has_validated_phone_extension_attribute(:phone_extension_attr)
|
58
|
+
has_validated_url_attribute(:url_attr)
|
59
|
+
has_validated_positive_percent_attribute(:positive_percent_attr)
|
60
|
+
has_validated_percent_attribute(:percent_attr)
|
61
|
+
has_validated_age_attribute(:age_attr)
|
62
|
+
has_validated_positive_dollar_attribute(:positive_dollar_attr)
|
63
|
+
has_validated_dollar_attribute(:dollar_attr)
|
64
|
+
has_validated_number_attribute(:number_attr)
|
65
|
+
has_validated_rails_name_attribute(:rails_name_attr)
|
66
|
+
has_validated_taxid_attribute(:taxid_attr)
|
67
|
+
has_validated_ssn_attribute(:ssn_attr)
|
68
|
+
has_validated_safe_text_attribute(:safe_text_attr)
|
69
|
+
has_validated_domain_attribute(:domain_attr)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "normalized attributes" do
|
74
|
+
describe NormalizedResource do
|
75
|
+
has_validated_phone_number_attribute(:phone_number_attr, normalized: true)
|
76
|
+
has_validated_positive_dollar_attribute(:positive_dollar_attr, normalized: true)
|
77
|
+
has_validated_dollar_attribute(:dollar_attr, normalized: true)
|
78
|
+
has_validated_number_attribute(:number_attr, normalized: true)
|
79
|
+
has_validated_taxid_attribute(:taxid_attr, normalized: true)
|
80
|
+
has_validated_ssn_attribute(:ssn_attr, normalized: true)
|
372
81
|
end
|
373
82
|
end
|
374
83
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "active_support"
|
2
2
|
require "active_record"
|
3
|
+
require "has_normalized_attributes"
|
3
4
|
require "database_cleaner"
|
4
5
|
require "yaml"
|
5
6
|
|
@@ -16,7 +17,9 @@ load(File.dirname(__FILE__) + "/db/schema.rb")
|
|
16
17
|
# Load in our code
|
17
18
|
$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
|
18
19
|
|
20
|
+
require 'shoulda-matchers'
|
19
21
|
require 'has_validated_attributes'
|
22
|
+
require 'has_validated_attributes/rspec'
|
20
23
|
|
21
24
|
RSpec.configure do |config|
|
22
25
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: has_validated_attributes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kyle Ginavan
|
@@ -24,6 +24,40 @@ dependencies:
|
|
24
24
|
- - '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: shoulda-matchers
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: has_normalized_attributes
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.0'
|
48
|
+
- - '>='
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: 0.0.8
|
51
|
+
type: :development
|
52
|
+
prerelease: false
|
53
|
+
version_requirements: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ~>
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0.0'
|
58
|
+
- - '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 0.0.8
|
27
61
|
- !ruby/object:Gem::Dependency
|
28
62
|
name: activerecord
|
29
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -81,6 +115,7 @@ files:
|
|
81
115
|
- Rakefile
|
82
116
|
- has_validated_attributes.gemspec
|
83
117
|
- lib/has_validated_attributes.rb
|
118
|
+
- lib/has_validated_attributes/rspec.rb
|
84
119
|
- lib/version.rb
|
85
120
|
- spec/db/database.yml
|
86
121
|
- spec/db/schema.rb
|