rails_validations 1.1.4 → 1.2
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.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
|