%PDF- %PDF-
| Direktori : /lib/python3/dist-packages/cssutils/tests/ |
| Current File : //lib/python3/dist-packages/cssutils/tests/test_prodparser.py |
"""Testcases for cssutils.css.CSSCharsetRule"""
__version__ = '$Id: test_csscharsetrule.py 1356 2008-07-13 17:29:09Z cthedot $'
import sys
import xml.dom
from . import basetest
from cssutils.prodparser import *
from cssutils.prodparser import ParseError, Done, Exhausted, NoMatch # not in __all__
class ProdTestCase(basetest.BaseTestCase):
def test_init(self):
"Prod.__init__(...)"
p = Prod('min', lambda t, v: t == 1 and v == 2)
self.assertEqual(str(p), 'min')
self.assertEqual(p.toStore, None)
self.assertEqual(p.optional, False)
p = Prod('optional', lambda t, v: True,
optional=True)
self.assertEqual(p.optional, True)
def test_initMatch(self):
"Prod.__init__(...match=...)"
p = Prod('min', lambda t, v: t == 1 and v == 2)
self.assertEqual(p.match(1, 2), True)
self.assertEqual(p.match(2, 2), False)
self.assertEqual(p.match(1, 1), False)
def test_initToSeq(self):
"Prod.__init__(...toSeq=...)"
# simply saves
p = Prod('all', lambda t, tokens: True,
toSeq=None)
self.assertEqual(p.toSeq([1, 2], None), (1, 2)) # simply saves
self.assertEqual(p.toSeq(['s1', 's2'], None), ('s1', 's2')) # simply saves
# saves callback(val)
p = Prod('all', lambda t, v: True,
toSeq=lambda t, tokens: (1 == t[0], 3 == t[1]))
self.assertEqual(p.toSeq([1, 3], None), (True, True))
self.assertEqual(p.toSeq([2, 4], None), (False, False))
def test_initToStore(self):
"Prod.__init__(...toStore=...)"
p = Prod('all', lambda t, v: True,
toStore='key')
# save as key
s = {}
p.toStore(s, 1)
self.assertEqual(s['key'], 1)
# append to key
s = {'key': []}
p.toStore(s, 1)
p.toStore(s, 2)
self.assertEqual(s['key'], [1, 2])
# callback
def doubleToStore(key):
def toStore(store, item):
store[key] = item * 2
return toStore
p = Prod('all', lambda t, v: True,
toStore=doubleToStore('key'))
s = {'key': []}
p.toStore(s, 1)
self.assertEqual(s['key'], 2)
def test_matches(self):
"Prod.matches(token)"
p1 = Prod('p1', lambda t, v: t == 1 and v == 2)
p2 = Prod('p2', lambda t, v: t == 1 and v == 2, optional=True)
self.assertEqual(p1.matches([1, 2, 0, 0]), True)
self.assertEqual(p2.matches([1, 2, 0, 0]), True)
self.assertEqual(p1.matches([0, 0, 0, 0]), False)
self.assertEqual(p2.matches([0, 0, 0, 0]), False)
class SequenceTestCase(basetest.BaseTestCase):
def test_init(self):
"Sequence.__init__()"
p1 = Prod('p1', lambda t, v: t == 1)
p2 = Prod('p2', lambda t, v: t == 2)
seq = Sequence(p1, p1)
self.assertEqual(1, seq._min)
self.assertEqual(1, seq._max)
def test_initminmax(self):
"Sequence.__init__(...minmax=...)"
p1 = Prod('p1', lambda t, v: t == 1)
p2 = Prod('p2', lambda t, v: t == 2)
s = Sequence(p1, p2, minmax=lambda: (2, 3))
self.assertEqual(2, s._min)
self.assertEqual(3, s._max)
s = Sequence(p1, p2, minmax=lambda: (0, None))
self.assertEqual(0, s._min)
try:
# py2.6/3
m = sys.maxsize
except AttributeError:
# py<1.6
m = sys.maxsize
self.assertEqual(m, s._max)
def test_optional(self):
"Sequence.optional"
p1 = Prod('p1', lambda t, v: t == 1)
s = Sequence(p1, minmax=lambda: (1, 3))
self.assertEqual(False, s.optional)
s = Sequence(p1, minmax=lambda: (0, 3))
self.assertEqual(True, s.optional)
s = Sequence(p1, minmax=lambda: (0, None))
self.assertEqual(True, s.optional)
def test_reset(self):
"Sequence.reset()"
p1 = Prod('p1', lambda t, v: t == 1)
p2 = Prod('p2', lambda t, v: t == 2)
seq = Sequence(p1, p2)
t1 = (1, 0, 0, 0)
t2 = (2, 0, 0, 0)
self.assertEqual(p1, seq.nextProd(t1))
self.assertEqual(p2, seq.nextProd(t2))
self.assertRaises(Exhausted, seq.nextProd, t1)
seq.reset()
self.assertEqual(p1, seq.nextProd(t1))
def test_matches(self):
"Sequence.matches()"
p1 = Prod('p1', lambda t, v: t == 1)
p2 = Prod('p2', lambda t, v: t == 2, optional=True)
t1 = (1, 0, 0, 0)
t2 = (2, 0, 0, 0)
t3 = (3, 0, 0, 0)
s = Sequence(p1, p2)
self.assertEqual(True, s.matches(t1))
self.assertEqual(False, s.matches(t2))
s = Sequence(p2, p1)
self.assertEqual(True, s.matches(t1))
self.assertEqual(True, s.matches(t2))
s = Sequence(Choice(p1, p2))
self.assertEqual(True, s.matches(t1))
self.assertEqual(True, s.matches(t2))
self.assertEqual(False, s.matches(t3))
def test_nextProd(self):
"Sequence.nextProd()"
p1 = Prod('p1', lambda t, v: t == 1, optional=True)
p2 = Prod('p2', lambda t, v: t == 2)
t1 = (1, 0, 0, 0)
t2 = (2, 0, 0, 0)
tests = {
# seq: list of list of (token, prod or error msg)
(p1, ): ([(t1, p1)],
[(t2, 'Extra token')], # as p1 optional
[(t1, p1), (t1, 'Extra token')],
[(t1, p1), (t2, 'Extra token')]
),
(p2, ): ([(t2, p2)],
[(t2, p2), (t2, 'Extra token')],
[(t2, p2), (t1, 'Extra token')],
[(t1, 'Missing token for production p2')]
),
(p1, p2): ([(t1, p1), (t2, p2)],
[(t1, p1), (t1, 'Missing token for production p2')]
)
}
for seqitems, results in list(tests.items()):
for result in results:
seq = Sequence(*seqitems)
for t, p in result:
if isinstance(p, str):
self.assertRaisesMsg(ParseError, p, seq.nextProd, t)
else:
self.assertEqual(p, seq.nextProd(t))
tests = {
# seq: list of list of (token, prod or error msg)
# as p1 optional!
(p1, p1): ([(t1, p1)],
[(t1, p1), (t1, p1)],
[(t1, p1), (t1, p1)],
[(t1, p1), (t1, p1), (t1, p1)],
[(t1, p1), (t1, p1), (t1, p1), (t1, p1)],
[(t1, p1), (t1, p1), (t1, p1), (t1, p1), (t1, 'Extra token')],
),
(p1, ): ([(t1, p1)],
[(t2, 'Extra token')],
[(t1, p1), (t1, p1)],
[(t1, p1), (t2, 'Extra token')],
[(t1, p1), (t1, p1), (t1, 'Extra token')],
[(t1, p1), (t1, p1), (t2, 'Extra token')]
),
# as p2 NOT optional
(p2, ): ([(t2, p2)],
[(t1, 'Missing token for production p2')],
[(t2, p2), (t2, p2)],
[(t2, p2), (t1, 'No match for (1, 0, 0, 0) in Sequence(p2)')],
[(t2, p2), (t2, p2), (t2, 'Extra token')],
[(t2, p2), (t2, p2), (t1, 'Extra token')]
),
(p1, p2): ([(t1, p1), (t1, 'Missing token for production p2')],
[(t2, p2), (t2, p2)],
[(t2, p2), (t1, p1), (t2, p2)],
[(t1, p1), (t2, p2), (t2, p2)],
[(t1, p1), (t2, p2), (t1, p1), (t2, p2)],
[(t2, p2), (t2, p2), (t2, 'Extra token')],
[(t2, p2), (t1, p1), (t2, p2), (t1, 'Extra token')],
[(t2, p2), (t1, p1), (t2, p2), (t2, 'Extra token')],
[(t1, p1), (t2, p2), (t2, p2), (t1, 'Extra token')],
[(t1, p1), (t2, p2), (t2, p2), (t2, 'Extra token')],
[(t1, p1), (t2, p2), (t1, p1), (t2, p2), (t1, 'Extra token')],
[(t1, p1), (t2, p2), (t1, p1), (t2, p2), (t2, 'Extra token')],
)
}
for seqitems, results in list(tests.items()):
for result in results:
seq = Sequence(minmax=lambda: (1,2), *seqitems)
for t, p in result:
if isinstance(p, str):
self.assertRaisesMsg(ParseError, p, seq.nextProd, t)
else:
self.assertEqual(p, seq.nextProd(t))
class ChoiceTestCase(basetest.BaseTestCase):
def test_init(self):
"Choice.__init__()"
p1 = Prod('p1', lambda t, v: t == 1)
p2 = Prod('p2', lambda t, v: t == 2)
t0 = (0,0,0,0)
t1 = (1,0,0,0)
t2 = (2,0,0,0)
ch = Choice(p1, p2)
self.assertRaisesMsg(ParseError, 'No match for (0, 0, 0, 0) in Choice(p1, p2)', ch.nextProd, t0)
self.assertEqual(p1, ch.nextProd(t1))
self.assertRaisesMsg(Exhausted, 'Extra token', ch.nextProd, t1)
ch = Choice(p1, p2)
self.assertEqual(p2, ch.nextProd(t2))
self.assertRaisesMsg(Exhausted, 'Extra token', ch.nextProd, t2)
ch = Choice(p2, p1)
self.assertRaisesMsg(ParseError, 'No match for (0, 0, 0, 0) in Choice(p2, p1)', ch.nextProd, t0)
self.assertEqual(p1, ch.nextProd(t1))
self.assertRaisesMsg(Exhausted, 'Extra token', ch.nextProd, t1)
ch = Choice(p2, p1)
self.assertEqual(p2, ch.nextProd(t2))
self.assertRaisesMsg(Exhausted, 'Extra token', ch.nextProd, t2)
def test_matches(self):
"Choice.matches()"
p1 = Prod('p1', lambda t, v: t == 1)
p2 = Prod('p2', lambda t, v: t == 2, optional=True)
t1 = (1, 0, 0, 0)
t2 = (2, 0, 0, 0)
t3 = (3, 0, 0, 0)
c = Choice(p1, p2)
self.assertEqual(True, c.matches(t1))
self.assertEqual(True, c.matches(t2))
self.assertEqual(False, c.matches(t3))
c = Choice(Sequence(p1), Sequence(p2))
self.assertEqual(True, c.matches(t1))
self.assertEqual(True, c.matches(t2))
self.assertEqual(False, c.matches(t3))
def test_nested(self):
"Choice with nested Sequence"
p1 = Prod('p1', lambda t, v: t == 1)
p2 = Prod('p2', lambda t, v: t == 2)
s1 = Sequence(p1, p1)
s2 = Sequence(p2, p2)
t0 = (0,0,0,0)
t1 = (1,0,0,0)
t2 = (2,0,0,0)
ch = Choice(s1, s2)
self.assertRaisesMsg(ParseError, 'No match for (0, 0, 0, 0) in Choice(Sequence(p1, p1), Sequence(p2, p2))', ch.nextProd, t0)
self.assertEqual(s1, ch.nextProd(t1))
self.assertRaisesMsg(Exhausted, 'Extra token', ch.nextProd, t1)
ch = Choice(s1, s2)
self.assertEqual(s2, ch.nextProd(t2))
self.assertRaisesMsg(Exhausted, 'Extra token', ch.nextProd, t1)
def test_reset(self):
"Choice.reset()"
p1 = Prod('p1', lambda t, v: t == 1)
p2 = Prod('p2', lambda t, v: t == 2)
t1 = (1,0,0,0)
t2 = (2,0,0,0)
ch = Choice(p1, p2)
self.assertEqual(p1, ch.nextProd(t1))
self.assertRaises(Exhausted, ch.nextProd, t1)
ch.reset()
self.assertEqual(p2, ch.nextProd(t2))
class ProdParserTestCase(basetest.BaseTestCase):
def setUp(self):
pass
def test_parse_keepS(self):
"ProdParser.parse(keepS)"
p = ProdParser()
# text, name, productions, store=None
prods = lambda: Sequence(PreDef.char(';', ';'),
PreDef.char(':', ':')
)
w, seq, store, unused = p.parse('; :', 'test', prods(),
keepS=True)
self.assertTrue(w)
self.assertEqual(3, len(seq))
w, seq, store, unused = p.parse('; :', 'test', prods(),
keepS=False)
self.assertTrue(w)
self.assertEqual(2, len(seq))
def test_combi(self):
"ProdParser.parse() 2"
p1 = Prod('p1', lambda t, v: v == '1')
p2 = Prod('p2', lambda t, v: v == '2')
p3 = Prod('p3', lambda t, v: v == '3')
tests = {'1 2': True,
'1 2 1 2': True,
'3': True,
#'': 'No match in Choice(Sequence(p1, p2), p3)',
'1': 'Missing token for production p2',
'1 2 1': 'Missing token for production p2',
'1 2 1 2 x': "No match: ('IDENT', 'x', 1, 9)",
'1 2 1 2 1': "No match: ('NUMBER', '1', 1, 9)",
'3 x': "No match: ('IDENT', 'x', 1, 3)",
'3 3': "No match: ('NUMBER', '3', 1, 3)",
}
for text, exp in list(tests.items()):
prods = Choice(Sequence(p1, p2, minmax=lambda: (1,2)),
p3)
if exp is True:
wellformed, seq, store, unused = ProdParser().parse(text, 'T', prods)
self.assertEqual(wellformed, exp)
else:
self.assertRaisesMsg(xml.dom.SyntaxErr, 'T: %s' % exp,
ProdParser().parse, text, 'T', prods)
tests = {'1 3': True,
'1 1 3': True,
'2 3': True,
'1': 'Missing token for production p3',
'1 1': 'Missing token for production p3',
'1 3 3': "No match: ('NUMBER', '3', 1, 5)",
'1 1 3 3': "No match: ('NUMBER', '3', 1, 7)",
'2 3 3': "No match: ('NUMBER', '3', 1, 5)",
'2': 'Missing token for production p3',
'3': "Missing token for production Choice(Sequence(p1), p2): ('NUMBER', '3', 1, 1)",
}
for text, exp in list(tests.items()):
prods = Sequence(Choice(Sequence(p1, minmax=lambda: (1,2)),
p2),
p3)
if exp is True:
wellformed, seq, store, unused = ProdParser().parse(text, 'T', prods)
self.assertEqual(wellformed, exp)
else:
self.assertRaisesMsg(xml.dom.SyntaxErr, 'T: %s' % exp,
ProdParser().parse, text, 'T', prods)
if __name__ == '__main__':
import unittest
unittest.main()