unit 0.4.1 → 0.5.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 +7 -0
- data/.gitignore +1 -0
- data/.travis.yml +9 -5
- data/Gemfile +1 -1
- data/LICENSE +1 -1
- data/README.markdown +28 -8
- data/Rakefile +5 -6
- data/lib/unit.rb +0 -1
- data/lib/unit/class.rb +16 -4
- data/lib/unit/dsl.rb +2 -0
- data/lib/unit/system.rb +4 -8
- data/lib/unit/version.rb +1 -1
- data/spec/error_spec.rb +2 -2
- data/spec/spec_helper.rb +1 -1
- data/spec/system_spec.rb +11 -11
- data/spec/unit_spec.rb +129 -93
- data/unit.gemspec +9 -10
- metadata +29 -23
- data/lib/unit/compatibility.rb +0 -9
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a84061a71aee6a42474eabd1fbf16301f8395d74
|
4
|
+
data.tar.gz: 979a52da34a279ed995492f15e03dc946024b13c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1aa9ee8eb10eafdf62ae69ca9010abaf9a14226c64d74845ca5df15975f98d6eb3b33a1fbf6f22c70f970c3c25ebd06c56308559e55e8af45d444cedcaafcdab
|
7
|
+
data.tar.gz: 6408e2577ceca493523554aba26a753651388d4ef9afddcae7ea8d7242f1253a3b000cc6b75f637cc8b1092d68f20153e833b8982cc598fffd3263fbd5f5924d
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
source
|
1
|
+
source 'https://rubygems.org/'
|
2
2
|
gemspec
|
data/LICENSE
CHANGED
data/README.markdown
CHANGED
@@ -1,10 +1,17 @@
|
|
1
1
|
README
|
2
|
-
|
2
|
+
===
|
3
|
+
**Unit** introduces computational units to Ruby. It offers built-in support for binary, mathematical, SI, imperial, scientific and temporal units, and a simple interface for adding your own, custom units.
|
3
4
|
|
4
|
-
|
5
|
+
[](http://badge.fury.io/rb/unit) [](https://gemnasium.com/minad/unit) [](http://travis-ci.org/minad/unit) [](https://codeclimate.com/github/minad/unit)
|
5
6
|
|
6
|
-
|
7
|
-
|
7
|
+
- Define units for operands to avoid the inevitable mistakes that plague unit-less operations.
|
8
|
+
- Perform complex mathematical operations while respecting the units of each operand.
|
9
|
+
- Get meaningful errors when units aren't compatible.
|
10
|
+
- Convert values between different systems of units with ease.
|
11
|
+
|
12
|
+
Examples
|
13
|
+
===
|
14
|
+
### General Usage
|
8
15
|
|
9
16
|
require 'unit'
|
10
17
|
puts 1.meter.in_kilometer
|
@@ -13,9 +20,22 @@ Usage
|
|
13
20
|
puts 10.KiB_per_second
|
14
21
|
puts Unit('1 m/s^2')
|
15
22
|
|
16
|
-
|
23
|
+
### Mathematics
|
24
|
+
|
25
|
+
Unit(1, 'km') + Unit(500, 'm') == Unit(1.5, 'km')
|
26
|
+
Unit(1, 'kg') - Unit(500, 'g') == Unit(0.5, 'kg')
|
27
|
+
Unit(100, 'miles/hour') * Unit(0.5, 'hours') == Unit('50 mi')
|
28
|
+
Unit(5.5, 'feet') / 2 == Unit(2.75, 'feet')
|
29
|
+
Unit(2, 'm') ** 2 == Unit(4, 'm^2')
|
30
|
+
|
31
|
+
### Conversions
|
32
|
+
|
33
|
+
Unit(1, 'mile').in('km') == Unit(1.609344, 'km')
|
34
|
+
(Unit(10, 'A') * Unit(0.1, 'volt')).in('watts') == Unit(1, 'watt')
|
35
|
+
|
36
|
+
See the test cases for many more examples.
|
17
37
|
|
18
|
-
|
19
|
-
|
38
|
+
Maintainers
|
39
|
+
---
|
40
|
+
Daniel Mendler and [Chris Cashwell](https://github.com/ccashwell)
|
20
41
|
|
21
|
-
Daniel Mendler
|
data/Rakefile
CHANGED
@@ -2,17 +2,16 @@
|
|
2
2
|
require 'rspec/core/rake_task'
|
3
3
|
task :default => :spec
|
4
4
|
|
5
|
-
desc
|
6
|
-
task :spec => [
|
5
|
+
desc 'Run specs'
|
6
|
+
task :spec => ['spec:no_dsl', 'spec:dsl']
|
7
7
|
|
8
8
|
namespace :spec do
|
9
|
-
desc
|
9
|
+
desc 'Run specs without DSL'
|
10
10
|
RSpec::Core::RakeTask.new(:no_dsl) do |t|
|
11
|
-
t.rspec_opts =
|
11
|
+
t.rspec_opts = '-t ~dsl'
|
12
12
|
end
|
13
13
|
|
14
|
-
desc
|
14
|
+
desc 'Run specs with DSL'
|
15
15
|
RSpec::Core::RakeTask.new(:dsl) do |t|
|
16
|
-
# Run all tests
|
17
16
|
end
|
18
17
|
end
|
data/lib/unit.rb
CHANGED
data/lib/unit/class.rb
CHANGED
@@ -159,11 +159,11 @@ class Unit < Numeric
|
|
159
159
|
end
|
160
160
|
|
161
161
|
def inspect
|
162
|
-
unit.empty? ? %{Unit("#{value}")} : %{Unit("#{
|
162
|
+
unit.empty? ? %{Unit("#{value}")} : %{Unit("#{value_string} #{unit_string('.')}")}
|
163
163
|
end
|
164
164
|
|
165
165
|
def to_s
|
166
|
-
unit.empty? ? value.to_s : "#{
|
166
|
+
unit.empty? ? value.to_s : "#{value_string} #{unit_string}"
|
167
167
|
end
|
168
168
|
|
169
169
|
def to_tex
|
@@ -182,14 +182,26 @@ class Unit < Numeric
|
|
182
182
|
Unit.new(self.to_f, unit, system)
|
183
183
|
end
|
184
184
|
|
185
|
-
def round
|
186
|
-
Unit.new(value.round, unit, system)
|
185
|
+
def round(precision = 0)
|
186
|
+
Unit.new(value.round(precision), unit, system)
|
187
187
|
end
|
188
188
|
|
189
189
|
def coerce(other)
|
190
190
|
[coerce_numeric(other), self]
|
191
191
|
end
|
192
192
|
|
193
|
+
def value_string
|
194
|
+
if Rational === value
|
195
|
+
if value.denominator == 1
|
196
|
+
value.numerator.to_s
|
197
|
+
else
|
198
|
+
value.inspect
|
199
|
+
end
|
200
|
+
else
|
201
|
+
value.to_s
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
193
205
|
def unit_string(sep = '·')
|
194
206
|
(unit_list(@unit.select {|factor, name, exp| exp >= 0 }) +
|
195
207
|
unit_list(@unit.select {|factor, name, exp| exp < 0 })).join(sep)
|
data/lib/unit/dsl.rb
CHANGED
data/lib/unit/system.rb
CHANGED
@@ -11,7 +11,7 @@ class Unit < Numeric
|
|
11
11
|
@unit_symbol = {}
|
12
12
|
|
13
13
|
# one is internal trivial factor
|
14
|
-
@factor = {:
|
14
|
+
@factor = {one: {symbol: 'one', value: 1} }
|
15
15
|
@factor_symbol = {'one' => :one}
|
16
16
|
@factor_value = {1 => :one}
|
17
17
|
|
@@ -45,11 +45,7 @@ class Unit < Numeric
|
|
45
45
|
load_factors(data['factors']) if data['factors']
|
46
46
|
load_units(data['units']) if data['units']
|
47
47
|
|
48
|
-
@unit.each
|
49
|
-
defs = unit.delete(:defs)
|
50
|
-
unit[:def] = parse_unit(defs) if defs
|
51
|
-
validate_unit(unit[:def])
|
52
|
-
end
|
48
|
+
@unit.each {|name, unit| validate_unit(unit[:def]) }
|
53
49
|
|
54
50
|
true
|
55
51
|
end
|
@@ -141,7 +137,7 @@ class Unit < Numeric
|
|
141
137
|
raise "Invalid definition for factor #{name}" unless base
|
142
138
|
value = base ** exp
|
143
139
|
$stderr.puts "Factor #{name} already defined" if @factor[name]
|
144
|
-
@factor[name] = { :
|
140
|
+
@factor[name] = { symbol: symbols.first, value: value }
|
145
141
|
symbols.each do |sym|
|
146
142
|
$stderr.puts "Factor symbol #{sym} for #{name} already defined" if @factor_symbol[name]
|
147
143
|
@factor_symbol[sym] = name
|
@@ -155,7 +151,7 @@ class Unit < Numeric
|
|
155
151
|
name = name.to_sym
|
156
152
|
symbols = [unit['sym'] || []].flatten
|
157
153
|
$stderr.puts "Unit #{name} already defined" if @unit[name]
|
158
|
-
@unit[name] = { :
|
154
|
+
@unit[name] = { symbol: symbols.first, def: parse_unit(unit['def']) }
|
159
155
|
symbols.each do |sym|
|
160
156
|
$stderr.puts "Unit symbol #{sym} for #{name} already defined" if @unit_symbol[name]
|
161
157
|
@unit_symbol[sym] = name
|
data/lib/unit/version.rb
CHANGED
data/spec/error_spec.rb
CHANGED
@@ -6,7 +6,7 @@ describe "Errors" do
|
|
6
6
|
it "should have a nice error message" do
|
7
7
|
a = Unit(1, "meter")
|
8
8
|
b = Unit(1, "second")
|
9
|
-
|
9
|
+
expect { a + b }.to raise_error(TypeError, "#{a.inspect} and #{b.inspect} are incompatible")
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
@@ -18,7 +18,7 @@ describe "Errors" do
|
|
18
18
|
)
|
19
19
|
end
|
20
20
|
|
21
|
-
it "should have a nice error message using the DSL", :
|
21
|
+
it "should have a nice error message using the DSL", dsl: true do
|
22
22
|
unit = Unit(1000, "m / s")
|
23
23
|
expect { unit.in_seconds! }.to(
|
24
24
|
raise_error(TypeError, %{Unexpected #{unit.inspect}, expected to be in s})
|
data/spec/spec_helper.rb
CHANGED
data/spec/system_spec.rb
CHANGED
@@ -9,7 +9,7 @@ describe Unit::System do
|
|
9
9
|
system.load(:si)
|
10
10
|
test_file = File.join(File.dirname(__FILE__), "yml", "io.yml")
|
11
11
|
File.open(test_file) { |file| system.load(file) }
|
12
|
-
Unit(1, "pim", system).
|
12
|
+
expect(Unit(1, "pim", system)).to eq(Unit(3.14159, "m", system))
|
13
13
|
end
|
14
14
|
|
15
15
|
context "when passed a String" do
|
@@ -18,14 +18,14 @@ describe Unit::System do
|
|
18
18
|
filename = File.join(File.dirname(__FILE__), "yml", "filename.yml")
|
19
19
|
system.load(:si)
|
20
20
|
system.load(filename)
|
21
|
-
Unit(2, "dzm", system).
|
21
|
+
expect(Unit(2, "dzm", system)).to eq(Unit(24, "m", system))
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
25
|
context "that is not a filename" do
|
26
26
|
it "should load the built-in system of that name" do
|
27
27
|
system.load("si")
|
28
|
-
|
28
|
+
expect { Unit(2, 'm', system) }.not_to raise_exception
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
@@ -42,7 +42,7 @@ describe Unit::System do
|
|
42
42
|
}
|
43
43
|
}
|
44
44
|
)
|
45
|
-
Unit(2, "dzm", system).
|
45
|
+
expect(Unit(2, "dzm", system)).to eq(Unit(24, "m", system))
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
@@ -57,14 +57,14 @@ describe Unit::System do
|
|
57
57
|
}
|
58
58
|
}
|
59
59
|
)
|
60
|
-
Unit(2, "dzm", system).
|
60
|
+
expect(Unit(2, "dzm", system)).to eq(Unit(24, "m", system))
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
64
|
context "when passed an invalid factor" do
|
65
65
|
it "should raise an exception" do
|
66
66
|
system.load(:si)
|
67
|
-
|
67
|
+
expect {
|
68
68
|
system.load(
|
69
69
|
'factors' => {
|
70
70
|
'dozen' => {
|
@@ -72,26 +72,26 @@ describe Unit::System do
|
|
72
72
|
}
|
73
73
|
}
|
74
74
|
)
|
75
|
-
}.
|
75
|
+
}.to raise_exception("Invalid definition for factor dozen")
|
76
76
|
end
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
80
80
|
context "when called on the same filename a second time" do
|
81
81
|
it "should be a no-op" do
|
82
|
-
$stderr.
|
82
|
+
expect($stderr).not_to receive(:puts)
|
83
83
|
test_file = File.join(File.dirname(__FILE__), "yml", "filename.yml")
|
84
84
|
system.load(:si)
|
85
85
|
system.load(test_file)
|
86
|
-
|
86
|
+
expect { system.load(test_file) }.not_to raise_exception
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
90
|
context "when called on the same symbol a second time" do
|
91
91
|
it "should be a no-op" do
|
92
|
-
$stderr.
|
92
|
+
expect($stderr).not_to receive(:puts)
|
93
93
|
system.load(:si)
|
94
|
-
|
94
|
+
expect { system.load(:si) }.not_to raise_exception
|
95
95
|
end
|
96
96
|
end
|
97
97
|
end
|
data/spec/unit_spec.rb
CHANGED
@@ -7,67 +7,67 @@ Unit.default_system.load(:misc)
|
|
7
7
|
|
8
8
|
describe 'Unit' do
|
9
9
|
it 'should support multiplication' do
|
10
|
-
(Unit(2, 'm') * Unit(3, 'm')).
|
11
|
-
(Unit(2, 'm') * 3).
|
12
|
-
(Unit(2, 'm') * Rational(3, 4)).
|
13
|
-
(Unit(2, 'm') * 0.5).
|
10
|
+
expect(Unit(2, 'm') * Unit(3, 'm')).to eq(Unit(6, 'm^2'))
|
11
|
+
expect(Unit(2, 'm') * 3).to eq(Unit(6, 'm'))
|
12
|
+
expect(Unit(2, 'm') * Rational(3, 4)).to eq(Unit(3, 2, 'm'))
|
13
|
+
expect(Unit(2, 'm') * 0.5).to eq(Unit(1.0, 'm'))
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'should support division' do
|
17
|
-
(Unit(2, 'm') / Unit(3, 'm^2')).
|
18
|
-
(Unit(2, 'm') / 3).
|
19
|
-
(Unit(2, 'm') / Rational(3, 4)).
|
20
|
-
(Unit(2, 'm') / 0.5).
|
17
|
+
expect(Unit(2, 'm') / Unit(3, 'm^2')).to eq(Unit(2, 3, '1/m'))
|
18
|
+
expect(Unit(2, 'm') / 3).to eq(Unit(2, 3, 'm'))
|
19
|
+
expect(Unit(2, 'm') / Rational(3, 4)).to eq(Unit(8, 3, 'm'))
|
20
|
+
expect(Unit(2, 'm') / 0.5).to eq(Unit(4.0, 'm'))
|
21
21
|
end
|
22
22
|
|
23
23
|
it 'should support addition' do
|
24
|
-
(Unit(42, 'm') + Unit(1, 'km')).
|
24
|
+
expect(Unit(42, 'm') + Unit(1, 'km')).to eq(Unit(1042, 'm'))
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'should support subtraction' do
|
28
|
-
(Unit(1, 'm') - Unit(1, 'cm')).
|
29
|
-
(Unit(2, 'm') - Unit(1, 'm')).
|
28
|
+
expect(Unit(1, 'm') - Unit(1, 'cm')).to eq(Unit(99, 100, 'm'))
|
29
|
+
expect(Unit(2, 'm') - Unit(1, 'm')).to eq(Unit(1, 'm'))
|
30
30
|
end
|
31
31
|
|
32
32
|
it "should support arithmetic with Integers when appropriate" do
|
33
|
-
(1 + Unit(1)).
|
34
|
-
(2 - Unit(1)).
|
35
|
-
(Unit(2) - 1).
|
36
|
-
(2 - Unit(-1)).
|
37
|
-
(Unit(2) - -1).
|
33
|
+
expect(1 + Unit(1)).to eq(Unit(2))
|
34
|
+
expect(2 - Unit(1)).to eq(Unit(1))
|
35
|
+
expect(Unit(2) - 1).to eq(Unit(1))
|
36
|
+
expect(2 - Unit(-1)).to eq(Unit(3))
|
37
|
+
expect(Unit(2) - -1).to eq(Unit(3))
|
38
38
|
end
|
39
39
|
|
40
40
|
it "should support arithmetic with other classes using #coerce" do
|
41
|
-
(Unit(2) + UnitOne.new).
|
42
|
-
(2 + UnitOne.new).
|
43
|
-
(Unit(2) - UnitOne.new).
|
44
|
-
(2 - UnitOne.new).
|
45
|
-
(Unit(2) * UnitOne.new).
|
46
|
-
(2 * UnitOne.new).
|
47
|
-
(Unit(2) / UnitOne.new).
|
48
|
-
(2 / UnitOne.new).
|
49
|
-
|
50
|
-
(UnitOne.new + Unit(4)).
|
51
|
-
(UnitOne.new + 4).
|
52
|
-
(UnitOne.new - Unit(4)).
|
53
|
-
(UnitOne.new - 4).
|
54
|
-
(UnitOne.new * Unit(4)).
|
55
|
-
(UnitOne.new * 4).
|
56
|
-
(UnitOne.new / Unit(4)).
|
57
|
-
(UnitOne.new / 4).
|
41
|
+
expect(Unit(2) + UnitOne.new).to eq(Unit(3))
|
42
|
+
expect(2 + UnitOne.new).to eq(3)
|
43
|
+
expect(Unit(2) - UnitOne.new).to eq(Unit(1))
|
44
|
+
expect(2 - UnitOne.new).to eq(1)
|
45
|
+
expect(Unit(2) * UnitOne.new).to eq(Unit(2))
|
46
|
+
expect(2 * UnitOne.new).to eq(2)
|
47
|
+
expect(Unit(2) / UnitOne.new).to eq(Unit(2))
|
48
|
+
expect(2 / UnitOne.new).to eq(2)
|
49
|
+
|
50
|
+
expect(UnitOne.new + Unit(4)).to eq(Unit(5))
|
51
|
+
expect(UnitOne.new + 4).to eq(5)
|
52
|
+
expect(UnitOne.new - Unit(4)).to eq(Unit(-3))
|
53
|
+
expect(UnitOne.new - 4).to eq(-3)
|
54
|
+
expect(UnitOne.new * Unit(4)).to eq(Unit(4))
|
55
|
+
expect(UnitOne.new * 4).to eq(4)
|
56
|
+
expect(UnitOne.new / Unit(4)).to eq(Unit(1, 4))
|
57
|
+
expect(UnitOne.new / 4).to eq(0)
|
58
58
|
end
|
59
59
|
|
60
60
|
it "should support logic with other classes using #coerce" do
|
61
|
-
Unit(1).
|
62
|
-
Unit(2).
|
61
|
+
expect(Unit(1)).to eq(UnitOne.new)
|
62
|
+
expect(Unit(2)).to be > UnitOne.new
|
63
63
|
end
|
64
64
|
|
65
65
|
it "should support eql comparison" do
|
66
|
-
Unit(1).
|
67
|
-
Unit(1.0).
|
66
|
+
expect(Unit(1)).to eql(Unit(1))
|
67
|
+
expect(Unit(1.0)).not_to eql(Unit(1))
|
68
68
|
|
69
|
-
Unit(1).
|
70
|
-
Unit(1.0).
|
69
|
+
expect(Unit(1)).not_to eql(UnitOne.new)
|
70
|
+
expect(Unit(1.0)).not_to eql(UnitOne.new)
|
71
71
|
end
|
72
72
|
|
73
73
|
it "should not support adding anything but numeric unless object is coerceable" do
|
@@ -78,8 +78,8 @@ describe 'Unit' do
|
|
78
78
|
end
|
79
79
|
|
80
80
|
it "should support adding through zero" do
|
81
|
-
(Unit(0, "m") + Unit(1, "m")).
|
82
|
-
(Unit(1, "m") + Unit(-1, "m") + Unit(1, "m")).
|
81
|
+
expect(Unit(0, "m") + Unit(1, "m")).to eq(Unit(1, "m"))
|
82
|
+
expect(Unit(1, "m") + Unit(-1, "m") + Unit(1, "m")).to eq(Unit(1, "m"))
|
83
83
|
end
|
84
84
|
|
85
85
|
it 'should check unit compatiblity' do
|
@@ -89,10 +89,10 @@ describe 'Unit' do
|
|
89
89
|
end
|
90
90
|
|
91
91
|
it 'should support exponentiation' do
|
92
|
-
(Unit(2, 'm') ** 3).
|
93
|
-
(Unit(9, 'm^2') ** 0.5).
|
94
|
-
(Unit(9, 'm^2') ** Rational(1, 2)).
|
95
|
-
(Unit(2, 'm') ** 1.3).
|
92
|
+
expect(Unit(2, 'm') ** 3).to eq(Unit(8, 'm^3'))
|
93
|
+
expect(Unit(9, 'm^2') ** 0.5).to eq(Unit(3.0, 'm'))
|
94
|
+
expect(Unit(9, 'm^2') ** Rational(1, 2)).to eq(Unit(3, 'm'))
|
95
|
+
expect(Unit(2, 'm') ** 1.3).to eq(Unit(2 ** 1.3, 'm^1.3'))
|
96
96
|
end
|
97
97
|
|
98
98
|
it 'should not allow units as exponent' do
|
@@ -104,7 +104,7 @@ describe 'Unit' do
|
|
104
104
|
unit = Unit(1, 'joule')
|
105
105
|
normalized_unit = Unit(1000, 'gram meter^2 / second^2')
|
106
106
|
|
107
|
-
unit.normalize.
|
107
|
+
expect(unit.normalize).to eql normalized_unit
|
108
108
|
end
|
109
109
|
|
110
110
|
it "should not modify the receiver" do
|
@@ -112,7 +112,7 @@ describe 'Unit' do
|
|
112
112
|
normalized_unit = Unit(1000, 'gram meter^2 / second^2')
|
113
113
|
|
114
114
|
unit.normalize
|
115
|
-
unit.
|
115
|
+
expect(unit).not_to eql normalized_unit
|
116
116
|
end
|
117
117
|
end
|
118
118
|
|
@@ -121,7 +121,7 @@ describe 'Unit' do
|
|
121
121
|
unit = Unit(1, 'joule')
|
122
122
|
normalized_unit = Unit(1000, 'gram meter^2 / second^2')
|
123
123
|
|
124
|
-
unit.normalize
|
124
|
+
expect(unit.normalize!).to eql normalized_unit
|
125
125
|
end
|
126
126
|
|
127
127
|
it "should modify the receiver" do
|
@@ -129,66 +129,94 @@ describe 'Unit' do
|
|
129
129
|
normalized_unit = Unit(1000, 'gram meter^2 / second^2')
|
130
130
|
|
131
131
|
unit.normalize!
|
132
|
-
unit.
|
132
|
+
expect(unit).to eql normalized_unit
|
133
133
|
end
|
134
134
|
end
|
135
135
|
|
136
136
|
it 'should convert units' do
|
137
|
-
Unit(1, "MeV").in("joule").
|
138
|
-
Unit(1, "kilometer").in("meter").
|
139
|
-
Unit(1, "liter").in('meter^3').
|
140
|
-
Unit(1, "kilometer/hour").in("meter/second").
|
137
|
+
expect(Unit(1, "MeV").in("joule")).to eq(Unit(1.602176487e-13, 'joule'))
|
138
|
+
expect(Unit(1, "kilometer").in("meter")).to eq(Unit(1000, 'meter'))
|
139
|
+
expect(Unit(1, "liter").in('meter^3')).to eq(Unit(1, 1000, 'meter^3'))
|
140
|
+
expect(Unit(1, "kilometer/hour").in("meter/second")).to eq(Unit(5, 18, 'meter/second'))
|
141
141
|
end
|
142
142
|
|
143
143
|
it 'should have a working compatible? method' do
|
144
|
-
Unit(7, "meter").compatible?('kilogram').
|
145
|
-
Unit(3, "parsec").compatible_with?('meter').
|
144
|
+
expect(Unit(7, "meter").compatible?('kilogram')).to eq(false)
|
145
|
+
expect(Unit(3, "parsec").compatible_with?('meter')).to eq(true)
|
146
146
|
end
|
147
147
|
|
148
148
|
it 'should have a pretty string representation' do
|
149
|
-
Unit(7, "joule").normalize.to_s.
|
149
|
+
expect(Unit(7, "joule").normalize.to_s).to eq('7000 g·m^2·s^-2')
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'should have a pretty string representation after subtraction' do
|
153
|
+
expect((Unit('5 cm') - Unit('1 cm')).to_s).to eq('4 cm')
|
154
|
+
end
|
155
|
+
|
156
|
+
describe "#value_string" do
|
157
|
+
it 'should behave like to_s normally' do
|
158
|
+
expect(Unit(1, "liter").send(:value_string)).to eq("1")
|
159
|
+
expect(Unit(0.5, "parsec").send(:value_string)).to eq("0.5")
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'should wrap fractions in parentheses' do
|
163
|
+
expect(Unit(Rational(1, 2), "m").send(:value_string)).to eq("(1/2)")
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'should show reduced fractions' do
|
167
|
+
expect(Unit(Rational(16, 6), "m").send(:value_string)).to eq("(8/3)")
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'should not show 1 in the denominator' do
|
171
|
+
expect(Unit(Rational(1), "foot").send(:value_string)).to eq("1")
|
172
|
+
expect(Unit(Rational(4, 1), "inch").send(:value_string)).to eq("4")
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'should support round trip through to_s' do
|
177
|
+
expect(Unit(Unit('(1/2) cm').to_s)).to eq(Unit('(1/2) cm'))
|
150
178
|
end
|
151
179
|
|
152
180
|
it 'should parse units' do
|
153
|
-
Unit(1, 'KiB s^-1').unit.
|
154
|
-
Unit(1, 'KiB/s').unit.
|
155
|
-
Unit(1, 'kilometer^2 / megaelectronvolt^7 * gram centiliter').unit.
|
156
|
-
[:one, :gram, 1], [:centi, :liter, 1]].sort
|
181
|
+
expect(Unit(1, 'KiB s^-1').unit).to eq([[:kibi, :byte, 1], [:one, :second, -1]].sort)
|
182
|
+
expect(Unit(1, 'KiB/s').unit).to eq([[:kibi, :byte, 1], [:one, :second, -1]].sort)
|
183
|
+
expect(Unit(1, 'kilometer^2 / megaelectronvolt^7 * gram centiliter').unit).to eq([[:kilo, :meter, 2], [:mega, :electronvolt, -7],
|
184
|
+
[:one, :gram, 1], [:centi, :liter, 1]].sort)
|
157
185
|
end
|
158
186
|
|
159
187
|
it 'should reduce units' do
|
160
|
-
Unit(1, "joule/kilogram").normalize.unit.
|
161
|
-
Unit(1, "megaton/kilometer").unit.
|
188
|
+
expect(Unit(1, "joule/kilogram").normalize.unit).to eq([[:one, :meter, 2], [:one, :second, -2]].sort)
|
189
|
+
expect(Unit(1, "megaton/kilometer").unit).to eq([[:one, :meter, -1], [:kilo, :ton, 1]])
|
162
190
|
end
|
163
191
|
|
164
192
|
it 'should work with floating point values' do
|
165
193
|
w = 5.2 * Unit('kilogram')
|
166
|
-
w.in("pounds").to_int.
|
194
|
+
expect(w.in("pounds").to_int).to eq(11)
|
167
195
|
end
|
168
196
|
|
169
197
|
it 'should have dimensionless? method' do
|
170
|
-
Unit(100, "m/km").
|
171
|
-
Unit(42, "meter/second").
|
172
|
-
Unit(100, "meter/km").
|
198
|
+
expect(Unit(100, "m/km")).to be_dimensionless
|
199
|
+
expect(Unit(42, "meter/second")).not_to be_unitless
|
200
|
+
expect(Unit(100, "meter/km")).to eq(Unit(Rational(1, 10)))
|
173
201
|
end
|
174
202
|
|
175
203
|
it 'should be equal to rational if dimensionless' do
|
176
|
-
Unit(100, "meter/km").
|
177
|
-
Unit(100, "meter/km").approx.
|
204
|
+
expect(Unit(100, "meter/km")).to eq(Rational(1, 10))
|
205
|
+
expect(Unit(100, "meter/km").approx).to eq(0.1)
|
178
206
|
end
|
179
207
|
|
180
208
|
it 'should be comparable' do
|
181
|
-
Unit(1, 'm').
|
182
|
-
Unit(1, 'm').
|
209
|
+
expect(Unit(1, 'm')).to be < Unit(2, 'm')
|
210
|
+
expect(Unit(1, 'm')).to be <= Unit(2, 'm')
|
183
211
|
|
184
|
-
Unit(1, 'm').
|
185
|
-
Unit(1, 'm').
|
212
|
+
expect(Unit(1, 'm')).to be <= Unit(1, 'm')
|
213
|
+
expect(Unit(1, 'm')).to be >= Unit(1, 'm')
|
186
214
|
|
187
|
-
Unit(1, 'm').
|
188
|
-
Unit(1, 'm').
|
215
|
+
expect(Unit(1, 'm')).to be > Unit(0, 'm')
|
216
|
+
expect(Unit(1, 'm')).to be >= Unit(0, 'm')
|
189
217
|
|
190
|
-
Unit(100, "m").
|
191
|
-
Unit(100, "m").
|
218
|
+
expect(Unit(100, "m")).to be < Unit(1, "km")
|
219
|
+
expect(Unit(100, "m")).to be > Unit(0.0001, "km")
|
192
220
|
end
|
193
221
|
|
194
222
|
it "should fail comparison on differing units" do
|
@@ -196,38 +224,46 @@ describe 'Unit' do
|
|
196
224
|
end
|
197
225
|
|
198
226
|
it "should keep units when the value is zero" do
|
199
|
-
Unit(0, "m").unit.
|
227
|
+
expect(Unit(0, "m").unit).to eq([[:one, :meter, 1]])
|
200
228
|
end
|
201
229
|
|
202
230
|
it "should support absolute value" do
|
203
|
-
Unit(1, "m").abs.
|
204
|
-
Unit(-1, "m").abs.
|
231
|
+
expect(Unit(1, "m").abs).to eq(Unit(1, "m"))
|
232
|
+
expect(Unit(-1, "m").abs).to eq(Unit(1, "m"))
|
205
233
|
end
|
206
234
|
|
207
235
|
it "should have #zero?" do
|
208
|
-
Unit(0, "m").zero
|
209
|
-
Unit(1, "m").zero
|
236
|
+
expect(Unit(0, "m").zero?).to eq(true)
|
237
|
+
expect(Unit(1, "m").zero?).to eq(false)
|
210
238
|
end
|
211
239
|
|
212
240
|
it "should produce an approximation" do
|
213
|
-
Unit(Rational(1,3), "m").approx.
|
241
|
+
expect(Unit(Rational(1,3), "m").approx).to eq(Unit(1.0/3.0, "m"))
|
214
242
|
end
|
215
243
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
244
|
+
describe "#round" do
|
245
|
+
it "should be able to round and return a unit" do
|
246
|
+
expect(Unit(Rational(1,3), "m").round).to eq(Unit(0, "m"))
|
247
|
+
expect(Unit(Rational(2,3), "m").round).to eq(Unit(1, "m"))
|
248
|
+
expect(Unit(0.1, "m").round).to eq(Unit(0, "m"))
|
249
|
+
expect(Unit(0.5, "m").round).to eq(Unit(1, "m"))
|
250
|
+
expect(Unit(1, "m").round).to eq(Unit(1, "m"))
|
251
|
+
end
|
252
|
+
|
253
|
+
it "should respect rounding precision" do
|
254
|
+
expect(Unit(0.1234, "m").round(0)).to eq(Unit(0, "m"))
|
255
|
+
expect(Unit(1.2345, "m").round(1)).to eq(Unit(1.2, "m"))
|
256
|
+
expect(Unit(5.4321, "m").round(2)).to eq(Unit(5.43, "m"))
|
257
|
+
end
|
222
258
|
end
|
223
259
|
|
224
260
|
end
|
225
261
|
|
226
|
-
describe "Unit DSL", :
|
262
|
+
describe "Unit DSL", dsl: true do
|
227
263
|
it 'should provide method sugar' do
|
228
|
-
1.meter.
|
229
|
-
1.meter_per_second.
|
230
|
-
1.meter.in_kilometer.
|
231
|
-
1.unit('°C').
|
264
|
+
expect(1.meter).to eq(Unit('1 meter'))
|
265
|
+
expect(1.meter_per_second).to eq(Unit('1 m/s'))
|
266
|
+
expect(1.meter.in_kilometer).to eq(Unit('1 m').in('km'))
|
267
|
+
expect(1.unit('°C')).to eq(Unit(1, '°C'))
|
232
268
|
end
|
233
269
|
end
|
data/unit.gemspec
CHANGED
@@ -1,22 +1,21 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
require File.dirname(__FILE__) + '/lib/unit/version'
|
3
|
+
require 'date'
|
3
4
|
|
4
5
|
Gem::Specification.new do |s|
|
5
|
-
s.name =
|
6
|
+
s.name = 'unit'
|
6
7
|
s.version = Unit::VERSION
|
8
|
+
s.description =
|
9
|
+
s.summary = 'Scientific unit support for ruby for calculations'
|
10
|
+
s.homepage = 'http://github.com/minad/unit'
|
11
|
+
s.license = 'MIT'
|
7
12
|
|
8
|
-
s.authors = [
|
13
|
+
s.authors = ['Daniel Mendler', 'Chris Cashwell']
|
9
14
|
s.date = Date.today.to_s
|
10
|
-
s.email = [
|
15
|
+
s.email = ['mail@daniel-mendler.de']
|
11
16
|
|
12
17
|
s.files = `git ls-files`.split("\n")
|
13
|
-
s.require_paths =
|
14
|
-
|
15
|
-
s.has_rdoc = true
|
16
|
-
s.require_paths = ["lib"]
|
17
|
-
s.rubyforge_project = s.name
|
18
|
-
s.summary = 'Scientific unit support for ruby for calculations'
|
19
|
-
s.homepage = %q{http://github.com/minad/unit}
|
18
|
+
s.require_paths = ['lib']
|
20
19
|
|
21
20
|
s.add_development_dependency('rake', ['>= 0.8.7'])
|
22
21
|
s.add_development_dependency('rspec')
|
metadata
CHANGED
@@ -1,54 +1,59 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: unit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.5.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Daniel Mendler
|
8
|
+
- Chris Cashwell
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2015-06-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
16
|
-
requirement:
|
17
|
-
none: false
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
18
17
|
requirements:
|
19
|
-
- -
|
18
|
+
- - ">="
|
20
19
|
- !ruby/object:Gem::Version
|
21
20
|
version: 0.8.7
|
22
21
|
type: :development
|
23
22
|
prerelease: false
|
24
|
-
version_requirements:
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: 0.8.7
|
25
28
|
- !ruby/object:Gem::Dependency
|
26
29
|
name: rspec
|
27
|
-
requirement:
|
28
|
-
none: false
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
29
31
|
requirements:
|
30
|
-
- -
|
32
|
+
- - ">="
|
31
33
|
- !ruby/object:Gem::Version
|
32
34
|
version: '0'
|
33
35
|
type: :development
|
34
36
|
prerelease: false
|
35
|
-
version_requirements:
|
36
|
-
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
description: Scientific unit support for ruby for calculations
|
37
43
|
email:
|
38
44
|
- mail@daniel-mendler.de
|
39
45
|
executables: []
|
40
46
|
extensions: []
|
41
47
|
extra_rdoc_files: []
|
42
48
|
files:
|
43
|
-
- .gitignore
|
44
|
-
- .travis.yml
|
49
|
+
- ".gitignore"
|
50
|
+
- ".travis.yml"
|
45
51
|
- Gemfile
|
46
52
|
- LICENSE
|
47
53
|
- README.markdown
|
48
54
|
- Rakefile
|
49
55
|
- lib/unit.rb
|
50
56
|
- lib/unit/class.rb
|
51
|
-
- lib/unit/compatibility.rb
|
52
57
|
- lib/unit/constructor.rb
|
53
58
|
- lib/unit/dsl.rb
|
54
59
|
- lib/unit/system.rb
|
@@ -69,27 +74,28 @@ files:
|
|
69
74
|
- spec/yml/io.yml
|
70
75
|
- unit.gemspec
|
71
76
|
homepage: http://github.com/minad/unit
|
72
|
-
licenses:
|
77
|
+
licenses:
|
78
|
+
- MIT
|
79
|
+
metadata: {}
|
73
80
|
post_install_message:
|
74
81
|
rdoc_options: []
|
75
82
|
require_paths:
|
76
83
|
- lib
|
77
84
|
required_ruby_version: !ruby/object:Gem::Requirement
|
78
|
-
none: false
|
79
85
|
requirements:
|
80
|
-
- -
|
86
|
+
- - ">="
|
81
87
|
- !ruby/object:Gem::Version
|
82
88
|
version: '0'
|
83
89
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
|
-
none: false
|
85
90
|
requirements:
|
86
|
-
- -
|
91
|
+
- - ">="
|
87
92
|
- !ruby/object:Gem::Version
|
88
93
|
version: '0'
|
89
94
|
requirements: []
|
90
|
-
rubyforge_project:
|
91
|
-
rubygems_version:
|
95
|
+
rubyforge_project:
|
96
|
+
rubygems_version: 2.2.2
|
92
97
|
signing_key:
|
93
|
-
specification_version:
|
98
|
+
specification_version: 4
|
94
99
|
summary: Scientific unit support for ruby for calculations
|
95
100
|
test_files: []
|
101
|
+
has_rdoc:
|