license_plate_validator 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +34 -5
- data/gem-private_key.pem +27 -0
- data/gem-public_cert.pem +21 -0
- data/lib/license_plate_validator.rb +35 -15
- data/lib/license_plate_validator/active_model.rb +7 -1
- data/lib/license_plate_validator/version.rb +1 -1
- data/spec/license_plate_validator/active_model_spec.rb +37 -7
- data/spec/license_plate_validator_spec.rb +60 -5
- data/spec/spec_helper.rb +5 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6aeaa805d035520162078f5df5b5ed52f0763a5b
|
4
|
+
data.tar.gz: e15a05beec09888f7b0b78f7e82dade6a3148365
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0bb8eec8130aca606ea32c7645a526f2d8168d16540ab7176db6acd58825bb14a5c26564fc4892ec61e925eab8cf5be2e19ad8a25e6a0353a2f39edec6d1f183
|
7
|
+
data.tar.gz: 080a9d8642b57e7397548e38cb24ad0aef447b7910ae985fbf64016a01cd4d46fdad0c039d648f90760eb3913c22aaa8575cd7097014db9835dfe849fed20be3
|
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# License Plate Validator
|
2
2
|
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/license_plate_validator.png)](http://badge.fury.io/rb/license_plate_validator)
|
3
4
|
[![Build Status](https://travis-ci.org/ariejan/license_plate_validator.png?branch=master)](https://travis-ci.org/ariejan/license_plate_validator)
|
4
5
|
|
5
6
|
This gem allows you to easily valdiate license plate fields to be valid
|
@@ -31,17 +32,41 @@ Or install it yourself as:
|
|
31
32
|
|
32
33
|
## Usage
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
LicensePlateValidator.new("60-NFH-1").valid?
|
35
|
+
LicensePlateValidator.new("60-NFH-1", country: :nl).valid?
|
37
36
|
#=> true
|
38
37
|
|
39
|
-
|
38
|
+
LicensePlateValidator.new("SBA 5226", country: :nl).valid?
|
39
|
+
#=> false
|
40
|
+
|
41
|
+
### Rails 3.x / 4.x
|
42
|
+
|
43
|
+
You can use LicensePlateValidator with any ActiveModel class, including
|
44
|
+
ActiveRecord models:
|
40
45
|
|
41
46
|
class Vehicle < ActiveRecord::Base
|
42
|
-
validates :license_plate_number, license_plate:
|
47
|
+
validates :license_plate_number, license_plate: { country: :nl }
|
43
48
|
end
|
44
49
|
|
50
|
+
### Dynamic country selection
|
51
|
+
|
52
|
+
If you supply a `Proc` it will be called with the current record begin validated.
|
53
|
+
|
54
|
+
The `Proc` must return either `nil` (accept all the things) or a valid country code.
|
55
|
+
|
56
|
+
class Vehicle < ActiveRecord::Base
|
57
|
+
validates :license_plate_number,
|
58
|
+
license_plate: { country: Proc.new { |vehicle| vehicle.country } }
|
59
|
+
end
|
60
|
+
|
61
|
+
### Edge cases
|
62
|
+
|
63
|
+
* When no country is selected (or set to `nil`), all plates are considered valid.
|
64
|
+
* When an unknown country is selected, all plates are considered valid (e.g. we assume there are no validation rules for that country)
|
65
|
+
|
66
|
+
### Supported countries
|
67
|
+
|
68
|
+
* `:nl` Netherlands; all common "sidecode" number formats.
|
69
|
+
|
45
70
|
## I18n
|
46
71
|
|
47
72
|
Locales for English and Dutch are provided. See [`lib/license_plate_validator/locales`](https://github.com/ariejan/license_plate_validator/tree/master/lib/license_plate_validator/locales)
|
@@ -71,6 +96,10 @@ specs.
|
|
71
96
|
4. Push to the branch (`git push origin my-new-feature`)
|
72
97
|
5. Create new Pull Request
|
73
98
|
|
99
|
+
## Contributor
|
100
|
+
|
101
|
+
* Pascal Widdershoven - for the original regexes for Dutch license plate numbers.
|
102
|
+
|
74
103
|
## License
|
75
104
|
|
76
105
|
See [LICENSE.txt](https://github.com/ariejan/license_plate_validator/blob/master/LICENSE.txt)
|
data/gem-private_key.pem
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
MIIEpAIBAAKCAQEAyt2l9tkc4bL1zgKZk9UiNbqNElgCuRzV1pfk32Sb+S57RH9w
|
3
|
+
CE8mkYituGW0mLAjxg9h/lcn424Q62D+vlSJsHyjsgisWtu3ZHg1uy6VE8xWlCaD
|
4
|
+
tvOas51M8LNyQtS+f5pTy0WB4BOcKk5M9TwJDK4zX/CJBErxttBhYx1QJhiERHgg
|
5
|
+
1wGFXQpUQAW5HW4FlXWgXtfvfljj9eE1bw5Qz3ycj8NE83kQOSS9NaKwX/ma60jb
|
6
|
+
JJakiZmjMabkctpSGYw3rqiumQ3MV6li0TY+dBjNB9V7yldCvv9ud4Wws9PLtWHx
|
7
|
+
cerYnGq6u9JRTT8NE8M+B7Xn7nKvt+6XGlBJJwIDAQABAoIBAA8haPd4Sgcradnr
|
8
|
+
p7i29M49E7iCh/F2jRxsR83Bm0CCjv8U4i48eQvxvcM7ErUwrfpfu1dU+MylsO1d
|
9
|
+
VqKre3mGUk89Bl3gdVUxAhDr8IKBgxOZq8lBchBjcxGg0KzbYTnzMLzAemdUDxm4
|
10
|
+
rVS9HY+sjnhhYFbJoC2abSkPTqMInxOGfeb68C/MiKzckZO4P/ncgU83fxmOi0Xf
|
11
|
+
h4hcxtdmd0ZjhkDgvyBv6tOdwvwH6U7zKkrqBjY2q0OYFLGcNSjjdYmTKTnK8iqk
|
12
|
+
YyFfqyg3c0ZyqkqmHFaXkiJiP5zpS1rFXORXNnTleMaRU7DZUTO8RjhBXoEX1VXp
|
13
|
+
g+5UBoECgYEA6b9Dzu/zPnSUGIaY15IxtQykXt0LGosIE/bfymtf6J99YpYbxcY/
|
14
|
+
fy43U5glCKj1YJlsFQMMir3FbJBfQNWD4d7sElyHJYiwkn3kbXwIILyumK3XIPnh
|
15
|
+
hVaMPLKM9j4CIMefj0nVyCHWWdfz/yVJlNFBly+olHrpn6+4dY7mw0kCgYEA3i3D
|
16
|
+
icKPXjpV8lQs26m50Q1mquV59f7AbbjjYw8v6kXs3EmIqvCGPZpFOoD4EnZXU4S+
|
17
|
+
irxWgbEtYT97KMNrCHkFn2af7BqezJ8v6o5vPZC7TgUMJHykTN+n8tG7CG98mYmV
|
18
|
+
kdTogWO/p+fyu6BdRUxGeO/0q7puVHHbHVzoOO8CgYEAk0qr3u2C+LsbSy0diNGd
|
19
|
+
svmJZiGhypMLfxEUygfJQtuldgci7whSoMCtqmZ4B7H4FWv4GHF4aMDWc+exrjgd
|
20
|
+
R6piVduqabNtmJHt7DO5J2/eEWWR5zyuqIf2DJVykARY8PD5kaA0L01rNegH36JO
|
21
|
+
cJE/5JXqg83EA5UGBkYLEckCgYAkcaFHcZCOxkbezwvkpDyEnAwhMC8HONhbpx41
|
22
|
+
W4JijUHDCJTQZU+/vxRn+ku2y46bdoTCwQ33jBaDgyQylYtzAlb3xJ+q3Nr7eYkk
|
23
|
+
kmSQ1rLCo3VQbtmMeotT+y8QvSjVDopoN2JEBxai9hsMx8tE2LQelk2t9ZCvbVWh
|
24
|
+
xWGaJQKBgQCf6qjON5bqVyDh0sZOavngBXh4cjA47GCWnUlXNkdCTJ6Q2upd80jC
|
25
|
+
mzJOeofZheY6OVrpvn1GVU+R57pM0XYsz4vC8ZXMcF5Yr888C6DM4sqWWJn0GAwU
|
26
|
+
g4i7PDqi8ACxkRUIUCQw/m4HLSqg915mQyAckCtq6AP6kCk1c/nE9w==
|
27
|
+
-----END RSA PRIVATE KEY-----
|
data/gem-public_cert.pem
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIDdDCCAlygAwIBAgIBATANBgkqhkiG9w0BAQUFADBAMRAwDgYDVQQDDAdhcmll
|
3
|
+
amFuMRcwFQYKCZImiZPyLGQBGRYHYXJpZWphbjETMBEGCgmSJomT8ixkARkWA25l
|
4
|
+
dDAeFw0xMzA3MjMxMjMxMTRaFw0xNDA3MjMxMjMxMTRaMEAxEDAOBgNVBAMMB2Fy
|
5
|
+
aWVqYW4xFzAVBgoJkiaJk/IsZAEZFgdhcmllamFuMRMwEQYKCZImiZPyLGQBGRYD
|
6
|
+
bmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyt2l9tkc4bL1zgKZ
|
7
|
+
k9UiNbqNElgCuRzV1pfk32Sb+S57RH9wCE8mkYituGW0mLAjxg9h/lcn424Q62D+
|
8
|
+
vlSJsHyjsgisWtu3ZHg1uy6VE8xWlCaDtvOas51M8LNyQtS+f5pTy0WB4BOcKk5M
|
9
|
+
9TwJDK4zX/CJBErxttBhYx1QJhiERHgg1wGFXQpUQAW5HW4FlXWgXtfvfljj9eE1
|
10
|
+
bw5Qz3ycj8NE83kQOSS9NaKwX/ma60jbJJakiZmjMabkctpSGYw3rqiumQ3MV6li
|
11
|
+
0TY+dBjNB9V7yldCvv9ud4Wws9PLtWHxcerYnGq6u9JRTT8NE8M+B7Xn7nKvt+6X
|
12
|
+
GlBJJwIDAQABo3kwdzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQU
|
13
|
+
ZwHc1uXiVvbwy96Xts52wSQspHQwHgYDVR0RBBcwFYETYXJpZWphbkBhcmllamFu
|
14
|
+
Lm5ldDAeBgNVHRIEFzAVgRNhcmllamFuQGFyaWVqYW4ubmV0MA0GCSqGSIb3DQEB
|
15
|
+
BQUAA4IBAQAyJDUHFZ8zy2L1PWTRQVxdTNfFLBwp/dj+vBgUrLrIL4L1sjTd8gli
|
16
|
+
gKyC8EB4aWLQ3Ir1myHU/52mhjtijKvhN7PjedXnX1raLe276aivjkArn27iuspg
|
17
|
+
sGjp2OtGm611w/h4ZC8n+HUzCMQaOTzNWOXQIIIjlNfYBSiPz9/b6zDtyuHxDhux
|
18
|
+
bIKVdAi8hBPMZF3l9OMIoslpwPv5d0acAtRKX2YTaZgnoY9yKlrfP4vSqm2bdDhf
|
19
|
+
7NiYH0Kuw9dhd6KTJkM9nkX0tYPEksLImmnf2di9+uZVXaXS0eNwX8OvHb48eoyM
|
20
|
+
fYCqplVyUXI9SqwzVPOD1Bf+drhGNR2O
|
21
|
+
-----END CERTIFICATE-----
|
@@ -1,27 +1,47 @@
|
|
1
1
|
class LicensePlateValidator
|
2
2
|
|
3
|
-
PATTERNS =
|
3
|
+
PATTERNS = {
|
4
4
|
# Netherlands
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
5
|
+
nl: [
|
6
|
+
/^([a-zA-Z]{2})-?([0-9]{2})-?([0-9]{2})$/,
|
7
|
+
/^([0-9]{2})-?([0-9]{2})-?([a-zA-Z]{2})$/,
|
8
|
+
/^([0-9]{2})-?([a-zA-Z]{2})-?([0-9]{2})$/,
|
9
|
+
/^([a-zA-Z]{2})-?([0-9]{2})-?([a-zA-Z]{2})$/,
|
10
|
+
/^([a-zA-Z]{2})-?([a-zA-Z]{2})-?([0-9]{2})$/,
|
11
|
+
/^([0-9]{2})-?([a-zA-Z]{2})-?([a-zA-Z]{2})$/,
|
12
|
+
/^([0-9]{2})-?([a-zA-Z]{3})-?([0-9]{1})$/,
|
13
|
+
/^([0-9]{1})-?([a-zA-Z]{3})-?([0-9]{2})$/,
|
14
|
+
/^([a-zA-Z]{2})-?([0-9]{3})-?([a-zA-Z]{1})$/,
|
15
|
+
/^([a-zA-Z]{1})-?([0-9]{3})-?([a-zA-Z]{2})$/
|
16
|
+
]
|
17
|
+
}.freeze
|
18
|
+
|
19
|
+
def initialize(raw, options = {})
|
20
|
+
@options = {
|
21
|
+
country: nil
|
22
|
+
}.merge(options)
|
23
|
+
|
18
24
|
@raw = normalize(raw || "")
|
19
25
|
end
|
20
26
|
|
21
27
|
attr_reader :raw
|
22
28
|
|
23
29
|
def valid?
|
24
|
-
|
30
|
+
return true if @options[:country].nil?
|
31
|
+
|
32
|
+
country = @options[:country].to_sym
|
33
|
+
|
34
|
+
return true unless supported_countries.include?(country)
|
35
|
+
|
36
|
+
PATTERNS[country].any? { |pattern| raw =~ pattern }
|
37
|
+
end
|
38
|
+
|
39
|
+
def supported_countries
|
40
|
+
PATTERNS.keys
|
41
|
+
end
|
42
|
+
|
43
|
+
def patterns_for_country(country)
|
44
|
+
return PATTERNS[country] || []
|
25
45
|
end
|
26
46
|
|
27
47
|
def to_s
|
@@ -5,7 +5,13 @@ module ActiveModel
|
|
5
5
|
class LicensePlateValidator < ::ActiveModel::EachValidator
|
6
6
|
|
7
7
|
def validate_each(record, attribute, value)
|
8
|
-
|
8
|
+
country = case(options[:country])
|
9
|
+
when Proc then options[:country].call(record)
|
10
|
+
when nil then nil
|
11
|
+
else options[:country].to_sym
|
12
|
+
end
|
13
|
+
|
14
|
+
license_plate = ::LicensePlateValidator.new(value.to_s, { country: country })
|
9
15
|
|
10
16
|
if !license_plate.valid?
|
11
17
|
record.errors.add(attribute, :invalid_license_plate, message: options[:message])
|
@@ -1,16 +1,46 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
if defined?(ActiveModel)
|
4
|
-
|
4
|
+
|
5
|
+
class DutchVehicle < ModelBase
|
6
|
+
validates :number, license_plate: { country: :nl }
|
7
|
+
end
|
8
|
+
|
9
|
+
class DutchMethodVehicle < ModelBase
|
10
|
+
validates :number, license_plate: { country: Proc.new { |dmv| dmv.country } }
|
11
|
+
end
|
12
|
+
|
13
|
+
class UnknownVehicle < ModelBase
|
5
14
|
validates :number, license_plate: true
|
6
15
|
end
|
7
16
|
|
8
|
-
describe
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
17
|
+
describe DutchVehicle do
|
18
|
+
it "accepts Dutch plates only" do
|
19
|
+
obj = DutchVehicle.new(number: "60-NFH-1")
|
20
|
+
expect(obj).to be_valid
|
21
|
+
|
22
|
+
obj = DutchVehicle.new(number: "SBA5226")
|
23
|
+
expect(obj).not_to be_valid
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe DutchMethodVehicle do
|
28
|
+
it "accepts Dutch plates only" do
|
29
|
+
obj = DutchMethodVehicle.new(number: "60-NFH-1", country: "nl")
|
30
|
+
expect(obj).to be_valid
|
31
|
+
|
32
|
+
obj = DutchMethodVehicle.new(number: "SBA5226", country: "nl")
|
33
|
+
expect(obj).not_to be_valid
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe UnknownVehicle do
|
38
|
+
it "accepts both Dutch and German plates" do
|
39
|
+
obj = UnknownVehicle.new(number: "60-NFH-1")
|
40
|
+
expect(obj).to be_valid
|
41
|
+
|
42
|
+
obj = UnknownVehicle.new(number: "SBA5226")
|
43
|
+
expect(obj).to be_valid
|
14
44
|
end
|
15
45
|
end
|
16
46
|
end
|
@@ -6,10 +6,11 @@ describe LicensePlateValidator do
|
|
6
6
|
end
|
7
7
|
|
8
8
|
describe "#new" do
|
9
|
-
it 'demands one
|
10
|
-
expect { LicensePlateValidator.new }.to raise_error
|
11
|
-
expect { LicensePlateValidator.new("a", "b") }.to raise_error
|
9
|
+
it 'demands one argument, optionally a second' do
|
10
|
+
expect { LicensePlateValidator.new() }.to raise_error
|
12
11
|
expect { LicensePlateValidator.new ("a") }.not_to raise_error
|
12
|
+
expect { LicensePlateValidator.new("a", country: :nl) }.not_to raise_error
|
13
|
+
expect { LicensePlateValidator.new("a", country: nil) }.not_to raise_error
|
13
14
|
end
|
14
15
|
|
15
16
|
it 'normalizes the input string' do
|
@@ -18,6 +19,60 @@ describe LicensePlateValidator do
|
|
18
19
|
end
|
19
20
|
end
|
20
21
|
|
22
|
+
context "#supported countries" do
|
23
|
+
subject { LicensePlateValidator.new("a") }
|
24
|
+
|
25
|
+
it "returns array of symbols" do
|
26
|
+
expect(subject.supported_countries).to eql([:nl])
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "#patterns_for_country" do
|
31
|
+
subject { LicensePlateValidator.new("a") }
|
32
|
+
|
33
|
+
it "returns empty array for unknown countries" do
|
34
|
+
expect(subject.patterns_for_country(:se)).to eql([])
|
35
|
+
end
|
36
|
+
|
37
|
+
it "returns array of patterns for known countries" do
|
38
|
+
expect(subject.patterns_for_country(:nl).size).to eql(10)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "country specific validations" do
|
43
|
+
context "with a specific country selected" do
|
44
|
+
it "accepts license plates for that country" do
|
45
|
+
license = LicensePlateValidator.new("60-NFH-1", country: :nl)
|
46
|
+
expect(license).to be_valid
|
47
|
+
end
|
48
|
+
|
49
|
+
it "does not accept foreign license plates" do
|
50
|
+
license = LicensePlateValidator.new("SBA5226", country: :nl)
|
51
|
+
expect(license).not_to be_valid
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "with an unknown country selected" do
|
56
|
+
it "accepts all license plates" do
|
57
|
+
license = LicensePlateValidator.new("60-NFH-1", country: :se)
|
58
|
+
expect(license).to be_valid
|
59
|
+
|
60
|
+
license = LicensePlateValidator.new("SBA5226", country: :se)
|
61
|
+
expect(license).to be_valid
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context "without a country selected" do
|
66
|
+
it "accepts all license plates / does no validation" do
|
67
|
+
license = LicensePlateValidator.new("60-NFH-1", country: nil)
|
68
|
+
expect(license).to be_valid
|
69
|
+
|
70
|
+
license = LicensePlateValidator.new("SBA5226", country: nil)
|
71
|
+
expect(license).to be_valid
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
21
76
|
context "NL - Netherlands" do
|
22
77
|
NL_VALID_SAMPLES = [
|
23
78
|
"FZ-61-24",
|
@@ -41,14 +96,14 @@ describe LicensePlateValidator do
|
|
41
96
|
|
42
97
|
NL_VALID_SAMPLES.each do |number|
|
43
98
|
it "accepts '#{number}'" do
|
44
|
-
license = LicensePlateValidator.new(number)
|
99
|
+
license = LicensePlateValidator.new(number, country: :nl)
|
45
100
|
expect(license).to be_valid
|
46
101
|
end
|
47
102
|
end
|
48
103
|
|
49
104
|
NL_INVALID_SAMPLES.each do |number|
|
50
105
|
it "does not accept '#{number}'" do
|
51
|
-
license = LicensePlateValidator.new(number)
|
106
|
+
license = LicensePlateValidator.new(number, country: :nl)
|
52
107
|
expect(license).not_to be_valid
|
53
108
|
end
|
54
109
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -22,5 +22,10 @@ if defined?(ActiveModel)
|
|
22
22
|
def read_attribute_for_validation(key)
|
23
23
|
@attributes[key.to_sym]
|
24
24
|
end
|
25
|
+
|
26
|
+
def method_missing(method_name, *args, &block)
|
27
|
+
return super unless @attributes.keys.any? { |k| k == method_name }
|
28
|
+
@attributes[method_name.to_sym]
|
29
|
+
end
|
25
30
|
end
|
26
31
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: license_plate_validator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ariejan de Vroom
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-07-
|
11
|
+
date: 2013-07-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -81,6 +81,8 @@ files:
|
|
81
81
|
- LICENSE.txt
|
82
82
|
- README.md
|
83
83
|
- Rakefile
|
84
|
+
- gem-private_key.pem
|
85
|
+
- gem-public_cert.pem
|
84
86
|
- gemfiles/activemodel-3-2
|
85
87
|
- gemfiles/activemodel-4
|
86
88
|
- gemfiles/standalone
|