home *** CD-ROM | disk | FTP | other *** search
/ Enter 2003: The Beautiful Scenery / enter-parhaat-2003.iso / files / Python-2.2.1.exe / TEST_MINIDOM.PY < prev    next >
Encoding:
Python Source  |  2001-12-06  |  19.6 KB  |  651 lines

  1. # test for xml.dom.minidom
  2.  
  3. from xml.dom.minidom import parse, Node, Document, parseString
  4. from xml.dom import HierarchyRequestErr
  5. import xml.parsers.expat
  6.  
  7. import os
  8. import sys
  9. import traceback
  10. from test_support import verbose
  11.  
  12. if __name__ == "__main__":
  13.     base = sys.argv[0]
  14. else:
  15.     base = __file__
  16. tstfile = os.path.join(os.path.dirname(base), "test"+os.extsep+"xml")
  17. del base
  18.  
  19. def confirm(test, testname = "Test"):
  20.     if test:
  21.         print "Passed " + testname
  22.     else:
  23.         print "Failed " + testname
  24.         raise Exception
  25.  
  26. Node._debug = 1
  27.  
  28. def testParseFromFile():
  29.     from StringIO import StringIO
  30.     dom = parse(StringIO(open(tstfile).read()))
  31.     dom.unlink()
  32.     confirm(isinstance(dom,Document))
  33.  
  34. def testGetElementsByTagName():
  35.     dom = parse(tstfile)
  36.     confirm(dom.getElementsByTagName("LI") == \
  37.             dom.documentElement.getElementsByTagName("LI"))
  38.     dom.unlink()
  39.  
  40. def testInsertBefore():
  41.     dom = parseString("<doc><foo/></doc>")
  42.     root = dom.documentElement
  43.     elem = root.childNodes[0]
  44.     nelem = dom.createElement("element")
  45.     root.insertBefore(nelem, elem)
  46.     confirm(len(root.childNodes) == 2
  47.             and root.childNodes.length == 2
  48.             and root.childNodes[0] is nelem
  49.             and root.childNodes.item(0) is nelem
  50.             and root.childNodes[1] is elem
  51.             and root.childNodes.item(1) is elem
  52.             and root.firstChild is nelem
  53.             and root.lastChild is elem
  54.             and root.toxml() == "<doc><element/><foo/></doc>"
  55.             , "testInsertBefore -- node properly placed in tree")
  56.     nelem = dom.createElement("element")
  57.     root.insertBefore(nelem, None)
  58.     confirm(len(root.childNodes) == 3
  59.             and root.childNodes.length == 3
  60.             and root.childNodes[1] is elem
  61.             and root.childNodes.item(1) is elem
  62.             and root.childNodes[2] is nelem
  63.             and root.childNodes.item(2) is nelem
  64.             and root.lastChild is nelem
  65.             and nelem.previousSibling is elem
  66.             and root.toxml() == "<doc><element/><foo/><element/></doc>"
  67.             , "testInsertBefore -- node properly placed in tree")
  68.     nelem2 = dom.createElement("bar")
  69.     root.insertBefore(nelem2, nelem)
  70.     confirm(len(root.childNodes) == 4
  71.             and root.childNodes.length == 4
  72.             and root.childNodes[2] is nelem2
  73.             and root.childNodes.item(2) is nelem2
  74.             and root.childNodes[3] is nelem
  75.             and root.childNodes.item(3) is nelem
  76.             and nelem2.nextSibling is nelem
  77.             and nelem.previousSibling is nelem2
  78.             and root.toxml() == "<doc><element/><foo/><bar/><element/></doc>"
  79.             , "testInsertBefore -- node properly placed in tree")
  80.     dom.unlink()
  81.  
  82. def _create_fragment_test_nodes():
  83.     dom = parseString("<doc/>")
  84.     orig = dom.createTextNode("original")
  85.     c1 = dom.createTextNode("foo")
  86.     c2 = dom.createTextNode("bar")
  87.     c3 = dom.createTextNode("bat")
  88.     dom.documentElement.appendChild(orig)
  89.     frag = dom.createDocumentFragment()
  90.     frag.appendChild(c1)
  91.     frag.appendChild(c2)
  92.     frag.appendChild(c3)
  93.     return dom, orig, c1, c2, c3, frag
  94.  
  95. def testInsertBeforeFragment():
  96.     dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
  97.     dom.documentElement.insertBefore(frag, None)
  98.     confirm(tuple(dom.documentElement.childNodes) == (orig, c1, c2, c3),
  99.             "insertBefore(<fragment>, None)")
  100.     frag.unlink()
  101.     dom.unlink()
  102.     #
  103.     dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
  104.     dom.documentElement.insertBefore(frag, orig)
  105.     confirm(tuple(dom.documentElement.childNodes) == (c1, c2, c3, orig),
  106.             "insertBefore(<fragment>, orig)")
  107.     frag.unlink()
  108.     dom.unlink()
  109.  
  110. def testAppendChild():
  111.     dom = parse(tstfile)
  112.     dom.documentElement.appendChild(dom.createComment(u"Hello"))
  113.     confirm(dom.documentElement.childNodes[-1].nodeName == "#comment")
  114.     confirm(dom.documentElement.childNodes[-1].data == "Hello")
  115.     dom.unlink()
  116.  
  117. def testAppendChildFragment():
  118.     dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
  119.     dom.documentElement.appendChild(frag)
  120.     confirm(tuple(dom.documentElement.childNodes) == (orig, c1, c2, c3),
  121.             "appendChild(<fragment>)")
  122.     frag.unlink()
  123.     dom.unlink()
  124.  
  125. def testReplaceChildFragment():
  126.     dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
  127.     dom.documentElement.replaceChild(frag, orig)
  128.     orig.unlink()
  129.     confirm(tuple(dom.documentElement.childNodes) == (c1, c2, c3),
  130.             "replaceChild(<fragment>)")
  131.     frag.unlink()
  132.     dom.unlink()
  133.  
  134. def testLegalChildren():
  135.     dom = Document()
  136.     elem = dom.createElement('element')
  137.     text = dom.createTextNode('text')
  138.  
  139.     try: dom.appendChild(text)
  140.     except HierarchyRequestErr: pass
  141.     else:
  142.         print "dom.appendChild didn't raise HierarchyRequestErr"
  143.  
  144.     dom.appendChild(elem)
  145.     try: dom.insertBefore(text, elem)
  146.     except HierarchyRequestErr: pass
  147.     else:
  148.         print "dom.appendChild didn't raise HierarchyRequestErr"
  149.  
  150.     try: dom.replaceChild(text, elem)
  151.     except HierarchyRequestErr: pass
  152.     else:
  153.         print "dom.appendChild didn't raise HierarchyRequestErr"
  154.  
  155.     nodemap = elem.attributes
  156.     try: nodemap.setNamedItem(text)
  157.     except HierarchyRequestErr: pass
  158.     else:
  159.         print "NamedNodeMap.setNamedItem didn't raise HierarchyRequestErr"
  160.  
  161.     try: nodemap.setNamedItemNS(text)
  162.     except HierarchyRequestErr: pass
  163.     else:
  164.         print "NamedNodeMap.setNamedItemNS didn't raise HierarchyRequestErr"
  165.  
  166.     elem.appendChild(text)
  167.     dom.unlink()
  168.  
  169. def testNamedNodeMapSetItem():
  170.     dom = Document()
  171.     elem = dom.createElement('element')
  172.     attrs = elem.attributes
  173.     attrs["foo"] = "bar"
  174.     a = attrs.item(0)
  175.     confirm(a.ownerDocument is dom,
  176.             "NamedNodeMap.__setitem__() sets ownerDocument")
  177.     confirm(a.ownerElement is elem,
  178.             "NamedNodeMap.__setitem__() sets ownerElement")
  179.     confirm(a.value == "bar",
  180.             "NamedNodeMap.__setitem__() sets value")
  181.     confirm(a.nodeValue == "bar",
  182.             "NamedNodeMap.__setitem__() sets nodeValue")
  183.     elem.unlink()
  184.     dom.unlink()
  185.  
  186. def testNonZero():
  187.     dom = parse(tstfile)
  188.     confirm(dom)# should not be zero
  189.     dom.appendChild(dom.createComment("foo"))
  190.     confirm(not dom.childNodes[-1].childNodes)
  191.     dom.unlink()
  192.  
  193. def testUnlink():
  194.     dom = parse(tstfile)
  195.     dom.unlink()
  196.  
  197. def testElement():
  198.     dom = Document()
  199.     dom.appendChild(dom.createElement("abc"))
  200.     confirm(dom.documentElement)
  201.     dom.unlink()
  202.  
  203. def testAAA():
  204.     dom = parseString("<abc/>")
  205.     el = dom.documentElement
  206.     el.setAttribute("spam", "jam2")
  207.     confirm(el.toxml() == '<abc spam="jam2"/>', "testAAA")
  208.     a = el.getAttributeNode("spam")
  209.     confirm(a.ownerDocument is dom,
  210.             "setAttribute() sets ownerDocument")
  211.     confirm(a.ownerElement is dom.documentElement,
  212.             "setAttribute() sets ownerElement")
  213.     dom.unlink()
  214.  
  215. def testAAB():
  216.     dom = parseString("<abc/>")
  217.     el = dom.documentElement
  218.     el.setAttribute("spam", "jam")
  219.     el.setAttribute("spam", "jam2")
  220.     confirm(el.toxml() == '<abc spam="jam2"/>', "testAAB")
  221.     dom.unlink()
  222.  
  223. def testAddAttr():
  224.     dom = Document()
  225.     child = dom.appendChild(dom.createElement("abc"))
  226.  
  227.     child.setAttribute("def", "ghi")
  228.     confirm(child.getAttribute("def") == "ghi")
  229.     confirm(child.attributes["def"].value == "ghi")
  230.  
  231.     child.setAttribute("jkl", "mno")
  232.     confirm(child.getAttribute("jkl") == "mno")
  233.     confirm(child.attributes["jkl"].value == "mno")
  234.  
  235.     confirm(len(child.attributes) == 2)
  236.  
  237.     child.setAttribute("def", "newval")
  238.     confirm(child.getAttribute("def") == "newval")
  239.     confirm(child.attributes["def"].value == "newval")
  240.  
  241.     confirm(len(child.attributes) == 2)
  242.     dom.unlink()
  243.  
  244. def testDeleteAttr():
  245.     dom = Document()
  246.     child = dom.appendChild(dom.createElement("abc"))
  247.  
  248.     confirm(len(child.attributes) == 0)
  249.     child.setAttribute("def", "ghi")
  250.     confirm(len(child.attributes) == 1)
  251.     del child.attributes["def"]
  252.     confirm(len(child.attributes) == 0)
  253.     dom.unlink()
  254.  
  255. def testRemoveAttr():
  256.     dom = Document()
  257.     child = dom.appendChild(dom.createElement("abc"))
  258.  
  259.     child.setAttribute("def", "ghi")
  260.     confirm(len(child.attributes) == 1)
  261.     child.removeAttribute("def")
  262.     confirm(len(child.attributes) == 0)
  263.  
  264.     dom.unlink()
  265.  
  266. def testRemoveAttrNS():
  267.     dom = Document()
  268.     child = dom.appendChild(
  269.             dom.createElementNS("http://www.python.org", "python:abc"))
  270.     child.setAttributeNS("http://www.w3.org", "xmlns:python",
  271.                                             "http://www.python.org")
  272.     child.setAttributeNS("http://www.python.org", "python:abcattr", "foo")
  273.     confirm(len(child.attributes) == 2)
  274.     child.removeAttributeNS("http://www.python.org", "abcattr")
  275.     confirm(len(child.attributes) == 1)
  276.  
  277.     dom.unlink()
  278.  
  279. def testRemoveAttributeNode():
  280.     dom = Document()
  281.     child = dom.appendChild(dom.createElement("foo"))
  282.     child.setAttribute("spam", "jam")
  283.     confirm(len(child.attributes) == 1)
  284.     node = child.getAttributeNode("spam")
  285.     child.removeAttributeNode(node)
  286.     confirm(len(child.attributes) == 0)
  287.  
  288.     dom.unlink()
  289.  
  290. def testChangeAttr():
  291.     dom = parseString("<abc/>")
  292.     el = dom.documentElement
  293.     el.setAttribute("spam", "jam")
  294.     confirm(len(el.attributes) == 1)
  295.     el.setAttribute("spam", "bam")
  296.     confirm(len(el.attributes) == 1)
  297.     el.attributes["spam"] = "ham"
  298.     confirm(len(el.attributes) == 1)
  299.     el.setAttribute("spam2", "bam")
  300.     confirm(len(el.attributes) == 2)
  301.     el.attributes[ "spam2"] = "bam2"
  302.     confirm(len(el.attributes) == 2)
  303.     dom.unlink()
  304.  
  305. def testGetAttrList():
  306.     pass
  307.  
  308. def testGetAttrValues(): pass
  309.  
  310. def testGetAttrLength(): pass
  311.  
  312. def testGetAttribute(): pass
  313.  
  314. def testGetAttributeNS(): pass
  315.  
  316. def testGetAttributeNode(): pass
  317.  
  318. def testGetElementsByTagNameNS():
  319.     d="""<foo xmlns:minidom="http://pyxml.sf.net/minidom">
  320.     <minidom:myelem/>
  321.     </foo>"""
  322.     dom = parseString(d)
  323.     elem = dom.getElementsByTagNameNS("http://pyxml.sf.net/minidom","myelem")
  324.     confirm(len(elem) == 1)
  325.     dom.unlink()
  326.  
  327. def testGetEmptyNodeListFromElementsByTagNameNS(): pass
  328.  
  329. def testElementReprAndStr():
  330.     dom = Document()
  331.     el = dom.appendChild(dom.createElement("abc"))
  332.     string1 = repr(el)
  333.     string2 = str(el)
  334.     confirm(string1 == string2)
  335.     dom.unlink()
  336.  
  337. # commented out until Fredrick's fix is checked in
  338. def _testElementReprAndStrUnicode():
  339.     dom = Document()
  340.     el = dom.appendChild(dom.createElement(u"abc"))
  341.     string1 = repr(el)
  342.     string2 = str(el)
  343.     confirm(string1 == string2)
  344.     dom.unlink()
  345.  
  346. # commented out until Fredrick's fix is checked in
  347. def _testElementReprAndStrUnicodeNS():
  348.     dom = Document()
  349.     el = dom.appendChild(
  350.         dom.createElementNS(u"http://www.slashdot.org", u"slash:abc"))
  351.     string1 = repr(el)
  352.     string2 = str(el)
  353.     confirm(string1 == string2)
  354.     confirm(string1.find("slash:abc") != -1)
  355.     dom.unlink()
  356.     confirm(len(Node.allnodes) == 0)
  357.  
  358. def testAttributeRepr():
  359.     dom = Document()
  360.     el = dom.appendChild(dom.createElement(u"abc"))
  361.     node = el.setAttribute("abc", "def")
  362.     confirm(str(node) == repr(node))
  363.     dom.unlink()
  364.     confirm(len(Node.allnodes) == 0)
  365.  
  366. def testTextNodeRepr(): pass
  367.  
  368. def testWriteXML():
  369.     str = '<?xml version="1.0" ?>\n<a b="c"/>'
  370.     dom = parseString(str)
  371.     domstr = dom.toxml()
  372.     dom.unlink()
  373.     confirm(str == domstr)
  374.     confirm(len(Node.allnodes) == 0)
  375.  
  376. def testProcessingInstruction(): pass
  377.  
  378. def testProcessingInstructionRepr(): pass
  379.  
  380. def testTextRepr(): pass
  381.  
  382. def testWriteText(): pass
  383.  
  384. def testDocumentElement(): pass
  385.  
  386. def testTooManyDocumentElements():
  387.     doc = parseString("<doc/>")
  388.     elem = doc.createElement("extra")
  389.     try:
  390.         doc.appendChild(elem)
  391.     except HierarchyRequestErr:
  392.         print "Caught expected exception when adding extra document element."
  393.     else:
  394.         print "Failed to catch expected exception when" \
  395.               " adding extra document element."
  396.     elem.unlink()
  397.     doc.unlink()
  398.  
  399. def testCreateElementNS(): pass
  400.  
  401. def testCreateAttributeNS(): pass
  402.  
  403. def testParse(): pass
  404.  
  405. def testParseString(): pass
  406.  
  407. def testComment(): pass
  408.  
  409. def testAttrListItem(): pass
  410.  
  411. def testAttrListItems(): pass
  412.  
  413. def testAttrListItemNS(): pass
  414.  
  415. def testAttrListKeys(): pass
  416.  
  417. def testAttrListKeysNS(): pass
  418.  
  419. def testAttrListValues(): pass
  420.  
  421. def testAttrListLength(): pass
  422.  
  423. def testAttrList__getitem__(): pass
  424.  
  425. def testAttrList__setitem__(): pass
  426.  
  427. def testSetAttrValueandNodeValue(): pass
  428.  
  429. def testParseElement(): pass
  430.  
  431. def testParseAttributes(): pass
  432.  
  433. def testParseElementNamespaces(): pass
  434.  
  435. def testParseAttributeNamespaces(): pass
  436.  
  437. def testParseProcessingInstructions(): pass
  438.  
  439. def testChildNodes(): pass
  440.  
  441. def testFirstChild(): pass
  442.  
  443. def testHasChildNodes(): pass
  444.  
  445. def testCloneElementShallow():
  446.     dom, clone = _setupCloneElement(0)
  447.     confirm(len(clone.childNodes) == 0
  448.             and clone.childNodes.length == 0
  449.             and clone.parentNode is None
  450.             and clone.toxml() == '<doc attr="value"/>'
  451.             , "testCloneElementShallow")
  452.     dom.unlink()
  453.  
  454. def testCloneElementDeep():
  455.     dom, clone = _setupCloneElement(1)
  456.     confirm(len(clone.childNodes) == 1
  457.             and clone.childNodes.length == 1
  458.             and clone.parentNode is None
  459.             and clone.toxml() == '<doc attr="value"><foo/></doc>'
  460.             , "testCloneElementDeep")
  461.     dom.unlink()
  462.  
  463. def _setupCloneElement(deep):
  464.     dom = parseString("<doc attr='value'><foo/></doc>")
  465.     root = dom.documentElement
  466.     clone = root.cloneNode(deep)
  467.     _testCloneElementCopiesAttributes(
  468.         root, clone, "testCloneElement" + (deep and "Deep" or "Shallow"))
  469.     # mutilate the original so shared data is detected
  470.     root.tagName = root.nodeName = "MODIFIED"
  471.     root.setAttribute("attr", "NEW VALUE")
  472.     root.setAttribute("added", "VALUE")
  473.     return dom, clone
  474.  
  475. def _testCloneElementCopiesAttributes(e1, e2, test):
  476.     attrs1 = e1.attributes
  477.     attrs2 = e2.attributes
  478.     keys1 = attrs1.keys()
  479.     keys2 = attrs2.keys()
  480.     keys1.sort()
  481.     keys2.sort()
  482.     confirm(keys1 == keys2, "clone of element has same attribute keys")
  483.     for i in range(len(keys1)):
  484.         a1 = attrs1.item(i)
  485.         a2 = attrs2.item(i)
  486.         confirm(a1 is not a2
  487.                 and a1.value == a2.value
  488.                 and a1.nodeValue == a2.nodeValue
  489.                 and a1.namespaceURI == a2.namespaceURI
  490.                 and a1.localName == a2.localName
  491.                 , "clone of attribute node has proper attribute values")
  492.         confirm(a2.ownerElement is e2,
  493.                 "clone of attribute node correctly owned")
  494.  
  495.  
  496. def testCloneDocumentShallow(): pass
  497.  
  498. def testCloneDocumentDeep(): pass
  499.  
  500. def testCloneAttributeShallow(): pass
  501.  
  502. def testCloneAttributeDeep(): pass
  503.  
  504. def testClonePIShallow(): pass
  505.  
  506. def testClonePIDeep(): pass
  507.  
  508. def testNormalize():
  509.     doc = parseString("<doc/>")
  510.     root = doc.documentElement
  511.     root.appendChild(doc.createTextNode("first"))
  512.     root.appendChild(doc.createTextNode("second"))
  513.     confirm(len(root.childNodes) == 2
  514.             and root.childNodes.length == 2, "testNormalize -- preparation")
  515.     doc.normalize()
  516.     confirm(len(root.childNodes) == 1
  517.             and root.childNodes.length == 1
  518.             and root.firstChild is root.lastChild
  519.             and root.firstChild.data == "firstsecond"
  520.             , "testNormalize -- result")
  521.     doc.unlink()
  522.  
  523.     doc = parseString("<doc/>")
  524.     root = doc.documentElement
  525.     root.appendChild(doc.createTextNode(""))
  526.     doc.normalize()
  527.     confirm(len(root.childNodes) == 0
  528.             and root.childNodes.length == 0,
  529.             "testNormalize -- single empty node removed")
  530.     doc.unlink()
  531.  
  532. def testSiblings():
  533.     doc = parseString("<doc><?pi?>text?<elm/></doc>")
  534.     root = doc.documentElement
  535.     (pi, text, elm) = root.childNodes
  536.  
  537.     confirm(pi.nextSibling is text and
  538.             pi.previousSibling is None and
  539.             text.nextSibling is elm and
  540.             text.previousSibling is pi and
  541.             elm.nextSibling is None and
  542.             elm.previousSibling is text, "testSiblings")
  543.  
  544.     doc.unlink()
  545.  
  546. def testParents():
  547.     doc = parseString("<doc><elm1><elm2/><elm2><elm3/></elm2></elm1></doc>")
  548.     root = doc.documentElement
  549.     elm1 = root.childNodes[0]
  550.     (elm2a, elm2b) = elm1.childNodes
  551.     elm3 = elm2b.childNodes[0]
  552.  
  553.     confirm(root.parentNode is doc and
  554.             elm1.parentNode is root and
  555.             elm2a.parentNode is elm1 and
  556.             elm2b.parentNode is elm1 and
  557.             elm3.parentNode is elm2b, "testParents")
  558.  
  559.     doc.unlink()
  560.  
  561. def testNodeListItem():
  562.     doc = parseString("<doc><e/><e/></doc>")
  563.     children = doc.childNodes
  564.     docelem = children[0]
  565.     confirm(children[0] is children.item(0)
  566.             and children.item(1) is None
  567.             and docelem.childNodes.item(0) is docelem.childNodes[0]
  568.             and docelem.childNodes.item(1) is docelem.childNodes[1]
  569.             and docelem.childNodes.item(0).childNodes.item(0) is None,
  570.             "test NodeList.item()")
  571.     doc.unlink()
  572.  
  573. def testSAX2DOM():
  574.     from xml.dom import pulldom
  575.  
  576.     sax2dom = pulldom.SAX2DOM()
  577.     sax2dom.startDocument()
  578.     sax2dom.startElement("doc", {})
  579.     sax2dom.characters("text")
  580.     sax2dom.startElement("subelm", {})
  581.     sax2dom.characters("text")
  582.     sax2dom.endElement("subelm")
  583.     sax2dom.characters("text")
  584.     sax2dom.endElement("doc")
  585.     sax2dom.endDocument()
  586.  
  587.     doc = sax2dom.document
  588.     root = doc.documentElement
  589.     (text1, elm1, text2) = root.childNodes
  590.     text3 = elm1.childNodes[0]
  591.  
  592.     confirm(text1.previousSibling is None and
  593.             text1.nextSibling is elm1 and
  594.             elm1.previousSibling is text1 and
  595.             elm1.nextSibling is text2 and
  596.             text2.previousSibling is elm1 and
  597.             text2.nextSibling is None and
  598.             text3.previousSibling is None and
  599.             text3.nextSibling is None, "testSAX2DOM - siblings")
  600.  
  601.     confirm(root.parentNode is doc and
  602.             text1.parentNode is root and
  603.             elm1.parentNode is root and
  604.             text2.parentNode is root and
  605.             text3.parentNode is elm1, "testSAX2DOM - parents")
  606.  
  607.     doc.unlink()
  608.  
  609. # --- MAIN PROGRAM
  610.  
  611. names = globals().keys()
  612. names.sort()
  613.  
  614. failed = []
  615.  
  616. for name in names:
  617.     if name.startswith("test"):
  618.         func = globals()[name]
  619.         try:
  620.             func()
  621.             print "Test Succeeded", name
  622.             confirm(len(Node.allnodes) == 0,
  623.                     "assertion: len(Node.allnodes) == 0")
  624.             if len(Node.allnodes):
  625.                 print "Garbage left over:"
  626.                 if verbose:
  627.                     print Node.allnodes.items()[0:10]
  628.                 else:
  629.                     # Don't print specific nodes if repeatable results
  630.                     # are needed
  631.                     print len(Node.allnodes)
  632.             Node.allnodes = {}
  633.         except:
  634.             failed.append(name)
  635.             print "Test Failed: ", name
  636.             sys.stdout.flush()
  637.             traceback.print_exception(*sys.exc_info())
  638.             print `sys.exc_info()[1]`
  639.             Node.allnodes = {}
  640.  
  641. if failed:
  642.     print "\n\n\n**** Check for failures in these tests:"
  643.     for name in failed:
  644.         print "  " + name
  645.     print
  646. else:
  647.     print "All tests succeeded"
  648.  
  649. Node.debug = None # Delete debug output collected in a StringIO object
  650. Node._debug = 0   # And reset debug mode
  651.