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.
@@ -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