measured 1.6.0 → 2.0.0.pre1

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.
@@ -1,46 +1,20 @@
1
- class Magic < Measured::Measurable
2
-
3
- conversion.set_base :magic_missile,
4
- aliases: [:magic_missiles]
5
-
6
- conversion.add :fireball,
7
- aliases: [:fire, :fireballs],
8
- value: "2/3 magic_missile"
9
-
10
- conversion.add :ice,
11
- value: "2 magic_missile"
12
-
13
- conversion.add :arcane,
14
- value: "10 magic_missile"
15
-
16
- conversion.add :ultima,
17
- value: "10 arcane"
18
-
1
+ Magic = Measured.build do
2
+ unit :magic_missile, aliases: [:magic_missiles]
3
+ unit :fireball, value: "2/3 magic_missile", aliases: [:fire, :fireballs]
4
+ unit :ice, value: "2 magic_missile"
5
+ unit :arcane, value: "10 magic_missile"
6
+ unit :ultima, value: "10 arcane"
19
7
  end
20
8
 
21
- class CaseSensitiveMagic < Measured::CaseSensitiveMeasurable
22
-
23
- conversion.set_base :magic_missile,
24
- aliases: [:magic_missiles]
25
-
26
- conversion.add :fireball,
27
- aliases: [:fire, :fireballs],
28
- value: "2/3 magic_missile"
29
-
30
- conversion.add :ice,
31
- value: "2 magic_missile"
32
-
33
- conversion.add :arcane,
34
- value: "10 magic_missile"
35
-
36
- conversion.add :ultima,
37
- value: "10 arcane"
38
-
9
+ CaseSensitiveMagic = Measured.build(case_sensitive: true) do
10
+ unit :magic_missile, aliases: [:magic_missiles]
11
+ unit :fireball, value: "2/3 magic_missile", aliases: [:fire, :fireballs]
12
+ unit :ice, value: "2 magic_missile"
13
+ unit :arcane, value: "10 magic_missile"
14
+ unit :ultima, value: "10 arcane"
39
15
  end
40
16
 
41
- class OtherFakeSystem < Measured::Measurable
42
-
43
- conversion.set_base :other_fake_base
44
- conversion.add :other_fake1, value: "2 other_fake_base"
45
-
17
+ OtherFakeSystem = Measured.build do
18
+ unit :other_fake_base
19
+ unit :other_fake1, value: "2 other_fake_base"
46
20
  end
data/test/test_helper.rb CHANGED
@@ -32,4 +32,9 @@ class ActiveSupport::TestCase
32
32
 
33
33
  assert_equal BigDecimal(to_amount), klass.new(from_amount, from_unit).convert_to(to_unit).value
34
34
  end
35
+
36
+ def assert_raises_with_message(exception, expected_message)
37
+ error = assert_raise(exception) { yield }
38
+ assert_equal expected_message, error.message, "Exception #{exception} raised but messages are not equal"
39
+ end
35
40
  end
@@ -0,0 +1,58 @@
1
+ require "test_helper"
2
+
3
+ class Measured::UnitSystemBuilderTest < ActiveSupport::TestCase
4
+ test "#unit adds a new unit" do
5
+ measurable = Measured.build do
6
+ unit :m
7
+ unit :in, aliases: [:inch], value: "0.0254 m"
8
+ end
9
+
10
+ assert_equal 2, measurable.unit_names.count
11
+ end
12
+
13
+ test "#unit cannot add duplicate unit names" do
14
+ assert_raises Measured::UnitError do
15
+ Measured.build do
16
+ unit :m
17
+ unit :in, aliases: [:inch], value: "0.0254 m"
18
+ unit :in, aliases: [:thing], value: "123 m"
19
+ end
20
+ end
21
+
22
+ assert_raises Measured::UnitError do
23
+ Measured.build(case_sensitive: true) do
24
+ unit :m
25
+ unit :in, aliases: [:inch], value: "0.0254 m"
26
+ unit :inch, aliases: [:thing], value: "123 m"
27
+ end
28
+ end
29
+
30
+ assert_raises Measured::UnitError do
31
+ Measured.build(case_sensitive: false) do
32
+ unit :normal
33
+ unit :bold, aliases: [:strong], value: "10 normal"
34
+ unit :bolder, aliases: [:BOLD], value: "100 normal"
35
+ end
36
+ end
37
+ end
38
+
39
+ test "#case_sensitive true produces a case-sensitive conversion" do
40
+ measurable = Measured.build(case_sensitive: true) do
41
+ unit :normal
42
+ unit :bold, value: "10 normal"
43
+ unit :BOLD, value: "100 normal"
44
+ end
45
+
46
+ assert_equal 2, measurable.new(200, :normal).convert_to(:BOLD).value
47
+ end
48
+
49
+ test "case-insensitive conversion is produced by default" do
50
+ measurable = Measured.build(case_sensitive: false) do
51
+ unit :normal
52
+ unit :bold, value: "10 normal"
53
+ unit :bolder, value: "100 normal"
54
+ end
55
+
56
+ assert_equal 20, measurable.new(200, :normal).convert_to(:bOlD).value
57
+ end
58
+ end
@@ -0,0 +1,99 @@
1
+ require "test_helper"
2
+
3
+ class Measured::UnitSystemTest < ActiveSupport::TestCase
4
+ setup do
5
+ @conversion = Measured::UnitSystem.new([
6
+ Measured::Unit.new(:m),
7
+ Measured::Unit.new(:in, aliases: [:Inch], value: "0.0254 m"),
8
+ Measured::Unit.new(:ft, aliases: [:Feet, :Foot], value: "0.3048 m"),
9
+ ])
10
+ end
11
+
12
+ test "#unit_names_with_aliases lists all allowed unit names" do
13
+ assert_equal ["Feet", "Foot", "Inch", "ft", "in", "m"], @conversion.unit_names_with_aliases
14
+ end
15
+
16
+ test "#unit_names lists all unit names without aliases" do
17
+ assert_equal ["ft", "in", "m"], @conversion.unit_names
18
+ end
19
+
20
+ test "#unit? checks if the unit is part of the units but not aliases" do
21
+ assert @conversion.unit?(:in)
22
+ assert @conversion.unit?("m")
23
+ refute @conversion.unit?("M")
24
+ refute @conversion.unit?("inch")
25
+ refute @conversion.unit?(:yard)
26
+ end
27
+
28
+ test "#unit? with blank and nil arguments" do
29
+ refute @conversion.unit?("")
30
+ refute @conversion.unit?(nil)
31
+ end
32
+
33
+ test "#unit_or_alias? checks if the unit is part of the units or aliases" do
34
+ assert @conversion.unit_or_alias?(:Inch)
35
+ assert @conversion.unit_or_alias?("m")
36
+ assert @conversion.unit_or_alias?("in")
37
+ refute @conversion.unit_or_alias?(:inch)
38
+ refute @conversion.unit_or_alias?(:IN)
39
+ refute @conversion.unit_or_alias?(:yard)
40
+ end
41
+
42
+ test "#unit_or_alias? with blank and nil arguments" do
43
+ refute @conversion.unit_or_alias?("")
44
+ refute @conversion.unit_or_alias?(nil)
45
+ end
46
+
47
+ test "#to_unit_name converts a unit name to its base unit" do
48
+ assert_equal "fireball", CaseSensitiveMagic.unit_system.to_unit_name("fire")
49
+ end
50
+
51
+ test "#to_unit_name does not care about string or symbol" do
52
+ assert_equal "fireball", CaseSensitiveMagic.unit_system.to_unit_name(:fire)
53
+ end
54
+
55
+ test "#to_unit_name passes through if already base unit name" do
56
+ assert_equal "fireball", CaseSensitiveMagic.unit_system.to_unit_name("fireball")
57
+ end
58
+
59
+ test "#to_unit_name returns nil if not found" do
60
+ assert_nil CaseSensitiveMagic.unit_system.to_unit_name("thunder")
61
+ end
62
+
63
+ test "#to_unit_name! converts a unit name to its base unit" do
64
+ assert_equal "fireball", CaseSensitiveMagic.unit_system.to_unit_name!("fire")
65
+ end
66
+
67
+ test "#to_unit_name! does not care about string or symbol" do
68
+ assert_equal "fireball", CaseSensitiveMagic.unit_system.to_unit_name!(:fire)
69
+ end
70
+
71
+ test "#to_unit_name! passes through if already base unit name" do
72
+ assert_equal "fireball", CaseSensitiveMagic.unit_system.to_unit_name!("fireball")
73
+ end
74
+
75
+ test "#to_unit_name! raises if not found" do
76
+ assert_raises_with_message(Measured::UnitError, "Unit 'thunder' does not exist") do
77
+ CaseSensitiveMagic.unit_system.to_unit_name!("thunder")
78
+ end
79
+ end
80
+
81
+ test "#convert raises if either unit is not found" do
82
+ assert_raises Measured::UnitError do
83
+ CaseSensitiveMagic.unit_system.convert(1, from: "fire", to: "doesnt_exist")
84
+ end
85
+
86
+ assert_raises Measured::UnitError do
87
+ CaseSensitiveMagic.unit_system.convert(1, from: "doesnt_exist", to: "fire")
88
+ end
89
+ end
90
+
91
+ test "#convert converts between two known units" do
92
+ assert_equal BigDecimal("3"), @conversion.convert(BigDecimal("36"), from: "in", to: "ft")
93
+ assert_equal BigDecimal("18"), @conversion.convert(BigDecimal("1.5"), from: "ft", to: "in")
94
+ end
95
+
96
+ test "#convert handles the same unit" do
97
+ assert_equal BigDecimal("2"), @conversion.convert(BigDecimal("2"), from: "in", to: "in")
98
+ end
99
+ end
data/test/unit_test.rb CHANGED
@@ -2,84 +2,21 @@ require "test_helper"
2
2
 
3
3
  class Measured::UnitTest < ActiveSupport::TestCase
4
4
  setup do
5
- @unit = Measured::Unit.new(:pie, value: "10 cake")
5
+ @unit = Measured::Unit.new(:Pie, value: "10 Cake")
6
+ @unit_with_aliases = Measured::Unit.new(:Pie, aliases: ["Cake", "Tart"])
6
7
  end
7
8
 
8
9
  test "#initialize converts the name to a string" do
9
- assert_equal "pie", @unit.name
10
+ assert_equal "Pie", @unit.name
10
11
  end
11
12
 
12
- test "#initialize converts aliases to strings and makes a list of names which includes the base" do
13
- assert_equal ["cake", "pie", "sweets"], Measured::Unit.new(:pie, aliases: ["cake", :sweets]).names
14
- end
15
-
16
- test "#name_eql?" do
17
- assert @unit.name_eql?("pIe")
18
- refute @unit.name_eql?("pastry")
19
- end
20
-
21
- test "#name_eql? with case_sensitive true" do
22
- assert @unit.name_eql?("pie", case_sensitive: true)
23
- refute @unit.name_eql?("Pie", case_sensitive: true)
24
- end
25
-
26
- test "#name_eql? with empty string" do
27
- assert @unit.name_eql?("pie")
28
- refute @unit.name_eql?("")
29
- end
30
-
31
- test "#names_include?" do
32
- unit = Measured::Unit.new(:pie, aliases:["cake", "tart"])
33
- assert unit.names_include?("pie")
34
- assert unit.names_include?("caKe")
35
- assert unit.names_include?("taRt")
36
- refute unit.names_include?("pastry")
37
- end
38
-
39
- test "#names_include? with case_sensitive true" do
40
- unit = Measured::Unit.new(:pie, aliases:["cake", "tart"])
41
- assert unit.names_include?("pie", case_sensitive: true)
42
- assert unit.names_include?("cake", case_sensitive: true)
43
- refute unit.names_include?("TART", case_sensitive: true)
44
- end
45
-
46
- test "#names_include? with empty string" do
47
- unit = Measured::Unit.new(:pie, aliases: ["cake", "tart"])
48
- assert unit.names_include?("cake")
49
- refute unit.names_include?("")
50
- end
51
-
52
- test "#add_alias with string" do
53
- unit = Measured::Unit.new(:pie, aliases: ["cake"], value: "10 cake")
54
- assert_equal ["cake", "pie"], unit.names
55
- unit.add_alias("pastry")
56
- assert_equal ["cake", "pastry", "pie"], unit.names
57
- end
58
-
59
- test "#add_alias with array" do
60
- unit = Measured::Unit.new(:pie, aliases: ["cake"], value: "10 cake")
61
- assert_equal ["cake", "pie"], unit.names
62
- unit.add_alias(["pastry", "tart", "turnover"])
63
- assert_equal ["cake", "pastry", "pie", "tart", "turnover"], unit.names
64
- end
65
-
66
- test "#add_alias with nil" do
67
- unit = Measured::Unit.new(:pie, aliases: ["cake"], value: "10 cake")
68
- assert_equal ["cake", "pie"], unit.names
69
- unit.add_alias(nil)
70
- assert_equal ["cake", "pie"], unit.names
71
- end
72
-
73
- test "#add_alias with empty string" do
74
- unit = Measured::Unit.new(:pie, aliases: ["cake"], value: "10 cake")
75
- assert_equal ["cake", "pie"], unit.names
76
- unit.add_alias("")
77
- assert_equal ["cake", "pie"], unit.names
13
+ test "#initialize converts aliases to strings and makes a list of sorted names" do
14
+ assert_equal %w(Cake pie sweets), Measured::Unit.new(:pie, aliases: ["Cake", :sweets]).names
78
15
  end
79
16
 
80
17
  test "#initialize parses out the unit and the number part" do
81
18
  assert_equal BigDecimal(10), @unit.conversion_amount
82
- assert_equal "cake", @unit.conversion_unit
19
+ assert_equal "Cake", @unit.conversion_unit
83
20
 
84
21
  unit = Measured::Unit.new(:pie, value: "5.5 sweets")
85
22
  assert_equal BigDecimal("5.5"), unit.conversion_amount
@@ -100,7 +37,7 @@ class Measured::UnitTest < ActiveSupport::TestCase
100
37
  end
101
38
  end
102
39
 
103
- test "#to_s" do
40
+ test "#to_s returns an expected string" do
104
41
  assert_equal "pie", Measured::Unit.new(:pie).to_s
105
42
  assert_equal "pie (1/2 sweet)", Measured::Unit.new(:pie, aliases: ["cake"], value: [Rational(1,2), "sweet"]).to_s
106
43
  end
@@ -110,28 +47,29 @@ class Measured::UnitTest < ActiveSupport::TestCase
110
47
  assert_equal "#<Measured::Unit: pie (cake, pie) 1/2 sweet>", Measured::Unit.new(:pie, aliases: ["cake"], value: [Rational(1,2), "sweet"]).inspect
111
48
  end
112
49
 
113
- test "is comparable" do
50
+ test "includes Comparable mixin" do
114
51
  assert Measured::Unit.ancestors.include?(Comparable)
115
52
  end
116
53
 
117
- test "#<=> delegates down to name for non Unit comparisons" do
118
- assert_equal 1, @unit <=> "anything"
54
+ test "#<=> compares non-Unit classes against name" do
55
+ assert_equal 1, @unit <=> "Pap"
56
+ assert_equal -1, @unit <=> "Pop"
119
57
  end
120
58
 
121
- test "#<=> is equal for same values" do
122
- assert_equal 0, @unit <=> Measured::Unit.new(:pie, value: "10 cake")
123
- assert_equal 0, @unit <=> Measured::Unit.new("pie", value: "10 cake")
124
- assert_equal 0, @unit <=> Measured::Unit.new("pie", value: [10, :cake])
59
+ test "#<=> is 0 for Unit instances that should be equivalent" do
60
+ assert_equal 0, @unit <=> Measured::Unit.new(:Pie, value: "10 cake")
61
+ assert_equal 0, @unit <=> Measured::Unit.new("Pie", value: "10 cake")
62
+ assert_equal 0, @unit <=> Measured::Unit.new("Pie", value: [10, :cake])
125
63
  end
126
64
 
127
- test "#<=> is slightly different" do
128
- assert_equal 1, @unit <=> Measured::Unit.new(:pies, value: "10 cake")
129
- assert_equal 1, @unit <=> Measured::Unit.new("pie", aliases: ["pies"], value: "10 cake")
130
- assert_equal 1, @unit <=> Measured::Unit.new(:pie, value: [11, :cake])
65
+ test "#<=> is 1 for units with names that come after Pie lexicographically" do
66
+ assert_equal 1, @unit <=> Measured::Unit.new(:Pigs, value: "10 bacon")
67
+ assert_equal 1, @unit <=> Measured::Unit.new("Pig", aliases: %w(Pigs), value: "10 bacon")
68
+ assert_equal 1, @unit <=> Measured::Unit.new(:Pig, value: [11, :bacon])
131
69
  end
132
70
 
133
71
  test "#inverse_conversion_amount returns 1/amount for BigDecimal" do
134
- assert_equal BigDecimal(1)/BigDecimal(10), @unit.inverse_conversion_amount
72
+ assert_equal BigDecimal(1) / 10, @unit.inverse_conversion_amount
135
73
  end
136
74
 
137
75
  test "#inverse_conversion_amount swaps the numerator and denominator for Rational" do
@@ -1,12 +1,19 @@
1
1
  require "test_helper"
2
2
 
3
3
  class Measured::LengthTest < ActiveSupport::TestCase
4
- test ".units_with_aliases should be the expected list of valid units" do
5
- assert_equal ["centimeter", "centimeters", "centimetre", "centimetres", "cm", "feet", "foot", "ft", "in", "inch", "inches", "m", "meter", "meters", "metre", "metres", "millimeter", "millimeters", "millimetre", "millimetres", "mm", "yard", "yards", "yd"], Measured::Length.units_with_aliases
6
- end
7
-
8
- test ".units should be the list of base units" do
9
- assert_equal ["cm", "ft", "in", "m", "mm", "yd"], Measured::Length.units
4
+ test ".unit_names_with_aliases should be the expected list of valid units" do
5
+ assert_equal(
6
+ %w(
7
+ centimeter centimeters centimetre centimetres cm feet foot ft
8
+ in inch inches m meter meters metre metres millimeter
9
+ millimeters millimetre millimetres mm yard yards yd
10
+ ),
11
+ Measured::Length.unit_names_with_aliases
12
+ )
13
+ end
14
+
15
+ test ".unit_names should be the list of base unit names" do
16
+ assert_equal %w(cm ft in m mm yd), Measured::Length.unit_names
10
17
  end
11
18
 
12
19
  test ".name" do
@@ -5,12 +5,15 @@ class Measured::WeightTest < ActiveSupport::TestCase
5
5
  @weight = Measured::Weight.new(1, "g")
6
6
  end
7
7
 
8
- test ".units_with_aliases should be the expected list of valid units" do
9
- assert_equal ["g", "gram", "grams", "kg", "kilogram", "kilograms", "lb", "lbs", "ounce", "ounces", "oz", "pound", "pounds"], Measured::Weight.units_with_aliases
8
+ 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
12
+ )
10
13
  end
11
14
 
12
- test ".units should be the list of base units" do
13
- assert_equal ["g", "kg", "lb", "oz"], Measured::Weight.units
15
+ test ".unit_names should be the list of base unit names" do
16
+ assert_equal %w(g kg lb oz), Measured::Weight.unit_names
14
17
  end
15
18
 
16
19
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: measured
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.0
4
+ version: 2.0.0.pre1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin McPhillips
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-28 00:00:00.000000000 Z
11
+ date: 2017-01-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '4.0'
19
+ version: '4.2'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '4.0'
26
+ version: '4.2'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -99,24 +99,28 @@ files:
99
99
  - lib/measured.rb
100
100
  - lib/measured/arithmetic.rb
101
101
  - lib/measured/base.rb
102
- - lib/measured/case_sensitive_measurable.rb
103
- - lib/measured/conversion.rb
102
+ - lib/measured/case_insensitive_unit.rb
103
+ - lib/measured/case_insensitive_unit_system.rb
104
104
  - lib/measured/conversion_table.rb
105
105
  - lib/measured/measurable.rb
106
106
  - lib/measured/unit.rb
107
+ - lib/measured/unit_system.rb
108
+ - lib/measured/unit_system_builder.rb
107
109
  - lib/measured/units/length.rb
108
110
  - lib/measured/units/weight.rb
109
111
  - lib/measured/version.rb
110
112
  - measured.gemspec
111
113
  - shipit.rubygems.yml
112
114
  - test/arithmetic_test.rb
113
- - test/case_sensitive_measurable_test.rb
115
+ - test/case_insensitive_unit_system_test.rb
116
+ - test/case_insensitive_unit_test.rb
114
117
  - test/conversion_table_test.rb
115
- - test/conversion_test.rb
116
118
  - test/measurable_test.rb
117
119
  - test/support/fake_system.rb
118
120
  - test/test_helper.rb
119
121
  - test/unit_error_test.rb
122
+ - test/unit_system_builder_test.rb
123
+ - test/unit_system_test.rb
120
124
  - test/unit_test.rb
121
125
  - test/units/length_test.rb
122
126
  - test/units/weight_test.rb
@@ -135,9 +139,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
135
139
  version: '0'
136
140
  required_rubygems_version: !ruby/object:Gem::Requirement
137
141
  requirements:
138
- - - ">="
142
+ - - ">"
139
143
  - !ruby/object:Gem::Version
140
- version: '0'
144
+ version: 1.3.1
141
145
  requirements: []
142
146
  rubyforge_project:
143
147
  rubygems_version: 2.5.1
@@ -146,13 +150,15 @@ specification_version: 4
146
150
  summary: Encapsulate measurements with their units in Ruby
147
151
  test_files:
148
152
  - test/arithmetic_test.rb
149
- - test/case_sensitive_measurable_test.rb
153
+ - test/case_insensitive_unit_system_test.rb
154
+ - test/case_insensitive_unit_test.rb
150
155
  - test/conversion_table_test.rb
151
- - test/conversion_test.rb
152
156
  - test/measurable_test.rb
153
157
  - test/support/fake_system.rb
154
158
  - test/test_helper.rb
155
159
  - test/unit_error_test.rb
160
+ - test/unit_system_builder_test.rb
161
+ - test/unit_system_test.rb
156
162
  - test/unit_test.rb
157
163
  - test/units/length_test.rb
158
164
  - test/units/weight_test.rb
@@ -1,7 +0,0 @@
1
- class Measured::CaseSensitiveMeasurable < Measured::Measurable
2
- class << self
3
- def conversion
4
- @conversion ||= Measured::Conversion.new(case_sensitive: true)
5
- end
6
- end
7
- end
@@ -1,95 +0,0 @@
1
- class Measured::Conversion
2
- ARBITRARY_CONVERSION_PRECISION = 20
3
- def initialize(case_sensitive: false)
4
- @base_unit = nil
5
- @units = []
6
- @case_sensitive = case_sensitive
7
- end
8
-
9
- attr_reader :base_unit, :units, :case_sensitive
10
-
11
- def set_base(unit_name, aliases: [])
12
- add_new_unit(unit_name, aliases: aliases, base: true)
13
- end
14
-
15
- def add(unit_name, aliases: [], value:)
16
- add_new_unit(unit_name, aliases: aliases, value: value)
17
- end
18
-
19
- def unit_names_with_aliases
20
- @units.map{|u| u.names}.flatten.sort
21
- end
22
-
23
- def unit_names
24
- @units.map{|u| u.name}.sort
25
- end
26
-
27
- def unit_or_alias?(name)
28
- @units.each{|unit| return true if unit.names_include?(name, case_sensitive: @case_sensitive)}
29
- false
30
- end
31
-
32
- def unit?(name)
33
- @units.each{|unit| return true if unit.name_eql?(name, case_sensitive: @case_sensitive)}
34
- false
35
- end
36
-
37
- def to_unit_name(name)
38
- unit_for(name).name
39
- end
40
-
41
- def convert(value, from:, to:)
42
- raise Measured::UnitError, "Source unit #{ from } does not exits." unless unit?(from)
43
- raise Measured::UnitError, "Converted unit #{ to } does not exits." unless unit?(to)
44
-
45
- from_unit = unit_for(from)
46
- to_unit = unit_for(to)
47
-
48
- raise Measured::UnitError, "Cannot find conversion entry from #{ from } to #{ to }" unless conversion = conversion_table[from][to]
49
-
50
- BigDecimal(value.to_r * conversion,ARBITRARY_CONVERSION_PRECISION)
51
- end
52
-
53
- def conversion_table
54
- @conversion_table ||= Measured::ConversionTable.new(@units).to_h
55
- end
56
-
57
- private
58
-
59
- def add_new_unit(unit_name, aliases:, value: nil, base: false)
60
- if base && @base_unit
61
- raise Measured::UnitError, "Can only have one base unit. Adding #{ unit_name } but already defined #{ @base_unit }."
62
- elsif !base && !@base_unit
63
- raise Measured::UnitError, "A base unit has not yet been set."
64
- end
65
-
66
- check_for_duplicate_unit_names([unit_name] + aliases)
67
-
68
- unit = Measured::Unit.new(unit_name, aliases: aliases, value: value)
69
- @units << unit
70
- @base_unit = unit if base
71
-
72
- clear_conversion_table
73
-
74
- unit
75
- end
76
-
77
- def check_for_duplicate_unit_names(names)
78
- names.each do |name|
79
- raise Measured::UnitError, "Unit #{ name } has already been added." if unit_or_alias?(name)
80
- end
81
- end
82
-
83
- def unit_for(name)
84
- @units.each do |unit|
85
- return unit if unit.names_include?(name, case_sensitive: @case_sensitive)
86
- end
87
-
88
- raise Measured::UnitError, "Cannot find unit for #{ name }."
89
- end
90
-
91
- def clear_conversion_table
92
- @conversion_table = nil
93
- end
94
-
95
- end