#!/www/python/bin/python

"""$URL: svn+ssh://svn/repos/trunk/dulcinea/lib/test/utest_typed_list.py $
$Id: utest_typed_list.py 25054 2004-09-09 18:04:30Z dbinger $

Test for dulcinea.typed_list.
"""

from types import *
from sancho.utest import UTest
from dulcinea.typed_list import TypedList

class Value:

    def __init__ (self, name=None):
        if name is not None:
            self.name = name

    def get_name(self):
        return getattr(self, 'name', 'no')

class OtherValue:

    def __init__ (self, name):
        self.name = name



class TestTypedList (UTest):

    test_cases = [ 'add', 'format', 'getset_list', 'getset_item',
                   'merge', 'find_index' ]

    def check_add(self):
        lst = TypedList() ; lst.required_class = Value
        v1 = Value("n1")
        v2 = Value("n2")
        lst.add(v1)
        lst.add(v2)
        assert lst.find('n1') == v1
        assert lst.find('foo') == None
        assert len(lst) == 2

        # adding something already on the list should raise a ValueError:
        try:
            lst.add(v1)
            assert 0
        except ValueError: pass
        assert lst.get_names() == ["n1", "n2"]

        # turning off type checking, (if you already know the types are ok)
        TypedList(lst.get_list(), check_types=0)

        # check remove method, while we're at it:
        assert lst.remove('n2') == v2
        assert lst.find('n2') == None
        assert lst.remove('foo') == None

        ov1 = OtherValue("n1")
        ov2 = OtherValue("foo")
        try:
            lst.add(ov1)
            assert 0
        except TypeError: pass
        try:
            lst.add(ov2)
            assert 0
        except TypeError: pass


    def check_format(self):
        lst = TypedList()
        assert str(lst) == "no values"
        lst.add(Value("n1"))
        assert str(lst) == "1 value"
        lst.add(Value("n2"))
        assert str(lst) == "2 values"


    def check_getset_list(self):
        lst = TypedList()
        v1 = Value("n1")
        v2 = Value("n2")
        assert lst.get_list() == []
        lst.add(v1)
        lst.add(v2)
        assert lst.get_list() == [v1, v2]
        lst.remove(v1.name)
        assert lst.get_list() == [v2]
        lst.set_list([v1, v2])
        assert lst.find('n2') == v2
        assert lst.get_list() == [v1, v2]
        try:
            lst.set_list([v1, v2, v1])
            assert 0
        except ValueError: pass

    def check_getset_item(self):
        lst = TypedList() ; lst.required_class = Value
        v1 = Value("n1")
        v2 = Value("n2")
        v3 = Value("n3")
        ov1 = OtherValue("n1")

        lst.add(v1) ; lst.add(v2)
        assert len(lst) == 2
        assert lst[0] == v1
        assert lst[1] == v2
        lst[1] = v2
        assert lst[1] == v2
        try:
            lst[1] = v1
            assert 0
        except ValueError: pass

        assert lst.remove('n1') == v1
        assert len(lst) == 1
        lst[0] = v2
        assert lst[0] == v2
        lst[0] = v1
        assert lst[0] == v1
        try:
            lst[1]
            assert 0
        except IndexError: pass

        try:
            lst[0] = ov1
            assert 0
        except TypeError: pass
        assert lst[0] == v1

    def check_merge(self):
        lst = TypedList()
        lst2 = TypedList()

        v1 = Value("n1")
        v2 = Value("n2")
        v3 = Value("n3")
        v4 = Value("n4")

        lst.add(v1)
        lst.add(v2)
        lst2.add(v3)
        lst2.add(v4)

        assert lst.get_names() == ['n1', 'n2']
        # presently, lst and lst2 are mutually exclusive.
        # merge them into lst3
        lst.merge(lst2)
        assert lst.get_names() == ['n1', 'n2', 'n3', 'n4']

        # merging a parameter list with itself --setting various merge flags:
        try:
            lst.merge(lst)
            assert 0
        except ValueError: pass
        # however, setting the merge flag to ignore should leave the original
        # parameter list unchanged:
        lst.merge(lst, 'ignore')
        assert lst.get_names() == ['n1', 'n2', 'n3', 'n4']

        # verify that 'replace' behavior is correct:
        v1 = Value("n1")
        lst3 = TypedList([v1])
        # first, ensure that the original list contains the param by name:
        lst.merge(lst3, 'replace')
        assert lst.get_list() == [v1, v2, v3, v4]
        # next verify that the 'duration' parameter has been replaced:
        assert lst.find('n1') == v1

    def check_find_index(self):
        v1 = Value("n1")
        v2 = Value("n2")
        lst = TypedList([v1, v2])

        assert lst.find_index('n1') == 0
        assert lst.find_index('n2') == 1
        assert lst.find_index('foo') == None


    def check_coverage(self):
        v1 = Value("n1")
        v2 = Value("n2")
        v3 = Value()
        t1 = TypedList([v1])
        t2=t1.copy()
        t2.add(v2)
        assert t1.get_list() == [v1]
        assert len(t2) == 2
        t3 = TypedList([v3])
        assert len(t1 + t3 + [1]) == 3

if __name__ == "__main__":
    TestTypedList()
