measured 2.3.0 → 2.6.0
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 +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
|