measured 0.0.1
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 +7 -0
- data/.gitignore +14 -0
- data/Gemfile +3 -0
- data/LICENSE +22 -0
- data/README.md +208 -0
- data/Rakefile +21 -0
- data/lib/measured/arithmetic.rb +37 -0
- data/lib/measured/base.rb +13 -0
- data/lib/measured/conversion.rb +91 -0
- data/lib/measured/conversion_table.rb +67 -0
- data/lib/measured/measurable.rb +67 -0
- data/lib/measured/unit.rb +59 -0
- data/lib/measured/units/length.rb +26 -0
- data/lib/measured/units/weight.rb +18 -0
- data/lib/measured/version.rb +3 -0
- data/lib/measured.rb +4 -0
- data/measured.gemspec +28 -0
- data/test/arithmetic_test.rb +133 -0
- data/test/conversion_table_test.rb +19 -0
- data/test/conversion_test.rb +206 -0
- data/test/measurable_test.rb +118 -0
- data/test/support/fake_system.rb +26 -0
- data/test/test_helper.rb +20 -0
- data/test/unit_error_test.rb +7 -0
- data/test/unit_test.rb +77 -0
- data/test/units/length_test.rb +160 -0
- data/test/units/weight_test.rb +80 -0
- metadata +165 -0
@@ -0,0 +1,67 @@
|
|
1
|
+
class Measured::Measurable
|
2
|
+
include Comparable
|
3
|
+
include Measured::Arithmetic
|
4
|
+
|
5
|
+
attr_reader :unit, :value
|
6
|
+
|
7
|
+
def initialize(value, unit)
|
8
|
+
raise Measured::UnitError, "Unit #{ unit } does not exits." unless self.class.conversion.unit_or_alias?(unit)
|
9
|
+
|
10
|
+
@value = value
|
11
|
+
@value = BigDecimal(@value) unless @value.is_a?(BigDecimal)
|
12
|
+
|
13
|
+
@unit = self.class.conversion.to_unit_name(unit)
|
14
|
+
end
|
15
|
+
|
16
|
+
def convert_to(new_unit)
|
17
|
+
new_unit_name = self.class.conversion.to_unit_name(new_unit)
|
18
|
+
value = self.class.conversion.convert(@value, from: @unit, to: new_unit_name)
|
19
|
+
|
20
|
+
self.class.new(value, new_unit)
|
21
|
+
end
|
22
|
+
|
23
|
+
def convert_to!(new_unit)
|
24
|
+
converted = convert_to(new_unit)
|
25
|
+
|
26
|
+
@value = converted.value
|
27
|
+
@unit = converted.unit
|
28
|
+
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_s
|
33
|
+
[value.to_f.to_s.gsub(/\.0\Z/, ""), unit].join(" ")
|
34
|
+
end
|
35
|
+
|
36
|
+
def inspect
|
37
|
+
"#<#{ self.class }: #{ value } #{ unit }>"
|
38
|
+
end
|
39
|
+
|
40
|
+
def <=>(other)
|
41
|
+
if other.is_a?(self.class) && unit == other.unit
|
42
|
+
value <=> other.value
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def ==(other)
|
47
|
+
!!(other.is_a?(self.class) && unit == other.unit && value == other.value)
|
48
|
+
end
|
49
|
+
|
50
|
+
alias_method :eql?, :==
|
51
|
+
|
52
|
+
class << self
|
53
|
+
|
54
|
+
def conversion
|
55
|
+
@conversion ||= Measured::Conversion.new
|
56
|
+
end
|
57
|
+
|
58
|
+
def units
|
59
|
+
conversion.unit_names
|
60
|
+
end
|
61
|
+
|
62
|
+
def units_with_aliases
|
63
|
+
conversion.unit_names_with_aliases
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
class Measured::Unit
|
2
|
+
include Comparable
|
3
|
+
|
4
|
+
def initialize(name, aliases: [], value: nil)
|
5
|
+
@name = name.to_s
|
6
|
+
@names = ([@name] + aliases.map{|n| n.to_s }).sort
|
7
|
+
|
8
|
+
@conversion_amount, @conversion_unit = parse_value(value) if value
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :name, :names, :conversion_amount, :conversion_unit
|
12
|
+
|
13
|
+
def to_s
|
14
|
+
if conversion_string
|
15
|
+
"#{ @name } (#{ conversion_string })"
|
16
|
+
else
|
17
|
+
@name
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def inspect
|
22
|
+
"#<Measured::Unit: #{ @name } (#{ @names.join(", ") }) #{ conversion_string }>"
|
23
|
+
end
|
24
|
+
|
25
|
+
def <=>(other)
|
26
|
+
if self.class == other.class
|
27
|
+
if other.names != @names
|
28
|
+
other.names <=> @names
|
29
|
+
else
|
30
|
+
other.conversion_amount <=> @conversion_amount
|
31
|
+
end
|
32
|
+
else
|
33
|
+
@name <=> other
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def inverse_conversion_amount
|
38
|
+
if conversion_amount.is_a?(Rational)
|
39
|
+
Rational(conversion_amount.denominator, conversion_amount.numerator)
|
40
|
+
else
|
41
|
+
BigDecimal(1) / conversion_amount
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def conversion_string
|
48
|
+
"#{ conversion_amount } #{ conversion_unit }" if @conversion_amount || @conversion_unit
|
49
|
+
end
|
50
|
+
|
51
|
+
def parse_value(tokens)
|
52
|
+
tokens = tokens.split(" ") if tokens.is_a?(String)
|
53
|
+
raise Measured::UnitError, "Cannot parse 'number unit' or [number, unit] formatted tokens from #{ tokens }." unless tokens.size == 2
|
54
|
+
|
55
|
+
tokens[0] = BigDecimal(tokens[0]) unless tokens[0].is_a?(BigDecimal) || tokens[0].is_a?(Rational)
|
56
|
+
|
57
|
+
tokens
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class Measured::Length < Measured::Measurable
|
2
|
+
|
3
|
+
conversion.set_base :m,
|
4
|
+
aliases: [:meter, :metre, :meters, :metres]
|
5
|
+
|
6
|
+
conversion.add :cm,
|
7
|
+
aliases: [:centimeter, :centimetre, :centimeters, :centimetres],
|
8
|
+
value: "0.01 m"
|
9
|
+
|
10
|
+
conversion.add :mm,
|
11
|
+
aliases: [:millimeter, :millimetre, :millimeters, :millimetres],
|
12
|
+
value: "0.001 m"
|
13
|
+
|
14
|
+
conversion.add :in,
|
15
|
+
aliases: [:inch, :inches],
|
16
|
+
value: "0.0254 m"
|
17
|
+
|
18
|
+
conversion.add :ft,
|
19
|
+
aliases: [:foot, :feet],
|
20
|
+
value: "0.3048 m"
|
21
|
+
|
22
|
+
conversion.add :yd,
|
23
|
+
aliases: [:yard, :yards],
|
24
|
+
value: "0.9144 m"
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class Measured::Weight < Measured::Measurable
|
2
|
+
|
3
|
+
conversion.set_base :g,
|
4
|
+
aliases: [:gram, :grams]
|
5
|
+
|
6
|
+
conversion.add :kg,
|
7
|
+
aliases: [:kilogram, :kilograms],
|
8
|
+
value: "1000 g"
|
9
|
+
|
10
|
+
conversion.add :lb,
|
11
|
+
aliases: [:lbs, :pound, :pounds],
|
12
|
+
value: [Rational(45359237,1e8), "kg"]
|
13
|
+
|
14
|
+
conversion.add :oz,
|
15
|
+
aliases: [:ounce, :ounces],
|
16
|
+
value: [Rational(1,16), "lb"]
|
17
|
+
|
18
|
+
end
|
data/lib/measured.rb
ADDED
data/measured.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'measured/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "measured"
|
8
|
+
spec.version = Measured::VERSION
|
9
|
+
spec.authors = ["Kevin McPhillips"]
|
10
|
+
spec.email = ["github@kevinmcphillips.ca"]
|
11
|
+
spec.summary = %q{Encapsulate measurements with their units in Ruby}
|
12
|
+
spec.description = %q{Wrapper objects which encapsulate measurments and their associated units in Ruby.}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_runtime_dependency "activesupport", ">= 4.0"
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
24
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
25
|
+
spec.add_development_dependency "minitest", "~> 5.5.1"
|
26
|
+
spec.add_development_dependency "mocha", "~> 1.1.0"
|
27
|
+
spec.add_development_dependency "pry"
|
28
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class Measured::ArithmeticTest < ActiveSupport::TestCase
|
4
|
+
setup do
|
5
|
+
@two = Magic.new(2, :magic_missile)
|
6
|
+
@three = Magic.new(3, :magic_missile)
|
7
|
+
@four = Magic.new(4, :magic_missile)
|
8
|
+
end
|
9
|
+
|
10
|
+
test "#+ should add together same units" do
|
11
|
+
assert_equal Magic.new(5, :magic_missile), @two + @three
|
12
|
+
assert_equal Magic.new(5, :magic_missile), @three + @two
|
13
|
+
end
|
14
|
+
|
15
|
+
test "#+ should add a number to the value" do
|
16
|
+
assert_equal Magic.new(5, :magic_missile), @two + 3
|
17
|
+
assert_equal Magic.new(5, :magic_missile), 2 + @three
|
18
|
+
end
|
19
|
+
|
20
|
+
test "#+ should raise if different unit system" do
|
21
|
+
assert_raises TypeError do
|
22
|
+
OtherFakeSystem.new(1, :other_fake_base) + @two
|
23
|
+
end
|
24
|
+
|
25
|
+
assert_raises TypeError do
|
26
|
+
@two + OtherFakeSystem.new(1, :other_fake_base)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
test "#+ should raise if adding something nonsense" do
|
31
|
+
assert_raises TypeError do
|
32
|
+
@two + "thing"
|
33
|
+
end
|
34
|
+
|
35
|
+
assert_raises TypeError do
|
36
|
+
"thing" + @two
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
test "#- should subtract same units" do
|
41
|
+
assert_equal Magic.new(-1, :magic_missile), @two - @three
|
42
|
+
assert_equal Magic.new(1, :magic_missile), @three - @two
|
43
|
+
end
|
44
|
+
|
45
|
+
test "#- should subtract a number from the value" do
|
46
|
+
assert_equal Magic.new(-1, :magic_missile), @two - 3
|
47
|
+
assert_equal Magic.new(1, :magic_missile), 2 - @three
|
48
|
+
end
|
49
|
+
|
50
|
+
test "#- should raise if different unit system" do
|
51
|
+
assert_raises TypeError do
|
52
|
+
OtherFakeSystem.new(1, :other_fake_base) - @two
|
53
|
+
end
|
54
|
+
|
55
|
+
assert_raises TypeError do
|
56
|
+
@two - OtherFakeSystem.new(1, :other_fake_base)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
test "#- should raise if subtracting something nonsense" do
|
61
|
+
assert_raises TypeError do
|
62
|
+
@two - "thing"
|
63
|
+
end
|
64
|
+
|
65
|
+
assert_raises NoMethodError do
|
66
|
+
"thing" - @two
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
test "#* should multiply together same units" do
|
71
|
+
assert_equal Magic.new(6, :magic_missile), @two * @three
|
72
|
+
assert_equal Magic.new(6, :magic_missile), @three * @two
|
73
|
+
end
|
74
|
+
|
75
|
+
test "#* should multiply a number to the value" do
|
76
|
+
assert_equal Magic.new(6, :magic_missile), @two * 3
|
77
|
+
assert_equal Magic.new(6, :magic_missile), 2 * @three
|
78
|
+
end
|
79
|
+
|
80
|
+
test "#* should raise if different unit system" do
|
81
|
+
assert_raises TypeError do
|
82
|
+
OtherFakeSystem.new(1, :other_fake_base) * @two
|
83
|
+
end
|
84
|
+
|
85
|
+
assert_raises TypeError do
|
86
|
+
@two * OtherFakeSystem.new(1, :other_fake_base)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
test "#* should raise if multiplying something nonsense" do
|
91
|
+
assert_raises TypeError do
|
92
|
+
@two * "thing"
|
93
|
+
end
|
94
|
+
|
95
|
+
assert_raises TypeError do
|
96
|
+
"thing" * @two
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
test "#/ should divide together same units" do
|
101
|
+
assert_equal Magic.new("0.5", :magic_missile), @two / @four
|
102
|
+
assert_equal Magic.new(2, :magic_missile), @four / @two
|
103
|
+
end
|
104
|
+
|
105
|
+
test "#/ should divide a number to the value" do
|
106
|
+
assert_equal Magic.new("0.5", :magic_missile), @two / 4
|
107
|
+
assert_equal Magic.new(2, :magic_missile), 2 / @four
|
108
|
+
end
|
109
|
+
|
110
|
+
test "#/ should raise if different unit system" do
|
111
|
+
assert_raises TypeError do
|
112
|
+
OtherFakeSystem.new(1, :other_fake_base) / @two
|
113
|
+
end
|
114
|
+
|
115
|
+
assert_raises TypeError do
|
116
|
+
@two / OtherFakeSystem.new(1, :other_fake_base)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
test "#/ should raise if dividing something nonsense" do
|
121
|
+
assert_raises TypeError do
|
122
|
+
@two / "thing"
|
123
|
+
end
|
124
|
+
|
125
|
+
assert_raises NoMethodError do
|
126
|
+
"thing" / @two
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
test "#-@ returns the negative version" do
|
131
|
+
assert_equal Magic.new(-2, :magic_missile), -@two
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class Measured::ConversionTableTest < ActiveSupport::TestCase
|
4
|
+
setup do
|
5
|
+
@unit = Measured::Unit.new(:test)
|
6
|
+
end
|
7
|
+
|
8
|
+
test "#initialize accepts a list of units and a base unit" do
|
9
|
+
Measured::ConversionTable.new([@unit])
|
10
|
+
end
|
11
|
+
|
12
|
+
test "#to_h should return a hash for the simple case" do
|
13
|
+
expected = {
|
14
|
+
"test" => {"test" => BigDecimal("1")}
|
15
|
+
}
|
16
|
+
|
17
|
+
assert_equal expected, Measured::ConversionTable.new([@unit]).to_h
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,206 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class Measured::ConversionTest < ActiveSupport::TestCase
|
4
|
+
setup do
|
5
|
+
@conversion = Measured::Conversion.new
|
6
|
+
end
|
7
|
+
|
8
|
+
test "#base sets the base unit" do
|
9
|
+
@conversion.set_base :m, aliases: [:metre]
|
10
|
+
assert_equal ["m", "metre"], @conversion.base_unit.names
|
11
|
+
end
|
12
|
+
|
13
|
+
test "#base doesn't allow a second base to be added" do
|
14
|
+
@conversion.set_base :m, aliases: [:metre]
|
15
|
+
|
16
|
+
assert_raises Measured::UnitError do
|
17
|
+
@conversion.set_base :in
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
test "#add adds a new unit" do
|
22
|
+
@conversion.set_base :m
|
23
|
+
@conversion.add :in, aliases: [:inch], value: "0.0254 meter"
|
24
|
+
|
25
|
+
assert_equal 2, @conversion.units.count
|
26
|
+
end
|
27
|
+
|
28
|
+
test "#add cannot add duplicate unit names" do
|
29
|
+
@conversion.set_base :m
|
30
|
+
@conversion.add :in, aliases: [:inch], value: "0.0254 meter"
|
31
|
+
|
32
|
+
assert_raises Measured::UnitError do
|
33
|
+
@conversion.add :in, aliases: [:thing], value: "123 m"
|
34
|
+
end
|
35
|
+
|
36
|
+
assert_raises Measured::UnitError do
|
37
|
+
@conversion.add :inch, value: "123 m"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
test "#add does not allow you to add a unit before the base" do
|
42
|
+
assert_raises Measured::UnitError do
|
43
|
+
@conversion.add :in, aliases: [:inch], value: "0.0254 meter"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
test "#unit_names_with_aliases lists all allowed unit names" do
|
48
|
+
@conversion.set_base :m
|
49
|
+
@conversion.add :in, aliases: [:inch], value: "0.0254 meter"
|
50
|
+
@conversion.add :ft, aliases: [:feet, :foot], value: "0.3048 meter"
|
51
|
+
|
52
|
+
assert_equal ["feet", "foot", "ft", "in", "inch", "m"], @conversion.unit_names_with_aliases
|
53
|
+
end
|
54
|
+
|
55
|
+
test "#unit_names lists all base unit names without aliases" do
|
56
|
+
@conversion.set_base :m
|
57
|
+
@conversion.add :in, aliases: [:inch], value: "0.0254 meter"
|
58
|
+
@conversion.add :ft, aliases: [:feet, :foot], value: "0.3048 meter"
|
59
|
+
|
60
|
+
assert_equal ["ft", "in", "m"], @conversion.unit_names
|
61
|
+
end
|
62
|
+
|
63
|
+
test "#unit? checks if the unit is part of the units and aliases" do
|
64
|
+
@conversion.set_base :m
|
65
|
+
@conversion.add :inch, aliases: [:in], value: "0.0254 meter"
|
66
|
+
|
67
|
+
assert @conversion.unit?(:inch)
|
68
|
+
assert @conversion.unit?("m")
|
69
|
+
refute @conversion.unit?("in")
|
70
|
+
refute @conversion.unit?(:yard)
|
71
|
+
end
|
72
|
+
|
73
|
+
test "#unit_or_alias? checks if the unit is part of the units but not aliases" do
|
74
|
+
@conversion.set_base :m
|
75
|
+
@conversion.add :inch, aliases: [:in], value: "0.0254 meter"
|
76
|
+
|
77
|
+
assert @conversion.unit_or_alias?(:inch)
|
78
|
+
assert @conversion.unit_or_alias?("m")
|
79
|
+
assert @conversion.unit_or_alias?("in")
|
80
|
+
refute @conversion.unit_or_alias?(:yard)
|
81
|
+
end
|
82
|
+
|
83
|
+
test "#to_unit_name converts a unit name to its base unit" do
|
84
|
+
assert_equal "fireball", Magic.conversion.to_unit_name("fire")
|
85
|
+
end
|
86
|
+
|
87
|
+
test "#to_unit_name does not care about string or symbol" do
|
88
|
+
assert_equal "fireball", Magic.conversion.to_unit_name(:fire)
|
89
|
+
end
|
90
|
+
|
91
|
+
test "#to_unit_name passes through if already base unit name" do
|
92
|
+
assert_equal "fireball", Magic.conversion.to_unit_name("fireball")
|
93
|
+
end
|
94
|
+
|
95
|
+
test "#to_unit_name raises if not found" do
|
96
|
+
assert_raises Measured::UnitError do
|
97
|
+
Magic.conversion.to_unit_name("thunder")
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
test "#convert raises if either unit is not found" do
|
102
|
+
assert_raises Measured::UnitError do
|
103
|
+
Magic.conversion.convert(1, from: "fire", to: "doesnt_exist")
|
104
|
+
end
|
105
|
+
|
106
|
+
assert_raises Measured::UnitError do
|
107
|
+
Magic.conversion.convert(1, from: "doesnt_exist", to: "fire")
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
test "#convert converts betwen two known units" do
|
112
|
+
@conversion.set_base :m
|
113
|
+
@conversion.add :cm, value: "0.01 m"
|
114
|
+
|
115
|
+
assert_equal BigDecimal("10"), @conversion.convert(BigDecimal("1000"), from: "cm", to: "m")
|
116
|
+
assert_equal BigDecimal("250"), @conversion.convert(BigDecimal("2.5"), from: "m", to: "cm")
|
117
|
+
end
|
118
|
+
|
119
|
+
test "#convert handles the same unit" do
|
120
|
+
@conversion.set_base :m
|
121
|
+
@conversion.add :cm, value: "0.01 m"
|
122
|
+
|
123
|
+
assert_equal BigDecimal("2"), @conversion.convert(BigDecimal("2"), from: "cm", to: "cm")
|
124
|
+
end
|
125
|
+
|
126
|
+
test "#conversion_table returns expected nested hashes with BigDecimal conversion factors in a tiny data set" do
|
127
|
+
@conversion.set_base :m
|
128
|
+
@conversion.add :cm, value: "0.01 m"
|
129
|
+
|
130
|
+
expected = {
|
131
|
+
"m" => {
|
132
|
+
"m" => BigDecimal("1"),
|
133
|
+
"cm" => BigDecimal("100")
|
134
|
+
},
|
135
|
+
"cm" => {
|
136
|
+
"cm" => BigDecimal("1"),
|
137
|
+
"m" => BigDecimal("0.01")
|
138
|
+
}
|
139
|
+
}
|
140
|
+
|
141
|
+
assert_equal expected, @conversion.conversion_table
|
142
|
+
end
|
143
|
+
|
144
|
+
test "#conversion_table returns expected nested hashes with BigDecimal conversion factors" do
|
145
|
+
@conversion.set_base :m
|
146
|
+
@conversion.add :cm, value: "0.01 m"
|
147
|
+
@conversion.add :mm, value: "0.001 m"
|
148
|
+
|
149
|
+
expected = {
|
150
|
+
"m" => {
|
151
|
+
"m" => BigDecimal("1"),
|
152
|
+
"cm" => BigDecimal("100"),
|
153
|
+
"mm" => BigDecimal("1000")
|
154
|
+
},
|
155
|
+
"cm" => {
|
156
|
+
"cm" => BigDecimal("1"),
|
157
|
+
"m" => BigDecimal("0.01"),
|
158
|
+
"mm" => BigDecimal("10")
|
159
|
+
},
|
160
|
+
"mm" => {
|
161
|
+
"mm" => BigDecimal("1"),
|
162
|
+
"m" => BigDecimal("0.001"),
|
163
|
+
"cm" => BigDecimal("0.1")
|
164
|
+
}
|
165
|
+
}
|
166
|
+
|
167
|
+
assert_equal expected, @conversion.conversion_table
|
168
|
+
end
|
169
|
+
|
170
|
+
test "#conversion_table returns expected nested hashes with BigDecimal conversion factors in an indrect path" do
|
171
|
+
@conversion.set_base :mm
|
172
|
+
@conversion.add :cm, value: "10 mm"
|
173
|
+
@conversion.add :dm, value: "10 cm"
|
174
|
+
@conversion.add :m, value: "10 dm"
|
175
|
+
|
176
|
+
expected = {
|
177
|
+
"m" => {
|
178
|
+
"m" => BigDecimal("1"),
|
179
|
+
"cm" => BigDecimal("100"),
|
180
|
+
"dm" => BigDecimal("10"),
|
181
|
+
"mm" => BigDecimal("1000")
|
182
|
+
},
|
183
|
+
"cm" => {
|
184
|
+
"cm" => BigDecimal("1"),
|
185
|
+
"dm" => BigDecimal("0.1"),
|
186
|
+
"m" => BigDecimal("0.01"),
|
187
|
+
"mm" => BigDecimal("10")
|
188
|
+
},
|
189
|
+
"dm" => {
|
190
|
+
"dm" => BigDecimal("1"),
|
191
|
+
"cm" => BigDecimal("10"),
|
192
|
+
"m" => BigDecimal("0.1"),
|
193
|
+
"mm" => BigDecimal("100")
|
194
|
+
},
|
195
|
+
"mm" => {
|
196
|
+
"mm" => BigDecimal("1"),
|
197
|
+
"m" => BigDecimal("0.001"),
|
198
|
+
"dm" => BigDecimal("0.01"),
|
199
|
+
"cm" => BigDecimal("0.1")
|
200
|
+
}
|
201
|
+
}
|
202
|
+
|
203
|
+
assert_equal expected, @conversion.conversion_table
|
204
|
+
end
|
205
|
+
|
206
|
+
end
|