resident 0.0.10 → 0.0.13
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 +5 -5
- data/README.md +13 -8
- data/lib/national_identification_number/base.rb +8 -1
- data/lib/national_identification_number/danish.rb +43 -0
- data/lib/national_identification_number/norwegian.rb +60 -0
- data/lib/national_identification_number/swedish.rb +14 -11
- data/lib/national_identification_number.rb +2 -0
- data/spec/national_identification_number/base_spec.rb +19 -0
- data/spec/national_identification_number/danish_spec.rb +81 -0
- data/spec/national_identification_number/finnish_spec.rb +33 -2
- data/spec/national_identification_number/norwegian_spec.rb +97 -0
- data/spec/national_identification_number/swedish_spec.rb +36 -1
- metadata +7 -32
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: bf01e9d01d506e8d1679e55d195fbf5b2b68e4f1ea92e071faa067c628ccdeed
|
4
|
+
data.tar.gz: 05faa5d541a34c27f6bfd7b3285ca1d7e45b0ec6a8368a76bc989f670bea6f88
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c5c5dae1f39cfc92325e801ccbe0af1823578afb21ace71433853d9bd689988789bf263751837589c35b89ffdf8affd2c5588971753393de21b86b5492c889a6
|
7
|
+
data.tar.gz: 6796c74e79556f2a291b6e18657551a5300809951c9310fa4dd5f0788f422b84bdd5ddf1b3cad52e9c175f72429a7c317931ae4c9d2bc5ff47b2d3dc408d87ad
|
data/README.md
CHANGED
@@ -2,9 +2,13 @@
|
|
2
2
|
|
3
3
|
Validates a National Identification Number (See http://en.wikipedia.org/wiki/National_identification_number).
|
4
4
|
There are some 62 countries that have this type of number.
|
5
|
-
This gem currently only supports Swedish (Personnummer) and Finnish (Henkilöasiakkaat) ones.
|
6
5
|
|
7
|
-
|
6
|
+
This gem currently only supports Swedish (Personnummer), Finnish
|
7
|
+
(Henkilöasiakkaat), Norwegian (Fødelsenummer) and Danish (CPR).
|
8
|
+
|
9
|
+
There is a special focus on identifying these numbers robustly
|
10
|
+
(i.e. you can safely validate a param[:number] directly, or cleanup
|
11
|
+
your database by running every non-normalized value through this gem).
|
8
12
|
|
9
13
|
## Installation
|
10
14
|
|
@@ -12,15 +16,16 @@ There is a special focus on identifying these numbers robustly (i.e. you can saf
|
|
12
16
|
|
13
17
|
## Usage
|
14
18
|
|
15
|
-
Really, you can just use <tt>valid?</tt>, <tt>to_s</tt>, and <tt>age</tt> like so:
|
19
|
+
Really, you can just use <tt>valid?</tt>, <tt>sanitize</tt>, <tt>to_s</tt>, and <tt>age</tt> like so:
|
16
20
|
|
17
21
|
require 'resident'
|
18
22
|
|
19
23
|
number = NationalIdentificationNumber::Swedish.new('0501261853')
|
20
24
|
|
21
|
-
number.valid?
|
22
|
-
number.to_s
|
23
|
-
number.
|
25
|
+
number.valid? #=> true
|
26
|
+
number.to_s #=> "050126-1853"
|
27
|
+
number.sanitize #=> "050126-1853" (Would have been nil if invalid)
|
28
|
+
number.age #=> 9
|
24
29
|
|
25
30
|
Please have a look at the specs to see how the national identification numbers of various countries are handled.
|
26
31
|
|
@@ -37,7 +42,7 @@ Some marked parts of the code are inspired or taken from MIT licensed code of
|
|
37
42
|
|
38
43
|
Other than that you got:
|
39
44
|
|
40
|
-
Copyright (c) 2011-
|
45
|
+
Copyright (c) 2011-2022 Bukowskis.
|
41
46
|
|
42
47
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
43
48
|
of this software and associated documentation files (the "Software"), to deal
|
@@ -55,4 +60,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
55
60
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
56
61
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
57
62
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
58
|
-
THE SOFTWARE.
|
63
|
+
THE SOFTWARE.
|
@@ -17,10 +17,18 @@ module NationalIdentificationNumber
|
|
17
17
|
@number
|
18
18
|
end
|
19
19
|
|
20
|
+
def sanitize
|
21
|
+
to_s if valid?
|
22
|
+
end
|
23
|
+
|
20
24
|
def age
|
21
25
|
age_for_dob date
|
22
26
|
end
|
23
27
|
|
28
|
+
def ==(other)
|
29
|
+
other.class == self.class && other&.to_s == to_s
|
30
|
+
end
|
31
|
+
|
24
32
|
protected
|
25
33
|
|
26
34
|
# stackoverflow.com/questions/819263
|
@@ -37,6 +45,5 @@ module NationalIdentificationNumber
|
|
37
45
|
def validate
|
38
46
|
raise 'You need to implement at least this method in subclasses.'
|
39
47
|
end
|
40
|
-
|
41
48
|
end
|
42
49
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'national_identification_number/base'
|
2
|
+
|
3
|
+
module NationalIdentificationNumber
|
4
|
+
class Danish < Base
|
5
|
+
attr_reader :date
|
6
|
+
|
7
|
+
protected
|
8
|
+
|
9
|
+
def repair
|
10
|
+
super
|
11
|
+
@number.gsub!(/[^0-9]/, '')
|
12
|
+
if (matches = @number.match(/\A(?<birthday>[0-9]{6})(?<checksum>[0-9]{4})\z/))
|
13
|
+
birthday, checksum = matches.values_at(:birthday, :checksum)
|
14
|
+
@number = "#{birthday}-#{checksum}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def validate
|
19
|
+
if (matches = @number.match(/\A(?<day>\d{2})(?<month>\d{2})(?<year>\d{2})-(?<serial>\d{3})(?<checksum>\d{1})\z/))
|
20
|
+
day, month, year, serial, checksum = matches.values_at(:day, :month, :year, :serial, :checksum)
|
21
|
+
begin
|
22
|
+
@date = Date.parse("#{full_year(serial, year)}-#{month}-#{day}")
|
23
|
+
@valid = true
|
24
|
+
@number = "#{day}#{month}#{year}-#{serial}#{checksum}"
|
25
|
+
rescue ArgumentError
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def full_year(serial, year)
|
33
|
+
century(serial, year.to_i) + year.to_i
|
34
|
+
end
|
35
|
+
|
36
|
+
def century(serial, year)
|
37
|
+
first_digit = serial[0].to_i
|
38
|
+
return 1800 if (5..8).include?(first_digit) && year > 57
|
39
|
+
return 2000 if (4..9).include?(first_digit) && year < 37
|
40
|
+
1900
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'national_identification_number/base'
|
2
|
+
|
3
|
+
module NationalIdentificationNumber
|
4
|
+
class Norwegian < Base
|
5
|
+
attr_reader :date
|
6
|
+
|
7
|
+
protected
|
8
|
+
|
9
|
+
def repair
|
10
|
+
super
|
11
|
+
@number.gsub!(/[^0-9]/, '')
|
12
|
+
end
|
13
|
+
|
14
|
+
def validate
|
15
|
+
if (matches = @number.match(/\A(?<day>\d{2})(?<month>\d{2})(?<year>\d{2})(?<serial>\d{3})(?<checksum>\d{2})\z/))
|
16
|
+
day, month, year, serial, checksum = matches.values_at(:day, :month, :year, :serial, :checksum)
|
17
|
+
sans_checksum = "#{day}#{month}#{year}#{serial}"
|
18
|
+
|
19
|
+
if checksum == calculate_checksum(sans_checksum)
|
20
|
+
begin
|
21
|
+
@date = Date.parse("#{full_year(serial, year)}-#{month}-#{day}")
|
22
|
+
@valid = true
|
23
|
+
@number = "#{sans_checksum}#{checksum}"
|
24
|
+
rescue ArgumentError
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def full_year(serial, year)
|
33
|
+
century(serial) + year.to_i
|
34
|
+
end
|
35
|
+
|
36
|
+
def century(serial)
|
37
|
+
case serial.to_i
|
38
|
+
when 0..499 then 1900
|
39
|
+
else 2000 # or 1800, not possible to tell.
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def calculate_checksum(number)
|
44
|
+
digits = number.split('').map(&:to_i)
|
45
|
+
w1 = [3, 7, 6, 1, 8, 9, 4, 5, 2]
|
46
|
+
w2 = [5, 4, 3, 2, 7, 6, 5, 4, 3, 2]
|
47
|
+
|
48
|
+
k1 = weighted_modulo_11(digits.zip(w1))
|
49
|
+
k2 = weighted_modulo_11([*digits, k1].zip(w2))
|
50
|
+
"#{k1}#{k2}"
|
51
|
+
end
|
52
|
+
|
53
|
+
def weighted_modulo_11(digits_and_weights)
|
54
|
+
result = 11 - (digits_and_weights.map do |terms|
|
55
|
+
terms.reduce(:*)
|
56
|
+
end.sum % 11)
|
57
|
+
result > 9 ? 0 : result
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -4,7 +4,6 @@ module NationalIdentificationNumber
|
|
4
4
|
# Inspired by https://github.com/c7/personnummer/blob/master/lib/personnummer.rb
|
5
5
|
# Copyright (c) 2008 Peter Hellberg MIT
|
6
6
|
class Swedish < Base
|
7
|
-
|
8
7
|
attr_reader :date # used for testing
|
9
8
|
|
10
9
|
# Generator for valid Swedish personnummer: http://en.wikipedia.org/wiki/Personal_identity_number_(Sweden)
|
@@ -31,7 +30,12 @@ module NationalIdentificationNumber
|
|
31
30
|
if @number.match(/\A(\d{0}|\d{2})(\d{6})(\-{0,1})(\d{4})\Z/)
|
32
31
|
@number = "#{$2}-#{$4}"
|
33
32
|
else
|
34
|
-
@number.gsub
|
33
|
+
candidate = @number.gsub(/[^\d\-\+]/, '')
|
34
|
+
if candidate.match(/\A(\d{0}|\d{2})(\d{6})(\-{0,1})(\d{4})\Z/)
|
35
|
+
@number = "#{$2}-#{$4}"
|
36
|
+
else
|
37
|
+
@number = candidate
|
38
|
+
end
|
35
39
|
end
|
36
40
|
end
|
37
41
|
|
@@ -98,15 +102,14 @@ module NationalIdentificationNumber
|
|
98
102
|
end
|
99
103
|
control_digit
|
100
104
|
end
|
101
|
-
|
102
105
|
end
|
103
106
|
end
|
104
107
|
|
105
|
-
if $0 == __FILE__
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
end
|
108
|
+
# if $0 == __FILE__
|
109
|
+
# # Randomize every part
|
110
|
+
# puts Bukowskis::NationalIdentificationNumber::Swedish.generate
|
111
|
+
# # Use given date, randomize serial
|
112
|
+
# puts Bukowskis::NationalIdentificationNumber::Swedish.generate(Date.new(1975,1,1))
|
113
|
+
# # Use given date and serial, calculate checksum
|
114
|
+
# puts Bukowskis::NationalIdentificationNumber::Swedish.generate(Date.new(1975,1,1), 123)
|
115
|
+
# end
|
@@ -74,4 +74,23 @@ describe NationalIdentificationNumber::Base do
|
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
|
+
describe '#==' do
|
78
|
+
it 'should be true if same class and string representation' do
|
79
|
+
one = NationalIdentificationNumber::Swedish.new('040626-5488')
|
80
|
+
other = NationalIdentificationNumber::Swedish.new('20040626-5488')
|
81
|
+
expect(one == other).to be true
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should be false if other string representation' do
|
85
|
+
one = NationalIdentificationNumber::Swedish.new('040626-5488')
|
86
|
+
other = NationalIdentificationNumber::Swedish.new('040626-8128')
|
87
|
+
expect(one == other).to be false
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'should be false if other class' do
|
91
|
+
one = NationalIdentificationNumber::Swedish.new('040626-5488')
|
92
|
+
other = NationalIdentificationNumber::Finnish.new('040626-5488')
|
93
|
+
expect(one == other).to be false
|
94
|
+
end
|
95
|
+
end
|
77
96
|
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'resident'
|
3
|
+
|
4
|
+
describe NationalIdentificationNumber::Danish do
|
5
|
+
describe '#valid?' do
|
6
|
+
it 'recognizes valid numbers' do
|
7
|
+
expect(described_class.new('311257-1735')).to be_valid
|
8
|
+
expect(described_class.new('290444-0305')).to be_valid
|
9
|
+
expect(described_class.new('300168-0330')).to be_valid
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'recognizes invalid numbers' do
|
13
|
+
expect(described_class.new('251379-4001')).not_to be_valid # invalid month
|
14
|
+
expect(described_class.new('300279-4001')).not_to be_valid # invalid day
|
15
|
+
expect(described_class.new('asdf')).not_to be_valid
|
16
|
+
expect(described_class.new('1234567890')).not_to be_valid
|
17
|
+
expect(described_class.new('0000000000000')).not_to be_valid
|
18
|
+
expect(described_class.new('000000-0000')).not_to be_valid
|
19
|
+
expect(described_class.new('')).not_to be_valid
|
20
|
+
expect(described_class.new(1234567890)).not_to be_valid
|
21
|
+
expect(described_class.new(:really_bad_input_value)).not_to be_valid
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe 'sanitize' do
|
26
|
+
context 'with valid numbers' do
|
27
|
+
it 'is the formatted number' do
|
28
|
+
expect(described_class.new('3112571735').sanitize).to eq '311257-1735'
|
29
|
+
expect(described_class.new('290444.0305').sanitize).to eq '290444-0305'
|
30
|
+
expect(described_class.new('30.01.68.03.30').sanitize).to eq '300168-0330'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'with invalid numbers' do
|
35
|
+
it 'is nil' do
|
36
|
+
expect(described_class.new('251379-4001').sanitize).to be_nil
|
37
|
+
expect(described_class.new('300279-4001').sanitize).to be_nil
|
38
|
+
expect(described_class.new('asdf').sanitize).to be_nil
|
39
|
+
expect(described_class.new('1234567890').sanitize).to be_nil
|
40
|
+
expect(described_class.new('0000000000000').sanitize).to be_nil
|
41
|
+
expect(described_class.new('000000-0000').sanitize).to be_nil
|
42
|
+
expect(described_class.new('').sanitize).to be_nil
|
43
|
+
expect(described_class.new(1234567890).sanitize).to be_nil
|
44
|
+
expect(described_class.new(:really_bad_input_value).sanitize).to be_nil
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe 'age' do
|
50
|
+
before do
|
51
|
+
Timecop.freeze Date.parse('2022-03-04')
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'recognizes valid numbers' do
|
55
|
+
expect(described_class.new('110779-4101').age).to eq 42
|
56
|
+
expect(described_class.new('010100-1000').age).to eq 122
|
57
|
+
expect(described_class.new('110736-4002').age).to be_nil # Birthday in the future
|
58
|
+
expect(described_class.new('030320-5006').age).to eq 2
|
59
|
+
expect(described_class.new('110952-3113').age).to eq 69
|
60
|
+
expect(described_class.new('211164-2234').age).to eq 57
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'is nil for invalid numbers' do
|
64
|
+
expect(described_class.new('251379-4001').age).to be_nil # invalid month
|
65
|
+
expect(described_class.new('300279-4001').age).to be_nil # invalid day
|
66
|
+
expect(described_class.new('asdf').age).to be_nil
|
67
|
+
expect(described_class.new('1234567890').age).to be_nil
|
68
|
+
expect(described_class.new('0000000000000').age).to be_nil
|
69
|
+
expect(described_class.new('000000-0000').age).to be_nil
|
70
|
+
expect(described_class.new('').age).to be_nil
|
71
|
+
expect(described_class.new(1234567890).age).to be_nil
|
72
|
+
expect(described_class.new(:really_bad_input_value).age).to be_nil
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe '#to_s' do
|
77
|
+
it 'returns the number normalized regardless of wether its valid' do
|
78
|
+
expect(described_class.new('251.379.4001').to_s).to eq '251379-4001'
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -5,7 +5,6 @@ include NationalIdentificationNumber
|
|
5
5
|
|
6
6
|
describe Finnish do
|
7
7
|
describe '#valid?' do
|
8
|
-
|
9
8
|
it "recognizes valid numbers" do
|
10
9
|
expect( Finnish.new('311280-999J') ).to be_valid
|
11
10
|
expect( Finnish.new('131052-308T') ).to be_valid
|
@@ -32,7 +31,39 @@ describe Finnish do
|
|
32
31
|
expect( Finnish.new(1234567890) ).to_not be_valid
|
33
32
|
expect( Finnish.new(:really_bad_input_value) ).to_not be_valid
|
34
33
|
end
|
34
|
+
end
|
35
35
|
|
36
|
+
describe 'sanitize' do
|
37
|
+
context 'valid numbers' do
|
38
|
+
it 'is the formatted number' do
|
39
|
+
expect(Finnish.new('311280-999J').sanitize).to eq '311280-999J'
|
40
|
+
expect(Finnish.new('131052-308T').sanitize).to eq '131052-308T'
|
41
|
+
expect(Finnish.new('290164-862u').sanitize).to eq '290164-862U'
|
42
|
+
expect(Finnish.new('270368A172X').sanitize).to eq '270368A172X'
|
43
|
+
expect(Finnish.new('310145A586a').sanitize).to eq '310145A586A'
|
44
|
+
expect(Finnish.new('080266+183P').sanitize).to eq '080266+183P'
|
45
|
+
expect(Finnish.new('290248+145c').sanitize).to eq '290248+145C'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'invalid numbers' do
|
50
|
+
it 'is nil' do
|
51
|
+
expect(Finnish.new('671301A172V').sanitize).to be nil
|
52
|
+
expect(Finnish.new('830231A172M').sanitize).to be nil
|
53
|
+
expect(Finnish.new('311180-999J').sanitize).to be nil
|
54
|
+
expect(Finnish.new('131052-308S').sanitize).to be nil
|
55
|
+
expect(Finnish.new('290164X862U').sanitize).to be nil
|
56
|
+
expect(Finnish.new('670368A172X').sanitize).to be nil
|
57
|
+
expect(Finnish.new('310145--586A').sanitize).to be nil
|
58
|
+
expect(Finnish.new('asdf').sanitize).to be nil
|
59
|
+
expect(Finnish.new('1234567890').sanitize).to be nil
|
60
|
+
expect(Finnish.new('0000000000000').sanitize).to be nil
|
61
|
+
expect(Finnish.new('000000-0000').sanitize).to be nil
|
62
|
+
expect(Finnish.new('').sanitize).to be nil
|
63
|
+
expect(Finnish.new(1234567890).sanitize).to be nil
|
64
|
+
expect(Finnish.new(:really_bad_input_value).sanitize).to be nil
|
65
|
+
end
|
66
|
+
end
|
36
67
|
end
|
37
68
|
|
38
69
|
describe 'age' do
|
@@ -94,4 +125,4 @@ describe Finnish do
|
|
94
125
|
end
|
95
126
|
|
96
127
|
end
|
97
|
-
end
|
128
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'resident'
|
3
|
+
|
4
|
+
describe NationalIdentificationNumber::Norwegian do
|
5
|
+
describe '#valid?' do
|
6
|
+
it 'recognizes valid numbers' do
|
7
|
+
expect(described_class.new('11077941012')).to be_valid
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'recognizes invalid numbers' do
|
11
|
+
expect(described_class.new('671301A172V')).not_to be_valid # valid checksum, invalid month
|
12
|
+
expect(described_class.new('830231A172M')).not_to be_valid # valid checksum, invalid day
|
13
|
+
expect(described_class.new('11077941010')).not_to be_valid
|
14
|
+
expect(described_class.new('670368A172X')).not_to be_valid
|
15
|
+
expect(described_class.new('310145--586A')).not_to be_valid
|
16
|
+
expect(described_class.new('asdf')).not_to be_valid
|
17
|
+
expect(described_class.new('1234567890')).not_to be_valid
|
18
|
+
expect(described_class.new('0000000000000')).not_to be_valid
|
19
|
+
expect(described_class.new('000000-0000')).not_to be_valid
|
20
|
+
expect(described_class.new('')).not_to be_valid
|
21
|
+
expect(described_class.new(1234567890)).not_to be_valid
|
22
|
+
expect(described_class.new(:really_bad_input_value)).not_to be_valid
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe 'sanitize' do
|
27
|
+
context 'with valid numbers' do
|
28
|
+
it 'is the formatted number' do
|
29
|
+
expect(described_class.new('11077941012').sanitize).to eq '11077941012'
|
30
|
+
expect(described_class.new('11.07.79.410.12').sanitize).to eq '11077941012'
|
31
|
+
expect(described_class.new('11 07 79 41012').sanitize).to eq '11077941012'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'with invalid numbers' do
|
36
|
+
it 'is nil' do
|
37
|
+
expect(described_class.new('11077941010').sanitize).to be_nil
|
38
|
+
expect(described_class.new('671301A172V').sanitize).to be_nil
|
39
|
+
expect(described_class.new('830231A172M').sanitize).to be_nil
|
40
|
+
expect(described_class.new('311180-999J').sanitize).to be_nil
|
41
|
+
expect(described_class.new('131052-308S').sanitize).to be_nil
|
42
|
+
expect(described_class.new('290164X862U').sanitize).to be_nil
|
43
|
+
expect(described_class.new('670368A172X').sanitize).to be_nil
|
44
|
+
expect(described_class.new('310145--586A').sanitize).to be_nil
|
45
|
+
expect(described_class.new('asdf').sanitize).to be_nil
|
46
|
+
expect(described_class.new('1234567890').sanitize).to be_nil
|
47
|
+
expect(described_class.new('0000000000000').sanitize).to be_nil
|
48
|
+
expect(described_class.new('000000-0000').sanitize).to be_nil
|
49
|
+
expect(described_class.new('').sanitize).to be_nil
|
50
|
+
expect(described_class.new(1234567890).sanitize).to be_nil
|
51
|
+
expect(described_class.new(:really_bad_input_value).sanitize).to be_nil
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe 'age' do
|
57
|
+
before do
|
58
|
+
Timecop.freeze Date.parse('2022-03-04')
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'recognizes valid numbers' do
|
62
|
+
expect(described_class.new('11077941012').age).to eq 42
|
63
|
+
expect(described_class.new('01010010000').age).to eq 122
|
64
|
+
expect(described_class.new('11077950020').age).to be_nil # Birthday in the future
|
65
|
+
expect(described_class.new('03032050068').age).to eq 2
|
66
|
+
expect(described_class.new('11095231138').age).to eq 69
|
67
|
+
expect(described_class.new('21116422341').age).to eq 57
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'is nil for invalid numbers' do
|
71
|
+
expect(described_class.new('671301A172V').age).to be_nil
|
72
|
+
expect(described_class.new('830231A172M').age).to be_nil
|
73
|
+
expect(described_class.new('311180-999J').age).to be_nil
|
74
|
+
expect(described_class.new('131052-308S').age).to be_nil
|
75
|
+
expect(described_class.new('290164X862U').age).to be_nil
|
76
|
+
expect(described_class.new('670368A172X').age).to be_nil
|
77
|
+
expect(described_class.new('310145--586A').age).to be_nil
|
78
|
+
expect(described_class.new('asdf').age).to be_nil
|
79
|
+
expect(described_class.new('1234567890').age).to be_nil
|
80
|
+
expect(described_class.new('0000000000000').age).to be_nil
|
81
|
+
expect(described_class.new('000000-0000').age).to be_nil
|
82
|
+
expect(described_class.new('').age).to be_nil
|
83
|
+
expect(described_class.new(1234567890).age).to be_nil
|
84
|
+
expect(described_class.new(:really_bad_input_value).age).to be_nil
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe '#to_s' do
|
89
|
+
it 'returns the number normalized regardless of wether it is valid' do
|
90
|
+
expect(described_class.new('311280999J').to_s).to eq '311280999'
|
91
|
+
expect(described_class.new('27..036.8A172X ').to_s).to eq '270368172'
|
92
|
+
expect(described_class.new('xx270368A172X ').to_s).to eq '270368172'
|
93
|
+
expect(described_class.new('xxx270368A172Xt ').to_s).to eq '270368172'
|
94
|
+
expect(described_class.new('\t050126-1853').to_s).to eq '0501261853'
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -41,6 +41,40 @@ describe Swedish, '.generate' do
|
|
41
41
|
|
42
42
|
end
|
43
43
|
|
44
|
+
describe 'sanitize' do
|
45
|
+
context 'invalid numbers' do
|
46
|
+
it 'is nil' do
|
47
|
+
expect(Swedish.new('991301-1236').sanitize).to be nil # valid checksum, invalid month
|
48
|
+
expect(Swedish.new('830231-5554').sanitize).to be nil # valid checksum, invalid day
|
49
|
+
expect(Swedish.new('050112--2451').sanitize).to be nil
|
50
|
+
expect(Swedish.new('123456-1239').sanitize).to be nil
|
51
|
+
expect(Swedish.new('180123-2668').sanitize).to be nil
|
52
|
+
expect(Swedish.new('150D1261853').sanitize).to be nil
|
53
|
+
expect(Swedish.new('750112-2451').sanitize).to be nil
|
54
|
+
expect(Swedish.new('123').sanitize).to be nil
|
55
|
+
expect(Swedish.new('000000-0000').sanitize).to be nil
|
56
|
+
expect(Swedish.new('0000000000').sanitize).to be nil
|
57
|
+
expect(Swedish.new('asdfghj').sanitize).to be nil
|
58
|
+
expect(Swedish.new('').sanitize).to be nil
|
59
|
+
expect(Swedish.new(12345678).sanitize).to be nil
|
60
|
+
expect(Swedish.new(:really_bad_input).sanitize).to be nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'valid numbers' do
|
65
|
+
it 'is the sanitize dnumber' do
|
66
|
+
expect(Swedish.new('19180123-2669').sanitize).to eq '180123-2669'
|
67
|
+
expect(Swedish.new('00180123-2669').sanitize).to eq '180123-2669'
|
68
|
+
expect(Swedish.new('000180123-2669').sanitize).to eq '180123-2669'
|
69
|
+
expect(Swedish.new('050126-1853').sanitize).to eq '050126-1853'
|
70
|
+
expect(Swedish.new('0asdfghj501261853').sanitize).to eq '050126-1853'
|
71
|
+
expect(Swedish.new('050112-2451').sanitize).to eq '050112-2451'
|
72
|
+
expect(Swedish.new('450202-6950').sanitize).to eq '450202-6950'
|
73
|
+
expect(Swedish.new('19450202-6950').sanitize).to eq '450202-6950'
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
44
78
|
describe '#age' do
|
45
79
|
|
46
80
|
before do
|
@@ -90,6 +124,7 @@ describe Swedish, '.generate' do
|
|
90
124
|
it "return the number normalized if the number is valid" do
|
91
125
|
expect( Swedish.new('0501261853').to_s ).to eq '050126-1853'
|
92
126
|
expect( Swedish.new('050126-1853').to_s ).to eq '050126-1853'
|
127
|
+
expect( Swedish.new('0asdfghj501261853').to_s).to eq '050126-1853'
|
93
128
|
expect( Swedish.new("190501261853").to_s ).to eq '050126-1853'
|
94
129
|
expect( Swedish.new("19050126-1853").to_s ).to eq '050126-1853'
|
95
130
|
expect( Swedish.new("19050126-185d3").to_s ).to eq '050126-1853'
|
@@ -180,4 +215,4 @@ describe Swedish, '.generate' do
|
|
180
215
|
end
|
181
216
|
end
|
182
217
|
|
183
|
-
end
|
218
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: resident
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bukowskis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-06-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -24,34 +24,6 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: guard-rspec
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: rb-fsevent
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
55
27
|
- !ruby/object:Gem::Dependency
|
56
28
|
name: timecop
|
57
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -76,11 +48,15 @@ files:
|
|
76
48
|
- README.md
|
77
49
|
- lib/national_identification_number.rb
|
78
50
|
- lib/national_identification_number/base.rb
|
51
|
+
- lib/national_identification_number/danish.rb
|
79
52
|
- lib/national_identification_number/finnish.rb
|
53
|
+
- lib/national_identification_number/norwegian.rb
|
80
54
|
- lib/national_identification_number/swedish.rb
|
81
55
|
- lib/resident.rb
|
82
56
|
- spec/national_identification_number/base_spec.rb
|
57
|
+
- spec/national_identification_number/danish_spec.rb
|
83
58
|
- spec/national_identification_number/finnish_spec.rb
|
59
|
+
- spec/national_identification_number/norwegian_spec.rb
|
84
60
|
- spec/national_identification_number/swedish_spec.rb
|
85
61
|
- spec/spec_helper.rb
|
86
62
|
homepage: http://github.com/bukowskis/national_identification_number/
|
@@ -103,8 +79,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
103
79
|
- !ruby/object:Gem::Version
|
104
80
|
version: '0'
|
105
81
|
requirements: []
|
106
|
-
|
107
|
-
rubygems_version: 2.2.2
|
82
|
+
rubygems_version: 3.0.3.1
|
108
83
|
signing_key:
|
109
84
|
specification_version: 4
|
110
85
|
summary: Validate National Identification Numbers.
|