| #!/usr/bin/env python2.5 |
| # Copyright 2006 Google, Inc. All Rights Reserved. |
| # Licensed to PSF under a Contributor Agreement. |
| |
| """Unit tests for pytree.py. |
| |
| NOTE: Please *don't* add doc strings to individual test methods! |
| In verbose mode, printing of the module, class and method name is much |
| more helpful than printing of (the first line of) the docstring, |
| especially when debugging a test. |
| """ |
| |
| # Testing imports |
| from . import support |
| |
| # Local imports (XXX should become a package) |
| from .. import pytree |
| |
| try: |
| sorted |
| except NameError: |
| def sorted(lst): |
| l = list(lst) |
| l.sort() |
| return l |
| |
| class TestNodes(support.TestCase): |
| |
| """Unit tests for nodes (Base, Leaf, Node).""" |
| |
| def testBaseCantConstruct(self): |
| if __debug__: |
| # Test that instantiating Base() raises an AssertionError |
| self.assertRaises(AssertionError, pytree.Base) |
| |
| def testLeaf(self): |
| l1 = pytree.Leaf(100, "foo") |
| self.assertEqual(l1.type, 100) |
| self.assertEqual(l1.value, "foo") |
| |
| def testLeafRepr(self): |
| l1 = pytree.Leaf(100, "foo") |
| self.assertEqual(repr(l1), "Leaf(100, 'foo')") |
| |
| def testLeafStr(self): |
| l1 = pytree.Leaf(100, "foo") |
| self.assertEqual(str(l1), "foo") |
| l2 = pytree.Leaf(100, "foo", context=(" ", (10, 1))) |
| self.assertEqual(str(l2), " foo") |
| |
| def testLeafStrNumericValue(self): |
| # Make sure that the Leaf's value is stringified. Failing to |
| # do this can cause a TypeError in certain situations. |
| l1 = pytree.Leaf(2, 5) |
| l1.set_prefix("foo_") |
| self.assertEqual(str(l1), "foo_5") |
| |
| def testLeafEq(self): |
| l1 = pytree.Leaf(100, "foo") |
| l2 = pytree.Leaf(100, "foo", context=(" ", (1, 0))) |
| self.assertEqual(l1, l2) |
| l3 = pytree.Leaf(101, "foo") |
| l4 = pytree.Leaf(100, "bar") |
| self.assertNotEqual(l1, l3) |
| self.assertNotEqual(l1, l4) |
| |
| def testLeafPrefix(self): |
| l1 = pytree.Leaf(100, "foo") |
| self.assertEqual(l1.get_prefix(), "") |
| self.failIf(l1.was_changed) |
| l1.set_prefix(" ##\n\n") |
| self.assertEqual(l1.get_prefix(), " ##\n\n") |
| self.failUnless(l1.was_changed) |
| |
| def testNode(self): |
| l1 = pytree.Leaf(100, "foo") |
| l2 = pytree.Leaf(200, "bar") |
| n1 = pytree.Node(1000, [l1, l2]) |
| self.assertEqual(n1.type, 1000) |
| self.assertEqual(n1.children, [l1, l2]) |
| |
| def testNodeRepr(self): |
| l1 = pytree.Leaf(100, "foo") |
| l2 = pytree.Leaf(100, "bar", context=(" ", (1, 0))) |
| n1 = pytree.Node(1000, [l1, l2]) |
| self.assertEqual(repr(n1), |
| "Node(1000, [%s, %s])" % (repr(l1), repr(l2))) |
| |
| def testNodeStr(self): |
| l1 = pytree.Leaf(100, "foo") |
| l2 = pytree.Leaf(100, "bar", context=(" ", (1, 0))) |
| n1 = pytree.Node(1000, [l1, l2]) |
| self.assertEqual(str(n1), "foo bar") |
| |
| def testNodePrefix(self): |
| l1 = pytree.Leaf(100, "foo") |
| self.assertEqual(l1.get_prefix(), "") |
| n1 = pytree.Node(1000, [l1]) |
| self.assertEqual(n1.get_prefix(), "") |
| n1.set_prefix(" ") |
| self.assertEqual(n1.get_prefix(), " ") |
| self.assertEqual(l1.get_prefix(), " ") |
| |
| def testGetSuffix(self): |
| l1 = pytree.Leaf(100, "foo", prefix="a") |
| l2 = pytree.Leaf(100, "bar", prefix="b") |
| n1 = pytree.Node(1000, [l1, l2]) |
| |
| self.assertEqual(l1.get_suffix(), l2.get_prefix()) |
| self.assertEqual(l2.get_suffix(), "") |
| self.assertEqual(n1.get_suffix(), "") |
| |
| l3 = pytree.Leaf(100, "bar", prefix="c") |
| n2 = pytree.Node(1000, [n1, l3]) |
| |
| self.assertEqual(n1.get_suffix(), l3.get_prefix()) |
| self.assertEqual(l3.get_suffix(), "") |
| self.assertEqual(n2.get_suffix(), "") |
| |
| def testNodeEq(self): |
| n1 = pytree.Node(1000, ()) |
| n2 = pytree.Node(1000, [], context=(" ", (1, 0))) |
| self.assertEqual(n1, n2) |
| n3 = pytree.Node(1001, ()) |
| self.assertNotEqual(n1, n3) |
| |
| def testNodeEqRecursive(self): |
| l1 = pytree.Leaf(100, "foo") |
| l2 = pytree.Leaf(100, "foo") |
| n1 = pytree.Node(1000, [l1]) |
| n2 = pytree.Node(1000, [l2]) |
| self.assertEqual(n1, n2) |
| l3 = pytree.Leaf(100, "bar") |
| n3 = pytree.Node(1000, [l3]) |
| self.assertNotEqual(n1, n3) |
| |
| def testReplace(self): |
| l1 = pytree.Leaf(100, "foo") |
| l2 = pytree.Leaf(100, "+") |
| l3 = pytree.Leaf(100, "bar") |
| n1 = pytree.Node(1000, [l1, l2, l3]) |
| self.assertEqual(n1.children, [l1, l2, l3]) |
| self.failUnless(isinstance(n1.children, list)) |
| self.failIf(n1.was_changed) |
| l2new = pytree.Leaf(100, "-") |
| l2.replace(l2new) |
| self.assertEqual(n1.children, [l1, l2new, l3]) |
| self.failUnless(isinstance(n1.children, list)) |
| self.failUnless(n1.was_changed) |
| |
| def testReplaceWithList(self): |
| l1 = pytree.Leaf(100, "foo") |
| l2 = pytree.Leaf(100, "+") |
| l3 = pytree.Leaf(100, "bar") |
| n1 = pytree.Node(1000, [l1, l2, l3]) |
| |
| l2.replace([pytree.Leaf(100, "*"), pytree.Leaf(100, "*")]) |
| self.assertEqual(str(n1), "foo**bar") |
| self.failUnless(isinstance(n1.children, list)) |
| |
| def testPostOrder(self): |
| l1 = pytree.Leaf(100, "foo") |
| l2 = pytree.Leaf(100, "bar") |
| n1 = pytree.Node(1000, [l1, l2]) |
| self.assertEqual(list(n1.post_order()), [l1, l2, n1]) |
| |
| def testPreOrder(self): |
| l1 = pytree.Leaf(100, "foo") |
| l2 = pytree.Leaf(100, "bar") |
| n1 = pytree.Node(1000, [l1, l2]) |
| self.assertEqual(list(n1.pre_order()), [n1, l1, l2]) |
| |
| def testChangedLeaf(self): |
| l1 = pytree.Leaf(100, "f") |
| self.failIf(l1.was_changed) |
| |
| l1.changed() |
| self.failUnless(l1.was_changed) |
| |
| def testChangedNode(self): |
| l1 = pytree.Leaf(100, "f") |
| n1 = pytree.Node(1000, [l1]) |
| self.failIf(n1.was_changed) |
| |
| n1.changed() |
| self.failUnless(n1.was_changed) |
| |
| def testChangedRecursive(self): |
| l1 = pytree.Leaf(100, "foo") |
| l2 = pytree.Leaf(100, "+") |
| l3 = pytree.Leaf(100, "bar") |
| n1 = pytree.Node(1000, [l1, l2, l3]) |
| n2 = pytree.Node(1000, [n1]) |
| self.failIf(l1.was_changed) |
| self.failIf(n1.was_changed) |
| self.failIf(n2.was_changed) |
| |
| n1.changed() |
| self.failUnless(n1.was_changed) |
| self.failUnless(n2.was_changed) |
| self.failIf(l1.was_changed) |
| |
| def testLeafConstructorPrefix(self): |
| for prefix in ("xyz_", ""): |
| l1 = pytree.Leaf(100, "self", prefix=prefix) |
| self.failUnless(str(l1), prefix + "self") |
| self.assertEqual(l1.get_prefix(), prefix) |
| |
| def testNodeConstructorPrefix(self): |
| for prefix in ("xyz_", ""): |
| l1 = pytree.Leaf(100, "self") |
| l2 = pytree.Leaf(100, "foo", prefix="_") |
| n1 = pytree.Node(1000, [l1, l2], prefix=prefix) |
| self.failUnless(str(n1), prefix + "self_foo") |
| self.assertEqual(n1.get_prefix(), prefix) |
| self.assertEqual(l1.get_prefix(), prefix) |
| self.assertEqual(l2.get_prefix(), "_") |
| |
| def testRemove(self): |
| l1 = pytree.Leaf(100, "foo") |
| l2 = pytree.Leaf(100, "foo") |
| n1 = pytree.Node(1000, [l1, l2]) |
| n2 = pytree.Node(1000, [n1]) |
| |
| self.assertEqual(n1.remove(), 0) |
| self.assertEqual(n2.children, []) |
| self.assertEqual(l1.parent, n1) |
| self.assertEqual(n1.parent, None) |
| self.assertEqual(n2.parent, None) |
| self.failIf(n1.was_changed) |
| self.failUnless(n2.was_changed) |
| |
| self.assertEqual(l2.remove(), 1) |
| self.assertEqual(l1.remove(), 0) |
| self.assertEqual(n1.children, []) |
| self.assertEqual(l1.parent, None) |
| self.assertEqual(n1.parent, None) |
| self.assertEqual(n2.parent, None) |
| self.failUnless(n1.was_changed) |
| self.failUnless(n2.was_changed) |
| |
| def testRemoveParentless(self): |
| n1 = pytree.Node(1000, []) |
| n1.remove() |
| self.assertEqual(n1.parent, None) |
| |
| l1 = pytree.Leaf(100, "foo") |
| l1.remove() |
| self.assertEqual(l1.parent, None) |
| |
| def testNodeSetChild(self): |
| l1 = pytree.Leaf(100, "foo") |
| n1 = pytree.Node(1000, [l1]) |
| |
| l2 = pytree.Leaf(100, "bar") |
| n1.set_child(0, l2) |
| self.assertEqual(l1.parent, None) |
| self.assertEqual(l2.parent, n1) |
| self.assertEqual(n1.children, [l2]) |
| |
| n2 = pytree.Node(1000, [l1]) |
| n2.set_child(0, n1) |
| self.assertEqual(l1.parent, None) |
| self.assertEqual(n1.parent, n2) |
| self.assertEqual(n2.parent, None) |
| self.assertEqual(n2.children, [n1]) |
| |
| self.assertRaises(IndexError, n1.set_child, 4, l2) |
| # I don't care what it raises, so long as it's an exception |
| self.assertRaises(Exception, n1.set_child, 0, list) |
| |
| def testNodeInsertChild(self): |
| l1 = pytree.Leaf(100, "foo") |
| n1 = pytree.Node(1000, [l1]) |
| |
| l2 = pytree.Leaf(100, "bar") |
| n1.insert_child(0, l2) |
| self.assertEqual(l2.parent, n1) |
| self.assertEqual(n1.children, [l2, l1]) |
| |
| l3 = pytree.Leaf(100, "abc") |
| n1.insert_child(2, l3) |
| self.assertEqual(n1.children, [l2, l1, l3]) |
| |
| # I don't care what it raises, so long as it's an exception |
| self.assertRaises(Exception, n1.insert_child, 0, list) |
| |
| def testNodeAppendChild(self): |
| n1 = pytree.Node(1000, []) |
| |
| l1 = pytree.Leaf(100, "foo") |
| n1.append_child(l1) |
| self.assertEqual(l1.parent, n1) |
| self.assertEqual(n1.children, [l1]) |
| |
| l2 = pytree.Leaf(100, "bar") |
| n1.append_child(l2) |
| self.assertEqual(l2.parent, n1) |
| self.assertEqual(n1.children, [l1, l2]) |
| |
| # I don't care what it raises, so long as it's an exception |
| self.assertRaises(Exception, n1.append_child, list) |
| |
| def testNodeNextSibling(self): |
| n1 = pytree.Node(1000, []) |
| n2 = pytree.Node(1000, []) |
| p1 = pytree.Node(1000, [n1, n2]) |
| |
| self.failUnless(n1.get_next_sibling() is n2) |
| self.assertEqual(n2.get_next_sibling(), None) |
| self.assertEqual(p1.get_next_sibling(), None) |
| |
| def testLeafNextSibling(self): |
| l1 = pytree.Leaf(100, "a") |
| l2 = pytree.Leaf(100, "b") |
| p1 = pytree.Node(1000, [l1, l2]) |
| |
| self.failUnless(l1.get_next_sibling() is l2) |
| self.assertEqual(l2.get_next_sibling(), None) |
| self.assertEqual(p1.get_next_sibling(), None) |
| |
| def testNodePrevSibling(self): |
| n1 = pytree.Node(1000, []) |
| n2 = pytree.Node(1000, []) |
| p1 = pytree.Node(1000, [n1, n2]) |
| |
| self.failUnless(n2.get_prev_sibling() is n1) |
| self.assertEqual(n1.get_prev_sibling(), None) |
| self.assertEqual(p1.get_prev_sibling(), None) |
| |
| def testLeafPrevSibling(self): |
| l1 = pytree.Leaf(100, "a") |
| l2 = pytree.Leaf(100, "b") |
| p1 = pytree.Node(1000, [l1, l2]) |
| |
| self.failUnless(l2.get_prev_sibling() is l1) |
| self.assertEqual(l1.get_prev_sibling(), None) |
| self.assertEqual(p1.get_prev_sibling(), None) |
| |
| |
| class TestPatterns(support.TestCase): |
| |
| """Unit tests for tree matching patterns.""" |
| |
| def testBasicPatterns(self): |
| # Build a tree |
| l1 = pytree.Leaf(100, "foo") |
| l2 = pytree.Leaf(100, "bar") |
| l3 = pytree.Leaf(100, "foo") |
| n1 = pytree.Node(1000, [l1, l2]) |
| n2 = pytree.Node(1000, [l3]) |
| root = pytree.Node(1000, [n1, n2]) |
| # Build a pattern matching a leaf |
| pl = pytree.LeafPattern(100, "foo", name="pl") |
| r = {} |
| self.assertFalse(pl.match(root, results=r)) |
| self.assertEqual(r, {}) |
| self.assertFalse(pl.match(n1, results=r)) |
| self.assertEqual(r, {}) |
| self.assertFalse(pl.match(n2, results=r)) |
| self.assertEqual(r, {}) |
| self.assertTrue(pl.match(l1, results=r)) |
| self.assertEqual(r, {"pl": l1}) |
| r = {} |
| self.assertFalse(pl.match(l2, results=r)) |
| self.assertEqual(r, {}) |
| # Build a pattern matching a node |
| pn = pytree.NodePattern(1000, [pl], name="pn") |
| self.assertFalse(pn.match(root, results=r)) |
| self.assertEqual(r, {}) |
| self.assertFalse(pn.match(n1, results=r)) |
| self.assertEqual(r, {}) |
| self.assertTrue(pn.match(n2, results=r)) |
| self.assertEqual(r, {"pn": n2, "pl": l3}) |
| r = {} |
| self.assertFalse(pn.match(l1, results=r)) |
| self.assertEqual(r, {}) |
| self.assertFalse(pn.match(l2, results=r)) |
| self.assertEqual(r, {}) |
| |
| def testWildcardPatterns(self): |
| # Build a tree for testing |
| l1 = pytree.Leaf(100, "foo") |
| l2 = pytree.Leaf(100, "bar") |
| l3 = pytree.Leaf(100, "foo") |
| n1 = pytree.Node(1000, [l1, l2]) |
| n2 = pytree.Node(1000, [l3]) |
| root = pytree.Node(1000, [n1, n2]) |
| # Build a pattern |
| pl = pytree.LeafPattern(100, "foo", name="pl") |
| pn = pytree.NodePattern(1000, [pl], name="pn") |
| pw = pytree.WildcardPattern([[pn], [pl, pl]], name="pw") |
| r = {} |
| self.assertFalse(pw.match_seq([root], r)) |
| self.assertEqual(r, {}) |
| self.assertFalse(pw.match_seq([n1], r)) |
| self.assertEqual(r, {}) |
| self.assertTrue(pw.match_seq([n2], r)) |
| # These are easier to debug |
| self.assertEqual(sorted(r.keys()), ["pl", "pn", "pw"]) |
| self.assertEqual(r["pl"], l1) |
| self.assertEqual(r["pn"], n2) |
| self.assertEqual(r["pw"], [n2]) |
| # But this is equivalent |
| self.assertEqual(r, {"pl": l1, "pn": n2, "pw": [n2]}) |
| r = {} |
| self.assertTrue(pw.match_seq([l1, l3], r)) |
| self.assertEqual(r, {"pl": l3, "pw": [l1, l3]}) |
| self.assert_(r["pl"] is l3) |
| r = {} |
| |
| def testGenerateMatches(self): |
| la = pytree.Leaf(1, "a") |
| lb = pytree.Leaf(1, "b") |
| lc = pytree.Leaf(1, "c") |
| ld = pytree.Leaf(1, "d") |
| le = pytree.Leaf(1, "e") |
| lf = pytree.Leaf(1, "f") |
| leaves = [la, lb, lc, ld, le, lf] |
| root = pytree.Node(1000, leaves) |
| pa = pytree.LeafPattern(1, "a", "pa") |
| pb = pytree.LeafPattern(1, "b", "pb") |
| pc = pytree.LeafPattern(1, "c", "pc") |
| pd = pytree.LeafPattern(1, "d", "pd") |
| pe = pytree.LeafPattern(1, "e", "pe") |
| pf = pytree.LeafPattern(1, "f", "pf") |
| pw = pytree.WildcardPattern([[pa, pb, pc], [pd, pe], |
| [pa, pb], [pc, pd], [pe, pf]], |
| min=1, max=4, name="pw") |
| self.assertEqual([x[0] for x in pw.generate_matches(leaves)], |
| [3, 5, 2, 4, 6]) |
| pr = pytree.NodePattern(type=1000, content=[pw], name="pr") |
| matches = list(pytree.generate_matches([pr], [root])) |
| self.assertEqual(len(matches), 1) |
| c, r = matches[0] |
| self.assertEqual(c, 1) |
| self.assertEqual(str(r["pr"]), "abcdef") |
| self.assertEqual(r["pw"], [la, lb, lc, ld, le, lf]) |
| for c in "abcdef": |
| self.assertEqual(r["p" + c], pytree.Leaf(1, c)) |
| |
| def testHasKeyExample(self): |
| pattern = pytree.NodePattern(331, |
| (pytree.LeafPattern(7), |
| pytree.WildcardPattern(name="args"), |
| pytree.LeafPattern(8))) |
| l1 = pytree.Leaf(7, "(") |
| l2 = pytree.Leaf(3, "x") |
| l3 = pytree.Leaf(8, ")") |
| node = pytree.Node(331, [l1, l2, l3]) |
| r = {} |
| self.assert_(pattern.match(node, r)) |
| self.assertEqual(r["args"], [l2]) |
| |
| |
| if __name__ == "__main__": |
| import __main__ |
| support.run_all_tests(__main__) |