quantity 0.1.1 → 0.1.2
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.
- data/.gemspec +36 -0
- data/.gitignore +10 -0
- data/.yardopts +13 -0
- data/AUTHORS +1 -0
- data/Gemfile +4 -0
- data/README +4 -5
- data/README.md +217 -0
- data/Rakefile +48 -0
- data/VERSION +1 -1
- data/doc/.gitignore +2 -0
- data/lib/quantity.rb +10 -0
- data/lib/quantity/dimension.rb +8 -1
- data/lib/quantity/rails.rb +12 -0
- data/lib/quantity/unit.rb +17 -5
- data/lib/quantity/version.rb +1 -1
- data/quantity.gemspec +42 -0
- data/spec/dimension.spec +330 -0
- data/spec/quantity.spec +282 -0
- data/spec/systems.spec +31 -0
- data/spec/unit.spec +284 -0
- metadata +94 -24
data/spec/systems.spec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'quantity'
|
2
|
+
|
3
|
+
# This is by no means comprehensive, just to make sure that we are loading
|
4
|
+
# units based on the planned require x/y/z syntax.
|
5
|
+
|
6
|
+
describe Quantity::Dimension do
|
7
|
+
it "should have the base dimensional units available" do
|
8
|
+
require 'quantity/dimension/base'
|
9
|
+
force = Quantity::Dimension.for(:force)
|
10
|
+
force.name.should == :force
|
11
|
+
force.numerators.first.dimension.should == :length
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe Quantity::Unit do
|
16
|
+
it "should have the SI system available" do
|
17
|
+
require 'quantity/systems/si'
|
18
|
+
Quantity::Unit.for(:kilometers).name.should == :kilometer
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should have the US system available" do
|
22
|
+
require 'quantity/systems/us'
|
23
|
+
Quantity::Unit.for(:gallons).name.should == :gallon
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should blow up the world" do
|
27
|
+
Quantity::Unit.__reset!
|
28
|
+
Quantity::Dimension.__reset!
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
data/spec/unit.spec
ADDED
@@ -0,0 +1,284 @@
|
|
1
|
+
$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), 'lib')))
|
2
|
+
|
3
|
+
require 'quantity/dimension'
|
4
|
+
require 'quantity/unit'
|
5
|
+
|
6
|
+
|
7
|
+
describe Quantity::Unit do
|
8
|
+
|
9
|
+
context "definition" do
|
10
|
+
|
11
|
+
before(:all) do
|
12
|
+
Quantity::Dimension.__reset!
|
13
|
+
Quantity::Unit.__reset!
|
14
|
+
length = Quantity::Dimension.add_dimension :length, :width
|
15
|
+
Quantity::Dimension.add_dimension :'length^2', :area
|
16
|
+
Quantity::Dimension.add_dimension :'length/time^2', :acceleration
|
17
|
+
Quantity::Dimension.add_dimension :mass
|
18
|
+
Quantity::Dimension.add_dimension :time
|
19
|
+
Quantity::Dimension.add_dimension :'mass*length/time^2', :force
|
20
|
+
Quantity::Dimension.add_dimension length**3, :volume
|
21
|
+
end
|
22
|
+
|
23
|
+
before(:each) do
|
24
|
+
@length = Quantity::Dimension.for(:length)
|
25
|
+
@mass = Quantity::Dimension.for(:mass)
|
26
|
+
@area = Quantity::Dimension.for(:area)
|
27
|
+
@accel = Quantity::Dimension.for(:acceleration)
|
28
|
+
@force = Quantity::Dimension.for(:force)
|
29
|
+
@time = Quantity::Dimension.for(:time)
|
30
|
+
@volume = Quantity::Dimension.for(:volume)
|
31
|
+
|
32
|
+
@meter = Quantity::Unit.for(:meter)
|
33
|
+
@mm = Quantity::Unit.for(:mm)
|
34
|
+
@inch = Quantity::Unit.for(:inch)
|
35
|
+
@foot = Quantity::Unit.for(:foot)
|
36
|
+
@second = Quantity::Unit.for(:second)
|
37
|
+
@gram = Quantity::Unit.for(:gram)
|
38
|
+
@liter = Quantity::Unit.for(:liter)
|
39
|
+
end
|
40
|
+
|
41
|
+
after(:all) do
|
42
|
+
Quantity::Dimension.__reset!
|
43
|
+
Quantity::Unit.__reset!
|
44
|
+
end
|
45
|
+
|
46
|
+
it "supports adding basic units" do
|
47
|
+
Quantity::Unit.add_unit :meter, @length, 1000, :meters, :m
|
48
|
+
meters = Quantity::Unit.for :meter
|
49
|
+
meters.dimension.should == @length
|
50
|
+
meters.name.should == :meter
|
51
|
+
meters.value.should == 1000
|
52
|
+
end
|
53
|
+
|
54
|
+
it "supports adding units for complex dimensions" do
|
55
|
+
Quantity::Unit.add_unit :millimeter, @length, 1, :mm, :millimeters
|
56
|
+
Quantity::Unit.add_unit :second, @time, 1000, :seconds, :s
|
57
|
+
Quantity::Unit.add_unit :foot, @length, 304.8, :feet
|
58
|
+
Quantity::Unit.add_unit :inch, @length, 25.4, :inches
|
59
|
+
Quantity::Unit.add_unit :gram, @mass, 1000, :grams
|
60
|
+
Quantity::Unit.add_unit :nanosecond, @time, 10**-6, :nanoseconds
|
61
|
+
Quantity::Unit.add_unit :picogram, @mass, 10**-9, :picograms
|
62
|
+
Quantity::Unit.add_unit :liter, @volume, 10**6, :liters, :l
|
63
|
+
Quantity::Unit.add_unit :mps, @accel, 10**12, :meterspersecond
|
64
|
+
mps = Quantity::Unit.for :mps
|
65
|
+
mps.name.should == :mps
|
66
|
+
mps.value.should == 10**12
|
67
|
+
end
|
68
|
+
|
69
|
+
it "supports unit aliases" do
|
70
|
+
m1 = Quantity::Unit.for(:meter)
|
71
|
+
m2 = Quantity::Unit.for(:meters)
|
72
|
+
m3 = Quantity::Unit.for(:m)
|
73
|
+
m1.name.should == :meter
|
74
|
+
m2.name.should == :meter
|
75
|
+
m3.name.should == :meter
|
76
|
+
end
|
77
|
+
|
78
|
+
it "interns units" do
|
79
|
+
m1 = Quantity::Unit.for(:meter)
|
80
|
+
m2 = Quantity::Unit.for(:meters)
|
81
|
+
m1.should equal m2
|
82
|
+
end
|
83
|
+
|
84
|
+
it "constructs units from an options hash" do
|
85
|
+
sqft = Quantity::Unit.new({ :name => :sqft, :dimension => @area, :units => { @length => @foot}})
|
86
|
+
sqft.name.should == :sqft
|
87
|
+
sqft.dimension.should == @area
|
88
|
+
sqft.value.should be_close @foot.value**2, 10**-5
|
89
|
+
sqft.string_form.should == 'foot^2'
|
90
|
+
end
|
91
|
+
|
92
|
+
it "constructs complex units from an options hash" do
|
93
|
+
area_p_sec = @area / @time
|
94
|
+
f2ps = Quantity::Unit.new({:name => :f2ps, :dimension => area_p_sec,
|
95
|
+
:units => { @length => @foot, @time => @second }})
|
96
|
+
f2ps.name.should == :f2ps
|
97
|
+
f2ps.value.should be_close((@foot.value**2)/@second.value, 10**-5)
|
98
|
+
f2ps.string_form.should == 'foot^2/second'
|
99
|
+
f2ps.dimension.string_form.should == 'length^2/time'
|
100
|
+
f2ps.value.should be_close 92.90304, 10**-5
|
101
|
+
end
|
102
|
+
|
103
|
+
it "allows a full reset" do
|
104
|
+
Quantity::Unit.__reset!
|
105
|
+
nil.should == Quantity::Unit.for(:meter)
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
context "use cases" do
|
111
|
+
before(:all) do
|
112
|
+
Quantity::Dimension.__reset!
|
113
|
+
Quantity::Unit.__reset!
|
114
|
+
@length = Quantity::Dimension.add_dimension :length, :width
|
115
|
+
@area = Quantity::Dimension.add_dimension :'length^2', :area
|
116
|
+
@accel = Quantity::Dimension.add_dimension :'length/time^2', :acceleration
|
117
|
+
@mass = Quantity::Dimension.add_dimension :mass
|
118
|
+
@time = Quantity::Dimension.add_dimension :time
|
119
|
+
@force = Quantity::Dimension.add_dimension :'mass*length/time^2', :force
|
120
|
+
@volume = Quantity::Dimension.add_dimension @length**3, :volume
|
121
|
+
|
122
|
+
Quantity::Unit.__reset!
|
123
|
+
Quantity::Unit.add_unit :meter, @length, 1000, :meters, :m
|
124
|
+
Quantity::Unit.add_unit :millimeter, @length, 1, :mm, :millimeters
|
125
|
+
Quantity::Unit.add_unit :second, @time, 1000, :seconds, :s
|
126
|
+
Quantity::Unit.add_unit :foot, @length, 304.8, :feet
|
127
|
+
Quantity::Unit.add_unit :inch, @length, 25.4, :inches
|
128
|
+
Quantity::Unit.add_unit :gram, @mass, 1000, :grams
|
129
|
+
Quantity::Unit.add_unit :nanosecond, @time, 10**-6, :nanoseconds
|
130
|
+
Quantity::Unit.add_unit :picogram, @mass, 10**-9, :picograms
|
131
|
+
Quantity::Unit.add_unit :liter, @volume, 10**6, :liters, :l
|
132
|
+
Quantity::Unit.add_unit :mps, @accel, 10**12, :meterspersecond
|
133
|
+
end
|
134
|
+
|
135
|
+
before(:each) do
|
136
|
+
@length = Quantity::Dimension.for(:length)
|
137
|
+
@mass = Quantity::Dimension.for(:mass)
|
138
|
+
@area = Quantity::Dimension.for(:area)
|
139
|
+
@accel = Quantity::Dimension.for(:acceleration)
|
140
|
+
@force = Quantity::Dimension.for(:force)
|
141
|
+
@time = Quantity::Dimension.for(:time)
|
142
|
+
@volume = Quantity::Dimension.for(:volume)
|
143
|
+
|
144
|
+
@meter = Quantity::Unit.for(:meter)
|
145
|
+
@mm = Quantity::Unit.for(:mm)
|
146
|
+
@inch = Quantity::Unit.for(:inch)
|
147
|
+
@foot = Quantity::Unit.for(:foot)
|
148
|
+
@second = Quantity::Unit.for(:second)
|
149
|
+
@gram = Quantity::Unit.for(:gram)
|
150
|
+
@liter = Quantity::Unit.for(:liter)
|
151
|
+
@mps = Quantity::Unit.for(:mps)
|
152
|
+
end
|
153
|
+
|
154
|
+
after(:all) do
|
155
|
+
Quantity::Dimension.__reset!
|
156
|
+
Quantity::Unit.__reset!
|
157
|
+
end
|
158
|
+
|
159
|
+
context "informational" do
|
160
|
+
it "has a symbol name" do
|
161
|
+
@second.name.should == :second
|
162
|
+
end
|
163
|
+
|
164
|
+
it "has a symbol name for complex units" do
|
165
|
+
@mps.name.should == :mps
|
166
|
+
end
|
167
|
+
|
168
|
+
it "has a reduced form name" do
|
169
|
+
@mps.name.should == :mps
|
170
|
+
end
|
171
|
+
|
172
|
+
it "has a reduced form name for complex units" do
|
173
|
+
@mps.reduced_name.should == :'meters/second^2'
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
context "multiplication" do
|
178
|
+
|
179
|
+
it "supports basic units" do
|
180
|
+
sqft = @foot * @foot
|
181
|
+
sqft.name.should == :'foot^2'
|
182
|
+
end
|
183
|
+
|
184
|
+
it "supports complex units" do
|
185
|
+
sqft = @foot * @foot
|
186
|
+
cubeft = sqft * @foot
|
187
|
+
cubeft.name.should == :'foot^3'
|
188
|
+
end
|
189
|
+
|
190
|
+
it "supports units of different dimensions" do
|
191
|
+
s_f3 = @second * (@foot * @foot * @foot)
|
192
|
+
s_f3.name.should == :'foot^3*second'
|
193
|
+
s_f3.value.should == @foot.value**3 / @second.value
|
194
|
+
end
|
195
|
+
|
196
|
+
it "supports different units of the same dimension" do
|
197
|
+
sqft = @foot * @meter
|
198
|
+
sqft.name.should == :'foot^2'
|
199
|
+
sqft.value.should == @foot.value**2
|
200
|
+
end
|
201
|
+
|
202
|
+
it "defaults to the second unit when multiplying units of the same dimension" do
|
203
|
+
sqft = @meter * @foot
|
204
|
+
sqft.name.should == :'foot^2'
|
205
|
+
sqft.value.should be_close 92903.04, 10**-5
|
206
|
+
end
|
207
|
+
|
208
|
+
end
|
209
|
+
|
210
|
+
context "division" do
|
211
|
+
|
212
|
+
it "supports basic units" do
|
213
|
+
m_s = @meter / @second
|
214
|
+
m_s.name.should == :'meter/second'
|
215
|
+
end
|
216
|
+
|
217
|
+
it "supports mixed units" do
|
218
|
+
result = @meter * @gram / @second
|
219
|
+
result.name.should == :'meter*gram/second'
|
220
|
+
end
|
221
|
+
|
222
|
+
it "supports mixed unit divisors" do
|
223
|
+
result = @meter / (@gram * @second)
|
224
|
+
result.name.should == :'meter/gram*second'
|
225
|
+
result.value.should == @meter.value / (@gram.value*@second.value)
|
226
|
+
end
|
227
|
+
|
228
|
+
it "simplifies results" do
|
229
|
+
result = (@meter * @second) / @second
|
230
|
+
result.name.should == :meter
|
231
|
+
result.value.should == @meter.value
|
232
|
+
end
|
233
|
+
|
234
|
+
it "supports named complex dimensions" do
|
235
|
+
lpm = @liter / @meter
|
236
|
+
lpm.name.should == :'liter/meter'
|
237
|
+
lpm.reduced_name.should == :'mm^2'
|
238
|
+
lpm.value.should == @liter.value / @meter.value
|
239
|
+
end
|
240
|
+
|
241
|
+
end
|
242
|
+
|
243
|
+
context "exponentiation" do
|
244
|
+
it "supports positive exponents" do
|
245
|
+
(@foot**2).should == (@foot * @foot)
|
246
|
+
end
|
247
|
+
|
248
|
+
it "supports negative exponents" do
|
249
|
+
(@foot**-1).name.should == :'1/foot'
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
context "conversions" do
|
254
|
+
|
255
|
+
it "converts basic units" do
|
256
|
+
@foot.convert(:meter).should == @meter
|
257
|
+
end
|
258
|
+
|
259
|
+
it "converts the portion of a given complex unit to a target unit" do
|
260
|
+
@mps.convert(:foot).should == @foot / @second
|
261
|
+
@liter.convert(:mm).should == @mm**3
|
262
|
+
end
|
263
|
+
|
264
|
+
it "won't convert a simple unit to another dimension" do
|
265
|
+
lambda { @foot.convert(:second) }.should raise_error TypeError
|
266
|
+
end
|
267
|
+
|
268
|
+
it "won't convert a complex unit to a dimension it doesn't contain" do
|
269
|
+
lambda { @mps.convert(:gram) }.should raise_error TypeError
|
270
|
+
end
|
271
|
+
|
272
|
+
it "won't convert to a higher-order unit unless it has an exact matching dimension" do
|
273
|
+
lambda { @liter.convert(:'mm^2') }.should raise_error TypeError
|
274
|
+
end
|
275
|
+
|
276
|
+
it "breaks down named complex units" do
|
277
|
+
@liter.convert(:mm).should == @mm**3
|
278
|
+
end
|
279
|
+
|
280
|
+
end
|
281
|
+
|
282
|
+
end
|
283
|
+
|
284
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quantity
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 2
|
9
|
+
version: 0.1.2
|
5
10
|
platform: ruby
|
6
11
|
authors:
|
7
12
|
- Ben Lavender
|
@@ -10,31 +15,76 @@ autorequire:
|
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
17
|
|
13
|
-
date:
|
18
|
+
date: 2011-05-03 00:00:00 -05:00
|
14
19
|
default_executable:
|
15
20
|
dependencies:
|
16
21
|
- !ruby/object:Gem::Dependency
|
17
22
|
name: rspec
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - "="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
segments:
|
30
|
+
- 1
|
31
|
+
- 2
|
32
|
+
- 9
|
33
|
+
version: 1.2.9
|
34
|
+
type: :development
|
35
|
+
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rake
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - "="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
- 8
|
47
|
+
- 7
|
48
|
+
version: 0.8.7
|
18
49
|
type: :development
|
19
|
-
|
20
|
-
|
50
|
+
version_requirements: *id002
|
51
|
+
- !ruby/object:Gem::Dependency
|
52
|
+
name: rspec
|
53
|
+
prerelease: false
|
54
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
21
56
|
requirements:
|
22
|
-
- - "
|
57
|
+
- - "="
|
23
58
|
- !ruby/object:Gem::Version
|
59
|
+
segments:
|
60
|
+
- 1
|
61
|
+
- 2
|
62
|
+
- 9
|
24
63
|
version: 1.2.9
|
25
|
-
|
64
|
+
type: :development
|
65
|
+
version_requirements: *id003
|
26
66
|
- !ruby/object:Gem::Dependency
|
27
67
|
name: yard
|
28
|
-
|
29
|
-
|
30
|
-
|
68
|
+
prerelease: false
|
69
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
31
71
|
requirements:
|
32
|
-
- - "
|
72
|
+
- - "="
|
33
73
|
- !ruby/object:Gem::Version
|
74
|
+
segments:
|
75
|
+
- 0
|
76
|
+
- 5
|
77
|
+
- 2
|
34
78
|
version: 0.5.2
|
35
|
-
|
36
|
-
|
37
|
-
|
79
|
+
type: :development
|
80
|
+
version_requirements: *id004
|
81
|
+
description: |
|
82
|
+
Quantity provides first-class quantities, units, and base quantities in pure ruby.
|
83
|
+
Things like 1.meter / 1.second == 1 meter/second.
|
84
|
+
|
85
|
+
email:
|
86
|
+
- blavender@gmail.com
|
87
|
+
- arto.bendiken@gmail.com
|
38
88
|
executables: []
|
39
89
|
|
40
90
|
extensions: []
|
@@ -42,13 +92,22 @@ extensions: []
|
|
42
92
|
extra_rdoc_files: []
|
43
93
|
|
44
94
|
files:
|
95
|
+
- .gemspec
|
96
|
+
- .gitignore
|
97
|
+
- .yardopts
|
45
98
|
- AUTHORS
|
99
|
+
- Gemfile
|
46
100
|
- README
|
101
|
+
- README.md
|
102
|
+
- Rakefile
|
47
103
|
- UNLICENSE
|
48
104
|
- VERSION
|
105
|
+
- doc/.gitignore
|
106
|
+
- lib/quantity.rb
|
49
107
|
- lib/quantity/all.rb
|
50
|
-
- lib/quantity/dimension/base.rb
|
51
108
|
- lib/quantity/dimension.rb
|
109
|
+
- lib/quantity/dimension/base.rb
|
110
|
+
- lib/quantity/rails.rb
|
52
111
|
- lib/quantity/systems/enumerable.rb
|
53
112
|
- lib/quantity/systems/imperial.rb
|
54
113
|
- lib/quantity/systems/information.rb
|
@@ -56,34 +115,45 @@ files:
|
|
56
115
|
- lib/quantity/systems/us.rb
|
57
116
|
- lib/quantity/unit.rb
|
58
117
|
- lib/quantity/version.rb
|
59
|
-
-
|
60
|
-
|
118
|
+
- quantity.gemspec
|
119
|
+
- spec/dimension.spec
|
120
|
+
- spec/quantity.spec
|
121
|
+
- spec/systems.spec
|
122
|
+
- spec/unit.spec
|
123
|
+
has_rdoc: true
|
61
124
|
homepage: http://quantity.rubyforge.org/
|
62
|
-
licenses:
|
63
|
-
|
125
|
+
licenses: []
|
126
|
+
|
64
127
|
post_install_message:
|
65
128
|
rdoc_options: []
|
66
129
|
|
67
130
|
require_paths:
|
68
131
|
- lib
|
69
132
|
required_ruby_version: !ruby/object:Gem::Requirement
|
133
|
+
none: false
|
70
134
|
requirements:
|
71
135
|
- - ">="
|
72
136
|
- !ruby/object:Gem::Version
|
73
|
-
|
74
|
-
|
137
|
+
segments:
|
138
|
+
- 0
|
139
|
+
version: "0"
|
75
140
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
141
|
+
none: false
|
76
142
|
requirements:
|
77
143
|
- - ">="
|
78
144
|
- !ruby/object:Gem::Version
|
145
|
+
segments:
|
146
|
+
- 0
|
79
147
|
version: "0"
|
80
|
-
version:
|
81
148
|
requirements: []
|
82
149
|
|
83
150
|
rubyforge_project: quantity
|
84
|
-
rubygems_version: 1.3.
|
151
|
+
rubygems_version: 1.3.7
|
85
152
|
signing_key:
|
86
153
|
specification_version: 3
|
87
154
|
summary: Units and quantities for Ruby.
|
88
|
-
test_files:
|
89
|
-
|
155
|
+
test_files:
|
156
|
+
- spec/dimension.spec
|
157
|
+
- spec/quantity.spec
|
158
|
+
- spec/systems.spec
|
159
|
+
- spec/unit.spec
|