~ubuntu-branches/ubuntu/oneiric/enigmail/oneiric-updates

« back to all changes in this revision

Viewing changes to build/pymake/tests/parsertests.py

  • Committer: Bazaar Package Importer
  • Author(s): Alexander Sack
  • Date: 2010-04-10 01:42:24 UTC
  • Revision ID: james.westby@ubuntu.com-20100410014224-fbq9ui5x3b0h2t36
Tags: 2:1.0.1-0ubuntu1
* First releaase of enigmail 1.0.1 for tbird/icedove 3
  (LP: #527138)
* redo packaging from scratch 
  + add debian/make-orig target that uses xulrunner provided
    buildsystem + enigmail tarball to produce a proper orig.tar.gz
  + use debhelper 7 with mozilla-devscripts
  + use debian source format 3.0 (quilt)
  + patch enigmail to use frozen API only
    - add debian/patches/frozen_api.diff
  + patch build system to not link against -lxul - which isnt
    available for sdks produced by all-static apps like tbird
    - add debian/patches/build_system_dont_link_libxul.diff
  + add minimal build-depends to control

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import pymake.data, pymake.parser, pymake.parserdata, pymake.functions
 
2
import unittest
 
3
import logging
 
4
 
 
5
from cStringIO import StringIO
 
6
 
 
7
def multitest(cls):
 
8
    for name in cls.testdata.iterkeys():
 
9
        def m(self, name=name):
 
10
            return self.runSingle(*self.testdata[name])
 
11
 
 
12
        setattr(cls, 'test_%s' % name, m)
 
13
    return cls
 
14
 
 
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))
 
19
 
 
20
class DataTest(TestBase):
 
21
    testdata = {
 
22
        'oneline':
 
23
            ("He\tllo", "f", 1, 0,
 
24
             ((0, "f", 1, 0), (2, "f", 1, 2), (3, "f", 1, 4))),
 
25
        'twoline':
 
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))),
 
28
    }
 
29
 
 
30
    def runSingle(self, data, filename, line, col, results):
 
31
        d = pymake.parser.Data(pymake.parserdata.Location(filename, line, col),
 
32
                               data)
 
33
        for pos, file, lineno, col in results:
 
34
            loc = d.getloc(pos)
 
35
            self.assertEqual(loc.path, file, "data file offset %i" % pos)
 
36
            self.assertEqual(loc.line, lineno, "data line offset %i" % pos)
 
37
            self.assertEqual(loc.column, col, "data col offset %i" % pos)
 
38
multitest(DataTest)
 
39
 
 
40
class TokenTest(TestBase):
 
41
    testdata = {
 
42
        'wsmatch': ('  ifdef FOO', 2, ('ifdef', 'else'), True, 'ifdef', 8),
 
43
        'wsnomatch': ('  unexpected FOO', 2, ('ifdef', 'else'), True, None, 2),
 
44
        'wsnows': ('  ifdefFOO', 2, ('ifdef', 'else'), True, None, 2),
 
45
        'paren': (' "hello"', 1, ('(', "'", '"'), False, '"', 2),
 
46
        }
 
47
 
 
48
    def runSingle(self, s, start, tlist, needws, etoken, eoffset):
 
49
        d = pymake.parser.Data.fromstring(s, None)
 
50
        tl = pymake.parser.TokenList.get(tlist)
 
51
        atoken, aoffset = d.findtoken(start, tl, needws)
 
52
        self.assertEqual(atoken, etoken)
 
53
        self.assertEqual(aoffset, eoffset)
 
54
multitest(TokenTest)
 
55
 
 
56
class IterTest(TestBase):
 
57
    testdata = {
 
58
        'plaindata': (
 
59
            pymake.parser.iterdata,
 
60
            "plaindata # test\n",
 
61
            "plaindata # test\n"
 
62
            ),
 
63
        'makecomment': (
 
64
            pymake.parser.itermakefilechars,
 
65
            "VAR = val # comment",
 
66
            "VAR = val "
 
67
            ),
 
68
        'makeescapedcomment': (
 
69
            pymake.parser.itermakefilechars,
 
70
            "VAR = val \# escaped hash\n",
 
71
            "VAR = val # escaped hash"
 
72
            ),
 
73
        'makeescapedslash': (
 
74
            pymake.parser.itermakefilechars,
 
75
            "VAR = val\\\\\n",
 
76
            "VAR = val\\\\",
 
77
            ),
 
78
        'makecontinuation': (
 
79
            pymake.parser.itermakefilechars,
 
80
            "VAR = VAL  \\\n  continuation # comment \\\n  continuation",
 
81
            "VAR = VAL continuation "
 
82
            ),
 
83
        'makecontinuation2': (
 
84
            pymake.parser.itermakefilechars,
 
85
            "VAR = VAL  \\  \\\n continuation",
 
86
            "VAR = VAL  \\ continuation"
 
87
            ),
 
88
        'makeawful': (
 
89
            pymake.parser.itermakefilechars,
 
90
            "VAR = VAL  \\\\# comment\n",
 
91
            "VAR = VAL  \\"
 
92
            ),
 
93
        'command': (
 
94
            pymake.parser.itercommandchars,
 
95
            "echo boo # comment\n",
 
96
            "echo boo # comment",
 
97
            ),
 
98
        'commandcomment': (
 
99
            pymake.parser.itercommandchars,
 
100
            "echo boo \# comment\n",
 
101
            "echo boo \# comment",
 
102
            ),
 
103
        'commandcontinue': (
 
104
            pymake.parser.itercommandchars,
 
105
            "echo boo # \\\n\t  command 2\n",
 
106
            "echo boo # \\\n  command 2"
 
107
            ),
 
108
        'define': (
 
109
            pymake.parser.iterdefinechars,
 
110
            "endef",
 
111
            ""
 
112
            ),
 
113
        'definenesting': (
 
114
            pymake.parser.iterdefinechars,
 
115
            """define BAR # comment
 
116
random text
 
117
endef not what you think!
 
118
endef # comment is ok\n""",
 
119
            """define BAR # comment
 
120
random text
 
121
endef not what you think!"""
 
122
            ),
 
123
        'defineescaped': (
 
124
            pymake.parser.iterdefinechars,
 
125
            """value   \\
 
126
endef
 
127
endef\n""",
 
128
            "value endef"
 
129
        ),
 
130
    }
 
131
 
 
132
    def runSingle(self, ifunc, idata, expected):
 
133
        fd = StringIO(idata)
 
134
        lineiter = enumerate(fd)
 
135
 
 
136
        d = pymake.parser.DynamicData(lineiter, 'PlainIterTest-data')
 
137
 
 
138
        actual = ''.join( (c for c, t, o, oo in ifunc(d, 0, pymake.parser._emptytokenlist)) )
 
139
        self.assertEqual(actual, expected)
 
140
 
 
141
        self.assertRaises(StopIteration, lambda: fd.next())
 
142
multitest(IterTest)
 
143
 
 
144
class MakeSyntaxTest(TestBase):
 
145
    # (string, startat, stopat, stopoffset, expansion
 
146
    testdata = {
 
147
        'text': ('hello world', 0, (), None, ['hello world']),
 
148
        'singlechar': ('hello $W', 0, (), None,
 
149
                       ['hello ',
 
150
                        {'type': 'VariableRef',
 
151
                         '.vname': ['W']}
 
152
                        ]),
 
153
        'stopat': ('hello: world', 0, (':', '='), 6, ['hello']),
 
154
        'funccall': ('h $(flavor FOO)', 0, (), None,
 
155
                     ['h ',
 
156
                      {'type': 'FlavorFunction',
 
157
                       '[0]': ['FOO']}
 
158
                      ]),
 
159
        'escapedollar': ('hello$$world', 0, (), None, ['hello$world']),
 
160
        'varref': ('echo $(VAR)', 0, (), None,
 
161
                   ['echo ',
 
162
                    {'type': 'VariableRef',
 
163
                     '.vname': ['VAR']}
 
164
                    ]),
 
165
        'dynamicvarname': ('echo $($(VARNAME):.c=.o)', 0, (':',), None,
 
166
                           ['echo ',
 
167
                            {'type': 'SubstitutionRef',
 
168
                             '.vname': [{'type': 'VariableRef',
 
169
                                         '.vname': ['VARNAME']}
 
170
                                        ],
 
171
                             '.substfrom': ['.c'],
 
172
                             '.substto': ['.o']}
 
173
                            ]),
 
174
        'substref': ('  $(VAR:VAL) := $(VAL)', 0, (':=', '+=', '=', ':'), 15,
 
175
                     ['  ',
 
176
                      {'type': 'VariableRef',
 
177
                       '.vname': ['VAR:VAL']},
 
178
                      ' ']),
 
179
        'vadsubstref': ('  $(VAR:VAL) = $(VAL)', 15, (), None,
 
180
                        [{'type': 'VariableRef',
 
181
                          '.vname': ['VAL']},
 
182
                         ]),
 
183
        }
 
184
 
 
185
    def compareRecursive(self, actual, expected, path):
 
186
        self.assertEqual(len(actual), len(expected),
 
187
                         "compareRecursive: %s" % (path,))
 
188
        for i in xrange(0, len(actual)):
 
189
            ipath = path + [i]
 
190
 
 
191
            a, isfunc = actual[i]
 
192
            e = expected[i]
 
193
            if isinstance(e, str):
 
194
                self.assertEqual(a, e, "compareRecursive: %s" % (ipath,))
 
195
            else:
 
196
                self.assertEqual(type(a), getattr(pymake.functions, e['type']),
 
197
                                 "compareRecursive: %s" % (ipath,))
 
198
                for k, v in e.iteritems():
 
199
                    if k == 'type':
 
200
                        pass
 
201
                    elif k[0] == '[':
 
202
                        item = int(k[1:-1])
 
203
                        proppath = ipath + [item]
 
204
                        self.compareRecursive(a[item], v, proppath)
 
205
                    elif k[0] == '.':
 
206
                        item = k[1:]
 
207
                        proppath = ipath + [item]
 
208
                        self.compareRecursive(getattr(a, item), v, proppath)
 
209
                    else:
 
210
                        raise Exception("Unexpected property at %s: %s" % (ipath, k))
 
211
 
 
212
    def runSingle(self, s, startat, stopat, stopoffset, expansion):
 
213
        d = pymake.parser.Data.fromstring(s, pymake.parserdata.Location('testdata', 1, 0))
 
214
 
 
215
        a, t, offset = pymake.parser.parsemakesyntax(d, startat, stopat, pymake.parser.itermakefilechars)
 
216
        self.compareRecursive(a, expansion, [])
 
217
        self.assertEqual(offset, stopoffset)
 
218
 
 
219
multitest(MakeSyntaxTest)
 
220
 
 
221
class VariableTest(TestBase):
 
222
    testdata = """
 
223
    VAR = value
 
224
    VARNAME = TESTVAR
 
225
    $(VARNAME) = testvalue
 
226
    $(VARNAME:VAR=VAL) = moretesting
 
227
    IMM := $(VARNAME) # this is a comment
 
228
    MULTIVAR = val1 \\
 
229
  val2
 
230
    VARNAME = newname
 
231
    """
 
232
    expected = {'VAR': 'value',
 
233
                'VARNAME': 'newname',
 
234
                'TESTVAR': 'testvalue',
 
235
                'TESTVAL': 'moretesting',
 
236
                'IMM': 'TESTVAR ',
 
237
                'MULTIVAR': 'val1 val2',
 
238
                'UNDEF': None}
 
239
 
 
240
    def runTest(self):
 
241
        stream = StringIO(self.testdata)
 
242
        stmts = pymake.parser.parsestream(stream, 'testdata')
 
243
 
 
244
        m = pymake.data.Makefile()
 
245
        stmts.execute(m)
 
246
        for k, v in self.expected.iteritems():
 
247
            flavor, source, val = m.variables.get(k)
 
248
            if val is None:
 
249
                self.assertEqual(val, v, 'variable named %s' % k)
 
250
            else:
 
251
                self.assertEqual(val.resolvestr(m, m.variables), v, 'variable named %s' % k)
 
252
 
 
253
class SimpleRuleTest(TestBase):
 
254
    testdata = """
 
255
    VAR = value
 
256
TSPEC = dummy
 
257
all: TSPEC = myrule
 
258
all:: test test2 $(VAR)
 
259
        echo "Hello, $(TSPEC)"
 
260
 
 
261
%.o: %.c
 
262
        $(CC) -o $@ $<
 
263
"""
 
264
 
 
265
    def runTest(self):
 
266
        stream = StringIO(self.testdata)
 
267
        stmts = pymake.parser.parsestream(stream, 'testdata')
 
268
 
 
269
        m = pymake.data.Makefile()
 
270
        stmts.execute(m)
 
271
        self.assertEqual(m.defaulttarget, 'all', "Default target")
 
272
 
 
273
        self.assertTrue(m.hastarget('all'), "Has 'all' target")
 
274
        target = m.gettarget('all')
 
275
        rules = target.rules
 
276
        self.assertEqual(len(rules), 1, "Number of rules")
 
277
        prereqs = rules[0].prerequisites
 
278
        self.assertEqual(prereqs, ['test', 'test2', 'value'], "Prerequisites")
 
279
        commands = rules[0].commands
 
280
        self.assertEqual(len(commands), 1, "Number of commands")
 
281
        expanded = commands[0].resolvestr(m, target.variables)
 
282
        self.assertEqual(expanded, 'echo "Hello, myrule"')
 
283
 
 
284
        irules = m.implicitrules
 
285
        self.assertEqual(len(irules), 1, "Number of implicit rules")
 
286
 
 
287
        irule = irules[0]
 
288
        self.assertEqual(len(irule.targetpatterns), 1, "%.o target pattern count")
 
289
        self.assertEqual(len(irule.prerequisites), 1, "%.o prerequisite count")
 
290
        self.assertEqual(irule.targetpatterns[0].match('foo.o'), 'foo', "%.o stem")
 
291
 
 
292
if __name__ == '__main__':
 
293
    logging.basicConfig(level=logging.DEBUG)
 
294
    unittest.main()