#!/www/python/bin/python

"""$URL: svn+ssh://svn.mems-exchange.org/repos/trunk/dulcinea/lib/test/test_spec.py $
$Id: test_spec.py 23442 2004-02-05 22:32:06Z dbinger $

Test for dulcinea.spec.
"""

from sancho.unittest import TestScenario, parse_args, run_scenarios
from dulcinea.base import DulcineaPersistent
from dulcinea.spec import spec, nspec, any, get_spec_doc, get_specs, \
     get_spec_problems, match, set, require, format_spec, interval, \
     string, sequence, eq, anything, mapping, equal, subclass, instance, \
     all, length, no, boolean, get_spec, get_spec_report

tested_modules = [ "dulcinea.spec" ]

class SpecTest (TestScenario):

    def check_match (self):
        self.test_bool("match(1, int)")
        self.test_bool("not match(2.5, int)")
        self.test_bool("match(2.5, any(int, float))")
        self.test_bool("not match('s', any(int, float))")
        self.test_bool("not match('hello', sequence(int, str))")
        self.test_bool("match('hello', sequence(str, str))")
        self.test_bool("not match('hello', sequence(str, tuple))")
        self.test_bool("match('hello', str)")
        self.test_bool("match('hello', any('yes', 'no', 'hello', int))")
        self.test_bool("match(3, any('yes', 'no', 'hello', int))")
        mydict = {'a': 1, 'b': None}
        self.test_bool("match(mydict, dict)")
        self.test_bool("match(mydict, { str : object })")
        self.test_bool("not match(mydict, { int : object })")
        self.test_bool("match(mydict, { str : object, int : object })")
        self.test_bool("match((2,3), (int, int))")
        self.test_bool("match((1,), tuple)")
        self.test_bool("match((1,), sequence(object, tuple))")
        self.test_bool("match((1,2,3,4), sequence(object, tuple))")
        self.test_bool("match((1,2,3,'ok'), sequence(object, tuple))")
        self.test_bool("not match((1,2,3,'ok'), sequence(int, tuple))")
        self.test_bool("match(mydict, mapping({ any(str, int) : object }))")
        self.test_bool("not match(mydict, mapping({int:object}, dict))")
        self.test_bool("not match(mydict, mapping({str: int}))")
        self.test_bool("match(True, boolean)")
        self.test_bool("not match(3, boolean)")
        self.test_bool("match([3,'ok'], [int, str])")
        self.test_bool("not match([3,'ok', 3], [int, str])")
        self.test_bool("match(3, no(None))")
        self.test_bool("match([3, 4], [all(int, no(None))])")
        self.test_bool("not match(3, any)")
        self.test_bool("match(3, object)")
        a=[2,3]
        b=[2,3]
        self.test_bool("match(a, eq(a))")
        self.test_bool("not match(b, eq(a))")
        self.test_bool("match(a, equal(b))")
        self.test_bool("match('a', string(1))")
        self.test_bool("match('a', length(1))")
        self.test_bool("match('a', interval('a','c'))")
        self.test_bool("not match('b', all(length(1), string(2)))")
        self.test_bool("not match('b', all(length(2)))")
        self.test_bool("match(10, interval(1))")
        self.test_bool("match(1, interval(1))")
        self.test_false("match(0, interval(1))")
        self.test_false("match(0, interval(1,4))")
        self.test_true("match(4, interval(1,4))")
        self.test_false("match(5, interval(1,4))")
        self.test_true("match(0, interval(anything,4))")
        self.test_true("match(0, instance('int'))")
        self.test_false("match(0, no(int))")

        class foo (dict, TestScenario):
            pass
        self.test_false("match(0, subclass(dict))")
        self.test_true("match(foo, subclass(dict))")
        self.test_false("match(0, mapping())")
        self.test_false("match(0, mapping({int:int},foo))")
        self.test_stmt("sequence().get_args()")
        self.test_false("match(0, instance('foo'))")
        for s in ('equal(1)',
                  'eq(1)',
                  'string(4)',
                  'sequence(2, anything)',
                  'interval(2, 4)',
                  'interval(2)',
                  'interval()',
                  'interval(anything, 3)',
                  'None',
                  '(int, str)',
                  '[int]',
                  '{int: str}',
                  "'constant'",
                  ):
            self.test_val("format_spec(%s)" % s, s)
        self.test_exc("require(1, str)", TypeError)
        self.test_exc("require(1, str, 'oops')", TypeError)
        self.test_false("match(1, [1])")
        self.test_false("match([1], [str])")
        self.test_false("match([1, 'hello'], [str, str])")
        self.test_false("match(1, {})")
        class mytest:
            def __call__ (self, value):
                return True
        self.test_true("match(1, mytest())")

    def check_specified (self):
        class A:
            flavor_is = spec(any('sweet', 'sour'), 'the flavor')
            texture_is = spec(int, 'roughness')

        class B(A):
            color_is = spec(str)
            texture_is = nspec(str)

            
        self.a = A()
        self.b = B()
        self.b.color = self.b.texture = 'ok'
        self.test_stmt("set(self.b, flavor='sweet')")
        self.test_bool("get_spec_problems(self.b) == []")
        self.test_stmt("self.b.nonsense = 34")
        self.test_bool("len(get_spec_problems(self.b)) == 1")
        self.test_stmt("del self.b.nonsense")
        self.test_bool("len(get_spec_problems(self.b)) == 0")
        self.test_stmt("self.b.color = 42")
        self.test_bool("len(get_spec_problems(self.b)) == 1")
        self.test_stmt("self.b.color = 'red'")
        self.test_bool("len(get_spec_problems(self.b)) == 0")
        self.test_bool("len(get_specs(B).values()) == 3")
        def is_texture(value):
            return value in (3,4)
        class C(DulcineaPersistent):
            color_is = nspec(str, 'the color')
            texture_is = is_texture
        self.test_bool("get_specs(C)")
        self.test_bool("get_spec_doc(C)")
        self.test_stmt("nspec(None)")
        self.test_stmt("nspec(int)")
        self.test_stmt("nspec(any(int, str))")
        self.test_stmt("get_spec(C, 'texture_is')")
        class D:
            color_is = nspec(str, 'the color')
            texture_is = is_texture
        self.test_stmt("get_spec(D, 'texture_is')")
        self.test_stmt("get_spec_problems(D())")
        class E:
            pass
        self.test_stmt("get_spec_report([D()])")
        self.test_stmt("get_spec_report([E()])")
        self.test_stmt("get_spec_report([])")
        
if __name__ == "__main__":
    (scenarios, options) = parse_args()
    options.show_coverage_lines = options.show_coverage = 1
    run_scenarios (scenarios, options)
