quantify 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +20 -0
- data/Examples.rb +104 -0
- data/README +7 -0
- data/lib/quantify/config.rb +379 -0
- data/lib/quantify/core_extensions.rb +63 -0
- data/lib/quantify/dimensions.rb +523 -0
- data/lib/quantify/exception.rb +21 -0
- data/lib/quantify/inflections.rb +63 -0
- data/lib/quantify/quantify.rb +37 -0
- data/lib/quantify/quantity.rb +325 -0
- data/lib/quantify/unit/base_unit.rb +518 -0
- data/lib/quantify/unit/compound_base_unit.rb +91 -0
- data/lib/quantify/unit/compound_unit.rb +321 -0
- data/lib/quantify/unit/non_si_unit.rb +20 -0
- data/lib/quantify/unit/prefix/base_prefix.rb +42 -0
- data/lib/quantify/unit/prefix/non_si_prefix.rb +10 -0
- data/lib/quantify/unit/prefix/prefix.rb +73 -0
- data/lib/quantify/unit/prefix/si_prefix.rb +10 -0
- data/lib/quantify/unit/si_unit.rb +10 -0
- data/lib/quantify/unit/unit.rb +217 -0
- data/lib/quantify.rb +26 -0
- data/spec/dimension_spec.rb +294 -0
- data/spec/quantity_spec.rb +250 -0
- data/spec/unit_spec.rb +687 -0
- metadata +103 -0
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
|
+
|