active_validation 1.1.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +3 -1
  3. data/active_validation.gemspec +1 -0
  4. data/config/locales/en.yml +4 -0
  5. data/lib/active_validation/matchers/ensure_valid_alpha_format_of.rb +2 -2
  6. data/lib/active_validation/matchers/ensure_valid_alpha_numeric_format_of.rb +2 -2
  7. data/lib/active_validation/matchers/ensure_valid_base64_format_of.rb +2 -2
  8. data/lib/active_validation/matchers/ensure_valid_boolean_format_of.rb +2 -2
  9. data/lib/active_validation/matchers/ensure_valid_coordinate_format_of.rb +2 -2
  10. data/lib/active_validation/matchers/ensure_valid_credit_card_format_of.rb +2 -2
  11. data/lib/active_validation/matchers/ensure_valid_currency_format_of.rb +2 -2
  12. data/lib/active_validation/matchers/ensure_valid_cusip_format_of.rb +2 -2
  13. data/lib/active_validation/matchers/ensure_valid_email_format_of.rb +2 -2
  14. data/lib/active_validation/matchers/ensure_valid_equality_matcher_of.rb +2 -2
  15. data/lib/active_validation/matchers/ensure_valid_hex_format_of.rb +2 -2
  16. data/lib/active_validation/matchers/ensure_valid_imei_format_of.rb +2 -2
  17. data/lib/active_validation/matchers/ensure_valid_ip_format_of.rb +2 -2
  18. data/lib/active_validation/matchers/ensure_valid_isbn_format_of.rb +2 -2
  19. data/lib/active_validation/matchers/ensure_valid_isin_format_of.rb +2 -2
  20. data/lib/active_validation/matchers/ensure_valid_mac_address_format_of.rb +2 -2
  21. data/lib/active_validation/matchers/ensure_valid_name_format_of.rb +2 -2
  22. data/lib/active_validation/matchers/ensure_valid_password_format_of.rb +2 -2
  23. data/lib/active_validation/matchers/ensure_valid_phone_format_of.rb +2 -2
  24. data/lib/active_validation/matchers/ensure_valid_sedol_format_of.rb +2 -2
  25. data/lib/active_validation/matchers/ensure_valid_slug_format_of.rb +2 -2
  26. data/lib/active_validation/matchers/ensure_valid_ssn_format_of.rb +2 -2
  27. data/lib/active_validation/matchers/ensure_valid_tracking_number_format_of.rb +26 -0
  28. data/lib/active_validation/matchers/ensure_valid_url_format_of.rb +2 -2
  29. data/lib/active_validation/matchers/ensure_valid_username_format_of.rb +2 -2
  30. data/lib/active_validation/matchers/ensure_valid_uuid_format_of.rb +2 -2
  31. data/lib/active_validation/validators/alpha_numeric_validator.rb +10 -7
  32. data/lib/active_validation/validators/alpha_validator.rb +10 -8
  33. data/lib/active_validation/validators/base64_validator.rb +16 -1
  34. data/lib/active_validation/validators/coordinate_validator.rb +12 -3
  35. data/lib/active_validation/validators/credit_card_validator.rb +10 -10
  36. data/lib/active_validation/validators/currency_validator.rb +7 -6
  37. data/lib/active_validation/validators/cusip_validator.rb +11 -9
  38. data/lib/active_validation/validators/email_validator.rb +11 -7
  39. data/lib/active_validation/validators/equality_validator.rb +14 -7
  40. data/lib/active_validation/validators/hex_validator.rb +16 -1
  41. data/lib/active_validation/validators/imei_validator.rb +14 -12
  42. data/lib/active_validation/validators/ip_validator.rb +16 -1
  43. data/lib/active_validation/validators/isbn_validator.rb +8 -4
  44. data/lib/active_validation/validators/isin_validator.rb +16 -14
  45. data/lib/active_validation/validators/mac_address_validator.rb +21 -7
  46. data/lib/active_validation/validators/name_validator.rb +16 -1
  47. data/lib/active_validation/validators/password_validator.rb +7 -6
  48. data/lib/active_validation/validators/phone_validator.rb +16 -1
  49. data/lib/active_validation/validators/sedol_validator.rb +15 -10
  50. data/lib/active_validation/validators/slug_validator.rb +16 -1
  51. data/lib/active_validation/validators/ssn_validator.rb +16 -1
  52. data/lib/active_validation/validators/tracking_number_validator.rb +235 -0
  53. data/lib/active_validation/validators/url_validator.rb +11 -2
  54. data/lib/active_validation/validators/username_validator.rb +16 -1
  55. data/lib/active_validation/validators/uuid_validator.rb +11 -6
  56. data/lib/active_validation/version.rb +1 -1
  57. data/lib/active_validation.rb +5 -6
  58. metadata +18 -2
@@ -0,0 +1,235 @@
1
+ class TrackingNumberValidator < ActiveModel::EachValidator
2
+
3
+ def validate_each(record, attribute, value)
4
+ unless valid?(value.to_s, options)
5
+ record.errors[attribute] << (options[:message] || I18n.t('active_validation.errors.messages.tracking_number'))
6
+ end
7
+ end
8
+
9
+ private
10
+
11
+ DEFAULT_CARRIERS_AND_SERVICES = {
12
+ dhl: {
13
+ express: /^([0-9]{9,9})([0-9])$/,
14
+ express_air: /^([0-9]{10,10})([0-9])$/
15
+ },
16
+ fedex: {
17
+ express: /^([0-9]{11,11})([0-9])$/,
18
+ ground: /^([0-9]{14,14})([0-9])$/,
19
+ ground18: /^[0-9]{2,2}([0-9]{15,15})([0-9])$/,
20
+ ground96: /^96[0-9]{5,5}([0-9]{14,14})([0-9])$/,
21
+ smart_post: /^((?:92)?[0-9]{5}[0-9]{14})([0-9])$/
22
+ },
23
+ ontrac: { express: /^(C[0-9]{13,13})([0-9])$/ },
24
+ ups: { express: /^1Z(\w{15,15})(\w)$/ },
25
+ usps: {
26
+ usps13: /^([A-Z]{2,2})([0-9]{9,9})([A-Z]{2,2})$/,
27
+ usps20: /^([0-9]{2,2})([0-9]{9,9})([0-9]{8,8})([0-9])$/,
28
+ usps91: /^(?:420\d{5})?(9[1-5](?:[0-9]{19}|[0-9]{23}))([0-9])$/
29
+ }
30
+ }
31
+
32
+ # DHL
33
+ DEFAULT_CARRIERS_AND_SERVICES.fetch(:dhl).each do |service, pattern|
34
+ define_method("valid_dhl_#{service}_checksum?") do |value|
35
+ formula = value.scan(pattern).flatten.compact
36
+ return(false) if formula.empty?
37
+ sequence, check_digit = formula.map(&:to_i)
38
+
39
+ (sequence % 7) == check_digit
40
+ end
41
+ end
42
+
43
+ # FedEx
44
+ def valid_fedex_express_checksum?(value)
45
+ return(false) unless value.size == 12
46
+
47
+ pattern = DEFAULT_CARRIERS_AND_SERVICES.fetch(:fedex).fetch(:express)
48
+ formula = value.scan(pattern).flatten.compact
49
+ return(false) if formula.empty?
50
+ sequence, check_digit = formula
51
+
52
+ total = 0
53
+ sequence.chars.zip([3, 1, 7, 3, 1, 7, 3, 1, 7, 3, 1]).each do |(char1, char2)|
54
+ total += (char1.to_i * char2)
55
+ end
56
+
57
+ (total % 11 % 10) == check_digit.to_i
58
+ end
59
+
60
+ DEFAULT_CARRIERS_AND_SERVICES.fetch(:fedex).only(:ground, :ground18, :ground96).each_with_index do |(service, pattern), i|
61
+ define_method("valid_fedex_#{service}_checksum?") do |value|
62
+ return(false) unless value.size == [15, 18, 22].at(i)
63
+
64
+ formula = value.scan(pattern).flatten.compact
65
+ return(false) if formula.empty?
66
+ sequence, check_digit = formula
67
+
68
+ total = 0
69
+ sequence.chars.reverse.each_with_index do |character, i|
70
+ result = character.to_i
71
+ result *= 3 if i.even?
72
+ total += result
73
+ end
74
+
75
+ check = total % 10
76
+ check = (10 - check) unless check.zero?
77
+ check == check_digit.to_i
78
+ end
79
+ end
80
+
81
+ def valid_fedex_smart_post_checksum?(value)
82
+ value = "92#{value}" unless value =~ /^92/
83
+ return(false) unless value.size == 22
84
+
85
+ pattern = DEFAULT_CARRIERS_AND_SERVICES.fetch(:fedex).fetch(:smart_post)
86
+ formula = value.scan(pattern).flatten.compact
87
+ return(false) if formula.empty?
88
+ sequence, check_digit = formula
89
+
90
+ total = 0
91
+ sequence.chars.reverse.each_with_index do |character, i|
92
+ result = character.to_i
93
+ result *= 3 if i.even?
94
+ total += result
95
+ end
96
+
97
+ check = total % 10
98
+ check = (10 - check) unless check.zero?
99
+ check == check_digit.to_i
100
+ end
101
+
102
+ # Ontrac & UPS
103
+ DEFAULT_CARRIERS_AND_SERVICES.only(:ontrac, :ups).each_with_index do |(carrier, services), i|
104
+ services.each do |service, pattern|
105
+ define_method("valid_#{carrier}_#{service}_checksum?") do |value|
106
+ return(false) unless value.size == [15, 18].at(i)
107
+
108
+ formula = value.scan(pattern).flatten.compact
109
+ return(false) if formula.empty?
110
+ sequence, check_digit = formula
111
+
112
+ total = 0
113
+ sequence.chars.each_with_index do |character, i|
114
+ result = character[/[0-9]/] ? character.to_i : ((character[0].ord - 3) % 10)
115
+ result *= 2 if i.odd?
116
+ total += result
117
+ end
118
+
119
+ check = total % 10
120
+ check = 10 - check unless check.zero?
121
+ check == check_digit.to_i
122
+ end
123
+ end
124
+ end
125
+
126
+ # USPS
127
+ def valid_usps_usps13_checksum?(value)
128
+ return(false) unless value.size == 13
129
+
130
+ pattern = DEFAULT_CARRIERS_AND_SERVICES.fetch(:usps).fetch(:usps13)
131
+ sequence = value.scan(pattern).flatten.compact
132
+ return(false) if sequence.empty?
133
+
134
+ characters = sequence[1].chars
135
+ check_digit = characters.pop.to_i
136
+
137
+ total = 0
138
+ characters.zip([8, 6, 4, 2, 3, 5, 9, 7]).each do |pair|
139
+ total += (pair[0].to_i * pair[1].to_i)
140
+ end
141
+
142
+ remainder = total % 11
143
+ check = case remainder
144
+ when 1
145
+ 0
146
+ when 0
147
+ 5
148
+ else
149
+ 11 - remainder
150
+ end
151
+
152
+ check == check_digit
153
+ end
154
+
155
+ def valid_usps_usps20_checksum?(value)
156
+ return(false) unless value.size == 20
157
+
158
+ pattern = DEFAULT_CARRIERS_AND_SERVICES.fetch(:usps).fetch(:usps20)
159
+ sequence = value.scan(pattern).flatten.compact
160
+ return(false) if sequence.empty?
161
+
162
+ characters = sequence.first(3).join.chars
163
+ check_digit = sequence.last.to_i
164
+
165
+ total = 0
166
+ characters.reverse.each_with_index do |character, i|
167
+ result = character.to_i
168
+ result *= 3 if i.even?
169
+ total += result
170
+ end
171
+
172
+ check = total % 10
173
+ check = (10 - check) unless check.zero?
174
+ check == check_digit
175
+ end
176
+
177
+ def valid_usps_usps91_checksum?(value)
178
+ value = "91#{value}" unless value =~ /^(420\d{5})?9[1-5]/
179
+ return(false) unless value.size == 22
180
+
181
+ pattern = DEFAULT_CARRIERS_AND_SERVICES.fetch(:usps).fetch(:usps91)
182
+ sequence = value.scan(pattern).flatten.compact
183
+ return(false) if sequence.empty?
184
+
185
+ characters = sequence.first.chars
186
+ check_digit = sequence.last.to_i
187
+
188
+ total = 0
189
+ characters.reverse.each_with_index do |character, i|
190
+ result = character.to_i
191
+ result *= 3 if i.even?
192
+ total += result
193
+ end
194
+
195
+ check = total % 10
196
+ check = (10 - check) unless check.zero?
197
+ check == check_digit
198
+ end
199
+
200
+ # Base
201
+ def valid_checksum?(value, options)
202
+ carrier = options[:carrier]
203
+ service = options[:service]
204
+ result = false
205
+
206
+ if carrier.nil? && service.nil?
207
+ DEFAULT_CARRIERS_AND_SERVICES.each do |carrier, services|
208
+ services.each_key do |carrier_service|
209
+ result = send("valid_#{carrier}_#{carrier_service}_checksum?", value)
210
+ break if result
211
+ end
212
+ break if result
213
+ end
214
+ elsif service.nil?
215
+ DEFAULT_CARRIERS_AND_SERVICES.fetch(carrier).each_key do |carrier_service|
216
+ result = send("valid_#{carrier}_#{carrier_service}_checksum?", value)
217
+ break if result
218
+ end
219
+ else
220
+ result = send("valid_#{carrier}_#{service}_checksum?", value)
221
+ end
222
+
223
+ return(result)
224
+ end
225
+
226
+ def valid_length?(value)
227
+ value.present?
228
+ end
229
+
230
+ def valid?(value, options)
231
+ valid_length?(value) &&
232
+ valid_checksum?(value, options)
233
+ end
234
+
235
+ end
@@ -2,7 +2,7 @@ require 'uri'
2
2
  class UrlValidator < ActiveModel::EachValidator
3
3
 
4
4
  def validate_each(record, attribute, value)
5
- uri = URI.parse(value)
5
+ uri = URI.parse(value.to_s)
6
6
  raise URI::InvalidURIError unless valid?(uri, options)
7
7
  rescue URI::InvalidURIError
8
8
  record.errors[attribute] << (options[:message] || I18n.t('active_validation.errors.messages.url'))
@@ -17,6 +17,10 @@ class UrlValidator < ActiveModel::EachValidator
17
17
  options.empty? || options.any? { |domain| value_downcased.end_with?(".#{domain.downcase}") }
18
18
  end
19
19
 
20
+ def valid_length?(value)
21
+ value.present?
22
+ end
23
+
20
24
  def valid_scheme?(value, options)
21
25
  value_downcased = value.scheme.to_s.downcase
22
26
  options.empty? || options.any? { |scheme| value_downcased == scheme.to_s.downcase }
@@ -26,8 +30,13 @@ class UrlValidator < ActiveModel::EachValidator
26
30
  ['/', ''].include?(value.path) && value.query.blank? && value.fragment.blank?
27
31
  end
28
32
 
33
+ def valid_uri?(value)
34
+ value.kind_of?(URI::Generic)
35
+ end
36
+
29
37
  def valid?(value, options)
30
- value.kind_of?(URI::Generic) &&
38
+ valid_length?(value) &&
39
+ valid_uri?(value) &&
31
40
  valid_domain?(value, [*(options[:domain])]) &&
32
41
  valid_scheme?(value, [*(options[:scheme] || UrlValidator::DEFAULT_SCHEMES)]) &&
33
42
  (options[:root] ? valid_root?(value) : true)
@@ -1,9 +1,24 @@
1
1
  class UsernameValidator < ActiveModel::EachValidator
2
2
 
3
3
  def validate_each(record, attribute, value)
4
- unless value =~ /^[a-z0-9_-]{2,16}$/
4
+ unless valid?(value.to_s)
5
5
  record.errors[attribute] << (options[:message] || I18n.t('active_validation.errors.messages.username'))
6
6
  end
7
7
  end
8
8
 
9
+ private
10
+
11
+ def valid_format?(value)
12
+ value =~ /^[a-z0-9_-]{2,16}$/
13
+ end
14
+
15
+ def valid_length?(value)
16
+ value.present?
17
+ end
18
+
19
+ def valid?(value)
20
+ valid_length?(value) &&
21
+ valid_format?(value)
22
+ end
23
+
9
24
  end
@@ -1,7 +1,7 @@
1
1
  class UuidValidator < ActiveModel::EachValidator
2
2
 
3
3
  def validate_each(record, attribute, value)
4
- unless valid?(value, options)
4
+ unless valid?(value.to_s, options)
5
5
  record.errors[attribute] << (options[:message] || I18n.t('active_validation.errors.messages.uuid'))
6
6
  end
7
7
  end
@@ -9,19 +9,24 @@ class UuidValidator < ActiveModel::EachValidator
9
9
  private
10
10
 
11
11
  def valid_format?(value, options)
12
- case options[:version]
12
+ value =~ case options[:version]
13
13
  when 3
14
- value =~ /^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i
14
+ /^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[0-9A-F]{4}-[0-9A-F]{12}$/i
15
15
  when 4
16
- value =~ /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
16
+ /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
17
17
  when 5
18
- value =~ /^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
18
+ /^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
19
19
  else
20
- value =~ /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i
20
+ /^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$/i
21
21
  end
22
22
  end
23
23
 
24
+ def valid_length?(value)
25
+ value.present?
26
+ end
27
+
24
28
  def valid?(value, options)
29
+ valid_length?(value) &&
25
30
  valid_format?(value, options)
26
31
  end
27
32
 
@@ -1,3 +1,3 @@
1
1
  module ActiveValidation
2
- VERSION = "1.1.0"
2
+ VERSION = "2.0.0"
3
3
  end
@@ -1,5 +1,6 @@
1
1
  require 'active_model'
2
2
  require 'active_support'
3
+ require 'active_object'
3
4
  require 'active_validation/version'
4
5
 
5
6
  require 'active_validation/validators/alpha_validator'
@@ -24,6 +25,7 @@ require 'active_validation/validators/phone_validator'
24
25
  require 'active_validation/validators/sedol_validator'
25
26
  require 'active_validation/validators/slug_validator'
26
27
  require 'active_validation/validators/ssn_validator'
28
+ require 'active_validation/validators/tracking_number_validator'
27
29
  require 'active_validation/validators/url_validator'
28
30
  require 'active_validation/validators/username_validator'
29
31
  require 'active_validation/validators/uuid_validator'
@@ -52,6 +54,7 @@ if defined?(RSpec)
52
54
  require 'active_validation/matchers/ensure_valid_sedol_format_of'
53
55
  require 'active_validation/matchers/ensure_valid_slug_format_of'
54
56
  require 'active_validation/matchers/ensure_valid_ssn_format_of'
57
+ require 'active_validation/matchers/ensure_valid_tracking_number_format_of'
55
58
  require 'active_validation/matchers/ensure_valid_url_format_of'
56
59
  require 'active_validation/matchers/ensure_valid_username_format_of'
57
60
  require 'active_validation/matchers/ensure_valid_uuid_format_of'
@@ -65,12 +68,8 @@ if defined?(Rails)
65
68
 
66
69
  initializer 'active_validation' do |app|
67
70
  ActiveValidation::Railtie.instance_eval do
68
- locales = locales_from(app.config.i18n.available_locales)
69
-
70
- locales.each do |locale|
71
- if File.file?(path(locale))
72
- I18n.load_path << path(locale)
73
- end
71
+ locales_from(app.config.i18n.available_locales).each do |locale|
72
+ (I18n.load_path << path(locale)) if File.file?(path(locale))
74
73
  end
75
74
  end
76
75
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_validation
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Juan Gomez
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-07-13 00:00:00.000000000 Z
11
+ date: 2015-08-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: active_object
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: bundler
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -152,6 +166,7 @@ files:
152
166
  - lib/active_validation/matchers/ensure_valid_sedol_format_of.rb
153
167
  - lib/active_validation/matchers/ensure_valid_slug_format_of.rb
154
168
  - lib/active_validation/matchers/ensure_valid_ssn_format_of.rb
169
+ - lib/active_validation/matchers/ensure_valid_tracking_number_format_of.rb
155
170
  - lib/active_validation/matchers/ensure_valid_url_format_of.rb
156
171
  - lib/active_validation/matchers/ensure_valid_username_format_of.rb
157
172
  - lib/active_validation/matchers/ensure_valid_uuid_format_of.rb
@@ -177,6 +192,7 @@ files:
177
192
  - lib/active_validation/validators/sedol_validator.rb
178
193
  - lib/active_validation/validators/slug_validator.rb
179
194
  - lib/active_validation/validators/ssn_validator.rb
195
+ - lib/active_validation/validators/tracking_number_validator.rb
180
196
  - lib/active_validation/validators/url_validator.rb
181
197
  - lib/active_validation/validators/username_validator.rb
182
198
  - lib/active_validation/validators/uuid_validator.rb