rails-units 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'rspec/core'
4
+ require File.dirname(__FILE__) + "/../lib/ruby-units"
@@ -0,0 +1,26 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'ruby-units'
4
+
5
+ class TestCache < Test::Unit::TestCase
6
+ def setup
7
+ Unit::Cache.clear
8
+ end
9
+
10
+ def test_clear
11
+ Unit::Cache.set("m", "m".unit)
12
+ Unit::Cache.clear
13
+ assert_nil(Unit::Cache.get('m'))
14
+ end
15
+
16
+ def test_set_cache
17
+ assert_nothing_raised { Unit::Cache.set("m", "m".unit) }
18
+ assert Unit::Cache.get.keys.include?('m')
19
+ end
20
+
21
+ def test_get_cache
22
+ Unit::Cache.set("m", "m".unit)
23
+ assert_equal("m".unit, Unit::Cache.get['m'])
24
+ end
25
+
26
+ end
@@ -0,0 +1,1011 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'ruby-units'
4
+ require 'yaml'
5
+ begin
6
+ require 'chronic'
7
+ rescue LoadError
8
+ warn "Can't test Chronic integration unless gem 'chronic' is installed"
9
+ end
10
+ begin
11
+ require 'uncertain'
12
+ rescue LoadError
13
+ warn "Can't test Uncertain Units unless 'Uncertain' gem is installed"
14
+ end
15
+
16
+
17
+ class Unit < Numeric
18
+ @@USER_DEFINITIONS = {'<inchworm>' => [%w{inworm inchworm}, 0.0254, :length, %w{<meter>} ],
19
+ '<habenero>' => [%w{degH}, 100, :temperature, %w{<celsius>}]}
20
+ Unit.setup
21
+ end
22
+
23
+ class Time
24
+ @@forced_now = nil
25
+ @@forced_gmt = nil
26
+ class << self
27
+ alias :unforced_now :now
28
+ def forced_now
29
+ @@forced_now.nil? ? unforced_now : @@forced_now
30
+ end
31
+ alias :now :forced_now
32
+
33
+ def forced_now=(now)
34
+ @@forced_now = now
35
+ end
36
+ end
37
+
38
+ alias :unforced_gmt :gmt_offset
39
+ def forced_gmt
40
+ @@forced_gmt.nil? ? unforced_gmt : @@forced_gmt
41
+ end
42
+ alias :gmt_offset :forced_gmt
43
+
44
+ def forced_gmt=(gmt)
45
+ @@forced_gmt = now
46
+ end
47
+
48
+ end
49
+
50
+ class DateTime
51
+ @@forced_now = nil
52
+ class << self
53
+ alias :unforced_now :now
54
+ def forced_now
55
+ return @@forced_now ? @@forced_now : unforced_now
56
+ end
57
+ alias :now :forced_now
58
+
59
+ def forced_now=(now)
60
+ @@forced_now = now
61
+ end
62
+
63
+ end
64
+ end
65
+
66
+ class Dummy
67
+ def to_unit
68
+ '1 mm'.unit
69
+ end
70
+ end
71
+
72
+ class TestRubyUnits < Test::Unit::TestCase
73
+
74
+ def setup
75
+ @april_fools = Time.at 1143910800
76
+ @april_fools_datetime = DateTime.parse('2006-04-01T12:00:00-05:00')
77
+ Time.forced_now = @april_fools
78
+ DateTime.forced_now = @april_fools_datetime
79
+ #Unit.clear_cache
80
+ end
81
+
82
+ def teardown
83
+ Time.forced_now = nil
84
+ DateTime.forced_now = nil
85
+ end
86
+
87
+ def test_to_yaml
88
+ unit = "1 mm".u
89
+ if RUBY_PLATFORM == "java"
90
+ # apparently jruby's implementation of yaml has some white space differences
91
+ assert_equal "--- !ruby/object:Unit \nscalar: 1\nnumerator: \n - <milli>\n - <meter>\ndenominator: \n - <1>\nsignature: 1\nbase_scalar: !ruby/object:Rational \n denominator: 1000\n numerator: 1\n", unit.to_yaml
92
+ else
93
+ assert_equal "--- !ruby/object:Unit \nscalar: 1\nnumerator: \n- <milli>\n- <meter>\ndenominator: \n- <1>\nsignature: 1\nbase_scalar: !ruby/object:Rational \n denominator: 1000\n numerator: 1\n", unit.to_yaml
94
+ end
95
+ end
96
+
97
+ def test_time
98
+ a = Time.now
99
+ assert_equal "s", a.to_unit.units
100
+ assert_equal a + 3600, a + "1 h".unit
101
+ assert_equal a - 3600, a - "1 h".unit
102
+ assert_in_delta Time.now - "1 h".unit, "1 h".ago, 1
103
+ assert_in_delta Time.now + 3600, "1 h".from_now, 1
104
+ assert_in_delta Time.now + "1 h".unit, "1 h".from_now, 1
105
+ assert_in_delta Time.now - 3600, "1 h".before_now, 1
106
+ assert_equal "60 min", "min".until(Time.now + 3600).to_s
107
+ assert_equal "01:00", "min".since(Time.now - 3600).to_s("%H:%M")
108
+ assert_in_delta Time.now, "now".time, 1
109
+ end
110
+
111
+ def test_from_now
112
+ assert_equal "1 day".from_now, @april_fools + 86400
113
+ end
114
+
115
+ def test_from
116
+ assert_equal "1 day".from("now"), @april_fools + 86400
117
+ end
118
+
119
+ def test_ago
120
+ assert_equal "1 day".ago, @april_fools - 86400
121
+ end
122
+
123
+ def test_before_now
124
+ assert_equal "1 day".before_now, @april_fools - 86400
125
+ end
126
+
127
+ def test_before
128
+ assert_equal '1 days'.before('now'), @april_fools - 86400
129
+ end
130
+
131
+ def test_since
132
+ assert_equal 'days'.since(@april_fools - 86400), "1 day".unit
133
+ assert_equal 'days'.since('2006-3-31 12:00:00 -5:00'), "1 day".unit
134
+ assert_equal 'days'.since(DateTime.parse('2006-3-31 12:00 -5:00')), "1 day".unit
135
+ assert_raises(ArgumentError) { 'days'.since(1) }
136
+ end
137
+
138
+ def test_until
139
+ assert_equal 'days'.until('2006-04-2 12:00:00 -5:00'), '1 day'.unit
140
+ assert_raises(ArgumentError) { 'days'.until(1) }
141
+ end
142
+
143
+ def test_time_helpers
144
+ assert_equal @april_fools, Time.now
145
+ assert_equal @april_fools_datetime, DateTime.now
146
+ assert_equal Time.now, 'now'.time
147
+ assert_equal DateTime.now, 'now'.datetime
148
+ assert_equal 1143910800, Unit.new(Time.now).scalar
149
+ assert_equal @april_fools.unit.to_time, @april_fools
150
+ assert_equal Time.in('1 day'), @april_fools + 86400
151
+ assert_equal "2006-04-01T12:00:00-05:00", @april_fools_datetime.inspect
152
+ assert_equal "2006-04-01T00:00:00+00:00", '2453826.5 days'.unit.to_datetime.to_s
153
+ end
154
+
155
+ def test_string_helpers
156
+ assert_equal '1 mm'.to('in'), Unit('1 mm').to('in')
157
+ end
158
+
159
+ [:sin, :cos, :tan, :sinh, :cosh, :tanh].each do |trig|
160
+ define_method("test_#{trig}") do
161
+ assert_equal Math.send(trig, Math::PI), Math.send(trig, "180 deg".unit)
162
+ end
163
+ end
164
+
165
+ def test_clone
166
+ unit1= "1 mm".unit
167
+ unit2 = unit1.clone
168
+ assert_not_equal unit1.numerator.object_id, unit2.numerator.object_id
169
+ assert_not_equal unit1.denominator.object_id, unit2.denominator.object_id
170
+ assert unit1 === unit2
171
+ end
172
+
173
+ def test_unary_minus
174
+ unit1 = Unit.new("1 mm^2")
175
+ unit2 = Unit.new("-1 mm^2")
176
+ assert_equal unit1, -unit2
177
+ end
178
+
179
+ def test_unary_plus
180
+ unit1 = Unit.new("1 mm")
181
+ assert_equal unit1, +unit1
182
+ end
183
+
184
+ def test_create_unit_only
185
+ unit1 = Unit.new("m")
186
+ assert_equal ['<meter>'], unit1.numerator
187
+ assert_equal 1.0, unit1.scalar
188
+ end
189
+
190
+ def test_to_base
191
+ unit1 = Unit.new("100 cm")
192
+ assert_in_delta 1, unit1.to_base.scalar, 0.001
193
+ unit2 = Unit("1 mm^2 ms^-2")
194
+ assert_in_delta 1, unit2.to_base.scalar, 0.001
195
+ end
196
+
197
+ def test_to_unit
198
+ unit1 = "1 mm".to_unit
199
+ assert_equal unit1, unit1.to_unit
200
+ assert Unit === unit1
201
+ unit2 = Unit("1 mm")
202
+ assert Unit === unit1
203
+ assert unit1 == unit2
204
+ unit1 = "2.54 cm".to_unit("in")
205
+ assert_in_delta 1, unit1.scalar, 0.001
206
+ assert_equal ['<inch>'], unit1.numerator
207
+ unit1 = "2.54 cm".unit("in")
208
+ assert_in_delta 1, unit1.scalar, 0.001
209
+ assert_equal ['<inch>'], unit1.numerator
210
+ unit1 = 1.unit
211
+ assert_in_delta 1, unit1.scalar, 0.001
212
+ assert_equal ['<1>'], unit1.numerator
213
+ unit1 = [1,'mm'].unit
214
+ assert_in_delta 1, unit1.scalar, 0.001
215
+ assert_equal ['<milli>','<meter>'], unit1.numerator
216
+ end
217
+
218
+ def test_create_unitless
219
+ unit1 = Unit("1")
220
+ assert_equal 1, unit1.to_f
221
+ assert_equal ['<1>'],unit1.numerator
222
+ assert_equal ['<1>'],unit1.denominator
223
+ unit1 = Unit.new("1.5")
224
+ assert_equal 1.5,unit1.to_f
225
+ assert_equal ['<1>'],unit1.numerator
226
+ assert_equal ['<1>'],unit1.denominator
227
+ end
228
+
229
+ def test_create_simple
230
+ unit1 = Unit.new("1 m")
231
+ assert_equal 1,unit1.scalar
232
+ assert_equal ['<meter>'], unit1.numerator
233
+ assert_equal ['<1>'],unit1.denominator
234
+ end
235
+
236
+ def test_create_compound
237
+ unit1 = Unit.new("1 N*m")
238
+ assert_equal 1,unit1.scalar
239
+ assert_equal ['<newton>','<meter>'],unit1.numerator
240
+ assert_equal ['<1>'],unit1.denominator
241
+ end
242
+
243
+ def test_create_with_denominator
244
+ unit1 = Unit.new("1 m/s")
245
+ assert_equal 1, unit1.scalar
246
+ assert_equal ['<meter>'],unit1.numerator
247
+ assert_equal ['<second>'],unit1.denominator
248
+ end
249
+
250
+ def test_create_with_powers
251
+ unit1 = Unit.new("1 m^2/s^2")
252
+ assert_equal 1, unit1.scalar
253
+ assert_equal ['<meter>','<meter>'],unit1.numerator
254
+ assert_equal ['<second>','<second>'],unit1.denominator
255
+ unit1 = Unit.new("1 m^2 kg^2 J^2/s^2")
256
+ assert_equal 1, unit1.scalar
257
+ assert_equal ['<meter>','<meter>','<kilogram>','<kilogram>','<joule>','<joule>'],unit1.numerator
258
+ assert_equal ['<second>','<second>'],unit1.denominator
259
+
260
+ end
261
+
262
+ def test_create_with_zero_power
263
+ unit1 = Unit.new("1 m^0")
264
+ assert_equal 1,unit1.scalar
265
+ assert_equal ['<1>'],unit1.numerator
266
+ assert_equal ['<1>'],unit1.denominator
267
+ end
268
+
269
+ def test_create_with_negative_powers
270
+ unit1 = Unit.new("1 m^2 s^-2")
271
+ assert_equal 1, unit1.scalar
272
+ assert_equal ['<meter>','<meter>'],unit1.numerator
273
+ assert_equal ['<second>','<second>'],unit1.denominator
274
+ end
275
+
276
+ def test_create_from_array
277
+ unit1 = Unit.new(1, "mm^2", "ul^2")
278
+ assert_equal 1, unit1.scalar
279
+ assert_equal ['<milli>','<meter>','<milli>','<meter>'], unit1.numerator
280
+ assert_equal ['<micro>','<liter>','<micro>','<liter>'], unit1.denominator
281
+ end
282
+
283
+ def test_bad_create
284
+ assert_raises(ArgumentError) { Unit.new(nil)}
285
+ assert_raises(ArgumentError) { Unit.new(true)}
286
+ assert_raises(ArgumentError) { Unit.new(false)}
287
+ assert_raises(ArgumentError) { Unit.new(/(.+)/)}
288
+ end
289
+
290
+ def test_convert
291
+ unit1 = Unit.new("1 attoparsec/microfortnight")
292
+ assert_nothing_raised {
293
+ unit2 = unit1 >> "in/s"
294
+ assert_equal ['<inch>'],unit2.numerator
295
+ assert_equal ['<second>'],unit2.denominator
296
+ assert_in_delta 1.0043269330917,unit2.scalar,0.00001
297
+ }
298
+ end
299
+
300
+ def test_add_operator
301
+ a = '0 mm'.unit
302
+ b = '10 cm'.unit
303
+ c = '1 in'.unit
304
+ d = '1 ml'.unit
305
+
306
+ assert_equal((a+b), b)
307
+ assert_equal((a+b).units, b.units)
308
+ assert_equal((b+a), b)
309
+ assert_equal((b+a).units, b.units)
310
+ assert_in_delta((b+c).scalar, 12.54, 0.01)
311
+ assert_equal((b+c).units, 'cm')
312
+ assert_raises(ArgumentError) {
313
+ b + d
314
+ }
315
+ end
316
+
317
+ def test_subtract_operator
318
+ a = '0 mm'.unit
319
+ b = '10 cm'.unit
320
+ c = '1 in'.unit
321
+ d = '1 ml'.unit
322
+
323
+ assert_equal((a-b), -b)
324
+ assert_equal((a-b).units, b.units)
325
+ assert_equal((b-a), b)
326
+ assert_equal((b-a).units, b.units)
327
+ assert_in_delta((b-c).scalar, 7.46, 0.01)
328
+ assert_equal((b-c).units, 'cm')
329
+ assert_raises(ArgumentError) {
330
+ b - d
331
+ }
332
+ end
333
+
334
+ def test_convert_to
335
+ unit1 = Unit.new("1 mm")
336
+ unit2 = Unit.new("1 ft")
337
+ assert_nothing_raised {
338
+ unit3 = unit1 >> unit2
339
+ assert_equal ['<foot>'], unit3.numerator
340
+ assert_equal ['<1>'],unit3.denominator
341
+ unit3 = unit1 >> "ft"
342
+ assert_equal ['<foot>'], unit3.numerator
343
+ assert_equal ['<1>'],unit3.denominator
344
+ }
345
+ assert_raises(ArgumentError) { unit1 >> 5.0}
346
+ assert_equal unit1, unit1.to(true)
347
+ assert_equal unit1, unit1.to(false)
348
+ assert_equal unit1, unit1.to(nil)
349
+ end
350
+
351
+ def test_compare
352
+ unit1 = "1 mm".unit
353
+ unit2 = "1 mm".unit
354
+ unit3 = unit2 >> "in"
355
+ assert unit1 === unit2
356
+ assert !(unit1 === unit3)
357
+ assert unit1 === "1 mm"
358
+ end
359
+
360
+ def test_matched_units
361
+ unit1 = Unit.new("1 m*kg/s")
362
+ unit2 = Unit.new("1 in*pound/min")
363
+ assert unit1 =~ unit2
364
+ end
365
+
366
+ def test_matched_units_using_string
367
+ unit1 = Unit.new("1 m*kg/s")
368
+ assert unit1 =~ "in*pound/min"
369
+ end
370
+
371
+ def test_unmatched_units
372
+ unit1 = Unit.new("1 m*kg/s")
373
+ unit2 = Unit.new("1 mm")
374
+ assert unit1 !~ unit2
375
+ end
376
+
377
+ def test_comparison_like_units
378
+ unit1 = Unit.new("1 in")
379
+ unit2 = Unit.new("1 mm")
380
+ assert_nothing_raised {
381
+ assert unit1 > unit2
382
+ }
383
+ end
384
+
385
+ def test_comparison_unlike_units
386
+ unit1 = Unit.new("1 kg")
387
+ unit2 = Unit.new("1 mm")
388
+ assert_raise(ArgumentError) { unit1 > unit2 }
389
+ end
390
+
391
+ def test_add_like_units
392
+ unit1 = Unit.new("1 mm")
393
+ unit2 = Unit.new("2 mm")
394
+ assert_nothing_raised {
395
+ assert_equal 3.0, (unit1+unit2).scalar
396
+ }
397
+ end
398
+
399
+ def test_add_similar_units
400
+ unit1 = Unit.new("1 cm")
401
+ unit2 = Unit.new("1 in")
402
+ assert_nothing_raised {
403
+ unit3 = unit1 + unit2
404
+ assert_in_delta 3.54, unit3.scalar, 0.01
405
+ }
406
+ end
407
+
408
+ def test_subtract_similar_units
409
+ unit1 = Unit.new("1 cm")
410
+ unit2 = Unit.new("1 in")
411
+ assert_nothing_raised {
412
+ unit3 = unit1 - unit2
413
+ assert_in_delta(-1.54, unit3.scalar, 0.01)
414
+ }
415
+ end
416
+
417
+ def test_add_unlike_units
418
+ unit1 = Unit.new("1 mm")
419
+ unit2 = Unit.new("2 ml")
420
+ assert_raise(ArgumentError) {(unit1+unit2).scalar}
421
+ end
422
+
423
+ def test_add_coerce
424
+ unit1 = "1 mm".unit
425
+ assert_nothing_raised {
426
+ unit2 = unit1 + "1 mm"
427
+ assert_equal "2 mm".unit, unit2
428
+ }
429
+ assert_nothing_raised {
430
+ unit2 = unit1 + [1,"mm"]
431
+ assert_equal "2 mm".unit, unit2
432
+ }
433
+ assert_nothing_raised {
434
+ unit2 = "1".unit + 1
435
+ assert_equal "2".unit, unit2
436
+ }
437
+ assert_raises(ArgumentError) {
438
+ "1".unit + nil
439
+ }
440
+ end
441
+
442
+ def test_subtract_coerce
443
+ unit1 = "1 mm".unit
444
+ assert_nothing_raised {
445
+ unit2 = unit1 - "1 mm"
446
+ assert_equal "0 mm".unit, unit2
447
+ }
448
+ end
449
+ def test_multiply_coerce
450
+ unit1 = "1 mm".unit
451
+ assert_nothing_raised {
452
+ unit2 = unit1 * "1 mm"
453
+ assert_equal "1 mm^2".unit, unit2
454
+ }
455
+ end
456
+ def test_divide_coerce
457
+ unit1 = "1 mm".unit
458
+ assert_nothing_raised {
459
+ unit2 = unit1 / "1 mm"
460
+ assert_equal "1".unit, unit2
461
+ }
462
+ end
463
+
464
+ def test_signature #"1 m s deg K kg A mol cd byte rad
465
+ unit1 = Unit.new("1 m*s*degK*kg*A*mol*cd*byte*rad*dollar")
466
+ assert_equal unit1.signature, (0..9).inject(0) {|product, n| product + 20**n}
467
+ end
468
+
469
+ def test_subtract_like_units
470
+ unit1 = Unit.new("1 mm")
471
+ unit2 = Unit.new("2 mm")
472
+ assert_nothing_raised {
473
+ assert_equal(-1, (unit1-unit2).scalar)
474
+ }
475
+ end
476
+
477
+ def test_subtract_unlike_units
478
+ unit1 = Unit.new("1 mm")
479
+ unit2 = Unit.new("2 ml")
480
+ assert_raise(ArgumentError) {(unit1-unit2).scalar}
481
+ end
482
+
483
+ def test_multiply
484
+ unit1 = Unit.new("1 m/ms")
485
+ unit2 = Unit.new("1 m/ms")
486
+ assert_nothing_raised {
487
+ unit3 = unit1 * unit2
488
+ assert_equal Unit.new("1 m^2/ms^2"), unit3
489
+ }
490
+ assert_equal unit1 * 0, '0 m/ms'.unit
491
+ end
492
+
493
+ def test_divide
494
+ unit1 = Unit.new("200 M*g/mol")
495
+ unit2 = Unit.new("200 g/mole")
496
+ assert_nothing_raised {
497
+ unit3 = unit1 / unit2
498
+ assert_equal Unit.new("1 M"), unit3
499
+ }
500
+ assert_equal unit2 / 1, unit2
501
+ unit3 = '0 s'.unit
502
+ assert_raises(ZeroDivisionError) {
503
+ unit1 / unit3
504
+ }
505
+
506
+ assert_raises(ZeroDivisionError) {
507
+ unit1 / 0
508
+ }
509
+ end
510
+
511
+ def test_inverse
512
+ unit1 = Unit.new("1 m")
513
+ unit2 = Unit.new("1 1/m")
514
+ assert_equal unit2, unit1.inverse
515
+ assert_raises((ZeroDivisionError)) { 0.unit.inverse }
516
+ end
517
+
518
+ def test_exponentiate_positive
519
+ unit1 = Unit.new("1 mm")
520
+ unit2 = Unit.new("1 mm^2")
521
+ assert_nothing_raised {
522
+ assert_equal unit2, unit1**2
523
+ }
524
+ end
525
+
526
+ def test_exponentiate_float
527
+ unit1 = Unit.new("1 mm")
528
+ assert_raise(ArgumentError) {unit1**2.5}
529
+ end
530
+
531
+ def test_exponentiate_negative
532
+ unit1 = Unit.new("1 m")
533
+ unit2 = Unit.new("1 m^-2")
534
+ assert_nothing_raised {
535
+ assert_equal unit2, unit1**-2
536
+ }
537
+ assert_raises(ZeroDivisionError) {
538
+ "0 mm".unit**-1
539
+ }
540
+ end
541
+
542
+ def test_exponentiate_zero
543
+ unit1 = Unit.new("10 mm")
544
+ unit2 = Unit.new("1")
545
+ assert_nothing_raised {
546
+ assert_equal unit2, unit1**0
547
+ }
548
+ assert_equal 1, "0 mm".unit**0
549
+ end
550
+
551
+ def test_abs
552
+ unit1 = Unit.new("-1 mm")
553
+ assert_equal "1 mm".unit, unit1.abs
554
+ end
555
+
556
+ def test_ceil
557
+ unit1 = Unit.new("1.1 mm")
558
+ unit2 = Unit.new("2 mm")
559
+ assert_equal unit2, unit1.ceil
560
+ assert_equal(('1 mm'.unit / '1 mm'.unit).ceil, 1)
561
+ assert_equal("11 kg*m".unit, ("1003 kg*m".unit / 100).ceil)
562
+ end
563
+
564
+ def test_floor
565
+ unit1 = Unit.new("1.1 mm")
566
+ unit2 = Unit.new("1 mm")
567
+ assert_equal unit2, unit1.floor
568
+ assert_equal(('1 mm'.unit / '1 mm'.unit).floor, 1)
569
+ end
570
+
571
+ def test_to_int
572
+ assert_raises(RuntimeError) {Unit.new("1.1 mm").to_i}
573
+ assert_nothing_raised {Unit.new(10.5).to_i}
574
+ end
575
+
576
+ def test_truncate
577
+ unit1 = Unit.new("1.1 mm")
578
+ unit2 = Unit.new("1 mm")
579
+ assert_equal unit2, unit1.truncate
580
+ assert_equal((unit1/unit2).truncate, 1)
581
+ end
582
+
583
+ def test_round
584
+ unit1 = Unit.new("1.1 mm")
585
+ unit2 = Unit.new("1 mm")
586
+ assert_equal unit2, unit1.round
587
+ assert_equal((unit1/unit2).round, 1)
588
+ end
589
+
590
+ def test_zero?
591
+ unit1 = Unit.new("0")
592
+ assert unit1.zero?
593
+ end
594
+
595
+ def test_nonzero?
596
+ unit1 = Unit.new("0")
597
+ unit2 = Unit.new("1 mm")
598
+ assert_nil unit1.nonzero?
599
+ assert_equal unit2, unit2.nonzero?
600
+ end
601
+
602
+ def test_equality
603
+ unit1 = Unit.new("1 cm")
604
+ unit2 = Unit.new("10 mm")
605
+ assert unit1 == unit2
606
+ end
607
+
608
+ def test_temperature_conversions
609
+ assert_raises(ArgumentError) { '-1 tempK'.unit}
610
+ assert_raises(ArgumentError) { '-1 tempR'.unit}
611
+ assert_raises(ArgumentError) { '-1000 tempC'.unit}
612
+ assert_raises(ArgumentError) { '-1000 tempF'.unit}
613
+
614
+ assert_in_delta '32 tempF'.unit.base_scalar, '0 tempC'.unit.base_scalar, 0.01
615
+ assert_in_delta '0 tempC'.unit.base_scalar, '32 tempF'.unit.base_scalar, 0.01
616
+ assert_in_delta '0 tempC'.unit.base_scalar, '273.15 tempK'.unit.base_scalar, 0.01
617
+ assert_in_delta '0 tempC'.unit.base_scalar, '491.67 tempR'.unit.base_scalar, 0.01
618
+
619
+ a = '10 degC'.unit
620
+ assert_equal a >> 'tempC', '-263.15 tempC'.unit
621
+ assert_equal a >> 'tempK', '10 tempK'.unit
622
+ assert_equal a >> 'tempR', '18 tempR'.unit
623
+ assert_equal a >> 'tempF', '-441.67 tempF'.unit
624
+
625
+ unit1 = '37 tempC'.unit
626
+ assert_equal unit1 >> 'tempF' >> 'tempK' >> 'tempR' >> 'tempC', unit1
627
+
628
+ a = '100 tempF'.unit
629
+ b = '10 degC'.unit
630
+ c = '50 tempF'.unit
631
+ d = '18 degF'.unit
632
+ assert_equal('118 tempF'.unit,a+b)
633
+ assert_equal b+a, '118 tempF'.unit
634
+ assert_equal a-b, '82 tempF'.unit
635
+ assert_in_delta((a-c).scalar, '50 degF'.unit.scalar, 0.01)
636
+ assert_in_delta '20 degC'.unit.scalar, (b+d).scalar, 0.01
637
+ assert_raises(ArgumentError) { a * b }
638
+ assert_raises(ArgumentError) { a / b }
639
+ assert_raises(ArgumentError) { a ** 2 }
640
+ assert_raises(ArgumentError) { c - '400 degK'.unit}
641
+ assert_equal a, a.to('tempF')
642
+ end
643
+
644
+ def test_feet
645
+ unit1 = Unit.new("6'6\"")
646
+ assert_in_delta 6.5, unit1.scalar, 0.01
647
+ unit2 = "6'".unit
648
+ assert_equal unit2, '6 feet'.unit
649
+ unit3 = '6"'.unit
650
+ assert_equal unit3, '6 inch'.unit
651
+
652
+ end
653
+
654
+ def test_pounds
655
+ unit1 = Unit.new("8 pounds, 8 ounces")
656
+ assert_in_delta 8.5, unit1.scalar, 0.01
657
+ assert_equal '150#'.unit, '150 lbs'.unit
658
+ end
659
+
660
+ # these units are 'ambiguous' and could be mis-parsed
661
+ def test_parse_tricky_units
662
+ unit1 = Unit.new('1 mm') #sometimes parsed as 'm*m'
663
+ assert_equal ['<milli>','<meter>'], unit1.numerator
664
+ unit2 = Unit.new('1 cd') # could be a 'centi-day' instead of a candela
665
+ assert_equal ['<candela>'], unit2.numerator
666
+ unit3 = Unit.new('1 min') # could be a 'milli-inch' instead of a minute
667
+ assert_equal ['<minute>'], unit3.numerator
668
+ unit4 = Unit.new('1 ft') # could be a 'femto-ton' instead of a foot
669
+ assert_equal ['<foot>'], unit4.numerator
670
+ unit5 = "1 atm".unit
671
+ assert_equal ['<atm>'], unit5.numerator
672
+ unit6 = "1 doz".unit
673
+ assert_equal ['<dozen>'], unit6.numerator
674
+ end
675
+
676
+ def test_to_s
677
+ unit1 = Unit.new("1")
678
+ assert_equal "1", unit1.to_s
679
+ unit2 = Unit.new("mm")
680
+ assert_equal "1 mm", unit2.to_s
681
+ assert_equal "0.04 in", unit2.to_s("%0.2f in")
682
+ assert_equal "1/10 cm", unit2.to_s("cm")
683
+ unit3 = Unit.new("1 mm")
684
+ assert_equal "1 mm", unit3.to_s
685
+ assert_equal "0.04 in", unit3.to_s("%0.2f in")
686
+ unit4 = Unit.new("1 mm^2")
687
+ assert_equal "1 mm^2", unit4.to_s
688
+ unit5 = Unit.new("1 mm^2 s^-2")
689
+ assert_equal "1 mm^2/s^2", unit5.to_s
690
+ unit6= Unit.new("1 kg*m/s")
691
+ assert_equal "1 kg*m/s", unit6.to_s
692
+ unit7= Unit.new("1 1/m")
693
+ assert_equal "1 1/m", unit7.to_s
694
+ assert_equal("1.5 mm", Unit.new("1.5 mm").to_s)
695
+ assert_equal("1.5 mm", "#{Unit.new('1.5 mm')}")
696
+ end
697
+
698
+ def test_to_feet_inches
699
+ unit1 = Unit.new("6'5\"")
700
+ assert_equal "6'5\"", unit1.to_s(:ft)
701
+ assert_raises(ArgumentError) {
702
+ unit1 = Unit.new("1 kg")
703
+ unit1.to_s(:ft)
704
+ }
705
+ end
706
+
707
+ def test_to_lbs_oz
708
+ unit1 = Unit.new("8 lbs 8 oz")
709
+ assert_equal "8 lbs, 8 oz", unit1.to_s(:lbs)
710
+ assert_raises(ArgumentError) {
711
+ unit1 = Unit.new("1 m")
712
+ unit1.to_s(:lbs)
713
+ }
714
+ end
715
+
716
+ def test_add_units
717
+ a = Unit.new("1 inchworm")
718
+ assert_equal "1 inworm", a.to_s
719
+ end
720
+
721
+ def test_ideal_gas_law
722
+ p = Unit "100 kPa"
723
+ v = Unit "1 m^3"
724
+ n = Unit "1 mole"
725
+ r = Unit "8.31451 J/mol*degK"
726
+ t = ((p*v)/(n*r)).to('tempK')
727
+ assert_in_delta 12027.16,t.base_scalar, 0.1
728
+ end
729
+
730
+
731
+ def test_eliminate_terms
732
+ a = ['<meter>','<meter>','<kelvin>','<second>']
733
+ b = ['<meter>','<meter>','<second>']
734
+ h = Unit.eliminate_terms(1,a,b)
735
+ assert_equal ['<kelvin>'], h[:numerator]
736
+ end
737
+
738
+ def test_to_base_consistency
739
+ a = "1 W*m/J*s".unit
740
+ assert_equal a.signature, a.to_base.signature
741
+ end
742
+
743
+ def test_unit_roots
744
+ unit1 = Unit "2 m*J*kg"
745
+ unit2 = Unit "4 m^2*J^2*kg^2"
746
+ unit3 = Unit "8 m^3*J^3*kg^3"
747
+ assert_equal unit2**(1/2), unit1
748
+ assert_equal unit3**(1/3), unit1
749
+ end
750
+
751
+ def test_inspect
752
+ unit1 = Unit "1 mm"
753
+ assert_equal "1 mm", unit1.inspect
754
+ assert_not_equal "1.0 mm", unit1.inspect(:dump)
755
+ end
756
+
757
+ def test_to_f
758
+ assert_equal 1, 1.unit.to_f
759
+ assert_raises(RuntimeError) {
760
+ assert_equal 1, "1 mm".unit.to_f
761
+ }
762
+ end
763
+
764
+ def test_exponentiate_float2
765
+ assert_equal "2 m".unit, "4 m^2".unit**(0.5)
766
+ assert_raises(ArgumentError) { "1 mm".unit**(2/3)}
767
+ assert_raises(ArgumentError) { "1 mm".unit**("A")}
768
+
769
+ end
770
+
771
+ def test_range
772
+ a = Unit "1 mm"
773
+ b = Unit "3 mm"
774
+ c = (a..b).to_a
775
+ assert_equal ["1 mm".unit, "2 mm".unit, "3 mm".unit], c
776
+ end
777
+
778
+ def test_scientific
779
+ a = Unit "1e6 cells"
780
+ assert_equal 1e6, a.scalar
781
+ assert_equal "cells", a.units
782
+ end
783
+
784
+ if defined?(Uncertain)
785
+ def test_uncertain
786
+ a = '1 +/- 1 mm'.unit
787
+ assert_equal a.to_s, '1 +/- 1 mm'
788
+ end
789
+ end
790
+
791
+ def test_format
792
+ assert_equal "%0.2f" % "1 mm".unit, "1.00 mm"
793
+ end
794
+
795
+ def test_bad_units
796
+ assert_raises(ArgumentError) { '1 doohickey / thingamabob'.unit}
797
+ assert_raises(ArgumentError) { '1 minimeter'.unit}
798
+ end
799
+
800
+ def test_currency
801
+ assert_nothing_raised {"$1".unit}
802
+ end
803
+
804
+ def test_kind
805
+ a = "1 mm".unit
806
+ assert_equal a.kind, :length
807
+ end
808
+
809
+ def test_percent
810
+ assert_nothing_raised {
811
+ "1 percent".unit
812
+ "1%".unit
813
+ "0.01%".unit
814
+ }
815
+ a = '100 ml'.unit
816
+ b = '50%'.unit
817
+ c = a*b >> 'ml'
818
+ assert c =~ a
819
+ assert_in_delta '50 ml'.unit.scalar, c.scalar, 0.0001
820
+ end
821
+
822
+ def test_parse
823
+ assert_nothing_raised { "1 1/m".unit }
824
+ assert_raises(ArgumentError) { "3 s/s/ft".unit }
825
+ assert_raises(ArgumentError) { "3 s**2|,s**2".unit }
826
+ assert_raises(ArgumentError) { "3 s**2 4s s**2".unit }
827
+ assert_raises(ArgumentError) { "3 s 5^6".unit }
828
+ assert_raises(ArgumentError) { "".unit }
829
+ assert_raises(ArgumentError) { " ".unit }
830
+ assert_raises(ArgumentError) { "\t".unit }
831
+ assert_raises(ArgumentError) { "\t\t".unit }
832
+ assert_raises(ArgumentError) { "\n".unit }
833
+ end
834
+
835
+ def test_inline_conversions
836
+ assert_equal "60 s".unit, Unit.parse("1 min to seconds")
837
+ assert_equal "60 s".unit, Unit.parse("1 min as seconds")
838
+ assert_equal "60 s".unit, Unit.parse("1 min in seconds")
839
+ end
840
+
841
+ def test_time_conversions
842
+ today = 'now'.to_time
843
+ assert_equal today,@april_fools
844
+ last_century = today - '150 years'.unit
845
+ assert_equal last_century.to_date, '1856-04-01'.to_date
846
+ end
847
+
848
+ def test_coercion
849
+ assert_nothing_raised { 1.0 * '1 mm'.unit}
850
+ assert_nothing_raised { '1 mm'.unit * 1.0}
851
+ end
852
+
853
+ def test_zero
854
+ assert_nothing_raised { Unit.new(0) }
855
+ end
856
+
857
+ def test_divide_results_in_unitless
858
+ a = '10 mg/ml'.unit
859
+ b = '10 mg/ml'.unit
860
+ assert_equal a/b, 1
861
+ end
862
+
863
+ def test_wt_percent
864
+ a = '1 wt%'.unit
865
+ b = '1 g/dl'.unit
866
+ assert_equal a,b
867
+ end
868
+
869
+ def test_parse_durations
870
+ assert_equal "1:00".unit, '1 hour'.unit
871
+ assert_equal "1:30".unit, "1.5 hour".unit
872
+ assert_equal "1:30:30".unit, "1.5 hour".unit + '30 sec'.unit
873
+ assert_equal "1:30:30,200".unit, "1.5 hour".unit + '30 sec'.unit + '200 usec'.unit
874
+ end
875
+
876
+ def test_coercion_2
877
+ a = Dummy.new
878
+ b = '1 mm'.unit
879
+ assert_equal '2 mm'.unit, b + a
880
+ end
881
+
882
+ def test_create_with_other_unit
883
+ a = '1 g'.unit
884
+ b = 0.unit(a)
885
+ assert_equal b, '0 g'.unit
886
+ end
887
+
888
+ def test_sqrt
889
+ a = '-9 mm^2'.unit
890
+ b = a**(0.5)
891
+ assert_in_delta Math.sqrt(a).to_unit.scalar.real, b.scalar.real, 0.00001
892
+ # ruby 1.8.x uses .image while 1.9.x uses .imaginary
893
+ if Complex.instance_methods.include?(:imaginary)
894
+ assert_in_delta Math.sqrt(a).to_unit.scalar.imaginary, b.scalar.imaginary, 0.00001
895
+ else
896
+ assert_in_delta Math.sqrt(a).to_unit.scalar.image, b.scalar.image, 0.00001
897
+ end
898
+ end
899
+
900
+ def test_div
901
+ assert_equal 11,"23 m".unit.div('2 m'.unit)
902
+ end
903
+
904
+ def test_divmod
905
+ assert_equal [277,1], 555.unit('mm').divmod(2.unit('mm'))
906
+ assert_equal [277, 0.0010000000000000373], '0.555 m'.unit.divmod('2 mm'.unit)
907
+ assert_raises(ArgumentError) { '1 m'.unit.divmod('1 kg'.unit) }
908
+ end
909
+
910
+ if Math.respond_to?(:cbrt)
911
+ def test_cbrt
912
+ assert_in_delta '2 mm'.to_unit, Math.cbrt('8 mm^3'.to_unit), 0.0001
913
+ end
914
+ end
915
+
916
+ def test_hypot
917
+ assert_equal Math.hypot('3 mm'.unit,'4 mm'.unit), '5 mm'.unit
918
+ assert_raises(ArgumentError) { Math.hypot('3 mm'.unit, '4 kg'.unit)}
919
+ end
920
+
921
+ def test_complex
922
+ assert_equal '1+1i mm'.unit.scalar, Complex(1,1)
923
+ assert_equal '1+1i'.unit.scalar, Complex(1,1)
924
+ assert_raises(RuntimeError) { '1+1i mm'.unit.to_c}
925
+ end
926
+
927
+ def test_atan2
928
+ assert_equal Math.atan2('1 mm'.unit,'1 mm'.unit), Math.atan2(1,1)
929
+ assert_raises(ArgumentError) {Math.atan2('1 mm'.unit, '1 lb'.unit)}
930
+ assert_raises(RuntimeError) {Math.atan2('1 mm'.unit, 1)}
931
+ end
932
+
933
+ def test_rational_units
934
+ assert_equal '1/4 cup'.unit, '0.25 cup'.unit
935
+ assert_equal '1/4 in/s'.unit, '0.25 in/s'.unit
936
+ assert_equal '1/4'.unit, 0.25
937
+ end
938
+
939
+ def test_to_date
940
+ a = Time.now
941
+ assert_equal a.send(:to_date), Date.today
942
+ end
943
+
944
+ def test_natural_language
945
+ assert_equal Unit.parse("10 mm in cm"), '10 mm'.unit.to('cm')
946
+ end
947
+
948
+ def test_round_pounds
949
+ assert_equal '1 lbs'.unit, '1.1 lbs'.unit.round
950
+ end
951
+
952
+ def test_explicit_init
953
+ assert_equal '1 lbf'.unit, '1 <pound-force>'.unit
954
+ assert_equal '1 lbs'.unit, '1 <pound>'.unit
955
+ assert_equal('1 kg*m'.unit, '1 <kilogram>*<meter>'.unit)
956
+ end
957
+
958
+ def test_format_nil_string
959
+ assert_nothing_raised {"" % nil}
960
+ assert_nothing_raised {"" % false}
961
+ end
962
+
963
+ def test_to_s_cache
964
+ Unit.clear_cache
965
+ a = Unit.new('1 mm')
966
+ a.to_s # cache the conversion to itself
967
+ b = Unit.new('2 mm')
968
+ assert_equal('2 mm', b.to_s)
969
+ assert_equal('1/1000 m', a.to_s('m'))
970
+ assert_equal('1/1000 m', a.output['m'])
971
+ end
972
+
973
+ def test_version
974
+ assert_equal('1.3.0.a', Unit::VERSION)
975
+ end
976
+
977
+ def test_negation
978
+ a = 1.to_unit
979
+ assert_equal(a.class, (1-a).class)
980
+ end
981
+
982
+ def test_degree
983
+ assert "100 tempF".unit.degree?
984
+ assert "100 degC".unit.degree?
985
+ assert !"1 mm".unit.degree?
986
+ end
987
+
988
+ def test_temperature
989
+ assert "100 tempF".unit.temperature?
990
+ assert !"100 degC".unit.temperature?
991
+ assert !"1 mm".unit.temperature?
992
+ end
993
+
994
+ def test_parse_into_numbers_and_units
995
+ assert_equal([1,"m"], Unit.parse_into_numbers_and_units("1 m"))
996
+ assert_equal([1.0,"m"], Unit.parse_into_numbers_and_units("1.0 m"))
997
+ assert_equal([0.1,"m"], Unit.parse_into_numbers_and_units("0.1 m"))
998
+ assert_equal([0.1,"m"], Unit.parse_into_numbers_and_units(".1 m"))
999
+ assert_equal([-1.23E-3,"m"], Unit.parse_into_numbers_and_units("-1.23E-3 m"))
1000
+ assert_equal([1/4,"m"], Unit.parse_into_numbers_and_units("1/4 m"))
1001
+ assert_equal([-1/4,"m"], Unit.parse_into_numbers_and_units("-1/4 m"))
1002
+ assert_equal([1,"m"], Unit.parse_into_numbers_and_units("1 m"))
1003
+ assert_equal([1,"m"], Unit.parse_into_numbers_and_units("m"))
1004
+ assert_equal([10,""], Unit.parse_into_numbers_and_units("10"))
1005
+ assert_equal([10.0,""], Unit.parse_into_numbers_and_units("10.0"))
1006
+ assert_equal([(1/4),""], Unit.parse_into_numbers_and_units("1/4"))
1007
+ assert_equal([Complex(1,1),""], Unit.parse_into_numbers_and_units("1+1i"))
1008
+ end
1009
+
1010
+ end
1011
+