# Copyright (c) 2000-2004 LOGILAB S.A. (Paris, FRANCE).
# http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# Copyright (c) 2004 DoCoMo Euro-Labs GmbH (Munich, Germany).
# http://www.docomolab-euro.com/ -- mailto:tarlano@docomolab-euro.com
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
"""unit tests for NSAttributes serialization / access

:version: $Revision:$  
:author: Logilab

:copyright:
  2000-2004 LOGILAB S.A. (Paris, FRANCE)
  
  2004 DoCoMo Euro-Labs GmbH (Munich, Germany)
  
:contact:
  http://www.logilab.fr/ -- mailto:contact@logilab.fr
  
  http://www.docomolab-euro.com/ -- mailto:tarlano@docomolab-euro.com
"""

__revision__  = '$Id$'

import unittest
from sets import Set

from narval import AL_NS, NO_NS, TYPE_NS
from narval.element import ALElement, NSAttribute
from narval.reader import REGISTRY as registry

DUMMY_NS = 'http://dummy.org'
class DummyElement(ALElement):
    """dummy element for tests"""

    __xml_element__ = (NO_NS, 'dum')
    __namespaces__ = {
        DUMMY_NS : "dummy",
        }
    foo = NSAttribute(AL_NS, 'fooval', str, str)
    bar = NSAttribute(DUMMY_NS, 'barval', int, str)

class DummyExtendedElement(DummyElement):
    """extends DummyElement"""
    __xml_element__ = (NO_NS, 'dumext')
    __namespaces__ = {
        DUMMY_NS : "dummyext",
        }
    toh = NSAttribute(DUMMY_NS, 'tohval', str, str)

registry.register_classes(DummyElement, DummyExtendedElement)

class NSAttributeSerializerTC(unittest.TestCase):
    """test case for attribute serialization"""

    def setUp(self):
        self.dummy = DummyElement()
        self.dummy.bar = 12

    def test_namespaces_extended(self):
        """tests __namespaces__ inheritance"""
        self.assertEquals(DummyElement.__namespaces__,
                          {DUMMY_NS : "dummy",
                           AL_NS    : 'al',
                           TYPE_NS  : 'type',})

    def test_nsattributes(self):
        """tests Element.ns_attributes method"""
        expected_attrs = Set( [# ALElement attributes
            'persist', 'outdated', 'eid', 'input_id',
            'output_id', 'from_plan', 'from_step',
            'timestamp', 'name',
            # + DummyElement ones
            'foo', 'bar'])
        dummy_attrnames = Set([descr.attrname for descr in
                               self.dummy.ns_attributes()])
        self.assertEquals(dummy_attrnames, expected_attrs)


    def test_attributes_prefix(self):
        """tests nsattributes prefix"""
        foo_descr = getattr(DummyElement, 'foo')
        bar_descr = getattr(DummyElement, 'bar')
        toh_descr = getattr(DummyExtendedElement, 'toh')
        ns_dict = DummyElement.__namespaces__
        self.assertEquals(foo_descr.prefix, ns_dict[AL_NS])
        self.assertEquals(bar_descr.prefix, ns_dict[DUMMY_NS])
        self.assertEquals(toh_descr.prefix, 'dummyext')


    def test_loader(self):
        """tests attribute deserializer"""
        xmlstr = '<dum xmlns:dummy="%s" dummy:bar="15" />' % DUMMY_NS
        loaded_elements = registry.from_string(xmlstr)
        self.assertEquals(len(loaded_elements), 1)
        dummy_elt = loaded_elements[0]
        self.assertEquals(dummy_elt.__class__, DummyElement)
        self.assertEquals(dummy_elt.foo, 'fooval')
        self.assertEquals(dummy_elt.bar, 15)
        

    def test_attribute_serializer(self):
        """tests default basic attribute serializer"""
        xmlstr = self.dummy.attributes_as_xml()
        expected_blocks = Set(['dummy:bar="12"'])
        self.assertEquals(Set(xmlstr.split()), expected_blocks)
        self.dummy.foo = "foo"
        expected_blocks.add('al:foo="foo"')
        xmlstr = self.dummy.attributes_as_xml()
        self.assertEquals(Set(xmlstr.split()), expected_blocks)


    def test_good_init(self):
        """tests Element's init mechanism"""
        dummy = DummyElement(foo = 'foo')
        self.assertEquals(dummy.foo, 'foo')
        self.assertEquals(dummy.bar, 'barval')
        dummy = DummyElement(foo = 'foo', bar = 'bar')
        self.assertEquals(dummy.foo, 'foo')
        self.assertEquals(dummy.bar, 'bar')
        

    def test_bad_init(self):
        """check that specifying unknown attributes raises a TypeError"""
        self.assertRaises(TypeError, DummyElement, spam = 'spam !')
        self.assertRaises(TypeError, DummyElement, foo = 'foo', spam = 'spam !')


if __name__ == '__main__':
    unittest.main()
