require 'test/unit' require 'ruby-units' class Unit < Numeric @@USER_DEFINITIONS = {'' => [%w{inworm inchworm}, 0.0254, :length, %w{} ], '' => [%{degH}, 100, :temperature, %w{}]} Unit.setup end class TestRubyUnit < Test::Unit::TestCase def test_clone unit1= "1 mm".unit unit2 = unit1.clone assert_not_equal unit1.numerator.object_id, unit2.numerator.object_id assert_not_equal unit1.denominator.object_id, unit2.denominator.object_id assert unit1 === unit2 end def test_unary_minus unit1 = Unit.new("1 mm") unit2 = Unit.new("-1 mm") assert_equal unit1, -unit2 end def test_unary_plus unit1 = Unit.new("1 mm") assert_equal unit1, +unit1 end def test_create_unit_only unit1 = Unit.new("m") assert_equal [''], unit1.numerator assert_equal 1.0, unit1.quantity end def test_to_base unit1 = Unit.new("100 cm") assert_in_delta 1, 0.001, unit1.to_base.quantity unit2 = Unit("1 mm^2 ms^-2") assert_in_delta 1, 0.001, unit2.to_base.quantity end def test_to_unit unit1 = "1 mm".to_unit assert Unit === unit1 unit2 = Unit("1 mm") assert Unit === unit1 assert unit1 == unit2 unit1 = "2.54 cm".to_unit("in") assert_in_delta 1, 0.001, unit1.quantity assert_equal [''], unit1.numerator unit1 = "2.54 cm".unit("in") assert_in_delta 1, 0.001, unit1.quantity assert_equal [''], unit1.numerator unit1 = 1.unit assert_in_delta 1, 0.001, unit1.quantity assert_equal ['<1>'], unit1.numerator unit1 = [1,'mm'].unit assert_in_delta 1, 0.001, unit1.quantity assert_equal ['',''], unit1.numerator end def test_create_unitless unit1 = Unit.new("1") assert_equal 1,unit1.to_f assert_equal ['<1>'],unit1.numerator assert_equal ['<1>'],unit1.denominator unit1 = Unit.new("1.5") assert_equal 1.5,unit1.to_f assert_equal ['<1>'],unit1.numerator assert_equal ['<1>'],unit1.denominator end def test_create_simple unit1 = Unit.new("1 m") assert_equal 1,unit1.to_f assert_equal [''], unit1.numerator assert_equal ['<1>'],unit1.denominator end def test_create_compound unit1 = Unit.new("1 N*m") assert_equal 1,unit1.to_f assert_equal ['',''],unit1.numerator assert_equal ['<1>'],unit1.denominator end def test_create_with_denominator unit1 = Unit.new("1 m/s") assert_equal 1, unit1.to_f assert_equal [''],unit1.numerator assert_equal [''],unit1.denominator end def test_create_with_powers unit1 = Unit.new("1 m^2/s^2") assert_equal 1, unit1.to_f assert_equal ['',''],unit1.numerator assert_equal ['',''],unit1.denominator end def test_create_with_zero_power unit1 = Unit.new("1 m^0") assert_equal 1,unit1.to_f assert_equal ['<1>'],unit1.numerator assert_equal ['<1>'],unit1.denominator end def test_create_with_negative_powers unit1 = Unit.new("1 m^2 s^-2") assert_equal 1, unit1.to_f assert_equal ['',''],unit1.numerator assert_equal ['',''],unit1.denominator end def test_create_from_array unit1 = Unit.new([1, "mm^2", "ul^2"]) assert_equal 1, unit1.to_f assert_equal ['','','',''], unit1.numerator assert_equal ['','','',''], unit1.denominator end def test_bad_create assert_raises(ArgumentError) { Unit.new(nil)} assert_raises(ArgumentError) { Unit.new(true)} assert_raises(ArgumentError) { Unit.new(false)} assert_raises(ArgumentError) { Unit.new(/(.+)/)} end def test_convert unit1 = Unit.new("1 attoparsec/microfortnight") assert_nothing_raised { unit2 = unit1 >> "in/s" assert_equal [''],unit2.numerator assert_equal [''],unit2.denominator assert_in_delta 1.0043269330917,unit2.to_f,0.00001 } end def test_convert_to unit1 = Unit.new("1 mm") unit2 = Unit.new("1 ft") assert_nothing_raised { unit3 = unit1 >> unit2 assert_equal [''], unit3.numerator assert_equal ['<1>'],unit3.denominator unit3 = unit1 >> "ft" assert_equal [''], unit3.numerator assert_equal ['<1>'],unit3.denominator } assert_raises(ArgumentError) { unit3= unit1 >> 5.0} end def test_compare unit1 = "1 mm".unit unit2 = "1 mm".unit unit3 = unit2 >> "in" assert unit1 === unit2 assert !(unit1 === unit3) assert unit1 === "1 mm" end def test_matched_units unit1 = Unit.new("1 m*kg/s") unit2 = Unit.new("1 in*pound/min") assert unit1 =~ unit2 end def test_matched_units_using_string unit1 = Unit.new("1 m*kg/s") assert unit1 =~ "in*pound/min" end def test_unmatched_units unit1 = Unit.new("1 m*kg/s") unit2 = Unit.new("1 mm") assert unit1 !~ unit2 end def test_comparison_like_units unit1 = Unit.new("1 in") unit2 = Unit.new("1 mm") assert_nothing_raised { assert unit1 > unit2 } end def test_comparison_unlike_units unit1 = Unit.new("1 kg") unit2 = Unit.new("1 mm") assert_raise(ArgumentError) { unit1 > unit2 } end def test_add_like_units unit1 = Unit.new("1 mm") unit2 = Unit.new("2 mm") assert_nothing_raised { assert_equal 3.0, (unit1+unit2).to_f } end def test_add_similar_units unit1 = Unit.new("1 cm") unit2 = Unit.new("1 in") assert_nothing_raised { unit3 = unit1 + unit2 assert_in_delta 3.54, unit3.to_f, 0.01 } end def test_subtract_similar_units unit1 = Unit.new("1 cm") unit2 = Unit.new("1 in") assert_nothing_raised { unit3 = unit1 - unit2 assert_in_delta -1.54, unit3.to_f, 0.01 } end def test_add_unlike_units unit1 = Unit.new("1 mm") unit2 = Unit.new("2 ml") assert_raise(ArgumentError) {(unit1+unit2).to_f} end def test_add_coerce unit1 = "1 mm".unit assert_nothing_raised { unit2 = unit1 + "1 mm" assert_equal "2 mm".unit, unit2 } assert_nothing_raised { unit2 = unit1 + [1,"mm"] assert_equal "2 mm".unit, unit2 } assert_nothing_raised { unit2 = "1".unit + 1 assert_equal "2".unit, unit2 } assert_raises(ArgumentError) { unit2 = "1".unit + nil } end def test_subtract_coerce unit1 = "1 mm".unit assert_nothing_raised { unit2 = unit1 - "1 mm" assert_equal "0 mm".unit, unit2 } end def test_multiply_coerce unit1 = "1 mm".unit assert_nothing_raised { unit2 = unit1 * "1 mm" assert_equal "1 mm^2".unit, unit2 } end def test_divide_coerce unit1 = "1 mm".unit assert_nothing_raised { unit2 = unit1 / "1 mm" assert_equal "1".unit, unit2 } end def test_signature #"1 m s deg K kg A mol cd byte rad unit1 = Unit.new("1 m*s*degK*kg*A*mol*cd*byte*rad*dollar") assert_equal unit1.signature, (0..9).inject(0) {|product, n| product + 20**n} end def test_subtract_like_units unit1 = Unit.new("1 mm") unit2 = Unit.new("2 mm") assert_nothing_raised { assert_equal -1, (unit1-unit2).to_f } end def test_subtract_unlike_units unit1 = Unit.new("1 mm") unit2 = Unit.new("2 ml") assert_raise(ArgumentError) {(unit1-unit2).to_f} end def test_multiply unit1 = Unit.new("1 m/ms") unit2 = Unit.new("1 m/ms") assert_nothing_raised { unit3 = unit1 * unit2 assert_equal Unit.new("1 m^2/ms^2"), unit3 } end def test_divide unit1 = Unit.new("200 M*g/mol") unit2 = Unit.new("200 g/mole") assert_nothing_raised { unit3 = unit1 / unit2 assert_equal Unit.new("1 M"), unit3 } end def test_inverse unit1 = Unit.new("1 m") unit2 = Unit.new("1 1/m") assert_equal unit2, unit1.inverse end def test_exponentiate_positive unit1 = Unit.new("1 mm") unit2 = Unit.new("1 mm^2") assert_nothing_raised { assert_equal unit2, unit1**2 } end def test_exponentiate_float unit1 = Unit.new("1 mm") assert_raise(ArgumentError) {unit1**2.5} end def test_exponentiate_negative unit1 = Unit.new("1 m") unit2 = Unit.new("1 m^-2") assert_nothing_raised { assert_equal unit2, unit1**-2 } end def test_exponentiate_zero unit1 = Unit.new("10 mm") unit2 = Unit.new("1") assert_nothing_raised { assert_equal unit2, unit1**0 } end def test_abs unit1 = Unit.new("-1 mm") assert_equal 1, unit1.abs end def test_ceil unit1 = Unit.new("1.1 mm") unit2 = Unit.new("2 mm") assert_equal unit2, unit1.ceil end def test_floor unit1 = Unit.new("1.1 mm") unit2 = Unit.new("1 mm") assert_equal unit2, unit1.floor end def test_to_int unit1 = Unit.new("1.1 mm") unit2 = Unit.new("1 mm") assert_equal unit2, unit1.to_int end def test_truncate unit1 = Unit.new("1.1 mm") unit2 = Unit.new("1 mm") assert_equal unit2, unit1.truncate end def test_round unit1 = Unit.new("1.1 mm") unit2 = Unit.new("1 mm") assert_equal unit2, unit1.round end def test_zero? unit1 = Unit.new("0") assert unit1.zero? end def test_nonzero? unit1 = Unit.new("0") unit2 = Unit.new("1 mm") assert_nil unit1.nonzero? assert_equal unit2, unit2.nonzero? end def test_equality unit1 = Unit.new("1 cm") unit2 = Unit.new("10 mm") assert unit1 == unit2 end def test_temperature_conversions unit1 = Unit.new("37 degC") unit2 = unit1 >> "degF" assert_in_delta 98.6, unit2.to_f, 0.1 unit2 = unit1 >> "degK" assert_in_delta 310.15, unit2.to_f, 0.01 unit2 = unit1 >> "degR" assert_in_delta 558.27, unit2.to_f, 0.01 unit3 = Unit.new("1 J/degC") assert_in_delta 1, (unit3 >> "J/degK").to_f, 0.01 assert_raises(ArgumentError) {unit1 >> "degH"} unit1 = Unit.new("98.6 degF") unit2 = unit1 >> "degC" assert_in_delta 37, unit2.to_f, 0.1 unit2 = unit1 >> "degK" assert_in_delta 310.15, unit2.to_f, 0.01 unit2 = unit1 >> "degR" assert_in_delta 558.27, unit2.to_f, 0.01 unit3 = Unit.new("1 J/degC") assert_in_delta 1, (unit3 >> "J/degK").to_f, 0.01 assert_raises(ArgumentError) {unit1 >> "degH"} unit1 = Unit.new("310.15 degK") unit2 = unit1 >> "degF" assert_in_delta 98.6, unit2.to_f, 0.1 unit2 = unit1 >> "degC" assert_in_delta 37, unit2.to_f, 0.01 unit2 = unit1 >> "degR" assert_in_delta 558.27, unit2.to_f, 0.01 unit3 = Unit.new("1 J/degC") assert_in_delta 1, (unit3 >> "J/degK").to_f, 0.01 assert_raises(ArgumentError) {unit1 >> "degH"} unit1 = Unit.new("558.27 degR") unit2 = unit1 >> "degC" assert_in_delta 37, unit2.to_f, 0.1 unit2 = unit1 >> "degK" assert_in_delta 310.15, unit2.to_f, 0.01 unit2 = unit1 >> "degF" assert_in_delta 98.6, unit2.to_f, 0.01 unit3 = Unit.new("1 J/degC") assert_in_delta 1, (unit3 >> "J/degK").to_f, 0.01 assert_raises(ArgumentError) {unit1 >> "degH"} assert_raises(ArgumentError) {"10 degH".unit >> "degH"} end def test_feet unit1 = Unit.new("6'6\"") assert_in_delta 6.5, unit1.to_f, 0.01 end def test_pounds unit1 = Unit.new("8 pounds, 8 ounces") assert_in_delta 8.5, unit1.to_f, 0.01 end # these units are 'ambiguous' and could be mis-parsed def test_parse_tricky_units unit1 = Unit.new('1 mm') #sometimes parsed as 'm*m' assert_equal ['',''], unit1.numerator unit2 = Unit.new('1 cd') # could be a 'centi-day' instead of a candela assert_equal [''], unit2.numerator unit3 = Unit.new('1 min') # could be a 'milli-inch' instead of a minute assert_equal [''], unit3.numerator unit4 = Unit.new('1 ft') # could be a 'femto-ton' instead of a foot assert_equal [''], unit4.numerator end def test_to_s unit1 = Unit.new("1") assert_equal "1", unit1.to_s unit2 = Unit.new("mm") assert_equal "1 mm", unit2.to_s assert_equal "0.04 in", unit2.to_s("%0.2f in") assert_equal "0.1 cm", unit2.to_s("cm") unit3 = Unit.new("1 mm") assert_equal "1 mm", unit3.to_s assert_equal "0.04 in", unit3.to_s("%0.2f in") unit4 = Unit.new("1 mm^2") assert_equal "1 mm^2", unit4.to_s unit5 = Unit.new("1 mm^2 s^-2") assert_equal "1 mm^2/s^2", unit5.to_s unit6= Unit.new("1 kg*m/s") assert_equal "1 kg*m/s", unit6.to_s unit7= Unit.new("1 1/m") assert_equal "1 1/m", unit7.to_s end def test_to_feet_inches unit1 = Unit.new("6'5\"") assert_equal "6'5\"", unit1.to_s(:ft) assert_raises(ArgumentError) { unit1 = Unit.new("1 kg") unit1.to_s(:ft) } end def test_to_lbs_oz unit1 = Unit.new("8 lbs 8 oz") assert_equal "8 lbs, 8 oz", unit1.to_s(:lbs) assert_raises(ArgumentError) { unit1 = Unit.new("1 m") unit1.to_s(:lbs) } end def test_add_units a = Unit.new("1 inchworm") assert_equal "1 inworm", a.to_s end end