Home | History | Annotate | Download | only in tests
      1 # Copyright 2006 Google, Inc. All Rights Reserved.
      2 # Licensed to PSF under a Contributor Agreement.
      3 
      4 """Unit tests for pytree.py.
      5 
      6 NOTE: Please *don't* add doc strings to individual test methods!
      7 In verbose mode, printing of the module, class and method name is much
      8 more helpful than printing of (the first line of) the docstring,
      9 especially when debugging a test.
     10 """
     11 
     12 from __future__ import with_statement
     13 
     14 import sys
     15 import warnings
     16 
     17 # Testing imports
     18 from . import support
     19 
     20 from lib2to3 import pytree
     21 
     22 try:
     23     sorted
     24 except NameError:
     25     def sorted(lst):
     26         l = list(lst)
     27         l.sort()
     28         return l
     29 
     30 class TestNodes(support.TestCase):
     31 
     32     """Unit tests for nodes (Base, Leaf, Node)."""
     33 
     34     if sys.version_info >= (2,6):
     35         # warnings.catch_warnings is new in 2.6.
     36         def test_deprecated_prefix_methods(self):
     37             l = pytree.Leaf(100, "foo")
     38             with warnings.catch_warnings(record=True) as w:
     39                 warnings.simplefilter("always", DeprecationWarning)
     40                 self.assertEqual(l.get_prefix(), "")
     41                 l.set_prefix("hi")
     42             self.assertEqual(l.prefix, "hi")
     43             self.assertEqual(len(w), 2)
     44             for warning in w:
     45                 self.assertTrue(warning.category is DeprecationWarning)
     46             self.assertEqual(str(w[0].message), "get_prefix() is deprecated; " \
     47                                  "use the prefix property")
     48             self.assertEqual(str(w[1].message), "set_prefix() is deprecated; " \
     49                                  "use the prefix property")
     50 
     51     def test_instantiate_base(self):
     52         if __debug__:
     53             # Test that instantiating Base() raises an AssertionError
     54             self.assertRaises(AssertionError, pytree.Base)
     55 
     56     def test_leaf(self):
     57         l1 = pytree.Leaf(100, "foo")
     58         self.assertEqual(l1.type, 100)
     59         self.assertEqual(l1.value, "foo")
     60 
     61     def test_leaf_repr(self):
     62         l1 = pytree.Leaf(100, "foo")
     63         self.assertEqual(repr(l1), "Leaf(100, 'foo')")
     64 
     65     def test_leaf_str(self):
     66         l1 = pytree.Leaf(100, "foo")
     67         self.assertEqual(str(l1), "foo")
     68         l2 = pytree.Leaf(100, "foo", context=(" ", (10, 1)))
     69         self.assertEqual(str(l2), " foo")
     70 
     71     def test_leaf_str_numeric_value(self):
     72         # Make sure that the Leaf's value is stringified. Failing to
     73         #  do this can cause a TypeError in certain situations.
     74         l1 = pytree.Leaf(2, 5)
     75         l1.prefix = "foo_"
     76         self.assertEqual(str(l1), "foo_5")
     77 
     78     def test_leaf_equality(self):
     79         l1 = pytree.Leaf(100, "foo")
     80         l2 = pytree.Leaf(100, "foo", context=(" ", (1, 0)))
     81         self.assertEqual(l1, l2)
     82         l3 = pytree.Leaf(101, "foo")
     83         l4 = pytree.Leaf(100, "bar")
     84         self.assertNotEqual(l1, l3)
     85         self.assertNotEqual(l1, l4)
     86 
     87     def test_leaf_prefix(self):
     88         l1 = pytree.Leaf(100, "foo")
     89         self.assertEqual(l1.prefix, "")
     90         self.assertFalse(l1.was_changed)
     91         l1.prefix = "  ##\n\n"
     92         self.assertEqual(l1.prefix, "  ##\n\n")
     93         self.assertTrue(l1.was_changed)
     94 
     95     def test_node(self):
     96         l1 = pytree.Leaf(100, "foo")
     97         l2 = pytree.Leaf(200, "bar")
     98         n1 = pytree.Node(1000, [l1, l2])
     99         self.assertEqual(n1.type, 1000)
    100         self.assertEqual(n1.children, [l1, l2])
    101 
    102     def test_node_repr(self):
    103         l1 = pytree.Leaf(100, "foo")
    104         l2 = pytree.Leaf(100, "bar", context=(" ", (1, 0)))
    105         n1 = pytree.Node(1000, [l1, l2])
    106         self.assertEqual(repr(n1),
    107                          "Node(1000, [%s, %s])" % (repr(l1), repr(l2)))
    108 
    109     def test_node_str(self):
    110         l1 = pytree.Leaf(100, "foo")
    111         l2 = pytree.Leaf(100, "bar", context=(" ", (1, 0)))
    112         n1 = pytree.Node(1000, [l1, l2])
    113         self.assertEqual(str(n1), "foo bar")
    114 
    115     def test_node_prefix(self):
    116         l1 = pytree.Leaf(100, "foo")
    117         self.assertEqual(l1.prefix, "")
    118         n1 = pytree.Node(1000, [l1])
    119         self.assertEqual(n1.prefix, "")
    120         n1.prefix = " "
    121         self.assertEqual(n1.prefix, " ")
    122         self.assertEqual(l1.prefix, " ")
    123 
    124     def test_get_suffix(self):
    125         l1 = pytree.Leaf(100, "foo", prefix="a")
    126         l2 = pytree.Leaf(100, "bar", prefix="b")
    127         n1 = pytree.Node(1000, [l1, l2])
    128 
    129         self.assertEqual(l1.get_suffix(), l2.prefix)
    130         self.assertEqual(l2.get_suffix(), "")
    131         self.assertEqual(n1.get_suffix(), "")
    132 
    133         l3 = pytree.Leaf(100, "bar", prefix="c")
    134         n2 = pytree.Node(1000, [n1, l3])
    135 
    136         self.assertEqual(n1.get_suffix(), l3.prefix)
    137         self.assertEqual(l3.get_suffix(), "")
    138         self.assertEqual(n2.get_suffix(), "")
    139 
    140     def test_node_equality(self):
    141         n1 = pytree.Node(1000, ())
    142         n2 = pytree.Node(1000, [], context=(" ", (1, 0)))
    143         self.assertEqual(n1, n2)
    144         n3 = pytree.Node(1001, ())
    145         self.assertNotEqual(n1, n3)
    146 
    147     def test_node_recursive_equality(self):
    148         l1 = pytree.Leaf(100, "foo")
    149         l2 = pytree.Leaf(100, "foo")
    150         n1 = pytree.Node(1000, [l1])
    151         n2 = pytree.Node(1000, [l2])
    152         self.assertEqual(n1, n2)
    153         l3 = pytree.Leaf(100, "bar")
    154         n3 = pytree.Node(1000, [l3])
    155         self.assertNotEqual(n1, n3)
    156 
    157     def test_replace(self):
    158         l1 = pytree.Leaf(100, "foo")
    159         l2 = pytree.Leaf(100, "+")
    160         l3 = pytree.Leaf(100, "bar")
    161         n1 = pytree.Node(1000, [l1, l2, l3])
    162         self.assertEqual(n1.children, [l1, l2, l3])
    163         self.assertTrue(isinstance(n1.children, list))
    164         self.assertFalse(n1.was_changed)
    165         l2new = pytree.Leaf(100, "-")
    166         l2.replace(l2new)
    167         self.assertEqual(n1.children, [l1, l2new, l3])
    168         self.assertTrue(isinstance(n1.children, list))
    169         self.assertTrue(n1.was_changed)
    170 
    171     def test_replace_with_list(self):
    172         l1 = pytree.Leaf(100, "foo")
    173         l2 = pytree.Leaf(100, "+")
    174         l3 = pytree.Leaf(100, "bar")
    175         n1 = pytree.Node(1000, [l1, l2, l3])
    176 
    177         l2.replace([pytree.Leaf(100, "*"), pytree.Leaf(100, "*")])
    178         self.assertEqual(str(n1), "foo**bar")
    179         self.assertTrue(isinstance(n1.children, list))
    180 
    181     def test_leaves(self):
    182         l1 = pytree.Leaf(100, "foo")
    183         l2 = pytree.Leaf(100, "bar")
    184         l3 = pytree.Leaf(100, "fooey")
    185         n2 = pytree.Node(1000, [l1, l2])
    186         n3 = pytree.Node(1000, [l3])
    187         n1 = pytree.Node(1000, [n2, n3])
    188 
    189         self.assertEqual(list(n1.leaves()), [l1, l2, l3])
    190 
    191     def test_depth(self):
    192         l1 = pytree.Leaf(100, "foo")
    193         l2 = pytree.Leaf(100, "bar")
    194         n2 = pytree.Node(1000, [l1, l2])
    195         n3 = pytree.Node(1000, [])
    196         n1 = pytree.Node(1000, [n2, n3])
    197 
    198         self.assertEqual(l1.depth(), 2)
    199         self.assertEqual(n3.depth(), 1)
    200         self.assertEqual(n1.depth(), 0)
    201 
    202     def test_post_order(self):
    203         l1 = pytree.Leaf(100, "foo")
    204         l2 = pytree.Leaf(100, "bar")
    205         l3 = pytree.Leaf(100, "fooey")
    206         c1 = pytree.Node(1000, [l1, l2])
    207         n1 = pytree.Node(1000, [c1, l3])
    208         self.assertEqual(list(n1.post_order()), [l1, l2, c1, l3, n1])
    209 
    210     def test_pre_order(self):
    211         l1 = pytree.Leaf(100, "foo")
    212         l2 = pytree.Leaf(100, "bar")
    213         l3 = pytree.Leaf(100, "fooey")
    214         c1 = pytree.Node(1000, [l1, l2])
    215         n1 = pytree.Node(1000, [c1, l3])
    216         self.assertEqual(list(n1.pre_order()), [n1, c1, l1, l2, l3])
    217 
    218     def test_changed(self):
    219         l1 = pytree.Leaf(100, "f")
    220         self.assertFalse(l1.was_changed)
    221         l1.changed()
    222         self.assertTrue(l1.was_changed)
    223 
    224         l1 = pytree.Leaf(100, "f")
    225         n1 = pytree.Node(1000, [l1])
    226         self.assertFalse(n1.was_changed)
    227         n1.changed()
    228         self.assertTrue(n1.was_changed)
    229 
    230         l1 = pytree.Leaf(100, "foo")
    231         l2 = pytree.Leaf(100, "+")
    232         l3 = pytree.Leaf(100, "bar")
    233         n1 = pytree.Node(1000, [l1, l2, l3])
    234         n2 = pytree.Node(1000, [n1])
    235         self.assertFalse(l1.was_changed)
    236         self.assertFalse(n1.was_changed)
    237         self.assertFalse(n2.was_changed)
    238 
    239         n1.changed()
    240         self.assertTrue(n1.was_changed)
    241         self.assertTrue(n2.was_changed)
    242         self.assertFalse(l1.was_changed)
    243 
    244     def test_leaf_constructor_prefix(self):
    245         for prefix in ("xyz_", ""):
    246             l1 = pytree.Leaf(100, "self", prefix=prefix)
    247             self.assertTrue(str(l1), prefix + "self")
    248             self.assertEqual(l1.prefix, prefix)
    249 
    250     def test_node_constructor_prefix(self):
    251         for prefix in ("xyz_", ""):
    252             l1 = pytree.Leaf(100, "self")
    253             l2 = pytree.Leaf(100, "foo", prefix="_")
    254             n1 = pytree.Node(1000, [l1, l2], prefix=prefix)
    255             self.assertTrue(str(n1), prefix + "self_foo")
    256             self.assertEqual(n1.prefix, prefix)
    257             self.assertEqual(l1.prefix, prefix)
    258             self.assertEqual(l2.prefix, "_")
    259 
    260     def test_remove(self):
    261         l1 = pytree.Leaf(100, "foo")
    262         l2 = pytree.Leaf(100, "foo")
    263         n1 = pytree.Node(1000, [l1, l2])
    264         n2 = pytree.Node(1000, [n1])
    265 
    266         self.assertEqual(n1.remove(), 0)
    267         self.assertEqual(n2.children, [])
    268         self.assertEqual(l1.parent, n1)
    269         self.assertEqual(n1.parent, None)
    270         self.assertEqual(n2.parent, None)
    271         self.assertFalse(n1.was_changed)
    272         self.assertTrue(n2.was_changed)
    273 
    274         self.assertEqual(l2.remove(), 1)
    275         self.assertEqual(l1.remove(), 0)
    276         self.assertEqual(n1.children, [])
    277         self.assertEqual(l1.parent, None)
    278         self.assertEqual(n1.parent, None)
    279         self.assertEqual(n2.parent, None)
    280         self.assertTrue(n1.was_changed)
    281         self.assertTrue(n2.was_changed)
    282 
    283     def test_remove_parentless(self):
    284         n1 = pytree.Node(1000, [])
    285         n1.remove()
    286         self.assertEqual(n1.parent, None)
    287 
    288         l1 = pytree.Leaf(100, "foo")
    289         l1.remove()
    290         self.assertEqual(l1.parent, None)
    291 
    292     def test_node_set_child(self):
    293         l1 = pytree.Leaf(100, "foo")
    294         n1 = pytree.Node(1000, [l1])
    295 
    296         l2 = pytree.Leaf(100, "bar")
    297         n1.set_child(0, l2)
    298         self.assertEqual(l1.parent, None)
    299         self.assertEqual(l2.parent, n1)
    300         self.assertEqual(n1.children, [l2])
    301 
    302         n2 = pytree.Node(1000, [l1])
    303         n2.set_child(0, n1)
    304         self.assertEqual(l1.parent, None)
    305         self.assertEqual(n1.parent, n2)
    306         self.assertEqual(n2.parent, None)
    307         self.assertEqual(n2.children, [n1])
    308 
    309         self.assertRaises(IndexError, n1.set_child, 4, l2)
    310         # I don't care what it raises, so long as it's an exception
    311         self.assertRaises(Exception, n1.set_child, 0, list)
    312 
    313     def test_node_insert_child(self):
    314         l1 = pytree.Leaf(100, "foo")
    315         n1 = pytree.Node(1000, [l1])
    316 
    317         l2 = pytree.Leaf(100, "bar")
    318         n1.insert_child(0, l2)
    319         self.assertEqual(l2.parent, n1)
    320         self.assertEqual(n1.children, [l2, l1])
    321 
    322         l3 = pytree.Leaf(100, "abc")
    323         n1.insert_child(2, l3)
    324         self.assertEqual(n1.children, [l2, l1, l3])
    325 
    326         # I don't care what it raises, so long as it's an exception
    327         self.assertRaises(Exception, n1.insert_child, 0, list)
    328 
    329     def test_node_append_child(self):
    330         n1 = pytree.Node(1000, [])
    331 
    332         l1 = pytree.Leaf(100, "foo")
    333         n1.append_child(l1)
    334         self.assertEqual(l1.parent, n1)
    335         self.assertEqual(n1.children, [l1])
    336 
    337         l2 = pytree.Leaf(100, "bar")
    338         n1.append_child(l2)
    339         self.assertEqual(l2.parent, n1)
    340         self.assertEqual(n1.children, [l1, l2])
    341 
    342         # I don't care what it raises, so long as it's an exception
    343         self.assertRaises(Exception, n1.append_child, list)
    344 
    345     def test_node_next_sibling(self):
    346         n1 = pytree.Node(1000, [])
    347         n2 = pytree.Node(1000, [])
    348         p1 = pytree.Node(1000, [n1, n2])
    349 
    350         self.assertTrue(n1.next_sibling is n2)
    351         self.assertEqual(n2.next_sibling, None)
    352         self.assertEqual(p1.next_sibling, None)
    353 
    354     def test_leaf_next_sibling(self):
    355         l1 = pytree.Leaf(100, "a")
    356         l2 = pytree.Leaf(100, "b")
    357         p1 = pytree.Node(1000, [l1, l2])
    358 
    359         self.assertTrue(l1.next_sibling is l2)
    360         self.assertEqual(l2.next_sibling, None)
    361         self.assertEqual(p1.next_sibling, None)
    362 
    363     def test_node_prev_sibling(self):
    364         n1 = pytree.Node(1000, [])
    365         n2 = pytree.Node(1000, [])
    366         p1 = pytree.Node(1000, [n1, n2])
    367 
    368         self.assertTrue(n2.prev_sibling is n1)
    369         self.assertEqual(n1.prev_sibling, None)
    370         self.assertEqual(p1.prev_sibling, None)
    371 
    372     def test_leaf_prev_sibling(self):
    373         l1 = pytree.Leaf(100, "a")
    374         l2 = pytree.Leaf(100, "b")
    375         p1 = pytree.Node(1000, [l1, l2])
    376 
    377         self.assertTrue(l2.prev_sibling is l1)
    378         self.assertEqual(l1.prev_sibling, None)
    379         self.assertEqual(p1.prev_sibling, None)
    380 
    381 
    382 class TestPatterns(support.TestCase):
    383 
    384     """Unit tests for tree matching patterns."""
    385 
    386     def test_basic_patterns(self):
    387         # Build a tree
    388         l1 = pytree.Leaf(100, "foo")
    389         l2 = pytree.Leaf(100, "bar")
    390         l3 = pytree.Leaf(100, "foo")
    391         n1 = pytree.Node(1000, [l1, l2])
    392         n2 = pytree.Node(1000, [l3])
    393         root = pytree.Node(1000, [n1, n2])
    394         # Build a pattern matching a leaf
    395         pl = pytree.LeafPattern(100, "foo", name="pl")
    396         r = {}
    397         self.assertFalse(pl.match(root, results=r))
    398         self.assertEqual(r, {})
    399         self.assertFalse(pl.match(n1, results=r))
    400         self.assertEqual(r, {})
    401         self.assertFalse(pl.match(n2, results=r))
    402         self.assertEqual(r, {})
    403         self.assertTrue(pl.match(l1, results=r))
    404         self.assertEqual(r, {"pl": l1})
    405         r = {}
    406         self.assertFalse(pl.match(l2, results=r))
    407         self.assertEqual(r, {})
    408         # Build a pattern matching a node
    409         pn = pytree.NodePattern(1000, [pl], name="pn")
    410         self.assertFalse(pn.match(root, results=r))
    411         self.assertEqual(r, {})
    412         self.assertFalse(pn.match(n1, results=r))
    413         self.assertEqual(r, {})
    414         self.assertTrue(pn.match(n2, results=r))
    415         self.assertEqual(r, {"pn": n2, "pl": l3})
    416         r = {}
    417         self.assertFalse(pn.match(l1, results=r))
    418         self.assertEqual(r, {})
    419         self.assertFalse(pn.match(l2, results=r))
    420         self.assertEqual(r, {})
    421 
    422     def test_wildcard(self):
    423         # Build a tree for testing
    424         l1 = pytree.Leaf(100, "foo")
    425         l2 = pytree.Leaf(100, "bar")
    426         l3 = pytree.Leaf(100, "foo")
    427         n1 = pytree.Node(1000, [l1, l2])
    428         n2 = pytree.Node(1000, [l3])
    429         root = pytree.Node(1000, [n1, n2])
    430         # Build a pattern
    431         pl = pytree.LeafPattern(100, "foo", name="pl")
    432         pn = pytree.NodePattern(1000, [pl], name="pn")
    433         pw = pytree.WildcardPattern([[pn], [pl, pl]], name="pw")
    434         r = {}
    435         self.assertFalse(pw.match_seq([root], r))
    436         self.assertEqual(r, {})
    437         self.assertFalse(pw.match_seq([n1], r))
    438         self.assertEqual(r, {})
    439         self.assertTrue(pw.match_seq([n2], r))
    440         # These are easier to debug
    441         self.assertEqual(sorted(r.keys()), ["pl", "pn", "pw"])
    442         self.assertEqual(r["pl"], l1)
    443         self.assertEqual(r["pn"], n2)
    444         self.assertEqual(r["pw"], [n2])
    445         # But this is equivalent
    446         self.assertEqual(r, {"pl": l1, "pn": n2, "pw": [n2]})
    447         r = {}
    448         self.assertTrue(pw.match_seq([l1, l3], r))
    449         self.assertEqual(r, {"pl": l3, "pw": [l1, l3]})
    450         self.assertTrue(r["pl"] is l3)
    451         r = {}
    452 
    453     def test_generate_matches(self):
    454         la = pytree.Leaf(1, "a")
    455         lb = pytree.Leaf(1, "b")
    456         lc = pytree.Leaf(1, "c")
    457         ld = pytree.Leaf(1, "d")
    458         le = pytree.Leaf(1, "e")
    459         lf = pytree.Leaf(1, "f")
    460         leaves = [la, lb, lc, ld, le, lf]
    461         root = pytree.Node(1000, leaves)
    462         pa = pytree.LeafPattern(1, "a", "pa")
    463         pb = pytree.LeafPattern(1, "b", "pb")
    464         pc = pytree.LeafPattern(1, "c", "pc")
    465         pd = pytree.LeafPattern(1, "d", "pd")
    466         pe = pytree.LeafPattern(1, "e", "pe")
    467         pf = pytree.LeafPattern(1, "f", "pf")
    468         pw = pytree.WildcardPattern([[pa, pb, pc], [pd, pe],
    469                                      [pa, pb], [pc, pd], [pe, pf]],
    470                                     min=1, max=4, name="pw")
    471         self.assertEqual([x[0] for x in pw.generate_matches(leaves)],
    472                          [3, 5, 2, 4, 6])
    473         pr = pytree.NodePattern(type=1000, content=[pw], name="pr")
    474         matches = list(pytree.generate_matches([pr], [root]))
    475         self.assertEqual(len(matches), 1)
    476         c, r = matches[0]
    477         self.assertEqual(c, 1)
    478         self.assertEqual(str(r["pr"]), "abcdef")
    479         self.assertEqual(r["pw"], [la, lb, lc, ld, le, lf])
    480         for c in "abcdef":
    481             self.assertEqual(r["p" + c], pytree.Leaf(1, c))
    482 
    483     def test_has_key_example(self):
    484         pattern = pytree.NodePattern(331,
    485                                      (pytree.LeafPattern(7),
    486                                       pytree.WildcardPattern(name="args"),
    487                                       pytree.LeafPattern(8)))
    488         l1 = pytree.Leaf(7, "(")
    489         l2 = pytree.Leaf(3, "x")
    490         l3 = pytree.Leaf(8, ")")
    491         node = pytree.Node(331, [l1, l2, l3])
    492         r = {}
    493         self.assertTrue(pattern.match(node, r))
    494         self.assertEqual(r["args"], [l2])
    495