fitment 0.1.0.1 → 0.1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +40 -0
- data/VERSION +1 -1
- data/examples/audi_s3.rb +11 -15
- data/examples/combos.rb +14 -0
- data/fitment.gemspec +1 -1
- data/lib/fitment/combo.rb +22 -11
- data/lib/fitment/parse.rb +96 -0
- data/lib/fitment/tire.rb +11 -19
- data/lib/fitment/wheel.rb +23 -28
- data/lib/fitment.rb +1 -1
- data/test/combo.rb +7 -7
- data/test/fitment.rb +1 -1
- data/test/parse.rb +103 -0
- data/test/tire.rb +2 -2
- data/test/wheel.rb +7 -27
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a839b9fe254226fc0aadebd2a4a14e0e111e7c00066dd332903e89fdaaf77422
|
4
|
+
data.tar.gz: 611b7d3d301a026dfdd7762e71a0596da3f050a4e399e429d9f57c294f9466f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 27bb27f5f2a4ba17961ca53b675b0ed7d52b28cd6d086f7ee05de8b16960cf7388d59ffeab55194785f2bde49c49499b9f9a08981723363dfcde086a144b842d
|
7
|
+
data.tar.gz: 3b98c146caae886574228774fe6c6051351e6ecb4a26b8625cd81e93f7e3973a4cc00d488844b073da9d1c07d69737473d918ffbfcc023bcc3ca427b03dd799d
|
data/README.md
CHANGED
@@ -0,0 +1,40 @@
|
|
1
|
+
[![CI Status](https://github.com/rickhull/fitment/actions/workflows/ci.yaml/badge.svg)](https://github.com/rickhull/fitment/actions/workflows/ci.yaml)
|
2
|
+
[![Gem Version](https://badge.fury.io/rb/fitment.svg)](http://badge.fury.io/rb/fitment)
|
3
|
+
|
4
|
+
# Fitment
|
5
|
+
|
6
|
+
This is a library and utility for analyzing and comparing common wheel and
|
7
|
+
tire sizes for passenger cars, across most of the globe, but primarily
|
8
|
+
considering North America, Europe, Japan, and Korea. Its validity may extend
|
9
|
+
somewhat towards passenger trucks and other sorts of utility vehicles.
|
10
|
+
|
11
|
+
## Wheels
|
12
|
+
|
13
|
+
Wheel diameters are expected to mostly conform to whole inch measurements.
|
14
|
+
Half-inch measurements are acceptable but expected to be rare. **This library
|
15
|
+
*does not* expect wheel diameters measured in metric units.**
|
16
|
+
|
17
|
+
Wheel widths are expected in half-inch increments, measured in inches.
|
18
|
+
Expect limited support for wheel widths below 4 inches or above 16 inches.
|
19
|
+
|
20
|
+
The location of the hub interface, measured via either "ET" or "offset" is
|
21
|
+
also required. "ET" is the most common standard for passenger cars, though
|
22
|
+
(particularly American) truck wheels and other rear wheel drive platform
|
23
|
+
wheels may come specified with an "offset" rather than "ET".
|
24
|
+
|
25
|
+
### ET
|
26
|
+
|
27
|
+
*ET* is measured in millimeters from the centerline of the wheel, and may be
|
28
|
+
positive or negative. +55 to -55 is common, with positive ETs associated with
|
29
|
+
FWD cars (hub towards the outside of the wheel) and negative ETs associated
|
30
|
+
with RWD cars (hub towards the inside of the wheel).
|
31
|
+
|
32
|
+
### Offset
|
33
|
+
|
34
|
+
*Offset* is measured in inches from the outside of the wheel, and is nearly
|
35
|
+
always positive, though it may be negative, meaning the hub interface extends
|
36
|
+
outside beyond the rim.
|
37
|
+
|
38
|
+
## Tires
|
39
|
+
|
40
|
+
TBD
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.1.1
|
data/examples/audi_s3.rb
CHANGED
@@ -2,21 +2,17 @@ require 'fitment/combo'
|
|
2
2
|
|
3
3
|
FC = Fitment::Combo
|
4
4
|
|
5
|
-
stock18 = FC.new_with_params(225, 40, 18, 8, 46)
|
6
|
-
stock19 = FC.new_with_params(235, 35, 19, 8, 49)
|
7
|
-
after18 = FC.new_with_params(245, 40, 18, 8, 45)
|
8
|
-
after19 = FC.new_with_params(245, 35, 19, 8, 49)
|
5
|
+
stock18 = FC.new_with_params(225, 40, 18, 8, et: 46)
|
6
|
+
stock19 = FC.new_with_params(235, 35, 19, 8, et: 49)
|
7
|
+
after18 = FC.new_with_params(245, 40, 18, 8, et: 45)
|
8
|
+
after19 = FC.new_with_params(245, 35, 19, 8, et: 49)
|
9
9
|
|
10
|
-
puts
|
11
|
-
|
12
|
-
|
13
|
-
puts
|
14
|
-
puts [after19, stock19.increase(after19).inspect].join(' ')
|
10
|
+
puts [stock19.report(after18),
|
11
|
+
stock19.report(after19)].join("\n\n")
|
12
|
+
|
13
|
+
puts "\n----------"
|
15
14
|
puts
|
16
15
|
|
17
|
-
puts
|
18
|
-
|
19
|
-
|
20
|
-
puts [after18, stock18.increase(after18).inspect].join(' ')
|
21
|
-
puts [stock19, stock18.increase(stock19).inspect].join(' ')
|
22
|
-
puts [after19, stock18.increase(after19).inspect].join(' ')
|
16
|
+
puts [stock18.report(after18),
|
17
|
+
stock18.report(stock19),
|
18
|
+
stock18.report(after19)].join("\n\n")
|
data/examples/combos.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'fitment/combo'
|
2
|
+
require 'fitment/parse'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
YAML.load_file('examples/combos.yaml').each { |name, combos|
|
6
|
+
puts name
|
7
|
+
puts '-' * 8
|
8
|
+
|
9
|
+
combos.each { |hsh|
|
10
|
+
puts "%s %s" % [Fitment::Parse.tire(hsh.fetch "tire"),
|
11
|
+
Fitment::Parse.wheel(hsh.fetch "wheel")]
|
12
|
+
}
|
13
|
+
puts
|
14
|
+
}
|
data/fitment.gemspec
CHANGED
data/lib/fitment/combo.rb
CHANGED
@@ -2,7 +2,6 @@ require 'fitment'
|
|
2
2
|
|
3
3
|
Fitment.autoload :Tire, 'fitment/tire'
|
4
4
|
Fitment.autoload :Wheel, 'fitment/wheel'
|
5
|
-
Fitment.autoload :OffsetWheel, 'fitment/wheel'
|
6
5
|
|
7
6
|
module Fitment
|
8
7
|
class Combo
|
@@ -112,19 +111,13 @@ module Fitment
|
|
112
111
|
end
|
113
112
|
end
|
114
113
|
|
115
|
-
def self.new_with_params(tread_with, ratio, diameter, width,
|
116
|
-
et:
|
114
|
+
def self.new_with_params(tread_with, ratio, diameter, width,
|
115
|
+
et: nil, offset: nil)
|
117
116
|
tire = Tire.new(tread_with, ratio, diameter)
|
118
|
-
wheel = et
|
119
|
-
Wheel.new(diameter, width, offset) :
|
120
|
-
OffsetWheel.new(diameter, width, offset)
|
117
|
+
wheel = Wheel.new(diameter, width, et: et, offset: offset)
|
121
118
|
Combo.new(wheel: wheel, tire: tire)
|
122
119
|
end
|
123
120
|
|
124
|
-
def self.new_with_offset(t, r, d, w, o)
|
125
|
-
self.new_with_params(t, r, d, w, o, et: false)
|
126
|
-
end
|
127
|
-
|
128
121
|
TIRE_EXCESS = 15 # extra rubber material near the bead relevant to fitment
|
129
122
|
|
130
123
|
attr_accessor :tire, :wheel, :model
|
@@ -153,7 +146,7 @@ module Fitment
|
|
153
146
|
if @tire.width < min
|
154
147
|
raise(MinError, msg % [@tire.width, '<', 'min', min, @wheel.width])
|
155
148
|
end
|
156
|
-
if max45 and @tire.ratio <= 45 and @tire.width > max45
|
149
|
+
if max45 and @tire.ratio <= 0.45 and @tire.width > max45
|
157
150
|
raise(Max45Error, msg % [@tire.width, '>', 'max45', max45, @wheel.width])
|
158
151
|
end
|
159
152
|
raise(MaxError, "no max available for width %i" % @wheel.width) if !max
|
@@ -223,5 +216,23 @@ module Fitment
|
|
223
216
|
tire: tire.map { |flt| flt.round(2) }, }
|
224
217
|
end
|
225
218
|
alias_method(:clearance, :increase)
|
219
|
+
|
220
|
+
def report(other)
|
221
|
+
increase = self.increase other
|
222
|
+
wheel = increase.fetch :wheel
|
223
|
+
tire = increase.fetch :tire
|
224
|
+
|
225
|
+
rpt = []
|
226
|
+
rpt << "Wheel: %s > %s" % [@wheel, other.wheel]
|
227
|
+
rpt << " Inside extension: %.1f mm" % wheel[0]
|
228
|
+
rpt << " Outside extension: %.1f mm" % wheel[1]
|
229
|
+
rpt << " Diameter extension: %.1f mm" % wheel[2]
|
230
|
+
rpt << "Tire: %s > %s" % [@tire, other.tire]
|
231
|
+
rpt << " Inside extension: %.1f mm" % tire[0]
|
232
|
+
rpt << " Outside extension: %.1f mm" % tire[1]
|
233
|
+
rpt << " Diameter extension: %.1f mm" % tire[2]
|
234
|
+
|
235
|
+
rpt.join "\n"
|
236
|
+
end
|
226
237
|
end
|
227
238
|
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'fitment'
|
2
|
+
|
3
|
+
Fitment.autoload(:Tire, 'fitment/tire')
|
4
|
+
Fitment.autoload(:Wheel, 'fitment/wheel')
|
5
|
+
|
6
|
+
module Fitment
|
7
|
+
module Parse
|
8
|
+
class InputError < RuntimeError; end
|
9
|
+
class DiameterError < InputError; end
|
10
|
+
class WidthError < InputError; end
|
11
|
+
class OffsetError < InputError; end
|
12
|
+
class ETError < InputError; end
|
13
|
+
class RatioError < InputError; end
|
14
|
+
|
15
|
+
MAX_INPUT = 32
|
16
|
+
|
17
|
+
def self.wheel(str)
|
18
|
+
raise(InputError, "str.length > #{MAX_INPUT}") if str.length > MAX_INPUT
|
19
|
+
# diameter and width: int or float.0 or float.5
|
20
|
+
dim_rgx = /\A[1-3]?[0-9](?:\.[05])?\z/
|
21
|
+
# offset: +- int or float.0 or float.5
|
22
|
+
offset_rgx = /\A[+-]?[1-9]?[0-9](?:\.[05])?\z/
|
23
|
+
# et: +- int
|
24
|
+
et_rgx = /\A[+-]?[1-9]?[0-9]\z/
|
25
|
+
|
26
|
+
# use split(str, -1) to detect multiple uses of keywords
|
27
|
+
parts = str.strip.downcase.split('x', -1).map(&:strip)
|
28
|
+
if parts.size != 2
|
29
|
+
raise(InputError, "unexpected split on x: #{str} #{parts.inspect}")
|
30
|
+
end
|
31
|
+
|
32
|
+
d, rest = *parts
|
33
|
+
raise(DiameterError, d) unless d.match dim_rgx
|
34
|
+
|
35
|
+
# check for offset first
|
36
|
+
parts = rest.split('offset', -1).map(&:strip)
|
37
|
+
case parts.size
|
38
|
+
when 2
|
39
|
+
# found offset
|
40
|
+
raise(WidthError, parts[0]) unless parts[0].match dim_rgx
|
41
|
+
raise(OffsetError, parts[1]) unless parts[1].match offset_rgx
|
42
|
+
Wheel.new(d, parts[0], offset: parts[1])
|
43
|
+
when 1
|
44
|
+
# check for et
|
45
|
+
parts = rest.split('et', -1).map(&:strip)
|
46
|
+
case parts.size
|
47
|
+
when 2
|
48
|
+
raise(WidthError, parts[0]) unless parts[0].match dim_rgx
|
49
|
+
raise(ETError, parts[1]) unless parts[1].match et_rgx
|
50
|
+
Wheel.new(d, parts[0], et: parts[1])
|
51
|
+
when 1
|
52
|
+
# no et or offset, just width
|
53
|
+
raise(WidthError, rest) unless rest.match dim_rgx
|
54
|
+
Wheel.new(d, rest)
|
55
|
+
else
|
56
|
+
# hmmm, multiple ets?
|
57
|
+
raise(ETError, [rest, parts.inspect].join("\t"))
|
58
|
+
end
|
59
|
+
else
|
60
|
+
# hmmm, multiple offsets?
|
61
|
+
raise(OffsetError, [rest, parts.inspect].join("\t"))
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.tire(str)
|
66
|
+
raise(InputError, "str.length > #{MAX_INPUT}") if str.length > MAX_INPUT
|
67
|
+
# width: 105-495
|
68
|
+
width_rgx = /\A[1-4][0-9]5\z/
|
69
|
+
|
70
|
+
# aspect ratio: 10-95%
|
71
|
+
ratio_rgx = /\A[1-9][05]\z/
|
72
|
+
|
73
|
+
# diameter: int or float.0 or float.5
|
74
|
+
dia_rgx = /\A[1-3]?[0-9](?:\.[05])?\z/
|
75
|
+
|
76
|
+
# use split(str, -1) to detect multiple uses of keywords
|
77
|
+
parts = str.strip.downcase.split('/', -1).map(&:strip)
|
78
|
+
if parts.size != 2
|
79
|
+
raise(InputError, "unexpected split on /: #{str} #{parts.inspect}")
|
80
|
+
end
|
81
|
+
|
82
|
+
w, rest = *parts
|
83
|
+
raise(WidthError, w) unless w.match width_rgx
|
84
|
+
|
85
|
+
# split on R
|
86
|
+
parts = rest.split('r', -1).map(&:strip)
|
87
|
+
if parts.size != 2
|
88
|
+
raise(InputError, "unexpected split on r: #{rest} #{parts.inspect}")
|
89
|
+
end
|
90
|
+
|
91
|
+
raise(RatioError, parts[0]) unless parts[0].match ratio_rgx
|
92
|
+
raise(DiameterError, parts[1]) unless parts[1].match dia_rgx
|
93
|
+
Tire.new(w, parts[0].to_i, parts[1])
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
data/lib/fitment/tire.rb
CHANGED
@@ -6,10 +6,6 @@ module Fitment
|
|
6
6
|
(ratio_flt * 100.0 / 5).round * 5
|
7
7
|
end
|
8
8
|
|
9
|
-
def self.ratio_flt(ratio_int)
|
10
|
-
ratio_int / 100.0
|
11
|
-
end
|
12
|
-
|
13
9
|
# mm
|
14
10
|
def self.sidewall_height(width_mm, ratio_flt)
|
15
11
|
width_mm * ratio_flt
|
@@ -17,54 +13,50 @@ module Fitment
|
|
17
13
|
|
18
14
|
# inches
|
19
15
|
def self.overall_diameter(width_mm, ratio_flt, wheel_in)
|
20
|
-
2 * Fitment.
|
16
|
+
2 * Fitment.inches(sidewall_height(width_mm, ratio_flt)) + wheel_in
|
21
17
|
end
|
22
18
|
|
23
19
|
# the aspect ratio is stored as an integer for easy assignment and
|
24
20
|
# comparison, and converted to a float for calculations
|
25
|
-
attr_reader :width, :ratio, :wheel_diameter
|
21
|
+
attr_reader :width, :ratio, :wheel_diameter, :series
|
26
22
|
|
27
23
|
def initialize(width_mm, ratio, wheel_in)
|
28
24
|
@width = width_mm
|
29
25
|
if ratio < 0.99 and ratio > 0.1
|
30
|
-
@
|
26
|
+
@series = self.class.ratio_int(ratio)
|
31
27
|
elsif ratio.is_a? Integer and ratio%5 == 0 and ratio > 10 and ratio < 99
|
32
|
-
@
|
28
|
+
@series = ratio
|
33
29
|
else
|
34
30
|
raise("unexpected ratio: #{ratio}")
|
35
31
|
end
|
32
|
+
@ratio = Rational(@series, 100)
|
36
33
|
@wheel_diameter = wheel_in
|
37
34
|
end
|
38
35
|
|
39
36
|
def to_s
|
40
|
-
[[@width, @
|
41
|
-
end
|
42
|
-
|
43
|
-
def ratio_flt
|
44
|
-
self.class.ratio_flt(@ratio)
|
37
|
+
[[@width, @series].join('/'), @wheel_diameter].join('R')
|
45
38
|
end
|
46
39
|
|
47
40
|
# sidewall height, (mm) and in
|
48
41
|
def sh_mm
|
49
|
-
self.class.sidewall_height(@width,
|
42
|
+
self.class.sidewall_height(@width, @ratio).round(1)
|
50
43
|
end
|
51
44
|
alias_method :sidewall_height, :sh_mm
|
52
45
|
|
53
46
|
def sh_in
|
54
|
-
Fitment.
|
47
|
+
Fitment.inches(sh_mm).round(2)
|
55
48
|
end
|
56
49
|
|
57
50
|
# overall diameter, mm and (in)
|
58
51
|
def od_in
|
59
|
-
self.class.overall_diameter(@width,
|
52
|
+
self.class.overall_diameter(@width, @ratio, @wheel_diameter).round(2)
|
60
53
|
end
|
61
54
|
alias_method :overall_diameter, :od_in
|
62
55
|
|
63
|
-
alias_method(:series, :ratio)
|
64
|
-
alias_method(:aspect_ratio, :ratio)
|
65
|
-
|
66
56
|
def od_mm
|
67
57
|
Fitment.mm(od_in).round(1)
|
68
58
|
end
|
59
|
+
|
60
|
+
alias_method(:aspect_ratio, :ratio)
|
69
61
|
end
|
70
62
|
end
|
data/lib/fitment/wheel.rb
CHANGED
@@ -7,44 +7,39 @@ module Fitment
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def self.offset(et_mm, width_in)
|
10
|
-
(width_in / 2 - Fitment.
|
10
|
+
(width_in / 2 - Fitment.inches(et_mm)).round(2)
|
11
11
|
end
|
12
12
|
|
13
|
-
attr_reader :diameter, :width, :et
|
14
|
-
attr_accessor :bolt_pattern
|
13
|
+
attr_reader :diameter, :width, :et, :offset
|
15
14
|
|
16
|
-
def initialize(diameter_in, width_in, et
|
17
|
-
@diameter = diameter_in
|
18
|
-
@width = width_in
|
19
|
-
|
20
|
-
|
15
|
+
def initialize(diameter_in, width_in, et: 0, offset: nil)
|
16
|
+
@diameter = Rational(diameter_in)
|
17
|
+
@width = Rational(width_in)
|
18
|
+
if offset
|
19
|
+
@et = nil
|
20
|
+
@offset = Rational(offset)
|
21
|
+
else
|
22
|
+
@offset = nil
|
23
|
+
@et = et.to_i
|
24
|
+
end
|
21
25
|
end
|
22
26
|
|
23
|
-
def
|
24
|
-
|
27
|
+
def et!
|
28
|
+
@et or self.class.et(@offset, @width)
|
25
29
|
end
|
26
30
|
|
27
|
-
def offset
|
28
|
-
self.class.offset(@et, @width)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
class OffsetWheel < Wheel
|
33
|
-
attr_reader :offset
|
34
|
-
|
35
|
-
def initialize(diameter_in, width_in, offset_in, bolt_pattern: "")
|
36
|
-
@diameter = diameter_in
|
37
|
-
@width = width_in
|
38
|
-
@offset = offset_in
|
39
|
-
@bolt_pattern = bolt_pattern
|
31
|
+
def offset!
|
32
|
+
@offset or self.class.offset(@et, @width)
|
40
33
|
end
|
41
34
|
|
42
35
|
def to_s
|
43
|
-
"
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
36
|
+
ary = ["%gx%g" % [@diameter, @width]]
|
37
|
+
if @offset
|
38
|
+
ary << "offset:%g" % @offset
|
39
|
+
else
|
40
|
+
ary << "et:%i" % @et
|
41
|
+
end
|
42
|
+
ary.join(' ')
|
48
43
|
end
|
49
44
|
end
|
50
45
|
end
|
data/lib/fitment.rb
CHANGED
data/test/combo.rb
CHANGED
@@ -66,11 +66,11 @@ describe Combo do
|
|
66
66
|
|
67
67
|
describe "real world combo examples" do
|
68
68
|
before do
|
69
|
-
@stock18 = Combo.new_with_params(225, 40, 18, 8, 46)
|
70
|
-
@stock19 = Combo.new_with_params(235, 35, 19, 8, 49)
|
69
|
+
@stock18 = Combo.new_with_params(225, 40, 18, 8, et: 46)
|
70
|
+
@stock19 = Combo.new_with_params(235, 35, 19, 8, et: 49)
|
71
71
|
|
72
|
-
@after18 = Combo.new_with_params(245, 40, 18, 8, 45)
|
73
|
-
@after19 = Combo.new_with_params(245, 35, 19, 8, 49)
|
72
|
+
@after18 = Combo.new_with_params(245, 40, 18, 8, et: 45)
|
73
|
+
@after19 = Combo.new_with_params(245, 35, 19, 8, et: 49)
|
74
74
|
|
75
75
|
@audi = [@stock18, @stock19, @after18, @after19]
|
76
76
|
end
|
@@ -132,16 +132,16 @@ describe Combo do
|
|
132
132
|
|
133
133
|
describe "unlikely combos" do
|
134
134
|
it "validates a truck tire" do
|
135
|
-
truck = Combo.
|
135
|
+
truck = Combo.new_with_params(275, 55, 16, 8, offset: 4)
|
136
136
|
expect(truck.validate!).must_equal true
|
137
137
|
|
138
|
-
too_wide = Combo.
|
138
|
+
too_wide = Combo.new_with_params(325, 55, 16, 8, offset: 4)
|
139
139
|
expect { too_wide.validate! }.must_raise Combo::MaxError
|
140
140
|
end
|
141
141
|
|
142
142
|
it "rejects wheel size mismatch" do
|
143
143
|
@tire19 = Tire.new(255, 35, 19)
|
144
|
-
@wheel18 = Wheel.new(18, 8, 45)
|
144
|
+
@wheel18 = Wheel.new(18, 8, et: 45)
|
145
145
|
@tire17 = Tire.new(205, 40, 17)
|
146
146
|
|
147
147
|
|
data/test/fitment.rb
CHANGED
@@ -7,7 +7,7 @@ describe Fitment do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
it "converts mm to inches and vice versa" do
|
10
|
-
expect(Fitment.
|
10
|
+
expect(Fitment.inches 25.4).must_be_within_epsilon 1.0
|
11
11
|
expect(Fitment.mm 1).must_equal 25.4
|
12
12
|
expect(Fitment.mm 12).must_equal 25.4 * 12
|
13
13
|
end
|
data/test/parse.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'fitment/parse'
|
3
|
+
require 'fitment/tire'
|
4
|
+
require 'fitment/wheel'
|
5
|
+
|
6
|
+
include Fitment
|
7
|
+
|
8
|
+
describe "Parse.tire" do
|
9
|
+
it "recognizes valid inputs" do
|
10
|
+
valid = ['225/35R18', '305 / 50 R 19', '265/70R16']
|
11
|
+
valid.each { |input| expect(Parse.tire(input)).must_be_kind_of Tire }
|
12
|
+
end
|
13
|
+
|
14
|
+
it "validates width" do
|
15
|
+
bad_w = ['220/35R18', '310 / 50 R 19', '256/50 R17']
|
16
|
+
bad_w.each { |input|
|
17
|
+
expect { Parse.tire(input) }.must_raise Parse::WidthError
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
it "validates aspect ratio" do
|
22
|
+
bad_r = ['225/37R18', '225/37 R18', '225 / 37 R 18']
|
23
|
+
bad_r.each { |input|
|
24
|
+
expect { Parse.tire(input) }.must_raise Parse::RatioError
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
it "validates diameter" do
|
29
|
+
bad_d = ['225/35 R47', '225/35R17.2']
|
30
|
+
bad_d.each { |input|
|
31
|
+
expect { Parse.tire(input) }.must_raise Parse::DiameterError
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "Parse.wheel" do
|
37
|
+
it "recognizes valid inputs" do
|
38
|
+
valid = [
|
39
|
+
'18x8',
|
40
|
+
'18 x 8',
|
41
|
+
'14.5x10.5',
|
42
|
+
'18 x 8 et 45',
|
43
|
+
'18 x 8 offset 4',
|
44
|
+
'18x8et-45',
|
45
|
+
'18 x 8 et +45',
|
46
|
+
'19 x 9.5 offset 4.5',
|
47
|
+
'18 X 8',
|
48
|
+
'18 X 8 OFFSET -8',
|
49
|
+
]
|
50
|
+
|
51
|
+
valid.each { |input| expect(Parse.wheel(input)).must_be_kind_of Wheel }
|
52
|
+
end
|
53
|
+
|
54
|
+
it "requires an X" do
|
55
|
+
has_x = ['18x8', '14.5 x 10.5', '19X9', '22.5 X 8.5 ET 27']
|
56
|
+
has_x.each { |input| expect(Parse.wheel(input)).must_be_kind_of Wheel }
|
57
|
+
no_x = ['abc defg', '18 8', '18 by 8']
|
58
|
+
no_x.each { |input|
|
59
|
+
expect { Parse.wheel(input) }.must_raise Parse::InputError
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
it "validates diameter" do
|
64
|
+
bad_d = ['99 x 5', '12.4 x 5', 'abc x defg']
|
65
|
+
bad_d.each { |input|
|
66
|
+
expect { Parse.wheel(input) }.must_raise Parse::DiameterError
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
it "validates width" do
|
71
|
+
bad_w = ['18 x 99', '18 x 8.4', '18 x abc']
|
72
|
+
bad_w.each { |input|
|
73
|
+
expect { Parse.wheel(input) }.must_raise Parse::WidthError
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
it "validates offset" do
|
78
|
+
bad_o = ['18x8 offset 123.456', '18x8 offset 1 offset 2']
|
79
|
+
bad_o.each { |input|
|
80
|
+
expect { Parse.wheel(input) }.must_raise Parse::OffsetError
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
it "validates ET" do
|
85
|
+
bad_e = ['18x8 et 123.456', '18x8 et 1 et']
|
86
|
+
bad_e.each { |input|
|
87
|
+
expect { Parse.wheel(input) }.must_raise Parse::ETError
|
88
|
+
}
|
89
|
+
end
|
90
|
+
|
91
|
+
it "rejects junk" do
|
92
|
+
junk = ['abc def',
|
93
|
+
'18 by 8',
|
94
|
+
'18x8 and stuff',
|
95
|
+
'18x8 et alot',
|
96
|
+
'x' * 1024,
|
97
|
+
'x' * 2,
|
98
|
+
'10x' * 4,]
|
99
|
+
junk.each { |input|
|
100
|
+
expect { Parse.wheel(input) }.must_raise Parse::InputError
|
101
|
+
}
|
102
|
+
end
|
103
|
+
end
|
data/test/tire.rb
CHANGED
@@ -28,14 +28,14 @@ describe T do
|
|
28
28
|
it "initializes with width, ratio, and wheel diameter" do
|
29
29
|
expect(@t).must_be_kind_of(T)
|
30
30
|
expect(@t.width).must_equal @w
|
31
|
-
expect(@t.ratio).must_equal @r
|
31
|
+
expect(@t.ratio).must_equal @r/100.0
|
32
32
|
expect(@t.wheel_diameter).must_equal @d
|
33
33
|
end
|
34
34
|
|
35
35
|
it "intializes with ratio between 0 and 1" do
|
36
36
|
t = T.new(225, 0.35, 18)
|
37
37
|
expect(t).must_be_kind_of(T)
|
38
|
-
expect(t.ratio).must_equal 35
|
38
|
+
expect(t.ratio).must_equal 35/100.0
|
39
39
|
end
|
40
40
|
|
41
41
|
it "has a sidewall height in mm and inches" do
|
data/test/wheel.rb
CHANGED
@@ -19,40 +19,20 @@ describe Wheel do
|
|
19
19
|
expect(wheel.diameter).must_equal d
|
20
20
|
expect(wheel.width).must_equal w
|
21
21
|
expect(wheel.et).must_equal 0
|
22
|
-
expect(wheel.bolt_pattern).must_equal ""
|
23
22
|
end
|
24
23
|
|
25
24
|
it "initializes with optional ET" do
|
26
25
|
d,w,et = 18,8,35
|
27
|
-
wet = Wheel.new(d, w, et)
|
26
|
+
wet = Wheel.new(d, w, et: et)
|
28
27
|
expect(wet).must_be_kind_of Wheel
|
29
28
|
expect(wet.et).must_equal et
|
30
29
|
end
|
31
30
|
|
32
|
-
it "initializes with optional
|
33
|
-
d,w,
|
34
|
-
|
35
|
-
expect(
|
36
|
-
expect(
|
37
|
-
|
38
|
-
|
39
|
-
it "allows updates to bolt_pattern" do
|
40
|
-
d,w,bp = 18,8,"5x112"
|
41
|
-
wbp = Wheel.new(d, w)
|
42
|
-
expect(wbp).must_be_kind_of Wheel
|
43
|
-
expect(wbp.bolt_pattern).must_equal ""
|
44
|
-
wbp.bolt_pattern = bp
|
45
|
-
expect(wbp.bolt_pattern).must_equal bp
|
46
|
-
end
|
47
|
-
|
48
|
-
describe OffsetWheel do
|
49
|
-
it "initializes with required offset" do
|
50
|
-
d,w,offset = 20,9,6
|
51
|
-
expect { OffsetWheel.new(d, w) }.must_raise ArgumentError
|
52
|
-
offset = 4
|
53
|
-
wof = OffsetWheel.new(d, w, offset)
|
54
|
-
expect(wof).must_be_kind_of OffsetWheel
|
55
|
-
expect(wof.offset).must_equal offset
|
56
|
-
end
|
31
|
+
it "initializes with optional offset" do
|
32
|
+
d,w,offset = 20,9,6
|
33
|
+
wof = Wheel.new(d, w, offset: offset)
|
34
|
+
expect(wof).must_be_kind_of Wheel
|
35
|
+
expect(wof.offset).must_equal offset
|
36
|
+
expect(wof.et).must_be_nil
|
57
37
|
end
|
58
38
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fitment
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rick Hull
|
@@ -20,13 +20,16 @@ files:
|
|
20
20
|
- Rakefile
|
21
21
|
- VERSION
|
22
22
|
- examples/audi_s3.rb
|
23
|
+
- examples/combos.rb
|
23
24
|
- fitment.gemspec
|
24
25
|
- lib/fitment.rb
|
25
26
|
- lib/fitment/combo.rb
|
27
|
+
- lib/fitment/parse.rb
|
26
28
|
- lib/fitment/tire.rb
|
27
29
|
- lib/fitment/wheel.rb
|
28
30
|
- test/combo.rb
|
29
31
|
- test/fitment.rb
|
32
|
+
- test/parse.rb
|
30
33
|
- test/tire.rb
|
31
34
|
- test/wheel.rb
|
32
35
|
homepage: https://github.com/rickhull/fitment
|
@@ -39,7 +42,7 @@ require_paths:
|
|
39
42
|
- lib
|
40
43
|
required_ruby_version: !ruby/object:Gem::Requirement
|
41
44
|
requirements:
|
42
|
-
- - "
|
45
|
+
- - ">"
|
43
46
|
- !ruby/object:Gem::Version
|
44
47
|
version: '2'
|
45
48
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
@@ -48,7 +51,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
48
51
|
- !ruby/object:Gem::Version
|
49
52
|
version: '0'
|
50
53
|
requirements: []
|
51
|
-
rubygems_version: 3.
|
54
|
+
rubygems_version: 3.4.4
|
52
55
|
signing_key:
|
53
56
|
specification_version: 4
|
54
57
|
summary: Simple, fast, and comprehensive wheel and tire fitment analysis
|