Statistics
| Revision:

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()