measured 0.0.12 → 1.0.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 +4 -4
- data/README.md +4 -1
- data/lib/measured/conversion.rb +11 -9
- data/lib/measured/measurable.rb +1 -1
- data/lib/measured/unit.rb +20 -2
- data/lib/measured/version.rb +1 -1
- data/test/conversion_test.rb +22 -0
- data/test/unit_test.rb +47 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6c3f21a067bd19800087dbdd098e55e0355c2584
|
|
4
|
+
data.tar.gz: 973ff94aed9323f0beb2875cbe944fd0dcb3d405
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a89c2dd0e93e0c348e76c493bd415ec5cc8aee7f2730d8a615d7f2cf208599ea94624f8994a1086d13bfb858f7f67528f011bdc87214deafec19a8af02a01625
|
|
7
|
+
data.tar.gz: e10e92567d23959d4c0fcf1df0b52bcef1624d105059890c38bfecf79a8cf66d01081b1e059efb6452575f4a1d92d63258a37a6d4e70e7ed010f8b96d454c8f3
|
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Measured [](https://travis-ci.org/Shopify/measured) [](http://badge.fury.io/rb/measured)
|
|
2
2
|
|
|
3
|
-
Encapsulates
|
|
3
|
+
Encapsulates measurements with their units. Provides easy conversion between units.
|
|
4
4
|
|
|
5
5
|
Light weight and easily extensible to include other units and conversions. Conversions done with `BigDecimal` for precision.
|
|
6
6
|
|
|
@@ -181,6 +181,7 @@ class Measured::Thing < Measured::Measurable
|
|
|
181
181
|
|
|
182
182
|
conversion.add :another_unit, # Add a second unit to the system
|
|
183
183
|
aliases: [:au], # All units allow aliases, as long as they are unique
|
|
184
|
+
case_sensitive: true, # Defaults to false; applies to name and aliases
|
|
184
185
|
value: ["1.5 base_unit"] # The conversion rate to another unit
|
|
185
186
|
|
|
186
187
|
conversion.add :different_unit
|
|
@@ -191,6 +192,8 @@ end
|
|
|
191
192
|
|
|
192
193
|
The base unit takes no value. Values for conversion units can be defined as a string with two tokens `"number unit"` or as an array with two elements. The numbers must be `Rational` or `BigDecimal`, else they will be coerced to `BigDecimal`. Conversion paths don't have to be direct as a conversion table will be built for all possible conversions using tree traversal.
|
|
193
194
|
|
|
195
|
+
The `case_sensitive` flag, which is false by default, gets taken into account any time you attempt to reference a unit by name or alias.
|
|
196
|
+
|
|
194
197
|
You can also open up the existing classes and add a new conversion:
|
|
195
198
|
|
|
196
199
|
```ruby
|
data/lib/measured/conversion.rb
CHANGED
|
@@ -7,12 +7,12 @@ class Measured::Conversion
|
|
|
7
7
|
|
|
8
8
|
attr_reader :base_unit, :units
|
|
9
9
|
|
|
10
|
-
def set_base(unit_name, aliases: [])
|
|
11
|
-
add_new_unit(unit_name, aliases: aliases, base: true)
|
|
10
|
+
def set_base(unit_name, aliases: [], case_sensitive: false)
|
|
11
|
+
add_new_unit(unit_name, aliases: aliases, case_sensitive: case_sensitive, base: true)
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
def add(unit_name, aliases: [], value:)
|
|
15
|
-
add_new_unit(unit_name, aliases: aliases, value: value)
|
|
14
|
+
def add(unit_name, aliases: [], case_sensitive: false, value:)
|
|
15
|
+
add_new_unit(unit_name, aliases: aliases, case_sensitive: case_sensitive, value: value)
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def unit_names_with_aliases
|
|
@@ -24,11 +24,13 @@ class Measured::Conversion
|
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
def unit_or_alias?(name)
|
|
27
|
-
|
|
27
|
+
@units.each{|unit| return true if unit.names_include?(name)}
|
|
28
|
+
false
|
|
28
29
|
end
|
|
29
30
|
|
|
30
31
|
def unit?(name)
|
|
31
|
-
|
|
32
|
+
@units.each{|unit| return true if unit.name_eql?(name)}
|
|
33
|
+
false
|
|
32
34
|
end
|
|
33
35
|
|
|
34
36
|
def to_unit_name(name)
|
|
@@ -53,7 +55,7 @@ class Measured::Conversion
|
|
|
53
55
|
|
|
54
56
|
private
|
|
55
57
|
|
|
56
|
-
def add_new_unit(unit_name, aliases:, value: nil, base: false)
|
|
58
|
+
def add_new_unit(unit_name, aliases:, case_sensitive: false, value: nil, base: false)
|
|
57
59
|
if base && @base_unit
|
|
58
60
|
raise Measured::UnitError, "Can only have one base unit. Adding #{ unit_name } but already defined #{ @base_unit }."
|
|
59
61
|
elsif !base && !@base_unit
|
|
@@ -62,7 +64,7 @@ class Measured::Conversion
|
|
|
62
64
|
|
|
63
65
|
check_for_duplicate_unit_names([unit_name] + aliases)
|
|
64
66
|
|
|
65
|
-
unit = Measured::Unit.new(unit_name, aliases: aliases, value: value)
|
|
67
|
+
unit = Measured::Unit.new(unit_name, aliases: aliases, case_sensitive: case_sensitive, value: value)
|
|
66
68
|
@units << unit
|
|
67
69
|
@base_unit = unit if base
|
|
68
70
|
|
|
@@ -79,7 +81,7 @@ class Measured::Conversion
|
|
|
79
81
|
|
|
80
82
|
def unit_for(name)
|
|
81
83
|
@units.each do |unit|
|
|
82
|
-
return unit if unit.
|
|
84
|
+
return unit if unit.names_include?(name.to_s)
|
|
83
85
|
end
|
|
84
86
|
|
|
85
87
|
raise Measured::UnitError, "Cannot find unit for #{ name }."
|
data/lib/measured/measurable.rb
CHANGED
|
@@ -6,7 +6,7 @@ class Measured::Measurable
|
|
|
6
6
|
|
|
7
7
|
def initialize(value, unit)
|
|
8
8
|
raise Measured::UnitError, "Unit cannot be blank" if unit.blank?
|
|
9
|
-
raise Measured::UnitError, "Unit #{ unit } does not
|
|
9
|
+
raise Measured::UnitError, "Unit #{ unit } does not exist" unless self.class.conversion.unit_or_alias?(unit)
|
|
10
10
|
|
|
11
11
|
@value = case value
|
|
12
12
|
when NilClass
|
data/lib/measured/unit.rb
CHANGED
|
@@ -1,14 +1,27 @@
|
|
|
1
1
|
class Measured::Unit
|
|
2
2
|
include Comparable
|
|
3
3
|
|
|
4
|
-
def initialize(name, aliases: [], value: nil)
|
|
4
|
+
def initialize(name, aliases: [], case_sensitive: false, value: nil)
|
|
5
5
|
@name = name.to_s
|
|
6
6
|
@names = ([@name] + aliases.map{|n| n.to_s }).sort
|
|
7
7
|
|
|
8
|
+
@case_sensitive = case_sensitive
|
|
8
9
|
@conversion_amount, @conversion_unit = parse_value(value) if value
|
|
9
10
|
end
|
|
10
11
|
|
|
11
|
-
attr_reader :name, :names, :conversion_amount, :conversion_unit
|
|
12
|
+
attr_reader :name, :names, :case_sensitive, :conversion_amount, :conversion_unit
|
|
13
|
+
|
|
14
|
+
def name_eql?(name_to_compare)
|
|
15
|
+
with_case_sensitivity(self.name).include?(with_case_sensitivity(name_to_compare).join)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def names_include?(name_to_compare)
|
|
19
|
+
with_case_sensitivity(self.names).include?(with_case_sensitivity(name_to_compare).join)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def add_alias(aliases)
|
|
23
|
+
@names = (@names << aliases).flatten.sort
|
|
24
|
+
end
|
|
12
25
|
|
|
13
26
|
def to_s
|
|
14
27
|
if conversion_string
|
|
@@ -40,6 +53,11 @@ class Measured::Unit
|
|
|
40
53
|
|
|
41
54
|
private
|
|
42
55
|
|
|
56
|
+
def with_case_sensitivity(comparison)
|
|
57
|
+
comparison = [comparison].flatten
|
|
58
|
+
case_sensitive ? comparison : comparison.map(&:downcase)
|
|
59
|
+
end
|
|
60
|
+
|
|
43
61
|
def conversion_string
|
|
44
62
|
"#{ conversion_amount } #{ conversion_unit }" if @conversion_amount || @conversion_unit
|
|
45
63
|
end
|
data/lib/measured/version.rb
CHANGED
data/test/conversion_test.rb
CHANGED
|
@@ -66,20 +66,42 @@ class Measured::ConversionTest < ActiveSupport::TestCase
|
|
|
66
66
|
|
|
67
67
|
assert @conversion.unit?(:inch)
|
|
68
68
|
assert @conversion.unit?("m")
|
|
69
|
+
assert @conversion.unit?("M")
|
|
69
70
|
refute @conversion.unit?("in")
|
|
70
71
|
refute @conversion.unit?(:yard)
|
|
71
72
|
end
|
|
72
73
|
|
|
74
|
+
test "#unit? takes into account case_sensitive flag" do
|
|
75
|
+
@conversion.set_base :m, case_sensitive: true
|
|
76
|
+
@conversion.add :inch, aliases: [:in], value: "0.0254 meter", case_sensitive: true
|
|
77
|
+
|
|
78
|
+
assert @conversion.unit?(:inch)
|
|
79
|
+
assert @conversion.unit?("m")
|
|
80
|
+
refute @conversion.unit?("M")
|
|
81
|
+
refute @conversion.unit?("in")
|
|
82
|
+
end
|
|
83
|
+
|
|
73
84
|
test "#unit_or_alias? checks if the unit is part of the units but not aliases" do
|
|
74
85
|
@conversion.set_base :m
|
|
75
86
|
@conversion.add :inch, aliases: [:in], value: "0.0254 meter"
|
|
76
87
|
|
|
77
88
|
assert @conversion.unit_or_alias?(:inch)
|
|
78
89
|
assert @conversion.unit_or_alias?("m")
|
|
90
|
+
assert @conversion.unit_or_alias?(:IN)
|
|
79
91
|
assert @conversion.unit_or_alias?("in")
|
|
80
92
|
refute @conversion.unit_or_alias?(:yard)
|
|
81
93
|
end
|
|
82
94
|
|
|
95
|
+
test "#unit_or_alias? takes into account case_sensitive flag" do
|
|
96
|
+
@conversion.set_base :m, case_sensitive: true
|
|
97
|
+
@conversion.add :inch, aliases: [:in], value: "0.0254 meter", case_sensitive: true
|
|
98
|
+
|
|
99
|
+
assert @conversion.unit_or_alias?(:inch)
|
|
100
|
+
assert @conversion.unit_or_alias?("m")
|
|
101
|
+
refute @conversion.unit_or_alias?(:M)
|
|
102
|
+
refute @conversion.unit_or_alias?("IN")
|
|
103
|
+
end
|
|
104
|
+
|
|
83
105
|
test "#to_unit_name converts a unit name to its base unit" do
|
|
84
106
|
assert_equal "fireball", Magic.conversion.to_unit_name("fire")
|
|
85
107
|
end
|
data/test/unit_test.rb
CHANGED
|
@@ -13,6 +13,53 @@ class Measured::UnitTest < ActiveSupport::TestCase
|
|
|
13
13
|
assert_equal ["cake", "pie", "sweets"], Measured::Unit.new(:pie, aliases: ["cake", :sweets]).names
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
+
test "case_sensitive flag default to false" do
|
|
17
|
+
assert_equal false, @unit.case_sensitive
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
test "#name_eql?" do
|
|
21
|
+
assert_equal true, @unit.name_eql?("pIe")
|
|
22
|
+
assert_equal false, @unit.name_eql?("pastry")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
test "#names_include?" do
|
|
26
|
+
unit = Measured::Unit.new(:pie, aliases:["cake", "tart"])
|
|
27
|
+
assert_equal true, unit.names_include?("pie")
|
|
28
|
+
assert_equal true, unit.names_include?("caKe")
|
|
29
|
+
assert_equal true, unit.names_include?("taRt")
|
|
30
|
+
assert_equal false, unit.names_include?("pastry")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
test "case_sensitive flag set to false" do
|
|
34
|
+
assert_equal false, Measured::Unit.new(:pie, case_sensitive: false).case_sensitive
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
test "case_sensitive flag set to true, #name_eql?" do
|
|
38
|
+
unit = Measured::Unit.new(:pie, case_sensitive: true)
|
|
39
|
+
assert_equal true, unit.name_eql?("pie")
|
|
40
|
+
assert_equal false, unit.name_eql?("pIe")
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
test "case_sensitive flag set to true, #names_include?" do
|
|
44
|
+
unit = Measured::Unit.new(:pie, aliases: ["cake", "tart", "pastry"], case_sensitive: true)
|
|
45
|
+
assert_equal true, unit.names_include?("cake")
|
|
46
|
+
assert_equal false, unit.names_include?("tArt")
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
test "#add_alias with string" do
|
|
50
|
+
unit = Measured::Unit.new(:pie, aliases: ["cake"], value: "10 cake")
|
|
51
|
+
assert_equal ["cake", "pie"], unit.names
|
|
52
|
+
unit.add_alias("pastry")
|
|
53
|
+
assert_equal ["cake", "pastry", "pie"], unit.names
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
test "#add_alias with array" do
|
|
57
|
+
unit = Measured::Unit.new(:pie, aliases: ["cake"], value: "10 cake")
|
|
58
|
+
assert_equal ["cake", "pie"], unit.names
|
|
59
|
+
unit.add_alias(["pastry", "tart", "turnover"])
|
|
60
|
+
assert_equal ["cake", "pastry", "pie", "tart", "turnover"], unit.names
|
|
61
|
+
end
|
|
62
|
+
|
|
16
63
|
test "#initialize parses out the unit and the number part" do
|
|
17
64
|
assert_equal BigDecimal(10), @unit.conversion_amount
|
|
18
65
|
assert_equal "cake", @unit.conversion_unit
|
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: 0.0
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kevin McPhillips
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2015-
|
|
11
|
+
date: 2015-08-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|