rails_validations 1.1.4 → 1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.markdown +34 -11
- data/config/locales/nl.yml +1 -1
- data/lib/validators/date_validator.rb +14 -15
- data/lib/validators/domain_validator.rb +25 -4
- data/lib/validators/email_validator.rb +7 -7
- data/lib/validators/iban_validator.rb +3 -1
- data/lib/validators/phone_validator.rb +6 -4
- data/spec/spec_helper.rb +29 -10
- data/spec/validations/date_spec.rb +19 -18
- data/spec/validations/domain_spec.rb +10 -8
- data/spec/validations/email_spec.rb +10 -11
- data/spec/validations/iban_spec.rb +12 -2
- data/spec/validations/phone_spec.rb +4 -3
- data/spec/validations/postal_code_spec.rb +3 -2
- metadata +3 -4
- data/lib/validators/presence_of_validator.rb +0 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 101607105b5fc99a8762be3fc19f1b98c5195706
|
4
|
+
data.tar.gz: d0486ef2ac9c0577b8d79c95c1370a0f7d5ce46d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1bbb66d567952305ba3d4832e18d7c5d15cc300d09cda5e519b6bda959cb83052e61fbc0771fb64d288ccd16ebe5908e667bce8f660aa3fc0866775ba8063473
|
7
|
+
data.tar.gz: 7fa7a7624e58f7cd31e2e8543c1bc003d9ed9ca1efe972ba303fad0c67caac0517a88738d4a4c0eb55ac9067d37459ef39c097aeed06d72298da67e4590ebbd9
|
data/README.markdown
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
[](http://inch-ci.org/github/bluerail/rails_validations)
|
5
5
|
|
6
6
|
|
7
|
-
A few extra validations for Rails.
|
7
|
+
A few extra validations for Ruby on Rails.
|
8
8
|
|
9
9
|
We try to do the ‘sane’ thing by not being too strict, when in doubt, we accept
|
10
10
|
input as being valid. We never want to reject valid input as invalid.
|
@@ -16,16 +16,26 @@ example, email validators will accept `artin@ico.nl` as being ‘valid’, even
|
|
16
16
|
though my email address is `martin@lico.nl.`.
|
17
17
|
|
18
18
|
|
19
|
+
|
20
|
+
|
21
|
+
Available validations
|
22
|
+
=====================
|
23
|
+
|
19
24
|
date
|
20
25
|
----
|
21
26
|
Validate if a column is a valid date, and if it’s before or after another date.
|
22
27
|
|
28
|
+
# Check if it looks like a valid date
|
23
29
|
validates :date_column, date: true
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
validates :date_column, date: {
|
30
|
+
|
31
|
+
# We use a lambda for these checks because otherwise Date.today would be
|
32
|
+
# evaluated *only* on startup, and not every time we run the validations
|
33
|
+
# (you never want this).
|
34
|
+
validates :date_column, date: { after: -> { Date.today } }
|
35
|
+
validates :date_column, date: { after_or_equal_to: -> { Date.today } }
|
36
|
+
validates :date_column, date: { equal_to: -> { Date.today } }
|
37
|
+
validates :date_column, date: { before: -> { Date.today } }
|
38
|
+
validates :date_column, date: { before_or_equal_to: -> { Date.today } }
|
29
39
|
|
30
40
|
Check if the column `enddate` is after the value of the column `begindate`:
|
31
41
|
|
@@ -41,7 +51,7 @@ This will accept `lico.nl`, but rejects `martin@lico.nl`:
|
|
41
51
|
|
42
52
|
validates :domain_column, domain: true
|
43
53
|
|
44
|
-
Set a minimum
|
54
|
+
Set a minimum and maximum number of domain parts (aka. labels), this will accept
|
45
55
|
`lico.nl`, but rejects `lico`:
|
46
56
|
|
47
57
|
validates :domain_column, domain: { min_domain_parts: 2 }
|
@@ -53,10 +63,10 @@ Accept `lico.nl`, but reject `www.lico.nl`:
|
|
53
63
|
|
54
64
|
email
|
55
65
|
-----
|
56
|
-
Validate if a string looks
|
66
|
+
Validate if a string looks like an email address. This should work with unicode
|
57
67
|
addresses ([RFC 6531][rfc6531], [IDN][idn]).
|
58
68
|
|
59
|
-
Accepts `martin@lico.nl`, but rejects `martinlico.nl` or `martin@lico
|
69
|
+
Accepts `martin@lico.nl`, but rejects `martinlico.nl` or `martin@lico`:
|
60
70
|
|
61
71
|
validates :email_column, email: true
|
62
72
|
|
@@ -68,13 +78,18 @@ Check if this is a valid IBAN account number. This uses the
|
|
68
78
|
|
69
79
|
validates :iban_column, iban: true
|
70
80
|
|
81
|
+
By default we set “not a valid IBAN account number” as the error message, but we
|
82
|
+
can also set more detailed errors:
|
83
|
+
|
84
|
+
validates :iban_column, iban: { detailed_errors: true }
|
85
|
+
|
71
86
|
|
72
87
|
phone
|
73
88
|
-----
|
74
89
|
Check if this is a valid phone number. This should work with most, if not all,
|
75
90
|
writing conventions. We consider a phone to be valid if it consists of numbers &
|
76
|
-
any
|
77
|
-
accepted.
|
91
|
+
any amount of ` \-.()` characters. A country code at the start indicated with
|
92
|
+
`+` is also accepted.
|
78
93
|
|
79
94
|
validates :phone_column, phone: true
|
80
95
|
|
@@ -96,6 +111,14 @@ Currently implemented countries:
|
|
96
111
|
|
97
112
|
ChangeLog
|
98
113
|
=========
|
114
|
+
Version 1.2, 2015-03-07
|
115
|
+
-----------------------
|
116
|
+
- The IBAN check will now defaults to just a "is invalid" message, set the
|
117
|
+
`detailed_errors` option to get the more detailed errors.
|
118
|
+
- Also allow emails with multiple domains (e.g. `test@hello.world.example.com`).
|
119
|
+
- Date validation now accepts a custom message.
|
120
|
+
|
121
|
+
|
99
122
|
Version 1.1.4, 2014-12-28
|
100
123
|
-------------------------
|
101
124
|
- Bugfix for Date validator when comparing to other columns that are a String.
|
data/config/locales/nl.yml
CHANGED
@@ -1,29 +1,28 @@
|
|
1
1
|
# Validate if a column is a valid date, and if it's before or after another date.
|
2
2
|
#
|
3
3
|
# validates :date_column, date: true
|
4
|
-
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
4
|
+
#
|
5
|
+
# We use a lambda for these checks because otherwise Date.today would be
|
6
|
+
# evaluated *only* on startup, and not every time we run the validations
|
7
|
+
# (you never want this).
|
8
|
+
#
|
9
|
+
# validates :date_column, date: { after: -> { Date.today } }
|
10
|
+
# validates :date_column, date: { after_or_equal_to: -> { Date.today } }
|
11
|
+
# validates :date_column, date: { equal_to: -> { Date.today } }
|
12
|
+
# validates :date_column, date: { before: -> { Date.today } }
|
13
|
+
# validates :date_column, date: { before_or_equal_to: -> { Date.today } }
|
9
14
|
#
|
10
15
|
# Check if the column `enddate` is after the value of the column `begindate`
|
16
|
+
#
|
11
17
|
# validates :begindate, date: true
|
12
18
|
# validates :enddate, date: { after: :begindate }
|
13
19
|
class DateValidator < ActiveModel::EachValidator
|
14
20
|
CHECKS = {
|
15
|
-
# These keys make the most sense for dates
|
16
21
|
after: :>,
|
17
22
|
after_or_equal_to: :>=,
|
18
23
|
equal_to: :==,
|
19
24
|
before: :<,
|
20
25
|
before_or_equal_to: :<=,
|
21
|
-
|
22
|
-
# For compatibility with numericality
|
23
|
-
#greater_than: :>,
|
24
|
-
#greater_than_or_equal_to: :>=,
|
25
|
-
#less_than: :<,
|
26
|
-
#less_than_or_equal_to: :<=,
|
27
26
|
}.freeze
|
28
27
|
|
29
28
|
|
@@ -48,7 +47,7 @@ class DateValidator < ActiveModel::EachValidator
|
|
48
47
|
value = value_to_date raw_value
|
49
48
|
|
50
49
|
unless value
|
51
|
-
record.errors.add attribute, I18n.t('rails_validations.date.invalid')
|
50
|
+
record.errors.add attribute, (options[:message] || I18n.t('rails_validations.date.invalid'))
|
52
51
|
return
|
53
52
|
end
|
54
53
|
|
@@ -70,12 +69,12 @@ class DateValidator < ActiveModel::EachValidator
|
|
70
69
|
end
|
71
70
|
|
72
71
|
unless option_value
|
73
|
-
record.errors.add attribute, I18n.t('rails_validations.date.invalid')
|
72
|
+
record.errors.add attribute, (options[:message] || I18n.t('rails_validations.date.invalid'))
|
74
73
|
return
|
75
74
|
end
|
76
75
|
|
77
76
|
unless value.send CHECKS[option], option_value
|
78
|
-
record.errors.add attribute, I18n.t("rails_validations.date.#{option}", date: I18n.l(option_value))
|
77
|
+
record.errors.add attribute, (options[:message] || I18n.t("rails_validations.date.#{option}", date: I18n.l(option_value)))
|
79
78
|
end
|
80
79
|
end
|
81
80
|
end
|
@@ -1,17 +1,38 @@
|
|
1
|
-
# Validate if a string is a valid domain. This should work with
|
1
|
+
# Validate if a string is a valid domain. This should work with IDN.
|
2
2
|
#
|
3
3
|
# validates :domain_column, domain: true
|
4
4
|
#
|
5
|
-
# Set a minimum
|
5
|
+
# Set a minimum and maximum number of domain parts (aka. labels)
|
6
6
|
#
|
7
7
|
# validates :domain_column, domain: { min_domain_parts: 2 }
|
8
8
|
# validates :domain_column, domain: { max_domain_parts: 2 }
|
9
9
|
class DomainValidator < ActiveModel::EachValidator
|
10
|
-
|
10
|
+
# RFC 1034, section 3.1:
|
11
|
+
# Each node has a label, which is zero to 63 octets in length.
|
12
|
+
#
|
13
|
+
# RFC 1035, secion 2.3.1:
|
14
|
+
# <label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]
|
15
|
+
#
|
16
|
+
# <let-dig> ::= <letter> | <digit>
|
17
|
+
#
|
18
|
+
# <letter> ::= any one of the 52 alphabetic characters A through Z in
|
19
|
+
# upper case and a through z in lower case
|
20
|
+
#
|
21
|
+
# <digit> ::= any one of the ten digits 0 through 9
|
22
|
+
#
|
23
|
+
# [...]
|
24
|
+
#
|
25
|
+
# Labels must be 63 characters or less.
|
26
|
+
#
|
27
|
+
# TODO: There are more considerations, especially for IDN. RFC5891 section 4.2
|
28
|
+
# lists some.
|
11
29
|
REGEXP = /
|
12
|
-
\A
|
30
|
+
\A
|
31
|
+
[\p{L}\d-]{1,63} # \p{L} is any unicode character in the category "Letter"
|
32
|
+
\z
|
13
33
|
/ix.freeze
|
14
34
|
|
35
|
+
|
15
36
|
def validate_each record, attribute, value
|
16
37
|
parts = value.split '.'
|
17
38
|
|
@@ -3,17 +3,17 @@
|
|
3
3
|
# The validation is intentionally simply, you can never be sure an email is
|
4
4
|
# valid anyway (a user can mistype gmail as gmaill, for example).
|
5
5
|
#
|
6
|
-
# -
|
7
|
-
# -
|
8
|
-
# - tld part: 2 or more word characters
|
6
|
+
# - User part: one or more characters except @ or whitespace.
|
7
|
+
# - Domain part: 1 or more character except @ or whitespace.
|
8
|
+
# - tld part: 2 or more word characters, numbers, or -
|
9
9
|
class EmailValidator < ActiveModel::EachValidator
|
10
10
|
REGEXP = /\A
|
11
11
|
[^@\s]+
|
12
12
|
@
|
13
|
-
[
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
([\p{L}\d-]+\.)+ # \p{L} is any unicode character in the category "Letter"
|
14
|
+
[\p{L}\d\-]{2,}
|
15
|
+
\z
|
16
|
+
/ix.freeze
|
17
17
|
|
18
18
|
def validate_each record, attribute, value
|
19
19
|
record.errors.add attribute, (options[:message] || I18n.t('rails_validations.email.invalid')) unless value =~ REGEXP
|
@@ -10,8 +10,10 @@ class IbanValidator < ActiveModel::EachValidator
|
|
10
10
|
|
11
11
|
if options[:message]
|
12
12
|
record.errors.add attribute, options[:message]
|
13
|
-
|
13
|
+
elsif options[:detailed_errors]
|
14
14
|
errors.each { |e| record.errors.add attribute, I18n.t("rails_validations.iban.#{e}") }
|
15
|
+
else
|
16
|
+
record.errors.add attribute, I18n.t("rails_validations.iban.invalid")
|
15
17
|
end
|
16
18
|
end
|
17
19
|
end
|
@@ -1,10 +1,12 @@
|
|
1
1
|
# Basic check for a telephone number; this should work with most, of not all,
|
2
2
|
# writing conventions.
|
3
3
|
class PhoneValidator < ActiveModel::EachValidator
|
4
|
-
REGEXP =
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
REGEXP = /
|
5
|
+
\A
|
6
|
+
(\(?\+\d+\)?)? # optional country code
|
7
|
+
[\d \-.()]{4,20}
|
8
|
+
\z
|
9
|
+
/x.freeze
|
8
10
|
|
9
11
|
def validate_each record, attribute, value
|
10
12
|
record.errors.add attribute, (options[:message] || I18n.t('rails_validations.phone.invalid')) unless value =~ REGEXP
|
data/spec/spec_helper.rb
CHANGED
@@ -11,16 +11,12 @@ require 'active_record'
|
|
11
11
|
require 'active_support'
|
12
12
|
require 'active_support/all'
|
13
13
|
|
14
|
-
#require 'rspec/rails'
|
15
|
-
|
16
|
-
# Requires supporting files with custom matchers and macros, etc,
|
17
|
-
# in ./support/ and its subdirectories in alphabetic order.
|
18
|
-
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].sort.each { |f| require f }
|
19
14
|
|
15
|
+
# Include our validators
|
20
16
|
Dir["#{File.dirname(__FILE__)}/../lib/**/*.rb"].sort.each { |f| require f }
|
21
17
|
|
18
|
+
# Make sure I18N works
|
22
19
|
I18n.enforce_available_locales = false if I18n.respond_to?(:enforce_available_locales)
|
23
|
-
|
24
20
|
I18n.load_path += Dir["#{File.dirname(__FILE__)}/../config/locales/*.yml"]
|
25
21
|
|
26
22
|
|
@@ -33,10 +29,9 @@ module ValidationsSpecHelper
|
|
33
29
|
|
34
30
|
|
35
31
|
class Record
|
36
|
-
extend ActiveModel::Naming
|
37
|
-
include ActiveModel::Conversion
|
38
|
-
include ActiveModel::Validations
|
39
|
-
|
32
|
+
extend ActiveModel::Naming
|
33
|
+
include ActiveModel::Conversion
|
34
|
+
include ActiveModel::Validations
|
40
35
|
|
41
36
|
def initialize attr={}
|
42
37
|
attr.each { |k, v| send("#{k}=", v) }
|
@@ -70,3 +65,27 @@ module ValidationsSpecHelper
|
|
70
65
|
yield
|
71
66
|
end
|
72
67
|
end
|
68
|
+
|
69
|
+
|
70
|
+
RSpec::Matchers.define :be_valid do
|
71
|
+
match { |record | record.valid? == true && record.errors.blank? }
|
72
|
+
end
|
73
|
+
|
74
|
+
RSpec::Matchers.define :be_invalid do |i18n_key, i18n_params={}|
|
75
|
+
match do |record|
|
76
|
+
record.valid? == false &&
|
77
|
+
record.errors.first.present? &&
|
78
|
+
record.errors.first[1] == I18n.t("rails_validations.#{i18n_key}", **i18n_params)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
shared_examples :validation do |validation|
|
84
|
+
it 'accepts a custom error message' do
|
85
|
+
with_validation "#{validation}: { message: 'foobar' }" do
|
86
|
+
m = described_class.new v: 'not even remotely valid'
|
87
|
+
expect(m.valid?).to eq(false)
|
88
|
+
expect(m.errors[:v].first).to eq('foobar')
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -9,63 +9,64 @@ end
|
|
9
9
|
describe ValidationsSpecHelper::Date do
|
10
10
|
include ValidationsSpecHelper
|
11
11
|
|
12
|
+
it_behaves_like :validation, 'date'
|
12
13
|
|
13
14
|
it 'works with true' do
|
14
15
|
with_validation 'date: true' do
|
15
|
-
expect(model(Date.today)
|
16
|
-
expect(model(Time.now)
|
16
|
+
expect(model(Date.today)).to be_valid
|
17
|
+
expect(model(Time.now)).to be_valid
|
17
18
|
end
|
18
19
|
end
|
19
20
|
|
20
21
|
|
21
22
|
it 'works with :after' do
|
22
23
|
with_validation 'date: { after: ::Date.today }' do
|
23
|
-
expect(model(Date.today
|
24
|
-
expect(model(Date.today
|
25
|
-
expect(model(Date.today.advance days: -1)
|
24
|
+
expect(model(Date.today.advance days: 1)).to be_valid
|
25
|
+
expect(model(Date.today)).to be_invalid('date.after', date: Date.today)
|
26
|
+
expect(model(Date.today.advance days: -1)).to be_invalid('date.after', date: Date.today)
|
26
27
|
end
|
27
28
|
end
|
28
29
|
|
29
30
|
|
30
31
|
it 'works with :after_or_equal_to:' do
|
31
32
|
with_validation 'date: { after_or_equal_to: ::Date.today }' do
|
32
|
-
expect(model(Date.today)
|
33
|
-
expect(model(Date.today.advance days: 1)
|
34
|
-
expect(model(Date.today.advance days: -1)
|
33
|
+
expect(model(Date.today)).to be_valid
|
34
|
+
expect(model(Date.today.advance days: 1)).to be_valid
|
35
|
+
expect(model(Date.today.advance days: -1)).to be_invalid('date.after_or_equal_to', date: Date.today)
|
35
36
|
end
|
36
37
|
end
|
37
38
|
|
38
39
|
|
39
40
|
it 'works with :equal_to' do
|
40
41
|
with_validation 'date: { equal_to: ::Date.today }' do
|
41
|
-
expect(model(Date.today)
|
42
|
-
expect(model(Date.today.advance days: 1)
|
43
|
-
expect(model(Date.today.advance days: -1)
|
42
|
+
expect(model(Date.today)).to be_valid
|
43
|
+
expect(model(Date.today.advance days: 1)).to be_invalid('date.equal_to', date: Date.today)
|
44
|
+
expect(model(Date.today.advance days: -1)).to be_invalid('date.equal_to', date: Date.today)
|
44
45
|
end
|
45
46
|
end
|
46
47
|
|
47
48
|
|
48
49
|
it 'works with :before' do
|
49
50
|
with_validation 'date: { before: ::Date.today }' do
|
50
|
-
expect(model(Date.today
|
51
|
-
expect(model(Date.today
|
52
|
-
expect(model(Date.today.advance days:
|
51
|
+
expect(model(Date.today.advance days: -1)).to be_valid
|
52
|
+
expect(model(Date.today)).to be_invalid('date.before', date: Date.today)
|
53
|
+
expect(model(Date.today.advance days: 1)).to be_invalid('date.before', date: Date.today)
|
53
54
|
end
|
54
55
|
end
|
55
56
|
|
56
57
|
|
57
58
|
it 'works with :before_or_equal_to' do
|
58
59
|
with_validation 'date: { before_or_equal_to: ::Date.today }' do
|
59
|
-
expect(model(Date.today)
|
60
|
-
expect(model(Date.today.advance days: 1)
|
61
|
-
expect(model(Date.today.advance days:
|
60
|
+
expect(model(Date.today)).to be_valid
|
61
|
+
expect(model(Date.today.advance days: -1)).to be_valid
|
62
|
+
expect(model(Date.today.advance days: 1)).to be_invalid('date.before_or_equal_to', date: Date.today)
|
62
63
|
end
|
63
64
|
end
|
64
65
|
|
65
66
|
|
66
67
|
it "works with input that is not even remotely a date" do
|
67
68
|
with_validation 'date: true' do
|
68
|
-
expect(model('Yesterday, a fish nibbled my toe.')).
|
69
|
+
expect(model('Yesterday, a fish nibbled my toe.')).to be_invalid('date.invalid')
|
69
70
|
end
|
70
71
|
end
|
71
72
|
|
@@ -9,6 +9,8 @@ end
|
|
9
9
|
describe ValidationsSpecHelper::Domain do
|
10
10
|
include ValidationsSpecHelper
|
11
11
|
|
12
|
+
it_behaves_like :validation, 'domain'
|
13
|
+
|
12
14
|
it 'gives an error on invalid domains' do
|
13
15
|
with_validation 'domain: true' do
|
14
16
|
%w{
|
@@ -16,7 +18,7 @@ describe ValidationsSpecHelper::Domain do
|
|
16
18
|
li_co.nl
|
17
19
|
lico@nl
|
18
20
|
}.each do |v|
|
19
|
-
expect(model(v)
|
21
|
+
expect(model(v)).to be_invalid('domain.invalid')
|
20
22
|
end
|
21
23
|
end
|
22
24
|
end
|
@@ -31,7 +33,7 @@ describe ValidationsSpecHelper::Domain do
|
|
31
33
|
hello.world.www.lico.nl
|
32
34
|
ﻢﻔﺗﻮﺣ.ﺬﺑﺎﺑﺓ
|
33
35
|
}.each do |v|
|
34
|
-
expect(model(v)
|
36
|
+
expect(model(v)).to be_valid
|
35
37
|
end
|
36
38
|
end
|
37
39
|
end
|
@@ -39,18 +41,18 @@ describe ValidationsSpecHelper::Domain do
|
|
39
41
|
|
40
42
|
it 'works with :max_domain_parts' do
|
41
43
|
with_validation 'domain: { max_domain_parts: 3 }' do
|
42
|
-
expect(model('not.many')
|
43
|
-
expect(model('not.too.many')
|
44
|
-
expect(model('too.many.domain.parts')
|
44
|
+
expect(model('not.many')).to be_valid
|
45
|
+
expect(model('not.too.many')).to be_valid
|
46
|
+
expect(model('too.many.domain.parts')).to be_invalid('domain.max_domain_parts', max: 3)
|
45
47
|
end
|
46
48
|
end
|
47
49
|
|
48
50
|
|
49
51
|
it 'works with :min' do
|
50
52
|
with_validation 'domain: { min_domain_parts: 3 }' do
|
51
|
-
expect(model('
|
52
|
-
expect(model('
|
53
|
-
expect(model('
|
53
|
+
expect(model('just.enough.parts')).to be_valid
|
54
|
+
expect(model('more.than.enough.parts')).to be_valid
|
55
|
+
expect(model('too.few')).to be_invalid('domain.min_domain_parts', min: 3)
|
54
56
|
end
|
55
57
|
end
|
56
58
|
end
|
@@ -9,6 +9,7 @@ end
|
|
9
9
|
describe ValidationsSpecHelper::Email do
|
10
10
|
include ValidationsSpecHelper
|
11
11
|
|
12
|
+
it_behaves_like :validation, 'email'
|
12
13
|
|
13
14
|
it 'gives an error on invalid emails' do
|
14
15
|
with_validation 'email: true' do
|
@@ -23,8 +24,14 @@ describe ValidationsSpecHelper::Email do
|
|
23
24
|
in\ valid@example.com
|
24
25
|
invalid@exam\ ple.com
|
25
26
|
}.each do |v|
|
26
|
-
expect(model(v)
|
27
|
+
expect(model(v)).to be_invalid('email.invalid')
|
27
28
|
end
|
29
|
+
|
30
|
+
# Newlines in email addresses is a potential security problem, do double
|
31
|
+
# check this
|
32
|
+
expect(model("no\nnewlines@example.com")).to be_invalid('email.invalid')
|
33
|
+
expect(model("no\rnewlines@example.com")).to be_invalid('email.invalid')
|
34
|
+
expect(model("no\r\nnewlines@example.com")).to be_invalid('email.invalid')
|
28
35
|
end
|
29
36
|
end
|
30
37
|
|
@@ -36,20 +43,12 @@ describe ValidationsSpecHelper::Email do
|
|
36
43
|
valid.address@example.com
|
37
44
|
valid-example@example.com
|
38
45
|
valid+address@example.com
|
46
|
+
valid@more.than.one.example.com
|
39
47
|
valid@example.anewtld
|
40
48
|
مفتوح.ذبابة@إرهاب.شبكة
|
41
49
|
}.each do |v|
|
42
|
-
expect(model(v)
|
50
|
+
expect(model(v)).to be_valid
|
43
51
|
end
|
44
52
|
end
|
45
53
|
end
|
46
|
-
|
47
|
-
|
48
|
-
it 'accepts a custom error message' do
|
49
|
-
with_validation 'email: { message: "foobar" }' do
|
50
|
-
m = described_class.new v: 'not even remotely valid'
|
51
|
-
m.valid?
|
52
|
-
expect(m.errors[:v].first).to eq('foobar')
|
53
|
-
end
|
54
|
-
end
|
55
54
|
end
|
@@ -9,6 +9,7 @@ end
|
|
9
9
|
describe ValidationsSpecHelper::Iban do
|
10
10
|
include ValidationsSpecHelper
|
11
11
|
|
12
|
+
it_behaves_like :validation, 'iban'
|
12
13
|
|
13
14
|
it 'accepts a valid IBAN' do
|
14
15
|
with_validation 'iban: true' do
|
@@ -16,7 +17,7 @@ describe ValidationsSpecHelper::Iban do
|
|
16
17
|
NL65AEGO0721647952
|
17
18
|
NL43ABNA0841376913
|
18
19
|
}.each do |v|
|
19
|
-
expect(model(v)
|
20
|
+
expect(model(v)).to be_valid
|
20
21
|
end
|
21
22
|
end
|
22
23
|
end
|
@@ -28,8 +29,17 @@ describe ValidationsSpecHelper::Iban do
|
|
28
29
|
NL65AEGO0721647951
|
29
30
|
not valid
|
30
31
|
}.each do |v|
|
31
|
-
expect(model(v)
|
32
|
+
expect(model(v)).to be_invalid('iban.invalid')
|
32
33
|
end
|
33
34
|
end
|
34
35
|
end
|
36
|
+
|
37
|
+
|
38
|
+
it 'sets detailed errrors' do
|
39
|
+
with_validation 'iban: { detailed_errors: true }' do
|
40
|
+
m = model 'NL61AEGO0721647952'
|
41
|
+
expect(m.valid?).to eq(false)
|
42
|
+
expect(m.errors.first[1]).to eq(I18n.t('rails_validations.iban.bad_check_digits'))
|
43
|
+
end
|
44
|
+
end
|
35
45
|
end
|
@@ -8,7 +8,8 @@ end
|
|
8
8
|
|
9
9
|
describe ValidationsSpecHelper::Phone do
|
10
10
|
include ValidationsSpecHelper
|
11
|
-
|
11
|
+
|
12
|
+
it_behaves_like :validation, 'phone'
|
12
13
|
|
13
14
|
it 'allows valid phone numbers' do
|
14
15
|
with_validation 'phone: true' do
|
@@ -19,7 +20,7 @@ describe ValidationsSpecHelper::Phone do
|
|
19
20
|
(+31)\ 06-51552300
|
20
21
|
(+1)\ 06.51.55.23.00
|
21
22
|
}.each do |v|
|
22
|
-
expect(model(v)
|
23
|
+
expect(model(v)).to be_valid
|
23
24
|
end
|
24
25
|
end
|
25
26
|
end
|
@@ -34,7 +35,7 @@ describe ValidationsSpecHelper::Phone do
|
|
34
35
|
123
|
35
36
|
132131313213213123123213213131231242312554
|
36
37
|
}.each do |v|
|
37
|
-
expect(model(v)
|
38
|
+
expect(model(v)).to be_invalid('phone.invalid')
|
38
39
|
end
|
39
40
|
end
|
40
41
|
end
|
@@ -9,6 +9,7 @@ end
|
|
9
9
|
describe ValidationsSpecHelper::PostalCode do
|
10
10
|
include ValidationsSpecHelper
|
11
11
|
|
12
|
+
it_behaves_like :validation, 'postal_code'
|
12
13
|
|
13
14
|
it 'works for nl codes' do
|
14
15
|
with_validation 'postal_code: { country: :nl }' do
|
@@ -18,7 +19,7 @@ describe ValidationsSpecHelper::PostalCode do
|
|
18
19
|
9999\ aa
|
19
20
|
1234\ AA
|
20
21
|
}.each do |v|
|
21
|
-
expect(model(v)
|
22
|
+
expect(model(v)).to be_valid
|
22
23
|
end
|
23
24
|
end
|
24
25
|
end
|
@@ -32,7 +33,7 @@ describe ValidationsSpecHelper::PostalCode do
|
|
32
33
|
9999\ a
|
33
34
|
1234\ AAA
|
34
35
|
}.each do |v|
|
35
|
-
expect(model(v)
|
36
|
+
expect(model(v)).to be_invalid('postal_code.invalid')
|
36
37
|
end
|
37
38
|
end
|
38
39
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails_validations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: '1.2'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martin Tournoij
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-03-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -85,7 +85,6 @@ files:
|
|
85
85
|
- lib/validators/iban_validator.rb
|
86
86
|
- lib/validators/phone_validator.rb
|
87
87
|
- lib/validators/postal_code_validator.rb
|
88
|
-
- lib/validators/presence_of_validator.rb
|
89
88
|
- spec/spec_helper.rb
|
90
89
|
- spec/validations/date_spec.rb
|
91
90
|
- spec/validations/domain_spec.rb
|
@@ -113,7 +112,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
113
112
|
version: '0'
|
114
113
|
requirements: []
|
115
114
|
rubyforge_project:
|
116
|
-
rubygems_version: 2.
|
115
|
+
rubygems_version: 2.4.5
|
117
116
|
signing_key:
|
118
117
|
specification_version: 4
|
119
118
|
summary: Extra validations for rails
|
@@ -1,29 +0,0 @@
|
|
1
|
-
# Test the presence of attributes from a belongs_to.
|
2
|
-
#
|
3
|
-
# For example, doing this in the User model:
|
4
|
-
#
|
5
|
-
# belongs_to :person
|
6
|
-
# validates :person, presence_of: :initials
|
7
|
-
#
|
8
|
-
# would be the same as your User model containing:
|
9
|
-
#
|
10
|
-
# has_one :user, inverse_of: :person
|
11
|
-
# has_one :admin, inverse_of: :person
|
12
|
-
#
|
13
|
-
# validates :initials, if: :user
|
14
|
-
#
|
15
|
-
# TODO: Unfinished, copied from K4K
|
16
|
-
class PresenceOfValidator < ActiveModel::EachValidator
|
17
|
-
def validate_each record, attribute, value
|
18
|
-
errortext = if options[:with].to_s.pluralize == options[:with].to_s
|
19
|
-
I18n.t('errors.messages.empty_plural')
|
20
|
-
else
|
21
|
-
I18n.t('errors.messages.empty')
|
22
|
-
end
|
23
|
-
|
24
|
-
if record.send(attribute) && record.send(attribute).send(options[:with]).blank?
|
25
|
-
record.send(attribute).errors[options[:with]] << errortext
|
26
|
-
record.errors["#{attribute}.#{options[:with]}"] << errortext
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|