/build/pymake/tests/parsertests.py
http://github.com/zpao/v8monkey · Python · 314 lines · 262 code · 29 blank · 23 comment · 17 complexity · 55fb45866bf25b66d93181841d6dddca MD5 · raw file
- import pymake.data, pymake.parser, pymake.parserdata, pymake.functions
- import unittest
- import logging
- from cStringIO import StringIO
- def multitest(cls):
- for name in cls.testdata.iterkeys():
- def m(self, name=name):
- return self.runSingle(*self.testdata[name])
- setattr(cls, 'test_%s' % name, m)
- return cls
- class TestBase(unittest.TestCase):
- def assertEqual(self, a, b, msg=""):
- """Actually print the values which weren't equal, if things don't work out!"""
- unittest.TestCase.assertEqual(self, a, b, "%s got %r expected %r" % (msg, a, b))
- class DataTest(TestBase):
- testdata = {
- 'oneline':
- ("He\tllo", "f", 1, 0,
- ((0, "f", 1, 0), (2, "f", 1, 2), (3, "f", 1, 4))),
- 'twoline':
- ("line1 \n\tl\tine2", "f", 1, 4,
- ((0, "f", 1, 4), (5, "f", 1, 9), (6, "f", 1, 10), (7, "f", 2, 0), (8, "f", 2, 4), (10, "f", 2, 8), (13, "f", 2, 11))),
- }
- def runSingle(self, data, filename, line, col, results):
- d = pymake.parser.Data(data, 0, len(data), pymake.parserdata.Location(filename, line, col))
- for pos, file, lineno, col in results:
- loc = d.getloc(pos)
- self.assertEqual(loc.path, file, "data file offset %i" % pos)
- self.assertEqual(loc.line, lineno, "data line offset %i" % pos)
- self.assertEqual(loc.column, col, "data col offset %i" % pos)
- multitest(DataTest)
- class LineEnumeratorTest(TestBase):
- testdata = {
- 'simple': (
- 'Hello, world', [
- ('Hello, world', 1),
- ]
- ),
- 'multi': (
- 'Hello\nhappy \n\nworld\n', [
- ('Hello', 1),
- ('happy ', 2),
- ('', 3),
- ('world', 4),
- ('', 5),
- ]
- ),
- 'continuation': (
- 'Hello, \\\n world\nJellybeans!', [
- ('Hello, \\\n world', 1),
- ('Jellybeans!', 3),
- ]
- ),
- 'multislash': (
- 'Hello, \\\\\n world', [
- ('Hello, \\\\', 1),
- (' world', 2),
- ]
- )
- }
- def runSingle(self, s, lines):
- gotlines = [(d.s[d.lstart:d.lend], d.loc.line) for d in pymake.parser.enumeratelines(s, 'path')]
- self.assertEqual(gotlines, lines)
- multitest(LineEnumeratorTest)
- class IterTest(TestBase):
- testdata = {
- 'plaindata': (
- pymake.parser.iterdata,
- "plaindata # test\n",
- "plaindata # test\n"
- ),
- 'makecomment': (
- pymake.parser.itermakefilechars,
- "VAR = val # comment",
- "VAR = val "
- ),
- 'makeescapedcomment': (
- pymake.parser.itermakefilechars,
- "VAR = val \# escaped hash",
- "VAR = val # escaped hash"
- ),
- 'makeescapedslash': (
- pymake.parser.itermakefilechars,
- "VAR = val\\\\",
- "VAR = val\\\\",
- ),
- 'makecontinuation': (
- pymake.parser.itermakefilechars,
- "VAR = VAL \\\n continuation # comment \\\n continuation",
- "VAR = VAL continuation "
- ),
- 'makecontinuation2': (
- pymake.parser.itermakefilechars,
- "VAR = VAL \\ \\\n continuation",
- "VAR = VAL \\ continuation"
- ),
- 'makeawful': (
- pymake.parser.itermakefilechars,
- "VAR = VAL \\\\# comment\n",
- "VAR = VAL \\"
- ),
- 'command': (
- pymake.parser.itercommandchars,
- "echo boo # comment",
- "echo boo # comment",
- ),
- 'commandcomment': (
- pymake.parser.itercommandchars,
- "echo boo \# comment",
- "echo boo \# comment",
- ),
- 'commandcontinue': (
- pymake.parser.itercommandchars,
- "echo boo # \\\n\t command 2",
- "echo boo # \\\n command 2"
- ),
- }
- def runSingle(self, ifunc, idata, expected):
- d = pymake.parser.Data.fromstring(idata, 'IterTest data')
- it = pymake.parser._alltokens.finditer(d.s, 0, d.lend)
- actual = ''.join( [c for c, t, o, oo in ifunc(d, 0, ('dummy-token',), it)] )
- self.assertEqual(actual, expected)
- if ifunc == pymake.parser.itermakefilechars:
- print "testing %r" % expected
- self.assertEqual(pymake.parser.flattenmakesyntax(d, 0), expected)
- multitest(IterTest)
- # 'define': (
- # pymake.parser.iterdefinechars,
- # "endef",
- # ""
- # ),
- # 'definenesting': (
- # pymake.parser.iterdefinechars,
- # """define BAR # comment
- #random text
- #endef not what you think!
- #endef # comment is ok\n""",
- # """define BAR # comment
- #random text
- #endef not what you think!"""
- # ),
- # 'defineescaped': (
- # pymake.parser.iterdefinechars,
- # """value \\
- #endef
- #endef\n""",
- # "value endef"
- # ),
- class MakeSyntaxTest(TestBase):
- # (string, startat, stopat, stopoffset, expansion
- testdata = {
- 'text': ('hello world', 0, (), None, ['hello world']),
- 'singlechar': ('hello $W', 0, (), None,
- ['hello ',
- {'type': 'VariableRef',
- '.vname': ['W']}
- ]),
- 'stopat': ('hello: world', 0, (':', '='), 6, ['hello']),
- 'funccall': ('h $(flavor FOO)', 0, (), None,
- ['h ',
- {'type': 'FlavorFunction',
- '[0]': ['FOO']}
- ]),
- 'escapedollar': ('hello$$world', 0, (), None, ['hello$world']),
- 'varref': ('echo $(VAR)', 0, (), None,
- ['echo ',
- {'type': 'VariableRef',
- '.vname': ['VAR']}
- ]),
- 'dynamicvarname': ('echo $($(VARNAME):.c=.o)', 0, (':',), None,
- ['echo ',
- {'type': 'SubstitutionRef',
- '.vname': [{'type': 'VariableRef',
- '.vname': ['VARNAME']}
- ],
- '.substfrom': ['.c'],
- '.substto': ['.o']}
- ]),
- 'substref': (' $(VAR:VAL) := $(VAL)', 0, (':=', '+=', '=', ':'), 15,
- [' ',
- {'type': 'VariableRef',
- '.vname': ['VAR:VAL']},
- ' ']),
- 'vadsubstref': (' $(VAR:VAL) = $(VAL)', 15, (), None,
- [{'type': 'VariableRef',
- '.vname': ['VAL']},
- ]),
- }
- def compareRecursive(self, actual, expected, path):
- self.assertEqual(len(actual), len(expected),
- "compareRecursive: %s %r" % (path, actual))
- for i in xrange(0, len(actual)):
- ipath = path + [i]
- a, isfunc = actual[i]
- e = expected[i]
- if isinstance(e, str):
- self.assertEqual(a, e, "compareRecursive: %s" % (ipath,))
- else:
- self.assertEqual(type(a), getattr(pymake.functions, e['type']),
- "compareRecursive: %s" % (ipath,))
- for k, v in e.iteritems():
- if k == 'type':
- pass
- elif k[0] == '[':
- item = int(k[1:-1])
- proppath = ipath + [item]
- self.compareRecursive(a[item], v, proppath)
- elif k[0] == '.':
- item = k[1:]
- proppath = ipath + [item]
- self.compareRecursive(getattr(a, item), v, proppath)
- else:
- raise Exception("Unexpected property at %s: %s" % (ipath, k))
- def runSingle(self, s, startat, stopat, stopoffset, expansion):
- d = pymake.parser.Data.fromstring(s, pymake.parserdata.Location('testdata', 1, 0))
- a, t, offset = pymake.parser.parsemakesyntax(d, startat, stopat, pymake.parser.itermakefilechars)
- self.compareRecursive(a, expansion, [])
- self.assertEqual(offset, stopoffset)
- multitest(MakeSyntaxTest)
- class VariableTest(TestBase):
- testdata = """
- VAR = value
- VARNAME = TESTVAR
- $(VARNAME) = testvalue
- $(VARNAME:VAR=VAL) = moretesting
- IMM := $(VARNAME) # this is a comment
- MULTIVAR = val1 \\
- val2
- VARNAME = newname
- """
- expected = {'VAR': 'value',
- 'VARNAME': 'newname',
- 'TESTVAR': 'testvalue',
- 'TESTVAL': 'moretesting',
- 'IMM': 'TESTVAR ',
- 'MULTIVAR': 'val1 val2',
- 'UNDEF': None}
- def runTest(self):
- stmts = pymake.parser.parsestring(self.testdata, 'VariableTest')
- m = pymake.data.Makefile()
- stmts.execute(m)
- for k, v in self.expected.iteritems():
- flavor, source, val = m.variables.get(k)
- if val is None:
- self.assertEqual(val, v, 'variable named %s' % k)
- else:
- self.assertEqual(val.resolvestr(m, m.variables), v, 'variable named %s' % k)
- class SimpleRuleTest(TestBase):
- testdata = """
- VAR = value
- TSPEC = dummy
- all: TSPEC = myrule
- all:: test test2 $(VAR)
- echo "Hello, $(TSPEC)"
- %.o: %.c
- $(CC) -o $@ $<
- """
- def runTest(self):
- stmts = pymake.parser.parsestring(self.testdata, 'SimpleRuleTest')
- m = pymake.data.Makefile()
- stmts.execute(m)
- self.assertEqual(m.defaulttarget, 'all', "Default target")
- self.assertTrue(m.hastarget('all'), "Has 'all' target")
- target = m.gettarget('all')
- rules = target.rules
- self.assertEqual(len(rules), 1, "Number of rules")
- prereqs = rules[0].prerequisites
- self.assertEqual(prereqs, ['test', 'test2', 'value'], "Prerequisites")
- commands = rules[0].commands
- self.assertEqual(len(commands), 1, "Number of commands")
- expanded = commands[0].resolvestr(m, target.variables)
- self.assertEqual(expanded, 'echo "Hello, myrule"')
- irules = m.implicitrules
- self.assertEqual(len(irules), 1, "Number of implicit rules")
- irule = irules[0]
- self.assertEqual(len(irule.targetpatterns), 1, "%.o target pattern count")
- self.assertEqual(len(irule.prerequisites), 1, "%.o prerequisite count")
- self.assertEqual(irule.targetpatterns[0].match('foo.o'), 'foo', "%.o stem")
- if __name__ == '__main__':
- logging.basicConfig(level=logging.DEBUG)
- unittest.main()