vindetta 0.19.0 → 0.20.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: ef0a0382f394eb885e1ef31017cb92a1176ff84d
4
- data.tar.gz: abdb80414aab149e380217fae57357c89a99579c
3
+ metadata.gz: c8dfed0d7c7a0c406c59017a6468cfa8e313a114
4
+ data.tar.gz: 3976fb86a2f0f0d1da131afc050b8a194569c808
5
5
  SHA512:
6
- metadata.gz: 67d06d280c0d2f201b124a1923911154f48e8441487340a7e0a47a8553a4713823b4bdd5a7f3f091b555d8e7cc1766a0ad8ec206fefd0dc9c4b3f1b5f78f943b
7
- data.tar.gz: 96dae041eadc8982a620a1766d7b5d370b4f289167c4ef8cd9f47da29465edc3be525d3241faf38284d58ad49ad61a9103ee7f1b6032f53621dc8e26af083373
6
+ metadata.gz: 861597ee5333726eb83c2486b4b8586d186f5c4b2529945cbd4cdeae49fd1e6b2f24cc0ea5a2a58ad1bf770a7e725ad29c7024e92fd4e8ef5e2670c43f684f0b
7
+ data.tar.gz: '082362eb73ac1ebe451d5c2dc12f2edd22b2903523f9cb49f92b0c00aa47cc1cbb2e6a99f9b6734db2fee48221f26f6486cd8714689319c1d5b5ac5594cd0856'
data/.travis.yml CHANGED
@@ -2,4 +2,4 @@ sudo: false
2
2
  language: ruby
3
3
  rvm:
4
4
  - 2.4.1
5
- before_install: gem install bundler -v 1.14.6
5
+ before_install: gem install bundler -v 1.16.1
@@ -1,19 +1,21 @@
1
1
  module Vindetta
2
2
  class Calculator
3
- CHECK_DIGITS = "0123456789X".chars
4
- WEIGHTS = [8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2]
5
-
6
3
  def self.check_digit(vin)
7
- CHECK_DIGITS[sum(vin) % CHECK_DIGITS.length]
8
- end
4
+ transliterator = -> (c) do
5
+ "0123456789.ABCDEFGH..JKLMN.P.R..STUVWXYZ".chars.index(c) % 10
6
+ end
7
+
8
+ summer = -> (sum, (a, b)) do
9
+ sum + (a * b)
10
+ end
9
11
 
10
- private
12
+ sum = vin
13
+ .chars
14
+ .map(&transliterator)
15
+ .zip([8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2])
16
+ .reduce(0, &summer)
11
17
 
12
- def self.sum(vin)
13
- Transliterator
14
- .vin(vin)
15
- .zip(WEIGHTS)
16
- .reduce(0) { |sum, (a, b)| sum + (a * b) }
18
+ "0123456789X"[sum % 11]
17
19
  end
18
20
  end
19
21
  end
data/lib/vindetta/cli.rb CHANGED
@@ -32,7 +32,7 @@ module Vindetta
32
32
 
33
33
  exit_now!(I18n.t("required"), 1) if vin.nil?
34
34
 
35
- puts Vindetta::Decoder.vin(vin).to_json
35
+ puts Vindetta::Decoder.vin(vin)
36
36
  end
37
37
  end
38
38
 
@@ -197,7 +197,8 @@ wmi:
197
197
  VF6: Renault (Trucks & Buses)
198
198
  VF7: Citroën
199
199
  VF8: Matra
200
- VF9/795: Bugatti
200
+ VF9: Bugatti
201
+ 795: Bugatti
201
202
  VG5: MBK (motorcycles)
202
203
  VLU: Scania France
203
204
  VN1: SOVAB (France)
@@ -251,7 +252,8 @@ wmi:
251
252
  XLB: Volvo (NedCar)
252
253
  XLE: Scania Netherlands
253
254
  XLR: DAF (trucks)
254
- XL9/363: Spyker
255
+ XL9: Spyker
256
+ 363: Spyker
255
257
  XMC: Mitsubishi (NedCar)
256
258
  XTA: Lada/AvtoVAZ (Russia)
257
259
  XTC: KAMAZ (Russia)
@@ -277,8 +279,10 @@ wmi:
277
279
  YS3: Saab
278
280
  YS4: Scania Bus
279
281
  YTN: Saab NEVS
280
- YT9/007: Koenigsegg
281
- YT9/034: Carvia
282
+ YT9: Koenigsegg
283
+ 007: Koenigsegg
284
+ YT9: Carvia
285
+ 034: Carvia
282
286
  YU7: Husaberg (motorcycles)
283
287
  YV1: Volvo Cars
284
288
  YV4: Volvo Cars
@@ -1,46 +1,12 @@
1
- require "vindetta/decoder/result"
2
- require "net/http"
3
- require "json"
4
-
5
1
  module Vindetta
6
2
  class Decoder
7
- CHECK_DIGIT_INDEX = 8
8
-
9
3
  def self.vin(vin)
10
- Result.new(Api.decode(vin)["Results"])
11
- end
12
-
13
- def self.plant_code(vin)
14
- vin[10]
15
- end
16
-
17
- def self.check_digit(vin)
18
- vin[CHECK_DIGIT_INDEX]
19
- end
20
-
21
- def self.wmi(vin)
22
- vin[0..2]
23
- end
24
-
25
- def self.vds(vin, options = {})
26
- defaults = { check_digit: true }
27
- options = defaults.merge(options)
28
-
29
- vin[3..CHECK_DIGIT_INDEX].tap do |vds|
30
- vds.chop! unless options[:check_digit]
31
- end
32
- end
33
-
34
- def self.year(vin)
35
- vin(vin).year
36
- end
37
-
38
- def self.vis(vin)
39
- vin[9..16]
40
- end
41
-
42
- def self.production_number(vin)
43
- vin[11..16]
4
+ {
5
+ :plant_code => vin[PLANT_CODE_INDEX],
6
+ :wmi => vin[WMI_RANGE],
7
+ :check_digit => vin[CHECK_DIGIT_INDEX],
8
+ :production_number => vin[PRODUCTION_NUMBER_RANGE]
9
+ }
44
10
  end
45
11
  end
46
12
  end
@@ -1,33 +1,29 @@
1
1
  module Vindetta
2
2
  class Generator
3
- WMI_CHARACTERS = "0123456789ABCDEFGHJKLMNPRSTUVWXYZ".chars
4
- VDS_CHARACTERS = "0123456789ABCDEFGHJKLMNPRSTUVWXYZ".chars
5
- VIS_CHARACTERS = "0123456789ABCDEFGHJKLMNPRSTUVWXYZ".chars
6
-
7
3
  def self.vin(options = {})
8
4
  "#{wmi}#{vds}#{vis}".tap do |vin|
9
- vin[8] = Calculator.check_digit(vin)
5
+ vin[CHECK_DIGIT_INDEX] = Calculator.check_digit(vin)
10
6
  end
11
7
  end
12
8
 
13
9
  def self.wmi(_options = {})
14
- WMI_CHARACTERS.sample(3).join("")
10
+ @wmis ||= begin
11
+ path = File.expand_path("../data/wmi.yaml", __FILE__)
12
+ YAML.load_file(path)["wmi"].keys
13
+ end
14
+
15
+ @wmis.sample.rjust(WMI_LENGTH, "9")
15
16
  end
16
17
 
17
18
  def self.vds(_options = {})
18
- VDS_CHARACTERS.sample(6).join("")
19
+ VDS_CHARACTERS.sample(VDS_LENGTH).join("")
19
20
  end
20
21
 
21
- ##
22
- # One consistent element of the VIS is the 10th digit,
23
- # which is required worldwide to encode the model year of
24
- # the vehicle. Besides the three letters that are not
25
- # allowed in the VIN itself (I, O and Q), the letters U
26
- # and Z and the digit 0 are not used for the model year
27
- # code. The year code is the model year for the vehicle.
28
- #
29
22
  def self.vis(_options = {})
30
- VIS_CHARACTERS.sample(8).join("")
23
+ [
24
+ VIS_CHARACTERS.sample(VIS_LENGTH - 1),
25
+ MODEL_YEAR_CHARACTERS.sample
26
+ ].flatten.join("")
31
27
  end
32
28
  end
33
29
  end
@@ -3,11 +3,13 @@ module Vindetta
3
3
  def self.vin(vin)
4
4
  return false unless vin.length == Vindetta::VIN_LENGTH
5
5
 
6
- Calculator.check_digit(vin) == Decoder.check_digit(vin)
6
+ Calculator.check_digit(vin) == Decoder.vin(vin)[:check_digit]
7
7
  end
8
8
 
9
9
  def self.wmi(wmi)
10
10
  return false unless wmi.length == Vindetta::WMI_LENGTH
11
+
12
+ true
11
13
  end
12
14
 
13
15
  def self.vds(vds)
@@ -1,3 +1,3 @@
1
1
  module Vindetta
2
- VERSION = "0.19.0".freeze
2
+ VERSION = "0.20.0".freeze
3
3
  end
data/lib/vindetta.rb CHANGED
@@ -1,11 +1,8 @@
1
+ require "vindetta/calculator"
1
2
  require "vindetta/cli"
2
- require "vindetta/errors"
3
+ require "vindetta/decoder"
3
4
  require "vindetta/generator"
4
- require "vindetta/transliterator"
5
5
  require "vindetta/validator"
6
- require "vindetta/api"
7
- require "vindetta/decoder"
8
- require "vindetta/calculator"
9
6
  require "vindetta/version"
10
7
 
11
8
  module Vindetta
@@ -13,4 +10,17 @@ module Vindetta
13
10
  WMI_LENGTH = 3
14
11
  VDS_LENGTH = 6
15
12
  VIS_LENGTH = 8
13
+
14
+ CHECK_DIGIT_INDEX = 8
15
+ PLANT_CODE_INDEX = 10
16
+
17
+ WMI_CHARACTERS = "0123456789ABCDEFGHJKLMNPRSTUVWXYZ".chars
18
+ VDS_CHARACTERS = "0123456789ABCDEFGHJKLMNPRSTUVWXYZ".chars
19
+ VIS_CHARACTERS = "0123456789ABCDEFGHJKLMNPRSTUVWXYZ".chars
20
+ MODEL_YEAR_CHARACTERS = VIS_CHARACTERS - "UZ".chars
21
+
22
+ WMI_RANGE = 0..2
23
+ VDS_RANGE = 3..CHECK_DIGIT_INDEX
24
+ PRODUCTION_NUMBER_RANGE = 11..16
25
+ VIS_RANGE = 9..16
16
26
  end
data/vindetta.gemspec CHANGED
@@ -24,12 +24,10 @@ Gem::Specification.new do |spec|
24
24
  spec.add_dependency "i18n", "~> 0.9.1"
25
25
 
26
26
  spec.add_development_dependency "bundler", "~> 1.14"
27
- spec.add_development_dependency "factory_bot", "~> 4.8.2"
28
27
  spec.add_development_dependency "guard-rspec", "~> 4.7.3"
28
+ spec.add_development_dependency "pry", "~> 0.11.3"
29
29
  spec.add_development_dependency "rake", "~> 12.3.0"
30
30
  spec.add_development_dependency "rspec", "~> 3.0"
31
31
  spec.add_development_dependency "rubocop", "~> 0.49"
32
32
  spec.add_development_dependency "simplecov", "~> 0.15.1"
33
- spec.add_development_dependency "vcr", "~> 4.0.0"
34
- spec.add_development_dependency "webmock", "~> 3.1.1"
35
33
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vindetta
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.19.0
4
+ version: 0.20.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kyle Decot
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-01-13 00:00:00.000000000 Z
11
+ date: 2018-01-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gli
@@ -53,33 +53,33 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.14'
55
55
  - !ruby/object:Gem::Dependency
56
- name: factory_bot
56
+ name: guard-rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 4.8.2
61
+ version: 4.7.3
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 4.8.2
68
+ version: 4.7.3
69
69
  - !ruby/object:Gem::Dependency
70
- name: guard-rspec
70
+ name: pry
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 4.7.3
75
+ version: 0.11.3
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 4.7.3
82
+ version: 0.11.3
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rake
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -136,34 +136,6 @@ dependencies:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
138
  version: 0.15.1
139
- - !ruby/object:Gem::Dependency
140
- name: vcr
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - "~>"
144
- - !ruby/object:Gem::Version
145
- version: 4.0.0
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - "~>"
151
- - !ruby/object:Gem::Version
152
- version: 4.0.0
153
- - !ruby/object:Gem::Dependency
154
- name: webmock
155
- requirement: !ruby/object:Gem::Requirement
156
- requirements:
157
- - - "~>"
158
- - !ruby/object:Gem::Version
159
- version: 3.1.1
160
- type: :development
161
- prerelease: false
162
- version_requirements: !ruby/object:Gem::Requirement
163
- requirements:
164
- - - "~>"
165
- - !ruby/object:Gem::Version
166
- version: 3.1.1
167
139
  description: Ruby gem for generating VINs
168
140
  email:
169
141
  - kyle@joinroot.com
@@ -185,23 +157,15 @@ files:
185
157
  - bin/setup
186
158
  - exe/vindetta
187
159
  - lib/vindetta.rb
188
- - lib/vindetta/api.rb
189
160
  - lib/vindetta/calculator.rb
190
161
  - lib/vindetta/cli.rb
191
162
  - lib/vindetta/data/vis.yaml
192
163
  - lib/vindetta/data/wmi.yaml
193
164
  - lib/vindetta/decoder.rb
194
- - lib/vindetta/decoder/dsl.rb
195
- - lib/vindetta/decoder/result.rb
196
- - lib/vindetta/errors.rb
197
165
  - lib/vindetta/generator.rb
198
166
  - lib/vindetta/locale/en.yml
199
- - lib/vindetta/transliterator.rb
200
167
  - lib/vindetta/validator.rb
201
168
  - lib/vindetta/version.rb
202
- - lib/vindetta/vin/vds.rb
203
- - lib/vindetta/vin/vis.rb
204
- - lib/vindetta/vin/wmi.rb
205
169
  - vindetta.gemspec
206
170
  homepage: https://github.com/kyledecot/vindetta
207
171
  licenses:
data/lib/vindetta/api.rb DELETED
@@ -1,24 +0,0 @@
1
- require "net/http"
2
- require "json"
3
-
4
- module Vindetta
5
- class Api
6
- def self.decode(vin)
7
- uri = URI("https://vpic.nhtsa.dot.gov/api/vehicles/decodevin/#{vin}?format=json")
8
-
9
- http = Net::HTTP.new(uri.host, uri.port)
10
- http.use_ssl = true
11
-
12
- request = Net::HTTP::Get.new(uri.request_uri)
13
- response = http.request(request)
14
-
15
- parse(http.request(request))
16
- end
17
-
18
- private
19
-
20
- def self.parse(response)
21
- JSON.parse(response.body)
22
- end
23
- end
24
- end
@@ -1,34 +0,0 @@
1
- module Vindetta
2
- class Decoder
3
- module DSL
4
- def decoded_attributes
5
- @decoded_attributes ||= []
6
- end
7
-
8
- def has_value(name, variable_id, options = {})
9
- decoded_attributes << name
10
-
11
- define_method name do
12
- value = value_for(variable_id)
13
-
14
- case options[:type]
15
- when :int then value&.to_i
16
- else
17
- value
18
- end
19
- end
20
- end
21
-
22
- def self.extended(mod)
23
- mod.instance_eval do
24
- define_method :value_for do |variable_id|
25
- result = @variables.find { |r| r["VariableId"] == variable_id }
26
- return unless result
27
-
28
- result["Value"]
29
- end
30
- end
31
- end
32
- end
33
- end
34
- end
@@ -1,38 +0,0 @@
1
- require "vindetta/decoder/dsl"
2
-
3
- module Vindetta
4
- class Decoder
5
- class Result
6
- extend Vindetta::Decoder::DSL
7
-
8
- has_value :make, 26
9
- has_value :model, 28
10
- has_value :year, 29, type: :int
11
- has_value :number_of_doors, 14, type: :int
12
- has_value :number_of_windows, 40, type: :int
13
- has_value :seat_belts_type, 79
14
- has_value :manufacturer_name, 27
15
- has_value :vehicle_type, 39
16
- has_value :plant_city, 31
17
- has_value :body_class, 5
18
- has_value :primary_fuel_type, 24
19
- has_value :engine_configuration, 64
20
- has_value :manufacturer_id, 157, type: :int
21
- has_value :primary_fuel_type, 24
22
-
23
- def initialize(variables)
24
- @variables = variables
25
- end
26
-
27
- def inspect
28
- "#<Vindetta::Decoder::Response:#{format('0x00%x', (object_id << 1))}>"
29
- end
30
-
31
- def to_json
32
- self.class.decoded_attributes.map do |a|
33
- [a, send(a)]
34
- end.to_h
35
- end
36
- end
37
- end
38
- end
@@ -1,7 +0,0 @@
1
- module Vindetta
2
- class InvalidCharacter < StandardError
3
- end
4
-
5
- class InvalidVin < StandardError
6
- end
7
- end
@@ -1,17 +0,0 @@
1
- module Vindetta
2
- class Transliterator
3
- MAPPING = "0123456789.ABCDEFGH..JKLMN.P.R..STUVWXYZ".chars
4
-
5
- def self.vin(vin)
6
- vin.chars.map do |c|
7
- index = MAPPING.find_index(c)
8
- raise Vindetta::InvalidCharacter, c unless index
9
- index % 10
10
- end
11
- end
12
-
13
- def self.run(character)
14
- vin(character.to_s)[0]
15
- end
16
- end
17
- end
@@ -1,21 +0,0 @@
1
- module Vindetta
2
- class Vin
3
- class Vds
4
- attr_reader :value
5
-
6
- def initialize(vin)
7
- @vin = vin
8
- end
9
-
10
- def value
11
- @vin[3..7].join("")
12
- end
13
-
14
- alias eql? ==
15
-
16
- def ==(other)
17
- self.class == other.class && value == other.value
18
- end
19
- end
20
- end
21
- end
@@ -1,47 +0,0 @@
1
- module Vindetta
2
- class Vin
3
- class Vis
4
- DATA_PATH = File.expand_path("../../data/vis.yaml", __FILE__)
5
-
6
- attr_reader :value
7
-
8
- def initialize(vin)
9
- @vin = vin
10
- end
11
-
12
- alias eql? ==
13
-
14
- def ==(other)
15
- self.class == other.class && value == other.value
16
- end
17
-
18
- def seventh
19
- @vin[6]
20
- end
21
-
22
- def value
23
- @vin[9..16].join("")
24
- end
25
-
26
- def year
27
- @year ||= begin
28
- years = self.class.data.dig("year", value[0])
29
-
30
- # TODO: Replace this w/ a constant of alpha characters and check against that
31
- begin
32
- Integer(seventh)
33
- years[0]
34
- rescue ArgumentError
35
- years[1]
36
- end
37
- end
38
- end
39
-
40
- private
41
-
42
- def self.data
43
- @data ||= YAML.load_file(DATA_PATH).stringify_keys
44
- end
45
- end
46
- end
47
- end
@@ -1,39 +0,0 @@
1
- module Vindetta
2
- class Vin
3
- class Wmi
4
- DATA_PATH = File.expand_path("../../data/wmi.yaml", __FILE__)
5
-
6
- def initialize(vin)
7
- @vin = vin
8
- end
9
-
10
- def name
11
- @name ||= self.class.data["wmi"][value]
12
- end
13
-
14
- alias eql? ==
15
-
16
- def value
17
- @vin[0..2].join("")
18
- end
19
-
20
- def region
21
- @name ||= begin
22
- regions = self.class.data["region"] # TODO: Pull this out into private method
23
-
24
- regions.detect do |key, characters_for_region|
25
- break key if characters_for_region.include?(value[0])
26
- end
27
- end
28
- end
29
-
30
- def ==(other)
31
- self.class == other.class && value == other.value
32
- end
33
-
34
- def self.data
35
- @data ||= YAML.load_file(DATA_PATH)
36
- end
37
- end
38
- end
39
- end