File relax_error_msg_check.patch of Package python3-css-parser
From df7fa4a4fa625acd02aaae11a718307c830b9d7a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mat=C4=9Bj=20Cepl?= <mcepl@cepl.eu>
Date: Wed, 26 Jan 2022 01:38:54 +0100
Subject: [PATCH 1/2] Remove assertRaisesEx and assertRaisesMsgSubstring
---
css_parser_tests/basetest.py | 99 ---
css_parser_tests/test_csscharsetrule.py | 22
css_parser_tests/test_cssimportrule.py | 28 -
css_parser_tests/test_cssstylesheet.py | 10
css_parser_tests/test_cssvalue.py | 10
css_parser_tests/test_medialist.py | 27 -
css_parser_tests/test_prodparser.py | 832 ++++++++++++++++----------------
css_parser_tests/test_profiles.py | 16
css_parser_tests/test_property.py | 27 -
css_parser_tests/test_selector.py | 7
10 files changed, 491 insertions(+), 587 deletions(-)
--- a/css_parser_tests/basetest.py
+++ b/css_parser_tests/basetest.py
@@ -17,14 +17,6 @@ TEST_HOME = os.path.dirname(os.path.absp
PY2x = sys.version_info < (3, 0)
-def msg3x(msg):
- """msg might contain unicode repr `u'...'` which in py3 is `u'...`
- needed by tests using ``assertRaisesMsg``"""
- if not PY2x and msg.find("u'"):
- msg = msg.replace("u'", "'")
- return msg
-
-
def get_resource_filename(resource_name):
"""Get the resource filename.
"""
@@ -107,97 +99,6 @@ class BaseTestCase(unittest.TestCase):
if hasattr(self, '_ser'):
self._restoreSer()
- def assertRaisesEx(self, exception, callable, *args, **kwargs):
- """
- from
- http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/307970
- """
- if "exc_args" in kwargs:
- exc_args = kwargs["exc_args"]
- del kwargs["exc_args"]
- else:
- exc_args = None
- if "exc_pattern" in kwargs:
- exc_pattern = kwargs["exc_pattern"]
- del kwargs["exc_pattern"]
- else:
- exc_pattern = None
-
- argv = [repr(a) for a in args]\
- + ["%s=%r" % (k, v) for k, v in kwargs.items()]
- callsig = "%s(%s)" % (callable.__name__, ", ".join(argv))
-
- try:
- callable(*args, **kwargs)
- except exception as exc:
- if exc_args is not None:
- self.failIf(exc.args != exc_args,
- "%s raised %s with unexpected args: "
- "expected=%r, actual=%r"
- % (callsig, exc.__class__, exc_args, exc.args))
- if exc_pattern is not None:
- self.assertTrue(exc_pattern.search(str(exc)),
- "%s raised %s, but the exception "
- "does not match '%s': %r"
- % (callsig, exc.__class__, exc_pattern.pattern,
- str(exc)))
- except Exception:
- exc_info = sys.exc_info()
- self.fail("%s raised an unexpected exception type: "
- "expected=%s, actual=%s"
- % (callsig, exception, exc_info[0]))
- else:
- self.fail("%s did not raise %s" % (callsig, exception))
-
- def _assertRaisesMsgSubstring(self, excClass, msg, substring_match, callableObj, *args, **kwargs):
- try:
- callableObj(*args, **kwargs)
- except excClass as exc:
- excMsg = str(exc)
- if not msg:
- # No message provided: any message is fine.
- return
- elif (msg in excMsg if substring_match else msg == excMsg):
- # Message provided, and we got the right message: passes.
- return
- else:
- # Message provided, and it didn't match: fail!
- raise self.failureException(
- "Right exception, wrong message: got '%s' instead of '%s'" %
- (excMsg, msg))
- else:
- if hasattr(excClass, '__name__'):
- excName = excClass.__name__
- else:
- excName = str(excClass)
- raise self.failureException(
- "Expected to raise %s, didn't get an exception at all" %
- excName
- )
-
- def assertRaisesMsg(self, excClass, msg, callableObj, *args, **kwargs):
- """
- Just like unittest.TestCase.assertRaises,
- but checks that the message is right too.
-
- Usage::
-
- self.assertRaisesMsg(
- MyException, "Exception message",
- my_function, arg1, arg2,
- kwarg1=val, kwarg2=val)
-
- from
- http://www.nedbatchelder.com/blog/200609.html#e20060905T064418
- """
- return self._assertRaisesMsgSubstring(excClass, msg, False, callableObj, *args, **kwargs)
-
- def assertRaisesMsgSubstring(self, excClass, msg, callableObj, *args, **kwargs):
- """
- Just like assertRaisesMsg, but looks for substring in the message.
- """
- return self._assertRaisesMsgSubstring(excClass, msg, True, callableObj, *args, **kwargs)
-
def do_equal_p(self, tests, att='cssText', debug=False, raising=True):
"""
if raising self.p is used for parsing, else self.pf
--- a/css_parser_tests/test_csscharsetrule.py
+++ b/css_parser_tests/test_csscharsetrule.py
@@ -42,14 +42,13 @@ class CSSCharsetRuleTestCase(test_cssrul
'@charset "%s";' % enc.lower(), r.cssText)
for enc in (' ascii ', ' ascii', 'ascii '):
- self.assertRaisesEx(xml.dom.SyntaxErr,
- css_parser.css.CSSCharsetRule, enc,
- exc_pattern=re.compile("Syntax Error"))
+ with self.assertRaisesRegex(xml.dom.SyntaxErr, r"Syntax Error"):
+ css_parser.css.CSSCharsetRule(enc)
for enc in ('unknown', ):
- self.assertRaisesEx(xml.dom.SyntaxErr,
- css_parser.css.CSSCharsetRule, enc,
- exc_pattern=re.compile(r"Unknown \(Python\) encoding"))
+ with self.assertRaisesRegex(xml.dom.SyntaxErr,
+ r"Unknown \(Python\) encoding"):
+ css_parser.css.CSSCharsetRule(enc)
def test_encoding(self):
"CSSCharsetRule.encoding"
@@ -60,14 +59,13 @@ class CSSCharsetRuleTestCase(test_cssrul
'@charset "%s";' % enc.lower(), self.r.cssText)
for enc in (None, ' ascii ', ' ascii', 'ascii '):
- self.assertRaisesEx(xml.dom.SyntaxErr,
- self.r.__setattr__, 'encoding', enc,
- exc_pattern=re.compile("Syntax Error"))
+ with self.assertRaisesRegex(xml.dom.SyntaxErr, r"Syntax Error"):
+ self.r.__setattr__('encoding', enc)
for enc in ('unknown', ):
- self.assertRaisesEx(xml.dom.SyntaxErr,
- self.r.__setattr__, 'encoding', enc,
- exc_pattern=re.compile("Unknown \(Python\) encoding"))
+ with self.assertRaisesRegex(xml.dom.SyntaxErr,
+ r"Unknown \(Python\) encoding"):
+ self.r.__setattr__('encoding', enc)
def test_cssText(self):
"""CSSCharsetRule.cssText
--- a/css_parser_tests/test_cssimportrule.py
+++ b/css_parser_tests/test_cssimportrule.py
@@ -272,17 +272,17 @@ class CSSImportRuleTestCase(test_cssrule
self.r.media.appendMedium('tv')
self.assertEqual('@import url(x) print, tv;', self.r.cssText)
+ # for later exception handling
+ exc_msg = r'''MediaList: Ignoring new medium css_parser.stylesheets.MediaQuery\(mediaText='tv'\) as already specified "all" \(set ``mediaText`` instead\).'''
+
# for generated rule
r = css_parser.css.CSSImportRule(href='x')
- self.assertRaisesMsg(xml.dom.InvalidModificationErr,
- basetest.msg3x(
- '''MediaList: Ignoring new medium css_parser.stylesheets.MediaQuery(mediaText=u'tv') as already specified "all" (set ``mediaText`` instead).'''),
- r.media.appendMedium, 'tv')
+ with self.assertRaisesRegex(xml.dom.InvalidModificationErr, exc_msg):
+ r.media.appendMedium('tv')
self.assertEqual('@import url(x);', r.cssText)
- self.assertRaisesMsg(xml.dom.InvalidModificationErr,
- basetest.msg3x(
- '''MediaList: Ignoring new medium css_parser.stylesheets.MediaQuery(mediaText=u'tv') as already specified "all" (set ``mediaText`` instead).'''),
- r.media.appendMedium, 'tv')
+
+ with self.assertRaisesRegex(xml.dom.InvalidModificationErr, exc_msg):
+ r.media.appendMedium('tv')
self.assertEqual('@import url(x);', r.cssText)
r.media.mediaText = 'tv'
self.assertEqual('@import url(x) tv;', r.cssText)
@@ -293,15 +293,11 @@ class CSSImportRuleTestCase(test_cssrule
s = css_parser.parseString('@import url(x);')
r = s.cssRules[0]
- self.assertRaisesMsg(xml.dom.InvalidModificationErr,
- basetest.msg3x(
- '''MediaList: Ignoring new medium css_parser.stylesheets.MediaQuery(mediaText=u'tv') as already specified "all" (set ``mediaText`` instead).'''),
- r.media.appendMedium, 'tv')
+ with self.assertRaisesRegex(xml.dom.InvalidModificationErr, exc_msg):
+ r.media.appendMedium('tv')
self.assertEqual('@import url(x);', r.cssText)
- self.assertRaisesMsg(xml.dom.InvalidModificationErr,
- basetest.msg3x(
- '''MediaList: Ignoring new medium css_parser.stylesheets.MediaQuery(mediaText=u'tv') as already specified "all" (set ``mediaText`` instead).'''),
- r.media.appendMedium, 'tv')
+ with self.assertRaisesRegex(xml.dom.InvalidModificationErr, exc_msg):
+ r.media.appendMedium('tv')
self.assertEqual('@import url(x);', r.cssText)
r.media.mediaText = 'tv'
self.assertEqual('@import url(x) tv;', r.cssText)
--- a/css_parser_tests/test_cssstylesheet.py
+++ b/css_parser_tests/test_cssstylesheet.py
@@ -506,8 +506,9 @@ ex2|SEL4, a, ex2|SELSR {
del s.namespaces.namespaces['p']
self.assertEqual({'p': 'uri'}, s.namespaces.namespaces)
- self.assertRaisesMsg(xml.dom.NamespaceErr, "Prefix undefined not found.",
- s.namespaces.__delitem__, 'undefined')
+ with self.assertRaisesRegex(xml.dom.NamespaceErr,
+ "Prefix undefined not found."):
+ s.namespaces.__delitem__('undefined')
def test_namespaces5(self):
"CSSStyleSheet.namespaces 5"
@@ -516,8 +517,9 @@ ex2|SEL4, a, ex2|SELSR {
self.assertEqual(s.cssText, ''.encode())
s = css_parser.css.CSSStyleSheet()
- self.assertRaisesMsg(xml.dom.NamespaceErr, "Prefix a not found.",
- s._setCssText, 'a|a { color: red }')
+ with self.assertRaisesRegex(xml.dom.NamespaceErr,
+ "Prefix a not found."):
+ s._setCssText('a|a { color: red }')
def test_deleteRuleIndex(self):
"CSSStyleSheet.deleteRule(index)"
--- a/css_parser_tests/test_cssvalue.py
+++ b/css_parser_tests/test_cssvalue.py
@@ -568,11 +568,11 @@
# if type(exp) == types.TypeType or\
# type(exp) == types.ClassType: # 2.4 compatibility
# if cssText:
-# self.assertRaisesMsg(
-# exp, cssText, pv.setFloatValue, setType, setValue)
+# with self.assertRaisesRegex(exp, cssText):
+# pv.setFloatValue(setType, setValue)
# else:
-# self.assertRaises(
-# exp, pv.setFloatValue, setType, setValue)
+# with self.assertRaises(exp):
+# pv.setFloatValue(setType, setValue)
# else:
# pv.setFloatValue(setType, setValue)
# self.assertEqual(pv._value[0], cssText)
@@ -818,4 +818,4 @@
# import unittest
# unittest.main()
-from __future__ import unicode_literals
\ No newline at end of file
+from __future__ import unicode_literals
--- a/css_parser_tests/test_medialist.py
+++ b/css_parser_tests/test_medialist.py
@@ -15,6 +15,7 @@ class MediaListTestCase(basetest.BaseTes
def setUp(self):
super(MediaListTestCase, self).setUp()
self.r = css_parser.stylesheets.MediaList()
+ self.exc_msg = r'''MediaList: Ignoring new medium css_parser.stylesheets.MediaQuery\(mediaText='tv'\) as already specified "all" \(set ``mediaText`` instead\).'''
def test_set(self):
"MediaList.mediaText 1"
@@ -27,9 +28,8 @@ class MediaListTestCase(basetest.BaseTes
self.assertEqual(2, ml.length)
self.assertEqual('print, screen', ml.mediaText)
- # self.assertRaisesMsg(xml.dom.InvalidModificationErr,
- # basetest.msg3x('''MediaList: Ignoring new medium css_parser.stylesheets.MediaQuery(mediaText=u'tv') as already specified "all" (set ``mediaText`` instead).'''),
- # ml._setMediaText, u' print , all , tv ')
+ # with self.assertRaisesRegex(xml.dom.InvalidModificationErr, self.exc_msg):
+ # ml._setMediaText(u' print , all , tv ')
#
#self.assertEqual(u'all', ml.mediaText)
#self.assertEqual(1, ml.length)
@@ -89,24 +89,20 @@ class MediaListTestCase(basetest.BaseTes
self.assertEqual(1, ml.length)
self.assertEqual('all', ml.mediaText)
- self.assertRaisesMsg(xml.dom.InvalidModificationErr,
- basetest.msg3x(
- '''MediaList: Ignoring new medium css_parser.stylesheets.MediaQuery(mediaText=u'tv') as already specified "all" (set ``mediaText`` instead).'''),
- ml.appendMedium, 'tv')
+ with self.assertRaisesRegex(xml.dom.InvalidModificationErr, self.exc_msg):
+ ml.appendMedium('tv')
self.assertEqual(1, ml.length)
self.assertEqual('all', ml.mediaText)
- self.assertRaises(xml.dom.InvalidModificationErr,
- ml.appendMedium, 'test')
+ with self.assertRaises(xml.dom.InvalidModificationErr):
+ ml.appendMedium('test')
def test_append2All(self):
"MediaList all"
ml = css_parser.stylesheets.MediaList()
ml.appendMedium('all')
- self.assertRaisesMsg(xml.dom.InvalidModificationErr,
- basetest.msg3x(
- '''MediaList: Ignoring new medium css_parser.stylesheets.MediaQuery(mediaText=u'print') as already specified "all" (set ``mediaText`` instead).'''),
- ml.appendMedium, 'print')
+ with self.assertRaisesRegex(xml.dom.InvalidModificationErr, self.exc_msg.replace('tv', 'print')):
+ ml.appendMedium('print')
sheet = css_parser.parseString('@media all, print { /**/ }')
self.assertEqual('@media all {\n /**/\n }'.encode(), sheet.cssText)
@@ -144,9 +140,8 @@ class MediaListTestCase(basetest.BaseTes
# self.assertEqual(2, ml.length)
# self.assertEqual(u'handheld, all', ml.mediaText)
- # self.assertRaisesMsg(xml.dom.InvalidModificationErr,
- # basetest.msg3x('''MediaList: Ignoring new medium css_parser.stylesheets.MediaQuery(mediaText=u'handheld') as already specified "all" (set ``mediaText`` instead).'''),
- # ml._setMediaText, u' handheld , all , tv ')
+ # with self.assertRaisesRegex(xml.dom.InvalidModificationErr, self.exc_msg):
+ # ml._setMediaText(u' handheld , all , tv ')
def test_mediaText(self):
"MediaList.mediaText 2"
--- a/css_parser_tests/test_prodparser.py
+++ b/css_parser_tests/test_prodparser.py
@@ -1,410 +1,422 @@
-"""Testcases for css_parser.css.CSSCharsetRule"""
-from __future__ import absolute_import, unicode_literals
-
-import sys
-import xml.dom
-
-from css_parser.prodparser import (Choice, Exhausted, ParseError, PreDef, Prod,
- ProdParser, Sequence)
-
-from . import basetest
-
-__version__ = '$Id: test_csscharsetrule.py 1356 2008-07-13 17:29:09Z cthedot $'
-
-
-if sys.version_info.major > 2:
- basestring = str
-
-
-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)
- 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 tests.items():
- for result in results:
- seq = Sequence(*seqitems)
- for t, p in result:
- if isinstance(p, basestring):
- 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 tests.items():
- for result in results:
- seq = Sequence(minmax=lambda: (1, 2), *seqitems)
- for t, p in result:
- if isinstance(p, basestring):
- 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
- def prods(): return 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 tests.items():
- if sys.version_info.major == 2 and hasattr(exp, 'replace'):
- exp = exp.replace("('", "(u'").replace(" '", " u'")
- 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 tests.items():
- if sys.version_info.major == 2 and hasattr(exp, 'replace'):
- exp = exp.replace("('", "(u'").replace(" '", " u'")
- 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()
+"""Testcases for css_parser.css.CSSCharsetRule"""
+from __future__ import absolute_import, unicode_literals
+
+import sys
+import xml.dom
+
+from css_parser.prodparser import (Choice, Exhausted, ParseError, PreDef, Prod,
+ ProdParser, Sequence)
+
+from . import basetest
+
+__version__ = '$Id: test_csscharsetrule.py 1356 2008-07-13 17:29:09Z cthedot $'
+
+
+if sys.version_info.major > 2:
+ basestring = str
+
+
+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)
+ 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 tests.items():
+ for result in results:
+ seq = Sequence(*seqitems)
+ for t, p in result:
+ if isinstance(p, basestring):
+ with self.assertRaisesRegex(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, r'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 tests.items():
+ for result in results:
+ seq = Sequence(minmax=lambda: (1, 2), *seqitems)
+ for t, p in result:
+ if isinstance(p, basestring):
+ with self.assertRaisesRegex(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)
+ with self.assertRaisesRegex(ParseError,
+ 'No match for \(0, 0, 0, 0\) in Choice\(p1, p2\)'):
+ ch.nextProd(t0)
+ self.assertEqual(p1, ch.nextProd(t1))
+ with self.assertRaisesRegex(Exhausted, 'Extra token'):
+ ch.nextProd(t1)
+
+ ch = Choice(p1, p2)
+ self.assertEqual(p2, ch.nextProd(t2))
+ with self.assertRaisesRegex(Exhausted, 'Extra token'):
+ ch.nextProd(t2)
+
+ ch = Choice(p2, p1)
+ with self.assertRaisesRegex(ParseError,
+ 'No match for \(0, 0, 0, 0\) in Choice\(p2, p1\)'):
+ ch.nextProd(t0)
+ self.assertEqual(p1, ch.nextProd(t1))
+ with self.assertRaisesRegex(Exhausted, 'Extra token'):
+ ch.nextProd(t1)
+
+ ch = Choice(p2, p1)
+ self.assertEqual(p2, ch.nextProd(t2))
+ with self.assertRaisesRegex(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)
+ with self.assertRaisesRegex(ParseError, r'No match for \(0, 0, 0, 0\) in Choice\(Sequence\(p1, p1\), Sequence\(p2, p2\)\)'):
+ ch.nextProd(t0)
+ self.assertEqual(s1, ch.nextProd(t1))
+ with self.assertRaisesRegex(Exhausted, 'Extra token'):
+ ch.nextProd(t1)
+
+ ch = Choice(s1, s2)
+ self.assertEqual(s2, ch.nextProd(t2))
+ with self.assertRaisesRegex(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
+ def prods(): return 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': r"No match: \('IDENT', 'x', 1, 9\)",
+ '1 2 1 2 1': r"No match: \('NUMBER', '1', 1, 9\)",
+ '3 x': r"No match: \('IDENT', 'x', 1, 3\)",
+ '3 3': r"No match: \('NUMBER', '3', 1, 3\)",
+ }
+ for text, exp in tests.items():
+ if sys.version_info.major == 2 and hasattr(exp, 'replace'):
+ exp = exp.replace("('", "(u'").replace(" '", " u'")
+ 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:
+ with self.assertRaisesRegex(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': r"No match: \('NUMBER', '3', 1, 5\)",
+ '1 1 3 3': r"No match: \('NUMBER', '3', 1, 7\)",
+ '2 3 3': r"No match: \('NUMBER', '3', 1, 5\)",
+ '2': 'Missing token for production p3',
+ '3': r"Missing token for production Choice\(Sequence\(p1\), p2\): \('NUMBER', '3', 1, 1\)",
+ }
+ for text, exp in tests.items():
+ if sys.version_info.major == 2 and hasattr(exp, 'replace'):
+ exp = exp.replace("('", "(u'").replace(" '", " u'")
+ 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:
+ with self.assertRaisesRegex(xml.dom.SyntaxErr, 'T: %s' % exp):
+ ProdParser().parse(text, 'T', prods)
+
+
+if __name__ == '__main__':
+ import unittest
+ unittest.main()
--- a/css_parser_tests/test_profiles.py
+++ b/css_parser_tests/test_profiles.py
@@ -121,19 +121,17 @@ class ProfilesTestCase(basetest.BaseTest
css_parser.log.raiseExceptions = True
# raises:
- expmsg = "invalid literal for int() with base 10: 'x'"
- # Python upto 2.4 and Jython have different msg format...
- if sys.version_info[0:2] == (2, 4):
- expmsg = "invalid literal for int(): x"
- elif sys.platform.startswith('java'):
- expmsg = "invalid literal for int() with base 10: x"
+ expmsg = r"invalid literal for int\(\) with base 10: 'x'"
+ # Jython have different msg format...
+ if sys.platform.startswith('java'):
+ expmsg = r"invalid literal for int\(\) with base 10: x"
# PyPy adds the u prefix, but only in versions lower than Python 3
elif (platform.python_implementation() == "PyPy" and
sys.version_info < (3, 0)):
- expmsg = "invalid literal for int() with base 10: u'x'"
+ expmsg = r"invalid literal for int\(\) with base 10: 'x'"
- self.assertRaisesMsg(Exception, expmsg,
- css_parser.profile.validate, '-test-funcval', 'x')
+ with self.assertRaisesRegex(Exception, expmsg):
+ css_parser.profile.validate('-test-funcval', 'x')
def test_removeProfile(self):
"Profiles.removeProfile()"
--- a/css_parser_tests/test_property.py
+++ b/css_parser_tests/test_property.py
@@ -93,25 +93,25 @@ class PropertyTestCase(basetest.BaseTest
tests = {
'': (xml.dom.SyntaxErr,
- 'Property: No property name found: '),
+ 'Property: No property name found: '),
':': (xml.dom.SyntaxErr,
- 'Property: No property name found: : [1:1: :]'),
+ r'Property: No property name found: : \[1:1: :\]'),
'a': (xml.dom.SyntaxErr,
- 'Property: No ":" after name found: a [1:1: a]'),
+ r'Property: No ":" after name found: a \[1:1: a\]'),
'b !': (xml.dom.SyntaxErr,
- 'Property: No ":" after name found: b ! [1:3: !]'),
+ r'Property: No ":" after name found: b ! \[1:3: !\]'),
'/**/x': (xml.dom.SyntaxErr,
- 'Property: No ":" after name found: /**/x [1:5: x]'),
+ r'Property: No ":" after name found: /\*\*/x \[1:5: x\]'),
'c:': (xml.dom.SyntaxErr,
- "Property: No property value found: c: [1:2: :]"),
+ r"Property: No property value found: c: \[1:2: :\]"),
'd: ': (xml.dom.SyntaxErr,
- "No content to parse."),
+ r"No content to parse."),
'e:!important': (xml.dom.SyntaxErr,
- "No content to parse."),
+ r"No content to parse."),
'f: 1!': (xml.dom.SyntaxErr,
- 'Property: Invalid priority: !'),
+ r'Property: Invalid priority: !'),
'g: 1!importantX': (xml.dom.SyntaxErr,
- "Property: No CSS priority value: importantx"),
+ r"Property: No CSS priority value: importantx"),
# TODO?
# u'a: 1;': (xml.dom.SyntaxErr,
@@ -119,7 +119,8 @@ class PropertyTestCase(basetest.BaseTest
}
for test in tests:
ecp, msg = tests[test]
- self.assertRaisesMsg(ecp, msg, p._setCssText, test)
+ with self.assertRaisesRegex(ecp, msg):
+ p._setCssText(test)
def test_name(self):
"Property.name"
@@ -162,8 +163,8 @@ class PropertyTestCase(basetest.BaseTest
"Property.literalname"
p = css_parser.css.property.Property(r'c\olor', 'red')
self.assertEqual(r'c\olor', p.literalname)
- self.assertRaisesMsgSubstring(AttributeError, "can't set attribute", p.__setattr__,
- 'literalname', 'color')
+ with self.assertRaisesRegex(AttributeError, r"can't set attribute"):
+ p.__setattr__('literalname', 'color')
def test_validate(self):
"Property.valid"
--- a/css_parser_tests/test_selector.py
+++ b/css_parser_tests/test_selector.py
@@ -36,7 +36,8 @@ class SelectorTestCase(basetest.BaseTest
self.assertEqual((0, 0, 0, 1), s.specificity)
self.assertEqual(True, s.wellformed)
- self.assertRaisesEx(xml.dom.NamespaceErr, css_parser.css.Selector, 'p|b')
+ with self.assertRaises(xml.dom.NamespaceErr):
+ css_parser.css.Selector('p|b')
def test_element(self):
"Selector.element (TODO: RESOLVE)"
@@ -411,8 +412,8 @@ class SelectorTestCase(basetest.BaseTest
selector = css_parser.css.Selector()
# readonly
- def _set(): selector.specificity = 1
- self.assertRaisesMsgSubstring(AttributeError, "can't set attribute", _set)
+ with self.assertRaisesRegex(AttributeError, r"can't set attribute"):
+ selector.specificity = 1
tests = {
'*': (0, 0, 0, 0),