measured 2.0.0 → 2.8.2

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.
Files changed (57) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ci.yml +31 -0
  3. data/CHANGELOG.md +60 -0
  4. data/README.md +68 -10
  5. data/Rakefile +22 -1
  6. data/cache/.keep +0 -0
  7. data/cache/length.json +2553 -0
  8. data/cache/volume.json +4695 -0
  9. data/cache/weight.json +3195 -0
  10. data/dev.yml +2 -6
  11. data/gemfiles/{activesupport-4.2.gemfile → activesupport-5.2.gemfile} +1 -1
  12. data/gemfiles/activesupport-6.0.gemfile +5 -0
  13. data/gemfiles/activesupport-6.1.gemfile +5 -0
  14. data/lib/measured/arithmetic.rb +10 -0
  15. data/lib/measured/base.rb +13 -6
  16. data/lib/measured/cache/json.rb +55 -0
  17. data/lib/measured/cache/json_writer.rb +9 -0
  18. data/lib/measured/cache/null.rb +16 -0
  19. data/lib/measured/conversion_table_builder.rb +110 -0
  20. data/lib/measured/cycle_detected.rb +11 -0
  21. data/lib/measured/measurable.rb +28 -21
  22. data/lib/measured/missing_conversion_path.rb +12 -0
  23. data/lib/measured/parser.rb +2 -1
  24. data/lib/measured/unit.rb +17 -27
  25. data/lib/measured/unit_already_added.rb +11 -0
  26. data/lib/measured/unit_error.rb +4 -0
  27. data/lib/measured/unit_system.rb +26 -21
  28. data/lib/measured/unit_system_builder.rb +46 -2
  29. data/lib/measured/units/length.rb +6 -3
  30. data/lib/measured/units/volume.rb +20 -0
  31. data/lib/measured/units/weight.rb +10 -2
  32. data/lib/measured/version.rb +2 -1
  33. data/lib/measured.rb +2 -0
  34. data/measured.gemspec +13 -5
  35. data/test/arithmetic_test.rb +36 -0
  36. data/test/cache/json_test.rb +43 -0
  37. data/test/cache/json_writer_test.rb +23 -0
  38. data/test/cache/null_test.rb +20 -0
  39. data/test/cache_consistency_test.rb +19 -0
  40. data/test/conversion_table_builder_test.rb +147 -0
  41. data/test/measurable_test.rb +28 -13
  42. data/test/parser_test.rb +1 -0
  43. data/test/support/always_true_cache.rb +14 -0
  44. data/test/support/fake_system.rb +1 -0
  45. data/test/support/subclasses.rb +7 -0
  46. data/test/test_helper.rb +5 -3
  47. data/test/unit_error_test.rb +1 -0
  48. data/test/unit_system_builder_test.rb +120 -2
  49. data/test/unit_system_test.rb +15 -0
  50. data/test/unit_test.rb +14 -5
  51. data/test/units/length_test.rb +123 -10
  52. data/test/units/volume_test.rb +497 -0
  53. data/test/units/weight_test.rb +290 -5
  54. metadata +49 -18
  55. data/.travis.yml +0 -17
  56. data/lib/measured/conversion_table.rb +0 -65
  57. data/test/conversion_table_test.rb +0 -98
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require "test_helper"
2
3
 
3
4
  class Measured::WeightTest < ActiveSupport::TestCase
@@ -6,17 +7,50 @@ class Measured::WeightTest < ActiveSupport::TestCase
6
7
  end
7
8
 
8
9
  test ".unit_names_with_aliases should be the expected list of valid units" do
9
- assert_equal(
10
- %w(g gram grams kg kilogram kilograms lb lbs ounce ounces oz pound pounds),
11
- Measured::Weight.unit_names_with_aliases
10
+ expected_units = %w(
11
+ N
12
+ W/T
13
+ displacement_ton
14
+ displacement_tons
15
+ g
16
+ gram
17
+ grams
18
+ imperial_ton
19
+ imperial_tons
20
+ lb
21
+ lbs
22
+ long_ton
23
+ long_tons
24
+ metric_ton
25
+ metric_tons
26
+ newton
27
+ newtons
28
+ ounce
29
+ ounces
30
+ oz
31
+ pound
32
+ pounds
33
+ short_ton
34
+ short_tons
35
+ slug
36
+ slugs
37
+ t
38
+ weight_ton
39
+ weight_tons
12
40
  )
41
+ expected_units += Measured::UnitSystemBuilder::SI_PREFIXES.flat_map do |short, long, _|
42
+ ["#{short}g", "#{long}gram", "#{long}grams"]
43
+ end
44
+
45
+ assert_equal expected_units.sort, Measured::Weight.unit_names_with_aliases
13
46
  end
14
47
 
15
48
  test ".unit_names should be the list of base unit names" do
16
- assert_equal %w(g kg lb oz), Measured::Weight.unit_names
49
+ expected_units = %w(N g lb long_ton oz short_ton slug t)
50
+ expected_units += Measured::UnitSystemBuilder::SI_PREFIXES.map { |short, _, _| "#{short}g" }
51
+ assert_equal expected_units.sort, Measured::Weight.unit_names
17
52
  end
18
53
 
19
-
20
54
  test "Measured::Weight() delegates automatically to .new" do
21
55
  assert_equal Measured::Weight.new(1, :lb), Measured::Weight(1, :lb)
22
56
  assert_equal Measured::Weight.new(2000, :g), Measured::Weight(2, :kg)
@@ -42,6 +76,26 @@ class Measured::WeightTest < ActiveSupport::TestCase
42
76
  assert_conversion Measured::Weight, "2000 g", "70.54792384 oz"
43
77
  end
44
78
 
79
+ test ".convert_to from g to slug" do
80
+ assert_conversion Measured::Weight, "2000 g", "0.1370435 slug"
81
+ end
82
+
83
+ test ".convert_to from g to N" do
84
+ assert_conversion Measured::Weight, "2000 g", "19.6133 N"
85
+ end
86
+
87
+ test ".convert_to from g to short_ton" do
88
+ assert_conversion Measured::Weight, "2000 g", "0.002204623 short_ton"
89
+ end
90
+
91
+ test ".convert_to from g to long_ton" do
92
+ assert_conversion Measured::Weight, "2000 g", "0.001968413055222 long_ton"
93
+ end
94
+
95
+ test ".convert_to from g to t" do
96
+ assert_exact_conversion Measured::Weight, "2000 g", "0.002 t"
97
+ end
98
+
45
99
  test ".convert_to from kg to g" do
46
100
  assert_exact_conversion Measured::Weight, "2000 kg", "2000000 g"
47
101
  end
@@ -58,6 +112,26 @@ class Measured::WeightTest < ActiveSupport::TestCase
58
112
  assert_conversion Measured::Weight, "2000 kg", "70547.92390 oz"
59
113
  end
60
114
 
115
+ test ".convert_to from kg to slug" do
116
+ assert_conversion Measured::Weight, "2000 kg", "137.0435311239221 slug"
117
+ end
118
+
119
+ test ".convert_to from kg to N" do
120
+ assert_conversion Measured::Weight, "2000 kg", "19613.3 N"
121
+ end
122
+
123
+ test ".convert_to from kg to short_ton" do
124
+ assert_conversion Measured::Weight, "2000 kg", "2.204622621848 short_ton"
125
+ end
126
+
127
+ test ".convert_to from kg to long_ton" do
128
+ assert_conversion Measured::Weight, "2000 kg", "1.9684130552220003 long_ton"
129
+ end
130
+
131
+ test ".convert_to from kg to t" do
132
+ assert_exact_conversion Measured::Weight, "2000 kg", "2 t"
133
+ end
134
+
61
135
  test ".convert_to from lb to g" do
62
136
  assert_exact_conversion Measured::Weight, "2000 lb", "907184.74 g"
63
137
  end
@@ -74,6 +148,26 @@ class Measured::WeightTest < ActiveSupport::TestCase
74
148
  assert_exact_conversion Measured::Weight, "2000 lb", "32000 oz"
75
149
  end
76
150
 
151
+ test ".convert_to from lb to slug" do
152
+ assert_conversion Measured::Weight, "2000 lb", "62.16190007566859 slug"
153
+ end
154
+
155
+ test ".convert_to from lb to N" do
156
+ assert_conversion Measured::Weight, "2000 lb", "8896.443230521 N"
157
+ end
158
+
159
+ test ".convert_to from lb to short_ton" do
160
+ assert_exact_conversion Measured::Weight, "2000 lb", "1 short_ton"
161
+ end
162
+
163
+ test ".convert_to from lb to long_ton" do
164
+ assert_conversion Measured::Weight, "2000 lb", "0.892857142857088 long_ton"
165
+ end
166
+
167
+ test ".convert_to from lb to t" do
168
+ assert_conversion Measured::Weight, "2000 lb", "0.90718474 t"
169
+ end
170
+
77
171
  test ".convert_to from oz to g" do
78
172
  assert_conversion Measured::Weight, "2000 oz", "56699.04625 g"
79
173
  end
@@ -90,4 +184,195 @@ class Measured::WeightTest < ActiveSupport::TestCase
90
184
  assert_exact_conversion Measured::Weight, "2000 oz", "2000 oz"
91
185
  end
92
186
 
187
+ test ".convert_to from oz to slug" do
188
+ assert_conversion Measured::Weight, "2000 oz", "3.885119 slug"
189
+ end
190
+
191
+ test ".convert_to from oz to N" do
192
+ assert_conversion Measured::Weight, "2000 oz", "556.0277019075625 N"
193
+ end
194
+
195
+ test ".convert_to from oz to short_ton" do
196
+ assert_conversion Measured::Weight, "2000 oz", "0.06249999999997801 short_ton"
197
+ end
198
+
199
+ test ".convert_to from oz to long_ton" do
200
+ assert_conversion Measured::Weight, "2000 oz", "0.055803571428568 long_ton"
201
+ end
202
+
203
+ test ".convert_to from oz to t" do
204
+ assert_conversion Measured::Weight, "2000 oz", "0.05669904625 t"
205
+ end
206
+
207
+ test ".convert_to from slug to g" do
208
+ assert_conversion Measured::Weight, "2000 slug", "29187806 g"
209
+ end
210
+
211
+ test ".convert_to from slug to kg" do
212
+ assert_conversion Measured::Weight, "2000 slug", "29187.805999999997 kg"
213
+ end
214
+
215
+ test ".convert_to from slug to lb" do
216
+ assert_conversion Measured::Weight, "2000 slug", "64348.09738973343 lb"
217
+ end
218
+
219
+ test ".convert_to from slug to oz" do
220
+ assert_conversion Measured::Weight, "2000 slug", "1029569.5582357347 oz"
221
+ end
222
+
223
+ test ".convert_to from slug to slug" do
224
+ assert_exact_conversion Measured::Weight, "2000 slug", "2000 slug"
225
+ end
226
+
227
+ test ".convert_to from slug to N" do
228
+ assert_conversion Measured::Weight, "2000 slug", "286234.59770989994 N"
229
+ end
230
+
231
+ test ".convert_to from slug to short_ton" do
232
+ assert_conversion Measured::Weight, "2000 slug", "32.17404869485539 short_ton"
233
+ end
234
+
235
+ test ".convert_to from slug to long_ton" do
236
+ assert_conversion Measured::Weight, "2000 slug", "28.726829191843514 long_ton"
237
+ end
238
+
239
+ test ".convert_to from slug to t" do
240
+ assert_conversion Measured::Weight, "2000 slug", "29.187806 t"
241
+ end
242
+
243
+ test ".convert_to from short_ton to g" do
244
+ assert_conversion Measured::Weight, "2000 short_ton", "1814369480 g"
245
+ end
246
+
247
+ test ".convert_to from short_ton to kg" do
248
+ assert_conversion Measured::Weight, "2000 short_ton", "1814369.48 kg"
249
+ end
250
+
251
+ test ".convert_to from short_ton to lb" do
252
+ assert_exact_conversion Measured::Weight, "2000 short_ton", "4000000 lb"
253
+ end
254
+
255
+ test ".convert_to from short_ton to oz" do
256
+ assert_exact_conversion Measured::Weight, "2000 short_ton", "64000000 oz"
257
+ end
258
+
259
+ test ".convert_to from short_ton to slug" do
260
+ assert_conversion Measured::Weight, "2000 short_ton", "124323.80015133717 slug"
261
+ end
262
+
263
+ test ".convert_to from short_ton to N" do
264
+ assert_conversion Measured::Weight, "2000 short_ton", "17792886.461041998 N"
265
+ end
266
+
267
+ test ".convert_to from short_ton to short_ton" do
268
+ assert_exact_conversion Measured::Weight, "2000 short_ton", "2000 short_ton"
269
+ end
270
+
271
+ test ".convert_to from short_ton to long_ton" do
272
+ assert_conversion Measured::Weight, "2000 short_ton", "1785.714285714176 long_ton"
273
+ end
274
+
275
+ test ".convert_to from short_ton to t" do
276
+ assert_conversion Measured::Weight, "2000 short_ton", "1814.36948 t"
277
+ end
278
+
279
+ test ".convert_to from long_ton to g" do
280
+ assert_conversion Measured::Weight, "2000 long_ton", "2032093817.6 g"
281
+ end
282
+
283
+ test ".convert_to from long_ton to kg" do
284
+ assert_conversion Measured::Weight, "2000 long_ton", "2032093.8176 kg"
285
+ end
286
+
287
+ test ".convert_to from long_ton to lb" do
288
+ assert_exact_conversion Measured::Weight, "2000 long_ton", "4480000 lb"
289
+ end
290
+
291
+ test ".convert_to from long_ton to oz" do
292
+ assert_exact_conversion Measured::Weight, "2000 long_ton", "71680000 oz"
293
+ end
294
+
295
+ test ".convert_to from long_ton to slug" do
296
+ assert_conversion Measured::Weight, "2000 long_ton", "139242.65616949764 slug"
297
+ end
298
+
299
+ test ".convert_to from long_ton to N" do
300
+ assert_conversion Measured::Weight, "2000 long_ton", "19928032.836367033 N"
301
+ end
302
+
303
+ test ".convert_to from long_ton to short_ton" do
304
+ assert_exact_conversion Measured::Weight, "2000 long_ton", "2240 short_ton"
305
+ end
306
+
307
+ test ".convert_to from long_ton to long_ton" do
308
+ assert_conversion Measured::Weight, "2000 long_ton", "2000 long_ton"
309
+ end
310
+
311
+ test ".convert_to from long_ton to t" do
312
+ assert_conversion Measured::Weight, "2000 long_ton", "2032.0938176 t"
313
+ end
314
+
315
+ test ".convert_to from N to g" do
316
+ assert_conversion Measured::Weight, "2000 N", "203943.24259558567 g"
317
+ end
318
+
319
+ test ".convert_to from N to kg" do
320
+ assert_conversion Measured::Weight, "2000 N", "203.9432425955857 kg"
321
+ end
322
+
323
+ test ".convert_to from N to lb" do
324
+ assert_conversion Measured::Weight, "2000 N", "449.6178861994211 lb"
325
+ end
326
+
327
+ test ".convert_to from N to oz" do
328
+ assert_conversion Measured::Weight, "2000 N", "7193.886179190737 oz"
329
+ end
330
+
331
+ test ".convert_to from N to slug" do
332
+ assert_conversion Measured::Weight, "2000 N", "13.974551057080868 slug"
333
+ end
334
+
335
+ test ".convert_to from N to N" do
336
+ assert_exact_conversion Measured::Weight, "2000 N", "2000 N"
337
+ end
338
+
339
+ test ".convert_to from N to short_ton" do
340
+ assert_conversion Measured::Weight, "2000 N", "0.2248089430996314 short_ton"
341
+ end
342
+
343
+ test ".convert_to from N to long_ton" do
344
+ assert_conversion Measured::Weight, "2000 N", "0.20072227062472917 long_ton"
345
+ end
346
+
347
+ test ".convert_to from N to t" do
348
+ assert_conversion Measured::Weight, "2000 N", "0.2039432425955857 t"
349
+ end
350
+
351
+ test ".convert_to from t to g" do
352
+ assert_exact_conversion Measured::Weight, "2000 t", "2000000000 g"
353
+ end
354
+
355
+ test ".convert_to from t to kg" do
356
+ assert_exact_conversion Measured::Weight, "2000 t", "2000000 kg"
357
+ end
358
+
359
+ test ".convert_to from t to lb" do
360
+ assert_conversion Measured::Weight, "2000 t", "4409245.243697552 lb"
361
+ end
362
+
363
+ test ".convert_to from t to oz" do
364
+ assert_conversion Measured::Weight, "2000 t", "70547923.89916082 oz"
365
+ end
366
+
367
+ test ".convert_to from t to slug" do
368
+ assert_conversion Measured::Weight, "2000 t", "137043.5311239221 slug"
369
+ end
370
+
371
+ test ".convert_to from t to short_ton" do
372
+ assert_conversion Measured::Weight, "2000 t", "2204.622621848 short_ton"
373
+ end
374
+
375
+ test ".convert_to from t to t" do
376
+ assert_conversion Measured::Weight, "2000 t", "2000 t"
377
+ end
93
378
  end
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.0.0
4
+ version: 2.8.2
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: 2017-04-05 00:00:00.000000000 Z
13
+ date: 2021-12-21 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: '4.2'
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: '4.2'
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.1.0
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.1.0
84
+ version: 1.4.0
83
85
  - !ruby/object:Gem::Dependency
84
86
  name: pry
85
87
  requirement: !ruby/object:Gem::Requirement
@@ -94,52 +96,75 @@ dependencies:
94
96
  - - ">="
95
97
  - !ruby/object:Gem::Version
96
98
  version: '0'
97
- description: Wrapper objects which encapsulate measurments and their associated units
99
+ description: Wrapper objects which encapsulate measurements and their associated units
98
100
  in Ruby.
99
101
  email:
100
- - github@kevinmcphillips.ca
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
- - ".travis.yml"
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-4.2.gemfile
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/conversion_table.rb
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
129
+ - lib/measured/cycle_detected.rb
117
130
  - lib/measured/measurable.rb
131
+ - lib/measured/missing_conversion_path.rb
118
132
  - lib/measured/parser.rb
119
133
  - lib/measured/unit.rb
134
+ - lib/measured/unit_already_added.rb
135
+ - lib/measured/unit_error.rb
120
136
  - lib/measured/unit_system.rb
121
137
  - lib/measured/unit_system_builder.rb
122
138
  - lib/measured/units/length.rb
139
+ - lib/measured/units/volume.rb
123
140
  - lib/measured/units/weight.rb
124
141
  - lib/measured/version.rb
125
142
  - measured.gemspec
126
143
  - shipit.rubygems.yml
127
144
  - test/arithmetic_test.rb
128
- - test/conversion_table_test.rb
145
+ - test/cache/json_test.rb
146
+ - test/cache/json_writer_test.rb
147
+ - test/cache/null_test.rb
148
+ - test/cache_consistency_test.rb
149
+ - test/conversion_table_builder_test.rb
129
150
  - test/measurable_test.rb
130
151
  - test/parser_test.rb
152
+ - test/support/always_true_cache.rb
131
153
  - test/support/fake_system.rb
154
+ - test/support/subclasses.rb
132
155
  - test/test_helper.rb
133
156
  - test/unit_error_test.rb
134
157
  - test/unit_system_builder_test.rb
135
158
  - test/unit_system_test.rb
136
159
  - test/unit_test.rb
137
160
  - test/units/length_test.rb
161
+ - test/units/volume_test.rb
138
162
  - test/units/weight_test.rb
139
163
  homepage: https://github.com/Shopify/measured
140
164
  licenses:
141
165
  - MIT
142
- metadata: {}
166
+ metadata:
167
+ allowed_push_host: https://rubygems.org
143
168
  post_install_message:
144
169
  rdoc_options: []
145
170
  require_paths:
@@ -155,21 +180,27 @@ required_rubygems_version: !ruby/object:Gem::Requirement
155
180
  - !ruby/object:Gem::Version
156
181
  version: '0'
157
182
  requirements: []
158
- rubyforge_project:
159
- rubygems_version: 2.5.2
183
+ rubygems_version: 3.2.20
160
184
  signing_key:
161
185
  specification_version: 4
162
186
  summary: Encapsulate measurements with their units in Ruby
163
187
  test_files:
164
188
  - test/arithmetic_test.rb
165
- - test/conversion_table_test.rb
189
+ - test/cache/json_test.rb
190
+ - test/cache/json_writer_test.rb
191
+ - test/cache/null_test.rb
192
+ - test/cache_consistency_test.rb
193
+ - test/conversion_table_builder_test.rb
166
194
  - test/measurable_test.rb
167
195
  - test/parser_test.rb
196
+ - test/support/always_true_cache.rb
168
197
  - test/support/fake_system.rb
198
+ - test/support/subclasses.rb
169
199
  - test/test_helper.rb
170
200
  - test/unit_error_test.rb
171
201
  - test/unit_system_builder_test.rb
172
202
  - test/unit_system_test.rb
173
203
  - test/unit_test.rb
174
204
  - test/units/length_test.rb
205
+ - test/units/volume_test.rb
175
206
  - test/units/weight_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
@@ -1,98 +0,0 @@
1
- require "test_helper"
2
-
3
- class Measured::ConversionTableTest < ActiveSupport::TestCase
4
- test ".build should return a hash for the simple case" do
5
- expected = {
6
- "test" => {"test" => BigDecimal("1")}
7
- }
8
-
9
- assert_equal expected, Measured::ConversionTable.build([Measured::Unit.new(:test)])
10
- end
11
-
12
- test ".build returns expected nested hashes with BigDecimal conversion factors in a tiny data set" do
13
- conversion_table = Measured::ConversionTable.build([
14
- Measured::Unit.new(:m),
15
- Measured::Unit.new(:cm, value: "0.01 m"),
16
- ])
17
-
18
- expected = {
19
- "m" => {
20
- "m" => BigDecimal("1"),
21
- "cm" => BigDecimal("100"),
22
- },
23
- "cm" => {
24
- "m" => BigDecimal("0.01"),
25
- "cm" => BigDecimal("1"),
26
- }
27
- }
28
-
29
- assert_equal expected, conversion_table
30
- end
31
-
32
- test ".build returns expected nested hashes with BigDecimal conversion factors" do
33
- conversion_table = Measured::ConversionTable.build([
34
- Measured::Unit.new(:m),
35
- Measured::Unit.new(:cm, value: "0.01 m"),
36
- Measured::Unit.new(:mm, value: "0.001 m"),
37
- ])
38
-
39
- expected = {
40
- "m" => {
41
- "m" => BigDecimal("1"),
42
- "cm" => BigDecimal("100"),
43
- "mm" => BigDecimal("1000"),
44
- },
45
- "cm" => {
46
- "m" => BigDecimal("0.01"),
47
- "cm" => BigDecimal("1"),
48
- "mm" => BigDecimal("10"),
49
- },
50
- "mm" => {
51
- "m" => BigDecimal("0.001"),
52
- "cm" => BigDecimal("0.1"),
53
- "mm" => BigDecimal("1"),
54
- }
55
- }
56
-
57
- assert_equal expected, conversion_table
58
- end
59
-
60
- test ".build returns expected nested hashes with BigDecimal conversion factors in an indrect path" do
61
- conversion_table = Measured::ConversionTable.build([
62
- Measured::Unit.new(:mm),
63
- Measured::Unit.new(:cm, value: "10 mm"),
64
- Measured::Unit.new(:dm, value: "10 cm"),
65
- Measured::Unit.new(:m, value: "10 dm"),
66
- ])
67
-
68
- expected = {
69
- "m" => {
70
- "m" => BigDecimal("1"),
71
- "dm" => BigDecimal("10"),
72
- "cm" => BigDecimal("100"),
73
- "mm" => BigDecimal("1000"),
74
- },
75
- "cm" => {
76
- "m" => BigDecimal("0.01"),
77
- "dm" => BigDecimal("0.1"),
78
- "cm" => BigDecimal("1"),
79
- "mm" => BigDecimal("10"),
80
- },
81
- "dm" => {
82
- "m" => BigDecimal("0.1"),
83
- "cm" => BigDecimal("10"),
84
- "dm" => BigDecimal("1"),
85
- "mm" => BigDecimal("100"),
86
- },
87
- "mm" => {
88
- "m" => BigDecimal("0.001"),
89
- "dm" => BigDecimal("0.01"),
90
- "cm" => BigDecimal("0.1"),
91
- "mm" => BigDecimal("1"),
92
- }
93
- }
94
-
95
- assert_equal expected, conversion_table
96
- end
97
-
98
- end