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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 81eb7bb2954ef3ebc22afde17e6f70b508020acc
4
- data.tar.gz: 6cea7414b6edc216d91ba274bced8d058bd05d59
3
+ metadata.gz: b59380a0e5ddb9e3885510cc564dfe25aa0bc3f7
4
+ data.tar.gz: 5b5e62bc3c546f638da79f78defe1b549e20ec0e
5
5
  SHA512:
6
- metadata.gz: 703a0437f83f5d03eb8ffc6bbedaf3dd422b77d3327646bca2b0ae0c262e2269dc88d702be9901bbb8b7227a230730f077c9241d0017567576ba77db18e26d56
7
- data.tar.gz: f7244387c404bb224cf90585df93141537f7a3dc72e99f8cf543eb57d82b2469fb49f2ed3c47ca8314558e42878122fa78857067d11162a7a03c08d31f5cf1a4
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
- Usage is fairly simple, there's an exposed `get` class method that you can pass in a VIN string to, and it will return you a NhtsaVin::Query.
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 webservice is contained in the `response` method. This returns a struct containing the various interesting bits from the API.
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
@@ -1,3 +1,3 @@
1
1
  module NhtsaVin
2
- VERSION = '0.0.4'.freeze
2
+ VERSION = '0.0.5'.freeze
3
3
  end
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
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-05 00:00:00.000000000 Z
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