nhtsa_vin 0.0.4 → 0.0.5
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 +21 -3
- data/lib/nhtsa_vin/validation.rb +76 -0
- data/lib/nhtsa_vin/version.rb +1 -1
- data/lib/nhtsa_vin.rb +1 -1
- data/spec/lib/nhtsa_vin/validation_spec.rb +108 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b59380a0e5ddb9e3885510cc564dfe25aa0bc3f7
|
4
|
+
data.tar.gz: 5b5e62bc3c546f638da79f78defe1b549e20ec0e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ca9557397db41dceaa8e7db53e26f7560b63e6bee043912dfa39107490d0e36c51e3bd7ecb2f6bac7c60aadfb3b7c3d8d399be31fa1f3ad9994bc0fc5b67e02b
|
7
|
+
data.tar.gz: b73345bd38a58f64fe14b252f1d05b016d9770658560e5ff71e65803baf1adeca134b16a86fa27abf7ccff0e944d8954e5c9ac5b0cc03acffbcbe859c1496151
|
data/README.md
CHANGED
@@ -25,16 +25,34 @@ Or install it yourself as:
|
|
25
25
|
|
26
26
|
gem install nhsta_vin
|
27
27
|
|
28
|
-
## Usage
|
28
|
+
## Usage
|
29
29
|
|
30
|
-
|
30
|
+
Validation
|
31
|
+
----
|
32
|
+
|
33
|
+
Prior to dispatching a call to the web service, you can optionally validate a given VIN first.
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
validation = NhtsaVin.Validate.new('1J4BA5H11AL143811') # => <#NhtsaVin.Validate>
|
37
|
+
validation.valid? # => true
|
38
|
+
validation.checksum # => 1
|
39
|
+
|
40
|
+
validation = NhtsaVin.Validate.new('SOMEBADVIN') # => <#NhtsaVin.Validate>
|
41
|
+
validation.valid? # => false
|
42
|
+
validation.checksum # => nil
|
43
|
+
```
|
44
|
+
|
45
|
+
Query
|
46
|
+
----
|
47
|
+
|
48
|
+
The main method for the gem is `NhtsaVin::get`, which takes a VIN string as the argument, and will return you a NhtsaVin::Query.
|
31
49
|
|
32
50
|
```ruby
|
33
51
|
query = NhtsaVin.get('1J4BA5H11AL143811') # => <NhtsaVin::Query>
|
34
52
|
query.valid? # => true
|
35
53
|
```
|
36
54
|
|
37
|
-
The actual data from the
|
55
|
+
The actual data from the web service is contained in the `response` method. This returns a struct containing the various interesting bits from the API.
|
38
56
|
|
39
57
|
```ruby
|
40
58
|
query.response # => <Struct::NhtsaResponse make="Jeep", model="Grand Cherokee", trim="Laredo/Rocky Mountain Edition", type="SUV", year="2008", size=nil, ... doors=4>
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module NhtsaVin
|
4
|
+
class Validation
|
5
|
+
TRANSLITERATIONS = { 'A': 1, 'B': 2, 'C': 3, 'D': 4, 'E': 5, 'F': 6, 'G': 7,
|
6
|
+
'H': 8, 'J': 1, 'K': 2, 'L': 3, 'M': 4, 'N': 5, 'P': 7,
|
7
|
+
'R': 9, 'S': 2, 'T': 3, 'U': 4, 'V': 5, 'W': 6, 'X': 7,
|
8
|
+
'Y': 8, 'Z': 9 }.freeze
|
9
|
+
|
10
|
+
WEIGHTS = [8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2].freeze
|
11
|
+
|
12
|
+
attr_reader :vin, :valid, :wmi, :vds, :check, :plant, :seq, :error
|
13
|
+
|
14
|
+
##
|
15
|
+
# Validates a VIN that it fits both the definition, and that the checksum
|
16
|
+
# is valid.
|
17
|
+
#
|
18
|
+
def initialize(vin)
|
19
|
+
@valid = false
|
20
|
+
if vin.nil?
|
21
|
+
@error = 'Blank VIN provided'
|
22
|
+
return
|
23
|
+
end
|
24
|
+
@vin = vin.strip
|
25
|
+
if !regex
|
26
|
+
@error = 'Invalid VIN format'
|
27
|
+
return
|
28
|
+
elsif checksum != @check
|
29
|
+
@error = "VIN checksum digit #{@check} failed "\
|
30
|
+
"to calculate (expected #{checksum})"
|
31
|
+
return
|
32
|
+
else
|
33
|
+
@valid = true
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def valid?
|
38
|
+
@valid
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def regex
|
44
|
+
match_data = %r{
|
45
|
+
^(?<wmi>[A-HJ-NPR-Z\d]{3})
|
46
|
+
(?<vds>[A-HJ-NPR-Z\d]{5})
|
47
|
+
(?<check>[\dX])
|
48
|
+
(?<vis>(?<year>[A-HJ-NPR-Z\d])
|
49
|
+
(?<plant>[A-HJ-NPR-Z\d])
|
50
|
+
(?<seq>[A-HJ-NPR-Z\d]{6}))$
|
51
|
+
}ix.match(@vin)
|
52
|
+
|
53
|
+
if match_data
|
54
|
+
@wmi = match_data[:wmi]
|
55
|
+
@vds = match_data[:vds]
|
56
|
+
@check = match_data[:check]
|
57
|
+
@vis = match_data[:vis]
|
58
|
+
@plant = match_data[:plant]
|
59
|
+
@seq = match_data[:seq]
|
60
|
+
end
|
61
|
+
match_data
|
62
|
+
end
|
63
|
+
|
64
|
+
def checksum
|
65
|
+
m = @vin.chars.each_with_index.map do |char, i|
|
66
|
+
if char !~ /\D/
|
67
|
+
char.to_i * WEIGHTS[i]
|
68
|
+
else
|
69
|
+
TRANSLITERATIONS[char.upcase.to_sym] * WEIGHTS[i]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
checksum = m.inject(0, :+) % 11
|
73
|
+
checksum == 10 ? 'X' : checksum.to_s
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/nhtsa_vin/version.rb
CHANGED
data/lib/nhtsa_vin.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'nhtsa_vin/version'
|
2
2
|
require 'nhtsa_vin/query'
|
3
|
+
require 'nhtsa_vin/validation'
|
3
4
|
|
4
5
|
module NhtsaVin
|
5
6
|
extend self
|
@@ -7,7 +8,6 @@ module NhtsaVin
|
|
7
8
|
def get(vin, options={})
|
8
9
|
query = NhtsaVin::Query.new(vin, options)
|
9
10
|
query.get
|
10
|
-
|
11
11
|
return query
|
12
12
|
end
|
13
13
|
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe NhtsaVin::Validation do
|
4
|
+
describe 'attrs' do
|
5
|
+
context 'with a valid VIN' do
|
6
|
+
let(:validation) { NhtsaVin::Validation.new('19XFB2F89CE308518') }
|
7
|
+
it 'has the checksum digit' do
|
8
|
+
expect(validation.check).to eq '9'
|
9
|
+
end
|
10
|
+
it 'parses out the WMI' do
|
11
|
+
expect(validation.wmi).to eq '19X'
|
12
|
+
end
|
13
|
+
it 'parses out the plant ID' do
|
14
|
+
expect(validation.plant).to eq 'E'
|
15
|
+
end
|
16
|
+
it 'parses out the sequence info' do
|
17
|
+
expect(validation.seq).to eq '308518'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
context 'with an invalid VIN' do
|
21
|
+
let(:validation) { NhtsaVin::Validation.new('WBAEV534X2KM1611') }
|
22
|
+
it 'has nil attrs' do
|
23
|
+
expect(validation.check).to be_nil
|
24
|
+
expect(validation.wmi).to be_nil
|
25
|
+
expect(validation.plant).to be_nil
|
26
|
+
expect(validation.seq).to be_nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
describe '#valid?' do
|
31
|
+
context 'a valid VIN' do
|
32
|
+
it 'validates' do
|
33
|
+
expect(NhtsaVin::Validation.new('19XFB2F89CE308518').valid?)
|
34
|
+
.to be true
|
35
|
+
end
|
36
|
+
it 'handles checksums of 10' do
|
37
|
+
expect(NhtsaVin::Validation.new('5NPEU46FX6H141974').valid?)
|
38
|
+
.to be true
|
39
|
+
end
|
40
|
+
it 'strips whitespace' do
|
41
|
+
expect(NhtsaVin::Validation.new(' 4T1BD1FK5CU061770 ').valid?)
|
42
|
+
.to be true
|
43
|
+
end
|
44
|
+
it 'validates BMW VINs' do
|
45
|
+
expect(NhtsaVin::Validation.new('WBAEV534X2KM16113').valid?)
|
46
|
+
.to be true
|
47
|
+
end
|
48
|
+
end
|
49
|
+
context 'an invalid VIN' do
|
50
|
+
context 'when the vin is too short' do
|
51
|
+
let(:validation) { NhtsaVin::Validation.new('WBAEV534X2KM1611') }
|
52
|
+
it 'fails' do
|
53
|
+
expect(validation.valid?).to be false
|
54
|
+
expect(validation.error).to eq 'Invalid VIN format'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
context 'when the vin contains O' do
|
58
|
+
let(:validation) { NhtsaVin::Validation.new('WBAEV534X2KM1611O') }
|
59
|
+
it 'fails' do
|
60
|
+
expect(NhtsaVin).not_to receive(:checksum)
|
61
|
+
expect(validation.valid?).to be false
|
62
|
+
expect(validation.error).to eq 'Invalid VIN format'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
context 'when the vin contains I' do
|
66
|
+
let(:validation) { NhtsaVin::Validation.new('WBAEV534X2KM1611I') }
|
67
|
+
it 'fails' do
|
68
|
+
expect(NhtsaVin).not_to receive(:checksum)
|
69
|
+
expect(validation.valid?).to be false
|
70
|
+
expect(validation.error).to eq 'Invalid VIN format'
|
71
|
+
end
|
72
|
+
end
|
73
|
+
context 'fails when the vin contains Q' do
|
74
|
+
let(:validation) { NhtsaVin::Validation.new('WBAEV534X2KM1611Q') }
|
75
|
+
it 'fails' do
|
76
|
+
expect(NhtsaVin).not_to receive(:checksum)
|
77
|
+
expect(validation.valid?).to be false
|
78
|
+
expect(validation.error).to eq 'Invalid VIN format'
|
79
|
+
end
|
80
|
+
end
|
81
|
+
context 'when the checksum is incorrect' do
|
82
|
+
let(:validation) { NhtsaVin::Validation.new('5NPEU46F96H141974') }
|
83
|
+
it 'fails' do
|
84
|
+
expect(validation.valid?).to be false
|
85
|
+
expect(validation.error)
|
86
|
+
.to eq 'VIN checksum digit 9 failed to calculate (expected X)'
|
87
|
+
end
|
88
|
+
end
|
89
|
+
context 'when the vin is nil' do
|
90
|
+
let(:validation) { NhtsaVin::Validation.new(nil) }
|
91
|
+
it 'fails' do
|
92
|
+
expect(validation.valid?).to be false
|
93
|
+
expect(validation.error).to eq 'Blank VIN provided'
|
94
|
+
end
|
95
|
+
end
|
96
|
+
context 'when high-ascii chars are used' do
|
97
|
+
it 'fails' do
|
98
|
+
expect(NhtsaVin::Validation.new('∂BAEV534X2KM16113').valid?)
|
99
|
+
.to be false
|
100
|
+
expect(NhtsaVin::Validation.new('🥃BAEV534X2KM16113').valid?)
|
101
|
+
.to be false
|
102
|
+
expect(NhtsaVin::Validation.new('WBAEV534X2KM1611').error)
|
103
|
+
.to eq 'Invalid VIN format'
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nhtsa_vin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Barclay Loftus
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-02-
|
11
|
+
date: 2018-02-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -72,11 +72,13 @@ files:
|
|
72
72
|
- Rakefile
|
73
73
|
- lib/nhtsa_vin.rb
|
74
74
|
- lib/nhtsa_vin/query.rb
|
75
|
+
- lib/nhtsa_vin/validation.rb
|
75
76
|
- lib/nhtsa_vin/version.rb
|
76
77
|
- nhtsa_vin.gemspec
|
77
78
|
- spec/fixtures/not_found.json
|
78
79
|
- spec/fixtures/success.json
|
79
80
|
- spec/lib/nhtsa_vin/query_spec.rb
|
81
|
+
- spec/lib/nhtsa_vin/validation_spec.rb
|
80
82
|
- spec/spec_helper.rb
|
81
83
|
homepage: https://github.com/deliv/nhtsa_vin
|
82
84
|
licenses:
|
@@ -106,4 +108,5 @@ test_files:
|
|
106
108
|
- spec/fixtures/not_found.json
|
107
109
|
- spec/fixtures/success.json
|
108
110
|
- spec/lib/nhtsa_vin/query_spec.rb
|
111
|
+
- spec/lib/nhtsa_vin/validation_spec.rb
|
109
112
|
- spec/spec_helper.rb
|