measured 2.0.0.pre3 → 2.0.0.pre4
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 +15 -9
- data/lib/measured/base.rb +3 -4
- data/lib/measured/measurable.rb +4 -0
- data/lib/measured/parser.rb +37 -0
- data/lib/measured/unit.rb +8 -3
- data/lib/measured/unit_system_builder.rb +3 -12
- data/lib/measured/version.rb +1 -1
- data/measured.gemspec +4 -3
- data/test/measurable_test.rb +75 -6
- data/test/parser_test.rb +88 -0
- data/test/support/fake_system.rb +1 -9
- data/test/test_helper.rb +3 -0
- data/test/unit_system_builder_test.rb +3 -21
- data/test/unit_system_test.rb +11 -11
- metadata +26 -15
- data/lib/measured/case_insensitive_unit.rb +0 -17
- data/lib/measured/case_insensitive_unit_system.rb +0 -9
- data/test/case_insensitive_unit_system_test.rb +0 -101
- data/test/case_insensitive_unit_test.rb +0 -81
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 674d14a40f494d518096818abee97059c304c311
|
4
|
+
data.tar.gz: f8303931e971c18c714e4d4ba74ec39c141fefd8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5402f3214c5b44a06f979f4fe86a9dc27682a2b3bb605ab944c8a35dcda780f58e11d8be70901eeb28e61986049bbd9e26e3930d13e66170b79de20b5f8c9446
|
7
|
+
data.tar.gz: 10f00639a2bc89230c0a60ab00f58cfb27801c90262c326e6a658947b22ef4bef7208bbed33fdd9486ecc6957f2cdfc5a954622e44c71f0b89021f690fb063f1
|
data/README.md
CHANGED
@@ -56,6 +56,20 @@ rescue Measured::UnitError
|
|
56
56
|
end
|
57
57
|
```
|
58
58
|
|
59
|
+
Parse from string without having to split out the value and unit first:
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
Measured::Weight.parse("123 grams")
|
63
|
+
> #<Measured::Weight 123 g>
|
64
|
+
```
|
65
|
+
|
66
|
+
Parse can scrub extra whitespace and split number from unit:
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
Measured::Weight.parse(" 2kg ")
|
70
|
+
> #<Measured::Weight 2 kg>
|
71
|
+
```
|
72
|
+
|
59
73
|
Perform addition / subtraction against other units, all represented internally as `Rational` or `BigDecimal`:
|
60
74
|
|
61
75
|
```ruby
|
@@ -169,15 +183,7 @@ Measured::Thing = Measured.build do
|
|
169
183
|
end
|
170
184
|
```
|
171
185
|
|
172
|
-
|
173
|
-
|
174
|
-
```ruby
|
175
|
-
Measured::Thing = Measured.build(case_sensitive: true) do
|
176
|
-
unit :base_unit, aliases: [:bu]
|
177
|
-
end
|
178
|
-
```
|
179
|
-
|
180
|
-
Other than case sensitivity, both classes are identical to each other. 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.
|
186
|
+
All unit names are case sensitive.
|
181
187
|
|
182
188
|
Values for conversion units can be defined as a string with two tokens `"number unit"` or as an array with two elements. All values will be parsed as / coerced to `Rational`. Conversion paths don't have to be direct as a conversion table will be built for all possible conversions.
|
183
189
|
|
data/lib/measured/base.rb
CHANGED
@@ -6,8 +6,8 @@ module Measured
|
|
6
6
|
class UnitError < StandardError ; end
|
7
7
|
|
8
8
|
class << self
|
9
|
-
def build(
|
10
|
-
builder = UnitSystemBuilder.new
|
9
|
+
def build(&block)
|
10
|
+
builder = UnitSystemBuilder.new
|
11
11
|
builder.instance_eval(&block)
|
12
12
|
|
13
13
|
Class.new(Measurable) do
|
@@ -38,10 +38,9 @@ module Measured
|
|
38
38
|
end
|
39
39
|
|
40
40
|
require "measured/arithmetic"
|
41
|
+
require "measured/parser"
|
41
42
|
require "measured/unit"
|
42
43
|
require "measured/unit_system"
|
43
|
-
require "measured/case_insensitive_unit"
|
44
|
-
require "measured/case_insensitive_unit_system"
|
45
44
|
require "measured/unit_system_builder"
|
46
45
|
require "measured/conversion_table"
|
47
46
|
require "measured/measurable"
|
data/lib/measured/measurable.rb
CHANGED
@@ -0,0 +1,37 @@
|
|
1
|
+
module Measured::Parser
|
2
|
+
extend self
|
3
|
+
|
4
|
+
PARSE_REGEX = /
|
5
|
+
\A # beginning of input
|
6
|
+
\s* # optionally any whitespace
|
7
|
+
( # capture the value
|
8
|
+
-? # number can be negative
|
9
|
+
\d+ # must have some digits
|
10
|
+
(?: # do not capture
|
11
|
+
[\.\/] # period or slash to split fractional part
|
12
|
+
\d+ # some digits after it
|
13
|
+
)? # fractional part is optional
|
14
|
+
)
|
15
|
+
\s* # optionally any space between number and unit
|
16
|
+
( # capture the unit
|
17
|
+
[a-zA-Z] # unit must start with a letter
|
18
|
+
[\w-]* # any word characters or dashes
|
19
|
+
(?: # non capturing group that is optional for multiple words
|
20
|
+
\s+ # space in the unit for multiple words
|
21
|
+
[\w-]+ # there must be something after the space
|
22
|
+
)* # allow many words
|
23
|
+
)
|
24
|
+
\s* # optionally any whitespace
|
25
|
+
\Z # end of unit
|
26
|
+
/x
|
27
|
+
|
28
|
+
def parse_string(string)
|
29
|
+
raise Measured::UnitError, "Cannot parse blank measurement" if string.blank?
|
30
|
+
|
31
|
+
result = PARSE_REGEX.match(string)
|
32
|
+
|
33
|
+
raise Measured::UnitError, "Cannot parse measurement from '#{string}'" unless result
|
34
|
+
|
35
|
+
[result.captures[0].to_r, result.captures[1]]
|
36
|
+
end
|
37
|
+
end
|
data/lib/measured/unit.rb
CHANGED
@@ -64,9 +64,14 @@ class Measured::Unit
|
|
64
64
|
end
|
65
65
|
|
66
66
|
def parse_value(tokens)
|
67
|
-
|
68
|
-
|
69
|
-
|
67
|
+
case tokens
|
68
|
+
when String
|
69
|
+
tokens = Measured::Parser.parse_string(tokens)
|
70
|
+
when Array
|
71
|
+
raise Measured::UnitError, "Cannot parse [number, unit] formatted tokens from #{tokens}." unless tokens.size == 2
|
72
|
+
else
|
73
|
+
raise Measured::UnitError, "Unit must be defined as string or array, but received #{tokens}"
|
74
|
+
end
|
70
75
|
|
71
76
|
[tokens[0].to_r, tokens[1].freeze]
|
72
77
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
class Measured::UnitSystemBuilder
|
2
|
-
def initialize
|
2
|
+
def initialize
|
3
3
|
@units = []
|
4
|
-
@case_sensitive = case_sensitive
|
5
4
|
end
|
6
5
|
|
7
6
|
def unit(unit_name, aliases: [], value: nil)
|
@@ -10,25 +9,17 @@ class Measured::UnitSystemBuilder
|
|
10
9
|
end
|
11
10
|
|
12
11
|
def build
|
13
|
-
|
12
|
+
Measured::UnitSystem.new(@units)
|
14
13
|
end
|
15
14
|
|
16
15
|
private
|
17
16
|
|
18
17
|
def build_unit(name, aliases: [], value: nil)
|
19
|
-
unit =
|
18
|
+
unit = Measured::Unit.new(name, aliases: aliases, value: value)
|
20
19
|
check_for_duplicate_unit_names!(unit)
|
21
20
|
unit
|
22
21
|
end
|
23
22
|
|
24
|
-
def unit_class
|
25
|
-
@case_sensitive ? Measured::Unit : Measured::CaseInsensitiveUnit
|
26
|
-
end
|
27
|
-
|
28
|
-
def unit_system_class
|
29
|
-
@case_sensitive ? Measured::UnitSystem : Measured::CaseInsensitiveUnitSystem
|
30
|
-
end
|
31
|
-
|
32
23
|
def check_for_duplicate_unit_names!(unit)
|
33
24
|
names = @units.flat_map(&:names)
|
34
25
|
if names.any? { |name| unit.names.include?(name) }
|
data/lib/measured/version.rb
CHANGED
data/measured.gemspec
CHANGED
@@ -20,8 +20,9 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.add_runtime_dependency "activesupport", ">= 4.2"
|
22
22
|
|
23
|
-
spec.add_development_dependency "rake", "
|
24
|
-
spec.add_development_dependency "minitest", "
|
25
|
-
spec.add_development_dependency "
|
23
|
+
spec.add_development_dependency "rake", "> 10.0"
|
24
|
+
spec.add_development_dependency "minitest", "> 5.5.1"
|
25
|
+
spec.add_development_dependency "minitest-reporters"
|
26
|
+
spec.add_development_dependency "mocha", "> 1.1.0"
|
26
27
|
spec.add_development_dependency "pry"
|
27
28
|
end
|
data/test/measurable_test.rb
CHANGED
@@ -82,10 +82,10 @@ class Measured::MeasurableTest < ActiveSupport::TestCase
|
|
82
82
|
end
|
83
83
|
|
84
84
|
test ".unit_system is set and cached" do
|
85
|
-
unit_system =
|
85
|
+
unit_system = Magic.unit_system
|
86
86
|
|
87
87
|
assert_instance_of Measured::UnitSystem, unit_system
|
88
|
-
assert_equal unit_system.__id__,
|
88
|
+
assert_equal unit_system.__id__, Magic.unit_system.__id__
|
89
89
|
end
|
90
90
|
|
91
91
|
test ".unit_names returns just the base unit names" do
|
@@ -94,7 +94,7 @@ class Measured::MeasurableTest < ActiveSupport::TestCase
|
|
94
94
|
|
95
95
|
test ".unit_names_with_aliases returns all units" do
|
96
96
|
assert_equal(
|
97
|
-
%w(arcane fire fireball fireballs ice magic_missile magic_missiles ultima),
|
97
|
+
%w(arcane fire fireball fireballs ice magic\ missile magic_missile magic_missiles ultima),
|
98
98
|
Magic.unit_names_with_aliases
|
99
99
|
)
|
100
100
|
end
|
@@ -115,6 +115,76 @@ class Measured::MeasurableTest < ActiveSupport::TestCase
|
|
115
115
|
assert_equal "very complex thing", Example::VeryComplexThing.name
|
116
116
|
end
|
117
117
|
|
118
|
+
test ".parse raises on nil input" do
|
119
|
+
exception = assert_raises(Measured::UnitError) do
|
120
|
+
Magic.parse(nil)
|
121
|
+
end
|
122
|
+
assert_equal "Cannot parse blank measurement", exception.message
|
123
|
+
end
|
124
|
+
|
125
|
+
test ".parse raises on blank string input" do
|
126
|
+
exception = assert_raises(Measured::UnitError) do
|
127
|
+
Magic.parse("")
|
128
|
+
end
|
129
|
+
assert_equal "Cannot parse blank measurement", exception.message
|
130
|
+
end
|
131
|
+
|
132
|
+
test ".parse raises on a single incorrect string" do
|
133
|
+
exception = assert_raises(Measured::UnitError) do
|
134
|
+
Magic.parse("arcane")
|
135
|
+
end
|
136
|
+
assert_equal "Cannot parse measurement from 'arcane'", exception.message
|
137
|
+
end
|
138
|
+
|
139
|
+
test ".parse raises on a single incorrect number" do
|
140
|
+
exception = assert_raises(Measured::UnitError) do
|
141
|
+
Magic.parse("1234")
|
142
|
+
end
|
143
|
+
assert_equal "Cannot parse measurement from '1234'", exception.message
|
144
|
+
end
|
145
|
+
|
146
|
+
test ".parse takes input with a space between" do
|
147
|
+
assert_equal Magic.new(1, :arcane), Magic.parse("1 arcane")
|
148
|
+
end
|
149
|
+
|
150
|
+
test ".parse takes input without a space" do
|
151
|
+
assert_equal Magic.new(99, :ice), Magic.parse("99ice")
|
152
|
+
end
|
153
|
+
|
154
|
+
test ".parse takes float with a space" do
|
155
|
+
assert_equal Magic.new(12.345, :arcane), Magic.parse("12.345 arcane")
|
156
|
+
end
|
157
|
+
|
158
|
+
test ".parse takes float without a space" do
|
159
|
+
assert_equal Magic.new(9.9, :magic_missile), Magic.parse("9.9magic_missile")
|
160
|
+
end
|
161
|
+
|
162
|
+
test ".parse truncates any space before and after" do
|
163
|
+
assert_equal Magic.new(8765, :arcane), Magic.parse(" 8765 arcane ")
|
164
|
+
end
|
165
|
+
|
166
|
+
test ".parse raises with multiple periods in fractional numbers" do
|
167
|
+
exception = assert_raises(Measured::UnitError) do
|
168
|
+
Magic.parse("12.34.56 ice")
|
169
|
+
end
|
170
|
+
assert_equal "Cannot parse measurement from '12.34.56 ice'", exception.message
|
171
|
+
end
|
172
|
+
|
173
|
+
test ".parse parses negative numbers" do
|
174
|
+
assert_equal Magic.new(-12.34, :arcane), Magic.parse("-12.34 arcane")
|
175
|
+
end
|
176
|
+
|
177
|
+
test ".parse parses rational numbers" do
|
178
|
+
assert_equal Magic.new(1.5, :magic_missile), Magic.parse("3/2magic missile")
|
179
|
+
end
|
180
|
+
|
181
|
+
test ".parse raises on unknown unit" do
|
182
|
+
exception = assert_raises(Measured::UnitError) do
|
183
|
+
Magic.parse("1 fake")
|
184
|
+
end
|
185
|
+
assert_equal "Unit 'fake' does not exist", exception.message
|
186
|
+
end
|
187
|
+
|
118
188
|
test "#convert_to raises on an invalid unit" do
|
119
189
|
assert_raises Measured::UnitError do
|
120
190
|
@magic.convert_to(Measured::Unit.new(:punch))
|
@@ -156,8 +226,8 @@ class Measured::MeasurableTest < ActiveSupport::TestCase
|
|
156
226
|
end
|
157
227
|
|
158
228
|
test "#inspect shows the number and the unit" do
|
159
|
-
assert_equal "#<Magic: 10 #<Measured::
|
160
|
-
assert_equal "#<Magic: 1.234 #<Measured::
|
229
|
+
assert_equal "#<Magic: 10 #<Measured::Unit: fireball (fire, fireballs) 2/3 magic_missile>>", Magic.new(10, :fire).inspect
|
230
|
+
assert_equal "#<Magic: 1.234 #<Measured::Unit: magic_missile (magic_missiles, magic missile)>>", Magic.new(1.234, :magic_missile).inspect
|
161
231
|
end
|
162
232
|
|
163
233
|
test "#zero? always returns false" do
|
@@ -215,5 +285,4 @@ class Measured::MeasurableTest < ActiveSupport::TestCase
|
|
215
285
|
assert_raises(ArgumentError) { @magic < BigDecimal.new(0) }
|
216
286
|
assert_raises(ArgumentError) { @magic < 0.00 }
|
217
287
|
end
|
218
|
-
|
219
288
|
end
|
data/test/parser_test.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class Measured::ParserTest < ActiveSupport::TestCase
|
4
|
+
test "#parse raises on nil input" do
|
5
|
+
exception = assert_raises(Measured::UnitError) do
|
6
|
+
Measured::Parser.parse_string(nil)
|
7
|
+
end
|
8
|
+
assert_equal "Cannot parse blank measurement", exception.message
|
9
|
+
end
|
10
|
+
|
11
|
+
test "#parse raises on blank string input" do
|
12
|
+
exception = assert_raises(Measured::UnitError) do
|
13
|
+
Measured::Parser.parse_string("")
|
14
|
+
end
|
15
|
+
assert_equal "Cannot parse blank measurement", exception.message
|
16
|
+
end
|
17
|
+
|
18
|
+
test "#parse raises on a single incorrect string" do
|
19
|
+
exception = assert_raises(Measured::UnitError) do
|
20
|
+
Measured::Parser.parse_string("word")
|
21
|
+
end
|
22
|
+
assert_equal "Cannot parse measurement from 'word'", exception.message
|
23
|
+
end
|
24
|
+
|
25
|
+
test "#parse raises on a single incorrect number" do
|
26
|
+
exception = assert_raises(Measured::UnitError) do
|
27
|
+
Measured::Parser.parse_string("1234")
|
28
|
+
end
|
29
|
+
assert_equal "Cannot parse measurement from '1234'", exception.message
|
30
|
+
end
|
31
|
+
|
32
|
+
test "#parse raises on a multiple incorrect numbers" do
|
33
|
+
exception = assert_raises(Measured::UnitError) do
|
34
|
+
Measured::Parser.parse_string("12.34 9999")
|
35
|
+
end
|
36
|
+
assert_equal "Cannot parse measurement from '12.34 9999'", exception.message
|
37
|
+
end
|
38
|
+
|
39
|
+
test "#parse takes input with a space between" do
|
40
|
+
assert_equal [Rational(2, 1), "test"], Measured::Parser.parse_string("4/2 test")
|
41
|
+
end
|
42
|
+
|
43
|
+
test "#parse takes input without a space" do
|
44
|
+
assert_equal [Rational(7, 2), "test"], Measured::Parser.parse_string("3.5test")
|
45
|
+
end
|
46
|
+
|
47
|
+
test "#parse takes input with a number in the unit" do
|
48
|
+
assert_equal [Rational(1, 1), "test3test"], Measured::Parser.parse_string("1 test3test")
|
49
|
+
end
|
50
|
+
|
51
|
+
test "#parse raises on a number first unit digit" do
|
52
|
+
exception = assert_raises(Measured::UnitError) do
|
53
|
+
Measured::Parser.parse_string("1 1test")
|
54
|
+
end
|
55
|
+
assert_equal "Cannot parse measurement from '1 1test'", exception.message
|
56
|
+
end
|
57
|
+
|
58
|
+
test "#parse takes float with a space" do
|
59
|
+
assert_equal [Rational(5, 4), "test"], Measured::Parser.parse_string("1.25 test")
|
60
|
+
end
|
61
|
+
|
62
|
+
test "#parse takes float without a space" do
|
63
|
+
assert_equal [Rational(251, 5), "test"], Measured::Parser.parse_string("50.2test")
|
64
|
+
end
|
65
|
+
|
66
|
+
test "#parse truncates any space before and after" do
|
67
|
+
assert_equal [Rational(111111, 100), "test"], Measured::Parser.parse_string(" 1111.11 test ")
|
68
|
+
end
|
69
|
+
|
70
|
+
test "#parse raises with multiple periods in fractional numbers" do
|
71
|
+
exception = assert_raises(Measured::UnitError) do
|
72
|
+
Measured::Parser.parse_string("12.34.56 test")
|
73
|
+
end
|
74
|
+
assert_equal "Cannot parse measurement from '12.34.56 test'", exception.message
|
75
|
+
end
|
76
|
+
|
77
|
+
test "#parse takes multiple words for the unit" do
|
78
|
+
assert_equal [Rational(2345, 1), "a b cde"], Measured::Parser.parse_string(" 2345 a b cde ")
|
79
|
+
end
|
80
|
+
|
81
|
+
test "#parse parses negative numbers" do
|
82
|
+
assert_equal [Rational(-13, 4), "test"], Measured::Parser.parse_string("-3.25 test")
|
83
|
+
end
|
84
|
+
|
85
|
+
test "#parse parses rational numbers" do
|
86
|
+
assert_equal [Rational(3, 2), "test"], Measured::Parser.parse_string("3/2test")
|
87
|
+
end
|
88
|
+
end
|
data/test/support/fake_system.rb
CHANGED
@@ -1,13 +1,5 @@
|
|
1
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"
|
7
|
-
end
|
8
|
-
|
9
|
-
CaseSensitiveMagic = Measured.build(case_sensitive: true) do
|
10
|
-
unit :magic_missile, aliases: [:magic_missiles]
|
2
|
+
unit :magic_missile, aliases: [:magic_missiles, "magic missile"]
|
11
3
|
unit :fireball, value: "2/3 magic_missile", aliases: [:fire, :fireballs]
|
12
4
|
unit :ice, value: "2 magic_missile"
|
13
5
|
unit :arcane, value: "10 magic_missile"
|
data/test/test_helper.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
require "measured"
|
2
|
+
require "minitest/reporters"
|
2
3
|
require "minitest/autorun"
|
3
4
|
require "mocha/setup"
|
4
5
|
require "pry"
|
5
6
|
|
6
7
|
ActiveSupport.test_order = :random
|
7
8
|
|
9
|
+
Minitest::Reporters.use! [Minitest::Reporters::ProgressReporter.new(color: true)]
|
10
|
+
|
8
11
|
require "support/fake_system"
|
9
12
|
|
10
13
|
class ActiveSupport::TestCase
|
@@ -20,24 +20,16 @@ class Measured::UnitSystemBuilderTest < ActiveSupport::TestCase
|
|
20
20
|
end
|
21
21
|
|
22
22
|
assert_raises Measured::UnitError do
|
23
|
-
Measured.build
|
23
|
+
Measured.build do
|
24
24
|
unit :m
|
25
25
|
unit :in, aliases: [:inch], value: "0.0254 m"
|
26
26
|
unit :inch, aliases: [:thing], value: "123 m"
|
27
27
|
end
|
28
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
29
|
end
|
38
30
|
|
39
|
-
test "#
|
40
|
-
measurable = Measured.build
|
31
|
+
test "#unit is case sensitive" do
|
32
|
+
measurable = Measured.build do
|
41
33
|
unit :normal
|
42
34
|
unit :bold, value: "10 normal"
|
43
35
|
unit :BOLD, value: "100 normal"
|
@@ -45,14 +37,4 @@ class Measured::UnitSystemBuilderTest < ActiveSupport::TestCase
|
|
45
37
|
|
46
38
|
assert_equal 'BOLD', measurable.unit_system.unit_for!(:BOLD).name
|
47
39
|
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 'bold', measurable.unit_system.unit_for!(:bOlD).name
|
57
|
-
end
|
58
40
|
end
|
data/test/unit_system_test.rb
CHANGED
@@ -2,7 +2,7 @@ require "test_helper"
|
|
2
2
|
|
3
3
|
class Measured::UnitSystemTest < ActiveSupport::TestCase
|
4
4
|
setup do
|
5
|
-
@unit_fireball =
|
5
|
+
@unit_fireball = Magic.unit_system.unit_for!(:fireball)
|
6
6
|
|
7
7
|
@unit_m = Measured::Unit.new(:m)
|
8
8
|
@unit_in = Measured::Unit.new(:in, aliases: [:Inch], value: "0.0254 m")
|
@@ -46,36 +46,36 @@ class Measured::UnitSystemTest < ActiveSupport::TestCase
|
|
46
46
|
end
|
47
47
|
|
48
48
|
test "#unit_for converts a unit name to its base unit" do
|
49
|
-
assert_equal @unit_fireball,
|
49
|
+
assert_equal @unit_fireball, Magic.unit_system.unit_for("fire")
|
50
50
|
end
|
51
51
|
|
52
52
|
test "#unit_for does not care about string or symbol" do
|
53
|
-
assert_equal @unit_fireball,
|
53
|
+
assert_equal @unit_fireball, Magic.unit_system.unit_for(:fire)
|
54
54
|
end
|
55
55
|
|
56
56
|
test "#unit_for passes through if already base unit name" do
|
57
|
-
assert_equal @unit_fireball,
|
57
|
+
assert_equal @unit_fireball, Magic.unit_system.unit_for("fireball")
|
58
58
|
end
|
59
59
|
|
60
60
|
test "#unit_for returns nil if not found" do
|
61
|
-
assert_nil
|
61
|
+
assert_nil Magic.unit_system.unit_for("thunder")
|
62
62
|
end
|
63
63
|
|
64
64
|
test "#unit_for! converts a unit name to its base unit" do
|
65
|
-
assert_equal @unit_fireball,
|
65
|
+
assert_equal @unit_fireball, Magic.unit_system.unit_for!("fire")
|
66
66
|
end
|
67
67
|
|
68
68
|
test "#unit_for! does not care about string or symbol" do
|
69
|
-
assert_equal @unit_fireball,
|
69
|
+
assert_equal @unit_fireball, Magic.unit_system.unit_for!(:fire)
|
70
70
|
end
|
71
71
|
|
72
72
|
test "#unit_for! passes through if already base unit name" do
|
73
|
-
assert_equal @unit_fireball,
|
73
|
+
assert_equal @unit_fireball, Magic.unit_system.unit_for!("fireball")
|
74
74
|
end
|
75
75
|
|
76
76
|
test "#unit_for! raises if not found" do
|
77
77
|
assert_raises_with_message(Measured::UnitError, "Unit 'thunder' does not exist") do
|
78
|
-
|
78
|
+
Magic.unit_system.unit_for!("thunder")
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
@@ -83,11 +83,11 @@ class Measured::UnitSystemTest < ActiveSupport::TestCase
|
|
83
83
|
unit_bad = Measured::Unit.new(:doesnt_exist)
|
84
84
|
|
85
85
|
assert_raises Measured::UnitError do
|
86
|
-
|
86
|
+
Magic.unit_system.convert(1, from: @unit_fireball, to: unit_bad)
|
87
87
|
end
|
88
88
|
|
89
89
|
assert_raises Measured::UnitError do
|
90
|
-
|
90
|
+
Magic.unit_system.convert(1, from: unit_bad, to: @unit_fireball)
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
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: 2.0.0.
|
4
|
+
version: 2.0.0.pre4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin McPhillips
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-03-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -28,42 +28,56 @@ dependencies:
|
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '10.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: minitest
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - ">"
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: 5.5.1
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - ">"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 5.5.1
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest-reporters
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: mocha
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
|
-
- - "
|
73
|
+
- - ">"
|
60
74
|
- !ruby/object:Gem::Version
|
61
75
|
version: 1.1.0
|
62
76
|
type: :development
|
63
77
|
prerelease: false
|
64
78
|
version_requirements: !ruby/object:Gem::Requirement
|
65
79
|
requirements:
|
66
|
-
- - "
|
80
|
+
- - ">"
|
67
81
|
- !ruby/object:Gem::Version
|
68
82
|
version: 1.1.0
|
69
83
|
- !ruby/object:Gem::Dependency
|
@@ -99,10 +113,9 @@ files:
|
|
99
113
|
- lib/measured.rb
|
100
114
|
- lib/measured/arithmetic.rb
|
101
115
|
- lib/measured/base.rb
|
102
|
-
- lib/measured/case_insensitive_unit.rb
|
103
|
-
- lib/measured/case_insensitive_unit_system.rb
|
104
116
|
- lib/measured/conversion_table.rb
|
105
117
|
- lib/measured/measurable.rb
|
118
|
+
- lib/measured/parser.rb
|
106
119
|
- lib/measured/unit.rb
|
107
120
|
- lib/measured/unit_system.rb
|
108
121
|
- lib/measured/unit_system_builder.rb
|
@@ -112,10 +125,9 @@ files:
|
|
112
125
|
- measured.gemspec
|
113
126
|
- shipit.rubygems.yml
|
114
127
|
- test/arithmetic_test.rb
|
115
|
-
- test/case_insensitive_unit_system_test.rb
|
116
|
-
- test/case_insensitive_unit_test.rb
|
117
128
|
- test/conversion_table_test.rb
|
118
129
|
- test/measurable_test.rb
|
130
|
+
- test/parser_test.rb
|
119
131
|
- test/support/fake_system.rb
|
120
132
|
- test/test_helper.rb
|
121
133
|
- test/unit_error_test.rb
|
@@ -144,16 +156,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
144
156
|
version: 1.3.1
|
145
157
|
requirements: []
|
146
158
|
rubyforge_project:
|
147
|
-
rubygems_version: 2.5.
|
159
|
+
rubygems_version: 2.5.2
|
148
160
|
signing_key:
|
149
161
|
specification_version: 4
|
150
162
|
summary: Encapsulate measurements with their units in Ruby
|
151
163
|
test_files:
|
152
164
|
- test/arithmetic_test.rb
|
153
|
-
- test/case_insensitive_unit_system_test.rb
|
154
|
-
- test/case_insensitive_unit_test.rb
|
155
165
|
- test/conversion_table_test.rb
|
156
166
|
- test/measurable_test.rb
|
167
|
+
- test/parser_test.rb
|
157
168
|
- test/support/fake_system.rb
|
158
169
|
- test/test_helper.rb
|
159
170
|
- test/unit_error_test.rb
|
@@ -1,17 +0,0 @@
|
|
1
|
-
class Measured::CaseInsensitiveUnit < Measured::Unit
|
2
|
-
def initialize(name, aliases: [], value: nil, unit_system: nil)
|
3
|
-
super(
|
4
|
-
name.to_s.downcase,
|
5
|
-
aliases: aliases.map(&:to_s).map!(&:downcase),
|
6
|
-
value: value,
|
7
|
-
unit_system: unit_system
|
8
|
-
)
|
9
|
-
end
|
10
|
-
|
11
|
-
private
|
12
|
-
|
13
|
-
def parse_value(tokens)
|
14
|
-
value, unit = super
|
15
|
-
[value, unit.downcase]
|
16
|
-
end
|
17
|
-
end
|
@@ -1,101 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
class Measured::CaseInsensitiveUnitSystemTest < ActiveSupport::TestCase
|
4
|
-
setup do
|
5
|
-
@unit_fireball = Magic.unit_system.unit_for!(:fireball)
|
6
|
-
|
7
|
-
@unit_m = Measured::CaseInsensitiveUnit.new(:m)
|
8
|
-
@unit_in = Measured::CaseInsensitiveUnit.new(:in, aliases: [:inch], value: "0.0254 m")
|
9
|
-
@unit_ft = Measured::CaseInsensitiveUnit.new(:ft, aliases: %w(Feet FOOT), value: "0.3048 m")
|
10
|
-
@conversion = Measured::CaseInsensitiveUnitSystem.new([@unit_m, @unit_in, @unit_ft])
|
11
|
-
end
|
12
|
-
|
13
|
-
test "#unit_names_with_aliases lists all allowed unit names in lowercase" do
|
14
|
-
assert_equal %w(feet foot ft in inch m), @conversion.unit_names_with_aliases
|
15
|
-
end
|
16
|
-
|
17
|
-
test "#unit_names lists all base unit names without aliases in lowercase" do
|
18
|
-
assert_equal %w(ft in m), @conversion.unit_names
|
19
|
-
end
|
20
|
-
|
21
|
-
test "#unit? checks if the unit is part of the units but not aliases" do
|
22
|
-
assert @conversion.unit?(:in)
|
23
|
-
assert @conversion.unit?("m")
|
24
|
-
assert @conversion.unit?("M")
|
25
|
-
refute @conversion.unit?("inch")
|
26
|
-
refute @conversion.unit?(:yard)
|
27
|
-
end
|
28
|
-
|
29
|
-
test "#unit? with blank and nil arguments" do
|
30
|
-
refute @conversion.unit?("")
|
31
|
-
refute @conversion.unit?(nil)
|
32
|
-
end
|
33
|
-
|
34
|
-
test "#unit_or_alias? checks if the unit is part of the units or aliases" do
|
35
|
-
assert @conversion.unit_or_alias?(:inch)
|
36
|
-
assert @conversion.unit_or_alias?("m")
|
37
|
-
assert @conversion.unit_or_alias?(:IN)
|
38
|
-
assert @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 "#unit_for converts a unit name to its base unit" do
|
48
|
-
assert_equal @unit_fireball, Magic.unit_system.unit_for("fire")
|
49
|
-
end
|
50
|
-
|
51
|
-
test "#unit_for does not care about string or symbol" do
|
52
|
-
assert_equal @unit_fireball, Magic.unit_system.unit_for(:fire)
|
53
|
-
end
|
54
|
-
|
55
|
-
test "#unit_for passes through if already base unit name" do
|
56
|
-
assert_equal @unit_fireball, Magic.unit_system.unit_for("fireball")
|
57
|
-
end
|
58
|
-
|
59
|
-
test "#unit_for returns nil if not found" do
|
60
|
-
assert_nil Magic.unit_system.unit_for("thunder")
|
61
|
-
end
|
62
|
-
|
63
|
-
test "#unit_for! converts a unit name to its base unit" do
|
64
|
-
assert_equal @unit_fireball, Magic.unit_system.unit_for!("fire")
|
65
|
-
end
|
66
|
-
|
67
|
-
test "#unit_for! does not care about string or symbol" do
|
68
|
-
assert_equal @unit_fireball, Magic.unit_system.unit_for!(:fire)
|
69
|
-
end
|
70
|
-
|
71
|
-
test "#unit_for! passes through if already base unit name" do
|
72
|
-
assert_equal @unit_fireball, Magic.unit_system.unit_for!("fireball")
|
73
|
-
end
|
74
|
-
|
75
|
-
test "#unit_for! raises if not found" do
|
76
|
-
assert_raises_with_message(Measured::UnitError, "Unit 'thunder' does not exist") do
|
77
|
-
Magic.unit_system.unit_for!("thunder")
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
test "#convert raises if either unit is not found" do
|
82
|
-
unit_bad = Measured::Unit.new(:doesnt_exist)
|
83
|
-
|
84
|
-
assert_raises Measured::UnitError do
|
85
|
-
Magic.unit_system.convert(1, from: @unit_fireball, to: unit_bad)
|
86
|
-
end
|
87
|
-
|
88
|
-
assert_raises Measured::UnitError do
|
89
|
-
Magic.unit_system.convert(1, from: unit_bad, to: @unit_fireball)
|
90
|
-
end
|
91
|
-
end
|
92
|
-
|
93
|
-
test "#convert converts between two known units" do
|
94
|
-
assert_equal 3, @conversion.convert(36, from: @unit_in, to: @unit_ft)
|
95
|
-
assert_equal 18, @conversion.convert(Rational(3, 2), from: @unit_ft, to: @unit_in)
|
96
|
-
end
|
97
|
-
|
98
|
-
test "#convert handles the same unit" do
|
99
|
-
assert_equal 2, @conversion.convert(2, from: @unit_in, to: @unit_in)
|
100
|
-
end
|
101
|
-
end
|
@@ -1,81 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
class Measured::CaseInsensitiveUnitTest < ActiveSupport::TestCase
|
4
|
-
setup do
|
5
|
-
@unit = Measured::CaseInsensitiveUnit.new(:Pie, value: "10 Cake")
|
6
|
-
@unit_with_aliases = Measured::CaseInsensitiveUnit.new(:Pie, aliases: %w(Cake Tart))
|
7
|
-
end
|
8
|
-
|
9
|
-
test "#initialize converts the name to a downcased string" do
|
10
|
-
assert_equal "pie", @unit.name
|
11
|
-
end
|
12
|
-
|
13
|
-
test "#initialize converts aliases to strings and makes a list of sorted, downcased names" do
|
14
|
-
assert_equal %w(cake pie sweets), Measured::CaseInsensitiveUnit.new(:pie, aliases: ["Cake", :Sweets]).names
|
15
|
-
end
|
16
|
-
|
17
|
-
test "#initialize parses out the unit and the number part" do
|
18
|
-
assert_equal 10, @unit.conversion_amount
|
19
|
-
assert_equal "cake", @unit.conversion_unit
|
20
|
-
|
21
|
-
unit = Measured::CaseInsensitiveUnit.new(:pie, value: "5.5 sweets")
|
22
|
-
assert_equal BigDecimal("5.5"), unit.conversion_amount
|
23
|
-
assert_equal "sweets", unit.conversion_unit
|
24
|
-
|
25
|
-
unit = Measured::CaseInsensitiveUnit.new(:pie, value: "1/3 Bitter Pies")
|
26
|
-
assert_equal Rational(1, 3), unit.conversion_amount
|
27
|
-
assert_equal "bitter pies", unit.conversion_unit
|
28
|
-
end
|
29
|
-
|
30
|
-
test "#initialize raises if the format of the value is incorrect" do
|
31
|
-
assert_raises Measured::UnitError do
|
32
|
-
Measured::CaseInsensitiveUnit.new(:pie, value: "hello")
|
33
|
-
end
|
34
|
-
|
35
|
-
assert_raises Measured::UnitError do
|
36
|
-
Measured::CaseInsensitiveUnit.new(:pie, value: "123456")
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
test "#to_s returns an expected string" do
|
41
|
-
assert_equal "pie", Measured::CaseInsensitiveUnit.new(:pie).to_s
|
42
|
-
assert_equal "pie (1/2 sweet)", Measured::CaseInsensitiveUnit.new(:pie, aliases: ["cake"], value: "0.5 sweet").to_s
|
43
|
-
end
|
44
|
-
|
45
|
-
test "#inspect returns an expected string" do
|
46
|
-
assert_equal "#<Measured::CaseInsensitiveUnit: pie>", Measured::CaseInsensitiveUnit.new(:pie).inspect
|
47
|
-
assert_equal "#<Measured::CaseInsensitiveUnit: pie (cake)>", Measured::CaseInsensitiveUnit.new(:pie, aliases: ["CAKE"]).inspect
|
48
|
-
assert_equal "#<Measured::CaseInsensitiveUnit: pie 1/2 sweet>", Measured::CaseInsensitiveUnit.new(:Pie, value: "1/2 sweet").inspect
|
49
|
-
assert_equal "#<Measured::CaseInsensitiveUnit: pie (cake) 1/2 sweet>", Measured::CaseInsensitiveUnit.new(:pie, aliases: ["cake"], value: "1/2 sweet").inspect
|
50
|
-
end
|
51
|
-
|
52
|
-
test "includes Comparable mixin" do
|
53
|
-
assert Measured::Unit.ancestors.include?(Comparable)
|
54
|
-
end
|
55
|
-
|
56
|
-
test "#<=> compares non-Unit classes against name" do
|
57
|
-
assert_equal 1, @unit <=> "pap"
|
58
|
-
assert_equal -1, @unit <=> "pop"
|
59
|
-
end
|
60
|
-
|
61
|
-
test "#<=> is 0 for Unit instances that should be equivalent" do
|
62
|
-
assert_equal 0, @unit <=> Measured::CaseInsensitiveUnit.new(:Pie, value: "10 cake")
|
63
|
-
assert_equal 0, @unit <=> Measured::CaseInsensitiveUnit.new("Pie", value: "10 cake")
|
64
|
-
assert_equal 0, @unit <=> Measured::CaseInsensitiveUnit.new("Pie", value: [10, :cake])
|
65
|
-
end
|
66
|
-
|
67
|
-
test "#<=> is 1 for units with names that come after Pie lexicographically" do
|
68
|
-
assert_equal 1, @unit <=> Measured::CaseInsensitiveUnit.new(:pancake, value: "10 cake")
|
69
|
-
assert_equal 1, @unit <=> Measured::CaseInsensitiveUnit.new("pie", aliases: ["pancakes"], value: "10 cake")
|
70
|
-
end
|
71
|
-
|
72
|
-
test "#<=> compares #conversion_amount when unit names the same" do
|
73
|
-
assert_equal -1, @unit <=> Measured::CaseInsensitiveUnit.new(:pie, value: [11, :pancake])
|
74
|
-
assert_equal 0, @unit <=> Measured::CaseInsensitiveUnit.new(:pie, value: [10, :foo])
|
75
|
-
assert_equal 1, @unit <=> Measured::CaseInsensitiveUnit.new(:pie, value: [9, :pancake])
|
76
|
-
end
|
77
|
-
|
78
|
-
test "#inverse_conversion_amount returns 1/amount" do
|
79
|
-
assert_equal Rational(1, 10), @unit.inverse_conversion_amount
|
80
|
-
end
|
81
|
-
end
|