uk_validators 0.1.0 → 0.2.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.
data/README.md CHANGED
@@ -4,6 +4,7 @@ This library contains Rails 3 custom validators for the following UK-centric dat
4
4
 
5
5
  * National Insurance Number
6
6
  * Post Code
7
+ * Driving Licence Number
7
8
 
8
9
 
9
10
  ## Installation
@@ -81,6 +82,37 @@ For the example Address model above, the customised en.yml would be:
81
82
  postcode: "is not valid"
82
83
 
83
84
 
85
+ ## Driving Licence Number
86
+ Validates the format of a UK Driving Licence Number covering the format used in England, Scotland and Wales. Northen Ireland has a different format containing 8 random alphanumeric characters.
87
+
88
+ References: [DVLA](http://www.direct.gov.uk/prod_consum_dg/groups/dg_digitalassets/@dg/@en/@motor/documents/digitalasset/dg_068626.pdf), [uk-osint.net](http://www.uk-osint.net/usefulbits.html#How%20To%20Check%20UK%20Driving%20Licences)
89
+
90
+ ### Usage
91
+
92
+ ```ruby
93
+ class User < ActiveRecord::Base
94
+ validates :licence_number, driving_licence: true
95
+ end
96
+ ```
97
+
98
+ ### I18n
99
+
100
+ The default error message is `is not a valid Driving Licence No.`
101
+
102
+ This can be translated in the same was as any other Rails validation message using the key **:driving_licence**.
103
+
104
+ For the example User model above, the customised en.yml would be:
105
+
106
+ en:
107
+ activerecord:
108
+ errors:
109
+ models:
110
+ user:
111
+ attributes:
112
+ licence_number:
113
+ driving_licence: "is not valid"
114
+
115
+
84
116
 
85
117
 
86
118
  ## Contributing
@@ -0,0 +1,57 @@
1
+ class DrivingLicenceValidator < ActiveModel::EachValidator
2
+
3
+ def validate_each(record, attribute, value)
4
+ record.errors.add(attribute, invalid_message(record, attribute)) unless valid_driving_licence?(value)
5
+ end
6
+
7
+ private
8
+
9
+ def valid_driving_licence?(value)
10
+ # first 5 letters of surname (padded with 9 if shorter than 5)
11
+ # decade of birth
12
+ # month of birth - 5 is added to first digit if female
13
+ # month day of birth
14
+ # year in decade of birth
15
+ # first name and second name initials (9 used if no second name)
16
+ # computer generated check digits (usually 9 followed by 2 alphabetics)
17
+ # Example: for Susan Ann Davis born 23 November 1978: DAVIS761238SA9WE
18
+ # value =~ /^[A-Z][A-Z9]{4}\d[0156]\d[0123]\d\d[A-Z][A-Z9]\d[A-Z]{2}$/i
19
+ valid = false
20
+ # if we get a valid match then check the date of birth looks valid
21
+ if value.present? && match = value.match(/^[A-Z][A-Z9]{4}(\d)([0156]\d)([0123]\d)(\d)[A-Z][A-Z9]\d[A-Z]{2}$/i)
22
+ decade, month, day, year = match.captures
23
+ yy = (decade + year).to_i
24
+ mm = month.to_i
25
+ dd = day.to_i
26
+ mm -= 50 if mm > 50
27
+
28
+ if dd > 0 && mm >= 1 && mm <= 12
29
+ if [4, 6, 9, 11].include? mm
30
+ valid = dd <= 30
31
+ elsif mm == 2
32
+ if dd <= 28
33
+ valid = true
34
+ else
35
+ if dd == 29
36
+ if Date.today.year > (2000 + yy)
37
+ valid = Date.leap?(2000 + yy) || Date.leap?(1900 + yy)
38
+ else
39
+ valid = Date.leap?(1900 + yy)
40
+ end
41
+ end
42
+ end
43
+ else
44
+ valid = dd <= 31
45
+ end
46
+ end
47
+ end
48
+ valid
49
+ end
50
+
51
+ def invalid_message(record, attribute)
52
+ I18n.t :driving_licence,
53
+ scope: "#{record.class.i18n_scope}.errors.models.#{record.class.model_name.i18n_key}.attributes.#{attribute}",
54
+ default: "is not a valid Driving Licence number"
55
+ end
56
+
57
+ end
@@ -1,3 +1,3 @@
1
1
  module UkValidators
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/uk_validators.rb CHANGED
@@ -1,3 +1,4 @@
1
1
  require "uk_validators/version"
2
2
  require "uk_validators/nino_validator"
3
3
  require "uk_validators/postcode_validator"
4
+ require "uk_validators/driving_licence_validator"
@@ -0,0 +1,75 @@
1
+ require_relative 'test_helper'
2
+
3
+ class TestDrivingLicenceValidator < MiniTest::Unit::TestCase
4
+ class User < TestModel
5
+ validates :licence_number, driving_licence: true
6
+ end
7
+
8
+ def test_valid_driving_licences
9
+ valid_licences.each { |licence| assert User.new(licence_number: licence).valid?, "Licence should be valid: #{licence}" }
10
+ end
11
+
12
+ def test_invalid_driving_licences
13
+ invalid_licences.each { |licence| assert User.new(licence_number: licence).invalid?, "Licence should be invalid: #{licence}" }
14
+ end
15
+
16
+ private
17
+
18
+ def valid_licences
19
+ [
20
+ 'ABCDE703120AB9AB',
21
+ 'ABCD9703120AB9AB',
22
+ 'ABC99703120AB9AB',
23
+ 'AB999703120AB9AB',
24
+ 'A9999703120AB9AB',
25
+ 'ABCDE752292AB9AB',
26
+ 'ABCDE753120AB9AB',
27
+ 'ABCDE761120AB9AB',
28
+ 'ABCDE703220AB9AB',
29
+ 'ABCDE703310AB9AB',
30
+ ]
31
+ end
32
+
33
+ def invalid_licences
34
+ [
35
+ '',
36
+ '1BCDE402149AB8AB',
37
+ 'A2CDE402149AB8AB',
38
+ 'AB3DE402149AB8AB',
39
+ 'ABC4E402149AB8AB',
40
+ 'ABCD5402149AB8AB',
41
+ 'ABCDEF02149AB8AB',
42
+ 'ABCDE4G2149AB8AB',
43
+ 'ABCDE4GH149AB8AB',
44
+ 'ABCDE4G2I49AB8AB',
45
+ 'ABCDE4G21J9AB8AB',
46
+ 'ABCDE4G214KAB8AB',
47
+ 'ABCDE4G21491B8AB',
48
+ 'ABCDE4G2149A28AB',
49
+ 'ABCDE4G2149ABVAB',
50
+ 'ABCDE4G2149AB81B',
51
+ 'ABCDE4G2149AB8A2',
52
+ 'ABCDE402149AB8A',
53
+ 'ABCDE402149AB8',
54
+ 'ABCDE402149AB',
55
+ 'ABCDE402149A',
56
+ 'ABCDE402149',
57
+ 'ABCDE40214',
58
+ 'ABCDE4021',
59
+ 'ABCDE402',
60
+ 'ABCDE40',
61
+ 'ABCDE4',
62
+ 'ABCDE',
63
+ 'ABCD',
64
+ 'ABC',
65
+ 'AB',
66
+ 'A',
67
+ 'ABCDE402149AB8AB1',
68
+ 'ABCDE763120AB9AB',
69
+ 'ABCDE702300AB9AB',
70
+ 'ABCDE752294AB9AB',
71
+
72
+ ]
73
+ end
74
+ end
75
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uk_validators
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-11-06 00:00:00.000000000 Z
12
+ date: 2013-11-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -88,9 +88,11 @@ files:
88
88
  - README.md
89
89
  - Rakefile
90
90
  - lib/uk_validators.rb
91
+ - lib/uk_validators/driving_licence_validator.rb
91
92
  - lib/uk_validators/nino_validator.rb
92
93
  - lib/uk_validators/postcode_validator.rb
93
94
  - lib/uk_validators/version.rb
95
+ - test/driving_licence_test.rb
94
96
  - test/nino_test.rb
95
97
  - test/postcode_test.rb
96
98
  - test/test_helper.rb
@@ -110,7 +112,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
110
112
  version: '0'
111
113
  segments:
112
114
  - 0
113
- hash: -2750721584728170900
115
+ hash: -224961422204427896
114
116
  required_rubygems_version: !ruby/object:Gem::Requirement
115
117
  none: false
116
118
  requirements:
@@ -119,7 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
119
121
  version: '0'
120
122
  segments:
121
123
  - 0
122
- hash: -2750721584728170900
124
+ hash: -224961422204427896
123
125
  requirements: []
124
126
  rubyforge_project:
125
127
  rubygems_version: 1.8.25
@@ -127,6 +129,7 @@ signing_key:
127
129
  specification_version: 3
128
130
  summary: Rails validations for UK data
129
131
  test_files:
132
+ - test/driving_licence_test.rb
130
133
  - test/nino_test.rb
131
134
  - test/postcode_test.rb
132
135
  - test/test_helper.rb