# Copyright (c) 2004 DoCoMo Euro-Labs GmbH (Munich, Germany).
# Copyright (c) 2001-2004 LOGILAB S.A. (Paris, FRANCE).
#
# http://www.docomolab-euro.com/ -- mailto:tarlano@docomolab-euro.com
# http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# 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
"""Basic elements and utility functions for acceptance tests :

- test-description, describing an acceptance test


:version: $Revision:$  
:author: Logilab

:copyright:
  2001-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: lib.py,v 1.78 2002/10/14 14:24:11 syt Exp $"
__docformat__ = "restructuredtext en"

from narval.public import AL_NS, NO_NS
from narval.element import DescriptionableMixin, ALElement, NSAttribute
from narval.xml_handlers import BaseXMLHandler, DescriptionHandler
from narval.interfaces.core import IStartPlan
from narval.elements.core import StartPlanElement, ErrorElement

class TestDescriptionXMLHandler(BaseXMLHandler):
    """XML handler for test description elements"""
    
    def __init__(self, elmt, ns_context, locator):
        super(TestDescriptionXMLHandler, self).__init__(elmt, ns_context, locator)
        self.sub_h = None
        
    def start_element(self, name, attrs):
        """SAX callback: start a new xml node

        :type name: tuple
        :param name: the tag name as a tuple (uri, name)
        
        :type attrs: dict
        :param attrs:
          the node's attribute values, indexed by attribute's name as a tuple
          (uri, name)
        """
        if name == (AL_NS, 'description'):
            self.sub_h = DescriptionHandler(self.elmt, attrs[(NO_NS, 'lang')])
    
    def end_element(self, name):
        """SAX callback: close a xml node

        :type name: tuple
        :param name: the tag name as a tuple (uri, name)
        """
        self.sub_h = None

    def characters(self, string):
        """SAX callback: get some (non empty) string

        :type content: unicode
        :param content: the non empty string to hold
        """
        if self.sub_h is not None:
            self.sub_h.characters(string)


class TestDescriptionElement(StartPlanElement, DescriptionableMixin):
    """element representing a test case description"""
    __implements__ = (IStartPlan,)
    __xml_element__ = (AL_NS, 'test')
    __child_handler__ = TestDescriptionXMLHandler
    
    category = NSAttribute(NO_NS, None, str, str)

    
    def __init__(self):
        super(TestDescriptionElement, self).__init__()
        self.category = None
        
    def children_as_xml(self, encoding='UTF-8'):
        """return the XML representation of the children of this element

        :type encoding: str
        :param encoding: the encoding to use in the returned string

        :rtype: str
        :return: XML string representing the element
        """
        return self.description_as_xml(encoding)


class ElementXMLHandler(BaseXMLHandler):
    """XML handler for test description elements"""
    
    def start(self, attrs):
        """SAX callback: start a new xml node

        :type name: tuple
        :param name: the tag name as a tuple (uri, name)
        
        :type attrs: dict
        :param attrs:
          the node's attribute values, indexed by attribute's name as a tuple
          (uri, name)
        """
        self.elmt = Element()
        for key, val in attrs.items():
            self.elmt.setattr(key, val)
        
class Element(ALElement):
    """dummy element manipulated by test cases"""
    __xml_element__ = (NO_NS, 'element')
    flag = NSAttribute(NO_NS, None, str, str)
    identity = NSAttribute(NO_NS, None, str, str)
    el_id = NSAttribute(NO_NS, None, str, str)
    attribute = NSAttribute(NO_NS, None, str, str)
    
    __child_handler__ = ElementXMLHandler
    
    def as_xml(self, encoding='uft-8'):
        """return the XML representation of the element

        :type encoding: str
        :param encoding: the encoding to use in the returned string

        :rtype: str
        :return: XML string representing the element
        """
        attrs = []
        for descr in self.ns_attributes():
            value = descr.__get__(self, self.__class__)
            if value is None or (
                 descr.namespace == AL_NS and 
                 descr.attrname not in ('timestamp', 'from_plan', 'from_step',
                                        'outdated')):
                continue
            attrs.append(descr.as_xml(value, encoding))
        return '<element %s/>' % ' '.join(attrs)
