license_plate_validator 1.0.1 → 1.1.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.
- 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
|
+
[](http://badge.fury.io/rb/license_plate_validator)
|
3
4
|
[](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
|