measured 2.3.0 → 2.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/workflows/ci.yml +31 -0
- data/CHANGELOG.md +25 -0
- data/README.md +12 -10
- data/Rakefile +22 -1
- data/cache/.keep +0 -0
- data/cache/length.json +2553 -0
- data/cache/volume.json +4163 -0
- data/cache/weight.json +3195 -0
- data/dev.yml +2 -2
- data/gemfiles/{activesupport-4.2.gemfile → activesupport-5.2.gemfile} +1 -1
- data/gemfiles/activesupport-6.0.gemfile +5 -0
- data/gemfiles/activesupport-6.1.gemfile +5 -0
- data/lib/measured.rb +1 -0
- data/lib/measured/arithmetic.rb +1 -0
- data/lib/measured/base.rb +12 -6
- data/lib/measured/cache/json.rb +49 -0
- data/lib/measured/cache/json_writer.rb +9 -0
- data/lib/measured/cache/null.rb +16 -0
- data/lib/measured/conversion_table_builder.rb +91 -0
- data/lib/measured/measurable.rb +18 -21
- data/lib/measured/missing_conversion_path.rb +12 -0
- data/lib/measured/parser.rb +1 -0
- data/lib/measured/unit.rb +16 -26
- data/lib/measured/unit_already_added.rb +11 -0
- data/lib/measured/unit_error.rb +4 -0
- data/lib/measured/unit_system.rb +26 -21
- data/lib/measured/unit_system_builder.rb +11 -4
- data/lib/measured/units/length.rb +3 -0
- data/lib/measured/units/volume.rb +4 -1
- data/lib/measured/units/weight.rb +3 -0
- data/lib/measured/version.rb +2 -1
- data/measured.gemspec +13 -5
- data/test/arithmetic_test.rb +1 -0
- data/test/cache/json_test.rb +43 -0
- data/test/cache/json_writer_test.rb +23 -0
- data/test/cache/null_test.rb +20 -0
- data/test/cache_consistency_test.rb +19 -0
- data/test/conversion_table_builder_test.rb +137 -0
- data/test/measurable_test.rb +5 -5
- data/test/parser_test.rb +1 -0
- data/test/support/always_true_cache.rb +14 -0
- data/test/support/fake_system.rb +1 -0
- data/test/support/subclasses.rb +7 -0
- data/test/test_helper.rb +5 -3
- data/test/unit_error_test.rb +1 -0
- data/test/unit_system_builder_test.rb +49 -3
- data/test/unit_system_test.rb +15 -0
- data/test/unit_test.rb +5 -0
- data/test/units/length_test.rb +5 -4
- data/test/units/volume_test.rb +6 -5
- data/test/units/weight_test.rb +1 -0
- metadata +45 -18
- data/.travis.yml +0 -17
- data/lib/measured/conversion_table.rb +0 -65
- data/test/conversion_table_test.rb +0 -98
data/test/test_helper.rb
CHANGED
@@ -1,17 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "pry" unless ENV["CI"]
|
1
3
|
require "measured"
|
2
4
|
require "minitest/reporters"
|
3
5
|
require "minitest/autorun"
|
4
|
-
require "mocha/
|
5
|
-
require "pry"
|
6
|
+
require "mocha/minitest"
|
6
7
|
|
7
8
|
ActiveSupport.test_order = :random
|
8
9
|
|
9
10
|
Minitest::Reporters.use! [Minitest::Reporters::ProgressReporter.new(color: true)]
|
10
11
|
|
12
|
+
require "support/subclasses"
|
11
13
|
require "support/fake_system"
|
14
|
+
require "support/always_true_cache"
|
12
15
|
|
13
16
|
class ActiveSupport::TestCase
|
14
|
-
|
15
17
|
protected
|
16
18
|
|
17
19
|
def assert_close_bigdecimal exp, act, delta = BigDecimal('0.000001')
|
data/test/unit_error_test.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require "test_helper"
|
2
3
|
|
3
4
|
class Measured::UnitSystemBuilderTest < ActiveSupport::TestCase
|
@@ -11,15 +12,17 @@ class Measured::UnitSystemBuilderTest < ActiveSupport::TestCase
|
|
11
12
|
end
|
12
13
|
|
13
14
|
test "#unit cannot add duplicate unit names" do
|
14
|
-
assert_raises Measured::
|
15
|
+
error = assert_raises Measured::UnitAlreadyAdded do
|
15
16
|
Measured.build do
|
16
17
|
unit :m
|
17
18
|
unit :in, aliases: [:inch], value: "0.0254 m"
|
18
19
|
unit :in, aliases: [:thing], value: "123 m"
|
19
20
|
end
|
20
21
|
end
|
22
|
+
assert_equal("in", error.unit_name)
|
23
|
+
assert_equal("Unit in has already been added.", error.message)
|
21
24
|
|
22
|
-
assert_raises Measured::
|
25
|
+
assert_raises Measured::UnitAlreadyAdded do
|
23
26
|
Measured.build do
|
24
27
|
unit :m
|
25
28
|
unit :in, aliases: [:inch], value: "0.0254 m"
|
@@ -28,6 +31,19 @@ class Measured::UnitSystemBuilderTest < ActiveSupport::TestCase
|
|
28
31
|
end
|
29
32
|
end
|
30
33
|
|
34
|
+
test "#unit raises when cannot find conversion path" do
|
35
|
+
error = assert_raises Measured::MissingConversionPath do
|
36
|
+
Measured.build do
|
37
|
+
unit :m
|
38
|
+
unit :in, value: "0.0254 m"
|
39
|
+
unit :pallets, value: "5 cases"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
assert_equal("pallets", error.from)
|
43
|
+
assert_equal("m", error.to)
|
44
|
+
assert_equal("Cannot find conversion path from pallets to m.", error.message)
|
45
|
+
end
|
46
|
+
|
31
47
|
test "#unit is case sensitive" do
|
32
48
|
measurable = Measured.build do
|
33
49
|
unit :normal
|
@@ -38,6 +54,16 @@ class Measured::UnitSystemBuilderTest < ActiveSupport::TestCase
|
|
38
54
|
assert_equal 'BOLD', measurable.unit_system.unit_for!(:BOLD).name
|
39
55
|
end
|
40
56
|
|
57
|
+
test "#unit traverses aliases" do
|
58
|
+
measurable = Measured.build do
|
59
|
+
unit :piece, aliases: [:pieces]
|
60
|
+
unit :dozen, aliases: [:dz], value: "12 pieces"
|
61
|
+
end
|
62
|
+
|
63
|
+
assert_equal 12, measurable.unit_system.units.last.conversion_amount
|
64
|
+
assert_equal "piece", measurable.unit_system.units.last.conversion_unit
|
65
|
+
end
|
66
|
+
|
41
67
|
test "#si_unit adds 21 new units" do
|
42
68
|
measurable = Measured.build do
|
43
69
|
unit :ft
|
@@ -54,7 +80,7 @@ class Measured::UnitSystemBuilderTest < ActiveSupport::TestCase
|
|
54
80
|
end
|
55
81
|
|
56
82
|
prefixes = Measured::UnitSystemBuilder::SI_PREFIXES.map { |short, _, _| "#{short}ft" }
|
57
|
-
prefixes += %w(in ft)
|
83
|
+
prefixes += %w(in ft)
|
58
84
|
assert_equal prefixes.sort, measurable.unit_names
|
59
85
|
end
|
60
86
|
|
@@ -109,4 +135,24 @@ class Measured::UnitSystemBuilderTest < ActiveSupport::TestCase
|
|
109
135
|
assert_equal (2240), measurable.unit_system.unit_for!(:long_ton).conversion_amount
|
110
136
|
assert_equal "lb", measurable.unit_system.unit_for!(:long_ton).conversion_unit
|
111
137
|
end
|
138
|
+
|
139
|
+
test "#cache sets no cache by default" do
|
140
|
+
measurable = Measured.build do
|
141
|
+
unit :m
|
142
|
+
unit :km, value: "1000 m"
|
143
|
+
end
|
144
|
+
|
145
|
+
refute_predicate measurable.unit_system, :cached?
|
146
|
+
end
|
147
|
+
|
148
|
+
test "#cache sets the class and args" do
|
149
|
+
measurable = Measured.build do
|
150
|
+
unit :m
|
151
|
+
unit :km, value: "1000 m"
|
152
|
+
|
153
|
+
cache AlwaysTrueCache
|
154
|
+
end
|
155
|
+
|
156
|
+
assert_predicate measurable.unit_system, :cached?
|
157
|
+
end
|
112
158
|
end
|
data/test/unit_system_test.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require "test_helper"
|
2
3
|
|
3
4
|
class Measured::UnitSystemTest < ActiveSupport::TestCase
|
@@ -99,4 +100,18 @@ class Measured::UnitSystemTest < ActiveSupport::TestCase
|
|
99
100
|
test "#convert handles the same unit" do
|
100
101
|
assert_equal 2, @conversion.convert(2, from: @unit_in, to: @unit_in)
|
101
102
|
end
|
103
|
+
|
104
|
+
test "#update_cache calls the builder" do
|
105
|
+
Measured::ConversionTableBuilder.any_instance.expects(:update_cache)
|
106
|
+
@conversion.update_cache
|
107
|
+
end
|
108
|
+
|
109
|
+
test "#cached? calls the builder and is false" do
|
110
|
+
refute_predicate @conversion, :cached?
|
111
|
+
end
|
112
|
+
|
113
|
+
test "#cached? calls the builder and is true" do
|
114
|
+
conversion = Measured::UnitSystem.new([@unit_m, @unit_in, @unit_ft], cache: { class: AlwaysTrueCache })
|
115
|
+
assert_predicate conversion, :cached?
|
116
|
+
end
|
102
117
|
end
|
data/test/unit_test.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require "test_helper"
|
2
3
|
|
3
4
|
class Measured::UnitTest < ActiveSupport::TestCase
|
@@ -78,4 +79,8 @@ class Measured::UnitTest < ActiveSupport::TestCase
|
|
78
79
|
test "#inverse_conversion_amount returns 1/amount" do
|
79
80
|
assert_equal Rational(1, 10), @unit.inverse_conversion_amount
|
80
81
|
end
|
82
|
+
|
83
|
+
test "#inverse_conversion_amount handles nil for base unit" do
|
84
|
+
assert_nil Measured::Unit.new(:pie).inverse_conversion_amount
|
85
|
+
end
|
81
86
|
end
|
data/test/units/length_test.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require "test_helper"
|
2
3
|
|
3
4
|
class Measured::LengthTest < ActiveSupport::TestCase
|
@@ -142,7 +143,7 @@ class Measured::LengthTest < ActiveSupport::TestCase
|
|
142
143
|
end
|
143
144
|
|
144
145
|
test ".convert_to from km to mi" do
|
145
|
-
assert_conversion Measured::Length, "2000 km", "0.1242742384475E4 mi"
|
146
|
+
assert_conversion Measured::Length, "2000 km", "0.1242742384475E4 mi"
|
146
147
|
end
|
147
148
|
|
148
149
|
test ".convert_to from km to mm" do
|
@@ -150,7 +151,7 @@ class Measured::LengthTest < ActiveSupport::TestCase
|
|
150
151
|
end
|
151
152
|
|
152
153
|
test ".convert_to from km to yd" do
|
153
|
-
assert_conversion Measured::Length, "2000 km", "0.218722659667542E7 yd"
|
154
|
+
assert_conversion Measured::Length, "2000 km", "0.218722659667542E7 yd"
|
154
155
|
end
|
155
156
|
|
156
157
|
test ".convert_to from m to cm" do
|
@@ -206,7 +207,7 @@ class Measured::LengthTest < ActiveSupport::TestCase
|
|
206
207
|
end
|
207
208
|
|
208
209
|
test ".convert_to from mi to mi" do
|
209
|
-
assert_exact_conversion Measured::Length, "2000 mi", "2000 mi"
|
210
|
+
assert_exact_conversion Measured::Length, "2000 mi", "2000 mi"
|
210
211
|
end
|
211
212
|
|
212
213
|
test ".convert_to from mi to mm" do
|
@@ -214,7 +215,7 @@ class Measured::LengthTest < ActiveSupport::TestCase
|
|
214
215
|
end
|
215
216
|
|
216
217
|
test ".convert_to from mi to yd" do
|
217
|
-
assert_exact_conversion Measured::Length, "2000 mi", "3520000 yd"
|
218
|
+
assert_exact_conversion Measured::Length, "2000 mi", "3520000 yd"
|
218
219
|
end
|
219
220
|
|
220
221
|
test ".convert_to from mm to cm" do
|
data/test/units/volume_test.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require "test_helper"
|
2
3
|
|
3
4
|
class Measured::VolumeTest < ActiveSupport::TestCase
|
@@ -68,7 +69,7 @@ class Measured::VolumeTest < ActiveSupport::TestCase
|
|
68
69
|
test ".unit_names should be the list of base unit names" do
|
69
70
|
expected_units = %w(l m3 ft3 in3 gal us_gal qt us_qt pt us_pt oz us_oz)
|
70
71
|
expected_units += Measured::UnitSystemBuilder::SI_PREFIXES.map { |short, _, _| "#{short}l" }
|
71
|
-
assert_equal expected_units.sort, Measured::Volume.unit_names
|
72
|
+
assert_equal expected_units.sort, Measured::Volume.unit_names
|
72
73
|
end
|
73
74
|
|
74
75
|
test ".name" do
|
@@ -95,7 +96,7 @@ class Measured::VolumeTest < ActiveSupport::TestCase
|
|
95
96
|
test ".convert_to from gal to gal" do
|
96
97
|
assert_conversion Measured::Volume, "2000 gal", "2000 gal"
|
97
98
|
end
|
98
|
-
|
99
|
+
|
99
100
|
test ".convert_to from us_gal to us_gal" do
|
100
101
|
assert_conversion Measured::Volume, "2000 us_gal", "2000 us_gal"
|
101
102
|
end
|
@@ -123,7 +124,7 @@ class Measured::VolumeTest < ActiveSupport::TestCase
|
|
123
124
|
test ".convert_to from us_oz to us_oz" do
|
124
125
|
assert_conversion Measured::Volume, "2000 us_oz", "2000 us_oz"
|
125
126
|
end
|
126
|
-
|
127
|
+
|
127
128
|
test ".convert_to from ml to m3" do
|
128
129
|
assert_conversion Measured::Volume, "2000 ml", "0.002 m3"
|
129
130
|
end
|
@@ -303,7 +304,7 @@ class Measured::VolumeTest < ActiveSupport::TestCase
|
|
303
304
|
test ".convert_to from gal to us_oz" do
|
304
305
|
assert_conversion Measured::Volume, "2 gal", "307.4431809292 us_oz"
|
305
306
|
end
|
306
|
-
|
307
|
+
|
307
308
|
test ".convert_to from us_gal to qt" do
|
308
309
|
assert_conversion Measured::Volume, "2 us_gal", "6.661393477 qt"
|
309
310
|
end
|
@@ -387,4 +388,4 @@ class Measured::VolumeTest < ActiveSupport::TestCase
|
|
387
388
|
test ".convert_to from oz to us_oz" do
|
388
389
|
assert_conversion Measured::Volume, "2 oz", "1.9215207864 us_oz"
|
389
390
|
end
|
390
|
-
end
|
391
|
+
end
|
data/test/units/weight_test.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: measured
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin McPhillips
|
8
|
+
- Jason Gedge
|
9
|
+
- Javier Honduvilla Coto
|
8
10
|
autorequire:
|
9
11
|
bindir: bin
|
10
12
|
cert_chain: []
|
11
|
-
date:
|
13
|
+
date: 2020-12-10 00:00:00.000000000 Z
|
12
14
|
dependencies:
|
13
15
|
- !ruby/object:Gem::Dependency
|
14
16
|
name: activesupport
|
@@ -16,14 +18,14 @@ dependencies:
|
|
16
18
|
requirements:
|
17
19
|
- - ">="
|
18
20
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
21
|
+
version: '5.2'
|
20
22
|
type: :runtime
|
21
23
|
prerelease: false
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
23
25
|
requirements:
|
24
26
|
- - ">="
|
25
27
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
28
|
+
version: '5.2'
|
27
29
|
- !ruby/object:Gem::Dependency
|
28
30
|
name: rake
|
29
31
|
requirement: !ruby/object:Gem::Requirement
|
@@ -70,16 +72,16 @@ dependencies:
|
|
70
72
|
name: mocha
|
71
73
|
requirement: !ruby/object:Gem::Requirement
|
72
74
|
requirements:
|
73
|
-
- - "
|
75
|
+
- - ">="
|
74
76
|
- !ruby/object:Gem::Version
|
75
|
-
version: 1.
|
77
|
+
version: 1.4.0
|
76
78
|
type: :development
|
77
79
|
prerelease: false
|
78
80
|
version_requirements: !ruby/object:Gem::Requirement
|
79
81
|
requirements:
|
80
|
-
- - "
|
82
|
+
- - ">="
|
81
83
|
- !ruby/object:Gem::Version
|
82
|
-
version: 1.
|
84
|
+
version: 1.4.0
|
83
85
|
- !ruby/object:Gem::Dependency
|
84
86
|
name: pry
|
85
87
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,29 +96,42 @@ dependencies:
|
|
94
96
|
- - ">="
|
95
97
|
- !ruby/object:Gem::Version
|
96
98
|
version: '0'
|
97
|
-
description: Wrapper objects which encapsulate
|
99
|
+
description: Wrapper objects which encapsulate measurements and their associated units
|
98
100
|
in Ruby.
|
99
101
|
email:
|
100
|
-
-
|
102
|
+
- gems@shopify.com
|
101
103
|
executables: []
|
102
104
|
extensions: []
|
103
105
|
extra_rdoc_files: []
|
104
106
|
files:
|
107
|
+
- ".github/workflows/ci.yml"
|
105
108
|
- ".gitignore"
|
106
|
-
-
|
109
|
+
- CHANGELOG.md
|
107
110
|
- Gemfile
|
108
111
|
- LICENSE
|
109
112
|
- README.md
|
110
113
|
- Rakefile
|
114
|
+
- cache/.keep
|
115
|
+
- cache/length.json
|
116
|
+
- cache/volume.json
|
117
|
+
- cache/weight.json
|
111
118
|
- dev.yml
|
112
|
-
- gemfiles/activesupport-
|
119
|
+
- gemfiles/activesupport-5.2.gemfile
|
120
|
+
- gemfiles/activesupport-6.0.gemfile
|
121
|
+
- gemfiles/activesupport-6.1.gemfile
|
113
122
|
- lib/measured.rb
|
114
123
|
- lib/measured/arithmetic.rb
|
115
124
|
- lib/measured/base.rb
|
116
|
-
- lib/measured/
|
125
|
+
- lib/measured/cache/json.rb
|
126
|
+
- lib/measured/cache/json_writer.rb
|
127
|
+
- lib/measured/cache/null.rb
|
128
|
+
- lib/measured/conversion_table_builder.rb
|
117
129
|
- lib/measured/measurable.rb
|
130
|
+
- lib/measured/missing_conversion_path.rb
|
118
131
|
- lib/measured/parser.rb
|
119
132
|
- lib/measured/unit.rb
|
133
|
+
- lib/measured/unit_already_added.rb
|
134
|
+
- lib/measured/unit_error.rb
|
120
135
|
- lib/measured/unit_system.rb
|
121
136
|
- lib/measured/unit_system_builder.rb
|
122
137
|
- lib/measured/units/length.rb
|
@@ -126,10 +141,16 @@ files:
|
|
126
141
|
- measured.gemspec
|
127
142
|
- shipit.rubygems.yml
|
128
143
|
- test/arithmetic_test.rb
|
129
|
-
- test/
|
144
|
+
- test/cache/json_test.rb
|
145
|
+
- test/cache/json_writer_test.rb
|
146
|
+
- test/cache/null_test.rb
|
147
|
+
- test/cache_consistency_test.rb
|
148
|
+
- test/conversion_table_builder_test.rb
|
130
149
|
- test/measurable_test.rb
|
131
150
|
- test/parser_test.rb
|
151
|
+
- test/support/always_true_cache.rb
|
132
152
|
- test/support/fake_system.rb
|
153
|
+
- test/support/subclasses.rb
|
133
154
|
- test/test_helper.rb
|
134
155
|
- test/unit_error_test.rb
|
135
156
|
- test/unit_system_builder_test.rb
|
@@ -141,7 +162,8 @@ files:
|
|
141
162
|
homepage: https://github.com/Shopify/measured
|
142
163
|
licenses:
|
143
164
|
- MIT
|
144
|
-
metadata:
|
165
|
+
metadata:
|
166
|
+
allowed_push_host: https://rubygems.org
|
145
167
|
post_install_message:
|
146
168
|
rdoc_options: []
|
147
169
|
require_paths:
|
@@ -157,17 +179,22 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
157
179
|
- !ruby/object:Gem::Version
|
158
180
|
version: '0'
|
159
181
|
requirements: []
|
160
|
-
|
161
|
-
rubygems_version: 2.6.14
|
182
|
+
rubygems_version: 3.0.3
|
162
183
|
signing_key:
|
163
184
|
specification_version: 4
|
164
185
|
summary: Encapsulate measurements with their units in Ruby
|
165
186
|
test_files:
|
166
187
|
- test/arithmetic_test.rb
|
167
|
-
- test/
|
188
|
+
- test/cache/json_test.rb
|
189
|
+
- test/cache/json_writer_test.rb
|
190
|
+
- test/cache/null_test.rb
|
191
|
+
- test/cache_consistency_test.rb
|
192
|
+
- test/conversion_table_builder_test.rb
|
168
193
|
- test/measurable_test.rb
|
169
194
|
- test/parser_test.rb
|
195
|
+
- test/support/always_true_cache.rb
|
170
196
|
- test/support/fake_system.rb
|
197
|
+
- test/support/subclasses.rb
|
171
198
|
- test/test_helper.rb
|
172
199
|
- test/unit_error_test.rb
|
173
200
|
- test/unit_system_builder_test.rb
|
data/.travis.yml
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
sudo: false
|
3
|
-
cache: bundler
|
4
|
-
rvm:
|
5
|
-
- 2.1.8
|
6
|
-
- 2.2.4
|
7
|
-
- 2.3.1
|
8
|
-
- 2.4.0
|
9
|
-
gemfile:
|
10
|
-
- Gemfile
|
11
|
-
- gemfiles/activesupport-4.2.gemfile
|
12
|
-
matrix:
|
13
|
-
exclude:
|
14
|
-
- gemfile: Gemfile
|
15
|
-
rvm: 2.1.8
|
16
|
-
- gemfile: gemfiles/activesupport-4.2.gemfile
|
17
|
-
rvm: 2.4.0
|
@@ -1,65 +0,0 @@
|
|
1
|
-
module Measured::ConversionTable
|
2
|
-
extend self
|
3
|
-
|
4
|
-
def build(units)
|
5
|
-
table = {}
|
6
|
-
|
7
|
-
units.map{|u| u.name}.each do |to_unit|
|
8
|
-
to_table = {to_unit => BigDecimal("1")}
|
9
|
-
|
10
|
-
table.each do |from_unit, from_table|
|
11
|
-
to_table[from_unit] = find_conversion(units, to: from_unit, from: to_unit)
|
12
|
-
from_table[to_unit] = find_conversion(units, to: to_unit, from: from_unit)
|
13
|
-
end
|
14
|
-
|
15
|
-
table[to_unit] = to_table
|
16
|
-
end
|
17
|
-
|
18
|
-
table
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def find_conversion(units, to:, from:)
|
24
|
-
conversion = find_direct_conversion(units, to: to, from: from) || find_tree_traversal_conversion(units, to: to, from: from)
|
25
|
-
|
26
|
-
raise Measured::UnitError, "Cannot find conversion path from #{ from } to #{ to }." unless conversion
|
27
|
-
|
28
|
-
conversion
|
29
|
-
end
|
30
|
-
|
31
|
-
def find_direct_conversion(units, to:, from:)
|
32
|
-
units.each do |unit|
|
33
|
-
return unit.conversion_amount if unit.name == from && unit.conversion_unit == to
|
34
|
-
end
|
35
|
-
|
36
|
-
units.each do |unit|
|
37
|
-
return unit.inverse_conversion_amount if unit.name == to && unit.conversion_unit == from
|
38
|
-
end
|
39
|
-
|
40
|
-
nil
|
41
|
-
end
|
42
|
-
|
43
|
-
def find_tree_traversal_conversion(units, to:, from:)
|
44
|
-
traverse(units, from: from, to: to, unit_names: units.map(&:name), amount: 1)
|
45
|
-
end
|
46
|
-
|
47
|
-
def traverse(units, from:, to:, unit_names:, amount:)
|
48
|
-
unit_names = unit_names - [from]
|
49
|
-
|
50
|
-
unit_names.each do |name|
|
51
|
-
if conversion = find_direct_conversion(units, from: from, to: name)
|
52
|
-
new_amount = amount * conversion
|
53
|
-
if name == to
|
54
|
-
return new_amount
|
55
|
-
else
|
56
|
-
result = traverse(units, from: name, to: to, unit_names: unit_names, amount: new_amount)
|
57
|
-
return result if result
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
nil
|
63
|
-
end
|
64
|
-
|
65
|
-
end
|