1
import pymake.data, pymake.parser, pymake.parserdata, pymake.functions
5
from cStringIO import StringIO
8
for name in cls.testdata.iterkeys():
9
def m(self, name=name):
10
return self.runSingle(*self.testdata[name])
12
setattr(cls, 'test_%s' % name, m)
15
class TestBase(unittest.TestCase):
16
def assertEqual(self, a, b, msg=""):
17
"""Actually print the values which weren't equal, if things don't work out!"""
18
unittest.TestCase.assertEqual(self, a, b, "%s got %r expected %r" % (msg, a, b))
20
class DataTest(TestBase):
23
("He\tllo", "f", 1, 0,
24
((0, "f", 1, 0), (2, "f", 1, 2), (3, "f", 1, 4))),
26
("line1 \n\tl\tine2", "f", 1, 4,
27
((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))),
30
def runSingle(self, data, filename, line, col, results):
31
d = pymake.parser.Data(data, 0, len(data), pymake.parserdata.Location(filename, line, col))
32
for pos, file, lineno, col in results:
34
self.assertEqual(loc.path, file, "data file offset %i" % pos)
35
self.assertEqual(loc.line, lineno, "data line offset %i" % pos)
36
self.assertEqual(loc.column, col, "data col offset %i" % pos)
39
class LineEnumeratorTest(TestBase):
47
'Hello\nhappy \n\nworld\n', [
56
'Hello, \\\n world\nJellybeans!', [
57
('Hello, \\\n world', 1),
62
'Hello, \\\\\n world', [
69
def runSingle(self, s, lines):
70
gotlines = [(d.s[d.lstart:d.lend], d.loc.line) for d in pymake.parser.enumeratelines(s, 'path')]
71
self.assertEqual(gotlines, lines)
73
multitest(LineEnumeratorTest)
75
class IterTest(TestBase):
78
pymake.parser.iterdata,
83
pymake.parser.itermakefilechars,
84
"VAR = val # comment",
87
'makeescapedcomment': (
88
pymake.parser.itermakefilechars,
89
"VAR = val \# escaped hash",
90
"VAR = val # escaped hash"
93
pymake.parser.itermakefilechars,
98
pymake.parser.itermakefilechars,
99
"VAR = VAL \\\n continuation # comment \\\n continuation",
100
"VAR = VAL continuation "
102
'makecontinuation2': (
103
pymake.parser.itermakefilechars,
104
"VAR = VAL \\ \\\n continuation",
105
"VAR = VAL \\ continuation"
108
pymake.parser.itermakefilechars,
109
"VAR = VAL \\\\# comment\n",
113
pymake.parser.itercommandchars,
114
"echo boo # comment",
115
"echo boo # comment",
118
pymake.parser.itercommandchars,
119
"echo boo \# comment",
120
"echo boo \# comment",
123
pymake.parser.itercommandchars,
124
"echo boo # \\\n\t command 2",
125
"echo boo # \\\n command 2"
129
def runSingle(self, ifunc, idata, expected):
130
d = pymake.parser.Data.fromstring(idata, 'IterTest data')
132
it = pymake.parser._alltokens.finditer(d.s, 0, d.lend)
133
actual = ''.join( [c for c, t, o, oo in ifunc(d, 0, ('dummy-token',), it)] )
134
self.assertEqual(actual, expected)
136
if ifunc == pymake.parser.itermakefilechars:
137
print "testing %r" % expected
138
self.assertEqual(pymake.parser.flattenmakesyntax(d, 0), expected)
144
# pymake.parser.iterdefinechars,
149
# pymake.parser.iterdefinechars,
150
# """define BAR # comment
152
#endef not what you think!
153
#endef # comment is ok\n""",
154
# """define BAR # comment
156
#endef not what you think!"""
159
# pymake.parser.iterdefinechars,
166
class MakeSyntaxTest(TestBase):
167
# (string, startat, stopat, stopoffset, expansion
169
'text': ('hello world', 0, (), None, ['hello world']),
170
'singlechar': ('hello $W', 0, (), None,
172
{'type': 'VariableRef',
175
'stopat': ('hello: world', 0, (':', '='), 6, ['hello']),
176
'funccall': ('h $(flavor FOO)', 0, (), None,
178
{'type': 'FlavorFunction',
181
'escapedollar': ('hello$$world', 0, (), None, ['hello$world']),
182
'varref': ('echo $(VAR)', 0, (), None,
184
{'type': 'VariableRef',
187
'dynamicvarname': ('echo $($(VARNAME):.c=.o)', 0, (':',), None,
189
{'type': 'SubstitutionRef',
190
'.vname': [{'type': 'VariableRef',
191
'.vname': ['VARNAME']}
193
'.substfrom': ['.c'],
196
'substref': (' $(VAR:VAL) := $(VAL)', 0, (':=', '+=', '=', ':'), 15,
198
{'type': 'VariableRef',
199
'.vname': ['VAR:VAL']},
201
'vadsubstref': (' $(VAR:VAL) = $(VAL)', 15, (), None,
202
[{'type': 'VariableRef',
207
def compareRecursive(self, actual, expected, path):
208
self.assertEqual(len(actual), len(expected),
209
"compareRecursive: %s %r" % (path, actual))
210
for i in xrange(0, len(actual)):
213
a, isfunc = actual[i]
215
if isinstance(e, str):
216
self.assertEqual(a, e, "compareRecursive: %s" % (ipath,))
218
self.assertEqual(type(a), getattr(pymake.functions, e['type']),
219
"compareRecursive: %s" % (ipath,))
220
for k, v in e.iteritems():
225
proppath = ipath + [item]
226
self.compareRecursive(a[item], v, proppath)
229
proppath = ipath + [item]
230
self.compareRecursive(getattr(a, item), v, proppath)
232
raise Exception("Unexpected property at %s: %s" % (ipath, k))
234
def runSingle(self, s, startat, stopat, stopoffset, expansion):
235
d = pymake.parser.Data.fromstring(s, pymake.parserdata.Location('testdata', 1, 0))
237
a, t, offset = pymake.parser.parsemakesyntax(d, startat, stopat, pymake.parser.itermakefilechars)
238
self.compareRecursive(a, expansion, [])
239
self.assertEqual(offset, stopoffset)
241
multitest(MakeSyntaxTest)
243
class VariableTest(TestBase):
247
$(VARNAME) = testvalue
248
$(VARNAME:VAR=VAL) = moretesting
249
IMM := $(VARNAME) # this is a comment
254
expected = {'VAR': 'value',
255
'VARNAME': 'newname',
256
'TESTVAR': 'testvalue',
257
'TESTVAL': 'moretesting',
259
'MULTIVAR': 'val1 val2',
263
stmts = pymake.parser.parsestring(self.testdata, 'VariableTest')
265
m = pymake.data.Makefile()
267
for k, v in self.expected.iteritems():
268
flavor, source, val = m.variables.get(k)
270
self.assertEqual(val, v, 'variable named %s' % k)
272
self.assertEqual(val.resolvestr(m, m.variables), v, 'variable named %s' % k)
274
class SimpleRuleTest(TestBase):
279
all:: test test2 $(VAR)
280
echo "Hello, $(TSPEC)"
287
stmts = pymake.parser.parsestring(self.testdata, 'SimpleRuleTest')
289
m = pymake.data.Makefile()
291
self.assertEqual(m.defaulttarget, 'all', "Default target")
293
self.assertTrue(m.hastarget('all'), "Has 'all' target")
294
target = m.gettarget('all')
296
self.assertEqual(len(rules), 1, "Number of rules")
297
prereqs = rules[0].prerequisites
298
self.assertEqual(prereqs, ['test', 'test2', 'value'], "Prerequisites")
299
commands = rules[0].commands
300
self.assertEqual(len(commands), 1, "Number of commands")
301
expanded = commands[0].resolvestr(m, target.variables)
302
self.assertEqual(expanded, 'echo "Hello, myrule"')
304
irules = m.implicitrules
305
self.assertEqual(len(irules), 1, "Number of implicit rules")
308
self.assertEqual(len(irule.targetpatterns), 1, "%.o target pattern count")
309
self.assertEqual(len(irule.prerequisites), 1, "%.o prerequisite count")
310
self.assertEqual(irule.targetpatterns[0].match('foo.o'), 'foo', "%.o stem")
312
if __name__ == '__main__':
313
logging.basicConfig(level=logging.DEBUG)