from xml.xpath import parser
_parsers = [parser]
try:
    from xml.xpath import XPathParser
    _parsers.append(XPathParser)
except:
    pass
try:
    from xml.xpath import XPathParserc
    _parsers.append(XPathParserc)
except:
    pass

def equal(expected, actual):
    results = map(lambda a,b: a == b, node_set, expected)
    return reduce(lambda a,b: a and b, results, 1)

def Test(tester):

    tester.startGroup('Expression Parser')
    
    tester.startTest('Creating test environment')
    from xml.xpath import Context
    DomTree = tester.test_data['tree']

    root = Context.Context(DomTree.ROOT,1,1)
    child1 = Context.Context(DomTree.CHILD1,1,2,processorNss={'x':'http://spam.com'})
    child2 = Context.Context(DomTree.CHILD2,2,2)
    child3 = Context.Context(DomTree.CHILD3,1,1)
    text = Context.Context(DomTree.TEXT1,3,3)
    gchild11 = Context.Context(DomTree.GCHILD11,1,2)
    
    tests = [('child::*', root, DomTree.CHILDREN),
             ('/child::*', child1, [DomTree.ROOT]),
             ('/*/*', child1, DomTree.CHILDREN),
             ('/child::*/*/child::GCHILD', child1, DomTree.GCHILDREN1 + DomTree.GCHILDREN2),
             ('//*', child1, ([DomTree.ROOT, DomTree.CHILD1] + DomTree.GCHILDREN1 +
                              [DomTree.CHILD2] + DomTree.GCHILDREN2 +
                              [DomTree.CHILD3])),
             ('//GCHILD', child1, DomTree.GCHILDREN1 + DomTree.GCHILDREN2),
             ('//@attr1', child1, [DomTree.ATTR1, DomTree.ATTR2]),
             ('x:GCHILD', child1, []),
             ('.//GCHILD', child2, DomTree.GCHILDREN2),
             ('.//GCHILD', root, DomTree.GCHILDREN1 + DomTree.GCHILDREN2),
             ('/', text, [DomTree.DOM]),
             ('//CHILD1/..', child1, [DomTree.ROOT]),
             ('.//foo:*', child3, []),
             ('CHILD1 | CHILD2', root, [DomTree.CHILD1, DomTree.CHILD2]),
             ('descendant::GCHILD[3]', root, [DomTree.GCHILD21]),
             ('descendant::GCHILD[parent::CHILD1]', root, DomTree.GCHILDREN1),
             ('descendant::GCHILD[position() > 1]', root, [DomTree.GCHILD12] + DomTree.GCHILDREN2),
             ]
    tester.testDone()

    for (expr_str, context, expected) in tests:
        fromHere = context.node.nodeName
        tester.startTest('Evaluating %s' % expr_str)
        message = 'From <%s>' % fromHere
        for factory in _parsers:
            parser = factory.new()
            try:
                parsed_expr = parser.parse(expr_str)
            except:
                tester.error('Error while parsing "%s"' % expr_str, saveTrace=1)
        node_set = parsed_expr.evaluate(context)
        tester.compare(expected, node_set, message)
        tester.testDone()
        
    return tester.groupDone()
