quantify 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/spec/unit_spec.rb ADDED
@@ -0,0 +1,687 @@
1
+ require 'quantify'
2
+ include Quantify
3
+
4
+ describe Unit do
5
+
6
+ describe "unit retrieval" do
7
+
8
+ it "symbols list should include" do
9
+ list = Unit.units_by_symbol
10
+ list.should include 'η'
11
+ list.should include 'g'
12
+ list.should include 'kg'
13
+ list.should include '°C'
14
+ list.should include 'K'
15
+ list.should include 'yd'
16
+ list.should include 'ly'
17
+ list.should include 'AU'
18
+ list.should include 'lb'
19
+ list.should include 'eV'
20
+ end
21
+
22
+ it "symbols list should not include these" do
23
+ Unit.units_by_symbol.should_not include 'zz'
24
+ end
25
+
26
+ it "si symbols list should include" do
27
+ list = Unit.si_units_by_symbol
28
+ list.should include 'η'
29
+ list.should include 'kg'
30
+ list.should include 'K'
31
+ end
32
+
33
+ it "si symbols list should not include" do
34
+ list = Unit.si_units_by_symbol
35
+ list.should_not include '°C'
36
+ list.should_not include 'yd'
37
+ list.should_not include 'ly'
38
+ list.should_not include 'AU'
39
+ list.should_not include 'lb'
40
+ list.should_not include 'eV'
41
+ end
42
+
43
+ it "non si symbols list should include" do
44
+ list = Unit.non_si_units_by_symbol
45
+ list.should include '°C'
46
+ list.should include 'yd'
47
+ list.should include 'ly'
48
+ list.should include 'AU'
49
+ list.should include 'lb'
50
+ list.should include 'eV'
51
+ end
52
+
53
+ it "non si symbols list should not include" do
54
+ list = Unit.non_si_units_by_symbol
55
+ list.should_not include 'η'
56
+ list.should_not include 'g'
57
+ list.should_not include 'kg'
58
+ list.should_not include 'K'
59
+ end
60
+
61
+ it "dynamic unit retrieval with name should be successful" do
62
+ Unit.metre.name.should == 'metre'
63
+ Unit.foot.symbol.should == 'ft'
64
+ end
65
+
66
+ it "dynamic unit retrieval with name and prefix should be successful" do
67
+ unit = Unit.kilometre
68
+ unit.name.should == 'kilometre'
69
+ unit.factor.should == 1000
70
+ end
71
+
72
+ it "dynamic unit retrieval with name and invalid prefix should throw error" do
73
+ lambda{Unit.megafoot}.should raise_error
74
+ end
75
+
76
+ it "dynamic unit retrieval with symbol should be successful" do
77
+ Unit.m.name.should == 'metre'
78
+ Unit.ft.symbol.should == 'ft'
79
+ Unit.μm.factor.should == 0.000001
80
+ Unit.°C.name.should == 'degree celsius'
81
+ end
82
+
83
+ it "dynamic unit retrieval with symbol and prefix should be successful" do
84
+ Unit.km.name.should == 'kilometre'
85
+ Unit.Gg.name.should == 'gigagram'
86
+ Unit.cm.factor.should == 0.01
87
+ Unit.TJ.name.should == 'terajoule'
88
+ Unit::Prefix::NonSI.load(:name => 'million ', :symbol => 'MM', :factor => 1e6)
89
+ Unit.MMBTU.name.should == 'million british thermal unit (59 °f)'
90
+ Unit::Prefix.unload :MM
91
+ end
92
+
93
+ it "dynamic unit retrieval with symbol and invalid prefix should raise error" do
94
+ lambda{Unit.MMm}.should raise_error
95
+ lambda{Unit.Gft}.should raise_error
96
+ lambda{Unit.centimetre.with_prefix :kilo}.should raise_error
97
+ end
98
+
99
+ it "explicit get should raise nil if not known" do
100
+ Unit.for(:MMm).should be_nil
101
+ Unit.for(:andrew).should be_nil
102
+ Unit.for(nil).should be_nil
103
+ end
104
+
105
+ it "empty string should return nil" do
106
+ Unit.for("").should be_nil
107
+ end
108
+
109
+ describe "parsing unit string" do
110
+
111
+ it "should parse string into correct single unit" do
112
+ Unit.parse("kg").name.should == "kilogram"
113
+ end
114
+
115
+ it "should parse string into correct single unit" do
116
+ Unit.parse("T").name.should == "tesla"
117
+ end
118
+
119
+ it "should parse string into correct single unit" do
120
+ Unit.parse("Tm").name.should == "terametre"
121
+ end
122
+
123
+ it "should parse string into correct compound unit" do
124
+ Unit.parse("kg kWh^-1").name.should == "kilogram per kilowatt hour"
125
+ end
126
+
127
+ it "should parse string into correct compound unit" do
128
+ Unit.parse("m^2").name.should == "square metre"
129
+ end
130
+
131
+ it "should parse string into correct compound unit" do
132
+ Unit.parse("m^-3").name.should == "per cubic metre"
133
+ end
134
+
135
+ it "should parse per unit correctly" do
136
+ unit = Unit.parse "s^-1"
137
+ unit.name.should == 'per second'
138
+ end
139
+
140
+ it "should raise error when parsing on unknown units" do
141
+ lambda{unit = Unit.parse "kg z^2"}.should raise_error
142
+ end
143
+
144
+ end
145
+
146
+ it "should create new instance with block initialize" do
147
+ unit = Unit::Base.new do |unit|
148
+ unit.name = 'megapanda'
149
+ unit.symbol = 'Mpd'
150
+ unit.label = 'Mpd'
151
+ unit.dimensions = Dimensions.dimensionless
152
+ end
153
+ unit.class.should == Quantify::Unit::Base
154
+ unit.symbol.should == 'Mpd'
155
+ end
156
+
157
+ it "should raise with block initialize and no name" do
158
+ lambda{unit = Unit::Base.new do |unit|
159
+ unit.symbol = 'Mpd'
160
+ unit.dimensions = Dimensions.dimensionless
161
+ end}.should raise_error
162
+ end
163
+
164
+ it "should raise with block initialize and no dimensions" do
165
+ lambda{unit = Unit::Base.new do |unit|
166
+ unit.symbol = 'Mpd'
167
+ unit.name = 'megapanda'
168
+ end}.should raise_error
169
+ end
170
+
171
+ it "should modify unit attributes with block and #operate" do
172
+ unit = (Unit.kg/Unit.kWh).operate do |u|
173
+ u.name = 'electricity emissions factor'
174
+ end
175
+ unit.class.should == Quantify::Unit::Compound
176
+ unit.name = 'electricity emissions factor'
177
+ end
178
+
179
+ it "should raise error with block and #operate which removes name" do
180
+ lambda{(Unit.kg/Unit.kWh).operate do |u|
181
+ u.name = ""
182
+ end}.should raise_error
183
+ end
184
+
185
+ it "should load new unit with block and #load" do
186
+ (Unit.kg/Unit.kWh).load do |u|
187
+ u.name = 'electricity emissions factor'
188
+ u.label = 'elec_fac'
189
+ end
190
+ unit = Unit.electricity_emissions_factor
191
+ unit.class.should == Quantify::Unit::Compound
192
+ unit.name = 'electricity emissions factor'
193
+ end
194
+
195
+ it "should raise error with block and #load which removes name" do
196
+ lambda{(Unit.kg/Unit.kWh).load do |u|
197
+ u.name = ""
198
+ end}.should raise_error
199
+ end
200
+
201
+ it "should recognize already loaded units" do
202
+ Unit.m.loaded?.should == true
203
+ Unit.ft.loaded?.should == true
204
+ Unit.kilometre.loaded?.should == true
205
+ (Unit.m/Unit.K).loaded?.should == false
206
+ Unit.m.with_prefix(:pico).loaded?.should == false
207
+ Unit.J.loaded?.should == true
208
+ Unit.psi.loaded?.should == true
209
+ end
210
+
211
+ it "should allow dimensions to be specified with :physical_quantity key" do
212
+ unit = Unit::Base.new :physical_quantity => :mass, :name => 'gigapile', :symbol => 'Gpl', :label => 'Gpl'
213
+ unit.class.should == Quantify::Unit::Base
214
+ end
215
+
216
+ it "should allow dimensions to be specified with :dimensions key" do
217
+ unit = Unit::Base.new :dimensions => :mass, :name => 'gigapile', :symbol => 'Gpl', :label => 'Gpl'
218
+ unit.class.should == Quantify::Unit::Base
219
+ end
220
+
221
+ it "should mass load units with prefixes" do
222
+ Unit::SI.prefix_and_load([:kilo,:mega,:giga,:tera],[:metre,:gram,:second])
223
+ Unit.kilometre.loaded?.should == true
224
+ Unit.Gigametre.loaded?.should == true
225
+ Unit.kilogram.loaded?.should == true
226
+ Unit.teragram.loaded?.should == true
227
+ Unit.kilosecond.loaded?.should == true
228
+ Unit.nanometre.loaded?.should == false
229
+ end
230
+
231
+ it "should mass load unit with prefixes" do
232
+ Unit::SI.prefix_and_load([:kilo,:mega,:giga,:tera],:metre)
233
+ Unit.kilometre.loaded?.should == true
234
+ Unit.Gigametre.loaded?.should == true
235
+ Unit.nanometre.loaded?.should == false
236
+ end
237
+
238
+ it "should mass load units with prefix" do
239
+ Unit::SI.prefix_and_load(:giga,[:metre,:gram,:second])
240
+ Unit.Gigametre.loaded?.should == true
241
+ Unit.gigagram.loaded?.should == true
242
+ Unit.gigasecond.loaded?.should == true
243
+ Unit.nanometre.loaded?.should == false
244
+ end
245
+
246
+ it "should mass load units with prefix using objects as arguments" do
247
+ Unit::SI.prefix_and_load(Unit::Prefix.giga,[Unit.metre,Unit.gram,Unit.second])
248
+ Unit.Gigametre.loaded?.should == true
249
+ Unit.gigagram.loaded?.should == true
250
+ Unit.gigasecond.loaded?.should == true
251
+ Unit.nanometre.loaded?.should == false
252
+ end
253
+
254
+ it "should unload unit with class method and symbol" do
255
+ Unit.nanometre.load
256
+ Unit.nanometre.loaded?.should == true
257
+ Unit.unload(:nanometre)
258
+ Unit.nanometre.loaded?.should == false
259
+ end
260
+
261
+ it "should unload unit with class method and object" do
262
+ Unit.nanometre.load
263
+ Unit.nanometre.loaded?.should == true
264
+ Unit.unload(Unit.nanometre)
265
+ Unit.nanometre.loaded?.should == false
266
+ end
267
+
268
+ it "should unload unit with instance method" do
269
+ Unit.nanometre.load
270
+ Unit.nanometre.loaded?.should == true
271
+ unit = Unit.nanometre
272
+ unit.unload
273
+ Unit.nanometre.loaded?.should == false
274
+ end
275
+
276
+ it "should unload multiple units with class method" do
277
+ Unit.nanometre.load
278
+ Unit.picometre.load
279
+ Unit.nanometre.loaded?.should == true
280
+ Unit.picometre.loaded?.should == true
281
+ Unit.unload(:nanometre,:picometre)
282
+ Unit.nanometre.loaded?.should == false
283
+ Unit.picometre.loaded?.should == false
284
+ end
285
+
286
+ it "should make new unit configuration canonical" do
287
+ unit = Unit.psi
288
+ unit.name.should == 'pound force per square inch'
289
+ unit.operate {|unit| unit.name = 'PSI'}
290
+ unit.name.should == 'PSI'
291
+ Unit.psi.name.should == 'pound force per square inch'
292
+ unit.make_canonical
293
+ Unit.psi.name.should == 'PSI'
294
+ unit.operate {|unit| unit.name = 'pound force per square inch'}
295
+ unit.make_canonical
296
+ end
297
+
298
+ end
299
+
300
+ describe "unit initialization" do
301
+
302
+ it "should load self into module variable with instance method" do
303
+ unit = Unit::Base.new :physical_quantity => :mass, :name => 'megalump', :symbol => 'Mlp', :label => 'Mlp'
304
+ unit.load
305
+ Unit.units_by_symbol.should include 'Mlp'
306
+ Unit.units_by_name.should include 'megalump'
307
+ end
308
+
309
+ it "should create unit" do
310
+ unit = Unit::NonSI.new :name => 'a name', :physical_quantity => :energy, :factor => 10, :symbol => 'anm', :label => 'a_name'
311
+ unit.class.should == Unit::NonSI
312
+ end
313
+
314
+ it "should throw error when creating unit with no name" do
315
+ lambda{unit = Unit::NonSI.new :physical_quantity => :energy, :factor => 10}.should raise_error
316
+ end
317
+
318
+ it "should throw error when creating unit with no physical quantity" do
319
+ lambda{unit = Unit::NonSI.new :name => 'energy', :factor => 10}.should raise_error
320
+ end
321
+
322
+ it "should load unit into module array with class method" do
323
+ unit = Unit::NonSI.load :name => 'a name', :physical_quantity => :energy, :factor => 10, :symbol => 'anm', :label => 'a_name'
324
+ Unit.non_si_units_by_name.should include 'a name'
325
+ end
326
+
327
+ it "should derive compound unit correctly" do
328
+ Unit::Prefix::NonSI.load(:name => 'million ', :symbol => 'MM', :factor => 1e6)
329
+ (Unit.MW_h/Unit.MMBTU).factor.should be_close 3.41295634070405, 0.00000001
330
+ Unit::Prefix.unload :MM
331
+ end
332
+
333
+ end
334
+
335
+ describe "unit scaling attribute" do
336
+
337
+ it "should return a scaling of zero if SI" do
338
+ unit = Unit.cm
339
+ unit.scaling.should == 0.0
340
+ end
341
+
342
+ it "should return a scaling of zero if NonSI and no appropriate value" do
343
+ unit = Unit.ft
344
+ unit.scaling.should == 0.0
345
+ end
346
+
347
+ it "should return a scaling value if appropriate" do
348
+ unit = Unit.degree_farenheit
349
+ unit.scaling.should == 459.67
350
+ end
351
+
352
+ end
353
+
354
+ describe "unit physical quantity" do
355
+
356
+ it "should return the physical quantity" do
357
+ unit = Unit.metre
358
+ unit.measures.should == 'length'
359
+ end
360
+
361
+ it "should return the physical quantity" do
362
+ unit = Unit.joule
363
+ unit.measures.should == 'energy'
364
+ end
365
+
366
+ it "should return the physical quantity" do
367
+ unit = Unit.BTU
368
+ unit.measures.should == 'energy'
369
+ end
370
+
371
+ end
372
+
373
+ describe "unit self awareness" do
374
+
375
+ it "should recognise joule as SI" do
376
+ unit = Unit.J
377
+ unit.is_si_unit?.should == true
378
+ end
379
+
380
+ it "should recognise newton as SI" do
381
+ unit = Unit.N
382
+ unit.is_si_unit?.should == true
383
+ end
384
+
385
+ it "should recognise kilometre as SI" do
386
+ unit = Unit.kilometre
387
+ unit.is_si_unit?.should == true
388
+ end
389
+
390
+ it "should recognise foot as non SI" do
391
+ unit = Unit.ft
392
+ unit.is_si_unit?.should_not == true
393
+ end
394
+
395
+ it "should recognise dram as non SI" do
396
+ unit = Unit.dram
397
+ unit.is_si_unit?.should_not == true
398
+ end
399
+
400
+ it "should recognise BTU as non SI" do
401
+ unit = Unit.BTU
402
+ unit.is_si_unit?.should_not == true
403
+ end
404
+
405
+ it "should recognise a compound unit" do
406
+ (Unit.m*Unit.t).is_compound_unit?.should == true
407
+ Unit.m.is_compound_unit?.should == false
408
+ end
409
+
410
+ it "should recognise compound units based entirely on SI units" do
411
+ unit = Unit.kg*Unit.m
412
+ unit.is_si_unit?.should == true
413
+ end
414
+
415
+ it "should recognise compound units based entirely on SI units" do
416
+ unit = Unit.lb*Unit.m*Unit.m/Unit.s/Unit.s
417
+ unit.is_si_unit?.should == false
418
+ end
419
+
420
+ it "should recognise compound units based entirely on SI units" do
421
+ unit = Unit.kg*Unit.m*Unit.m/Unit.s/Unit.s
422
+ unit.is_si_unit?.should == true
423
+ end
424
+
425
+ it "should recognise compound units based entirely on SI units" do
426
+ unit = (Unit.kilograms/(Unit.megagram*Unit.km))
427
+ unit.is_si_unit?.should == true
428
+ end
429
+
430
+ it "should recognise compound units based entirely on SI units" do
431
+ unit = (Unit.kilograms/(Unit.tonne*Unit.km))
432
+ unit.is_si_unit?.should == false
433
+ end
434
+
435
+ it "should recognise a base unit" do
436
+ Unit.m.is_base_unit?.should == true
437
+ Unit.K.is_base_unit?.should == true
438
+ Unit.degree_celsius.is_base_unit?.should == true
439
+ Unit.ft.is_base_unit?.should == true
440
+ Unit.cd.is_base_unit?.should == true
441
+ (Unit.square_metre/Unit.m).is_base_unit?.should == true
442
+ (Unit.km/Unit.h).is_base_unit?.should == false
443
+ Unit.J.is_base_unit?.should == false
444
+ Unit.N.is_base_unit?.should == false
445
+ Unit.W.is_base_unit?.should == false
446
+ end
447
+
448
+ it "should recognise a derived unit" do
449
+ Unit.m.is_derived_unit?.should == false
450
+ Unit.K.is_derived_unit?.should == false
451
+ Unit.degree_celsius.is_derived_unit?.should == false
452
+ Unit.ft.is_derived_unit?.should == false
453
+ Unit.cd.is_derived_unit?.should == false
454
+ (Unit.cubic_metre/Unit.square_metre).is_derived_unit?.should == false
455
+ Unit.J.is_derived_unit?.should == true
456
+ Unit.N.is_derived_unit?.should == true
457
+ Unit.W.is_derived_unit?.should == true
458
+ Unit.parse("m^3").is_derived_unit?.should == true
459
+ (Unit.m/Unit.s).is_derived_unit?.should == true
460
+ end
461
+
462
+ it "should recognise a prefixed unit" do
463
+ Unit.m.is_prefixed_unit?.should == false
464
+ Unit.K.is_prefixed_unit?.should == false
465
+ Unit.degree_celsius.is_prefixed_unit?.should == false
466
+ Unit.ft.is_prefixed_unit?.should == false
467
+ Unit.cd.is_prefixed_unit?.should == false
468
+ (Unit.cubic_metre/Unit.square_metre).is_derived_unit?.should == false
469
+ Unit.TJ.is_prefixed_unit?.should == true
470
+ Unit.GN.is_prefixed_unit?.should == true
471
+ Unit.kW.is_prefixed_unit?.should == true
472
+ Unit.parse("Gcd").is_prefixed_unit?.should == true
473
+ Unit.parse("picosecond").is_prefixed_unit?.should == true
474
+ end
475
+
476
+ it "should recognise a benchmark unit" do
477
+ Unit.m.is_benchmark_unit?.should == true
478
+ Unit.K.is_benchmark_unit?.should == true
479
+ Unit.degree_celsius.is_benchmark_unit?.should == true
480
+ Unit.ft.is_benchmark_unit?.should == false
481
+ Unit.cd.is_benchmark_unit?.should == true
482
+ (Unit.cubic_metre/Unit.square_metre).is_benchmark_unit?.should == true
483
+ Unit.TJ.is_benchmark_unit?.should == false
484
+ Unit.N.is_benchmark_unit?.should == true
485
+ Unit.kW.is_benchmark_unit?.should == false
486
+ Unit.parse("kg").is_benchmark_unit?.should == true
487
+ Unit.parse("picosecond").is_benchmark_unit?.should == false
488
+ end
489
+
490
+ it "compound unit should be recognsed as Unit::Base and Compound" do
491
+ unit = Unit.m*Unit.kg*Unit.s
492
+ unit.is_a?(Unit::Base).should be_true
493
+ unit.is_a?(Unit::Compound).should be_true
494
+ unit.is_a?(Unit::SI).should_not be_true
495
+ unit.is_a?(Unit::NonSI).should_not be_true
496
+ end
497
+
498
+ end
499
+
500
+ describe "alternative units" do
501
+
502
+ it "should recognise alternative units" do
503
+ unit_1 = Unit.yard
504
+ unit_2 = Unit.foot
505
+ unit_1.is_alternative_for?(unit_2).should == true
506
+ end
507
+
508
+ it "should recognise non-alternative units" do
509
+ unit_1 = Unit.yard
510
+ unit_2 = Unit.kelvin
511
+ unit_1.is_alternative_for?(unit_2).should_not == true
512
+ end
513
+
514
+ it "should list alternative unit objects" do
515
+ unit = Unit.kg
516
+ unit.alternatives.class.should == Array
517
+ unit.alternatives[0].is_a?(Unit::SI).should == true
518
+ unit.alternatives[0].symbol.should == 'g'
519
+ end
520
+
521
+ it "should list alternative unit symbols" do
522
+ unit = Unit.kg
523
+ unit.alternatives(:symbol).class.should == Array
524
+ unit.alternatives(:symbol)[0].is_a?(String).should == true
525
+ unit.alternatives(:symbol)[0].should == 'g'
526
+ end
527
+
528
+ it "should list alternative unit names" do
529
+ unit = Unit.kg
530
+ unit.alternatives(:name).class.should == Array
531
+ unit.alternatives(:name)[0].is_a?(String).should == true
532
+ unit.alternatives(:name)[0].should == 'gram'
533
+ end
534
+
535
+ it "should recognise similar units" do
536
+ unit_1 = Unit.yard
537
+ unit_2 = Unit.yard
538
+ unit_1.is_same_as?(unit_2).should == true
539
+ end
540
+
541
+ it "should recognise non-similar units" do
542
+ unit_1 = Unit.yard
543
+ unit_2 = Unit.foot
544
+ unit_1.is_same_as?(unit_2).should_not == true
545
+ end
546
+
547
+ it "should recognise non-similar units" do
548
+ unit_1 = Unit.yard
549
+ unit_2 = Unit.kelvin
550
+ (unit_1 == unit_2).should_not == true
551
+ end
552
+
553
+ it "should recognise known units from compound units based on dimensions and factor" do
554
+ unit = Unit.kg*Unit.m*Unit.m/Unit.s/Unit.s
555
+ unit.equivalent_known_unit.name.should == 'joule'
556
+ end
557
+
558
+ it "megagram and tonne should be similar" do
559
+ tonne = Unit.t
560
+ tonne.symbol.should == 't'
561
+ tonne.factor.should == 1000.0
562
+ megagram = Unit.Mg
563
+ megagram.symbol.should == 'Mg'
564
+ megagram.factor.should == 1000.0
565
+ megagram.should == tonne
566
+ end
567
+
568
+ it "should return correct SI unit" do
569
+ Unit.ft.si_unit.name.should == 'metre'
570
+ Unit.lb.si_unit.name.should == 'kilogram'
571
+ Unit.BTU.si_unit.name.should == 'joule'
572
+ (Unit.ft**2).si_unit.name.should == 'square metre'
573
+ Unit.pounds_force_per_square_inch.si_unit.name.should == 'pascal'
574
+ end
575
+
576
+ it "should not return alternative if feature disabled" do
577
+ alt = Unit.kg.alternatives
578
+ alt.class.should == Array
579
+ alt[0].is_a?(Unit::Base).should == true
580
+ alt.any?{|unit| unit == Unit.g }.should == true
581
+
582
+ Unit.g.acts_as_alternative_unit = false
583
+
584
+ alt = Unit.kg.alternatives
585
+ alt.class.should == Array
586
+ alt[0].is_a?(Unit::Base).should == true
587
+ alt.any?{|unit| unit == Unit.g }.should == false
588
+
589
+ Unit.g.acts_as_alternative_unit = true
590
+
591
+ alt = Unit.kg.alternatives
592
+ alt.class.should == Array
593
+ alt[0].is_a?(Unit::Base).should == true
594
+ alt.any?{|unit| unit == Unit.g }.should == true
595
+ end
596
+
597
+ end
598
+
599
+ describe "operating on units" do
600
+
601
+ it "should multiply units" do
602
+ kilometre = Unit.km
603
+ hour = Unit.h
604
+ new = kilometre / hour
605
+ new.measures.should == 'velocity'
606
+ end
607
+
608
+ it "should divide units" do
609
+ kilowatt = Unit.kW
610
+ hour = Unit.h
611
+ new = kilowatt * hour
612
+ new.measures.should == 'energy'
613
+ end
614
+
615
+ it "should multiply units" do
616
+ length_1 = Unit.m
617
+ length_2 = Unit.m
618
+ new = length_1 * length_2
619
+ new.measures.should == 'area'
620
+ end
621
+
622
+ it "should divide units" do
623
+ energy = Unit.J
624
+ length = Unit.m
625
+ new = energy / length
626
+ new.measures.should == 'force'
627
+ end
628
+
629
+ it "should create compound" do
630
+ unit = (Unit.kg / Unit.kWh)
631
+ unit.name.should == 'kilogram per kilowatt hour'
632
+ unit.measures.should_not == 'energy'
633
+ end
634
+
635
+ it "should raise unit to power" do
636
+ (Unit.m**3).measures.should == 'volume'
637
+ end
638
+
639
+ it "coerce method should handle reciprocal syntax" do
640
+ (1/Unit.s).name.should == 'per second'
641
+ end
642
+
643
+ it "should raise to power -1" do
644
+ (Unit.s**-1).dimensions.time.should == -1
645
+ end
646
+
647
+ it "should raise to power -2" do
648
+ unit = Unit.m**-2
649
+ unit.name.should == 'per square metre'
650
+ end
651
+
652
+ it "should return correct unit ratio quantity with symbols" do
653
+ Unit.ratio(:lb,:kg).to_s(:name).should == "2.20462262184878 pounds per kilogram"
654
+ end
655
+
656
+ it "should return correct unit ratio quantity with symbols and rounding" do
657
+ Unit.ratio(:lb,:kg).round(3).to_s(:name).should == "2.205 pounds per kilogram"
658
+ end
659
+
660
+ it "should return correct unit ratio quantity with strings" do
661
+ Unit.ratio('K','degree farenheit').round(5).to_s(:name).should == "0.55556 kelvins per degree farenheit"
662
+ end
663
+
664
+ it "should return correct unit ratio quantity with unit instance" do
665
+ Unit.ratio(Unit.square_metre,'hectare').round.to_s(:name).should == "10000 square metres per hectare"
666
+ end
667
+
668
+ end
669
+
670
+ describe "handling prefixes" do
671
+
672
+ it "should throw error when trying to add prefix to prefixed-unit" do
673
+ lambda{Unit.kilometre.with_prefix :giga}.should raise_error
674
+ end
675
+
676
+ it "should add prefix with explcit method" do
677
+ Unit.metre.with_prefix(:c).name.should == 'centimetre'
678
+ end
679
+
680
+ it "trying to add invalid prefix should raise error" do
681
+ lambda{Unit.ft.with_prefix(:kilo)}.should raise_error
682
+ end
683
+
684
+ end
685
+
686
+ end
687
+