quantity 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,7 +2,7 @@ class Quantity
2
2
  module VERSION
3
3
  MAJOR = 0
4
4
  MINOR = 1
5
- TINY = 0
5
+ TINY = 2
6
6
  EXTRA = nil
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY].join('.')
@@ -0,0 +1,42 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "quantity/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "quantity"
7
+ s.version = Quantity::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Ben Lavender", "Arto Bendiken"]
10
+ s.email = ["blavender@gmail.com", "arto.bendiken@gmail.com"]
11
+ s.homepage = %q{http://quantity.rubyforge.org/}
12
+ s.summary = %q{Units and quantities for Ruby.}
13
+ s.description = %q{Quantity provides first-class quantities, units, and base quantities in pure ruby.
14
+ Things like 1.meter / 1.second == 1 meter/second.
15
+ }
16
+
17
+ s.rubyforge_project = %q{quantity}
18
+
19
+ s.add_development_dependency "rspec", ["= 1.2.9"]
20
+ if s.respond_to? :specification_version then
21
+ s.specification_version = 3
22
+
23
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
24
+ s.add_development_dependency(%q<rake>, ["= 0.8.7"])
25
+ s.add_development_dependency(%q<rspec>, ["= 1.2.9"])
26
+ s.add_development_dependency(%q<yard>, ["= 0.5.2"])
27
+ else
28
+ s.add_dependency(%q<rake>, ["= 0.8.7"])
29
+ s.add_dependency(%q<rspec>, ["= 1.2.9"])
30
+ s.add_dependency(%q<yard>, ["= 0.5.2"])
31
+ end
32
+ else
33
+ s.add_dependency(%q<rake>, ["= 0.8.7"])
34
+ s.add_dependency(%q<rspec>, ["= 1.2.9"])
35
+ s.add_dependency(%q<yard>, ["= 0.5.2"])
36
+ end
37
+
38
+ s.files = `git ls-files`.split("\n")
39
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
40
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
41
+ s.require_paths = ["lib"]
42
+ end
@@ -0,0 +1,330 @@
1
+ $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), 'lib')))
2
+
3
+ require 'quantity/dimension'
4
+
5
+ describe Quantity::Dimension do
6
+
7
+ ## we test other things, so make sure dimensions are destroyed before we start
8
+ before :all do
9
+ Quantity::Dimension.__reset!
10
+ end
11
+
12
+ context "definition" do
13
+ after :all do
14
+ Quantity::Dimension.__reset!
15
+ end
16
+
17
+ context "creation via DSL" do
18
+ it "creates simple dimensions" do
19
+ Quantity::Dimension.add_dimension :length, :width
20
+ length = Quantity::Dimension.for(:length)
21
+ length.to_s.should == "length"
22
+ length.name.should == :length
23
+ end
24
+
25
+ it "creates complex dimensions" do
26
+ Quantity::Dimension.add_dimension :'length^2', :area
27
+ area = Quantity::Dimension.for(:area)
28
+ area.to_s.should == "area"
29
+ area.name.should == :area
30
+ area.reduced_name.should == :'length^2'
31
+ end
32
+
33
+ end
34
+
35
+ it "returns nil for non-existent dimensions" do
36
+ Quantity::Dimension.for(:nodimension).should be nil
37
+ end
38
+
39
+ # this is useful for testing
40
+ it "should allow resetting the world" do
41
+ Quantity::Dimension.__reset!
42
+ x = Quantity::Dimension.for(:length)
43
+ x.should == nil
44
+ end
45
+ end
46
+
47
+ context "use case" do
48
+
49
+ before :all do
50
+ Quantity::Dimension.__reset!
51
+ length = Quantity::Dimension.add_dimension :length, :width
52
+ Quantity::Dimension.add_dimension :'length^2', :area
53
+ mass = Quantity::Dimension.add_dimension :mass
54
+ time = Quantity::Dimension.add_dimension :time
55
+ Quantity::Dimension.add_dimension :'length/time^2', :acceleration
56
+ Quantity::Dimension.add_dimension(((mass * length) / time**2), :force)
57
+ end
58
+
59
+ # We use these for testing dimension. the systems are tested in a separate spec.
60
+ # we'll be using these for the rest of the specs
61
+ before(:each) do
62
+ @length = Quantity::Dimension.for(:length)
63
+ @mass = Quantity::Dimension.for(:mass)
64
+ @area = Quantity::Dimension.for(:area)
65
+ @accel = Quantity::Dimension.for(:acceleration)
66
+ @force = Quantity::Dimension.for(:force)
67
+ @time = Quantity::Dimension.for(:time)
68
+ end
69
+
70
+ after :all do
71
+ Quantity::Dimension.__reset!
72
+ end
73
+
74
+ it "has a name for simple dimensions" do
75
+ @mass.name.should == :mass
76
+ end
77
+
78
+ it "uses the primary name for dimensions with aliases" do
79
+ @length.name.should == :length
80
+ end
81
+
82
+ it "has a name for named complex dimensions" do
83
+ @force.name.should == :force
84
+ end
85
+
86
+ it "provides a reduced form for base dimensions" do
87
+ @length.reduced_name.should == :'length'
88
+ end
89
+
90
+ it "provides a reduced form for complex dimensions" do
91
+ @force.reduced_name.should == :'length*mass/time^2'
92
+ end
93
+
94
+ it "provides a hash form for simple dimensions" do
95
+ @length.hash.should == { :length => 1 }
96
+ end
97
+
98
+ it "provides a hash form for unnamed dimensions" do
99
+ lm = @length * @mass
100
+ lm.hash.should == { :length => 1, :mass => 1 }
101
+ end
102
+
103
+ it "provides a hash form for named dimensions" do
104
+ @area.to_hash.should == { :area => 1 }
105
+ end
106
+
107
+ it "provides a reduced hash form" do
108
+ @length.to_hash.should == @length.reduced_hash
109
+ @area.reduced.to_hash.should == { :length => 2 }
110
+ end
111
+
112
+ it "provides a hash form with negative components" do
113
+ @force.to_hash.should = { :length => 1, :mass => -1 , :time => -2 }
114
+ end
115
+
116
+ it "provides a reduced form" do
117
+ @area.name.should == :area
118
+ @area.reduce.name.should == :'length^2'
119
+ end
120
+
121
+ ## this is going to be removed for hashes, but unit still uses it, so we test it.
122
+ it "should track numerators and denominators" do
123
+ @length.numerators.first.dimension.should == :length
124
+ @length.numerators.first.power.should == 1
125
+ @force.numerators.first.dimension.should == :length
126
+ @force.numerators.first.power== 1
127
+ @force.numerators[1].dimension.should == :mass
128
+ @force.numerators[1].power== 1
129
+ @force.denominators.first.dimension.should == :time
130
+ @force.denominators.first.power.should == 2
131
+ end
132
+
133
+ # This is a bad interface and will be removed.
134
+ it "should provide a vaguely parsable string format" do
135
+ component = Quantity::Dimension::DimensionComponent.new(:length,3)
136
+ component2 = Quantity::Dimension::DimensionComponent.new(:length,2)
137
+ component3 = Quantity::Dimension::DimensionComponent.new(:time,2)
138
+ component4 = Quantity::Dimension::DimensionComponent.new(:length,5)
139
+ Quantity::Dimension.string_form([component],[]).should=='length^3'
140
+ Quantity::Dimension.string_form([component,component2],[]).should=='length^3*length^2'
141
+ Quantity::Dimension.string_form([component,component2],[component3]).should=='length^3*length^2/time^2'
142
+ Quantity::Dimension.parse_string_form('length^3*length^2/time^2').inspect.should == [[component4],[component3]].inspect
143
+ end
144
+
145
+ context "multiplication" do
146
+ it "multiplies base dimensions" do
147
+ mass_squared = @mass * @mass
148
+ mass_squared.name.should == :'mass^2'
149
+ end
150
+
151
+ it "interns base multiplcation results" do
152
+ mass_squared = @mass * @mass
153
+ mass_squared_again = @mass * @mass
154
+ mass_squared.should equal mass_squared_again
155
+ end
156
+
157
+ it "multiplies derived complex dimensions and base dimensions" do
158
+ mass_squared = @mass * @mass
159
+ mass_cubed = mass_squared * @mass
160
+ mass_cubed.name.should == :'mass^3'
161
+ end
162
+
163
+ it "multiplies base dimensions and derived complex dimensions" do
164
+ mass_squared = @mass * @mass
165
+ mass_cubed = @mass * mass_squared
166
+ mass_cubed.name.should == :'mass^3'
167
+ end
168
+
169
+ it "interns mixed multiplcation results" do
170
+ mass_squared = @mass * @mass
171
+ mass_cubed = @mass * mass_squared
172
+ mass_cubed_again = mass_squared * @mass
173
+ mass_cubed.should equal mass_cubed_again
174
+ end
175
+
176
+ it "multiplies derived complex dimensions with each other" do
177
+ mass_squared = @mass * @mass
178
+ time_squared = @time * @time
179
+ mt = mass_squared * time_squared
180
+ mt.name.should == :'mass^2*time^2'
181
+ end
182
+
183
+ it "multiplies named complex dimensions with base dimensions" do
184
+ ma = @area * @mass
185
+ ma.name.should == :'area*mass'
186
+ end
187
+
188
+ it "multiplies base dimensions with named complex dimensions" do
189
+ ma = @mass * @area
190
+ ma.name.should == :'area*mass'
191
+ end
192
+
193
+ it "multiplies named complex dimensions with each other" do
194
+ l4 = @area * @area
195
+ l4.name.should == :'area^2'
196
+ end
197
+
198
+ it "performs exponentiation" do
199
+ (@length**3).should == @length * @length * @length
200
+ end
201
+
202
+ it "allows naming of units first derived via multiplication" do
203
+ t2 = @time * @time
204
+ Quantity::Dimension.add_dimension @time * @time, :time_squared
205
+ Quantity::Dimension.for(:time_squared).should equal t2
206
+ end
207
+
208
+ end
209
+
210
+ # in division, we test base / complex, but based on equality and
211
+ # multiplication tests, we do not specifically test division against named
212
+ # and derived. either is fine unless we expect different semantics
213
+ context "division" do
214
+
215
+ context "with base dividends" do
216
+
217
+ it "supports base divisors" do
218
+ speed = @length / @time
219
+ speed.name.should == :'length/time'
220
+ end
221
+
222
+ it "supports complex divisors" do
223
+ ta = @time / @area
224
+ ta.name.should == :'time/area'
225
+ end
226
+
227
+ it "supports complex divisors with a negative exponent" do
228
+ mt = @mass / @time
229
+ lmt = @length / mt
230
+ lmt.name.should == :'length*time/mass'
231
+ end
232
+
233
+ # This one is a tough call. Supporting this is difficult, since
234
+ # acceleration as a denominator is the same as multiplying by the
235
+ # reciprocal. It's confusing for the internal representation. I'm also
236
+ # hard-pressed to find examples of this being useful, i.e. when's it
237
+ # useful to have something divided by force? length per force?
238
+ it "supports reduced form with a named complex divisor " do
239
+ ma = @mass / @accel
240
+ ma.name.should == :'mass*time^2/length'
241
+ end
242
+
243
+ it "supports named form with a named complex divisor" do
244
+ ma = @mass / @accel
245
+ ma.name.should == :'mass/acceleration'
246
+ end
247
+
248
+ it "supports a nil numerator component" do
249
+ speed = @mass / @time
250
+ t_neg_1 = speed / @mass
251
+ t_neg_1.name.should == :'1/time'
252
+ t_neg_1.reduced_hash.should == { :time => -1 }
253
+ end
254
+
255
+ end
256
+
257
+ context "with complex dividends" do
258
+ it "supports base dimension divisors" do
259
+ am = @area / @mass
260
+ am.reduced_name.should == :'length^2/mass'
261
+ am.name.should == :'area/mass'
262
+ end
263
+
264
+ it "supports complex divisors" do
265
+ am = @area / (@mass * @mass)
266
+ am.reduced_name.should == :'length^2/mass^2'
267
+ am.name.should == :'area/mass^2'
268
+ end
269
+
270
+ it "supports divisors with a negative exponent" do
271
+ result = (@mass * @mass) / (@length / @time)
272
+ result.name.should == :'mass^2*time/length'
273
+ end
274
+
275
+ it "supports reduced form for divisors with a negative exponent" do
276
+ result = (@mass * @mass) / @accel
277
+ result.name.should == :'mass^2*time^2/length'
278
+ end
279
+ end
280
+
281
+ context "with dividends with negative exponents" do
282
+ it "supports reduced form for base divisor" do
283
+ jerk = @accel / @time
284
+ jerk.reduced_name.should == :'length/time^3'
285
+ end
286
+
287
+ it "supports named form for base divisor" do
288
+ jerk = @accel / @time
289
+ jerk.name.should == :'acceleration/time'
290
+ end
291
+
292
+ it "supports reduced form for complex divisors" do
293
+ af = @accel / (@mass * @mass)
294
+ af.reduced_name.should == :'length/mass^2*time^2'
295
+ end
296
+
297
+ it "supports named form for complex divisors" do
298
+ af = @accel / (@mass * @mass)
299
+ af.name.should == :'acceleration/mass^2'
300
+ end
301
+
302
+ it "only supports reduced form for a subdimension divisor" do
303
+ fa = @force / @accel
304
+ fa.reduced_name.should == :'force/acceleration'
305
+ fa.reduced_name.should == :'mass'
306
+ end
307
+
308
+ it "supports named form for complex divisors with negative exponents" do
309
+ tm = @time / @mass
310
+ fa = @force / tm
311
+ fa.name.should == :'force*mass/time'
312
+ end
313
+
314
+ it "supports reduced form for a complex divisors with negative exponents" do
315
+ tm = @time / @mass
316
+ fa = @force / tm
317
+ fa.reduced_name.should == :'length*mass^2/time^3'
318
+ end
319
+ end
320
+
321
+ context "as negative exponentiation" do
322
+ it "supports negative exponents" do
323
+ length_neg_2 = @length**-2
324
+ length_neg_2.name.should == :'1/length^2'
325
+ end
326
+ end
327
+
328
+ end
329
+ end
330
+ end
@@ -0,0 +1,282 @@
1
+ $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), 'lib')))
2
+
3
+ require 'quantity'
4
+ require 'quantity/systems/si'
5
+ require 'quantity/systems/us'
6
+
7
+ describe Quantity do
8
+
9
+ context "instantiation" do
10
+ it "should be instantiated from numbers" do
11
+ 1.meter.should == 1
12
+ 2.5.feet.should == 2.5
13
+ end
14
+
15
+ it "should work with alias names" do
16
+ 2.meters.should == 2
17
+ end
18
+
19
+ it "should know what it measures" do
20
+ 2.meters.unit.dimension.name.should == :length
21
+ 2.meters.measures.name.should == :length
22
+ end
23
+
24
+ it "should know its units" do
25
+ 2.meters.unit.name.should == :meter
26
+ 2.meters.units.should == :meter
27
+ end
28
+
29
+ it "should have a string representation" do
30
+ 2.meters.to_s.should == "2 meter"
31
+ (2.meters * 2.meters).to_s.should == (defined?(Rational) ? "4 meter^2" : "4.0 meter^2")
32
+ end
33
+
34
+ end
35
+
36
+ context "conversions" do
37
+ it "converts from one type to another" do
38
+ 1.meter.in_centimeters.should == 100
39
+ 10.meters.convert(:feet).should be_close 32.808399.feet, 10**-6
40
+ end
41
+
42
+ it "converts from one type to another when not using the reference value for that dimension" do
43
+ 1.kilometer.in_centimeters.should == 100_000
44
+ end
45
+
46
+ it "fails to convert things that do not measure the same dimension" do
47
+ lambda { 1.picogram.in_meters }.should raise_error ArgumentError
48
+ end
49
+
50
+ it "converts derived units" do
51
+ Quantity.new(2,'m^2').to_feet.to_f.should be_close 21.5278208, 10**-5
52
+ Quantity.new(2,'m^2').convert('foot^2').to_f.should be_close 21.5278208, 10**-5
53
+ end
54
+
55
+ it "converts derived units to named units" do
56
+ (1.centimeter * 1.centimeter * 1.centimeter).should == 0.1.centiliter
57
+ (1000.mm * 1.mm * 1.mm).should == 1.ml
58
+ (1.mm**3).unit.name.should == 'millimeter^3'
59
+ (1.mm**3).measures.name.should == :volume
60
+ (1.centimeter * 1.centimeter).measures.name.should == :area
61
+ (30.meters / 1.second).measures.name.should == :speed
62
+ end
63
+
64
+ it "reduces derived units" do
65
+ ((1.meter / 1.second) * 1.second).should == 1.meter
66
+ end
67
+
68
+ it "respond_to? conversion methods" do
69
+ 1.meter.should respond_to(:in_centimeters)
70
+ 1.meter.should respond_to(:to_centimeters)
71
+ end
72
+
73
+ end
74
+
75
+ context "math operations" do
76
+
77
+ context "equality" do
78
+ it "enforces exact equality" do
79
+ 12.meter.should == 12.meters
80
+ end
81
+
82
+ it "does not intern quantities" do
83
+ 12.meter.should_not equal 12.meters
84
+ end
85
+
86
+ it "enforces equality across a dimension" do
87
+ 1.meter.should == 100.centimeter
88
+ end
89
+
90
+ it "does not find quantities on different dimensions to be equal" do
91
+ 1.millimeter.should_not == 1.milligram
92
+ end
93
+
94
+ end
95
+
96
+ context "general" do
97
+ it "supports abs" do
98
+ ((-(5.seconds)).abs).should == 5.seconds
99
+ (-5).seconds.abs.should == 5.seconds
100
+ 5.seconds.abs.should == 5.seconds
101
+ end
102
+
103
+ it "supports @-" do
104
+ (-(35.meters)).should be_close -(114.829396.feet), 10**-5
105
+ end
106
+
107
+ it "supports @+" do
108
+ +4.kilograms.should == 4.kilograms
109
+ end
110
+
111
+ it "supports %" do
112
+ (35.meters % 6).should == 5.meters
113
+ (35.meters % 6.feet).should be_close 0.2528.meters, 10**-5
114
+ end
115
+
116
+ it "supports modulo" do
117
+ 4.kilograms.modulo(15.grams).should == 10.grams
118
+ end
119
+
120
+ it "supports round" do
121
+ 15.6.meters.round.should == 16.meters
122
+ end
123
+
124
+ it "supports truncate" do
125
+ 15.2.meters.truncate.should == 15.meters
126
+ end
127
+
128
+ it "supports ceil" do
129
+ 15.2.meters.ceil.should == 16.meters
130
+ end
131
+
132
+ it "supports floor" do
133
+ (-5.5.meters).floor.should == -6.meters
134
+ end
135
+
136
+ it "supports divmod" do
137
+ 11.meters.divmod(3).should == [3.meter,2.meter]
138
+ 11.meters.divmod(3.meters).should == [3.meter,2.meter]
139
+ 11.meters.divmod(-3).should == [-4.meter,-1.meter]
140
+ 11.meters.divmod(-3.meters).should == [-4.meter,-1.meter]
141
+ 11.meters.divmod(3.5).should == [3.meter,0.5.meter]
142
+ 11.meters.divmod(3.5.meters).should == [3.meter,0.5.meter]
143
+ (-11.meters).divmod(3.5).should == [-4.meter,3.0.meter]
144
+ (-11.meters).divmod(3.5.meters).should == [-4.meter,3.0.meter]
145
+ 11.5.meters.divmod(3.5).should == [3.meter,1.0.meter]
146
+ 11.5.meters.divmod(3.5.meters).should == [3.meter,1.0.meter]
147
+ end
148
+
149
+ it "supports zero?" do
150
+ 0.kilograms.zero?.should == true
151
+ end
152
+ end
153
+
154
+ context "addition and subtraction" do
155
+ it "adds quantities of the same thing" do
156
+ (12.meters + 5.meters).should == 17.meters
157
+ end
158
+
159
+ it "adds quantities of the same dimension" do
160
+ (12.meters + 15.centimeters).should == 1215.centimeters
161
+ end
162
+
163
+ it "adds numerics to quantities" do
164
+ 3.meters.should == 1.meter + 2
165
+ end
166
+
167
+ it "adds quantities to numerics" do
168
+ 6.4.meters.should == 4.4 + 2.meter
169
+ end
170
+
171
+ it "does not add items of different types" do
172
+ lambda { 12.meters + 24.picograms }.should raise_error TypeError
173
+ end
174
+
175
+ it "adds negative quantities" do
176
+ (5.meters + (-3.meters)).should == 2.meters
177
+ end
178
+
179
+ it "subtracts quantities of the same thing" do
180
+ (12.meters - 3.meters).should == 9.meters
181
+ end
182
+
183
+ it "subtracts quantities of the same dimension" do
184
+ (12.meters - 3650.centimeters).should == -2450.centimeters
185
+ end
186
+
187
+ it "does not add items of different types" do
188
+ lambda { (12.meters - 3650.picograms)}.should raise_error TypeError
189
+ end
190
+
191
+ it "subtracts numerics from quantities" do
192
+ (12.meters - 3).should == 9.meters
193
+ end
194
+
195
+ it "subtracts quantities from numerics" do
196
+ (15 - 5.meters).should == 10.meters
197
+ end
198
+ end
199
+
200
+ context "multiplication" do
201
+
202
+ it "multiplies quantities of the same unit" do
203
+ (2.meters * 5.meters).should == 10
204
+ end
205
+
206
+ it "multiplies quantities of the same dimension" do
207
+ (1.meter * 1.foot).should be_close Quantity.new(3.280839,:'foot^2'), 10**-5
208
+ end
209
+
210
+ it "uses the unit on the right when multiplying across the same dimension" do
211
+ (1.meter * 1.foot).unit.name.should == :'foot^2'
212
+ end
213
+
214
+ it "multiplies complex units" do
215
+ (3.meter * Quantity.new(1,:'m^2')).should == Quantity.new(3,:'m^3')
216
+ end
217
+
218
+ it "multiplies units of different dimensions" do
219
+ (2.meters * 2.kilograms).should == Quantity.new(4,:'meter*kilogram')
220
+ end
221
+ end
222
+
223
+ context "division" do
224
+ it "divides numerics by quantities" do
225
+ (6 / 2.meters).should == 3.meters
226
+ end
227
+
228
+ it "divides quantities by numerics" do
229
+ (6.meters / 2).should == 3.meters
230
+ end
231
+
232
+ it "divides quantities of the same unit" do
233
+ (6.meters / 2.meters).should == 3.meters
234
+ end
235
+
236
+ it "divides quantities of the same dimension" do
237
+ (6.meters / 2.feet).should == 3.meters
238
+ end
239
+
240
+ it "divides quantities of different dimensions" do
241
+ (1.kilogram / 1.second).unit.name.should == :'kilogram/second'
242
+ end
243
+
244
+ it "correctly calculates the value of a divided unit" do
245
+ (10.meters / 2.picograms).should be_close 5, 10**-5
246
+ end
247
+
248
+ end
249
+
250
+ context "exponentiation" do
251
+ it "raises quantities to positive powers" do
252
+ (2.meters**2).should be_close Quantity.new(4,:'meter^2'), 10**-5
253
+ end
254
+
255
+ it "raises quantities to negative powers" do
256
+ (2.meters**-1).unit.name.should == :'1/meter'
257
+ (2.meters**-1).should == 2
258
+ end
259
+
260
+ it "supports a cubed function" do
261
+ (1.centimeter * 1.centimeter * 1.centimeter).should == 1.centimeter.cubed
262
+ end
263
+
264
+ it "supports a squared function" do
265
+ (1.centimeter * 1.centimeter).should == 1.centimeter.squared
266
+ end
267
+
268
+ it "does not raise to fractional powers" do
269
+ lambda {2.meters**1.5}.should raise_error ArgumentError
270
+ end
271
+ end
272
+
273
+ context "enumerable" do
274
+ it "should be comparable" do
275
+ 2.meters.should be < 3.meters
276
+ 150.centimeters.should be > 1.meter
277
+ [1.meter, 1.foot, 1.inch].sort.should == [1.inch, 1.foot, 1.meter]
278
+ end
279
+ end
280
+
281
+ end
282
+ end