measured 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|