Exemple #1
0
 def test_namespace_fixup_from_scratch(self):
     '''Basic ns fixup upon mutation'''
     doc = tree.entity()
     elem = doc.xml_element_factory(NS_A, u'top')
     doc.xml_append(elem)
     self.assertEqual(doc.xml_first_child.xml_namespace, NS_A)
     return
Exemple #2
0
 def test_namespace_fixup_from_scratch(self):
     '''Basic ns fixup upon mutation'''
     doc = tree.entity()
     elem = doc.xml_element_factory(NS_A, u'top')
     doc.xml_append(elem)
     self.assertEqual(doc.xml_first_child.xml_namespace, NS_A)
     return
Exemple #3
0
 def test_empty_doc_deep(self):
     """Deep copy of empty entity"""
     doc = tree.entity()
     copied = copy.deepcopy(doc)
     self.assertNotEqual(doc, copied)
     self.assertEqual(copied.xml_type, tree.entity.xml_type)
     self.assertEqual(len(copied.xml_children), 0)
     return
Exemple #4
0
 def test_empty_doc_deep(self):
     '''Deep copy of empty entity'''
     doc = tree.entity()
     copied = copy.deepcopy(doc)
     self.assertNotEqual(doc, copied)
     self.assertEqual(copied.xml_type, tree.entity.xml_type)
     self.assertEqual(len(copied.xml_children), 0)
     return
Exemple #5
0
 def __init__(self, request, **kw):
     FormatterBase.__init__(self, request, **kw)
     self._current_depth = 1
     self._base_depth = 0
     self.in_pre = 0
     self._doc = tree.entity()
     self._curr = self._doc
     #self._writer = structwriter(indent=u"yes", encoding=config.charset)
     return
Exemple #6
0
 def __init__(self, request, **kw):
     FormatterBase.__init__(self, request, **kw)
     self._current_depth = 1
     self._base_depth = 0
     self.in_pre = 0
     self._doc = tree.entity()
     self._curr = self._doc
     # self._writer = structwriter(indent=u"yes", encoding=config.charset)
     return
Exemple #7
0
 def test_create_new_doc_comment(self):
     EXPECTED = '<A a="b">One</A><!--This is easy-->'
     doc = tree.entity()
     A = tree.element(None, u'A')
     A.xml_attributes[u'a'] = u'b'
     A.xml_append(tree.text(u'One'))
     doc.xml_append(A)
     doc.xml_append(tree.comment(u"This is easy"))
     self.compare_output(doc, XMLDECL + EXPECTED)
     return
Exemple #8
0
 def test_create_new_doc_comment(self):
     EXPECTED = '<A a="b">One</A><!--This is easy-->'
     doc = tree.entity()
     A = tree.element(None, u'A')
     A.xml_attributes[u'a'] = u'b'
     A.xml_append(tree.text(u'One'))
     doc.xml_append(A)
     doc.xml_append(tree.comment(u"This is easy"))
     self.compare_output(doc, XMLDECL+EXPECTED)
     return 
Exemple #9
0
 def test_doc1_shallow(self):
     """Shallow copy of entity"""
     doc = tree.entity()
     elem = doc.xml_element_factory(None, u"A")
     doc.xml_append(elem)
     copied = copy.copy(doc)
     self.assertNotEqual(doc, copied)
     self.assertEqual(copied.xml_type, tree.entity.xml_type)
     self.assertEqual(len(copied.xml_children), 0)
     return
Exemple #10
0
 def test_doc1_shallow(self):
     '''Shallow copy of entity'''
     doc = tree.entity()
     elem = doc.xml_element_factory(None, u'A')
     doc.xml_append(elem)
     copied = copy.copy(doc)
     self.assertNotEqual(doc, copied)
     self.assertEqual(copied.xml_type, tree.entity.xml_type)
     self.assertEqual(len(copied.xml_children), 0)
     return
Exemple #11
0
 def test_create_new_doc_pi(self):
     EXPECTED = '<?xml-stylesheet href="classic.xsl" type="text/xml"?><A a="b">One</A>'
     doc = tree.entity()
     doc.xml_append(tree.processing_instruction(u'xml-stylesheet', 
                                                u'href="classic.xsl" type="text/xml"'))
     A = tree.element(None, u'A')
     A.xml_attributes[u'a'] = u'b'
     A.xml_append(tree.text(u'One'))
     doc.xml_append(A)
     self.compare_output(doc, XMLDECL+EXPECTED)
     return 
Exemple #12
0
    def test_create_new_doc_attr_factory(self):
        EXPECTED = '<A a="b">One</A>'
        doc = tree.entity()
        A = tree.element(None, u'A')

        new_attr = A.xml_attribute_factory(None, u'a', u'b')
        A.xml_attributes.setnode(new_attr)
        A.xml_append(tree.text(u'One'))
        doc.xml_append(A)
        self.compare_output(doc, XMLDECL + EXPECTED)
        return
Exemple #13
0
 def test_create_new_doc_attr_factory(self):
     EXPECTED = '<A a="b">One</A>'
     doc = tree.entity()
     A = tree.element(None, u'A')
     
     new_attr = A.xml_attribute_factory(None, u'a', u'b')
     A.xml_attributes.setnode(new_attr)
     A.xml_append(tree.text(u'One'))
     doc.xml_append(A)
     self.compare_output(doc, XMLDECL+EXPECTED)
     return 
Exemple #14
0
 def test_create_new_doc_pi(self):
     EXPECTED = '<?xml-stylesheet href="classic.xsl" type="text/xml"?><A a="b">One</A>'
     doc = tree.entity()
     doc.xml_append(
         tree.processing_instruction(u'xml-stylesheet',
                                     u'href="classic.xsl" type="text/xml"'))
     A = tree.element(None, u'A')
     A.xml_attributes[u'a'] = u'b'
     A.xml_append(tree.text(u'One'))
     doc.xml_append(A)
     self.compare_output(doc, XMLDECL + EXPECTED)
     return
Exemple #15
0
def paramvalue(obj):
    """
    Try to convert a Python object into an XPath data model value

    returns the value if successful, else None
    """
    if isinstance(obj, datatypes.xpathobject):
        return obj
    if isinstance(obj, unicode):
        return datatypes.string(obj)
    elif isinstance(obj, str):
        try:
            obj = obj.decode('utf-8')
        except UnicodeError:
            return None
        else:
            return datatypes.string(obj)
    elif isinstance(obj, bool): # <bool> is subclasses of <int>, test first
        return datatypes.TRUE if obj else datatypes.FALSE
    elif isinstance(obj, (int, long, float)):
        return datatypes.number(obj)
    elif isinstance(obj, tree.node):
        return obj
    # NOTE: At one time (WSGI.xml days) this attemped to be smart and handle
    # all iterables but this would mean blindly dealing with dangerous
    # creatures, such as sockets. So now it's more conservative and sticks to
    # just list & tuple.
    elif isinstance(obj, (list, tuple)):
        # We can only use the list if the items are all nodes or all strings.
        # Strings are converted to a nodeset of text nodes.
        for item in obj:
            if not isinstance(item, (str, unicode)):
                break
        else:
            # We need to use an entity to preserve ordering
            entity = tree.entity()
            for item in obj:
                if isinstance(item, str):
                    try:
                        item = unicode(item, 'utf8')
                    except UnicodeError:
                        return None
                entity.xml_append(tree.text(item))
            return datatypes.nodeset(entity.xml_children)
        # We can only use the list if all the items are nodes.
        for item in obj:
            if not isinstance(item, tree.node):
                return None
        return datatypes.nodeset(obj)
    else:
        return None
Exemple #16
0
def paramvalue(obj):
    """
    Try to convert a Python object into an XPath data model value

    returns the value if successful, else None
    """
    if isinstance(obj, datatypes.xpathobject):
        return obj
    if isinstance(obj, unicode):
        return datatypes.string(obj)
    elif isinstance(obj, str):
        try:
            obj = obj.decode("utf-8")
        except UnicodeError:
            return None
        else:
            return datatypes.string(obj)
    elif isinstance(obj, bool):  # <bool> is subclasses of <int>, test first
        return datatypes.TRUE if obj else datatypes.FALSE
    elif isinstance(obj, (int, long, float)):
        return datatypes.number(obj)
    elif isinstance(obj, tree.node):
        return obj
    # NOTE: At one time (WSGI.xml days) this attemped to be smart and handle
    # all iterables but this would mean blindly dealing with dangerous
    # creatures, such as sockets. So now it's more conservative and sticks to
    # just list & tuple.
    elif isinstance(obj, (list, tuple)):
        # We can only use the list if the items are all nodes or all strings.
        # Strings are converted to a nodeset of text nodes.
        for item in obj:
            if not isinstance(item, (str, unicode)):
                break
        else:
            # We need to use an entity to preserve ordering
            entity = tree.entity()
            for item in obj:
                if isinstance(item, str):
                    try:
                        item = unicode(item, "utf8")
                    except UnicodeError:
                        return None
                entity.xml_append(tree.text(item))
            return datatypes.nodeset(entity.xml_children)
        # We can only use the list if all the items are nodes.
        for item in obj:
            if not isinstance(item, tree.node):
                return None
        return datatypes.nodeset(obj)
    else:
        return None
Exemple #17
0
 def test_reading_building(self):
     doc = tree.entity()
     doc.xml_append(tree.processing_instruction(u'xml-stylesheet', 
                                                u'href="classic.xsl" type="text/xml"'))
     A = tree.element(None, u'A')
     A.xml_attributes[u'a'] = u'b'
     A.xml_append(tree.text(u'One'))
     doc.xml_append(A)
     doc.xml_append(tree.comment(u"This is easy"))
     doc2 = amara.parse('docs/whatsnew_doc1.xml')
     output1 = cStringIO.StringIO()        
     output2 = cStringIO.StringIO()        
     xml_print(doc, stream=output1)
     xml_print(doc2, stream=output2)
     self.assertEqual(output1.getvalue(), output2.getvalue())
     return
Exemple #18
0
 def list_services(self, ident=None):
     document = tree.entity()
     services = document.xml_append(tree.element(None, 'services'))
     for path, service in sorted(self._registered_services.iteritems()):
         if ident is not None and service.ident != ident:
             continue
         service_node = services.xml_append(tree.element(None, 'service'))
         service_node.xml_attributes['ident'] = service.ident
         E = service_node.xml_append(tree.element(None, 'path'))
         template = service.template
         if template is not None:
             E.xml_attributes["template"] = service.template.template
         E.xml_append(tree.text(path))
         E = service_node.xml_append(tree.element(None, 'description'))
         E.xml_append(tree.text(service.doc))
     return document
Exemple #19
0
 def list_services(self, ident=None):
     document = tree.entity()
     services = document.xml_append(tree.element(None, 'services'))
     for path, service in sorted(self._registered_services.iteritems()):
         if ident is not None and service.ident != ident:
             continue
         service_node = services.xml_append(tree.element(None, 'service'))
         service_node.xml_attributes['ident'] = service.ident
         E = service_node.xml_append(tree.element(None, 'path'))
         template = service.template
         if template is not None:
             E.xml_attributes["template"] = service.template.template
         E.xml_append(tree.text(path))
         E = service_node.xml_append(tree.element(None, 'description'))
         E.xml_append(tree.text(service.doc))
     return document
Exemple #20
0
 def test_reading_building(self):
     doc = tree.entity()
     doc.xml_append(
         tree.processing_instruction(u'xml-stylesheet',
                                     u'href="classic.xsl" type="text/xml"'))
     A = tree.element(None, u'A')
     A.xml_attributes[u'a'] = u'b'
     A.xml_append(tree.text(u'One'))
     doc.xml_append(A)
     doc.xml_append(tree.comment(u"This is easy"))
     doc2 = amara.parse('docs/whatsnew_doc1.xml')
     output1 = cStringIO.StringIO()
     output2 = cStringIO.StringIO()
     xml_print(doc, stream=output1)
     xml_print(doc2, stream=output2)
     self.assertEqual(output1.getvalue(), output2.getvalue())
     return
Exemple #21
0
    def startDocument(self, pagename):
        self.doc = tree.entity()
        self.doc.xml_public_id = "-//OASIS//DTD DocBook XML V4.4//EN"
        self.doc.xml_system_id = "http://www.docbook.org/xml/4.4/docbookx.dtd"
        self.root = tree.element(None, unicode(self.doctype))
        self.doc.xml_append(self.root)
        self.title = pagename
        if not self.include_kludge and self.doctype == u"article":
            info = tree.element(None, u"articleinfo")
            self.root.xml_append(info)
            self._addTitleElement(self.title, targetNode=info)
            self._addRevisionHistory(targetNode=info)
        else:
            self._addTitleElement(self.title, targetNode=self.root)

        self.cur = self.root
        return ""
Exemple #22
0
    def startDocument(self, pagename):
        self.doc = tree.entity()
        self.doc.xml_public_id = "-//OASIS//DTD DocBook XML V4.4//EN"
        self.doc.xml_system_id = "http://www.docbook.org/xml/4.4/docbookx.dtd"
        self.root = tree.element(None, unicode(self.doctype))
        self.doc.xml_append(self.root)
        self.title = pagename
        if not self.include_kludge and self.doctype == u"article":
            info = tree.element(None, u"articleinfo")
            self.root.xml_append(info)
            self._addTitleElement(self.title, targetNode=info)
            self._addRevisionHistory(targetNode=info)
        else:
            self._addTitleElement(self.title, targetNode=self.root)

        self.cur = self.root
        return ""
Exemple #23
0
# Test internal Akara code

from akara.services import convert_body
from amara import tree

# Found a problem in the convert_body code. Returned the XML as a
# string instead of a list containing a single string. Ruined the
# throughput as WSGI processed the result character-by-character.

test_tree = tree.entity()
test_tree.xml_append(tree.element(None, 'spam'))


def test_convert_body_string():
    result = convert_body("Hello", None, None, None)
    assert result == (["Hello"], "text/plain", 5), result

    result = convert_body("Hello", "text/not-plain", None, None)
    assert result == (["Hello"], "text/not-plain", 5), result


def test_convert_body_unicode():
    result = convert_body(u"G\u00f6teborg", None, "utf8", None)
    assert result == (["G\xc3\xb6teborg"], "text/plain; charset=utf8",
                      9), result

    result = convert_body(u"G\u00f6teborg", "text/not-plain", "utf16", None)
    assert result == (["\xff\xfeG\x00\xf6\x00t\x00e\x00b\x00o\x00r\x00g\x00"],
                      "text/not-plain", 18), result

Exemple #24
0
    def runNode(self,
                node,
                sourceUri=None,
                parameters=None,
                result=None,
                preserveSrc=0,
                docInputSource=None):
        """
        Transform a source document as given via a Domlette document
        node.

        Use Ft.Xml.Domlette.ConvertDocument() to create a Domlette
        from some other type of DOM.

        Assumes that either the Processor instance has already had
        stylesheets appended (via appendStylesheet(), for example), or
        the source document contains xml-stylesheet processing
        instructions that are not being ignored.

        sourceUri - The absolute URI of the document
        entity that the node represents, and should be explicitly
        provided, even if it is available from the node itself.

        `parameters` - optional dictionary of
        stylesheet parameters, the keys of which may be given as
        strings if they have no namespace, or as (uri, localname)
        tuples otherwise.

        writer - optional SAX-like event handler that
        is an Ft.Xml.Xslt.NullWriter subclass. The default writer is
        either an Ft.Xml.Xslt.XmlWriter, HtmlWriter or PlainTextWriter,
        depending on the stylesheet(s).

        output - optional Python file-like object
        to be used as the destination for the writer's output.

        preserveSrc - (flag) If set signals that the source DOM should not be
        mutated, as would normally happen when honoring XSLT whitespace
        stripping requirements. Setting preserveSrc results in the
        creation of a copy of the source DOM.

        isrc - optional input source used strictly for further resolution
        relative the given DOM
        """
        if not isinstance(node, tree.entity):
            raise ValueError(MessageSource.g_errorMessages[
                XsltError.CANNOT_TRANSFORM_FRAGMENT])

        # A base URI must be absolute, but DOM L3 Load & Save allows
        # implementation-dependent behavior if the URI is actually
        # relative, empty or missing. We'll generate a URN for the
        # InputSource's benefit if the base URI is empty/missing.
        # Relative URIs can pass through; the resolvers will handle
        # them appropriately (we hope).
        if not sourceUri:
            sourceUri = node.xml_base or Uri.BASIC_RESOLVER.generate()

        if preserveSrc:
            # preserve the node's baseURI so our DOM is a true copy
            entity = tree.entity(node.xml_base)
            for child in node:
                entity.xml_append(entity.importNode(child, 1))
            node = entity

        self._stripElements(node)

        if not docInputSource:
            #Create a dummy iSrc
            docInputSource = inputsource.input_source(
                None,
                sourceUri,
                processIncludes=1,
                stripElements=self.getStripElements(),
                factory=self.inputSourceFactory)

        if self.__checkStylesheetPis(node, docInputSource):
            #Do it again with updated WS strip lists

            #NOTE:  There is a case where this will produce the wrong results.  If, there were
            #previous stylesheets that defined removing white space, then the
            #processing instruction referenced a stylesheet that overrode some of these
            #whitespace processing rules, the original trimmed space will be lost

            #Regardless, we need to remove any new whitespace defined in the PI
            self._stripElements(node)

        return self._run(node, parameters, result)
Exemple #25
0
    nodeset_literal,
    ROOT,
    CHILD1,
    CHILD2,
    CHILD3,
    LCHILD1,
    LCHILD2)

# contexts for nodeset {CHILD1, CHILD2, CHILD3}
CONTEXT1 = context(CHILD1, 1, 3)
CONTEXT2 = context(CHILD2, 2, 3)
# contexts for nodeset {LCHILD1, LCHILD2, NONASCIIQNAME}
CONTEXTLANG1 = context(LCHILD1, 1, 3)
CONTEXTLANG2 = context(LCHILD2, 2, 3)

DOC = tree.entity()
EGG1 = DOC.xml_append(tree.element(None, 'egg0'))
EGG1.xml_append(tree.text('0'))
EGG2 = DOC.xml_append(tree.element(None, 'egg1'))
EGG2.xml_append(tree.text('1'))
EGG3 = DOC.xml_append(tree.element(None, 'egg0'))
EGG3.xml_append(tree.text('0'))
EGG4 = DOC.xml_append(tree.element(None, 'egg1'))
EGG4.xml_append(tree.text('1'))
EGG5 = DOC.xml_append(tree.element(None, 'egg0'))
EGG5.xml_append(tree.text('0'))

from amara.xpath.expressions.functioncalls import function_call


def test_last_function():
Exemple #26
0
 def test_create_new_doc(self):
     EXPECTED = "<spam/>"
     doc = tree.entity()
     doc.xml_append(tree.element(None, u'spam'))
     self.compare_output(doc, XMLDECL + EXPECTED)
     return
Exemple #27
0
# the simple_service parameter overrides the default, which is based
# on the return being a Unicode string.
@simple_service("GET", "http://example.com/test", "test_unicode_latin1", "text/plain", "latin1")
def test_unicode_latin1():
    return u"\xc5sa bor i G\xf6teborg"


# Check that I can override the default content-type specification
@simple_service("GET", "http://example.com/test", None, "text/plain", encoding="utf16")
def test_unicode_utf16():
    response.add_header("Content-Type", "something/strange")
    return u"\xc5sa bor i G\xf6teborg"


# Amara strings
test_document = tree.entity()
node = test_document.xml_append(tree.element(None, "nothing"))
node.xml_attributes["name"] = u"\xc5sa"
node.xml_attributes["city"] = u"G\xf6teborg"
node.xml_append(tree.element(None, "something"))
del node


@simple_service("GET", "http://example.com/test")
def test_xml_utf8():
    return test_document


@simple_service("GET", "http://example.com/test", encoding="latin1")
def test_xml_latin1():
    return test_document
Exemple #28
0
 def test_create_new_doc(self):
     EXPECTED = "<spam/>"
     doc = tree.entity()
     doc.xml_append(tree.element(None, u'spam'))
     self.compare_output(doc, XMLDECL+EXPECTED)
     return
Exemple #29
0
# Test internal Akara code

from akara.services import convert_body
from amara import tree

# Found a problem in the convert_body code. Returned the XML as a
# string instead of a list containing a single string. Ruined the
# throughput as WSGI processed the result character-by-character.


test_tree = tree.entity()
test_tree.xml_append(tree.element(None, 'spam'))

def test_convert_body_string():
    result = convert_body("Hello", None, None, None)
    assert result == (["Hello"], "text/plain", 5), result

    result = convert_body("Hello", "text/not-plain", None, None)
    assert result == (["Hello"], "text/not-plain", 5), result

def test_convert_body_unicode():
    result = convert_body(u"G\u00f6teborg", None, "utf8", None)
    assert result == (["G\xc3\xb6teborg"], "text/plain; charset=utf8", 9), result

    result = convert_body(u"G\u00f6teborg", "text/not-plain", "utf16", None)
    assert result == (["\xff\xfeG\x00\xf6\x00t\x00e\x00b\x00o\x00r\x00g\x00"], "text/not-plain", 18), result


def test_convert_body_xml():
    result = convert_body(test_tree, None, "utf8", "xml")
    assert result == (['<?xml version="1.0" encoding="utf8"?>\n<spam/>'], "application/xml", 45), result
Exemple #30
0
CONTEXT_GCHILD11 = context(GCHILD11, 1, 2)
CONTEXT_LANG = context(LANG, 1, 1)

# <elements>
#   <element>
#     <x>
#       <y>a</y>
#     </x>
#   </element>
#   <element>
#     <x>
#       <y>z</y>
#     </x>
#   </element>
# </elements>
ELEMENTS = tree.entity().xml_append(tree.element(None, 'elements'))
for cdata in ('a', 'z'):
    node = ELEMENTS.xml_append(tree.element(None, 'element'))
    node = node.xml_append(tree.element(None, 'x'))
    node = node.xml_append(tree.element(None, 'y'))
    node.xml_append(tree.text(cdata))
del node, cdata
CONTEXT_ELEMENT = context(ELEMENTS, 1, 1)
ELEMENT1, ELEMENT2 = ELEMENTS

from amara.xpath.parser import parse


def _run_parser_pass(test_cases):
    for args, expected, ctx in test_cases:
        result = parse(*args).evaluate(ctx)
Exemple #31
0
    def runNode(self, node, sourceUri=None, parameters=None, result=None,
                preserveSrc=0, docInputSource=None):
        """
        Transform a source document as given via a Domlette document
        node.

        Use Ft.Xml.Domlette.ConvertDocument() to create a Domlette
        from some other type of DOM.

        Assumes that either the Processor instance has already had
        stylesheets appended (via appendStylesheet(), for example), or
        the source document contains xml-stylesheet processing
        instructions that are not being ignored.

        sourceUri - The absolute URI of the document
        entity that the node represents, and should be explicitly
        provided, even if it is available from the node itself.

        `parameters` - optional dictionary of
        stylesheet parameters, the keys of which may be given as
        strings if they have no namespace, or as (uri, localname)
        tuples otherwise.

        writer - optional SAX-like event handler that
        is an Ft.Xml.Xslt.NullWriter subclass. The default writer is
        either an Ft.Xml.Xslt.XmlWriter, HtmlWriter or PlainTextWriter,
        depending on the stylesheet(s).

        output - optional Python file-like object
        to be used as the destination for the writer's output.

        preserveSrc - (flag) If set signals that the source DOM should not be
        mutated, as would normally happen when honoring XSLT whitespace
        stripping requirements. Setting preserveSrc results in the
        creation of a copy of the source DOM.

        isrc - optional input source used strictly for further resolution
        relative the given DOM
        """
        if not isinstance(node, tree.entity):
            raise ValueError(MessageSource.g_errorMessages[
                             XsltError.CANNOT_TRANSFORM_FRAGMENT])

        # A base URI must be absolute, but DOM L3 Load & Save allows
        # implementation-dependent behavior if the URI is actually
        # relative, empty or missing. We'll generate a URN for the
        # InputSource's benefit if the base URI is empty/missing.
        # Relative URIs can pass through; the resolvers will handle
        # them appropriately (we hope).
        if not sourceUri:
            sourceUri = node.xml_base or Uri.BASIC_RESOLVER.generate()

        if preserveSrc:
            # preserve the node's baseURI so our DOM is a true copy
            entity = tree.entity(node.xml_base)
            for child in node:
                entity.xml_append(entity.importNode(child, 1))
            node = entity

        self._stripElements(node)

        if not docInputSource:
            #Create a dummy iSrc
            docInputSource = inputsource.input_source(
                None, sourceUri, processIncludes=1,
                stripElements=self.getStripElements(),
                factory=self.inputSourceFactory)

        if self.__checkStylesheetPis(node, docInputSource):
            #Do it again with updated WS strip lists

            #NOTE:  There is a case where this will produce the wrong results.  If, there were
            #previous stylesheets that defined removing white space, then the
            #processing instruction referenced a stylesheet that overrode some of these
            #whitespace processing rules, the original trimmed space will be lost

            #Regardless, we need to remove any new whitespace defined in the PI
            self._stripElements(node)


        return self._run(node, parameters, result)
    # boolean literals
    TRUE, FALSE,
    # number literals (for special values)
    NOT_A_NUMBER, POSITIVE_INFINITY, NEGATIVE_INFINITY,
    # nodeset literals
    nodeset_literal, ROOT, CHILD1, CHILD2, CHILD3, LCHILD1, LCHILD2
    )

# contexts for nodeset {CHILD1, CHILD2, CHILD3}
CONTEXT1 = context(CHILD1, 1, 3)
CONTEXT2 = context(CHILD2, 2, 3)
# contexts for nodeset {LCHILD1, LCHILD2, NONASCIIQNAME}
CONTEXTLANG1 = context(LCHILD1, 1, 3)
CONTEXTLANG2 = context(LCHILD2, 2, 3)

DOC = tree.entity()
EGG1 = DOC.xml_append(tree.element(None, 'egg0'))
EGG1.xml_append(tree.text('0'))
EGG2 = DOC.xml_append(tree.element(None, 'egg1'))
EGG2.xml_append(tree.text('1'))
EGG3 = DOC.xml_append(tree.element(None, 'egg0'))
EGG3.xml_append(tree.text('0'))
EGG4 = DOC.xml_append(tree.element(None, 'egg1'))
EGG4.xml_append(tree.text('1'))
EGG5 = DOC.xml_append(tree.element(None, 'egg0'))
EGG5.xml_append(tree.text('0'))


from amara.xpath.expressions.functioncalls import function_call

def test_last_function():