%PDF- %PDF-
| Direktori : /lib/python3/dist-packages/cssutils/tests/ |
| Current File : //lib/python3/dist-packages/cssutils/tests/test_util.py |
# -*- coding: utf-8 -*-
"""Testcases for cssutils.util"""
import cgi
from email import message_from_string, message_from_file
import io
import re
import sys
import urllib.request, urllib.error, urllib.parse
import xml.dom
try:
import mock
except ImportError:
mock = None
print("install mock library to run all tests")
from . import basetest
import encutils
from cssutils.util import Base, ListSeq, _readUrl, _defaultFetcher, LazyRegex
class ListSeqTestCase(basetest.BaseTestCase):
def test_all(self):
"util.ListSeq"
ls = ListSeq()
self.assertEqual(0, len(ls))
# append()
self.assertRaises(NotImplementedError, ls.append, 1)
# set
self.assertRaises(NotImplementedError, ls.__setitem__, 0, 1)
# hack:
ls.seq.append(1)
ls.seq.append(2)
# len
self.assertEqual(2, len(ls))
# __contains__
self.assertEqual(True, 1 in ls)
# get
self.assertEqual(1, ls[0])
self.assertEqual(2, ls[1])
# del
del ls[0]
self.assertEqual(1, len(ls))
self.assertEqual(False, 1 in ls)
# for in
for x in ls:
self.assertEqual(2, x)
class BaseTestCase(basetest.BaseTestCase):
def test_normalize(self):
"Base._normalize()"
b = Base()
tests = {'abcdefg ABCDEFG äöü߀ AÖÜ': 'abcdefg abcdefg äöü߀ aöü',
r'\ga\Ga\\\ ': r'gaga\ ',
r'0123456789': '0123456789',
# unicode escape seqs should have been done by
# the tokenizer...
}
for test, exp in list(tests.items()):
self.assertEqual(b._normalize(test), exp)
# static too
self.assertEqual(Base._normalize(test), exp)
def test_tokenupto(self):
"Base._tokensupto2()"
# tests nested blocks of {} [] or ()
b = Base()
tests = [
('default', 'a[{1}]({2}) { } NOT', 'a[{1}]({2}) { }', False),
('default', 'a[{1}]({2}) { } NOT', 'a[{1}]func({2}) { }', True),
('blockstartonly', 'a[{1}]({2}) { NOT', 'a[{1}]({2}) {', False),
('blockstartonly', 'a[{1}]({2}) { NOT', 'a[{1}]func({2}) {', True),
('propertynameendonly', 'a[(2)1] { }2 : a;', 'a[(2)1] { }2 :', False),
('propertynameendonly', 'a[(2)1] { }2 : a;', 'a[func(2)1] { }2 :', True),
('propertyvalueendonly', 'a{;{;}[;](;)}[;{;}[;](;)](;{;}[;](;)) 1; NOT',
'a{;{;}[;](;)}[;{;}[;](;)](;{;}[;](;)) 1;', False),
('propertyvalueendonly', 'a{;{;}[;](;)}[;{;}[;](;)](;{;}[;](;)) 1; NOT',
'a{;{;}[;]func(;)}[;{;}[;]func(;)]func(;{;}[;]func(;)) 1;', True),
('funcendonly', 'a{[1]}([3])[{[1]}[2]([3])]) NOT',
'a{[1]}([3])[{[1]}[2]([3])])', False),
('funcendonly', 'a{[1]}([3])[{[1]}[2]([3])]) NOT',
'a{[1]}func([3])[{[1]}[2]func([3])])', True),
('selectorattendonly', '[a[()]{()}([()]{()}())] NOT',
'[a[()]{()}([()]{()}())]', False),
('selectorattendonly', '[a[()]{()}([()]{()}())] NOT',
'[a[func()]{func()}func([func()]{func()}func())]', True),
# issue 50
('withstarttoken [', 'a];x', '[a];', False)
]
for typ, values, exp, paransasfunc in tests:
def maketokens(valuelist):
# returns list of tuples
return [('TYPE', v, 0, 0) for v in valuelist]
tokens = maketokens(list(values))
if paransasfunc:
for i, t in enumerate(tokens):
if '(' == t[1]:
tokens[i] = ('FUNCTION', 'func(', t[2], t[3])
if 'default' == typ:
restokens = b._tokensupto2(tokens)
elif 'blockstartonly' == typ:
restokens = b._tokensupto2(
tokens, blockstartonly=True)
elif 'propertynameendonly' == typ:
restokens = b._tokensupto2(
tokens, propertynameendonly=True)
elif 'propertyvalueendonly' == typ:
restokens = b._tokensupto2(
tokens, propertyvalueendonly=True)
elif 'funcendonly' == typ:
restokens = b._tokensupto2(
tokens, funcendonly=True)
elif 'selectorattendonly' == typ:
restokens = b._tokensupto2(
tokens, selectorattendonly=True)
elif 'withstarttoken [' == typ:
restokens = b._tokensupto2(tokens, ('CHAR', '[', 0, 0))
res = ''.join([t[1] for t in restokens])
self.assertEqual(exp, res)
class _readUrl_TestCase(basetest.BaseTestCase):
"""needs mock"""
def test_readUrl(self):
"""util._readUrl()"""
# for additional tests see test_parse.py
url = 'http://example.com/test.css'
def make_fetcher(r):
# normally r == encoding, content
def fetcher(url):
return r
return fetcher
tests = {
# defaultFetcher returns: readUrl returns
None: (None, None, None),
(None, ''): ('utf-8', 5, ''),
(None, '€'.encode('utf-8')): ('utf-8', 5, '€'),
('utf-8', '€'.encode('utf-8')): ('utf-8', 1, '€'),
('ISO-8859-1', 'ä'.encode('iso-8859-1')): ('ISO-8859-1', 1, 'ä'),
('ASCII', 'a'.encode('ascii')): ('ASCII', 1, 'a')
}
for r, exp in list(tests.items()):
self.assertEqual(_readUrl(url, fetcher=make_fetcher(r)), exp)
tests = {
# (overrideEncoding, parentEncoding, (httpencoding, content)):
# readUrl returns
# ===== 0. OVERRIDE WINS =====
# override + parent + http
('latin1', 'ascii', ('utf-16', ''.encode())): ('latin1', 0, ''),
('latin1', 'ascii', ('utf-16', '123'.encode())): ('latin1', 0, '123'),
('latin1', 'ascii', ('utf-16', 'ä'.encode('iso-8859-1'))):
('latin1', 0, 'ä'),
('latin1', 'ascii', ('utf-16', 'a'.encode('ascii'))):
('latin1',0, 'a'),
# + @charset
('latin1', 'ascii', ('utf-16', '@charset "ascii";'.encode())):
('latin1', 0, '@charset "latin1";'),
('latin1', 'ascii', ('utf-16', '@charset "utf-8";ä'.encode('latin1'))):
('latin1', 0, '@charset "latin1";ä'),
('latin1', 'ascii', ('utf-16', '@charset "utf-8";ä'.encode('utf-8'))):
('latin1', 0, '@charset "latin1";\xc3\xa4'), # read as latin1!
# override only
('latin1', None, None): (None, None, None),
('latin1', None, (None, ''.encode())): ('latin1', 0, ''),
('latin1', None, (None, '123'.encode())): ('latin1', 0, '123'),
('latin1', None, (None, 'ä'.encode('iso-8859-1'))):
('latin1', 0, 'ä'),
('latin1', None, (None, 'a'.encode('ascii'))):
('latin1', 0, 'a'),
# + @charset
('latin1', None, (None, '@charset "ascii";'.encode())):
('latin1', 0, '@charset "latin1";'),
('latin1', None, (None, '@charset "utf-8";ä'.encode('latin1'))):
('latin1', 0, '@charset "latin1";ä'),
('latin1', None, (None, '@charset "utf-8";ä'.encode('utf-8'))):
('latin1', 0, '@charset "latin1";\xc3\xa4'), # read as latin1!
# override + parent
('latin1', 'ascii', None): (None, None, None),
('latin1', 'ascii', (None, ''.encode())): ('latin1', 0, ''),
('latin1', 'ascii', (None, '123'.encode())): ('latin1', 0, '123'),
('latin1', 'ascii', (None, 'ä'.encode('iso-8859-1'))):
('latin1', 0, 'ä'),
('latin1', 'ascii', (None, 'a'.encode('ascii'))):
('latin1', 0, 'a'),
# + @charset
('latin1', 'ascii', (None, '@charset "ascii";'.encode())):
('latin1', 0, '@charset "latin1";'),
('latin1', 'ascii', (None, '@charset "utf-8";ä'.encode('latin1'))):
('latin1', 0, '@charset "latin1";ä'),
('latin1', 'ascii', (None, '@charset "utf-8";ä'.encode('utf-8'))):
('latin1', 0, '@charset "latin1";\xc3\xa4'), # read as latin1!
# override + http
('latin1', None, ('utf-16', ''.encode())): ('latin1', 0, ''),
('latin1', None, ('utf-16', '123'.encode())): ('latin1', 0, '123'),
('latin1', None, ('utf-16', 'ä'.encode('iso-8859-1'))):
('latin1', 0, 'ä'),
('latin1', None, ('utf-16', 'a'.encode('ascii'))):
('latin1', 0, 'a'),
# + @charset
('latin1', None, ('utf-16', '@charset "ascii";'.encode())):
('latin1', 0, '@charset "latin1";'),
('latin1', None, ('utf-16', '@charset "utf-8";ä'.encode('latin1'))):
('latin1', 0, '@charset "latin1";ä'),
('latin1', None, ('utf-16', '@charset "utf-8";ä'.encode('utf-8'))):
('latin1', 0, '@charset "latin1";\xc3\xa4'), # read as latin1!
# override ü @charset
('latin1', None, (None, '@charset "ascii";'.encode())):
('latin1', 0, '@charset "latin1";'),
('latin1', None, (None, '@charset "utf-8";ä'.encode('latin1'))):
('latin1', 0, '@charset "latin1";ä'),
('latin1', None, (None, '@charset "utf-8";ä'.encode('utf-8'))):
('latin1', 0, '@charset "latin1";\xc3\xa4'), # read as latin1!
# ===== 1. HTTP WINS =====
(None, 'ascii', ('latin1', ''.encode())): ('latin1', 1, ''),
(None, 'ascii', ('latin1', '123'.encode())): ('latin1', 1, '123'),
(None, 'ascii', ('latin1', 'ä'.encode('iso-8859-1'))):
('latin1', 1, 'ä'),
(None, 'ascii', ('latin1', 'a'.encode('ascii'))):
('latin1', 1, 'a'),
# + @charset
(None, 'ascii', ('latin1', '@charset "ascii";'.encode())):
('latin1', 1, '@charset "latin1";'),
(None, 'ascii', ('latin1', '@charset "utf-8";ä'.encode('latin1'))):
('latin1', 1, '@charset "latin1";ä'),
(None, 'ascii', ('latin1', '@charset "utf-8";ä'.encode('utf-8'))):
('latin1', 1, '@charset "latin1";\xc3\xa4'), # read as latin1!
# ===== 2. @charset WINS =====
(None, 'ascii', (None, '@charset "latin1";'.encode())):
('latin1', 2, '@charset "latin1";'),
(None, 'ascii', (None, '@charset "latin1";ä'.encode('latin1'))):
('latin1', 2, '@charset "latin1";ä'),
(None, 'ascii', (None, '@charset "latin1";ä'.encode('utf-8'))):
('latin1', 2, '@charset "latin1";\xc3\xa4'), # read as latin1!
# ===== 2. BOM WINS =====
(None, 'ascii', (None, 'ä'.encode('utf-8-sig'))):
('utf-8-sig', 2, '\xe4'), # read as latin1!
(None, 'ascii', (None, '@charset "utf-8";ä'.encode('utf-8-sig'))):
('utf-8-sig', 2, '@charset "utf-8";\xe4'), # read as latin1!
(None, 'ascii', (None, '@charset "latin1";ä'.encode('utf-8-sig'))):
('utf-8-sig', 2, '@charset "utf-8";\xe4'), # read as latin1!
# ===== 4. parentEncoding WINS =====
(None, 'latin1', (None, ''.encode())): ('latin1', 4, ''),
(None, 'latin1', (None, '123'.encode())): ('latin1', 4, '123'),
(None, 'latin1', (None, 'ä'.encode('iso-8859-1'))):
('latin1', 4, 'ä'),
(None, 'latin1', (None, 'a'.encode('ascii'))):
('latin1', 4, 'a'),
(None, 'latin1', (None, 'ä'.encode('utf-8'))):
('latin1', 4, '\xc3\xa4'), # read as latin1!
# ===== 5. default WINS which in this case is None! =====
(None, None, (None, ''.encode())): ('utf-8', 5, ''),
(None, None, (None, '123'.encode())): ('utf-8', 5, '123'),
(None, None, (None, 'a'.encode('ascii'))):
('utf-8', 5, 'a'),
(None, None, (None, 'ä'.encode('utf-8'))):
('utf-8', 5, 'ä'), # read as utf-8
(None, None, (None, 'ä'.encode('iso-8859-1'))): # trigger UnicodeDecodeError!
('utf-8', 5, None),
}
for (override, parent, r), exp in list(tests.items()):
self.assertEqual(_readUrl(url,
overrideEncoding=override,
parentEncoding=parent,
fetcher=make_fetcher(r)),
exp)
def test_defaultFetcher(self):
"""util._defaultFetcher"""
if mock:
class Response(object):
"""urllib2.Reponse mock"""
def __init__(self, url,
contenttype, content,
exception=None, args=None):
self.url = url
mt, params = cgi.parse_header(contenttype)
self.mimetype = mt
self.charset = params.get('charset', None)
self.text = content
self.exception = exception
self.args = args
def geturl(self):
return self.url
def info(self):
mimetype, charset = self.mimetype, self.charset
class Info(object):
# py2x
def gettype(self):
return mimetype
def getparam(self, name=None):
return charset
# py 3x
get_content_type = gettype
get_content_charset = getparam # here always charset!
return Info()
def read(self):
# returns fake text or raises fake exception
if not self.exception:
return self.text
else:
raise self.exception(*self.args)
def urlopen(url,
contenttype=None, content=None,
exception=None, args=None):
# return an mock which returns parameterized Response
def x(*ignored):
if exception:
raise exception(*args)
else:
return Response(url,
contenttype, content,
exception=exception, args=args)
return x
urlopenpatch = 'urllib2.urlopen' if basetest.PY2x else 'urllib.request.urlopen'
# positive tests
tests = {
# content-type, contentstr: encoding, contentstr
('text/css', '€'.encode('utf-8')):
(None, '€'.encode('utf-8')),
('text/css;charset=utf-8', '€'.encode('utf-8')):
('utf-8', '€'.encode('utf-8')),
('text/css;charset=ascii', 'a'):
('ascii', 'a')
}
url = 'http://example.com/test.css'
for (contenttype, content), exp in list(tests.items()):
@mock.patch(urlopenpatch, new=urlopen(url, contenttype, content))
def do(url):
return _defaultFetcher(url)
self.assertEqual(exp, do(url))
# wrong mimetype
@mock.patch(urlopenpatch, new=urlopen(url, 'text/html', 'a'))
def do(url):
return _defaultFetcher(url)
self.assertRaises(ValueError, do, url)
# calling url results in fake exception
# py2 ~= py3 raises error earlier than urlopen!
tests = {
'1': (ValueError, ['invalid value for url']),
#_readUrl('mailto:a.css')
'mailto:e4': (urllib.error.URLError, ['urlerror']),
# cannot resolve x, IOError
'http://x': (urllib.error.URLError, ['ioerror']),
}
for url, (exception, args) in list(tests.items()):
@mock.patch(urlopenpatch, new=urlopen(url, exception=exception, args=args))
def do(url):
return _defaultFetcher(url)
self.assertRaises(exception, do, url)
# py2 != py3 raises error earlier than urlopen!
urlrequestpatch = 'urllib2.urlopen' if basetest.PY2x else 'urllib.request.Request'
tests = {
#_readUrl('http://cthedot.de/__UNKNOWN__.css')
'e2': (urllib.error.HTTPError, ['u', 500, 'server error', {}, None]),
'e3': (urllib.error.HTTPError, ['u', 404, 'not found', {}, None]),
}
for url, (exception, args) in list(tests.items()):
@mock.patch(urlrequestpatch, new=urlopen(url, exception=exception, args=args))
def do(url):
return _defaultFetcher(url)
self.assertRaises(exception, do, url)
else:
self.assertEqual(False, 'Mock needed for this test')
class TestLazyRegex(basetest.BaseTestCase):
"""Tests for cssutils.util.LazyRegex."""
def setUp(self):
self.lazyre = LazyRegex('f.o')
def test_public_interface(self):
methods = ['search', 'match', 'split', 'sub', 'subn', 'findall',
'finditer', 'pattern', 'flags', 'groups', 'groupindex',]
for method in methods:
self.assertTrue(hasattr(self.lazyre, method),
'expected %r public attribute' % method)
def test_ensure(self):
self.assertIsNone(self.lazyre.matcher)
self.lazyre.ensure()
self.assertIsNotNone(self.lazyre.matcher)
def test_calling(self):
self.assertIsNone(self.lazyre('bar'))
match = self.lazyre('foobar')
self.assertEqual(match.group(), 'foo')
def test_matching(self):
self.assertIsNone(self.lazyre.match('bar'))
match = self.lazyre.match('foobar')
self.assertEqual(match.group(), 'foo')
def test_matching_with_position_parameters(self):
self.assertIsNone(self.lazyre.match('foo', 1))
self.assertIsNone(self.lazyre.match('foo', 0, 2))
def test_searching(self):
self.assertIsNone(self.lazyre.search('rafuubar'))
match = self.lazyre.search('rafoobar')
self.assertEqual(match.group(), 'foo')
def test_searching_with_position_parameters(self):
self.assertIsNone(self.lazyre.search('rafoobar', 3))
self.assertIsNone(self.lazyre.search('rafoobar', 0, 4))
match = self.lazyre.search('rafoofuobar', 4)
self.assertEqual(match.group(), 'fuo')
def test_split(self):
self.assertEqual(self.lazyre.split('rafoobarfoobaz'),
['ra', 'bar', 'baz'])
self.assertEqual(self.lazyre.split('rafoobarfoobaz', 1),
['ra', 'barfoobaz'])
def test_findall(self):
self.assertEqual(self.lazyre.findall('rafoobarfuobaz'),
['foo', 'fuo'])
def test_finditer(self):
result = self.lazyre.finditer('rafoobarfuobaz')
self.assertEqual([m.group() for m in result], ['foo', 'fuo'])
def test_sub(self):
self.assertEqual(self.lazyre.sub('bar', 'foofoo'), 'barbar')
self.assertEqual(self.lazyre.sub(lambda x: 'baz', 'foofoo'), 'bazbaz')
def test_subn(self):
subbed = self.lazyre.subn('bar', 'foofoo')
self.assertEqual(subbed, ('barbar', 2))
subbed = self.lazyre.subn(lambda x: 'baz', 'foofoo')
self.assertEqual(subbed, ('bazbaz', 2))
def test_groups(self):
lazyre = LazyRegex('(.)(.)')
self.assertIsNone(lazyre.groups)
lazyre.ensure()
self.assertEqual(lazyre.groups, 2)
def test_groupindex(self):
lazyre = LazyRegex('(?P<foo>.)')
self.assertIsNone(lazyre.groupindex)
lazyre.ensure()
self.assertEqual(lazyre.groupindex, {'foo': 1})
def test_flags(self):
self.lazyre.ensure()
self.assertEqual(self.lazyre.flags, re.compile('.').flags)
def test_pattern(self):
self.assertEqual(self.lazyre.pattern, 'f.o')
if __name__ == '__main__':
import unittest
unittest.main()