| # -*- coding: utf-8 -*- |
| |
| import os |
| import unittest |
| from StringIO import StringIO |
| |
| from antlr3.tree import CommonTreeAdaptor, CommonTree, INVALID_TOKEN_TYPE |
| from antlr3.treewizard import TreeWizard, computeTokenTypes, \ |
| TreePatternLexer, EOF, ID, BEGIN, END, PERCENT, COLON, DOT, ARG, \ |
| TreePatternParser, \ |
| TreePattern, WildcardTreePattern, TreePatternTreeAdaptor |
| |
| |
| class TestComputeTokenTypes(unittest.TestCase): |
| """Test case for the computeTokenTypes function.""" |
| |
| def testNone(self): |
| """computeTokenTypes(None) -> {}""" |
| |
| typeMap = computeTokenTypes(None) |
| self.failUnless(isinstance(typeMap, dict)) |
| self.failUnlessEqual(typeMap, {}) |
| |
| |
| def testList(self): |
| """computeTokenTypes(['a', 'b']) -> { 'a': 0, 'b': 1 }""" |
| |
| typeMap = computeTokenTypes(['a', 'b']) |
| self.failUnless(isinstance(typeMap, dict)) |
| self.failUnlessEqual(typeMap, { 'a': 0, 'b': 1 }) |
| |
| |
| class TestTreePatternLexer(unittest.TestCase): |
| """Test case for the TreePatternLexer class.""" |
| |
| def testBegin(self): |
| """TreePatternLexer(): '('""" |
| |
| lexer = TreePatternLexer('(') |
| type = lexer.nextToken() |
| self.failUnlessEqual(type, BEGIN) |
| self.failUnlessEqual(lexer.sval, '') |
| self.failUnlessEqual(lexer.error, False) |
| |
| |
| def testEnd(self): |
| """TreePatternLexer(): ')'""" |
| |
| lexer = TreePatternLexer(')') |
| type = lexer.nextToken() |
| self.failUnlessEqual(type, END) |
| self.failUnlessEqual(lexer.sval, '') |
| self.failUnlessEqual(lexer.error, False) |
| |
| |
| def testPercent(self): |
| """TreePatternLexer(): '%'""" |
| |
| lexer = TreePatternLexer('%') |
| type = lexer.nextToken() |
| self.failUnlessEqual(type, PERCENT) |
| self.failUnlessEqual(lexer.sval, '') |
| self.failUnlessEqual(lexer.error, False) |
| |
| |
| def testDot(self): |
| """TreePatternLexer(): '.'""" |
| |
| lexer = TreePatternLexer('.') |
| type = lexer.nextToken() |
| self.failUnlessEqual(type, DOT) |
| self.failUnlessEqual(lexer.sval, '') |
| self.failUnlessEqual(lexer.error, False) |
| |
| |
| def testColon(self): |
| """TreePatternLexer(): ':'""" |
| |
| lexer = TreePatternLexer(':') |
| type = lexer.nextToken() |
| self.failUnlessEqual(type, COLON) |
| self.failUnlessEqual(lexer.sval, '') |
| self.failUnlessEqual(lexer.error, False) |
| |
| |
| def testEOF(self): |
| """TreePatternLexer(): EOF""" |
| |
| lexer = TreePatternLexer(' \n \r \t ') |
| type = lexer.nextToken() |
| self.failUnlessEqual(type, EOF) |
| self.failUnlessEqual(lexer.sval, '') |
| self.failUnlessEqual(lexer.error, False) |
| |
| |
| def testID(self): |
| """TreePatternLexer(): ID""" |
| |
| lexer = TreePatternLexer('_foo12_bar') |
| type = lexer.nextToken() |
| self.failUnlessEqual(type, ID) |
| self.failUnlessEqual(lexer.sval, '_foo12_bar') |
| self.failUnlessEqual(lexer.error, False) |
| |
| |
| def testARG(self): |
| """TreePatternLexer(): ARG""" |
| |
| lexer = TreePatternLexer('[ \\]bla\\n]') |
| type = lexer.nextToken() |
| self.failUnlessEqual(type, ARG) |
| self.failUnlessEqual(lexer.sval, ' ]bla\\n') |
| self.failUnlessEqual(lexer.error, False) |
| |
| |
| def testError(self): |
| """TreePatternLexer(): error""" |
| |
| lexer = TreePatternLexer('1') |
| type = lexer.nextToken() |
| self.failUnlessEqual(type, EOF) |
| self.failUnlessEqual(lexer.sval, '') |
| self.failUnlessEqual(lexer.error, True) |
| |
| |
| class TestTreePatternParser(unittest.TestCase): |
| """Test case for the TreePatternParser class.""" |
| |
| def setUp(self): |
| """Setup text fixure |
| |
| We need a tree adaptor, use CommonTreeAdaptor. |
| And a constant list of token names. |
| |
| """ |
| |
| self.adaptor = CommonTreeAdaptor() |
| self.tokens = [ |
| "", "", "", "", "", "A", "B", "C", "D", "E", "ID", "VAR" |
| ] |
| self.wizard = TreeWizard(self.adaptor, tokenNames=self.tokens) |
| |
| |
| def testSingleNode(self): |
| """TreePatternParser: 'ID'""" |
| lexer = TreePatternLexer('ID') |
| parser = TreePatternParser(lexer, self.wizard, self.adaptor) |
| tree = parser.pattern() |
| self.failUnless(isinstance(tree, CommonTree)) |
| self.failUnlessEqual(tree.getType(), 10) |
| self.failUnlessEqual(tree.getText(), 'ID') |
| |
| |
| def testSingleNodeWithArg(self): |
| """TreePatternParser: 'ID[foo]'""" |
| lexer = TreePatternLexer('ID[foo]') |
| parser = TreePatternParser(lexer, self.wizard, self.adaptor) |
| tree = parser.pattern() |
| self.failUnless(isinstance(tree, CommonTree)) |
| self.failUnlessEqual(tree.getType(), 10) |
| self.failUnlessEqual(tree.getText(), 'foo') |
| |
| |
| def testSingleLevelTree(self): |
| """TreePatternParser: '(A B)'""" |
| lexer = TreePatternLexer('(A B)') |
| parser = TreePatternParser(lexer, self.wizard, self.adaptor) |
| tree = parser.pattern() |
| self.failUnless(isinstance(tree, CommonTree)) |
| self.failUnlessEqual(tree.getType(), 5) |
| self.failUnlessEqual(tree.getText(), 'A') |
| self.failUnlessEqual(tree.getChildCount(), 1) |
| self.failUnlessEqual(tree.getChild(0).getType(), 6) |
| self.failUnlessEqual(tree.getChild(0).getText(), 'B') |
| |
| |
| def testNil(self): |
| """TreePatternParser: 'nil'""" |
| lexer = TreePatternLexer('nil') |
| parser = TreePatternParser(lexer, self.wizard, self.adaptor) |
| tree = parser.pattern() |
| self.failUnless(isinstance(tree, CommonTree)) |
| self.failUnlessEqual(tree.getType(), 0) |
| self.failUnlessEqual(tree.getText(), None) |
| |
| |
| def testWildcard(self): |
| """TreePatternParser: '(.)'""" |
| lexer = TreePatternLexer('(.)') |
| parser = TreePatternParser(lexer, self.wizard, self.adaptor) |
| tree = parser.pattern() |
| self.failUnless(isinstance(tree, WildcardTreePattern)) |
| |
| |
| def testLabel(self): |
| """TreePatternParser: '(%a:A)'""" |
| lexer = TreePatternLexer('(%a:A)') |
| parser = TreePatternParser(lexer, self.wizard, TreePatternTreeAdaptor()) |
| tree = parser.pattern() |
| self.failUnless(isinstance(tree, TreePattern)) |
| self.failUnlessEqual(tree.label, 'a') |
| |
| |
| def testError1(self): |
| """TreePatternParser: ')'""" |
| lexer = TreePatternLexer(')') |
| parser = TreePatternParser(lexer, self.wizard, self.adaptor) |
| tree = parser.pattern() |
| self.failUnless(tree is None) |
| |
| |
| def testError2(self): |
| """TreePatternParser: '()'""" |
| lexer = TreePatternLexer('()') |
| parser = TreePatternParser(lexer, self.wizard, self.adaptor) |
| tree = parser.pattern() |
| self.failUnless(tree is None) |
| |
| |
| def testError3(self): |
| """TreePatternParser: '(A ])'""" |
| lexer = TreePatternLexer('(A ])') |
| parser = TreePatternParser(lexer, self.wizard, self.adaptor) |
| tree = parser.pattern() |
| self.failUnless(tree is None) |
| |
| |
| class TestTreeWizard(unittest.TestCase): |
| """Test case for the TreeWizard class.""" |
| |
| def setUp(self): |
| """Setup text fixure |
| |
| We need a tree adaptor, use CommonTreeAdaptor. |
| And a constant list of token names. |
| |
| """ |
| |
| self.adaptor = CommonTreeAdaptor() |
| self.tokens = [ |
| "", "", "", "", "", "A", "B", "C", "D", "E", "ID", "VAR" |
| ] |
| |
| |
| def testInit(self): |
| """TreeWizard.__init__()""" |
| |
| wiz = TreeWizard( |
| self.adaptor, |
| tokenNames=['a', 'b'] |
| ) |
| |
| self.failUnless(wiz.adaptor is self.adaptor) |
| self.failUnlessEqual( |
| wiz.tokenNameToTypeMap, |
| { 'a': 0, 'b': 1 } |
| ) |
| |
| |
| def testGetTokenType(self): |
| """TreeWizard.getTokenType()""" |
| |
| wiz = TreeWizard( |
| self.adaptor, |
| tokenNames=self.tokens |
| ) |
| |
| self.failUnlessEqual( |
| wiz.getTokenType('A'), |
| 5 |
| ) |
| |
| self.failUnlessEqual( |
| wiz.getTokenType('VAR'), |
| 11 |
| ) |
| |
| self.failUnlessEqual( |
| wiz.getTokenType('invalid'), |
| INVALID_TOKEN_TYPE |
| ) |
| |
| def testSingleNode(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| t = wiz.create("ID") |
| found = t.toStringTree() |
| expecting = "ID" |
| self.failUnlessEqual(expecting, found) |
| |
| |
| def testSingleNodeWithArg(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| t = wiz.create("ID[foo]") |
| found = t.toStringTree() |
| expecting = "foo" |
| self.failUnlessEqual(expecting, found) |
| |
| |
| def testSingleNodeTree(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| t = wiz.create("(A)") |
| found = t.toStringTree() |
| expecting = "A" |
| self.failUnlessEqual(expecting, found) |
| |
| |
| def testSingleLevelTree(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| t = wiz.create("(A B C D)") |
| found = t.toStringTree() |
| expecting = "(A B C D)" |
| self.failUnlessEqual(expecting, found) |
| |
| |
| def testListTree(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| t = wiz.create("(nil A B C)") |
| found = t.toStringTree() |
| expecting = "A B C" |
| self.failUnlessEqual(expecting, found) |
| |
| |
| def testInvalidListTree(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| t = wiz.create("A B C") |
| self.failUnless(t is None) |
| |
| |
| def testDoubleLevelTree(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| t = wiz.create("(A (B C) (B D) E)") |
| found = t.toStringTree() |
| expecting = "(A (B C) (B D) E)" |
| self.failUnlessEqual(expecting, found) |
| |
| |
| def __simplifyIndexMap(self, indexMap): |
| return dict( # stringify nodes for easy comparing |
| (ttype, [str(node) for node in nodes]) |
| for ttype, nodes in indexMap.items() |
| ) |
| |
| def testSingleNodeIndex(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| tree = wiz.create("ID") |
| indexMap = wiz.index(tree) |
| found = self.__simplifyIndexMap(indexMap) |
| expecting = { 10: ["ID"] } |
| self.failUnlessEqual(expecting, found) |
| |
| |
| def testNoRepeatsIndex(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| tree = wiz.create("(A B C D)") |
| indexMap = wiz.index(tree) |
| found = self.__simplifyIndexMap(indexMap) |
| expecting = { 8:['D'], 6:['B'], 7:['C'], 5:['A'] } |
| self.failUnlessEqual(expecting, found) |
| |
| |
| def testRepeatsIndex(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| tree = wiz.create("(A B (A C B) B D D)") |
| indexMap = wiz.index(tree) |
| found = self.__simplifyIndexMap(indexMap) |
| expecting = { 8: ['D', 'D'], 6: ['B', 'B', 'B'], 7: ['C'], 5: ['A', 'A'] } |
| self.failUnlessEqual(expecting, found) |
| |
| |
| def testNoRepeatsVisit(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| tree = wiz.create("(A B C D)") |
| |
| elements = [] |
| def visitor(node, parent, childIndex, labels): |
| elements.append(str(node)) |
| |
| wiz.visit(tree, wiz.getTokenType("B"), visitor) |
| |
| expecting = ['B'] |
| self.failUnlessEqual(expecting, elements) |
| |
| |
| def testNoRepeatsVisit2(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| tree = wiz.create("(A B (A C B) B D D)") |
| |
| elements = [] |
| def visitor(node, parent, childIndex, labels): |
| elements.append(str(node)) |
| |
| wiz.visit(tree, wiz.getTokenType("C"), visitor) |
| |
| expecting = ['C'] |
| self.failUnlessEqual(expecting, elements) |
| |
| |
| def testRepeatsVisit(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| tree = wiz.create("(A B (A C B) B D D)") |
| |
| elements = [] |
| def visitor(node, parent, childIndex, labels): |
| elements.append(str(node)) |
| |
| wiz.visit(tree, wiz.getTokenType("B"), visitor) |
| |
| expecting = ['B', 'B', 'B'] |
| self.failUnlessEqual(expecting, elements) |
| |
| |
| def testRepeatsVisit2(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| tree = wiz.create("(A B (A C B) B D D)") |
| |
| elements = [] |
| def visitor(node, parent, childIndex, labels): |
| elements.append(str(node)) |
| |
| wiz.visit(tree, wiz.getTokenType("A"), visitor) |
| |
| expecting = ['A', 'A'] |
| self.failUnlessEqual(expecting, elements) |
| |
| |
| def testRepeatsVisitWithContext(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| tree = wiz.create("(A B (A C B) B D D)") |
| |
| elements = [] |
| def visitor(node, parent, childIndex, labels): |
| elements.append('%s@%s[%d]' % (node, parent, childIndex)) |
| |
| wiz.visit(tree, wiz.getTokenType("B"), visitor) |
| |
| expecting = ['B@A[0]', 'B@A[1]', 'B@A[2]'] |
| self.failUnlessEqual(expecting, elements) |
| |
| |
| def testRepeatsVisitWithNullParentAndContext(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| tree = wiz.create("(A B (A C B) B D D)") |
| |
| elements = [] |
| def visitor(node, parent, childIndex, labels): |
| elements.append( |
| '%s@%s[%d]' |
| % (node, ['nil', parent][parent is not None], childIndex) |
| ) |
| |
| wiz.visit(tree, wiz.getTokenType("A"), visitor) |
| |
| expecting = ['A@nil[0]', 'A@A[1]'] |
| self.failUnlessEqual(expecting, elements) |
| |
| |
| def testVisitPattern(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| tree = wiz.create("(A B C (A B) D)") |
| |
| elements = [] |
| def visitor(node, parent, childIndex, labels): |
| elements.append( |
| str(node) |
| ) |
| |
| wiz.visit(tree, '(A B)', visitor) |
| |
| expecting = ['A'] # shouldn't match overall root, just (A B) |
| self.failUnlessEqual(expecting, elements) |
| |
| |
| def testVisitPatternMultiple(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| tree = wiz.create("(A B C (A B) (D (A B)))") |
| |
| elements = [] |
| def visitor(node, parent, childIndex, labels): |
| elements.append( |
| '%s@%s[%d]' |
| % (node, ['nil', parent][parent is not None], childIndex) |
| ) |
| |
| wiz.visit(tree, '(A B)', visitor) |
| |
| expecting = ['A@A[2]', 'A@D[0]'] |
| self.failUnlessEqual(expecting, elements) |
| |
| |
| def testVisitPatternMultipleWithLabels(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| tree = wiz.create("(A B C (A[foo] B[bar]) (D (A[big] B[dog])))") |
| |
| elements = [] |
| def visitor(node, parent, childIndex, labels): |
| elements.append( |
| '%s@%s[%d]%s&%s' |
| % (node, |
| ['nil', parent][parent is not None], |
| childIndex, |
| labels['a'], |
| labels['b'], |
| ) |
| ) |
| |
| wiz.visit(tree, '(%a:A %b:B)', visitor) |
| |
| expecting = ['foo@A[2]foo&bar', 'big@D[0]big&dog'] |
| self.failUnlessEqual(expecting, elements) |
| |
| |
| def testParse(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| t = wiz.create("(A B C)") |
| valid = wiz.parse(t, "(A B C)") |
| self.failUnless(valid) |
| |
| |
| def testParseSingleNode(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| t = wiz.create("A") |
| valid = wiz.parse(t, "A") |
| self.failUnless(valid) |
| |
| |
| def testParseSingleNodeFails(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| t = wiz.create("A") |
| valid = wiz.parse(t, "B") |
| self.failUnless(not valid) |
| |
| |
| def testParseFlatTree(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| t = wiz.create("(nil A B C)") |
| valid = wiz.parse(t, "(nil A B C)") |
| self.failUnless(valid) |
| |
| |
| def testParseFlatTreeFails(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| t = wiz.create("(nil A B C)") |
| valid = wiz.parse(t, "(nil A B)") |
| self.failUnless(not valid) |
| |
| |
| def testParseFlatTreeFails2(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| t = wiz.create("(nil A B C)") |
| valid = wiz.parse(t, "(nil A B A)") |
| self.failUnless(not valid) |
| |
| |
| def testWildcard(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| t = wiz.create("(A B C)") |
| valid = wiz.parse(t, "(A . .)") |
| self.failUnless(valid) |
| |
| |
| def testParseWithText(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| t = wiz.create("(A B[foo] C[bar])") |
| # C pattern has no text arg so despite [bar] in t, no need |
| # to match text--check structure only. |
| valid = wiz.parse(t, "(A B[foo] C)") |
| self.failUnless(valid) |
| |
| |
| def testParseWithText2(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| t = wiz.create("(A B[T__32] (C (D E[a])))") |
| # C pattern has no text arg so despite [bar] in t, no need |
| # to match text--check structure only. |
| valid = wiz.parse(t, "(A B[foo] C)") |
| self.assertEquals("(A T__32 (C (D a)))", t.toStringTree()) |
| |
| |
| def testParseWithTextFails(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| t = wiz.create("(A B C)") |
| valid = wiz.parse(t, "(A[foo] B C)") |
| self.failUnless(not valid) # fails |
| |
| |
| def testParseLabels(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| t = wiz.create("(A B C)") |
| labels = {} |
| valid = wiz.parse(t, "(%a:A %b:B %c:C)", labels) |
| self.failUnless(valid) |
| self.failUnlessEqual("A", str(labels["a"])) |
| self.failUnlessEqual("B", str(labels["b"])) |
| self.failUnlessEqual("C", str(labels["c"])) |
| |
| |
| def testParseWithWildcardLabels(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| t = wiz.create("(A B C)") |
| labels = {} |
| valid = wiz.parse(t, "(A %b:. %c:.)", labels) |
| self.failUnless(valid) |
| self.failUnlessEqual("B", str(labels["b"])) |
| self.failUnlessEqual("C", str(labels["c"])) |
| |
| |
| def testParseLabelsAndTestText(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| t = wiz.create("(A B[foo] C)") |
| labels = {} |
| valid = wiz.parse(t, "(%a:A %b:B[foo] %c:C)", labels) |
| self.failUnless(valid) |
| self.failUnlessEqual("A", str(labels["a"])) |
| self.failUnlessEqual("foo", str(labels["b"])) |
| self.failUnlessEqual("C", str(labels["c"])) |
| |
| |
| def testParseLabelsInNestedTree(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| t = wiz.create("(A (B C) (D E))") |
| labels = {} |
| valid = wiz.parse(t, "(%a:A (%b:B %c:C) (%d:D %e:E) )", labels) |
| self.failUnless(valid) |
| self.failUnlessEqual("A", str(labels["a"])) |
| self.failUnlessEqual("B", str(labels["b"])) |
| self.failUnlessEqual("C", str(labels["c"])) |
| self.failUnlessEqual("D", str(labels["d"])) |
| self.failUnlessEqual("E", str(labels["e"])) |
| |
| |
| def testEquals(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| t1 = wiz.create("(A B C)") |
| t2 = wiz.create("(A B C)") |
| same = wiz.equals(t1, t2) |
| self.failUnless(same) |
| |
| |
| def testEqualsWithText(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| t1 = wiz.create("(A B[foo] C)") |
| t2 = wiz.create("(A B[foo] C)") |
| same = wiz.equals(t1, t2) |
| self.failUnless(same) |
| |
| |
| def testEqualsWithMismatchedText(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| t1 = wiz.create("(A B[foo] C)") |
| t2 = wiz.create("(A B C)") |
| same = wiz.equals(t1, t2) |
| self.failUnless(not same) |
| |
| |
| def testEqualsWithMismatchedList(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| t1 = wiz.create("(A B C)") |
| t2 = wiz.create("(A B A)") |
| same = wiz.equals(t1, t2) |
| self.failUnless(not same) |
| |
| |
| def testEqualsWithMismatchedListLength(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| t1 = wiz.create("(A B C)") |
| t2 = wiz.create("(A B)") |
| same = wiz.equals(t1, t2) |
| self.failUnless(not same) |
| |
| |
| def testFindPattern(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| t = wiz.create("(A B C (A[foo] B[bar]) (D (A[big] B[dog])))") |
| subtrees = wiz.find(t, "(A B)") |
| found = [str(node) for node in subtrees] |
| expecting = ['foo', 'big'] |
| self.failUnlessEqual(expecting, found) |
| |
| |
| def testFindTokenType(self): |
| wiz = TreeWizard(self.adaptor, self.tokens) |
| t = wiz.create("(A B C (A[foo] B[bar]) (D (A[big] B[dog])))") |
| subtrees = wiz.find(t, wiz.getTokenType('A')) |
| found = [str(node) for node in subtrees] |
| expecting = ['A', 'foo', 'big'] |
| self.failUnlessEqual(expecting, found) |
| |
| |
| |
| if __name__ == "__main__": |
| unittest.main(testRunner=unittest.TextTestRunner(verbosity=2)) |