#!/www/python/bin/python
"""
$URL: svn+ssh://svn/repos/trunk/mems/lib/lib/test/test_range.py $
$Id: test_range.py 24663 2004-07-12 16:16:28Z dbinger $
"""

from sancho.unittest import TestScenario, parse_args, run_scenarios
from dulcinea.range_value import RangeValue
from dulcinea.physical_value import PhysicalValue

tested_modules = [ "dulcinea.range_value" ]

class RangeTest (TestScenario):

    def check_init(self):
        self.test_stmt("r1 = RangeValue(1, 3)")
        self.test_val("r1.get_tuple()", (1,3))
        self.test_val("r1.get_min()", 1)
        self.test_val("r1.get_max()", 3)
        self.test_val("r1.get_type()", int)
        self.test_stmt("r = RangeValue(1.0, 3.0)")
        self.test_val("r.get_tuple()", (1.0,3.0))
        self.test_val("map(type, r.get_tuple())", [float,float])


    def check_init_err(self):
        self.test_exc("RangeValue()", TypeError)
        self.test_exc("RangeValue(1)", TypeError)
        self.test_exc("RangeValue(1, 2, 3)", TypeError)
        self.test_exc("RangeValue(1, 'foo')", TypeError)
        self.test_exc("RangeValue('foo', 1)", TypeError)
        self.test_exc("RangeValue((1,'foo'))", TypeError)

        # type mismatches
        self.test_exc("RangeValue(1, 3.0)", TypeError)
        self.test_exc("RangeValue(3L, 5.0)", TypeError)
        self.test_exc("RangeValue(-6.66, 10)", TypeError)
        # range values CANNOT contain PhysicalValues!
        pv1 = PhysicalValue(1.0)
        pv2 = PhysicalValue(2.0)
        self.test_exc("RangeValue(pv1, pv2)", TypeError)
        self.test_exc("RangeValue(1, 0)", ValueError)
        self.test_exc("RangeValue(1.5, -5.0)", ValueError)

    def check_format(self):
        r1 = RangeValue(1, 3)
        r2 = RangeValue(2.0, 5.6)
        r3 = RangeValue(0, 0)

        self.test_val("str(r1)", "1 .. 3")
        self.test_val("r1.format()", "1 .. 3")
        self.test_val("str(r2)", "2.0 .. 5.6")
        self.test_val("r2.format()", "2 .. 5.6")
        self.test_val("r3.format()", "0")


    def check_convert(self):
        self.test_stmt("r1 = RangeValue(1, 10)")
        self.test_stmt("r2 = RangeValue(1, 10)")
        self.test_true("r1 == r2")
        self.test_val("r1.get_type()", int)
        self.test_val("r2.get_type()", int)

        self.test_stmt("r3 = r2.to_float()")
        self.test_val("r2.get_type()", int)
        self.test_val("r3.get_type()", float)

        self.test_true("r2 == r3")
        self.test_false("r2 is r3")


    def check_eq(self):
        irange = RangeValue(1, 4)
        frange = RangeValue(2.5, 3.5)
        self.test_true("irange == irange")
        self.test_true("irange == RangeValue(1, 4)")
        self.test_true("frange == frange")
        self.test_true("frange == RangeValue(2.5, 3.5)")
        self.test_true("irange != frange")
        self.test_true("frange != irange")
        self.test_true("irange != 37")
        self.test_true("irange != 'foo'")
        self.test_true("frange != 37")
        self.test_true("frange != 'foo'")

    def check_addsub(self):
        r1 = RangeValue(1, 4)
        r2 = RangeValue(2, 3)
        self.test_val("(r1 + 2).get_tuple()", (3, 6))
        self.test_val("(2 + r1).get_tuple()", (3, 6))
        self.test_val("(r1 - 2).get_tuple()", (-1, 2))
        self.test_val("(2 - r1).get_tuple()", (-2, 1))
        self.test_val("(r1 + 2.0).get_tuple()", (3, 6))
        self.test_val("(r1 - 2.0).get_tuple()", (-1, 2))
        self.test_exc("r1 + r2", TypeError)
        self.test_exc("r1 - r2", TypeError)

    def check_muldiv(self):
        r1 = RangeValue(1, 4)
        r2 = RangeValue(2, 3)
        # Multiplication and division: range with scalar
        self.test_val("(r1 * 2).get_tuple()", (2, 8))
        self.test_val("(2 * r1).get_tuple()", (2, 8))
        self.test_val("(r1 / 2).get_tuple()", (0, 2))

        self.test_stmt("fr1 = RangeValue(*map(float, r1.get_tuple()))")
        self.test_true("fr1 == r1")
        self.test_val("(fr1 / 2).get_tuple()", (0.5, 2.0))

        # Multiplication and division of ranges
        self.test_exc("r1 * r2", TypeError)
        self.test_exc("r1 / r2", TypeError)

        # Try dividing float range
        r1 = r1.to_float()
        self.test_val("(r1 / 2.0).get_tuple()", (0.50, 2.0))


    def check_compare(self):
        r1 = RangeValue(1, 4)
        r1a = RangeValue(1.0, 4.0)
        r2 = RangeValue(-2.5, 3.25)

        # ranges can only be compared for equality -- relations
        # don't make sense because of Python's weak comparison
        # semantics ;-(
        self.test_true("r1 == RangeValue(1, 4)")
        self.test_true("r1 == r1a")
        self.test_true("r1 != r2")

        # test the 'in_range()' method
        self.test_true("r1.in_range(2)")
        self.test_true("r1.in_range(1)")
        self.test_true("r1.in_range(4)")
        self.test_true("r1.in_range(1.001)")
        self.test_false("r1.in_range(0)")
        self.test_false("r1.in_range(4.1)")

        self.test_true("r2.in_range(-2.5)")
        self.test_true("r2.in_range(3.25)")
        self.test_false("r2.in_range(-2.6)")
        self.test_false("r2.in_range(3.26)")


if __name__ == "__main__":
    (scenarios, options) = parse_args()
    run_scenarios(scenarios, options)
