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