gvsig-scripting / org.gvsig.scripting / trunk / org.gvsig.scripting / org.gvsig.scripting.app / org.gvsig.scripting.app.mainplugin / src / main / resources-plugin / scripting / lib / cssutils / tests / test_prodparser.py @ 475
History | View | Annotate | Download (15.1 KB)
1 |
"""Testcases for cssutils.css.CSSCharsetRule"""
|
---|---|
2 |
__version__ = '$Id: test_csscharsetrule.py 1356 2008-07-13 17:29:09Z cthedot $'
|
3 |
|
4 |
import sys |
5 |
import xml.dom |
6 |
import basetest |
7 |
from cssutils.prodparser import * |
8 |
from cssutils.prodparser import ParseError, Done, Exhausted, NoMatch # not in __all__ |
9 |
|
10 |
class ProdTestCase(basetest.BaseTestCase): |
11 |
|
12 |
def test_init(self): |
13 |
"Prod.__init__(...)"
|
14 |
p = Prod('min', lambda t, v: t == 1 and v == 2) |
15 |
|
16 |
self.assertEqual(str(p), 'min') |
17 |
self.assertEqual(p.toStore, None) |
18 |
self.assertEqual(p.optional, False) |
19 |
|
20 |
p = Prod('optional', lambda t, v: True, |
21 |
optional=True)
|
22 |
self.assertEqual(p.optional, True) |
23 |
|
24 |
def test_initMatch(self): |
25 |
"Prod.__init__(...match=...)"
|
26 |
p = Prod('min', lambda t, v: t == 1 and v == 2) |
27 |
self.assertEqual(p.match(1, 2), True) |
28 |
self.assertEqual(p.match(2, 2), False) |
29 |
self.assertEqual(p.match(1, 1), False) |
30 |
|
31 |
def test_initToSeq(self): |
32 |
"Prod.__init__(...toSeq=...)"
|
33 |
# simply saves
|
34 |
p = Prod('all', lambda t, tokens: True, |
35 |
toSeq=None)
|
36 |
self.assertEqual(p.toSeq([1, 2], None), (1, 2)) # simply saves |
37 |
self.assertEqual(p.toSeq(['s1', 's2'], None), ('s1', 's2')) # simply saves |
38 |
|
39 |
# saves callback(val)
|
40 |
p = Prod('all', lambda t, v: True, |
41 |
toSeq=lambda t, tokens: (1 == t[0], 3 == t[1])) |
42 |
self.assertEqual(p.toSeq([1, 3], None), (True, True)) |
43 |
self.assertEqual(p.toSeq([2, 4], None), (False, False)) |
44 |
|
45 |
def test_initToStore(self): |
46 |
"Prod.__init__(...toStore=...)"
|
47 |
p = Prod('all', lambda t, v: True, |
48 |
toStore='key')
|
49 |
|
50 |
# save as key
|
51 |
s = {} |
52 |
p.toStore(s, 1)
|
53 |
self.assertEqual(s['key'], 1) |
54 |
|
55 |
# append to key
|
56 |
s = {'key': []}
|
57 |
p.toStore(s, 1)
|
58 |
p.toStore(s, 2)
|
59 |
self.assertEqual(s['key'], [1, 2]) |
60 |
|
61 |
# callback
|
62 |
def doubleToStore(key): |
63 |
def toStore(store, item): |
64 |
store[key] = item * 2
|
65 |
return toStore
|
66 |
|
67 |
p = Prod('all', lambda t, v: True, |
68 |
toStore=doubleToStore('key'))
|
69 |
s = {'key': []}
|
70 |
p.toStore(s, 1)
|
71 |
self.assertEqual(s['key'], 2) |
72 |
|
73 |
def test_matches(self): |
74 |
"Prod.matches(token)"
|
75 |
p1 = Prod('p1', lambda t, v: t == 1 and v == 2) |
76 |
p2 = Prod('p2', lambda t, v: t == 1 and v == 2, optional=True) |
77 |
self.assertEqual(p1.matches([1, 2, 0, 0]), True) |
78 |
self.assertEqual(p2.matches([1, 2, 0, 0]), True) |
79 |
self.assertEqual(p1.matches([0, 0, 0, 0]), False) |
80 |
self.assertEqual(p2.matches([0, 0, 0, 0]), False) |
81 |
|
82 |
|
83 |
class SequenceTestCase(basetest.BaseTestCase): |
84 |
|
85 |
def test_init(self): |
86 |
"Sequence.__init__()"
|
87 |
p1 = Prod('p1', lambda t, v: t == 1) |
88 |
p2 = Prod('p2', lambda t, v: t == 2) |
89 |
seq = Sequence(p1, p1) |
90 |
|
91 |
self.assertEqual(1, seq._min) |
92 |
self.assertEqual(1, seq._max) |
93 |
|
94 |
def test_initminmax(self): |
95 |
"Sequence.__init__(...minmax=...)"
|
96 |
p1 = Prod('p1', lambda t, v: t == 1) |
97 |
p2 = Prod('p2', lambda t, v: t == 2) |
98 |
|
99 |
s = Sequence(p1, p2, minmax=lambda: (2, 3)) |
100 |
self.assertEqual(2, s._min) |
101 |
self.assertEqual(3, s._max) |
102 |
|
103 |
s = Sequence(p1, p2, minmax=lambda: (0, None)) |
104 |
self.assertEqual(0, s._min) |
105 |
|
106 |
try:
|
107 |
# py2.6/3
|
108 |
m = sys.maxsize |
109 |
except AttributeError: |
110 |
# py<1.6
|
111 |
m = sys.maxint |
112 |
self.assertEqual(m, s._max)
|
113 |
|
114 |
def test_optional(self): |
115 |
"Sequence.optional"
|
116 |
p1 = Prod('p1', lambda t, v: t == 1) |
117 |
|
118 |
s = Sequence(p1, minmax=lambda: (1, 3)) |
119 |
self.assertEqual(False, s.optional) |
120 |
s = Sequence(p1, minmax=lambda: (0, 3)) |
121 |
self.assertEqual(True, s.optional) |
122 |
s = Sequence(p1, minmax=lambda: (0, None)) |
123 |
self.assertEqual(True, s.optional) |
124 |
|
125 |
def test_reset(self): |
126 |
"Sequence.reset()"
|
127 |
p1 = Prod('p1', lambda t, v: t == 1) |
128 |
p2 = Prod('p2', lambda t, v: t == 2) |
129 |
seq = Sequence(p1, p2) |
130 |
t1 = (1, 0, 0, 0) |
131 |
t2 = (2, 0, 0, 0) |
132 |
self.assertEqual(p1, seq.nextProd(t1))
|
133 |
self.assertEqual(p2, seq.nextProd(t2))
|
134 |
self.assertRaises(Exhausted, seq.nextProd, t1)
|
135 |
seq.reset() |
136 |
self.assertEqual(p1, seq.nextProd(t1))
|
137 |
|
138 |
def test_matches(self): |
139 |
"Sequence.matches()"
|
140 |
p1 = Prod('p1', lambda t, v: t == 1) |
141 |
p2 = Prod('p2', lambda t, v: t == 2, optional=True) |
142 |
|
143 |
t1 = (1, 0, 0, 0) |
144 |
t2 = (2, 0, 0, 0) |
145 |
t3 = (3, 0, 0, 0) |
146 |
|
147 |
s = Sequence(p1, p2) |
148 |
self.assertEqual(True, s.matches(t1)) |
149 |
self.assertEqual(False, s.matches(t2)) |
150 |
|
151 |
s = Sequence(p2, p1) |
152 |
self.assertEqual(True, s.matches(t1)) |
153 |
self.assertEqual(True, s.matches(t2)) |
154 |
|
155 |
s = Sequence(Choice(p1, p2)) |
156 |
self.assertEqual(True, s.matches(t1)) |
157 |
self.assertEqual(True, s.matches(t2)) |
158 |
self.assertEqual(False, s.matches(t3)) |
159 |
|
160 |
def test_nextProd(self): |
161 |
"Sequence.nextProd()"
|
162 |
p1 = Prod('p1', lambda t, v: t == 1, optional=True) |
163 |
p2 = Prod('p2', lambda t, v: t == 2) |
164 |
t1 = (1, 0, 0, 0) |
165 |
t2 = (2, 0, 0, 0) |
166 |
|
167 |
tests = { |
168 |
# seq: list of list of (token, prod or error msg)
|
169 |
(p1, ): ([(t1, p1)], |
170 |
[(t2, 'Extra token')], # as p1 optional |
171 |
[(t1, p1), (t1, u'Extra token')],
|
172 |
[(t1, p1), (t2, u'Extra token')]
|
173 |
), |
174 |
(p2, ): ([(t2, p2)], |
175 |
[(t2, p2), (t2, u'Extra token')],
|
176 |
[(t2, p2), (t1, u'Extra token')],
|
177 |
[(t1, 'Missing token for production p2')]
|
178 |
), |
179 |
(p1, p2): ([(t1, p1), (t2, p2)], |
180 |
[(t1, p1), (t1, u'Missing token for production p2')]
|
181 |
) |
182 |
} |
183 |
for seqitems, results in tests.items(): |
184 |
for result in results: |
185 |
seq = Sequence(*seqitems) |
186 |
for t, p in result: |
187 |
if isinstance(p, basestring): |
188 |
self.assertRaisesMsg(ParseError, p, seq.nextProd, t)
|
189 |
else:
|
190 |
self.assertEqual(p, seq.nextProd(t))
|
191 |
|
192 |
tests = { |
193 |
# seq: list of list of (token, prod or error msg)
|
194 |
# as p1 optional!
|
195 |
(p1, p1): ([(t1, p1)], |
196 |
[(t1, p1), (t1, p1)], |
197 |
[(t1, p1), (t1, p1)], |
198 |
[(t1, p1), (t1, p1), (t1, p1)], |
199 |
[(t1, p1), (t1, p1), (t1, p1), (t1, p1)], |
200 |
[(t1, p1), (t1, p1), (t1, p1), (t1, p1), (t1, u'Extra token')],
|
201 |
), |
202 |
(p1, ): ([(t1, p1)], |
203 |
[(t2, 'Extra token')],
|
204 |
[(t1, p1), (t1, p1)], |
205 |
[(t1, p1), (t2, 'Extra token')],
|
206 |
[(t1, p1), (t1, p1), (t1, u'Extra token')],
|
207 |
[(t1, p1), (t1, p1), (t2, u'Extra token')]
|
208 |
), |
209 |
# as p2 NOT optional
|
210 |
(p2, ): ([(t2, p2)], |
211 |
[(t1, 'Missing token for production p2')],
|
212 |
[(t2, p2), (t2, p2)], |
213 |
[(t2, p2), (t1, u'No match for (1, 0, 0, 0) in Sequence(p2)')],
|
214 |
[(t2, p2), (t2, p2), (t2, u'Extra token')],
|
215 |
[(t2, p2), (t2, p2), (t1, u'Extra token')]
|
216 |
), |
217 |
(p1, p2): ([(t1, p1), (t1, u'Missing token for production p2')],
|
218 |
[(t2, p2), (t2, p2)], |
219 |
[(t2, p2), (t1, p1), (t2, p2)], |
220 |
[(t1, p1), (t2, p2), (t2, p2)], |
221 |
[(t1, p1), (t2, p2), (t1, p1), (t2, p2)], |
222 |
[(t2, p2), (t2, p2), (t2, u'Extra token')],
|
223 |
[(t2, p2), (t1, p1), (t2, p2), (t1, 'Extra token')],
|
224 |
[(t2, p2), (t1, p1), (t2, p2), (t2, 'Extra token')],
|
225 |
[(t1, p1), (t2, p2), (t2, p2), (t1, 'Extra token')],
|
226 |
[(t1, p1), (t2, p2), (t2, p2), (t2, 'Extra token')],
|
227 |
[(t1, p1), (t2, p2), (t1, p1), (t2, p2), (t1, 'Extra token')],
|
228 |
[(t1, p1), (t2, p2), (t1, p1), (t2, p2), (t2, 'Extra token')],
|
229 |
) |
230 |
} |
231 |
for seqitems, results in tests.items(): |
232 |
for result in results: |
233 |
seq = Sequence(minmax=lambda: (1,2), *seqitems) |
234 |
for t, p in result: |
235 |
if isinstance(p, basestring): |
236 |
self.assertRaisesMsg(ParseError, p, seq.nextProd, t)
|
237 |
else:
|
238 |
self.assertEqual(p, seq.nextProd(t))
|
239 |
|
240 |
|
241 |
class ChoiceTestCase(basetest.BaseTestCase): |
242 |
|
243 |
def test_init(self): |
244 |
"Choice.__init__()"
|
245 |
p1 = Prod('p1', lambda t, v: t == 1) |
246 |
p2 = Prod('p2', lambda t, v: t == 2) |
247 |
t0 = (0,0,0,0) |
248 |
t1 = (1,0,0,0) |
249 |
t2 = (2,0,0,0) |
250 |
|
251 |
ch = Choice(p1, p2) |
252 |
self.assertRaisesMsg(ParseError, u'No match for (0, 0, 0, 0) in Choice(p1, p2)', ch.nextProd, t0) |
253 |
self.assertEqual(p1, ch.nextProd(t1))
|
254 |
self.assertRaisesMsg(Exhausted, u'Extra token', ch.nextProd, t1) |
255 |
|
256 |
ch = Choice(p1, p2) |
257 |
self.assertEqual(p2, ch.nextProd(t2))
|
258 |
self.assertRaisesMsg(Exhausted, u'Extra token', ch.nextProd, t2) |
259 |
|
260 |
ch = Choice(p2, p1) |
261 |
self.assertRaisesMsg(ParseError, 'No match for (0, 0, 0, 0) in Choice(p2, p1)', ch.nextProd, t0) |
262 |
self.assertEqual(p1, ch.nextProd(t1))
|
263 |
self.assertRaisesMsg(Exhausted, u'Extra token', ch.nextProd, t1) |
264 |
|
265 |
ch = Choice(p2, p1) |
266 |
self.assertEqual(p2, ch.nextProd(t2))
|
267 |
self.assertRaisesMsg(Exhausted, u'Extra token', ch.nextProd, t2) |
268 |
|
269 |
def test_matches(self): |
270 |
"Choice.matches()"
|
271 |
p1 = Prod('p1', lambda t, v: t == 1) |
272 |
p2 = Prod('p2', lambda t, v: t == 2, optional=True) |
273 |
|
274 |
t1 = (1, 0, 0, 0) |
275 |
t2 = (2, 0, 0, 0) |
276 |
t3 = (3, 0, 0, 0) |
277 |
|
278 |
c = Choice(p1, p2) |
279 |
self.assertEqual(True, c.matches(t1)) |
280 |
self.assertEqual(True, c.matches(t2)) |
281 |
self.assertEqual(False, c.matches(t3)) |
282 |
|
283 |
c = Choice(Sequence(p1), Sequence(p2)) |
284 |
self.assertEqual(True, c.matches(t1)) |
285 |
self.assertEqual(True, c.matches(t2)) |
286 |
self.assertEqual(False, c.matches(t3)) |
287 |
|
288 |
def test_nested(self): |
289 |
"Choice with nested Sequence"
|
290 |
p1 = Prod('p1', lambda t, v: t == 1) |
291 |
p2 = Prod('p2', lambda t, v: t == 2) |
292 |
s1 = Sequence(p1, p1) |
293 |
s2 = Sequence(p2, p2) |
294 |
t0 = (0,0,0,0) |
295 |
t1 = (1,0,0,0) |
296 |
t2 = (2,0,0,0) |
297 |
|
298 |
ch = Choice(s1, s2) |
299 |
self.assertRaisesMsg(ParseError, u'No match for (0, 0, 0, 0) in Choice(Sequence(p1, p1), Sequence(p2, p2))', ch.nextProd, t0) |
300 |
self.assertEqual(s1, ch.nextProd(t1))
|
301 |
self.assertRaisesMsg(Exhausted, u'Extra token', ch.nextProd, t1) |
302 |
|
303 |
ch = Choice(s1, s2) |
304 |
self.assertEqual(s2, ch.nextProd(t2))
|
305 |
self.assertRaisesMsg(Exhausted, u'Extra token', ch.nextProd, t1) |
306 |
|
307 |
def test_reset(self): |
308 |
"Choice.reset()"
|
309 |
p1 = Prod('p1', lambda t, v: t == 1) |
310 |
p2 = Prod('p2', lambda t, v: t == 2) |
311 |
t1 = (1,0,0,0) |
312 |
t2 = (2,0,0,0) |
313 |
|
314 |
ch = Choice(p1, p2) |
315 |
self.assertEqual(p1, ch.nextProd(t1))
|
316 |
self.assertRaises(Exhausted, ch.nextProd, t1)
|
317 |
ch.reset() |
318 |
self.assertEqual(p2, ch.nextProd(t2))
|
319 |
|
320 |
class ProdParserTestCase(basetest.BaseTestCase): |
321 |
|
322 |
def setUp(self): |
323 |
pass
|
324 |
|
325 |
def test_parse_keepS(self): |
326 |
"ProdParser.parse(keepS)"
|
327 |
p = ProdParser() |
328 |
|
329 |
# text, name, productions, store=None
|
330 |
prods = lambda: Sequence(PreDef.char(';', u';'), |
331 |
PreDef.char(':', u':') |
332 |
) |
333 |
|
334 |
w, seq, store, unused = p.parse('; :', 'test', prods(), |
335 |
keepS=True)
|
336 |
self.assertTrue(w)
|
337 |
self.assertEqual(3, len(seq)) |
338 |
|
339 |
w, seq, store, unused = p.parse('; :', 'test', prods(), |
340 |
keepS=False)
|
341 |
self.assertTrue(w)
|
342 |
self.assertEqual(2, len(seq)) |
343 |
|
344 |
def test_combi(self): |
345 |
"ProdParser.parse() 2"
|
346 |
p1 = Prod('p1', lambda t, v: v == '1') |
347 |
p2 = Prod('p2', lambda t, v: v == '2') |
348 |
p3 = Prod('p3', lambda t, v: v == '3') |
349 |
|
350 |
tests = {'1 2': True, |
351 |
'1 2 1 2': True, |
352 |
'3': True, |
353 |
#'': 'No match in Choice(Sequence(p1, p2), p3)',
|
354 |
'1': 'Missing token for production p2', |
355 |
'1 2 1': 'Missing token for production p2', |
356 |
'1 2 1 2 x': "No match: ('IDENT', 'x', 1, 9)", |
357 |
'1 2 1 2 1': "No match: ('NUMBER', '1', 1, 9)", |
358 |
'3 x': "No match: ('IDENT', 'x', 1, 3)", |
359 |
'3 3': "No match: ('NUMBER', '3', 1, 3)", |
360 |
} |
361 |
for text, exp in tests.items(): |
362 |
prods = Choice(Sequence(p1, p2, minmax=lambda: (1,2)), |
363 |
p3) |
364 |
if exp is True: |
365 |
wellformed, seq, store, unused = ProdParser().parse(text, 'T', prods)
|
366 |
self.assertEqual(wellformed, exp)
|
367 |
else:
|
368 |
self.assertRaisesMsg(xml.dom.SyntaxErr, u'T: %s' % exp, |
369 |
ProdParser().parse, text, 'T', prods)
|
370 |
|
371 |
tests = {'1 3': True, |
372 |
'1 1 3': True, |
373 |
'2 3': True, |
374 |
'1': 'Missing token for production p3', |
375 |
'1 1': 'Missing token for production p3', |
376 |
'1 3 3': "No match: ('NUMBER', '3', 1, 5)", |
377 |
'1 1 3 3': "No match: ('NUMBER', '3', 1, 7)", |
378 |
'2 3 3': "No match: ('NUMBER', '3', 1, 5)", |
379 |
'2': 'Missing token for production p3', |
380 |
'3': "Missing token for production Choice(Sequence(p1), p2): ('NUMBER', '3', 1, 1)", |
381 |
} |
382 |
for text, exp in tests.items(): |
383 |
prods = Sequence(Choice(Sequence(p1, minmax=lambda: (1,2)), |
384 |
p2), |
385 |
p3) |
386 |
if exp is True: |
387 |
wellformed, seq, store, unused = ProdParser().parse(text, 'T', prods)
|
388 |
self.assertEqual(wellformed, exp)
|
389 |
else:
|
390 |
self.assertRaisesMsg(xml.dom.SyntaxErr, u'T: %s' % exp, |
391 |
ProdParser().parse, text, 'T', prods)
|
392 |
|
393 |
|
394 |
|
395 |
if __name__ == '__main__': |
396 |
import unittest |
397 |
unittest.main() |