

#Test a domlette interface
from Ft.Lib import pDomlette, cDomlette, ReaderException
from xml.dom import Node

class SKIP:
    pass

def _test_simple_attribute(tester,name,dom,items,attrName = None):
    for tName,get,comp in items:
        tester.startTest("%s %s attribute" % (tName,name))
        if attrName:
            x = getattr(get,attrName)
        else:
            exec "x = " + get
        tester.compare(comp,x)
        tester.testDone()

def _test_simple_method(tester,name,dom,items,methodName = None):
    for tName,get,comp,args in items:
        tester.startTest("%s %s method" % (tName,name))
        if methodName:
            x = apply(getattr(get,methodName),args)
        else:
            exec "x = " + get
        tester.compare(comp,x)
        tester.testDone()


def test_node_access(tester,dom):

    tester.startGroup("Node Access Interfaces")

    _test_simple_attribute(tester,"childNodes",dom,[('Document','len(dom.childNodes)',2),
                                                    ('Element','len(dom.documentElement.childNodes)',7),
                                                    ('Text','len(getFirstText(dom).childNodes)',0),
                                                    ('Comment','len(getComment(dom).childNodes)',0),
                                                    ('PI','len(getPi(dom).childNodes)',0),
                                                    ('Attr','len(getAttr(dom).childNodes)',1),
                                                    ])
    _test_simple_attribute(tester,"nodeName",dom,[('Document',dom,'#document'),
                                                  ('Element',getChild(dom),'child'),
                                                  ('NsElement',getNsChild(dom),'ft:nschild'),
                                                  ('Text',getFirstText(dom),'#text'),
                                                  ('Comment',getComment(dom),'#comment'),
                                                  ('PI',getPi(dom),'xml-stylesheet'),
                                                  ('Attr',getAttr(dom),'foo'),
                                                  ('NsAttr',getNsAttr(dom),'ft:foo'),
                                                  ],attrName='nodeName')
    _test_simple_attribute(tester,"nodeValue",dom,[('Document',dom,None),
                                                   ('Element',getChild(dom),None),
                                                   ('Text',getFirstText(dom),'Some Text'),
                                                   ('Comment',getComment(dom),'A comment'),
                                                   ('PI',getPi(dom),'href="addr_book1.xsl" type="text/xml"'),
                                                   ('Attr',getAttr(dom),'bar'),
                                                   ],attrName='nodeValue')
    
    _test_simple_attribute(tester,"parentNode",dom,[('Document',dom,None),
                                                    ('Element',getChild(dom),dom.documentElement),
                                                    ('Text',getFirstText(dom),getChild(dom)),
                                                    ('Comment',getComment(dom),dom.documentElement),
                                                    ('PI',getPi(dom),dom),
                                                    ('Attr',getAttr(dom),None),
                                                    ],attrName='parentNode')

    _test_simple_attribute(tester,"firstChild",dom,[('Document','dom.firstChild',getPi(dom)),
                                                    ('Element','getChild(dom).firstChild',getFirstText(dom)),
                                                    ('Text','getFirstText(dom).firstChild',None),
                                                    ('Comment','getComment(dom).firstChild',None),
                                                    ('PI','getPi(dom).firstChild',None),
                                                    ('Attr','getAttr(dom).firstChild.data','bar'),
                                                    ])
    
    _test_simple_attribute(tester,"lastChild",dom,[('Document','dom.lastChild',dom.documentElement),
                                                    ('Element','getChild(dom).lastChild',getFirstText(dom)),
                                                    ('Text','getFirstText(dom).lastChild',None),
                                                    ('Comment','getComment(dom).lastChild',None),
                                                    ('PI','getPi(dom).lastChild',None),
                                                    ('Attr','getAttr(dom).lastChild.data','bar'),
                                                    ])



    _test_simple_attribute(tester,"previousSibling",dom,[('Document',dom,None),
                                                         ('Element',getChild(dom),dom.documentElement.childNodes[0]),
                                                         ('Text',getFirstText(dom),None),
                                                         ('Comment',getComment(dom),dom.documentElement.childNodes[2]),
                                                         ('PI',getPi(dom),None),
                                                         ('Attr',getAttr(dom),None),
                                                         ],attrName='previousSibling')

    _test_simple_attribute(tester,"nextSibling",dom,[('Document',dom,None),
                                                     ('Element',getChild(dom),dom.documentElement.childNodes[2]),
                                                     ('Text',getFirstText(dom),None),
                                                     ('Comment',getComment(dom),dom.documentElement.childNodes[4]),
                                                     ('PI',getPi(dom),dom.documentElement),
                                                     ('Attr',getAttr(dom),None),
                                                     ],attrName='nextSibling')

    _test_simple_attribute(tester,"attributes",dom,[('Document','dom.attributes',None),
                                                     ('Element','len(getChild(dom).attributes.keys())',1),
                                                     ('Text','getFirstText(dom).attributes',None),
                                                     ('Comment','getComment(dom).attributes',None),
                                                     ('PI','getPi(dom).attributes',None),
                                                     ('Attr','getAttr(dom).attributes',None),
                                                     ])

    _test_simple_attribute(tester,"ownerDocument",dom,[('Document',dom,None),
                                                       ('Element',getChild(dom),dom),
                                                       ('Text',getFirstText(dom),dom),
                                                       ('Comment',getComment(dom),dom),
                                                       ('PI',getPi(dom),dom),
                                                       ('Attr',getAttr(dom),dom),
                                                       ],attrName='ownerDocument')

    _test_simple_attribute(tester,"namespaceURI",dom,[('Document',dom,None),
                                                      ('Element',getChild(dom),''),
                                                      ('NsElement',getNsChild(dom),'http://fourthought.com'),
                                                      ('Text',getFirstText(dom),None),
                                                      ('Comment',getComment(dom),None),
                                                      ('PI',getPi(dom),None),
                                                      ('Attr',getAttr(dom),''),
                                                      ('NsAttr',getNsAttr(dom),'http://fourthought.com'),
                                                      ],attrName='namespaceURI')

    _test_simple_attribute(tester,"prefix",dom,[('Document',dom,None),
                                                ('Element',getChild(dom),''),
                                                ('NsElement',getNsChild(dom),'ft'),
                                                ('Text',getFirstText(dom),None),
                                                ('Comment',getComment(dom),None),
                                                ('PI',getPi(dom),None),
                                                ('Attr',getAttr(dom),''),
                                                ('NsAttr',getNsAttr(dom),'ft'),
                                                ],attrName='prefix')

    _test_simple_attribute(tester,"localName",dom,[('Document',dom,None),
                                                   ('Element',getChild(dom),'child'),
                                                   ('NsElement',getNsChild(dom),'nschild'),
                                                   ('Text',getFirstText(dom),None),
                                                   ('Comment',getComment(dom),None),
                                                   ('PI',getPi(dom),None),
                                                   ('Attr',getAttr(dom),'foo'),
                                                   ('NsAttr',getNsAttr(dom),'foo'),
                                                   ],attrName='localName')

    _test_simple_attribute(tester,"nodeType",dom,[('Document',dom,Node.DOCUMENT_NODE),
                                                  ('Element',getChild(dom),Node.ELEMENT_NODE),
                                                  ('Text',getFirstText(dom),Node.TEXT_NODE),
                                                  ('Comment',getComment(dom),Node.COMMENT_NODE),
                                                  ('PI',getPi(dom),Node.PROCESSING_INSTRUCTION_NODE),
                                                  ('Attr',getAttr(dom),Node.ATTRIBUTE_NODE),
                                                  ],attrName='nodeType')
    _test_simple_method(tester,"hasChildNodes",dom,[('Document',dom,1,()),
                                                    ('Element',getChild(dom),1,()),
                                                    ('Text',getFirstText(dom),0,()),
                                                    ('Comment',getComment(dom),0,()),
                                                    ('PI',getPi(dom),0,()),
                                                    ('Attr',getAttr(dom),1,()),
                                                    ],methodName='hasChildNodes')
    _test_simple_method(tester,"isSameNode",dom,[('Document',dom,1,(dom,)),
                                                 ('Document',dom,0,(dom.documentElement,)),
                                                 ('Element',getChild(dom),1,(getChild(dom),)),
                                                 ('Element',getChild(dom),0,(dom.documentElement,)),
                                                 ('Text',getFirstText(dom),1,(getFirstText(dom),)),
                                                 ('Text',getFirstText(dom),0,(dom.documentElement,)),
                                                 ('Comment',getComment(dom),1,(getComment(dom),)),
                                                 ('Comment',getComment(dom),0,(dom.documentElement,)),
                                                 ('PI',getPi(dom),1,(getPi(dom),)),
                                                 ('PI',getPi(dom),0,(dom.documentElement,)),
                                                 ('Attr',getAttr(dom),1,(getAttr(dom),)),
                                                 ('Attr',getAttr(dom),0,(dom.documentElement,)),
                                                 ],methodName='isSameNode')


    tester.groupDone()


def test_document_access(tester,dom):

    tester.startGroup("Document Access Interfaces")

    tester.startTest("DocType")
    tester.compare(None,dom.doctype)
    tester.testDone()

    tester.startTest("documentElement")
    tester.compare(dom.childNodes[1],dom.documentElement)
    tester.testDone()

    tester.startTest("implementation")
    tester.compare(1,hasattr(dom.implementation,'hasFeature'))
    tester.testDone()

    tester.startTest("getElementsByTagNameNS")
    tester.warning("Not Tested")
    tester.testDone()


    tester.groupDone()

def test_element_access(tester,dom):

    tester.startGroup("Element Access Interfaces")

    tester.startTest("attributes")
    tester.compare(1,len(getChild(dom).attributes.keys()))
    tester.testDone()

    tester.startTest("tagname")
    tester.compare('child',getChild(dom).tagName)
    tester.compare('ft:nschild',getNsChild(dom).tagName)
    tester.testDone()

    tester.startTest("getAttributeNodeNS")
    tester.compare(getAttr(dom),getChild(dom).getAttributeNodeNS('','foo'))
    tester.compare(None,getChild(dom).getAttributeNodeNS('','foo2'))
    tester.compare(getNsAttr(dom),getNsChild(dom).getAttributeNodeNS('http://fourthought.com','foo'))
    tester.compare(None,getNsChild(dom).getAttributeNodeNS('http://fourthought.com','foo2'))
    tester.testDone()

    tester.startTest("getAttributeNode")
    tester.compare(None,getChild(dom).getAttributeNode('foo'))
    tester.compare(None,getNsChild(dom).getAttributeNode('foo'))
    tester.testDone()


    tester.startTest("getAttributeNS")
    tester.compare('bar',getChild(dom).getAttributeNS('','foo'))
    tester.compare('',getChild(dom).getAttributeNS('','foo2'))
    tester.compare('nsbar',getNsChild(dom).getAttributeNS('http://fourthought.com','foo'))
    tester.compare('',getNsChild(dom).getAttributeNS('http://fourthought.com','foo2'))
    tester.testDone()

    tester.startTest("getAttribute")
    tester.compare('',getChild(dom).getAttribute('foo'))
    tester.compare('',getNsChild(dom).getAttribute('foo'))
    tester.testDone()


    tester.startTest("hasAttributeNS")
    tester.compare(1,getChild(dom).hasAttributeNS('','foo'))
    tester.compare(0,getChild(dom).hasAttributeNS('','foo2'))
    tester.compare(1,getNsChild(dom).hasAttributeNS('http://fourthought.com','foo'))
    tester.compare(0,getNsChild(dom).hasAttributeNS('http://fourthought.com','foo2'))
    tester.testDone()

    tester.startTest("hasAttribute")
    tester.compare(0,getChild(dom).hasAttribute('foo'))
    tester.compare(0,getNsChild(dom).hasAttribute('foo'))
    tester.testDone()


    tester.startTest("getElementsByTagNameNS")
    tester.warning("Not Tested")
    tester.testDone()


    tester.groupDone()


def test_attr_access(tester,dom):

    tester.startGroup("Attribute Access Interfaces")


    tester.startTest("name attribute")
    tester.compare('foo',getAttr(dom).name)
    tester.compare('ft:foo',getNsAttr(dom).name)
    tester.testDone()

    tester.startTest("value attribute")
    tester.compare('bar',getAttr(dom).value)
    tester.compare('nsbar',getNsAttr(dom).value)
    tester.testDone()

    tester.startTest("specified attribute")
    tester.compare(0,getAttr(dom).specified)
    tester.testDone()

    tester.startTest("ownerElement attribute")
    tester.compare(getChild(dom),getAttr(dom).ownerElement)
    tester.compare(getNsChild(dom),getNsAttr(dom).ownerElement)
    tester.testDone()

    tester.groupDone()

def test_text_access(tester,dom):

    tester.startGroup("Text Access Interfaces")


    tester.startTest("data attribute")
    tester.compare('Some Text',getFirstText(dom).data)
    tester.testDone()

    tester.startTest("substringData method")
    tester.compare('Some',getFirstText(dom).substringData(0,4))
    tester.testDone()


    tester.groupDone()

def test_pi_access(tester,dom):

    tester.startGroup("Processing Instruction Access Interfaces")


    tester.startTest("target attribute")
    tester.compare('xml-stylesheet',getPi(dom).target)
    tester.testDone()

    tester.startTest("data attribute")
    tester.compare('href="addr_book1.xsl" type="text/xml"',getPi(dom).data)
    tester.testDone()

    tester.groupDone()

def test_comment_access(tester,dom):

    tester.startGroup("Comment Access Interfaces")

    tester.startTest("data attribute")
    tester.compare('A comment',getComment(dom).data)
    tester.testDone()

    tester.groupDone()


def test_access(tester,reader):

    tester.startGroup("Access Interfaces")
    dom = reader.fromString(DOC)
    test_node_access(tester,dom)
    test_document_access(tester,dom)
    test_element_access(tester,dom)
    test_attr_access(tester,dom)
    test_text_access(tester,dom)
    test_pi_access(tester,dom)
    test_comment_access(tester,dom)
    reader.releaseNode(dom)
    tester.groupDone()

def test_read_exceptions(tester,reader):
    tester.startGroup("Reader exceptions")

    tester.startTest("Basic Parse Exception")
    tester.testException(reader.fromString,
                         (DOC2,),
                         ReaderException,
                         {'errorCode': ReaderException.XML_PARSE_ERROR}
                         )
    tester.testDone()

    tester.groupDone()

def test_mutate(tester,reader):
    tester.startGroup("Mutate Interfaces")
    dom = reader.fromString(DOC)



    reader.releaseNode(dom)
    tester.groupDone()



def Test(tester,cDomletteOnly=0):


    if not cDomletteOnly:
        reader = pDomlette.PyExpatReader()
        tester.startGroup("pDomlette")
        test_access(tester,reader)
        test_mutate(tester,reader)
        test_read_exceptions(tester,reader)
        tester.groupDone()
    
    reader = cDomlette.RawExpatReader()
    tester.startGroup("cDomlette")
    test_access(tester,reader)
    test_read_exceptions(tester,reader)
    #test_mutate(reader)
    tester.groupDone()
    

#into the docs children
def getPi(dom):
    return dom.childNodes[0]

def getChild(dom):
    return dom.documentElement.childNodes[1]

def getNsChild(dom):
    return dom.documentElement.childNodes[5]

def getFirstText(dom):
    return getChild(dom).childNodes[0]

def getComment(dom):
    return dom.documentElement.childNodes[3]

def getAttr(dom):
    child = getChild(dom)
    return child.attributes[child.attributes.keys()[0]]

def getNsAttr(dom):
    child = getNsChild(dom)
    return child.attributes[child.attributes.keys()[0]]




    

CHILD_INDEX = 1
COMMENT_INDEX = 3
NSCHILD_INDEX = 5

DOC = """<?xml version = "1.0"?>
<?xml-stylesheet href="addr_book1.xsl" type="text/xml"?>
<docelem xmlns:ft='http://fourthought.com'>
  <child foo='bar'>Some Text</child>
  <!--A comment-->
  <ft:nschild ft:foo='nsbar'>Some More Text</ft:nschild>
</docelem>
"""


DOC2 = "foo"




if __name__ == '__main__':
    import sys
    from Ft.Lib import TestSuite
    tester = TestSuite.TestSuite(1,1)
    Test(tester,'--cdomlette' in sys.argv[1:])
