rails-units 1.3.1

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