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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 612a3486dc6990acf095cf3f62f377c2576d0331
4
- data.tar.gz: 07bdfab07e6e9846000e598e8abf38a5e476e9e0
3
+ metadata.gz: 6aeaa805d035520162078f5df5b5ed52f0763a5b
4
+ data.tar.gz: e15a05beec09888f7b0b78f7e82dade6a3148365
5
5
  SHA512:
6
- metadata.gz: 65f07d4ac403bb6f5247fb1ff2f150e96505328fc5dc20e282c178a33d76f88e15a6470594deb9b47e38b1da1cfdbbd5f89249314af71f0bfd21ef3c2b333f3e
7
- data.tar.gz: 6802d1f908ed1424bbea8fa5cc15d11c4d6543115fddd26ae4de65312b3978f6094165973690c67797d5bd872ddf95b2bd62cb47ca3c668fee2ec667ed0f7bec
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
- Without ActiveModel or Rails:
35
-
36
- LicensePlateValidator.new("60-NFH-1").valid?
35
+ LicensePlateValidator.new("60-NFH-1", country: :nl).valid?
37
36
  #=> true
38
37
 
39
- Or add it to your Rails 3.x or 4.x project, using ActiveModel:
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: true
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)
@@ -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-----
@@ -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
- /^([a-zA-Z]{2})-?([0-9]{2})-?([0-9]{2})$/,
6
- /^([0-9]{2})-?([0-9]{2})-?([a-zA-Z]{2})$/,
7
- /^([0-9]{2})-?([a-zA-Z]{2})-?([0-9]{2})$/,
8
- /^([a-zA-Z]{2})-?([0-9]{2})-?([a-zA-Z]{2})$/,
9
- /^([a-zA-Z]{2})-?([a-zA-Z]{2})-?([0-9]{2})$/,
10
- /^([0-9]{2})-?([a-zA-Z]{2})-?([a-zA-Z]{2})$/,
11
- /^([0-9]{2})-?([a-zA-Z]{3})-?([0-9]{1})$/,
12
- /^([0-9]{1})-?([a-zA-Z]{3})-?([0-9]{2})$/,
13
- /^([a-zA-Z]{2})-?([0-9]{3})-?([a-zA-Z]{1})$/,
14
- /^([a-zA-Z]{1})-?([0-9]{3})-?([a-zA-Z]{2})$/
15
- ].freeze
16
-
17
- def initialize(raw)
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
- PATTERNS.any? { |pattern| raw =~ pattern }
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
- license_plate = ::LicensePlateValidator.new(value.to_s)
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,3 +1,3 @@
1
1
  class LicensePlateValidator
2
- VERSION = "1.0.1"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -1,16 +1,46 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  if defined?(ActiveModel)
4
- class Vehicle < ModelBase
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 Vehicle do
9
- context "with a valid license plate number" do
10
- it "is valid" do
11
- obj = Vehicle.new(number: "60-NFH-1")
12
- expect(obj).to be_valid
13
- end
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 and only one argument' do
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.1
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-23 00:00:00.000000000 Z
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