require './units'    # Use require "numru/units" after installation.
include NumRu

def assert(test, seikai)
	raise "#{test.inspect} != #{seikai.inspect}" if test != seikai
	puts "ok #{seikai.inspect}"
end

puts "=== reduce1 ==="

assert Units.new('').reduce1.to_s, "1"
assert Units.new('m').reduce1.to_s, "m"
assert Units.new('3').reduce1.to_s, "3"
assert Units.new('3.14').reduce1.to_s, "3.14"
assert Units.new('m2').reduce1.to_s, "m2"
assert Units.new('m.s').reduce1.to_s, "m.s"
assert Units.new('m/s').reduce1.to_s, "m.s-1"
assert Units.new('kg.m/s2').reduce1.to_s, "kg.m.(s2)-1"
assert Units.new('s @ 2003-11-29').reduce1.to_s,
	"(s @ 2003-11-29T00:00:00.00 +00:00)"
assert Units.new('s @ 2003-11-29T11:24').reduce1.to_s,
	"(s @ 2003-11-29T11:24:00.00 +00:00)"
assert Units.new('s @ 2003-11-29T11:24:11 -09:00').reduce1.to_s,
	"(s @ 2003-11-29T11:24:11.00 -09:00)"

assert Units.new('100').reduce1.to_s, "100"
assert Units.new('(10)^2').reduce1.to_s, "(10)2"
assert Units.new('(10)^2/100').reduce1.to_s, "(10)2.(100)-1"

puts "=== reduce2 ==="

assert Units.new('s @ 2003-11-29').reduce2.to_s,
	"(s @ 2003-11-29T00:00:00.00 +00:00)"
assert Units.new('m/(s @ 2003-11-29)').reduce2.to_s, "m.s-1"
assert Units.new('m/((K @ 273.15) (s from 2003-11-29))').reduce2.to_s, "m.(K.s)-1"

assert Units.new('(10)^2/100').reduce2.to_s, "(10)2.(100)-1"

puts "=== reduce3 ==="

assert Units::MultiNode.new(Units::NameNode.new('a'),  \
	Units::NumberNode.new(1), \
	Units::NameNode.new('b')).to_s, 'a.1 b'

assert Units.new('kg').reduce3.inspect, "Units[Name[kg]]"
assert Units.new('kg.m').reduce3.inspect, "Units[Multi[Name[kg], Name[m]]]"
assert Units.new('kg.m.s').reduce3.inspect,
	"Units[Multi[Name[kg], Name[m], Name[s]]]"

assert Units.new('(m.s)^2').reduce3.inspect,
	"Units[Multi[Pow[Name[m], Number[2]], Pow[Name[s], Number[2]]]]"
assert Units.new('K @ 273.15').reduce3.inspect,
	"Units[Shift[Name[K], Number[273.15]]]"
assert Units.new('((a.b)^2)^2').reduce3.inspect,
	"Units[Multi[Pow[Name[a], Number[4]], Pow[Name[b], Number[4]]]]"
assert Units.new('((a.b)^2 c4 d)^2').reduce3.inspect,
	"Units[Multi[Pow[Name[a], Number[4]], Pow[Name[b], Number[4]], Pow[Name[c], Number[8]], Pow[Name[d], Number[2]]]]"
assert Units.new('((a.b)^2 c4 d)^2').reduce3.to_s,
	"a4 b4 c8 d2"
assert Units.new('((a.b)^2 a4 b)^2').reduce3.to_s,
	"a4 b4 a8 b2"

assert Units.new('s @ 2003-11-29').reduce3.to_s,
	"(s @ 2003-11-29T00:00:00.00 +00:00)"
assert Units.new('m/(s @ 2003-11-29)').reduce3.to_s, "m.s-1"
assert Units.new('m/((K @ 273.15) (s from 2003-11-29))').reduce3.to_s, "m.K-1 s-1"

assert Units.new('(10)^2/100').reduce3.to_s, "(10)2.(100)-1"

puts "=== reduce4 ==="

assert Units.new('((a.b)^2 a4 b @ now)^2 @ 273.15').reduce4.to_s,
	"(a12 b6 @ 273.15)"

assert Units.new('km2').reduce4.to_s, "km2"
assert Units.new('hours.hour').reduce4.to_s, "hour2"
assert Units.new('(10)^2').reduce4.to_s, "100"
assert Units.new('100/10').reduce4.to_s, "10"
assert Units.new('(10)^2/100').reduce4.to_s, "1"

puts "=== reduce5 ==="

assert Units.new('km2').reduce5.to_s, "1000000 m2"
assert Units.new('(10)^2/100').reduce5.to_s, "1"

assert Units.new('hPa').reduce5.to_s, "100 kg.m-1 s-2"
assert Units.new('mb').reduce5.to_s, "100 kg.m-1 s-2"

assert Units.new('hPa/mb').reduce5.to_s, "1"

assert Units.new('(K @ 273.15)@ 10').reduce5.to_s, "(K @ 283.15)"

puts "=== APPLICATIONS ==="

assert Units.new('km @ 2').convert(3, Units.new('m @ 100')), 4900
assert Units.new('degree_F').convert(32, Units.new('K')).to_s, ((32+459.67)*(1.8**-1)).to_s

u1 = Units.new('m/s')
u2 = Units.new('mm/s')
assert((u1/u2).to_s, "m.mm-1")
assert((u1*u2).to_s, "m.mm.s-2")

u1 = Units.new('years since 1999-01-01 00:00').reduce4
u2 = Units.new('hours since 2001-01-01 00:00').reduce4
assert u1.convert(3, u2), 24 * 365
u3 = Units.new('months since 2001-01-01 00:00').reduce4
assert u1.convert(3, u3), 12.0

Units.reduce_level = 3
assert((Units.new('hours') ** 2).to_s, "hours2")
Units.reduce_level = 4
assert((Units.new('hours') ** 2).to_s, "hour2")
Units.reduce_level = 5
assert((Units.new('hours') ** 2).to_s, "12960000 s2")

assert(Units.new('day') =~ Units.new('s since 2002-01-01'), true)
assert(Units.new('m') =~ Units.new('1'), false)

un1  = Units['day since 2000-01-01']
un2 = Units['s since 2000-01-01']
assert(un1.convert(0, un2), 0.0)
assert(un1.convert(1, un2), 86400.0)
