diff -Nru cssutils-0.9.10~b1/PKG-INFO cssutils-0.9.10/PKG-INFO --- cssutils-0.9.10~b1/PKG-INFO 2012-04-28 15:10:00.000000000 +0000 +++ cssutils-0.9.10/PKG-INFO 2013-03-31 20:03:46.000000000 +0000 @@ -1,6 +1,6 @@ -Metadata-Version: 1.0 +Metadata-Version: 1.1 Name: cssutils -Version: 0.9.10b1 +Version: 0.9.10 Summary: A CSS Cascading Style Sheets library for Python Home-page: http://cthedot.de/cssutils/ Author: Christof Hoeke @@ -16,7 +16,7 @@ ------------------------------------------------------- cssutils: CSS Cascading Style Sheets library for Python ------------------------------------------------------- - :Copyright: 2004-2012 Christof Hoeke + :Copyright: 2004-2013 Christof Hoeke Overview ======== @@ -61,11 +61,11 @@ Compatibility ============= - cssutils is developed on standard Python but works under Python 2.x (from 2.5, v2.5.4 tested), 3.x (v3.2.2 tested) and Jython (from 2.5.1). IronPython has not been tested yet but might work? Python 2.4 and older are not supported since cssutils 0.9.8 anymore. + cssutils is developed on standard Python but works under Python 2.x (from 2.5, 2.7.3 tested), 3.x (v3.3 tested) and Jython (from 2.5.1). IronPython has not been tested yet but might work? Python 2.4 and older are not supported since cssutils 0.9.8 anymore. License ======= - Copyright 2005 - 2012 Christof Hoeke + Copyright 2005 - 2013 Christof Hoeke cssutils is published under the LGPL 3 or later @@ -171,6 +171,7 @@ Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3.2 +Classifier: Programming Language :: Python :: 3.3 Classifier: Topic :: Internet Classifier: Topic :: Software Development :: Libraries :: Python Modules Classifier: Topic :: Text Processing :: Markup :: HTML diff -Nru cssutils-0.9.10~b1/README.txt cssutils-0.9.10/README.txt --- cssutils-0.9.10~b1/README.txt 2012-01-31 19:23:10.000000000 +0000 +++ cssutils-0.9.10/README.txt 2013-03-31 19:53:08.000000000 +0000 @@ -6,7 +6,7 @@ ------------------------------------------------------- cssutils: CSS Cascading Style Sheets library for Python ------------------------------------------------------- -:Copyright: 2004-2012 Christof Hoeke +:Copyright: 2004-2013 Christof Hoeke Overview ======== @@ -51,11 +51,11 @@ Compatibility ============= -cssutils is developed on standard Python but works under Python 2.x (from 2.5, v2.5.4 tested), 3.x (v3.2.2 tested) and Jython (from 2.5.1). IronPython has not been tested yet but might work? Python 2.4 and older are not supported since cssutils 0.9.8 anymore. +cssutils is developed on standard Python but works under Python 2.x (from 2.5, 2.7.3 tested), 3.x (v3.3 tested) and Jython (from 2.5.1). IronPython has not been tested yet but might work? Python 2.4 and older are not supported since cssutils 0.9.8 anymore. License ======= -Copyright 2005 - 2012 Christof Hoeke +Copyright 2005 - 2013 Christof Hoeke cssutils is published under the LGPL 3 or later diff -Nru cssutils-0.9.10~b1/debian/changelog cssutils-0.9.10/debian/changelog --- cssutils-0.9.10~b1/debian/changelog 2013-05-22 18:23:03.000000000 +0000 +++ cssutils-0.9.10/debian/changelog 2013-10-06 08:49:10.000000000 +0000 @@ -1,3 +1,15 @@ +cssutils (0.9.10-1) unstable; urgency=low + + * New upstream release. + * Removed debian/python3-cssutils.examples. Closes: #712150 + * Updated debian/rules to account for upstream directory changes. + * With upstream directory changes the test dir renaming is not needed so + removed from debian/rules. + * Reworked debian/patches/02_disable_wrong_test.patch, one test has been + removed by upstream. + + -- Charlie Smotherman Sun, 06 Oct 2013 03:49:10 -0500 + cssutils (0.9.10~b1-2) unstable; urgency=low * Team upload. diff -Nru cssutils-0.9.10~b1/debian/control cssutils-0.9.10/debian/control --- cssutils-0.9.10~b1/debian/control 2013-05-05 16:01:13.000000000 +0000 +++ cssutils-0.9.10/debian/control 2013-09-18 05:01:38.000000000 +0000 @@ -14,7 +14,7 @@ python3-setuptools, python3-nose (>= 1.1.2-2), python3-mock -Standards-Version: 3.9.3 +Standards-Version: 3.9.4 Homepage: https://bitbucket.org/cthedot/cssutils X-Python-Version: >= 2.5 X-Python3-Version: >= 3.0 diff -Nru cssutils-0.9.10~b1/debian/copyright cssutils-0.9.10/debian/copyright --- cssutils-0.9.10~b1/debian/copyright 2012-05-05 18:21:51.000000000 +0000 +++ cssutils-0.9.10/debian/copyright 2013-10-06 09:30:11.000000000 +0000 @@ -5,7 +5,7 @@ Source: http://code.google.com/p/cssutils/downloads/list Files: * -Copyright: 2004-2012 Christof Hoeke +Copyright: 2004-2013 Christof Hoeke 2004-2012 Walter Doerwald License: LGPL-3+ encutils is free software: you can redistribute it and/or modify it under the @@ -35,7 +35,7 @@ Copyright: 2008 Bernd Zeimetz 2008 Damien Churchill 2008 Loïc Minier - 2011 Charlie Smotherman + 2011-2013 Charlie Smotherman License: LGPL-2.1 This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free diff -Nru cssutils-0.9.10~b1/debian/patches/02_disable_wrong_tests.patch cssutils-0.9.10/debian/patches/02_disable_wrong_tests.patch --- cssutils-0.9.10~b1/debian/patches/02_disable_wrong_tests.patch 2013-05-22 17:46:00.000000000 +0000 +++ cssutils-0.9.10/debian/patches/02_disable_wrong_tests.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +0,0 @@ -Description: disable two tests that caused the package to FTBFS - First one is wrong and already removed upstream: - https://bitbucket.org/cthedot/cssutils/commits/153f6254f3/ - . - Another one is sometimes failing with hash randomization enabled, - see https://bitbucket.org/cthedot/cssutils/issue/30/ -Bug-Debian: http://bugs.debian.org/686340 -Last-Update: 2013-05-19 - ---- a/src/tests/test_cssstylesheet.py -+++ b/src/tests/test_cssstylesheet.py -@@ -333,7 +333,7 @@ - self.assertEquals('example', s.namespaces['ex2']) - self.assertRaises(xml.dom.NamespaceErr, s.namespaces.__getitem__, 'UNSET') - # __iter__ -- self.assertEquals(['', 'ex2'], list(s.namespaces)) -+ #self.assertEquals(['', 'ex2'], list(s.namespaces)) - # __len__ - self.assertEqual(2, len(s.namespaces)) - # __setitem__ ---- a/src/tests/test_encutils/__init__.py -+++ b/src/tests/test_encutils/__init__.py -@@ -153,9 +153,9 @@ - """ - """: - ('text/html', 'ascii'), -- """ -- """: -- (None, None), -+# """ -+# """: -+# (None, None), - """ - - """: diff -Nru cssutils-0.9.10~b1/debian/patches/disable_test.patch cssutils-0.9.10/debian/patches/disable_test.patch --- cssutils-0.9.10~b1/debian/patches/disable_test.patch 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/debian/patches/disable_test.patch 2013-09-18 04:46:21.000000000 +0000 @@ -0,0 +1,19 @@ +Description: disable test that caused the package to FTBFS +Author: Charlie Smotherman +Last-Update: 2013-09-17 + + + +Index: cssutils-0.9.10/src/cssutils/tests/test_cssstylesheet.py +=================================================================== +--- cssutils-0.9.10.orig/src/cssutils/tests/test_cssstylesheet.py 2013-03-31 17:42:26.000000000 -0500 ++++ cssutils-0.9.10/src/cssutils/tests/test_cssstylesheet.py 2013-09-16 07:19:18.633097907 -0500 +@@ -333,7 +333,7 @@ + self.assertEquals('example', s.namespaces['ex2']) + self.assertRaises(xml.dom.NamespaceErr, s.namespaces.__getitem__, 'UNSET') + # __iter__ +- self.assertEquals(['', 'ex2'], list(s.namespaces)) ++# self.assertEquals(['', 'ex2'], list(s.namespaces)) + # __len__ + self.assertEqual(2, len(s.namespaces)) + # __setitem__ diff -Nru cssutils-0.9.10~b1/debian/patches/series cssutils-0.9.10/debian/patches/series --- cssutils-0.9.10~b1/debian/patches/series 2013-05-22 17:46:00.000000000 +0000 +++ cssutils-0.9.10/debian/patches/series 2013-09-18 04:46:21.000000000 +0000 @@ -1,2 +1,2 @@ +disable_test.patch 01_setup_fix.patch -02_disable_wrong_tests.patch diff -Nru cssutils-0.9.10~b1/debian/python3-cssutils.examples cssutils-0.9.10/debian/python3-cssutils.examples --- cssutils-0.9.10~b1/debian/python3-cssutils.examples 2011-11-11 08:42:48.000000000 +0000 +++ cssutils-0.9.10/debian/python3-cssutils.examples 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -examples/* diff -Nru cssutils-0.9.10~b1/debian/rules cssutils-0.9.10/debian/rules --- cssutils-0.9.10~b1/debian/rules 2013-02-22 06:06:22.000000000 +0000 +++ cssutils-0.9.10/debian/rules 2013-09-19 11:02:19.000000000 +0000 @@ -29,7 +29,7 @@ --exclude='test_cssText2' \ --exclude='test_getMetaInfo' \ --exclude='test_errorhandler.py' \ - --where $(CURDIR)/build/lib.linux-*/tests; \ + --where $(CURDIR)/build/lib.linux-*/cssutils/tests; \ done set -ex; \ for py in $(PY3VERS); do \ @@ -40,7 +40,7 @@ --exclude='test_combine' \ --exclude='test_cssText2' \ --exclude='test_errorhandler.py' \ - --py3where $(CURDIR)/build/lib/tests; \ + --py3where $(CURDIR)/build/lib/cssutils/tests; \ done endif @@ -49,8 +49,6 @@ for py in $(PYVERS); do \ $$py setup.py install --skip-build --root debian/python-cssutils \ --install-layout deb; \ - mv $(DESTDIR2)/usr/lib/$$py/dist-packages/tests \ - $(DESTDIR2)/usr/lib/$$py/dist-packages/cssutils_tests; \ done #fix our py2 shebangs sed -i -e 's,#!/usr/bin/python.*,#!/usr/bin/python,' $(DESTDIR2)/usr/bin/cssparse_py2 \ @@ -63,8 +61,6 @@ for py in $(PY3VERS); do \ $$py setup.py install --skip-build --root debian/python3-cssutils \ --install-layout deb; \ - mv $(DESTDIR3)/usr/lib/python3/dist-packages/tests \ - $(DESTDIR3)/usr/lib/python3/dist-packages/cssutils_tests; \ done #fix our py3 shebangs sed -i -e 's,#!/usr/bin/python.*,#!/usr/bin/python3,' $(DESTDIR3)/usr/bin/cssparse_py3 \ diff -Nru cssutils-0.9.10~b1/setup.py cssutils-0.9.10/setup.py --- cssutils-0.9.10~b1/setup.py 2012-03-24 15:20:04.000000000 +0000 +++ cssutils-0.9.10/setup.py 2013-03-31 19:07:34.000000000 +0000 @@ -7,7 +7,7 @@ >python setup.py install """ __docformat__ = 'restructuredtext' -__author__ = 'Christof Hoeke with contributions by Walter Doerwald' +__author__ = 'Christof Hoeke with contributions by Walter Doerwald and lots of other people' __date__ = '$LastChangedDate:: $:' import codecs @@ -49,7 +49,7 @@ version=VERSION, package_dir={'':'src'}, packages=find_packages('src'), - test_suite='tests', #'nose.collector' + test_suite='cssutils.tests', #'nose.collector' tests_require='mock', entry_points={ 'console_scripts': [ @@ -82,6 +82,7 @@ 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3.2', + 'Programming Language :: Python :: 3.3', 'Topic :: Internet', 'Topic :: Software Development :: Libraries :: Python Modules', 'Topic :: Text Processing :: Markup :: HTML' diff -Nru cssutils-0.9.10~b1/setup3.py cssutils-0.9.10/setup3.py --- cssutils-0.9.10~b1/setup3.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/setup3.py 2013-03-31 15:56:00.000000000 +0000 @@ -0,0 +1,92 @@ +# -*- coding: utf-8 -*- +#!/usr/bin/env python +""" +cssutils setup + +use EasyInstall or install with + >python setup.py install +""" +__docformat__ = 'restructuredtext' +__author__ = 'Christof Hoeke with contributions by Walter Doerwald' +__date__ = '$LastChangedDate:: $:' + +import codecs +import os +import sys + +# For Python 2.5 +try: + next +except NameError: + next = lambda iter: iter.next + +# extract the version without importing the module +lines = open('src3/cssutils/__init__.py') +is_ver_line = lambda line: line.startswith('VERSION = ') +line = next(line for line in lines if is_ver_line(line)) + +# For Python 2.5 +try: + exec(line, locals(), globals()) +except TypeError: + exec(line(), locals(), globals()) + +# use the build_py_2to3 if we're building on Python 3 +try: + from distutils.command.build_py import build_py_2to3 as build_py +except ImportError: + from distutils.command.build_py import build_py + +try: + from setuptools import setup, find_packages +except ImportError: + from ez_setup import use_setuptools + use_setuptools() + from setuptools import setup, find_packages + +def read(*rnames): + return codecs.open(os.path.join(*rnames), encoding='utf-8').read() + +long_description = '\n' + read('README.txt') + '\n'# + read('CHANGELOG.txt') + +setup( + name='cssutils', + version=VERSION, + package_dir={'':'src3'}, + packages=find_packages('src3'), + test_suite='cssutils.tests', #'nose.collector' + tests_require='mock', + entry_points={ + 'console_scripts': [ + 'csscapture = cssutils.scripts.csscapture:main', + 'csscombine = cssutils.scripts.csscombine:main', + 'cssparse = cssutils.scripts.cssparse:main' + ] + }, + description='A CSS Cascading Style Sheets library for Python', + long_description=long_description, + author='Christof Hoeke', + author_email='c@cthedot.de', + url='http://cthedot.de/cssutils/', + download_url='http://code.google.com/p/cssutils/downloads/list', + license='LGPL 2.1 or later, see also http://cthedot.de/cssutils/', + keywords='CSS, Cascading Style Sheets, CSSParser, DOM Level 2 Stylesheets, DOM Level 2 CSS', + platforms='Python 3.2 and later.', + cmdclass=dict( + # specify the build_py command imported earlier + build_py=build_py, + ), + classifiers=[ + 'Development Status :: 4 - Beta', + 'Environment :: Web Environment', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)', + 'Operating System :: OS Independent', + 'Programming Language :: Python', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 3', + 'Topic :: Internet', + 'Topic :: Software Development :: Libraries :: Python Modules', + 'Topic :: Text Processing :: Markup :: HTML' + ] + ) diff -Nru cssutils-0.9.10~b1/sheets/import/import-impossible.css cssutils-0.9.10/sheets/import/import-impossible.css --- cssutils-0.9.10~b1/sheets/import/import-impossible.css 2011-07-24 18:24:04.000000000 +0000 +++ cssutils-0.9.10/sheets/import/import-impossible.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -@namespace "y"; -@media tv {} -.import4 { - background: url(images2/example2.gif); - } diff -Nru cssutils-0.9.10~b1/sheets/import/import2.css cssutils-0.9.10/sheets/import/import2.css --- cssutils-0.9.10~b1/sheets/import/import2.css 2011-07-24 18:24:04.000000000 +0000 +++ cssutils-0.9.10/sheets/import/import2.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ -@import "../import3.css"; -@import "import-impossible.css" print; -.import2 { - /* sheets/import2.css */ - background: url(http://example.com/images/example.gif); - background: url(//example.com/images/example.gif); - background: url(/images/example.gif); - background: url(images2/example.gif); - background: url(./images2/example.gif); - background: url(../images/example.gif); - background: url(./../images/example.gif); - } \ No newline at end of file diff -Nru cssutils-0.9.10~b1/sheets/var/start.css cssutils-0.9.10/sheets/var/start.css --- cssutils-0.9.10~b1/sheets/var/start.css 2011-07-24 18:24:04.000000000 +0000 +++ cssutils-0.9.10/sheets/var/start.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ -@import "vars.css"; -@import "vars2.css"; -@import "use.css"; - -@variables { - TEST: 1px; - T2: 'T2' -} - -a { - left: var(T2); -} diff -Nru cssutils-0.9.10~b1/sheets/var/use.css cssutils-0.9.10/sheets/var/use.css --- cssutils-0.9.10~b1/sheets/var/use.css 2011-07-24 18:24:04.000000000 +0000 +++ cssutils-0.9.10/sheets/var/use.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -a { - content: var(TEST) -} -a { - content: var(TEST) -} -a { - content: var(TEST) -} -a { - content: var(TEST) -} -a { - content: var(TEST) -} -a { - content: var(TEST) -} -a { - content: var(TEST) -} -a { - content: var(TEST) -} -a { - content: var(TEST) -} -a { - content: var(TEST) -} diff -Nru cssutils-0.9.10~b1/sheets/var/vars.css cssutils-0.9.10/sheets/var/vars.css --- cssutils-0.9.10~b1/sheets/var/vars.css 2011-07-24 18:24:04.000000000 +0000 +++ cssutils-0.9.10/sheets/var/vars.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -@variables { - TEST: 1px; - T2: 'T2' -} diff -Nru cssutils-0.9.10~b1/sheets/var/vars2.css cssutils-0.9.10/sheets/var/vars2.css --- cssutils-0.9.10~b1/sheets/var/vars2.css 2011-07-24 18:24:04.000000000 +0000 +++ cssutils-0.9.10/sheets/var/vars2.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -@variables { - TEST: 'VARS2' -} diff -Nru cssutils-0.9.10~b1/src/cssutils/__init__.py cssutils-0.9.10/src/cssutils/__init__.py --- cssutils-0.9.10~b1/src/cssutils/__init__.py 2012-04-28 14:55:08.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/__init__.py 2013-03-31 19:51:40.000000000 +0000 @@ -1,7 +1,7 @@ #!/usr/bin/env python """cssutils - CSS Cascading Style Sheets library for Python - Copyright (C) 2004-2012 Christof Hoeke + Copyright (C) 2004-2013 Christof Hoeke cssutils is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -70,7 +70,7 @@ Please visit http://cthedot.de/cssutils/ for more details. -Tested with Python 2.7 on Windows 7 mainly. +Tested with Python 2.7.3 and 3.3 on Windows 8 64bit. This library may be used ``from cssutils import *`` which @@ -93,7 +93,7 @@ __author__ = 'Christof Hoeke with contributions by Walter Doerwald' __date__ = '$LastChangedDate:: $:' -VERSION = '0.9.10b1' +VERSION = '0.9.10' __version__ = '%s $Id$' % VERSION diff -Nru cssutils-0.9.10~b1/src/cssutils/css/cssstyledeclaration.py cssutils-0.9.10/src/cssutils/css/cssstyledeclaration.py --- cssutils-0.9.10~b1/src/cssutils/css/cssstyledeclaration.py 2011-12-26 12:26:38.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/css/cssstyledeclaration.py 2013-03-31 18:11:54.000000000 +0000 @@ -35,7 +35,7 @@ IMG { } IMG { } -Cssutils again will issue a message (WARNING in this case) about invalid +Cssutils again will issue a message (WARNING in this case) about invalid CSS2 property values. TODO: @@ -91,7 +91,7 @@ Format:: - + [Property: Value Priority?;]* [Property: Value Priority?]? """ def __init__(self, cssText=u'', parentRule=None, readonly=False, @@ -116,7 +116,7 @@ def __contains__(self, nameOrProperty): """Check if a property (or a property with given name) is in style. - + :param name: a string or Property, uses normalized name and not literalname """ @@ -125,7 +125,7 @@ else: name = self._normalize(nameOrProperty) return name in self.__nnames() - + def __iter__(self): """Iterator of set Property objects with different normalized names.""" def properties(): @@ -137,18 +137,18 @@ """Analoguous to standard dict returns property names which are set in this declaration.""" return list(self.__nnames()) - + def __getitem__(self, CSSName): """Retrieve the value of property ``CSSName`` from this declaration. - + ``CSSName`` will be always normalized. """ return self.getPropertyValue(CSSName) - + def __setitem__(self, CSSName, value): - """Set value of property ``CSSName``. ``value`` may also be a tuple of + """Set value of property ``CSSName``. ``value`` may also be a tuple of (value, priority), e.g. style['color'] = ('red', 'important') - + ``CSSName`` will be always normalized. """ priority = None @@ -159,9 +159,9 @@ def __delitem__(self, CSSName): """Delete property ``CSSName`` from this declaration. - If property is not in this declaration return u'' just like + If property is not in this declaration return u'' just like removeProperty. - + ``CSSName`` will be always normalized. """ return self.removeProperty(CSSName) @@ -200,14 +200,14 @@ def __nnames(self): """Return iterator for all different names in order as set - if names are set twice the last one is used (double reverse!) + if names are set twice the last one is used (double reverse!) """ names = [] for item in reversed(self.seq): val = item.value if isinstance(val, Property) and not val.name in names: names.append(val.name) - return reversed(names) + return reversed(names) # overwritten accessor functions for CSS2Properties' properties def _getP(self, CSSName): @@ -241,7 +241,7 @@ >>> style.fontStyle = 'italic' >>> # or >>> style.setProperty('font-style', 'italic', '!important') - + """ self.setProperty(CSSName, value) # TODO: Shorthand ones @@ -287,10 +287,10 @@ tokenizer = self._tokenize2(cssText) # for closures: must be a mutable - new = {'wellformed': True} + new = {'wellformed': True} def ident(expected, seq, token, tokenizer=None): # a property - + tokens = self._tokensupto2(tokenizer, starttoken=token, semicolon=True) if self._tokenvalue(tokens[-1]) == u';': @@ -298,37 +298,46 @@ property = Property(parent=self) property.cssText = tokens if property.wellformed: - seq.append(property, 'Property') + seq.append(property, 'Property') else: self._log.error(u'CSSStyleDeclaration: Syntax Error in ' u'Property: %s' % self._valuestr(tokens)) # does not matter in this case - return expected + return expected def unexpected(expected, seq, token, tokenizer=None): # error, find next ; or } to omit upto next property ignored = self._tokenvalue(token) + self._valuestr( - self._tokensupto2(tokenizer, + self._tokensupto2(tokenizer, propertyvalueendonly=True)) self._log.error(u'CSSStyleDeclaration: Unexpected token, ignoring ' 'upto %r.' % ignored,token) # does not matter in this case return expected + def char(expected, seq, token, tokenizer=None): + # a standalone ; or error... + if self._tokenvalue(token) == u';': + self._log.info(u'CSSStyleDeclaration: Stripped standalone semicolon' + u': %s' % self._valuestr([token]), neverraise=True) + return expected + else: + return unexpected(expected, seq, token, tokenizer) + # [Property: Value;]* Property: Value? newseq = self._tempSeq() wellformed, expected = self._parse(expected=None, seq=newseq, tokenizer=tokenizer, - productions={'IDENT': ident}, + productions={'IDENT': ident, 'CHAR': char}, default=unexpected) # wellformed set by parse for item in newseq: item.value._parent = self - - # do not check wellformed as invalid things are removed anyway + + # do not check wellformed as invalid things are removed anyway self._setSeq(newseq) - + cssText = property(_getCssText, _setCssText, doc=u"(DOM) A parsable textual representation of the " u"declaration block excluding the surrounding curly " @@ -336,7 +345,7 @@ def getCssText(self, separator=None): """ - :returns: + :returns: serialized property cssText, each property separated by given `separator` which may e.g. be ``u''`` to be able to use cssText directly in an HTML style attribute. ``;`` is part of @@ -349,7 +358,7 @@ self._parentRule = parentRule # for x in self.children(): # x.parent = self - + parentRule = property(lambda self: self._parentRule, _setParentRule, doc="(DOM) The CSS rule that contains this declaration block or " "None if this CSSStyleDeclaration is not attached to a CSSRule.") @@ -359,18 +368,18 @@ :param name: optional `name` of properties which are requested. Only properties with this **always normalized** `name` are returned. - If `name` is ``None`` all properties are returned (at least one for + If `name` is ``None`` all properties are returned (at least one for each set name depending on parameter `all`). :param all: - if ``False`` (DEFAULT) only the effective properties are returned. + if ``False`` (DEFAULT) only the effective properties are returned. If name is given a list with only one property is returned. if ``True`` all properties including properties set multiple times with different values or priorities for different UAs are returned. - The order of the properties is fully kept as in the original + The order of the properties is fully kept as in the original stylesheet. - :returns: - a list of :class:`~cssutils.css.Property` objects set in + :returns: + a list of :class:`~cssutils.css.Property` objects set in this declaration. """ if name and not all: @@ -378,13 +387,13 @@ p = self.getProperty(name) if p: return [p] - else: + else: return [] elif not all: # effective Properties in name order return [self.getProperty(name) for name in self.__nnames()] - else: - # all properties or all with this name + else: + # all properties or all with this name nname = self._normalize(name) properties = [] for item in self.seq: @@ -402,7 +411,7 @@ if ``True`` (DEFAULT) name will be normalized (lowercase, no simple escapes) so "color", "COLOR" or "C\olor" will all be equivalent - If ``False`` may return **NOT** the effective value but the + If ``False`` may return **NOT** the effective value but the effective for the unnormalized name. :returns: the effective :class:`~cssutils.css.Property` object. @@ -427,23 +436,23 @@ if ``True`` (DEFAULT) name will be normalized (lowercase, no simple escapes) so "color", "COLOR" or "C\olor" will all be equivalent - If ``False`` may return **NOT** the effective value but the + If ``False`` may return **NOT** the effective value but the effective for the unnormalized name. :returns: :class:`~cssutils.css.CSSValue`, the value of the effective - property if it has been explicitly set for this declaration block. + property if it has been explicitly set for this declaration block. (DOM) Used to retrieve the object representation of the value of a CSS property if it has been explicitly set within this declaration block. Returns None if the property has not been set. - + (This method returns None if the property is a shorthand property. Shorthand property values can only be accessed and modified as strings, using the getPropertyValue and setProperty methods.) - **cssutils currently always returns a CSSValue if the property is + **cssutils currently always returns a CSSValue if the property is set.** for more on shorthand properties see @@ -452,7 +461,7 @@ nname = self._normalize(name) if nname in self._SHORTHANDPROPERTIES: self._log.info(u'CSSValue for shorthand property "%s" should be ' - u'None, this may be implemented later.' % + u'None, this may be implemented later.' % nname, neverraise=True) p = self.getProperty(name, normalize) @@ -460,7 +469,7 @@ return p.cssValue else: return None - + def getPropertyValue(self, name, normalize=True): """ :param name: @@ -481,7 +490,7 @@ return p.value else: return u'' - + def getPropertyPriority(self, name, normalize=True): """ :param name: @@ -517,8 +526,8 @@ The effective Property value is returned and *all* Properties with ``Property.name == name`` are removed. - If ``False`` may return **NOT** the effective value but the - effective for the unnormalized `name` only. Also only the + If ``False`` may return **NOT** the effective value but the + effective for the unnormalized `name` only. Also only the Properties with the literal name `name` are removed. :returns: the value of the property if it has been explicitly set for @@ -539,19 +548,19 @@ # remove all properties with name == nname nname = self._normalize(name) for item in self.seq: - if not (isinstance(item.value, Property) + if not (isinstance(item.value, Property) and item.value.name == nname): newseq.appendItem(item) else: # remove all properties with literalname == name for item in self.seq: - if not (isinstance(item.value, Property) + if not (isinstance(item.value, Property) and item.value.literalname == name): newseq.appendItem(item) self._setSeq(newseq) return r - def setProperty(self, name, value=None, priority=u'', + def setProperty(self, name, value=None, priority=u'', normalize=True, replace=True): """(DOM) Set a property value and priority within this declaration block. @@ -561,11 +570,11 @@ "propertyName"), always lowercase (even if not normalized) If a property with this `name` is present it will be reset. - - cssutils also allowed `name` to be a + + cssutils also allowed `name` to be a :class:`~cssutils.css.Property` object, all other parameter are ignored in this case - + :param value: the new value of the property, ignored if `name` is a Property. :param priority: @@ -575,14 +584,14 @@ if True (DEFAULT) `name` will be normalized (lowercase, no simple escapes) so "color", "COLOR" or "C\olor" will all be equivalent :param replace: - if True (DEFAULT) the given property will replace a present + if True (DEFAULT) the given property will replace a present property. If False a new property will be added always. - The difference to `normalize` is that two or more properties with + The difference to `normalize` is that two or more properties with the same name may be set, useful for e.g. stuff like:: - + background: red; background: rgba(255, 0, 0, 0.5); - + which defines the same property but only capable UAs use the last property value, older ones use the first value. @@ -595,9 +604,9 @@ readonly. """ self._checkReadonly() - + if isinstance(name, Property): - newp = name + newp = name name = newp.literalname elif not value: # empty string or None effectively removed property @@ -607,7 +616,7 @@ if newp.wellformed: if replace: - # check if update + # check if update nname = self._normalize(name) properties = self.getProperties(name, all=(not normalize)) for property in reversed(properties): diff -Nru cssutils-0.9.10~b1/src/cssutils/css/cssvalue.py cssutils-0.9.10/src/cssutils/css/cssvalue.py --- cssutils-0.9.10~b1/src/cssutils/css/cssvalue.py 2011-07-26 19:06:42.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/css/cssvalue.py 2013-03-31 16:05:08.000000000 +0000 @@ -39,7 +39,7 @@ 2: 'CSS_VALUE_LIST', 3: 'CSS_CUSTOM', 4: 'CSS_VARIABLE'} - + def __init__(self, cssText=None, parent=None, readonly=False): """ :param cssText: @@ -48,13 +48,16 @@ defaults to False """ super(CSSValue, self).__init__() - + self._cssValueType = None self.wellformed = False self.parent = parent if cssText is not None: # may be 0 - if isinstance(cssText, (int, float)): - cssText = unicode(cssText) # if it is a number + if isinstance(cssText, int): + cssText = unicode(cssText) # if it is an integer + elif isinstance(cssText, float): + cssText = u'%f' % cssText # if it is a floating point number + self.cssText = cssText self._readonly = readonly @@ -65,9 +68,9 @@ def __str__(self): return u"" % (self.__class__.__name__, + u"0x%x>" % (self.__class__.__name__, self.cssValueTypeString, - self.cssText, + self.cssText, id(self)) def _setCssText(self, cssText): @@ -85,7 +88,7 @@ ; term : unary_operator? - [ NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* | + [ NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* | ANGLE S* | TIME S* | FREQ S* ] | STRING S* | IDENT S* | URI S* | hexcolor | function | UNICODE-RANGE S* @@ -107,17 +110,17 @@ Raised if the specified CSS string value has a syntax error (according to the attached property) or is unparsable. - :exc:`~xml.dom.InvalidModificationErr`: - TODO: Raised if the specified CSS string value represents a - different type of values than the values allowed by the CSS + TODO: Raised if the specified CSS string value represents a + different type of values than the values allowed by the CSS property. - :exc:`~xml.dom.NoModificationAllowedErr`: Raised if this value is readonly. """ self._checkReadonly() - + # used as operator is , / or S nextSor = u',/' - + term = Choice(Sequence(PreDef.unary(), Choice(PreDef.number(nextSor=nextSor), PreDef.percentage(nextSor=nextSor), @@ -141,10 +144,10 @@ u'gray(', u'invert(', u'mask(', - u'shadow(', + u'shadow(', u'wave(', u'xray(') or - v.startswith(u'progid:DXImageTransform.Microsoft.') + v.startswith(u'progid:DXImageTransform.Microsoft.') ), nextSor=nextSor, toSeq=lambda t, tokens: (ExpressionValue._functionName, @@ -157,7 +160,7 @@ PreDef.variable(nextSor=nextSor, toSeq=lambda t, tokens: ('CSSVariable', CSSVariable( - cssutils.helper.pushtoken(t, tokens), + cssutils.helper.pushtoken(t, tokens), parent=self) ) ), @@ -165,7 +168,7 @@ PreDef.calc(nextSor=nextSor, toSeq=lambda t, tokens: (CalcValue._functionName, CalcValue( - cssutils.helper.pushtoken(t, tokens), + cssutils.helper.pushtoken(t, tokens), parent=self) ) ), @@ -175,12 +178,12 @@ # match=lambda t, v: t == self._prods.FUNCTION and ( # cssutils.helper.normalize(v) in (u'rgb(', # u'rgba(' -# ) +# ) # ), # nextSor=nextSor, # toSeq=lambda t, tokens: (RGBColor._functionName, # RGBColor( -# cssutils.helper.pushtoken(t, tokens), +# cssutils.helper.pushtoken(t, tokens), # parent=self) # ) # ), @@ -202,15 +205,15 @@ # CSSValue PRODUCTIONS valueprods = Sequence(term, Sequence(operator, # mayEnd this Sequence if whitespace - + # TODO: only when setting via other class # used by variabledeclaration currently PreDef.char('END', ';', stopAndKeep=True, optional=True), - + term, - minmax=lambda: (0, None))) + minmax=lambda: (0, None))) # parse wellformed, seq, store, notused = ProdParser().parse(cssText, u'CSSValue', @@ -237,11 +240,11 @@ # list of IDENTs is handled as STRING! if firstvalue[1] == self._prods.IDENT: firstvalue = firstvalue[0], 'STRING' - + elif item.value == u'/': # / separated items count as one newseq.appendItem(item) - + elif item.value == u'-' or item.value == u'+': # combine +- and following number or other i += 1 @@ -257,7 +260,7 @@ if not firstvalue: firstvalue = (newval, next.type) count += 1 - + elif item.type != cssutils.css.CSSComment: newseq.appendItem(item) if not firstvalue: @@ -266,12 +269,12 @@ else: newseq.appendItem(item) - + i += 1 if not firstvalue: self._log.error( - u'CSSValue: Unknown syntax or no value: %r.' % + u'CSSValue: Unknown syntax or no value: %r.' % self._valuestr(cssText)) else: # ok and set @@ -296,16 +299,16 @@ else: self.__class__ = CSSPrimitiveValue self._value = firstvalue - + elif count > 1: # valuelist self.__class__ = CSSValueList - + # change items in list to specific type (primitive etc) newseq = self._tempSeq() commalist = [] nexttocommalist = False - + def itemValue(item): "Reserialized simple item.value" if self._prods.STRING == item.type: @@ -317,7 +320,7 @@ return item.value.cssText else: return item.value - + def saveifcommalist(commalist, newseq): """ saves items in commalist to seq and items @@ -331,13 +334,13 @@ newseq[-1].line, newseq[-1].col) del commalist[:] - + for i, item in enumerate(self._seq): if issubclass(type(item.value), CSSValue): # set parent of CSSValueList items to the lists # parent item.value.parent = self.parent - + if item.type in (self._prods.DIMENSION, self._prods.FUNCTION, self._prods.HASH, @@ -352,7 +355,7 @@ # wait until complete commalist.append(itemValue(item)) else: - saveifcommalist(commalist, newseq) + saveifcommalist(commalist, newseq) # append new item if hasattr(item.value, 'cssText'): newseq.append(item.value, @@ -366,14 +369,14 @@ item.line, item.col) nexttocommalist = False - + elif u',' == item.value: if not commalist: # save last item to commalist commalist.append(itemValue(self._seq[i - 1])) commalist.append(u',') nexttocommalist = True - + else: if nexttocommalist: commalist.append(item.value.cssText) @@ -382,7 +385,7 @@ saveifcommalist(commalist, newseq) self._setSeq(newseq) - + else: # should not happen... self.__class__ = CSSValue @@ -418,7 +421,7 @@ # constant: type of this CSSValue class cssValueType = CSSValue.CSS_PRIMITIVE_VALUE - __types = cssutils.cssproductions.CSSProductions + __types = cssutils.cssproductions.CSSProductions # An integer indicating which type of unit applies to the value. CSS_UNKNOWN = 0 # only obtainable via cssText @@ -516,7 +519,7 @@ def __str__(self): return u""\ - % (self.__class__.__name__, + % (self.__class__.__name__, self.primitiveTypeString, self.cssText, id(self)) @@ -539,7 +542,7 @@ ] _reNumDim = re.compile(ur'([+-]?\d*\.\d+|[+-]?\d+)(.*)$', re.I | re.U | re.X) - + def _unitDIMENSION(value): """Check val for dimension name.""" units = {'em': 'CSS_EMS', 'ex': 'CSS_EXS', @@ -550,7 +553,7 @@ 'deg': 'CSS_DEG', 'rad': 'CSS_RAD', 'grad': 'CSS_GRAD', 'ms': 'CSS_MS', 's': 'CSS_S', 'hz': 'CSS_HZ', 'khz': 'CSS_KHZ' - } + } val, dim = CSSPrimitiveValue._reNumDim.findall(cssutils.helper.normalize(value))[0] return units.get(dim, 'CSS_DIMENSION') @@ -566,7 +569,7 @@ cssutils.helper.normalize(value.cssText), re.U)[0], 'CSS_UNKNOWN') - + __unitbytype = { __types.NUMBER: 'CSS_NUMBER', __types.PERCENTAGE: 'CSS_PERCENTAGE', @@ -589,7 +592,7 @@ # multiple options, check value too pt = pt(val) self._primitiveType = getattr(self, pt) - + def _getPrimitiveType(self): if not hasattr(self, '_primitivetype'): self.__set_primitiveType() @@ -616,7 +619,7 @@ "Split self._value in numerical and dimension part." if value is None: value = cssutils.helper.normalize(self._value[0]) - + try: val, dim = CSSPrimitiveValue._reNumDim.findall(value)[0] except IndexError: @@ -655,7 +658,7 @@ u'unitType Parameter is not a float type') val, dim = self._getNumDim() - + if unitType is not None and self.primitiveType != unitType: # convert if needed try: @@ -696,13 +699,13 @@ self._checkReadonly() if unitType not in self._floattypes: raise xml.dom.InvalidAccessErr( - u'CSSPrimitiveValue: unitType %r is not a float type' % + u'CSSPrimitiveValue: unitType %r is not a float type' % self._getCSSPrimitiveTypeString(unitType)) try: val = float(floatValue) except ValueError, e: raise xml.dom.InvalidAccessErr( - u'CSSPrimitiveValue: floatValue %r is not a float' % + u'CSSPrimitiveValue: floatValue %r is not a float' % floatValue) oldval, dim = self._getNumDim() @@ -759,7 +762,7 @@ not part of the string value :exceptions: - - :exc:`~xml.dom.InvalidAccessErr`: + - :exc:`~xml.dom.InvalidAccessErr`: Raised if the CSS value doesn't contain a string value or if the string value can't be converted into the specified unit. @@ -800,7 +803,7 @@ this CSS value doesn't contain a counter value, a DOMException is raised. Modification to the corresponding style property can be achieved using the Counter interface. - + **Not implemented.** """ if not self.CSS_COUNTER == self.primitiveType: @@ -823,7 +826,7 @@ value doesn't contain a rect value, a DOMException is raised. Modification to the corresponding style property can be achieved using the Rect interface. - + **Not implemented.** """ if self.primitiveType not in self._recttypes: @@ -838,7 +841,7 @@ def _setCssText(self, cssText): """Use CSSValue.""" return super(CSSPrimitiveValue, self)._setCssText(cssText) - + cssText = property(_getCssText, _setCssText, doc="A string representation of the current value.") @@ -877,7 +880,7 @@ id(self)) def __items(self): - return [item for item in self._seq + return [item for item in self._seq if isinstance(item.value, CSSValue)] def item(self, index): @@ -894,13 +897,13 @@ length = property(lambda self: len(self.__items()), doc=u"(DOM attribute) The number of CSSValues in the " u"list.") - + class CSSFunction(CSSPrimitiveValue): """A CSS function value like rect() etc.""" _functionName = u'CSSFunction' primitiveType = CSSPrimitiveValue.CSS_UNKNOWN - + def __init__(self, cssText=None, parent=None, readonly=False): """ Init a new CSSFunction @@ -917,11 +920,11 @@ if cssText is not None: self.cssText = cssText self._readonly = readonly - + def _productiondefinition(self): """Return definition used for parsing.""" types = self._prods # rename! - + value = Sequence(PreDef.unary(), Prod(name='PrimitiveValue', match=lambda t, v: t in (types.DIMENSION, @@ -930,13 +933,13 @@ types.NUMBER, types.PERCENTAGE, types.STRING), - toSeq=lambda t, tokens: (t[0], + toSeq=lambda t, tokens: (t[0], CSSPrimitiveValue(t[1])) ) ) valueOrFunc = Choice(value, # FUNC is actually not in spec but used in e.g. Prince - PreDef.function(toSeq=lambda t, + PreDef.function(toSeq=lambda t, tokens: ('FUNCTION', CSSFunction( cssutils.helper.pushtoken(t, tokens)) @@ -948,7 +951,7 @@ toSeq=lambda t, tokens: (t[0], cssutils.helper.normalize(t[1]))), Choice(Sequence(valueOrFunc, # more values starting with Comma - # should use store where colorType is saved to + # should use store where colorType is saved to # define min and may, closure? Sequence(PreDef.comma(), valueOrFunc, @@ -957,7 +960,7 @@ PreDef.funcEnd(stop=True)) ) return funcProds - + def _setCssText(self, cssText): self._checkReadonly() # store: colorType, parts @@ -984,28 +987,28 @@ item.line, item.col) else: # expressions only? - newseq.appendItem(item) + newseq.appendItem(item) newseq.appendItem(next) else: newseq.appendItem(item) - + i += 1 - + self.wellformed = True self._setSeq(newseq) self._funcType = newseq[0].value cssText = property(lambda self: cssutils.ser.do_css_FunctionValue(self), _setCssText) - + funcType = property(lambda self: self._funcType) - - + + class RGBColor(CSSFunction): """A CSS color like RGB, RGBA or a simple value like `#000` or `red`.""" - + _functionName = u'Function rgb()' - + def __init__(self, cssText=None, parent=None, readonly=False): """ Init a new RGBColor @@ -1028,7 +1031,7 @@ self.cssText = cssText self._readonly = readonly - + def __repr__(self): return u"cssutils.css.%s(%r)" % (self.__class__.__name__, self.cssText) @@ -1039,7 +1042,7 @@ self.colorType, self.cssText, id(self)) - + def _setCssText(self, cssText): self._checkReadonly() types = self._prods # rename! @@ -1068,14 +1071,14 @@ match=lambda t, v: t == types.IDENT, toStore='colorType' ) - ) + ) # store: colorType, parts wellformed, seq, store, unusedtokens = ProdParser().parse(cssText, u'RGBColor', colorprods, keepS=True, store={'parts': []}) - + if wellformed: self.wellformed = True if store['colorType'].type == self._prods.HASH: @@ -1085,27 +1088,27 @@ else: self._colorType = store['colorType'].value[:-1] #self._colorType = cssutils.helper.normalize(store['colorType'].value)[:-1] - + self._setSeq(seq) cssText = property(lambda self: cssutils.ser.do_css_RGBColor(self), _setCssText) - + colorType = property(lambda self: self._colorType) class CalcValue(CSSFunction): """Calc Function""" _functionName = u'Function calc()' - + def _productiondefinition(self): """Return defintion used for parsing.""" types = self._prods # rename! - + def toSeq(t, tokens): "Do not normalize function name!" return t[0], t[1] - + funcProds = Sequence(Prod(name='calc', match=lambda t, v: t == types.FUNCTION, toSeq=toSeq @@ -1123,13 +1126,13 @@ minmax=lambda: (0, None)), PreDef.funcEnd(stop=True)) return funcProds - + def _getCssText(self): return cssutils.ser.do_css_CalcValue(self) - + def _setCssText(self, cssText): return super(CalcValue, self)._setCssText(cssText) - + cssText = property(_getCssText, _setCssText, doc=u"A string representation of the current value.") @@ -1138,15 +1141,15 @@ """Special IE only CSSFunction which may contain *anything*. Used for expressions and ``alpha(opacity=100)`` currently.""" _functionName = u'Expression (IE only)' - + def _productiondefinition(self): """Return defintion used for parsing.""" types = self._prods # rename! - + def toSeq(t, tokens): "Do not normalize function name!" return t[0], t[1] - + funcProds = Sequence(Prod(name='expression', match=lambda t, v: t == types.FUNCTION, toSeq=toSeq @@ -1164,24 +1167,24 @@ minmax=lambda: (0, None)), PreDef.funcEnd(stop=True)) return funcProds - + def _getCssText(self): return cssutils.ser.do_css_ExpressionValue(self) - + def _setCssText(self, cssText): #self._log.warn(u'CSSValue: Unoffial and probably invalid MS value used!') return super(ExpressionValue, self)._setCssText(cssText) - + cssText = property(_getCssText, _setCssText, doc=u"A string representation of the current value.") class CSSVariable(CSSValue): """The CSSVariable represents a call to CSS Variable.""" - + def __init__(self, cssText=None, parent=None, readonly=False): """Init a new CSSVariable. - + :param cssText: the parsable cssText of the value, e.g. ``var(x)`` :param readonly: @@ -1191,7 +1194,7 @@ super(CSSVariable, self).__init__(cssText=cssText, parent=parent, readonly=readonly) - + def __repr__(self): return u"cssutils.css.%s(%r)" % (self.__class__.__name__, self.cssText) @@ -1200,19 +1203,19 @@ self.__class__.__name__, self.name, self.value, - id(self)) - + id(self)) + def _setCssText(self, cssText): self._checkReadonly() types = self._prods # rename! - + funcProds = Sequence(Prod(name='var', - match=lambda t, v: t == types.FUNCTION + match=lambda t, v: t == types.FUNCTION ), PreDef.ident(toStore='ident'), PreDef.funcEnd(stop=True)) - + # store: name of variable store = {'ident': None} wellformed, seq, store, unusedtokens = ProdParser().parse(cssText, @@ -1223,7 +1226,7 @@ self._name = store['ident'].value self._setSeq(seq) self.wellformed = True - + cssText = property(lambda self: cssutils.ser.do_css_CSSVariable(self), _setCssText, doc=u"A string representation of the current variable.") @@ -1244,5 +1247,5 @@ return variables[self.name] except KeyError: return None - + value = property(_getValue) diff -Nru cssutils-0.9.10~b1/src/cssutils/css/property.py cssutils-0.9.10/src/cssutils/css/property.py --- cssutils-0.9.10~b1/src/cssutils/css/property.py 2012-03-28 13:30:22.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/css/property.py 2013-03-31 19:45:18.000000000 +0000 @@ -243,7 +243,7 @@ def _setPropertyValue(self, cssText): """ - See css.PropertyValze + See css.PropertyValue :exceptions: - :exc:`~xml.dom.SyntaxErr`: diff -Nru cssutils-0.9.10~b1/src/cssutils/css/value.py cssutils-0.9.10/src/cssutils/css/value.py --- cssutils-0.9.10~b1/src/cssutils/css/value.py 2012-03-24 19:08:28.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/css/value.py 2013-03-31 19:46:10.000000000 +0000 @@ -1,4 +1,4 @@ -"""Value related classes. +"""Value related classes. DOM Level 2 CSS CSSValue, CSSPrimitiveValue and CSSValueList are **no longer** supported and are replaced by these new classes. @@ -8,7 +8,7 @@ 'ColorValue', 'DimensionValue', 'URIValue', - 'CSSFunction', + 'CSSFunction', 'CSSVariable', 'MSValue' ] @@ -26,14 +26,14 @@ class PropertyValue(cssutils.util._NewBase): """ - An unstructured list like holder for all values defined for a - :class:`~cssutils.css.Property`. Contains :class:`~cssutils.css.Value` + An unstructured list like holder for all values defined for a + :class:`~cssutils.css.Property`. Contains :class:`~cssutils.css.Value` or subclass objects. Currently there is no access to the combinators of - the defined values which might simply be space or comma or slash. - + the defined values which might simply be space or comma or slash. + You may: - - - iterate over all contained Value objects (not the separators like ``,``, + + - iterate over all contained Value objects (not the separators like ``,``, ``/`` or `` `` though!) - get a Value item by index or use ``PropertyValue[index]`` - find out the number of values defined (unstructured) @@ -46,46 +46,46 @@ defaults to False """ super(PropertyValue, self).__init__() - + self.parent = parent self.wellformed = False - + if cssText is not None: # may be 0 if isinstance(cssText, (int, float)): cssText = unicode(cssText) # if it is a number self.cssText = cssText - + self._readonly = readonly def __len__(self): return len(list(self.__items())) - + def __getitem__(self, index): try: return list(self.__items())[index] except IndexError: return None - + def __iter__(self): "Generator which iterates over values." for item in self.__items(): yield item - + def __repr__(self): return u"cssutils.css.%s(%r)" % (self.__class__.__name__, self.cssText) def __str__(self): return u"" % (self.__class__.__name__, + u"0x%x>" % (self.__class__.__name__, self.length, self.cssText, id(self)) - + def __items(self, seq=None): "a generator of Value obects only, no , / or ' '" if seq is None: seq = self.seq return (x.value for x in seq if isinstance(x.value, Value)) - + def _setCssText(self, cssText): if isinstance(cssText, (int, float)): cssText = unicode(cssText) # if it is a number @@ -103,7 +103,7 @@ ; term : unary_operator? - [ NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* | + [ NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* | ANGLE S* | TIME S* | FREQ S* ] | STRING S* | IDENT S* | URI S* | hexcolor | function | UNICODE-RANGE S* @@ -125,14 +125,14 @@ Raised if the specified CSS string value has a syntax error (according to the attached property) or is unparsable. - :exc:`~xml.dom.InvalidModificationErr`: - TODO: Raised if the specified CSS string value represents a - different type of values than the values allowed by the CSS + TODO: Raised if the specified CSS string value represents a + different type of values than the values allowed by the CSS property. - :exc:`~xml.dom.NoModificationAllowedErr`: Raised if this value is readonly. """ self._checkReadonly() - + # used as operator is , / or S nextSor = u',/' term = Choice(_ColorProd(self, nextSor), @@ -144,7 +144,7 @@ # all other functions _CSSVariableProd(self, nextSor), _MSValueProd(self, nextSor), - _CSSFunctionProd(self, nextSor) + _CSSFunctionProd(self, nextSor) ) operator = Choice(PreDef.S(toSeq=False), PreDef.char('comma', ',', @@ -154,7 +154,7 @@ optional=True) prods = Sequence(term, Sequence(# mayEnd this Sequence if whitespace - operator, + operator, # TODO: only when setting via other class # used by variabledeclaration currently PreDef.char('END', ';', @@ -162,7 +162,7 @@ optional=True), # TODO: } and !important ends too! term, - minmax=lambda: (0, None))) + minmax=lambda: (0, None))) # parse ok, seq, store, unused = ProdParser().parse(cssText, u'PropertyValue', @@ -173,18 +173,18 @@ self._setSeq(seq) self.wellformed = True else: - self._log.error(u'PropertyValue: Unknown syntax or no value: %s' % + self._log.error(u'PropertyValue: Unknown syntax or no value: %s' % self._valuestr(cssText)) - + cssText = property(lambda self: cssutils.ser.do_css_PropertyValue(self), _setCssText, doc="A string representation of the current value.") def item(self, index): """ - The value at position `index`. Alternatively simple use + The value at position `index`. Alternatively simple use ``PropertyValue[index]``. - + :param index: the parsable cssText of the value :exceptions: @@ -196,7 +196,7 @@ length = property(lambda self: len(self), doc=u"Number of values set.") - value = property(lambda self: cssutils.ser.do_css_PropertyValue(self, + value = property(lambda self: cssutils.ser.do_css_PropertyValue(self, valuesOnly=True), doc=u"A string representation of the current value " u"without any comments used for validation.") @@ -208,7 +208,7 @@ IDENT, STRING, or UNICODE-RANGE values are represented directly as Value objects. Other values like e.g. FUNCTIONs are represented by subclasses with an extended API. - """ + """ IDENT = u'IDENT' STRING = u'STRING' UNICODE_RANGE = u'UNICODE-RANGE' @@ -216,22 +216,22 @@ DIMENSION = u'DIMENSION' NUMBER = u'NUMBER' - PERCENTAGE = u'PERCENTAGE' - + PERCENTAGE = u'PERCENTAGE' + COLOR_VALUE = u'COLOR_VALUE' HASH = u'HASH' - + FUNCTION = u'FUNCTION' VARIABLE = u'VARIABLE' - + _type = None _value = u'' - + def __init__(self, cssText=None, parent=None, readonly=False): super(Value, self).__init__() - + self.parent = parent - + if cssText: self.cssText = cssText @@ -241,7 +241,7 @@ def __str__(self): return u""\ - % (self.__class__.__name__, + % (self.__class__.__name__, self.type, self.value, self.cssText, id(self)) @@ -258,15 +258,15 @@ # only 1 value anyway! self._type = seq[0].type self._value = seq[0].value - + self._setSeq(seq) self.wellformed = ok - - cssText = property(lambda self: cssutils.ser.do_css_Value(self), - _setCssText, + + cssText = property(lambda self: cssutils.ser.do_css_Value(self), + _setCssText, doc=u'String value of this value.') - type = property(lambda self: self._type, #_setType, + type = property(lambda self: self._type, #_setType, doc=u"Type of this value, for now the production type " u"like e.g. `DIMENSION` or `STRING`. All types are " u"defined as constants in :class:`~cssutils.css.Value`.") @@ -275,7 +275,7 @@ # TODO: check! self._value = value - value = property(lambda self: self._value, _setValue, + value = property(lambda self: self._value, _setValue, doc=u"Actual value if possible: An int or float or else " u" a string") @@ -283,11 +283,11 @@ class ColorValue(Value): """ A color value like rgb(), rgba(), hsl(), hsla() or #rgb, #rrggbb - + TODO: Color Keywords """ from colors import COLORS - + type = Value.COLOR_VALUE # hexcolor, FUNCTION? _colorType = None @@ -295,28 +295,28 @@ _green = 0 _blue = 0 _alpha = 0 - + def __str__(self): return u""\ - % (self.__class__.__name__, - self.type, self.value, + % (self.__class__.__name__, + self.type, self.value, self.colorType, self.red, self.green, self.blue, self.alpha, id(self)) - + def _setCssText(self, cssText): self._checkReadonly() types = self._prods # rename! - component = Choice(PreDef.unary(toSeq=lambda t, tokens: (t[0], + component = Choice(PreDef.unary(toSeq=lambda t, tokens: (t[0], DimensionValue(pushtoken(t, tokens), parent=self) )), - PreDef.number(toSeq=lambda t, tokens: (t[0], + PreDef.number(toSeq=lambda t, tokens: (t[0], DimensionValue(pushtoken(t, tokens), parent=self) )), - PreDef.percentage(toSeq=lambda t, tokens: (t[0], + PreDef.percentage(toSeq=lambda t, tokens: (t[0], DimensionValue(pushtoken(t, tokens), parent=self) )) @@ -326,7 +326,7 @@ v in (u'rgb(', u'hsl('), toSeq=lambda t, tokens: (t[0], normalize(t[1]))), component, - Sequence(PreDef.comma(), + Sequence(PreDef.comma(), component, minmax=lambda: (2, 2) ), @@ -335,11 +335,11 @@ witha = Sequence(Prod(name='FUNCTION', match=lambda t, v: t == types.FUNCTION and v in (u'rgba(', u'hsla('), - toSeq=lambda t, tokens: (t[0], + toSeq=lambda t, tokens: (t[0], normalize(t[1])) ), component, - Sequence(PreDef.comma(), + Sequence(PreDef.comma(), component, minmax=lambda: (3, 3) ), @@ -350,13 +350,13 @@ normalize(v) in self.COLORS.keys() ), stop=True) - - prods = Choice(PreDef.hexcolor(stop=True), - namedcolor, - noalp, + + prods = Choice(PreDef.hexcolor(stop=True), + namedcolor, + noalp, witha) - - ok, seq, store, unused = ProdParser().parse(cssText, + + ok, seq, store, unused = ProdParser().parse(cssText, self.type, prods) if ok: @@ -368,19 +368,19 @@ # HASH #rgb rgba = (int(2*v[1], 16), int(2*v[2], 16), - int(2*v[3], 16), + int(2*v[3], 16), 1.0) else: # HASH #rrggbb rgba = (int(v[1:3], 16), int(v[3:5], 16), - int(v[5:7], 16), + int(v[5:7], 16), 1.0) - + elif u'FUNCTION' == t: functiontype, raw, check = None, [], u'' HSL = False - + for item in seq: try: type_ = item.value.type @@ -391,7 +391,7 @@ HSL = functiontype in (u'hsl(', u'hsla(') continue - # save components + # save components if type_ == Value.NUMBER: raw.append(item.value.value) check += u'N' @@ -403,7 +403,7 @@ # save as real value of percentage of 255 raw.append(int(255 * item.value.value / 100)) check += u'P' - + if HSL: # convert to rgb # h is 360 based (circle) @@ -411,20 +411,20 @@ # ORDER h l s !!! r, g, b = colorsys.hls_to_rgb(h, l, s) # back to 255 based - rgba = [int(round(r*255)), - int(round(g*255)), + rgba = [int(round(r*255)), + int(round(g*255)), int(round(b*255))] - + if len(raw) > 3: rgba.append(raw[3]) - + else: # rgb, rgba rgba = raw if len(rgba) < 4: rgba.append(1.0) - + # validate checks = {u'rgb(': ('NNN', 'PPP'), u'rgba(': ('NNNN', 'PPPN'), @@ -433,19 +433,19 @@ } if check not in checks[functiontype]: self._log.error(u'ColorValue has invalid %s) parameters: ' - u'%s (N=Number, P=Percentage)' % + u'%s (N=Number, P=Percentage)' % (functiontype, check)) - + self._colorType = t self._red, self._green, self._blue, self._alpha = tuple(rgba) self._setSeq(seq) self.wellformed = ok - - cssText = property(lambda self: cssutils.ser.do_css_ColorValue(self), - _setCssText, + + cssText = property(lambda self: cssutils.ser.do_css_ColorValue(self), + _setCssText, doc=u"String value of this value.") - - value = property(lambda self: cssutils.ser.do_css_CSSFunction(self, True), + + value = property(lambda self: cssutils.ser.do_css_CSSFunction(self, True), doc=u'Same as cssText but without comments.') type = property(lambda self: Value.COLOR_VALUE, @@ -458,7 +458,7 @@ colorType = property(lambda self: self._colorType, doc=u"IDENT (red), HASH (#f00) or FUNCTION (rgb(255, 0, 0).") - + name = property(_getName, doc=u'Name of the color if known (in ColorValue.COLORS) ' u'else None') @@ -475,16 +475,16 @@ class DimensionValue(Value): """ A numerical value with an optional dimenstion like e.g. "px" or "%". - + Covers DIMENSION, PERCENTAGE or NUMBER values. """ __reNumDim = re.compile(ur'^(\d*\.\d+|\d+)(.*)$', re.I | re.U | re.X) _dimension = None _sign = None - + def __str__(self): return u""\ - % (self.__class__.__name__, + % (self.__class__.__name__, self.type, self.value, self.dimension, self.cssText, id(self)) @@ -496,21 +496,21 @@ PreDef.number(stop=True), PreDef.percentage(stop=True) ) - ) - ok, seq, store, unused = ProdParser().parse(cssText, - u'DimensionValue', + ) + ok, seq, store, unused = ProdParser().parse(cssText, + u'DimensionValue', prods) if ok: sign = val = u'' dim = type_ = None - - # find + + # find for item in seq: if item.value in u'+-': sign = item.value else: type_ = item.type - + # number + optional dim v, d = self.__reNumDim.findall( normalize(item.value))[0] @@ -521,19 +521,19 @@ if d: dim = d - self._sign = sign + self._sign = sign self._value = val self._dimension = dim self._type = type_ self._setSeq(seq) self.wellformed = ok - - cssText = property(lambda self: cssutils.ser.do_css_Value(self), - _setCssText, + + cssText = property(lambda self: cssutils.ser.do_css_Value(self), + _setCssText, doc=u"String value of this value including dimension.") - - dimension = property(lambda self: self._dimension, #_setValue, + + dimension = property(lambda self: self._dimension, #_setValue, doc=u"Dimension if a DIMENSION or PERCENTAGE value, " u"else None") class URIValue(Value): @@ -542,10 +542,10 @@ """ _type = Value.URI _uri = Value._value - + def __str__(self): return u""\ - % (self.__class__.__name__, + % (self.__class__.__name__, self.type, self.value, self.uri, self.cssText, id(self)) @@ -553,27 +553,27 @@ self._checkReadonly() prods = Sequence(PreDef.uri(stop=True)) - + ok, seq, store, unused = ProdParser().parse(cssText, u'URIValue', prods) if ok: # only 1 value only anyway self._type = seq[0].type self._value = seq[0].value - + self._setSeq(seq) self.wellformed = ok - - cssText = property(lambda self: cssutils.ser.do_css_Value(self), - _setCssText, + + cssText = property(lambda self: cssutils.ser.do_css_Value(self), + _setCssText, doc=u'String value of this value.') - + def _setUri(self, uri): # TODO: check? self._value = uri - - uri = property(lambda self: self._value, _setUri, + + uri = property(lambda self: self._value, _setUri, doc=u"Actual URL without delimiters or the empty string") - + def absoluteUri(self): """Actual URL, made absolute if possible, else same as `uri`.""" # Ancestry: PropertyValue, Property, CSSStyleDeclaration, CSSStyleRule, @@ -585,20 +585,20 @@ return self.uri else: return urlparse.urljoin(styleSheet.href, self.uri) - + absoluteUri = property(absoluteUri, doc=absoluteUri.__doc__) - + class CSSFunction(Value): """ A function value. """ _functionName = 'Function' - + def _productions(self): """Return definition used for parsing.""" types = self._prods # rename! - + itemProd = Choice(_ColorProd(self), _DimensionProd(self), _URIProd(self), @@ -609,7 +609,7 @@ ) funcProds = Sequence(Prod(name='FUNCTION', match=lambda t, v: t == types.FUNCTION, - toSeq=lambda t, tokens: (t[0], + toSeq=lambda t, tokens: (t[0], normalize(t[1]))), Choice(Sequence(itemProd, Sequence(PreDef.comma(), @@ -619,47 +619,47 @@ PreDef.funcEnd(stop=True)) ) return funcProds - + def _setCssText(self, cssText): self._checkReadonly() - ok, seq, store, unused = ProdParser().parse(cssText, + ok, seq, store, unused = ProdParser().parse(cssText, self.type, self._productions()) if ok: self._setSeq(seq) self.wellformed = ok - - cssText = property(lambda self: cssutils.ser.do_css_CSSFunction(self), - _setCssText, + + cssText = property(lambda self: cssutils.ser.do_css_CSSFunction(self), + _setCssText, doc=u"String value of this value.") - - value = property(lambda self: cssutils.ser.do_css_CSSFunction(self, True), + + value = property(lambda self: cssutils.ser.do_css_CSSFunction(self, True), doc=u'Same as cssText but without comments.') type = property(lambda self: Value.FUNCTION, doc=u"Type is fixed to Value.FUNCTION.") class MSValue(CSSFunction): - """An IE specific Microsoft only function value which is much looser + """An IE specific Microsoft only function value which is much looser in what is syntactically allowed.""" _functionName = 'MSValue' - + def _productions(self): """Return definition used for parsing.""" types = self._prods # rename! - + func = Prod(name='MSValue-Sub', match=lambda t, v: t == self._prods.FUNCTION, - toSeq=lambda t, tokens: (MSValue._functionName, - MSValue(pushtoken(t, + toSeq=lambda t, tokens: (MSValue._functionName, + MSValue(pushtoken(t, tokens ), parent=self ) ) ) - - + + funcProds = Sequence(Prod(name='FUNCTION', match=lambda t, v: t == types.FUNCTION, toSeq=lambda t, tokens: (t[0], t[1]) @@ -683,18 +683,18 @@ PreDef.funcEnd(stop=True) ) return funcProds - + def _setCssText(self, cssText): super(MSValue, self)._setCssText(cssText) - - cssText = property(lambda self: cssutils.ser.do_css_MSValue(self), - _setCssText, + + cssText = property(lambda self: cssutils.ser.do_css_MSValue(self), + _setCssText, doc=u"String value of this value.") class CSSVariable(CSSFunction): """The CSSVariable represents a CSS variables like ``var(varname)``. - + A variable has a (nonnormalized!) `name` and a `value` which is tried to be resolved from any available CSSVariablesRule definition. """ @@ -703,34 +703,34 @@ def __str__(self): return u"" % ( - self.__class__.__name__, self.name, self.value, id(self)) - + self.__class__.__name__, self.name, self.value, id(self)) + def _setCssText(self, cssText): self._checkReadonly() types = self._prods # rename! prods = Sequence(Prod(name='var', match=lambda t, v: t == types.FUNCTION and - normalize(v) == u'var(' + normalize(v) == u'var(' ), PreDef.ident(toStore='ident'), PreDef.funcEnd(stop=True)) - + # store: name of variable store = {'ident': None} - ok, seq, store, unused = ProdParser().parse(cssText, + ok, seq, store, unused = ProdParser().parse(cssText, u'CSSVariable', prods) if ok: self._name = store['ident'].value self._setSeq(seq) self.wellformed = ok - + cssText = property(lambda self: cssutils.ser.do_css_CSSVariable(self), _setCssText, doc=u"String representation of variable.") # TODO: writable? check if var (value) available? - name = property(lambda self: self._name, + name = property(lambda self: self._name, doc=u"The name identifier of this variable referring to " u"a value in a " u":class:`cssutils.css.CSSVariablesDeclaration`.") @@ -746,7 +746,7 @@ if hasattr(rel, 'parent'): rel = rel.parent else: - break + break try: variables = rel.parentRule.parentStyleSheet.variables except AttributeError: @@ -756,8 +756,8 @@ return variables[self.name] except KeyError: return None - - value = property(_getValue, + + value = property(_getValue, doc=u'The resolved actual value or None.') @@ -767,21 +767,21 @@ match=lambda t, v: t in ('IDENT', 'STRING', 'UNICODE-RANGE'), nextSor = nextSor, toSeq=lambda t, tokens: ('Value', Value( - pushtoken(t, + pushtoken(t, tokens), parent=parent) ) ) - + def _DimensionProd(parent, nextSor=False): return Prod(name='Dimension', - match=lambda t, v: t in (u'DIMENSION', - u'NUMBER', + match=lambda t, v: t in (u'DIMENSION', + u'NUMBER', u'PERCENTAGE') or v in u'+-', nextSor = nextSor, toSeq=lambda t, tokens: (t[0], DimensionValue( - pushtoken(t, + pushtoken(t, tokens), parent=parent) ) @@ -792,34 +792,40 @@ match=lambda t, v: t == 'URI', nextSor = nextSor, toSeq=lambda t, tokens: ('URIValue', URIValue( - pushtoken(t, + pushtoken(t, tokens), parent=parent) ) ) - + +reHexcolor = re.compile(r'^\#(?:[0-9abcdefABCDEF]{3}|[0-9abcdefABCDEF]{6})$') + def _ColorProd(parent, nextSor=False): return Prod(name='ColorValue', - match=lambda t, v: t == 'HASH' or + match=lambda t, v: + (t == 'HASH' and + reHexcolor.match(v) + ) or (t == 'FUNCTION' and - normalize(v) in (u'rgb(', + normalize(v) in (u'rgb(', u'rgba(', - u'hsl(', - u'hsla(')) or - (t == 'IDENT' and + u'hsl(', + u'hsla(') + ) or + (t == 'IDENT' and normalize(v) in ColorValue.COLORS.keys() ), nextSor = nextSor, toSeq=lambda t, tokens: ('ColorValue', ColorValue( - pushtoken(t, + pushtoken(t, tokens), parent=parent) ) ) - + def _CSSFunctionProd(parent, nextSor=False): return PreDef.function(nextSor=nextSor, - toSeq=lambda t, tokens: (CSSFunction._functionName, + toSeq=lambda t, tokens: (CSSFunction._functionName, CSSFunction( pushtoken(t, tokens), parent=parent) @@ -828,13 +834,13 @@ def _CSSVariableProd(parent, nextSor=False): return PreDef.variable(nextSor=nextSor, - toSeq=lambda t, tokens: (CSSVariable._functionName, + toSeq=lambda t, tokens: (CSSVariable._functionName, CSSVariable( - pushtoken(t, tokens), + pushtoken(t, tokens), parent=parent) ) - ) - + ) + def _MSValueProd(parent, nextSor=False): return Prod(name=MSValue._functionName, match=lambda t, v: (#t == self._prods.FUNCTION and ( @@ -849,14 +855,14 @@ u'gray(', u'invert(', u'mask(', - u'shadow(', + u'shadow(', u'wave(', u'xray(') or - v.startswith(u'progid:DXImageTransform.Microsoft.') + v.startswith(u'progid:DXImageTransform.Microsoft.') ), nextSor=nextSor, - toSeq=lambda t, tokens: (MSValue._functionName, - MSValue(pushtoken(t, + toSeq=lambda t, tokens: (MSValue._functionName, + MSValue(pushtoken(t, tokens ), parent=parent diff -Nru cssutils-0.9.10~b1/src/cssutils/prodparser.py cssutils-0.9.10/src/cssutils/prodparser.py --- cssutils-0.9.10~b1/src/cssutils/prodparser.py 2011-12-28 18:14:28.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/prodparser.py 2013-03-31 19:48:30.000000000 +0000 @@ -20,6 +20,8 @@ from helper import pushtoken import cssutils +import re +import string import sys @@ -220,7 +222,7 @@ """Single Prod in Sequence or Choice.""" def __init__(self, name, match, optional=False, toSeq=None, toStore=None, - stop=False, stopAndKeep=False, + stop=False, stopAndKeep=False, nextSor=False, mayEnd=False, storeToken=None, exception=None): @@ -233,9 +235,9 @@ toSeq callback (optional) or False calling toSeq(token, tokens) returns (type_, val) == (token[0], token[1]) to be appended to seq else simply unaltered (type_, val) - + if False nothing is added - + toStore (optional) key to save util.Item to store or callback(store, util.Item) optional = False @@ -250,11 +252,11 @@ mayEnd = False no token must follow even defined by Sequence. Used for operator ',/ ' currently only - + storeToken = None if True toStore saves simple token tuple and not and Item object to store. Old style processing, TODO: resolve - + exception = None exception to be raised in case of error, normaly SyntaxErr """ @@ -266,7 +268,7 @@ self.nextSor = nextSor self.mayEnd = mayEnd self.storeToken = storeToken - self.exception = exception + self.exception = exception def makeToStore(key): "Return a function used by toStore." @@ -331,7 +333,7 @@ if isinstance(text, basestring): # DEFAULT, to tokenize strip space return tokenizer.tokenize(text.strip()) - + elif isinstance(text, tuple): # OLD: (token, tokens) or a single token if len(text) == 2: @@ -340,11 +342,11 @@ else: # single token return iter([text]) - + elif isinstance(text, list): # OLD: generator from list return iter(text) - + else: # DEFAULT, already tokenized, assume generator return text @@ -395,7 +397,7 @@ used for logging productions used to parse tokens - keepS + keepS if WS should be added to Seq or just be ignored store UPDATED If a Prod defines ``toStore`` the key defined there @@ -412,7 +414,7 @@ :store: filled keys defined by Prod.toStore :unusedtokens: token generator containing tokens not used yet """ - tokens = self._texttotokens(text) + tokens = self._texttotokens(text) if not tokens: self._log.error(u'No content to parse.') # TODO: return??? @@ -435,7 +437,7 @@ except StopIteration: break type_, val, line, col = token - + # default productions if type_ == self.types.COMMENT: # always append COMMENT @@ -487,7 +489,7 @@ wellformed = False self._log.error(u'%s: %s: %r' % (name, e, token)) break - else: + else: # process prod if prod.toSeq and not prod.stopAndKeep: type_, val = prod.toSeq(token, tokens) @@ -496,12 +498,12 @@ if prod.toStore: if not prod.storeToken: prod.toStore(store, seq[-1]) - else: + else: # workaround for now for old style token # parsing! # TODO: remove when all new style prod.toStore(store, token) - + if prod.stop: # EOF? # stop here and ignore following tokens break @@ -512,7 +514,7 @@ tokenizer.push(token) stopall = True break - + if prod.nextSor: # following is S or other token (e.g. ",")? # remove S if @@ -522,7 +524,7 @@ defaultS = True lastprod = prod - + if not stopall: # stop immediately while True: @@ -532,26 +534,26 @@ except Done, e: # ok prod = None - + except Missing, e: prod = None # last was a S operator which may End a Sequence, then ok if hasattr(lastprod, 'mayEnd') and not lastprod.mayEnd: wellformed = False self._log.error(u'%s: %s' % (name, e)) - + except ParseError, e: prod = None wellformed = False self._log.error(u'%s: %s' % (name, e)) - + else: if prods[-1].optional: prod = None elif prod and prod.optional: # ignore optional continue - + if prod and not prod.optional: wellformed = False self._log.error(u'%s: Missing token for production %r' @@ -573,6 +575,7 @@ for ProdParser instances. """ types = cssutils.cssproductions.CSSProductions + reHexcolor = re.compile(r'^\#(?:[0-9abcdefABCDEF]{3}|[0-9abcdefABCDEF]{6})$') @staticmethod def calc(toSeq=None, nextSor=False): @@ -582,7 +585,7 @@ nextSor=nextSor) @staticmethod - def char(name='char', char=u',', toSeq=None, + def char(name='char', char=u',', toSeq=None, stop=False, stopAndKeep=False, optional=True, nextSor=False): "any CHAR" @@ -619,11 +622,13 @@ def hexcolor(stop=False, nextSor=False): "#123 or #123456" return Prod(name='HEX color', - match=lambda t, v: t == PreDef.types.HASH and ( - len(v) == 4 or len(v) == 7), + match=lambda t, v: ( + t == PreDef.types.HASH and + PreDef.reHexcolor.match(v) + ), stop=stop, nextSor=nextSor) - + @staticmethod def ident(stop=False, toStore=None, nextSor=False): return Prod(name=u'ident', @@ -636,7 +641,7 @@ def number(stop=False, toSeq=None, nextSor=False): return Prod(name=u'number', match=lambda t, v: t == PreDef.types.NUMBER, - stop=stop, + stop=stop, toSeq=toSeq, nextSor=nextSor) @@ -670,7 +675,7 @@ "+ or -" return Prod(name=u'unary +-', match=lambda t, v: v in (u'+', u'-'), optional=True, - stop=stop, + stop=stop, toSeq=toSeq, nextSor=nextSor) @@ -692,7 +697,7 @@ stop=stop, nextSor=nextSor ) - + @staticmethod def variable(toSeq=None, stop=False, nextSor=False): return Prod(name=u'variable', @@ -704,25 +709,25 @@ # used for MarginRule for now: @staticmethod def unknownrule(name=u'@', toStore=None): - """@rule dummy (matches ATKEYWORD to remove unknown rule tokens from + """@rule dummy (matches ATKEYWORD to remove unknown rule tokens from stream:: - + @x; @x {...} - + no nested yet! - """ + """ def rule(tokens): saved = [] for t in tokens: saved.append(t) if (t[1] == u'}' or t[1] == u';'): return cssutils.css.CSSUnknownRule(saved) - + return Prod(name=name, match=lambda t, v: t == u'ATKEYWORD', - toSeq=lambda t, tokens: (u'CSSUnknownRule', + toSeq=lambda t, tokens: (u'CSSUnknownRule', rule(pushtoken(t, tokens)) ), toStore=toStore - ) \ No newline at end of file + ) diff -Nru cssutils-0.9.10~b1/src/cssutils/profiles.py cssutils-0.9.10/src/cssutils/profiles.py --- cssutils-0.9.10~b1/src/cssutils/profiles.py 2012-04-28 14:36:12.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/profiles.py 2013-03-31 19:00:54.000000000 +0000 @@ -29,7 +29,7 @@ Still should be a TODO. """ match = _fontRegexReplacements['__FONT_FAMILY_SINGLE'] - + for f in families.split(u','): if not match(f.strip()): return False @@ -118,7 +118,7 @@ } _MACROS = { 'hexcolor': r'#[0-9a-f]{3}|#[0-9a-f]{6}', - 'rgbcolor': r'rgb\({w}{int}{w},{w}{int}{w},{w}{int}{w}\)|rgb\({w}{num}%{w},{w}{num}%{w},{w}{num}%{w}\)', + 'rgbcolor': r'rgb\({w}{int}{w}\,{w}{int}{w}\,{w}{int}{w}\)|rgb\({w}{num}%{w}\,{w}{num}%{w}\,{w}{num}%{w}\)', 'namedcolor': r'(transparent|orange|maroon|red|orange|yellow|olive|purple|fuchsia|white|lime|green|navy|blue|aqua|teal|black|silver|gray)', 'uicolor': r'(ActiveBorder|ActiveCaption|AppWorkspace|Background|ButtonFace|ButtonHighlight|ButtonShadow|ButtonText|CaptionText|GrayText|Highlight|HighlightText|InactiveBorder|InactiveCaption|InactiveCaptionText|InfoBackground|InfoText|Menu|MenuText|Scrollbar|ThreeDDarkShadow|ThreeDFace|ThreeDHighlight|ThreeDLightShadow|ThreeDShadow|Window|WindowFrame|WindowText)', 'color': r'{namedcolor}|{hexcolor}|{rgbcolor}|{uicolor}', @@ -132,22 +132,22 @@ 'percentage': r'{num}%', 'shadow': '(inset)?{w}{length}{w}{length}{w}{length}?{w}{length}?{w}{color}?' } - + def __init__(self, log=None): """A few profiles are predefined.""" self._log = log - + # macro cache self._usedMacros = Profiles._TOKEN_MACROS.copy() self._usedMacros.update(Profiles._MACROS.copy()) - + # to keep order, REFACTOR! - self._profileNames = [] + self._profileNames = [] # for reset if macro changes self._rawProfiles = {} # already compiled profiles: {profile: {property: checkfunc, ...}, ...} self._profilesProperties = {} - + self._defaultProfiles = None self.addProfiles([(self.CSS_LEVEL_2, @@ -195,14 +195,14 @@ """Expand macros in token dictionary""" def macro_value(m): return '(?:%s)' % macros[m.groupdict()['macro']] - + for key, value in dictionary.items(): if not hasattr(value, '__call__'): while re.search(r'{[a-z][a-z0-9-]*}', value): value = re.sub(r'{(?P[a-z][a-z0-9-]*)}', macro_value, value) dictionary[key] = value - + return dictionary def _compile_regexes(self, dictionary): @@ -253,11 +253,11 @@ # base macros = Profiles._TOKEN_MACROS.copy() macros.update(Profiles._MACROS.copy()) - + # former for profile in self._profileNames: - macros.update(self._rawProfiles[profile]['macros']) - + macros.update(self._rawProfiles[profile]['macros']) + # new if newMacros: macros.update(newMacros) @@ -267,17 +267,17 @@ for profile in self._profileNames: properties = self._expand_macros( # keep raw - self._rawProfiles[profile]['properties'].copy(), + self._rawProfiles[profile]['properties'].copy(), macros) self._profilesProperties[profile] = self._compile_regexes(properties) # save self._usedMacros = macros - + def addProfiles(self, profiles): - """Add a list of profiles at once. Useful as if profiles define custom - macros these are used in one go. Using `addProfile` instead my be + """Add a list of profiles at once. Useful as if profiles define custom + macros these are used in one go. Using `addProfile` instead my be **very** slow instead. """ # add macros @@ -289,8 +289,8 @@ # only add new properties for profile, properties, macros in profiles: self.addProfile(profile, properties.copy(), None) - - + + def addProfile(self, profile, properties, macros=None): """Add a new profile with name `profile` (e.g. 'CSS level 2') and the given `properties`. @@ -319,38 +319,38 @@ # check if known macros would change and if yes reset properties if len(set(macros.keys()).intersection(self._usedMacros.keys())): self._resetProperties(newMacros=macros) - + else: # no replacement, simply continue self._usedMacros.update(macros) - + else: # might have been set by addProfiles before try: macros = self._rawProfiles[profile]['macros'] except KeyError, e: macros = {} - - # save name and raw props/macros if macros change to completely reset - self._profileNames.append(profile) + + # save name and raw props/macros if macros change to completely reset + self._profileNames.append(profile) self._rawProfiles[profile] = {'properties': properties.copy(), 'macros': macros.copy()} # prepare and save properties - properties = self._expand_macros(properties, self._usedMacros) + properties = self._expand_macros(properties, self._usedMacros) self._profilesProperties[profile] = self._compile_regexes(properties) self.__update_knownNames() - + # hack for font and font-family which are too slow with regexes if '__FONT_WITH_1_FAMILY' in properties: _fontRegexReplacements['__FONT_WITH_1_FAMILY'] = properties['__FONT_WITH_1_FAMILY'] if '__FONT_FAMILY_SINGLE' in properties: _fontRegexReplacements['__FONT_FAMILY_SINGLE'] = properties['__FONT_FAMILY_SINGLE'] - - + + def removeProfile(self, profile=None, all=False): """Remove `profile` or remove `all` profiles. - + If the removed profile used custom macros all remaining profiles are reset to reflect the macro changes. This may be quite an expensive operation! @@ -369,7 +369,7 @@ del self._profileNames[:] else: reset = False - + try: if (self._rawProfiles[profile]['macros']): reset = True @@ -423,7 +423,7 @@ # custom validation errors are caught r = bool(self._profilesProperties[profile][name](value)) except Exception, e: - # TODO: more specific exception? + # TODO: more specific exception? # Validate should not be fatal though! self._log.error(e, error=Exception) r = False @@ -731,14 +731,14 @@ # orange and transparent in CSS 2.1 'namedcolor': r'(currentcolor|transparent|aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow)', # orange? - 'rgbacolor': r'rgba\({w}{int}{w},{w}{int}{w},{w}{int}{w},{w}{int}{w}\)|rgba\({w}{num}%{w},{w}{num}%{w},{w}{num}%{w},{w}{num}{w}\)', - 'hslcolor': r'hsl\({w}{int}{w},{w}{num}%{w},{w}{num}%{w}\)|hsla\({w}{int}{w},{w}{num}%{w},{w}{num}%{w},{w}{num}{w}\)', + 'rgbacolor': r'rgba\({w}{int}{w}\,{w}{int}{w}\,{w}{int}{w}\,{w}{num}{w}\)|rgba\({w}{num}%{w}\,{w}{num}%{w}\,{w}{num}%{w}\,{w}{num}{w}\)', + 'hslcolor': r'hsl\({w}{int}{w}\,{w}{num}%{w}\,{w}{num}%{w}\)|hsla\({w}{int}{w}\,{w}{num}%{w}\,{w}{num}%{w}\,{w}{num}{w}\)', 'x11color': r'aliceblue|antiquewhite|aqua|aquamarine|azure|beige|bisque|black|blanchedalmond|blue|blueviolet|brown|burlywood|cadetblue|chartreuse|chocolate|coral|cornflowerblue|cornsilk|crimson|cyan|darkblue|darkcyan|darkgoldenrod|darkgray|darkgreen|darkgrey|darkkhaki|darkmagenta|darkolivegreen|darkorange|darkorchid|darkred|darksalmon|darkseagreen|darkslateblue|darkslategray|darkslategrey|darkturquoise|darkviolet|deeppink|deepskyblue|dimgray|dimgrey|dodgerblue|firebrick|floralwhite|forestgreen|fuchsia|gainsboro|ghostwhite|gold|goldenrod|gray|green|greenyellow|grey|honeydew|hotpink|indianred|indigo|ivory|khaki|lavender|lavenderblush|lawngreen|lemonchiffon|lightblue|lightcoral|lightcyan|lightgoldenrodyellow|lightgray|lightgreen|lightgrey|lightpink|lightsalmon|lightseagreen|lightskyblue|lightslategray|lightslategrey|lightsteelblue|lightyellow|lime|limegreen|linen|magenta|maroon|mediumaquamarine|mediumblue|mediumorchid|mediumpurple|mediumseagreen|mediumslateblue|mediumspringgreen|mediumturquoise|mediumvioletred|midnightblue|mintcream|mistyrose|moccasin|navajowhite|navy|oldlace|olive|olivedrab|orange|orangered|orchid|palegoldenrod|palegreen|paleturquoise|palevioletred|papayawhip|peachpuff|peru|pink|plum|powderblue|purple|red|rosybrown|royalblue|saddlebrown|salmon|sandybrown|seagreen|seashell|sienna|silver|skyblue|slateblue|slategray|slategrey|snow|springgreen|steelblue|tan|teal|thistle|tomato|turquoise|violet|wheat|white|whitesmoke|yellow|yellowgreen', 'uicolor': r'(ActiveBorder|ActiveCaption|AppWorkspace|Background|ButtonFace|ButtonHighlight|ButtonShadow|ButtonText|CaptionText|GrayText|Highlight|HighlightText|InactiveBorder|InactiveCaption|InactiveCaptionText|InfoBackground|InfoText|Menu|MenuText|Scrollbar|ThreeDDarkShadow|ThreeDFace|ThreeDHighlight|ThreeDLightShadow|ThreeDShadow|Window|WindowFrame|WindowText)', 'color': r'{namedcolor}|{hexcolor}|{rgbcolor}|{rgbacolor}|{hslcolor}|{x11color}|inherit', } properties[Profiles.CSS3_COLOR] = { - 'opacity': r'{num}|inherit' + 'opacity': r'{num}|inherit', } # CSS Fonts Module Level 3 http://www.w3.org/TR/css3-fonts/ diff -Nru cssutils-0.9.10~b1/src/cssutils/serialize.py cssutils-0.9.10/src/cssutils/serialize.py --- cssutils-0.9.10~b1/src/cssutils/serialize.py 2012-03-24 18:36:36.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/serialize.py 2013-03-31 19:38:38.000000000 +0000 @@ -48,7 +48,7 @@ indent = 4 * ' ' Indentation of e.g Properties inside a CSSStyleDeclaration indentClosingBrace = True - Defines if closing brace of block is indented to match indentation + Defines if closing brace of block is indented to match indentation of the block (default) oder match indentation of selector. indentSpecificities = False (**EXPERIMENTAL**) Indent rules with subset of Selectors and higher Specitivity @@ -243,7 +243,7 @@ self._remove_last_if_S() # APPEND - + if indent or (val == u'}' and self.ser.prefs.indentClosingBrace): self.out.append(self.ser._indentblock(val, self.ser._level+1)) else: @@ -570,7 +570,7 @@ out.extend(rulesout) # } - out.append(u'%s}' % ((self._level + int(self.prefs.indentClosingBrace)) + out.append(u'%s}' % ((self._level + int(self.prefs.indentClosingBrace)) * self.prefs.indent)) return u''.join(out) @@ -596,19 +596,19 @@ if rtext: rulesout.append(rtext) rulesout.append(self.prefs.lineSeparator) - + rulesText = u''.join(rulesout)#.strip() # omit semicolon only if no MarginRules styleText = self.do_css_CSSStyleDeclaration(rule.style, omit=not rulesText) - + if (styleText or rulesText) and rule.wellformed: out = Out(self) out.append(self._atkeyword(rule)) out.append(rule.selectorText) out.append(u'{') - + if styleText: if not rulesText: out.append(u'%s%s' % (styleText, @@ -616,14 +616,14 @@ ), indent=1) else: out.append(styleText, type_='styletext', indent=1, space=False) - - if rulesText: + + if rulesText: out.append(rulesText, indent=1) #? - self._level -= 1 + self._level -= 1 out.append(u'}') - self._level += 1 - + self._level += 1 + return out.value() else: return u'' @@ -652,10 +652,10 @@ # might not be set at all?! if rule.atkeyword: styleText = self.do_css_CSSStyleDeclaration(rule.style) - + if styleText and rule.wellformed: out = Out(self) - + # # use seq but styledecl missing # for item in rule.seq: # if item.type == 'ATKEYWORD': @@ -665,7 +665,7 @@ # print type_, val # out.append(item.value, item.type) # return out.value() - + # ok for now: out.append(self._atkeyword(rule), type_='ATKEYWORD') out.append(u'{') @@ -750,7 +750,7 @@ selectorText = self.do_css_SelectorList(rule.selectorList) if not selectorText or not rule.wellformed: - return u'' + return u'' self._level += 1 styleText = u'' try: @@ -769,7 +769,7 @@ self.prefs.lineSeparator, self._indentblock(styleText, self._level + 1), self.prefs.lineSeparator, - (self._level + int(self.prefs.indentClosingBrace)) + (self._level + int(self.prefs.indentClosingBrace)) * self.prefs.indent), self._selectorlevel) @@ -884,7 +884,7 @@ out = [] omitLastSemicolon = omit and self.prefs.omitLastSemicolon - + for i, item in enumerate(seq): type_, val = item.type, item.value if isinstance(val, cssutils.css.CSSComment): @@ -998,6 +998,12 @@ return out.value() + def _strip_zeros(self, s): + i = s.index(u'.') + 2 + a, b = s[0:i], s[i:len(s)] + b = b.rstrip('0') + return a + b + def do_css_Value(self, value, valuesOnly=None): """Serializes a Value, valuesOnly is ignored""" if not value: @@ -1015,28 +1021,29 @@ # cut off after . which is zero anyway val = unicode(int(value.value)) elif self.prefs.omitLeadingZero and -1 < value.value < 1: - v = unicode(value.value) + v = self._strip_zeros(u'%f' % value.value) # issue #27 val = v if value._sign == u'-': val = v[0] + v[2:] else: val = v[1:] else: - val = unicode(value.value) + + val = self._strip_zeros(u'%f' % value.value) # issue #27 # keep '+' if given if value.value != 0 and value._sign == u'+': sign = u'+' else: sign = u'' - + out.append(sign + val + dim, value.type) - + else: # e.g. URI out.append(value.value, value.type) - - return out.value() + + return out.value() def do_css_ColorValue(self, value, valuesOnly=False): """Serialize a ColorValue, a HASH simple value or FUNCTION""" @@ -1044,7 +1051,7 @@ return {'FUNCTION': self.do_css_CSSFunction, 'HASH': self.do_css_Value, 'IDENT': self.do_css_Value - }[value.colorType](value, + }[value.colorType](value, valuesOnly=valuesOnly) except KeyError, e: return u'' diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/__init__.py cssutils-0.9.10/src/cssutils/tests/__init__.py --- cssutils-0.9.10~b1/src/cssutils/tests/__init__.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/__init__.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1 @@ +"""cssutils unittests""" diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/basetest.py cssutils-0.9.10/src/cssutils/tests/basetest.py --- cssutils-0.9.10~b1/src/cssutils/tests/basetest.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/basetest.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,168 @@ +"""Base class for all tests""" + +import logging +import os +import sys +import StringIO +import unittest +import urllib2 +from email import message_from_string, message_from_file + +# add src to PYTHONPATH +sys.path.append(os.path.join(os.path.abspath('.'), '..')) + +import cssutils + + +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 + + +class BaseTestCase(unittest.TestCase): + + def _tempSer(self): + "Replace default ser with temp ser." + self._ser = cssutils.ser + cssutils.ser = cssutils.serialize.CSSSerializer() + + def _restoreSer(self): + "Restore the default ser." + cssutils.ser = self._ser + + def setUp(self): + # a raising parser!!! + cssutils.log.raiseExceptions = True + cssutils.log.setLevel(logging.FATAL) + self.p = cssutils.CSSParser(raiseExceptions=True) + + def tearDown(self): + 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, 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.failUnless(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: + exc_info = sys.exc_info() + print 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 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) + ) + + from + http://www.nedbatchelder.com/blog/200609.html#e20060905T064418 + """ + try: + callableObj(*args, **kwargs) + except excClass, exc: + excMsg = unicode(exc) + if not msg: + # No message provided: any message is fine. + return + elif excMsg == msg: + # Message provided, and we got the right message: passes. + return + else: + # Message provided, and it didn't match: fail! + raise self.failureException( + u"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 do_equal_p(self, tests, att='cssText', debug=False, raising=True): + """ + if raising self.p is used for parsing, else self.pf + """ + p = cssutils.CSSParser(raiseExceptions=raising) + # parses with self.p and checks att of result + for test, expected in tests.items(): + if debug: + print '"%s"' % test + s = p.parseString(test) + if expected is None: + expected = test + self.assertEqual(expected, unicode(s.__getattribute__(att), 'utf-8')) + + def do_raise_p(self, tests, debug=False, raising=True): + # parses with self.p and expects raise + p = cssutils.CSSParser(raiseExceptions=raising) + for test, expected in tests.items(): + if debug: + print '"%s"' % test + self.assertRaises(expected, p.parseString, test) + + def do_equal_r(self, tests, att='cssText', debug=False): + # sets attribute att of self.r and asserts Equal + for test, expected in tests.items(): + if debug: + print '"%s"' % test + self.r.__setattr__(att, test) + if expected is None: + expected = test + self.assertEqual(expected, self.r.__getattribute__(att)) + + def do_raise_r(self, tests, att='_setCssText', debug=False): + # sets self.r and asserts raise + for test, expected in tests.items(): + if debug: + print '"%s"' % test + self.assertRaises(expected, self.r.__getattribute__(att), test) diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_codec.py cssutils-0.9.10/src/cssutils/tests/test_codec.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_codec.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_codec.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,342 @@ +"""Testcases for cssutils.codec""" + +import codecs +import unittest +import sys + +PY2x = sys.version_info < (3,0) +if PY2x: + import StringIO + iostream = StringIO.StringIO +else: + import io + iostream = io.BytesIO + +from cssutils import codec + +try: + codecs.lookup("utf-32") +except LookupError: + haveutf32 = False +else: + haveutf32 = True + + +class Queue(object): + """ + queue: write bytes at one end, read bytes from the other end + """ + def __init__(self): + self._buffer = "".encode() + + def write(self, chars): + # TODO ??? + if not PY2x: + if isinstance(chars, str): + chars = chars.encode() + elif isinstance(chars, int): + chars = bytes([chars]) + + self._buffer += chars + + def read(self, size=-1): + if size<0: + s = self._buffer + self._buffer = "".encode() + return s + else: + s = self._buffer[:size] + self._buffer = self._buffer[size:] + return s + + +class CodecTestCase(unittest.TestCase): + + def test_detectencoding_str(self): + "codec.detectencoding_str()" + self.assertEqual(codec.detectencoding_str(u''.encode()), (None, False)) + self.assertEqual(codec.detectencoding_str(u'\xef'.encode('latin1')), (None, False)) + self.assertEqual(codec.detectencoding_str(u'\xef\x33'.encode("utf-8")), ("utf-8", False)) + self.assertEqual(codec.detectencoding_str(u'\xc3\xaf3'.encode("utf-8")), ("utf-8", False)) + self.assertEqual(codec.detectencoding_str(u'\xef\xbb'.encode("latin1")), (None, False)) + self.assertEqual(codec.detectencoding_str(u'\xef\xbb\x33'.encode("utf-8")), ("utf-8", False)) + self.assertEqual(codec.detectencoding_str(u'\xef\xbb\xbf'.encode("utf-8-sig")), ("utf-8-sig", True)) + self.assertEqual(codec.detectencoding_str(u'\xff'.encode("latin1")), (None, False)) + self.assertEqual(codec.detectencoding_str(u'\xff\x33'.encode("utf-8")), ("utf-8", False)) + self.assertEqual(codec.detectencoding_str(u'\xff\xfe'.encode("latin1")), (None, False)) + self.assertEqual(codec.detectencoding_str(u'\xff\xfe\x33'.encode("utf-16")), ("utf-16", True)) + self.assertEqual(codec.detectencoding_str(u'\xff\xfe\x00'.encode("latin1")), (None, False)) + self.assertEqual(codec.detectencoding_str(u'\xff\xfe\x00\x33'.encode("utf-16")), ("utf-16", True)) + if haveutf32: + self.assertEqual(codec.detectencoding_str(u'\xff\xfe\x00\x00'.encode("utf-32")), ("utf-32", True)) + self.assertEqual(codec.detectencoding_str(u'\x00'.encode()), (None, False)) + self.assertEqual(codec.detectencoding_str(u'\x00\x33'.encode()), ("utf-8", False)) + self.assertEqual(codec.detectencoding_str(u'\x00\x00'.encode()), (None, False)) + self.assertEqual(codec.detectencoding_str(u'\x00\x00\x33'.encode()), ("utf-8", False)) + self.assertEqual(codec.detectencoding_str(u'\x00\x00\xfe'.encode('latin1')), (None, False)) + self.assertEqual(codec.detectencoding_str(u'\x00\x00\x00\x33'.encode()), ("utf-8", False)) + if haveutf32: + self.assertEqual(codec.detectencoding_str(u'\x00\x00\x00@'.encode()), ("utf-32-be", False)) + self.assertEqual(codec.detectencoding_str(u'\x00\x00\xfe\xff'.encode('utf-32')), ("utf-32", True)) + self.assertEqual(codec.detectencoding_str(u'@'.encode()), (None, False)) + self.assertEqual(codec.detectencoding_str(u'@\x33'.encode()), ("utf-8", False)) + self.assertEqual(codec.detectencoding_str(u'@\x00'.encode()), (None, False)) + self.assertEqual(codec.detectencoding_str(u'@\x00\x33'.encode()), ("utf-8", False)) + self.assertEqual(codec.detectencoding_str(u'@\x00\x00'.encode()), (None, False)) + self.assertEqual(codec.detectencoding_str(u'@\x00\x00\x33'.encode()), ("utf-8", False)) + if haveutf32: + self.assertEqual(codec.detectencoding_str(u'@\x00\x00\x00'.encode()), ("utf-32-le", False)) + self.assertEqual(codec.detectencoding_str(u'@c'.encode()), (None, False)) + self.assertEqual(codec.detectencoding_str(u'@ch'.encode()), (None, False)) + self.assertEqual(codec.detectencoding_str(u'@cha'.encode()), (None, False)) + self.assertEqual(codec.detectencoding_str(u'@char'.encode()), (None, False)) + self.assertEqual(codec.detectencoding_str(u'@chars'.encode()), (None, False)) + self.assertEqual(codec.detectencoding_str(u'@charse'.encode()), (None, False)) + self.assertEqual(codec.detectencoding_str(u'@charset'.encode()), (None, False)) + self.assertEqual(codec.detectencoding_str(u'@charset '.encode()), (None, False)) + self.assertEqual(codec.detectencoding_str(u'@charset "'.encode()), (None, False)) + self.assertEqual(codec.detectencoding_str(u'@charset "x'.encode()), (None, False)) + self.assertEqual(codec.detectencoding_str(u'@charset ""'.encode()), ("", True)) + self.assertEqual(codec.detectencoding_str(u'@charset "x"'.encode()), ("x", True)) + self.assertEqual(codec.detectencoding_str(u"@".encode(), False), (None, False)) + self.assertEqual(codec.detectencoding_str(u"@".encode(), True), ("utf-8", False)) + self.assertEqual(codec.detectencoding_str(u"@c".encode(), False), (None, False)) + self.assertEqual(codec.detectencoding_str(u"@c".encode(), True), ("utf-8", False)) + + def test_detectencoding_unicode(self): + "codec.detectencoding_unicode()" + # Unicode version (only parses the header) + self.assertEqual(codec.detectencoding_unicode(u'@charset "x'), (None, False)) + self.assertEqual(codec.detectencoding_unicode(u'a {}'), ("utf-8", False)) + self.assertEqual(codec.detectencoding_unicode(u'@charset "x', True), (None, False)) + self.assertEqual(codec.detectencoding_unicode(u'@charset "x"'), ("x", True)) + + def test_fixencoding(self): + "codec._fixencoding()" + s = u'@charset "' + self.assert_(codec._fixencoding(s, u"utf-8") is None) + + s = u'@charset "x' + self.assert_(codec._fixencoding(s, u"utf-8") is None) + + s = u'@charset "x' + self.assertEqual(codec._fixencoding(s, u"utf-8", True), s) + + s = u'@charset x' + self.assertEqual(codec._fixencoding(s, u"utf-8"), s) + + s = u'@charset "x"' + self.assertEqual(codec._fixencoding(s, u"utf-8"), s.replace('"x"', '"utf-8"')) + + def test_decoder(self): + "codecs.decoder" + def checkauto(encoding, input=u'@charset "x";g\xfcrk\u20ac{}'): + outputencoding = encoding + if outputencoding == "utf-8-sig": + outputencoding = "utf-8" + # Check stateless decoder with encoding autodetection + d = codecs.getdecoder("css") + self.assertEqual(d(input.encode(encoding))[0], input.replace('"x"', '"%s"' % outputencoding)) + + # Check stateless decoder with specified encoding + self.assertEqual(d(input.encode(encoding), encoding=encoding)[0], input.replace('"x"', '"%s"' % outputencoding)) + + if hasattr(codec, "getincrementaldecoder"): + # Check incremental decoder with encoding autodetection + id = codecs.getincrementaldecoder("css")() + self.assertEqual("".join(id.iterdecode(input.encode(encoding))), input.replace('"x"', '"%s"' % outputencoding)) + + # Check incremental decoder with specified encoding + id = codecs.getincrementaldecoder("css")(encoding=encoding) + self.assertEqual("".join(id.iterdecode(input.encode(encoding))), input.replace('"x"', '"%s"' % outputencoding)) + + # Check stream reader with encoding autodetection + q = Queue() + sr = codecs.getreader("css")(q) + result = [] + # TODO: py3 only??? + for c in input.encode(encoding): + q.write(c) + result.append(sr.read()) + self.assertEqual("".join(result), input.replace('"x"', '"%s"' % outputencoding)) + + # Check stream reader with specified encoding + q = Queue() + sr = codecs.getreader("css")(q, encoding=encoding) + result = [] + for c in input.encode(encoding): + q.write(c) + result.append(sr.read()) + self.assertEqual("".join(result), input.replace('"x"', '"%s"' % outputencoding)) + + # Autodetectable encodings + checkauto("utf-8-sig") + checkauto("utf-16") + checkauto("utf-16-le") + checkauto("utf-16-be") + if haveutf32: + checkauto("utf-32") + checkauto("utf-32-le") + checkauto("utf-32-be") + + def checkdecl(encoding, input=u'@charset "%s";g\xfcrk{}'): + # Check stateless decoder with encoding autodetection + d = codecs.getdecoder("css") + input = input % encoding + outputencoding = encoding + if outputencoding == "utf-8-sig": + outputencoding = "utf-8" + self.assertEqual(d(input.encode(encoding))[0], input) + + # Check stateless decoder with specified encoding + self.assertEqual(d(input.encode(encoding), encoding=encoding)[0], input) + + if hasattr(codec, "getincrementaldecoder"): + # Check incremental decoder with encoding autodetection + id = codecs.getincrementaldecoder("css")() + self.assertEqual("".join(id.iterdecode(input.encode(encoding))), input) + + # Check incremental decoder with specified encoding + id = codecs.getincrementaldecoder("css")(encoding) + self.assertEqual("".join(id.iterdecode(input.encode(encoding))), input) + + # Check stream reader with encoding autodetection + q = Queue() + sr = codecs.getreader("css")(q) + result = [] + for c in input.encode(encoding): + q.write(c) + result.append(sr.read()) + self.assertEqual("".join(result), input) + + # Check stream reader with specified encoding + q = Queue() + sr = codecs.getreader("css")(q, encoding=encoding) + result = [] + for c in input.encode(encoding): + q.write(c) + result.append(sr.read()) + self.assertEqual("".join(result), input) + + # Use correct declaration + checkdecl("utf-8") + checkdecl("iso-8859-1", u'@charset "%s";g\xfcrk') + checkdecl("iso-8859-15") + checkdecl("cp1252") + + # No recursion + self.assertRaises(ValueError, u'@charset "css";div{}'.encode().decode, "css") + + def test_encoder(self): + "codec.encoder" + def check(encoding, input=u'@charset "x";g\xfcrk\u20ac{}'): + outputencoding = encoding + if outputencoding == "utf-8-sig": + outputencoding = "utf-8" + + # Check stateless encoder with encoding autodetection + e = codecs.getencoder("css") + inputdecl = input.replace('"x"', '"%s"' % encoding) + outputdecl = input.replace('"x"', '"%s"' % outputencoding) + self.assertEqual(e(inputdecl)[0].decode(encoding), outputdecl) + + # Check stateless encoder with specified encoding + self.assertEqual(e(input, encoding=encoding)[0].decode(encoding), outputdecl) + + if hasattr(codec, "getincrementalencoder"): + # Check incremental encoder with encoding autodetection + ie = codecs.getincrementalencoder("css")() + self.assertEqual("".join(ie.iterencode(inputdecl)).decode(encoding), outputdecl) + + # Check incremental encoder with specified encoding + ie = codecs.getincrementalencoder("css")(encoding=encoding) + self.assertEqual("".join(ie.iterencode(input)).decode(encoding), outputdecl) + + # Check stream writer with encoding autodetection + q = Queue() + sw = codecs.getwriter("css")(q) + for c in inputdecl:#.encode(outputencoding): # TODO: .encode()??? + sw.write(c) + self.assertEqual(q.read().decode(encoding), input.replace('"x"', '"%s"' % outputencoding)) + + # Check stream writer with specified encoding + q = Queue() + sw = codecs.getwriter("css")(q, encoding=encoding) + for c in input: + sw.write(c) + self.assertEqual(q.read().decode(encoding), input.replace('"x"', '"%s"' % outputencoding)) + + # Autodetectable encodings + check("utf-8-sig") + check("utf-16") + check("utf-16-le") + check("utf-16-be") + if haveutf32: + check("utf-32") + check("utf-32-le") + check("utf-32-be") + check("utf-8") + check("iso-8859-1", u'@charset "x";g\xfcrk{}') + check("iso-8859-15") + check("cp1252") + + # No recursion + self.assertRaises(ValueError, u'@charset "css";div{}'.encode, "css") + + def test_decode_force(self): + "codec.decode (force)" + info = codecs.lookup("css") + + def decodeall(input, **kwargs): + # Py 2.5: info.decode('@charset "utf-8"; x') + return info[1](input, **kwargs)[0] + + def incdecode(input, **kwargs): + decoder = info.incrementaldecoder(**kwargs) + return decoder.decode(input) + + def streamdecode(input, **kwargs): + stream = iostream(input) # py3 .decode('utf-8') but still error?! + reader = info.streamreader(stream, **kwargs) + return reader.read() + + for d in (decodeall, incdecode, streamdecode): +# input = '@charset "utf-8"; \xc3\xbf' +# output = u'@charset "utf-8"; \xff' +# self.assertEqual(d(input), output) +# +# input = '@charset "utf-8"; \xc3\xbf' +# output = u'@charset "iso-8859-1"; \xc3\xbf' +# self.assertEqual(d(input, encoding="iso-8859-1", force=True), output) +# +# input = '\xc3\xbf' +# output = u'\xc3\xbf' +# self.assertEqual(d(input, encoding="iso-8859-1", force=True), output) +# +# input = '@charset "utf-8"; \xc3\xbf' +# output = u'@charset "utf-8"; \xff' +# self.assertEqual(d(input, encoding="iso-8859-1", force=False), output) + + input = u'@charset "utf-8"; \xff'.encode('utf-8') + output = u'@charset "utf-8"; \xff' + self.assertEqual(d(input), output) + + #input = b'@charset "utf-8"; \xc3\xbf' + input = u'@charset "utf-8"; \xff'.encode('utf-8') + output = u'@charset "iso-8859-1"; \xc3\xbf' + self.assertEqual(d(input, encoding="iso-8859-1", force=True), output) + + #input = b'\xc3\xbf' + input = u'\xff'.encode('utf-8') + output = u'\xc3\xbf' + self.assertEqual(d(input, encoding="iso-8859-1", force=True), output) + + #input = b'@charset "utf-8"; \xc3\xbf' + input = u'@charset "utf-8"; \xff'.encode('utf-8') + output = u'@charset "utf-8"; \xff' + self.assertEqual(d(input, encoding="iso-8859-1", force=False), output) + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_csscharsetrule.py cssutils-0.9.10/src/cssutils/tests/test_csscharsetrule.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_csscharsetrule.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_csscharsetrule.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,123 @@ +"""Testcases for cssutils.css.CSSCharsetRule""" + +import re +import xml.dom +import test_cssrule +import cssutils.css + +class CSSCharsetRuleTestCase(test_cssrule.CSSRuleTestCase): + + def setUp(self): + super(CSSCharsetRuleTestCase, self).setUp() + self.r = cssutils.css.CSSCharsetRule() + self.rRO = cssutils.css.CSSCharsetRule(readonly=True) + self.r_type = cssutils.css.CSSCharsetRule.CHARSET_RULE + self.r_typeString = 'CHARSET_RULE' + + def test_init(self): + "CSSCharsetRule.__init__()" + super(CSSCharsetRuleTestCase, self).test_init() + self.assertEqual(None, self.r.encoding) + self.assertEqual(u'', self.r.cssText) + + self.assertRaises(xml.dom.InvalidModificationErr, self.r._setCssText, u'xxx') + + def test_InvalidModificationErr(self): + "CSSCharsetRule InvalidModificationErr" + self._test_InvalidModificationErr(u'@charset') + + def test_init_encoding(self): + "CSSCharsetRule.__init__(encoding)" + for enc in (None, u'UTF-8', u'utf-8', u'iso-8859-1', u'ascii'): + r = cssutils.css.CSSCharsetRule(enc) + if enc is None: + self.assertEqual(None, r.encoding) + self.assertEqual(u'', r.cssText) + else: + self.assertEqual(enc.lower(), r.encoding) + self.assertEqual( + u'@charset "%s";' % enc.lower(), r.cssText) + + for enc in (' ascii ', ' ascii', 'ascii '): + self.assertRaisesEx(xml.dom.SyntaxErr, + cssutils.css.CSSCharsetRule, enc, + exc_pattern=re.compile("Syntax Error")) + + for enc in (u'unknown', ): + self.assertRaisesEx(xml.dom.SyntaxErr, + cssutils.css.CSSCharsetRule, enc, + exc_pattern=re.compile("Unknown \(Python\) encoding")) + + def test_encoding(self): + "CSSCharsetRule.encoding" + for enc in (u'UTF-8', u'utf-8', u'iso-8859-1', u'ascii'): + self.r.encoding = enc + self.assertEqual(enc.lower(), self.r.encoding) + self.assertEqual( + u'@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")) + + for enc in (u'unknown', ): + self.assertRaisesEx(xml.dom.SyntaxErr, + self.r.__setattr__, 'encoding', enc, + exc_pattern=re.compile("Unknown \(Python\) encoding")) + + def test_cssText(self): + """CSSCharsetRule.cssText + + setting cssText is ok to use @CHARSET or other but a file + using parse MUST use ``@charset "ENCODING";`` + """ + tests = { + u'@charset "utf-8";': None, + u"@charset 'utf-8';": u'@charset "utf-8";', + } + self.do_equal_r(tests) + self.do_equal_p(tests) # also parse + + tests = { + # token is "@charset " with space! + u'@charset;"': xml.dom.InvalidModificationErr, + u'@CHARSET "UTF-8";': xml.dom.InvalidModificationErr, + u'@charset "";': xml.dom.SyntaxErr, + u'''@charset /*1*/"utf-8"/*2*/;''': xml.dom.SyntaxErr, + u'''@charset /*1*/"utf-8";''': xml.dom.SyntaxErr, + u'''@charset "utf-8"/*2*/;''': xml.dom.SyntaxErr, + u'@charset { utf-8 }': xml.dom.SyntaxErr, + u'@charset "utf-8"': xml.dom.SyntaxErr, + u'@charset a;': xml.dom.SyntaxErr, + u'@charset /**/;': xml.dom.SyntaxErr, + # trailing content + u'@charset "utf-8";s': xml.dom.SyntaxErr, + u'@charset "utf-8";/**/': xml.dom.SyntaxErr, + u'@charset "utf-8"; ': xml.dom.SyntaxErr, + + # comments do not work in this rule! + u'@charset "utf-8"/*1*//*2*/;': xml.dom.SyntaxErr + } + self.do_raise_r(tests) + + def test_repr(self): + "CSSCharsetRule.__repr__()" + self.r.encoding = 'utf-8' + self.assert_('utf-8' in repr(self.r)) + + def test_reprANDstr(self): + "CSSCharsetRule.__repr__(), .__str__()" + encoding='utf-8' + + s = cssutils.css.CSSCharsetRule(encoding=encoding) + + self.assert_(encoding in str(s)) + + s2 = eval(repr(s)) + self.assert_(isinstance(s2, s.__class__)) + self.assert_(encoding == s2.encoding) + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_csscomment.py cssutils-0.9.10/src/cssutils/tests/test_csscomment.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_csscomment.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_csscomment.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- +"""Testcases for cssutils.css.CSSComment""" + +import xml +import test_cssrule +import cssutils.css + +class CSSCommentTestCase(test_cssrule.CSSRuleTestCase): + + def setUp(self): + super(CSSCommentTestCase, self).setUp() + self.r = cssutils.css.CSSComment() + self.rRO = cssutils.css.CSSComment(readonly=True) + self.r_type = cssutils.css.CSSComment.COMMENT + self.r_typeString = 'COMMENT' + + def test_init(self): + "CSSComment.type and init" + super(CSSCommentTestCase, self).test_init() + + def test_csstext(self): + "CSSComment.cssText" + tests = { + u'/*öäü߀ÖÄÜ*/': u'/*\xf6\xe4\xfc\xdf\u20ac\xd6\xc4\xdc*/', + u'/*x*/': None, + u'/* x */': None, + u'/*\t12\n*/': None, + u'/* /* */': None, + u'/* \\*/': None, + u'/*"*/': None, + u'''/*" + */''': None, + u'/** / ** //*/': None + } + self.do_equal_r(tests) # set cssText + tests.update({ + u'/*x': u'/*x*/', + u'\n /*': u'/**/', + }) + self.do_equal_p(tests) # parse + + tests = { + u'/* */ ': xml.dom.InvalidModificationErr, + u'/* *//**/': xml.dom.InvalidModificationErr, + u'/* */1': xml.dom.InvalidModificationErr, + u'/* */ */': xml.dom.InvalidModificationErr, + u' */ /* ': xml.dom.InvalidModificationErr, + u'*/': xml.dom.InvalidModificationErr, + u'@x /* x */': xml.dom.InvalidModificationErr + } + self.do_raise_r(tests) # set cssText + # no raising of error possible? + # self.do_raise_p(tests) # parse + + def test_InvalidModificationErr(self): + "CSSComment.cssText InvalidModificationErr" + self._test_InvalidModificationErr(u'/* comment */') + + def test_reprANDstr(self): + "CSSComment.__repr__(), .__str__()" + text = '/* test */' + + s = cssutils.css.CSSComment(cssText=text) + + s2 = eval(repr(s)) + self.assert_(isinstance(s2, s.__class__)) + self.assert_(text == s2.cssText) + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_cssfontfacerule.py cssutils-0.9.10/src/cssutils/tests/test_cssfontfacerule.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_cssfontfacerule.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_cssfontfacerule.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,241 @@ +"""Testcases for cssutils.css.CSSFontFaceRule""" + +import xml.dom +import test_cssrule +import cssutils + +class CSSFontFaceRuleTestCase(test_cssrule.CSSRuleTestCase): + + def setUp(self): + super(CSSFontFaceRuleTestCase, self).setUp() + self.r = cssutils.css.CSSFontFaceRule() + self.rRO = cssutils.css.CSSFontFaceRule(readonly=True) + self.r_type = cssutils.css.CSSFontFaceRule.FONT_FACE_RULE# + self.r_typeString = 'FONT_FACE_RULE' + + def test_init(self): + "CSSFontFaceRule.__init__()" + super(CSSFontFaceRuleTestCase, self).test_init() + + r = cssutils.css.CSSFontFaceRule() + self.assert_(isinstance(r.style, cssutils.css.CSSStyleDeclaration)) + self.assertEqual(r, r.style.parentRule) + + # until any properties + self.assertEqual(u'', r.cssText) + + # only possible to set @... similar name + self.assertRaises(xml.dom.InvalidModificationErr, self.r._setAtkeyword, 'x') + + def checkrefs(ff): + self.assertEqual(ff, ff.style.parentRule) + for p in ff.style: + self.assertEqual(ff.style, p.parent) + + checkrefs(cssutils.css.CSSFontFaceRule( + style=cssutils.css.CSSStyleDeclaration('font-family: x'))) + + r = cssutils.css.CSSFontFaceRule() + r.cssText = '@font-face { font-family: x }' + checkrefs(r) + + r = cssutils.css.CSSFontFaceRule() + r.style.setProperty('font-family', 'y') + checkrefs(r) + + r = cssutils.css.CSSFontFaceRule() + r.style['font-family'] = 'z' + checkrefs(r) + + r = cssutils.css.CSSFontFaceRule() + r.style.fontFamily = 'a' + checkrefs(r) + + def test_cssText(self): + "CSSFontFaceRule.cssText" + tests = { + u'''@font-face { + font-family: x; + src: url(../fonts/LateefRegAAT.ttf) format("truetype-aat"), url(../fonts/LateefRegOT.ttf) format("opentype"); + font-style: italic; + font-weight: 500; + font-stretch: condensed; + unicode-range: u+1-ff, u+111 + }''': None, + u'@font-face{font-family: x;}': u'@font-face {\n font-family: x\n }', + u'@font-face { font-family: x; }': u'@font-face {\n font-family: x\n }', + u'@f\\ont\\-face{font-family : x;}': u'@font-face {\n font-family: x\n }', + # comments + u'@font-face/*1*//*2*/{font-family: x;}': + u'@font-face /*1*/ /*2*/ {\n font-family: x\n }', + # WS + u'@font-face\n\t\f {\n\t\f font-family:x;\n\t\f }': + u'@font-face {\n font-family: x\n }', + } + self.do_equal_r(tests) + self.do_equal_p(tests) + + tests = { + u'@font-face;': xml.dom.SyntaxErr, + u'@font-face }': xml.dom.SyntaxErr, + } + self.do_raise_p(tests) # parse + tests.update({ + u'@font-face {': xml.dom.SyntaxErr, # no } + # trailing + u'@font-face {}1': xml.dom.SyntaxErr, + u'@font-face {}/**/': xml.dom.SyntaxErr, + u'@font-face {} ': xml.dom.SyntaxErr, + }) + self.do_raise_r(tests) # set cssText + + def test_style(self): + "CSSFontFaceRule.style (and references)" + r = cssutils.css.CSSFontFaceRule() + s1 = r.style + self.assertEqual(r, s1.parentRule) + self.assertEqual(u'', s1.cssText) + + # set rule.cssText + r.cssText = '@font-face { font-family: x1 }' + self.failIfEqual(r.style, s1) + self.assertEqual(r, r.style.parentRule) + self.assertEqual(r.cssText, u'@font-face {\n font-family: x1\n }') + self.assertEqual(r.style.cssText, u'font-family: x1') + self.assertEqual(s1.cssText, u'') + s2 = r.style + + # set invalid rule.cssText + try: + r.cssText = '@font-face { $ }' + except xml.dom.SyntaxErr, e: + pass + self.assertEqual(r.style, s2) + self.assertEqual(r, s2.parentRule) + self.assertEqual(r.cssText, u'@font-face {\n font-family: x1\n }') + self.assertEqual(s2.cssText, u'font-family: x1') + self.assertEqual(r.style.cssText, u'font-family: x1') + + # set rule.style.cssText + r.style.cssText = 'font-family: x2' + self.assertEqual(r.style, s2) + self.assertEqual(r, s2.parentRule) + self.assertEqual(r.cssText, u'@font-face {\n font-family: x2\n }') + self.assertEqual(s2.cssText, u'font-family: x2') + self.assertEqual(r.style.cssText, u'font-family: x2') + + # set new style object s2 + sn = cssutils.css.CSSStyleDeclaration('font-family: y1') + r.style = sn + self.assertEqual(r.style, sn) + self.assertEqual(r, sn.parentRule) + self.assertEqual(r.cssText, u'@font-face {\n font-family: y1\n }') + self.assertEqual(sn.cssText, u'font-family: y1') + self.assertEqual(r.style.cssText, u'font-family: y1') + self.assertEqual(s2.cssText, u'font-family: x2') # old + + # set s2.cssText + sn.cssText = 'font-family: y2' + self.assertEqual(r.style, sn) + self.assertEqual(r.cssText, u'@font-face {\n font-family: y2\n }') + self.assertEqual(r.style.cssText, u'font-family: y2') + self.assertEqual(s2.cssText, u'font-family: x2') # old + + # set invalid s2.cssText + try: + sn.cssText = '$' + except xml.dom.SyntaxErr, e: + pass + self.assertEqual(r.style, sn) + self.assertEqual(r.style.cssText, u'font-family: y2') + self.assertEqual(r.cssText, u'@font-face {\n font-family: y2\n }') + + # set r.style with text + r.style = 'font-family: z' + self.failIfEqual(r.style, sn) + self.assertEqual(r.cssText, u'@font-face {\n font-family: z\n }') + self.assertEqual(r.style.cssText, u'font-family: z') + self.assertEqual(sn.cssText, u'font-family: y2') + + def test_properties(self): + "CSSFontFaceRule.style properties" + r = cssutils.css.CSSFontFaceRule() + r.style.cssText = ''' + src: url(x) + ''' + exp = u'''@font-face { + src: url(x) + }''' + self.assertEqual(exp, r.cssText) + + tests = { + 'font-family': [#('serif', True), +# ('x', True), +# ('"x"', True), + ('x, y', False), + ('"x", y', False), + ('x, "y"', False), +# ('"x", "y"', False) + ] + } + for n, t in tests.items(): + for (v, valid) in t: + r = cssutils.css.CSSFontFaceRule() + r.style[n] = v + self.assertEqual(r.style.getProperty(n).parent, r.style) + self.assertEqual(r.style.getProperty(n).valid, valid) + + def test_incomplete(self): + "CSSFontFaceRule (incomplete)" + tests = { + u'@font-face{': + u'', # no } and no content + u'@font-face { ': + u'', # no } and no content + u'@font-face { font-family: x': + u'@font-face {\n font-family: x\n }', # no } + } + self.do_equal_p(tests) # parse + + def test_InvalidModificationErr(self): + "CSSFontFaceRule.cssText InvalidModificationErr" + self._test_InvalidModificationErr(u'@font-face') + tests = { + u'@font-fac {}': xml.dom.InvalidModificationErr, + } + self.do_raise_r(tests) + + def test_valid(self): + "CSSFontFaceRule.valid" + r = cssutils.css.CSSFontFaceRule() + self.assertEqual(False, r.valid) + N = 'font-family: x; src: local(x);' + tests = { + True: (N, + N + 'font-style: italic; font-weight: bold', + ), + False: ('', + 'font-family: x, y; src: local(x);', + N + 'font-style: inherit', + N + 'invalid: 1') + } + for valid, testlist in tests.items(): + for test in testlist: + r.style.cssText = test + self.assertEqual(valid, r.valid) + + def test_reprANDstr(self): + "CSSFontFaceRule.__repr__(), .__str__()" + style='src: url(x)' + s = cssutils.css.CSSFontFaceRule(style=style) + + self.assert_(style in str(s)) + + s2 = eval(repr(s)) + self.assert_(isinstance(s2, s.__class__)) + self.assert_(style == s2.style.cssText) + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_cssimportrule.py cssutils-0.9.10/src/cssutils/tests/test_cssimportrule.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_cssimportrule.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_cssimportrule.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,436 @@ +"""Testcases for cssutils.css.CSSImportRule""" + +import xml.dom +import test_cssrule +import cssutils + +import basetest + +class CSSImportRuleTestCase(test_cssrule.CSSRuleTestCase): + + def setUp(self): + super(CSSImportRuleTestCase, self).setUp() + self.r = cssutils.css.CSSImportRule() + self.rRO = cssutils.css.CSSImportRule(readonly=True) + self.r_type = cssutils.css.CSSImportRule.IMPORT_RULE + self.r_typeString = 'IMPORT_RULE' + + def test_init(self): + "CSSImportRule.__init__()" + super(CSSImportRuleTestCase, self).test_init() + + # no init param + self.assertEqual(None, self.r.href) + self.assertEqual(None, self.r.hreftype) + self.assertEqual(False, self.r.hrefFound) + self.assertEqual(u'all', self.r.media.mediaText) + self.assertEqual( + cssutils.stylesheets.MediaList, type(self.r.media)) + self.assertEqual(None, self.r.name) + self.assertEqual(cssutils.css.CSSStyleSheet, type(self.r.styleSheet)) + self.assertEqual(0, self.r.styleSheet.cssRules.length) + self.assertEqual(u'', self.r.cssText) + + # all + r = cssutils.css.CSSImportRule(href='href', mediaText='tv', name='name') + self.assertEqual(u'@import url(href) tv "name";', r.cssText) + self.assertEqual("href", r.href) + self.assertEqual(None, r.hreftype) + self.assertEqual(u'tv', r.media.mediaText) + self.assertEqual( + cssutils.stylesheets.MediaList, type(r.media)) + self.assertEqual('name', r.name) + self.assertEqual(None, r.parentRule) # see CSSRule + self.assertEqual(None, r.parentStyleSheet) # see CSSRule + self.assertEqual(cssutils.css.CSSStyleSheet, type(self.r.styleSheet)) + self.assertEqual(0, self.r.styleSheet.cssRules.length) + + # href + r = cssutils.css.CSSImportRule(u'x') + self.assertEqual(u'@import url(x);', r.cssText) + self.assertEqual('x', r.href) + self.assertEqual(None, r.hreftype) + + # href + mediaText + r = cssutils.css.CSSImportRule(u'x', u'print') + self.assertEqual(u'@import url(x) print;', r.cssText) + self.assertEqual('x', r.href) + self.assertEqual('print', r.media.mediaText) + + # href + name + r = cssutils.css.CSSImportRule(u'x', name=u'n') + self.assertEqual(u'@import url(x) "n";', r.cssText) + self.assertEqual('x', r.href) + self.assertEqual('n', r.name) + + # href + mediaText + name + r = cssutils.css.CSSImportRule(u'x', u'print', 'n') + self.assertEqual(u'@import url(x) print "n";', r.cssText) + self.assertEqual('x', r.href) + self.assertEqual('print', r.media.mediaText) + self.assertEqual('n', r.name) + + # media +name only + self.r = cssutils.css.CSSImportRule(mediaText=u'print', name="n") + self.assertEqual(cssutils.stylesheets.MediaList, + type(self.r.media)) + self.assertEqual(u'', self.r.cssText) + self.assertEqual(u'print', self.r.media.mediaText) + self.assertEqual(u'n', self.r.name) + + # only possible to set @... similar name + self.assertRaises(xml.dom.InvalidModificationErr, self.r._setAtkeyword, 'x') + + def test_cssText(self): + "CSSImportRule.cssText" + tests = { + # href string + u'''@import "str";''': None, + u'''@import"str";''': u'''@import "str";''', + u'''@\\import "str";''': u'''@import "str";''', + u'''@IMPORT "str";''': u'''@import "str";''', + u'''@import 'str';''': u'''@import "str";''', + u'''@import 'str' ;''': u'''@import "str";''', + u'''@import "str";''': None, + u'''@import "str" ;''': u'''@import "str";''', + ur'''@import "\"" ;''': ur'''@import "\"";''', + u'''@import '\\'';''': ur'''@import "'";''', + u'''@import '"';''': ur'''@import "\"";''', + # href url + u'''@import url(x.css);''': None, + # nospace + u'''@import url(")");''': u'''@import url(")");''', + u'''@import url("\\"");''': u'''@import url("\\"");''', + u'''@import url('\\'');''': u'''@import url("'");''', + + # href + media + # all is removed + u'''@import "str" all;''': u'''@import "str";''', + u'''@import "str" tv, print;''': None, + u'''@import"str"tv,print;''': u'''@import "str" tv, print;''', + u'''@import "str" tv, print, all;''': u'''@import "str";''', + u'''@import "str" handheld, all;''': u'''@import "str" all, handheld;''', + u'''@import "str" all, handheld;''': None, + u'''@import "str" not tv;''': None, + u'''@import "str" only tv;''': None, + u'''@import "str" only tv and (color: 2);''': None, + + # href + name + u'''@import "str" "name";''': None, + u'''@import "str" 'name';''': u'''@import "str" "name";''', + u'''@import url(x) "name";''': None, + u'''@import "str" "\\"";''': None, + u'''@import "str" '\\'';''': u'''@import "str" "'";''', + + # href + media + name + u'''@import"str"tv"name";''': u'''@import "str" tv "name";''', + u'''@import\t\r\f\n"str"\t\t\r\f\ntv\t\t\r\f\n"name"\t;''': + u'''@import "str" tv "name";''', + + # comments + u'''@import /*1*/ "str" /*2*/;''': None, + u'@import/*1*//*2*/"str"/*3*//*4*/all/*5*//*6*/"name"/*7*//*8*/ ;': + u'@import /*1*/ /*2*/ "str" /*3*/ /*4*/ all /*5*/ /*6*/ "name" /*7*/ /*8*/;', + u'@import/*1*//*2*/url(u)/*3*//*4*/all/*5*//*6*/"name"/*7*//*8*/ ;': + u'@import /*1*/ /*2*/ url(u) /*3*/ /*4*/ all /*5*/ /*6*/ "name" /*7*/ /*8*/;', + u'@import/*1*//*2*/url("u")/*3*//*4*/all/*5*//*6*/"name"/*7*//*8*/ ;': + u'@import /*1*/ /*2*/ url(u) /*3*/ /*4*/ all /*5*/ /*6*/ "name" /*7*/ /*8*/;', + # WS + u'@import\n\t\f "str"\n\t\f tv\n\t\f "name"\n\t\f ;': + u'@import "str" tv "name";', + u'@import\n\t\f url(\n\t\f u\n\t\f )\n\t\f tv\n\t\f "name"\n\t\f ;': + u'@import url(u) tv "name";', + u'@import\n\t\f url("u")\n\t\f tv\n\t\f "name"\n\t\f ;': + u'@import url(u) tv "name";', + u'@import\n\t\f url(\n\t\f "u"\n\t\f )\n\t\f tv\n\t\f "name"\n\t\f ;': + u'@import url(u) tv "name";', + } + self.do_equal_r(tests) # set cssText + tests.update({ + u'@import "x.css" tv': '@import "x.css" tv;', + u'@import "x.css"': '@import "x.css";', # no ; + u"@import 'x.css'": '@import "x.css";', # no ; + u'@import url(x.css)': '@import url(x.css);', # no ; + u'@import "x;': '@import "x;";', # no "! + }) + self.do_equal_p(tests) # parse + + tests = { + u'''@import;''': xml.dom.SyntaxErr, + u'''@import all;''': xml.dom.SyntaxErr, + u'''@import all"name";''': xml.dom.SyntaxErr, + u'''@import;''': xml.dom.SyntaxErr, + u'''@import x";''': xml.dom.SyntaxErr, + u'''@import "str" ,all;''': xml.dom.SyntaxErr, + u'''@import "str" all,;''': xml.dom.SyntaxErr, + u'''@import "str" all tv;''': xml.dom.SyntaxErr, + u'''@import "str" "name" all;''': xml.dom.SyntaxErr, + } + self.do_raise_p(tests) # parse + tests.update({ + u'@import "x.css"': xml.dom.SyntaxErr, + u"@import 'x.css'": xml.dom.SyntaxErr, + u'@import url(x.css)': xml.dom.SyntaxErr, + u'@import "x.css" tv': xml.dom.SyntaxErr, + u'@import "x;': xml.dom.SyntaxErr, + u'''@import url("x);''': xml.dom.SyntaxErr, + # trailing + u'''@import "x";"a"''': xml.dom.SyntaxErr, + # trailing S or COMMENT + u'''@import "x";/**/''': xml.dom.SyntaxErr, + u'''@import "x"; ''': xml.dom.SyntaxErr, + }) + self.do_raise_r(tests) # set cssText + + def test_href(self): + "CSSImportRule.href" + # set + self.r.href = 'x' + self.assertEqual('x', self.r.href) + self.assertEqual(u'@import url(x);', self.r.cssText) + + # http + self.r.href = 'http://www.example.com/x?css=z&v=1' + self.assertEqual('http://www.example.com/x?css=z&v=1' , self.r.href) + self.assertEqual(u'@import url(http://www.example.com/x?css=z&v=1);', + self.r.cssText) + + # also if hreftype changed + self.r.hreftype='string' + self.assertEqual('http://www.example.com/x?css=z&v=1' , self.r.href) + self.assertEqual(u'@import "http://www.example.com/x?css=z&v=1";', + self.r.cssText) + + # string escaping? + self.r.href = '"' + self.assertEqual(u'@import "\\"";', self.r.cssText) + self.r.hreftype='url' + self.assertEqual(u'@import url("\\"");', self.r.cssText) + + # url escaping? + self.r.href = ')' + self.assertEqual(u'@import url(")");', self.r.cssText) + + self.r.hreftype = 'NOT VALID' # using default + self.assertEqual(u'@import url(")");', self.r.cssText) + + def test_hrefFound(self): + "CSSImportRule.hrefFound" + def fetcher(url): + if url == u'http://example.com/yes': + return None, u'/**/' + else: + return None, None + + parser = cssutils.CSSParser(fetcher=fetcher) + sheet = parser.parseString(u'@import "http://example.com/yes" "name"') + + r = sheet.cssRules[0] + self.assertEqual(u'/**/'.encode(), r.styleSheet.cssText) + self.assertEqual(True, r.hrefFound) + self.assertEqual(u'name', r.name) + + r.cssText = '@import url(http://example.com/none) "name2";' + self.assertEqual(u''.encode(), r.styleSheet.cssText) + self.assertEqual(False, r.hrefFound) + self.assertEqual(u'name2', r.name) + + sheet.cssText = '@import url(http://example.com/none);' + self.assertNotEqual(r, sheet.cssRules[0]) + + def test_hreftype(self): + "CSSImportRule.hreftype" + self.r = cssutils.css.CSSImportRule() + + self.r.cssText = '@import /*1*/url(org) /*2*/;' + self.assertEqual('uri', self.r.hreftype) + self.assertEqual(u'@import /*1*/ url(org) /*2*/;', self.r.cssText) + + self.r.cssText = '@import /*1*/"org" /*2*/;' + self.assertEqual('string', self.r.hreftype) + self.assertEqual(u'@import /*1*/ "org" /*2*/;', self.r.cssText) + + self.r.href = 'new' + self.assertEqual(u'@import /*1*/ "new" /*2*/;', self.r.cssText) + + self.r.hreftype='uri' + self.assertEqual(u'@import /*1*/ url(new) /*2*/;', self.r.cssText) + + def test_media(self): + "CSSImportRule.media" + self.r.href = 'x' # @import url(x) + + # media is readonly + self.assertRaises(AttributeError, self.r.__setattr__, 'media', None) + + # but not static + self.r.media.mediaText = 'print' + self.assertEqual(u'@import url(x) print;', self.r.cssText) + self.r.media.appendMedium('tv') + self.assertEqual(u'@import url(x) print, tv;', self.r.cssText) + + # for generated rule + r = cssutils.css.CSSImportRule(href='x') + self.assertRaisesMsg(xml.dom.InvalidModificationErr, + basetest.msg3x('''MediaList: Ignoring new medium cssutils.stylesheets.MediaQuery(mediaText=u'tv') as already specified "all" (set ``mediaText`` instead).'''), + r.media.appendMedium, 'tv') + self.assertEqual(u'@import url(x);', r.cssText) + self.assertRaisesMsg(xml.dom.InvalidModificationErr, + basetest.msg3x('''MediaList: Ignoring new medium cssutils.stylesheets.MediaQuery(mediaText=u'tv') as already specified "all" (set ``mediaText`` instead).'''), + r.media.appendMedium, 'tv') + self.assertEqual(u'@import url(x);', r.cssText) + r.media.mediaText = 'tv' + self.assertEqual(u'@import url(x) tv;', r.cssText) + r.media.appendMedium('print') # all + tv = all! + self.assertEqual(u'@import url(x) tv, print;', r.cssText) + + # for parsed rule without initial media + s = cssutils.parseString('@import url(x);') + r = s.cssRules[0] + + self.assertRaisesMsg(xml.dom.InvalidModificationErr, + basetest.msg3x('''MediaList: Ignoring new medium cssutils.stylesheets.MediaQuery(mediaText=u'tv') as already specified "all" (set ``mediaText`` instead).'''), + r.media.appendMedium, 'tv') + self.assertEqual(u'@import url(x);', r.cssText) + self.assertRaisesMsg(xml.dom.InvalidModificationErr, + basetest.msg3x('''MediaList: Ignoring new medium cssutils.stylesheets.MediaQuery(mediaText=u'tv') as already specified "all" (set ``mediaText`` instead).'''), + r.media.appendMedium, 'tv') + self.assertEqual(u'@import url(x);', r.cssText) + r.media.mediaText = 'tv' + self.assertEqual(u'@import url(x) tv;', r.cssText) + r.media.appendMedium('print') # all + tv = all! + self.assertEqual(u'@import url(x) tv, print;', r.cssText) + + def test_name(self): + "CSSImportRule.name" + r = cssutils.css.CSSImportRule('x', name='a000000') + self.assertEqual('a000000', r.name) + self.assertEqual(u'@import url(x) "a000000";', r.cssText) + + r.name = "n" + self.assertEqual('n', r.name) + self.assertEqual(u'@import url(x) "n";', r.cssText) + r.name = '"' + self.assertEqual('"', r.name) + self.assertEqual(u'@import url(x) "\\"";', r.cssText) + + r.hreftype = 'string' + self.assertEqual(u'@import "x" "\\"";', r.cssText) + r.name = "123" + self.assertEqual(u'@import "x" "123";', r.cssText) + + r.name = None + self.assertEqual(None, r.name) + self.assertEqual(u'@import "x";', r.cssText) + + r.name = "" + self.assertEqual(None, r.name) + self.assertEqual(u'@import "x";', r.cssText) + + self.assertRaises(xml.dom.SyntaxErr, r._setName, 0) + self.assertRaises(xml.dom.SyntaxErr, r._setName, 123) + + def test_styleSheet(self): + "CSSImportRule.styleSheet" + def fetcher(url): + if url == "/root/level1/anything.css": + return None, '@import "level2/css.css" "title2";' + else: + return None, 'a { color: red }' + + parser = cssutils.CSSParser(fetcher=fetcher) + sheet = parser.parseString('''@charset "ascii"; + @import "level1/anything.css" tv "title";''', + href='/root/') + + self.assertEqual(sheet.href, '/root/') + + ir = sheet.cssRules[1] + self.assertEqual(ir.href, 'level1/anything.css') + self.assertEqual(ir.styleSheet.href, '/root/level1/anything.css') + # inherits ascii as no self charset is set + self.assertEqual(ir.styleSheet.encoding, 'ascii') + self.assertEqual(ir.styleSheet.ownerRule, ir) + self.assertEqual(ir.styleSheet.media.mediaText, 'tv') + self.assertEqual(ir.styleSheet.parentStyleSheet, None) # sheet + self.assertEqual(ir.styleSheet.title, 'title') + self.assertEqual(ir.styleSheet.cssText, + '@charset "ascii";\n@import "level2/css.css" "title2";'.encode()) + + ir2 = ir.styleSheet.cssRules[1] + self.assertEqual(ir2.href, 'level2/css.css') + self.assertEqual(ir2.styleSheet.href, '/root/level1/level2/css.css') + # inherits ascii as no self charset is set + self.assertEqual(ir2.styleSheet.encoding, 'ascii') + self.assertEqual(ir2.styleSheet.ownerRule, ir2) + self.assertEqual(ir2.styleSheet.media.mediaText, 'all') + self.assertEqual(ir2.styleSheet.parentStyleSheet, None) #ir.styleSheet + self.assertEqual(ir2.styleSheet.title, 'title2') + self.assertEqual(ir2.styleSheet.cssText, + '@charset "ascii";\na {\n color: red\n }'.encode()) + + sheet = cssutils.parseString('@import "CANNOT-FIND.css";') + ir = sheet.cssRules[0] + self.assertEqual(ir.href, "CANNOT-FIND.css") + self.assertEqual(type(ir.styleSheet), cssutils.css.CSSStyleSheet) + + def fetcher(url): + if url.endswith('level1.css'): + return None, u'@charset "ascii"; @import "level2.css";'.encode() + else: + return None, u'a { color: red }'.encode() + + parser = cssutils.CSSParser(fetcher=fetcher) + + sheet = parser.parseString('@charset "iso-8859-1";@import "level1.css";') + self.assertEqual(sheet.encoding, 'iso-8859-1') + + sheet = sheet.cssRules[1].styleSheet + self.assertEqual(sheet.encoding, 'ascii') + + sheet = sheet.cssRules[1].styleSheet + self.assertEqual(sheet.encoding, 'ascii') + + def test_incomplete(self): + "CSSImportRule (incomplete)" + tests = { + u'@import "x.css': u'@import "x.css";', + u"@import 'x": u'@import "x";', + # TODO: + u"@import url(x": u'@import url(x);', + u"@import url('x": u'@import url(x);', + u'@import url("x;': u'@import url("x;");', + u'@import url( "x;': u'@import url("x;");', + u'@import url("x ': u'@import url("x ");', + u'@import url(x ': u'@import url(x);', + u'''@import "a + @import "b"; + @import "c";''': u'@import "c";' + } + self.do_equal_p(tests, raising=False) # parse + + def test_InvalidModificationErr(self): + "CSSImportRule.cssText InvalidModificationErr" + self._test_InvalidModificationErr(u'@import') + + def test_reprANDstr(self): + "CSSImportRule.__repr__(), .__str__()" + href = 'x.css' + mediaText = 'tv, print' + name = 'name' + s = cssutils.css.CSSImportRule(href=href, mediaText=mediaText, name=name) + + # str(): mediaText nor name are present here + self.assert_(href in str(s)) + + # repr() + s2 = eval(repr(s)) + self.assert_(isinstance(s2, s.__class__)) + self.assert_(href == s2.href) + self.assert_(mediaText == s2.media.mediaText) + self.assert_(name == s2.name) + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_cssmediarule.py cssutils-0.9.10/src/cssutils/tests/test_cssmediarule.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_cssmediarule.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_cssmediarule.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,370 @@ +"""Testcases for cssutils.css.CSSMediaRule""" + +import xml.dom +import test_cssrule +import cssutils + +class CSSMediaRuleTestCase(test_cssrule.CSSRuleTestCase): + + def setUp(self): + super(CSSMediaRuleTestCase, self).setUp() + self.r = cssutils.css.CSSMediaRule() + self.rRO = cssutils.css.CSSMediaRule(readonly=True) + self.r_type = cssutils.css.CSSMediaRule.MEDIA_RULE + self.r_typeString = 'MEDIA_RULE' + # for tests + self.stylerule = cssutils.css.CSSStyleRule() + self.stylerule.cssText = u'a {}' + + def test_init(self): + "CSSMediaRule.__init__()" + super(CSSMediaRuleTestCase, self).test_init() + + r = cssutils.css.CSSMediaRule() + self.assertEqual(cssutils.css.CSSRuleList, type(r.cssRules)) + self.assertEqual([], r.cssRules) + self.assertEqual(u'', r.cssText) + self.assertEqual(cssutils.stylesheets.MediaList, type(r.media)) + self.assertEqual('all', r.media.mediaText) + self.assertEqual(None, r.name) + + r = cssutils.css.CSSMediaRule(mediaText='print', name='name') + self.assertEqual(cssutils.css.CSSRuleList, type(r.cssRules)) + self.assertEqual([], r.cssRules) + self.assertEqual(u'', r.cssText) + self.assertEqual(cssutils.stylesheets.MediaList, type(r.media)) + self.assertEqual('print', r.media.mediaText) + self.assertEqual('name', r.name) + + # only possible to set @... similar name + self.assertRaises(xml.dom.InvalidModificationErr, self.r._setAtkeyword, 'x') + + def test_iter(self): + "CSSMediaRule.__iter__()" + m = cssutils.css.CSSMediaRule() + m.cssText = '''@media all { /*1*/a { left: 0} b{ top:0} }''' + types = [cssutils.css.CSSRule.COMMENT, + cssutils.css.CSSRule.STYLE_RULE, + cssutils.css.CSSRule.STYLE_RULE] + for i, rule in enumerate(m): + self.assertEqual(rule, m.cssRules[i]) + self.assertEqual(rule.type, types[i]) + self.assertEqual(rule.parentRule, m) + + def test_refs(self): + """CSSStylesheet references""" + s = cssutils.parseString('@media all {a {color: red}}') + r = s.cssRules[0] + rules = r.cssRules + self.assertEqual(r.cssRules[0].parentStyleSheet, s) + self.assertEqual(rules[0].parentStyleSheet, s) + + # set cssText + r.cssText = '@media all {a {color: blue}}' + # not anymore: self.assertEqual(rules, r.cssRules) + + # set cssRules + r.cssRules = cssutils.parseString(''' + /**/ + @x; + b {}').cssRules''').cssRules + # new object + self.assertNotEqual(rules, r.cssRules) + for i, sr in enumerate(r.cssRules): + self.assertEqual(sr.parentStyleSheet, s) + self.assertEqual(sr.parentRule, r) + + def test_cssRules(self): + "CSSMediaRule.cssRules" + r = cssutils.css.CSSMediaRule() + self.assertEqual([], r.cssRules) + sr = cssutils.css.CSSStyleRule() + r.cssRules.append(sr) + self.assertEqual([sr], r.cssRules) + ir = cssutils.css.CSSImportRule() + self.assertRaises(xml.dom.HierarchyRequestErr, r.cssRules.append, ir) + + s = cssutils.parseString('@media all { /*1*/a {x:1} }') + m = s.cssRules[0] + self.assertEqual(2, m.cssRules.length) + del m.cssRules[0] + self.assertEqual(1, m.cssRules.length) + m.cssRules.append('/*2*/') + self.assertEqual(2, m.cssRules.length) + m.cssRules.extend(cssutils.parseString('/*3*/x {y:2}').cssRules) + self.assertEqual(4, m.cssRules.length) + self.assertEqual(u'@media all {\n a {\n x: 1\n }\n /*2*/\n /*3*/\n x {\n y: 2\n }\n }', + m.cssText) + + for rule in m.cssRules: + self.assertEqual(rule.parentStyleSheet, s) + self.assertEqual(rule.parentRule, m) + + def test_cssText(self): + "CSSMediaRule.cssText" + tests = { + u'''@media all "name"{}''': u'', + u'''@media all {}''': u'', + u'''@media/*x*/all{}''': u'', + u'''@media all { a{ x: 1} }''': u'''@media all {\n a {\n x: 1\n }\n }''', + u'''@media all "name" { a{ x: 1} }''': u'''@media all "name" {\n a {\n x: 1\n }\n }''', + u'''@MEDIA all { a{x:1} }''': u'''@media all {\n a {\n x: 1\n }\n }''', + u'''@\\media all { a{x:1} }''': u'''@media all {\n a {\n x: 1\n }\n }''', + u'''@media all {@x some;a{color: red;}b{color: green;}}''': + u'''@media all { + @x some; + a { + color: red + } + b { + color: green + } + }''', + u'@media all { @x{}}': u'@media all {\n @x {\n }\n }', + u'@media all "n" /**/ { @x{}}': + u'@media all "n" /**/ {\n @x {\n }\n }', + # comments + u'@media/*1*//*2*/all/*3*//*4*/{/*5*/a{x:1}}': + u'@media /*1*/ /*2*/ all /*3*/ /*4*/ {\n /*5*/\n a {\n x: 1\n }\n }', + u'@media /*1*/ /*2*/ all /*3*/ /*4*/ { /*5*/ a{ x: 1} }': + u'@media /*1*/ /*2*/ all /*3*/ /*4*/ {\n /*5*/\n a {\n x: 1\n }\n }', + # WS + u'@media\n\t\f all\n\t\f {\n\t\f a{ x: 1}\n\t\f }': + u'@media all {\n a {\n x: 1\n }\n }', + } + self.do_equal_p(tests) + self.do_equal_r(tests) + + tests = { + u'@media {}': xml.dom.SyntaxErr, + u'@media;': xml.dom.SyntaxErr, + u'@media/*only comment*/{}': xml.dom.SyntaxErr, + u'@media all;': xml.dom.SyntaxErr, + u'@media all "n";': xml.dom.SyntaxErr, + u'@media all; @x{}': xml.dom.SyntaxErr, + u'@media { a{ x: 1} }': xml.dom.SyntaxErr, + u'@media "name" { a{ x: 1} }': xml.dom.SyntaxErr, + u'@media "name" all { a{ x: 1} }': xml.dom.SyntaxErr, + u'@media all { @charset "x"; a{}}': xml.dom.HierarchyRequestErr, + u'@media all { @import "x"; a{}}': xml.dom.HierarchyRequestErr, + u'@media all { @media all {} }': xml.dom.HierarchyRequestErr, + u'@media all { , }': xml.dom.SyntaxErr, + u'@media all {}EXTRA': xml.dom.SyntaxErr, + } + self.do_raise_p(tests) + self.do_raise_r(tests) + + tests = { + # extra stuff + '@media all { x{} } a{}': xml.dom.SyntaxErr, + } + self.do_raise_r(tests) + + m = cssutils.css.CSSMediaRule() + m.cssText = u'''@media all {@x; /*1*/a{color: red;}}''' + for r in m.cssRules: + self.assertEqual(m, r.parentRule) + self.assertEqual(m.parentStyleSheet, r.parentStyleSheet) + + cssutils.ser.prefs.useDefaults() + + def test_media(self): + "CSSMediaRule.media" + # see CSSImportRule.media + + # setting not allowed + self.assertRaises(AttributeError, + self.r.__setattr__, 'media', None) + self.assertRaises(AttributeError, + self.r.__setattr__, 'media', 0) + + # set mediaText instead + self.r.media.mediaText = 'print' + self.r.insertRule(self.stylerule) + self.assertEqual(u'', self.r.cssText) + cssutils.ser.prefs.keepEmptyRules = True + self.assertEqual(u'@media print {\n a {}\n }', self.r.cssText) + cssutils.ser.prefs.useDefaults() + + def test_name(self): + "CSSMediaRule.name" + r = cssutils.css.CSSMediaRule() + r.cssText = '@media all "\\n\\"ame" {a{left: 0}}' + + self.assertEqual('\\n"ame', r.name) + r.name = "n" + self.assertEqual('n', r.name) + self.assertEqual(u'@media all "n" {\n a {\n left: 0\n }\n }', + r.cssText) + r.name = '"' + self.assertEqual('"', r.name) + self.assertEqual(u'@media all "\\"" {\n a {\n left: 0\n }\n }', + r.cssText) + + r.name = '' + self.assertEqual(None, r.name) + self.assertEqual(u'@media all {\n a {\n left: 0\n }\n }', + r.cssText) + + r.name = None + self.assertEqual(None, r.name) + self.assertEqual(u'@media all {\n a {\n left: 0\n }\n }', + r.cssText) + + self.assertRaises(xml.dom.SyntaxErr, r._setName, 0) + self.assertRaises(xml.dom.SyntaxErr, r._setName, 123) + + def test_deleteRuleIndex(self): + "CSSMediaRule.deleteRule(index)" + # see CSSStyleSheet.deleteRule + m = cssutils.css.CSSMediaRule() + m.cssText = u'''@media all { + @a; + /* x */ + @b; + @c; + @d; + }''' + self.assertEqual(5, m.cssRules.length) + self.assertRaises(xml.dom.IndexSizeErr, m.deleteRule, 5) + + # end -1 + # check parentRule + r = m.cssRules[-1] + self.assertEqual(m, r.parentRule) + m.deleteRule(-1) + self.assertEqual(None, r.parentRule) + + self.assertEqual(4, m.cssRules.length) + self.assertEqual( + u'@media all {\n @a;\n /* x */\n @b;\n @c;\n }', m.cssText) + # beginning + m.deleteRule(0) + self.assertEqual(3, m.cssRules.length) + self.assertEqual(u'@media all {\n /* x */\n @b;\n @c;\n }', m.cssText) + # middle + m.deleteRule(1) + self.assertEqual(2, m.cssRules.length) + self.assertEqual(u'@media all {\n /* x */\n @c;\n }', m.cssText) + # end + m.deleteRule(1) + self.assertEqual(1, m.cssRules.length) + self.assertEqual(u'@media all {\n /* x */\n }', m.cssText) + + def test_deleteRule(self): + "CSSMediaRule.deleteRule(rule)" + m = cssutils.css.CSSMediaRule() + m.cssText='''@media all { + a { color: red; } + b { color: blue; } + c { color: green; } + }''' + s1, s2, s3 = m.cssRules + + r = cssutils.css.CSSStyleRule() + self.assertRaises(xml.dom.IndexSizeErr, m.deleteRule, r) + + self.assertEqual(3, m.cssRules.length) + m.deleteRule(s2) + self.assertEqual(2, m.cssRules.length) + self.assertEqual(m.cssText, '@media all {\n a {\n color: red\n }\n c {\n color: green\n }\n }') + self.assertRaises(xml.dom.IndexSizeErr, m.deleteRule, s2) + + def test_add(self): + "CSSMediaRule.add()" + # see CSSStyleSheet.add + r = cssutils.css.CSSMediaRule() + stylerule1 = cssutils.css.CSSStyleRule() + stylerule2 = cssutils.css.CSSStyleRule() + r.add(stylerule1) + r.add(stylerule2) + self.assertEqual(r.cssRules[0], stylerule1) + self.assertEqual(r.cssRules[1], stylerule2) + + def test_insertRule(self): + "CSSMediaRule.insertRule" + # see CSSStyleSheet.insertRule + r = cssutils.css.CSSMediaRule() + charsetrule = cssutils.css.CSSCharsetRule('ascii') + importrule = cssutils.css.CSSImportRule('x') + namespacerule = cssutils.css.CSSNamespaceRule() + pagerule = cssutils.css.CSSPageRule() + mediarule = cssutils.css.CSSMediaRule() + unknownrule = cssutils.css.CSSUnknownRule('@x;') + stylerule = cssutils.css.CSSStyleRule('a') + stylerule.cssText = u'a { x: 1}' + comment1 = cssutils.css.CSSComment(u'/*1*/') + comment2 = cssutils.css.CSSComment(u'/*2*/') + + # hierarchy + self.assertRaises(xml.dom.HierarchyRequestErr, + r.insertRule, charsetrule, 0) + self.assertRaises(xml.dom.HierarchyRequestErr, + r.insertRule, importrule, 0) + self.assertRaises(xml.dom.HierarchyRequestErr, + r.insertRule, namespacerule, 0) + self.assertRaises(xml.dom.HierarchyRequestErr, + r.insertRule, pagerule, 0) + self.assertRaises(xml.dom.HierarchyRequestErr, + r.insertRule, mediarule, 0) + + # start insert + r.insertRule(stylerule, 0) + self.assertEqual(r, stylerule.parentRule) + self.assertEqual(r.parentStyleSheet, stylerule.parentStyleSheet) + # before + r.insertRule(comment1, 0) + self.assertEqual(r, comment1.parentRule) + self.assertEqual(r.parentStyleSheet, stylerule.parentStyleSheet) + # end explicit + r.insertRule(unknownrule, 2) + self.assertEqual(r, unknownrule.parentRule) + self.assertEqual(r.parentStyleSheet, stylerule.parentStyleSheet) + # end implicit + r.insertRule(comment2) + self.assertEqual(r, comment2.parentRule) + self.assertEqual(r.parentStyleSheet, stylerule.parentStyleSheet) + self.assertEqual( + '@media all {\n /*1*/\n a {\n x: 1\n }\n @x;\n /*2*/\n }', + r.cssText) + + # index + self.assertRaises(xml.dom.IndexSizeErr, + r.insertRule, stylerule, -1) + self.assertRaises(xml.dom.IndexSizeErr, + r.insertRule, stylerule, r.cssRules.length + 1) + + def test_InvalidModificationErr(self): + "CSSMediaRule.cssText InvalidModificationErr" + self._test_InvalidModificationErr(u'@media') + + def test_incomplete(self): + "CSSMediaRule (incomplete)" + tests = { + u'@media all { @unknown;': # no } + u'@media all {\n @unknown;\n }', + u'@media all { a {x:"1"}': # no } + u'@media all {\n a {\n x: "1"\n }\n }', + u'@media all { a {x:"1"': # no }} + u'@media all {\n a {\n x: "1"\n }\n }', + u'@media all { a {x:"1': # no "}} + u'@media all {\n a {\n x: "1"\n }\n }', + } + self.do_equal_p(tests) # parse + + def test_reprANDstr(self): + "CSSMediaRule.__repr__(), .__str__()" + mediaText='tv, print' + + s = cssutils.css.CSSMediaRule(mediaText=mediaText) + + self.assert_(mediaText in str(s)) + + s2 = eval(repr(s)) + self.assert_(isinstance(s2, s.__class__)) + self.assert_(mediaText == s2.media.mediaText) + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_cssnamespacerule.py cssutils-0.9.10/src/cssutils/tests/test_cssnamespacerule.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_cssnamespacerule.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_cssnamespacerule.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,232 @@ +"""Testcases for cssutils.css.CSSImportRule""" + +import xml.dom +import test_cssrule +import cssutils + +class CSSNamespaceRuleTestCase(test_cssrule.CSSRuleTestCase): + + def setUp(self): + super(CSSNamespaceRuleTestCase, self).setUp() + self.r = cssutils.css.CSSNamespaceRule(namespaceURI='x') + #self.rRO = cssutils.css.CSSNamespaceRule(namespaceURI='x', + # readonly=True) + self.r_type = cssutils.css.CSSRule.NAMESPACE_RULE + self.r_typeString = 'NAMESPACE_RULE' + + def test_init(self): + "CSSNamespaceRule.__init__()" + # cannot use here as self.r and self rRO and not useful + #super(CSSNamespaceRuleTestCase, self).test_init() + tests = [ + (None, None), + ('', ''), + (None, u''), + (u'', None), + (u'', u'no-uri'), + ] + for uri, p in tests: + r = cssutils.css.CSSNamespaceRule(namespaceURI=uri, prefix=p) + self.assertEqual(None, r.namespaceURI) + self.assertEqual(u'', r.prefix) + self.assertEqual(u'', r.cssText) + self.assertEqual(None, r.parentStyleSheet) + self.assertEqual(None, r.parentRule) + + r = cssutils.css.CSSNamespaceRule(namespaceURI='example') + self.assertEqual('example', r.namespaceURI) + self.assertEqual(u'', r.prefix) + self.assertEqual(u'@namespace "example";', r.cssText) + self.sheet.add(r) + self.assertEqual(self.sheet, r.parentStyleSheet) + + r = cssutils.css.CSSNamespaceRule(namespaceURI='example', prefix='p') + self.assertEqual('example', r.namespaceURI) + self.assertEqual(u'p', r.prefix) + self.assertEqual(u'@namespace p "example";', r.cssText) + + css = u'@namespace p "u";' + r = cssutils.css.CSSNamespaceRule(cssText=css) + self.assertEqual(r.cssText, css) + + # only possible to set @... similar name + self.assertRaises(xml.dom.InvalidModificationErr, self.r._setAtkeyword, 'x') + + def test_cssText(self): + "CSSNamespaceRule.cssText" + # cssText may only be set initalially + r = cssutils.css.CSSNamespaceRule() + css = u'@namespace p "u";' + r.cssText = css + self.assertEqual(r.cssText, css) + self.assertRaises(xml.dom.NoModificationAllowedErr, r._setCssText, + u'@namespace p "OTHER";') + + tests = { + u'@namespace "";': None, + u'@namespace "u";': None, + u'@namespace p "u";': None, + u'@namespace empty "";': None, + + u'@namespace p "p";': None, + u"@namespace p 'u';": u'@namespace p "u";', + + u'@\\namespace p "u";': u'@namespace p "u";', + u'@NAMESPACE p "u";': u'@namespace p "u";', + + u'@namespace p "u" ;': u'@namespace p "u";', + u'@namespace p"u";': u'@namespace p "u";', + u'@namespace p "u";': u'@namespace p "u";', + + u'@namespace/*1*/"u"/*2*/;': u'@namespace /*1*/ "u" /*2*/;', + u'@namespace/*1*/p/*2*/"u"/*3*/;': u'@namespace /*1*/ p /*2*/ "u" /*3*/;', + + u'@namespace p url(u);': u'@namespace p "u";', + u'@namespace p url(\'u\');': u'@namespace p "u";', + u'@namespace p url(\"u\");': u'@namespace p "u";', + u'@namespace p url( \"u\" );': u'@namespace p "u";', + + # comments + u'@namespace/*1*//*2*/p/*3*//*4*/url(u)/*5*//*6*/;': + u'@namespace /*1*/ /*2*/ p /*3*/ /*4*/ "u" /*5*/ /*6*/;', + u'@namespace/*1*//*2*/p/*3*//*4*/"u"/*5*//*6*/;': + u'@namespace /*1*/ /*2*/ p /*3*/ /*4*/ "u" /*5*/ /*6*/;', + u'@namespace/*1*//*2*/p/*3*//*4*/url("u")/*5*//*6*/;': + u'@namespace /*1*/ /*2*/ p /*3*/ /*4*/ "u" /*5*/ /*6*/;', + + u'@namespace/*1*//*2*/url(u)/*5*//*6*/;': + u'@namespace /*1*/ /*2*/ "u" /*5*/ /*6*/;', + + # WS + u'@namespace\n\r\t\f p\n\r\t\f url(\n\r\t\f u\n\r\t\f )\n\r\t\f ;': + u'@namespace p "u";', + u'@namespace\n\r\t\f p\n\r\t\f url(\n\r\t\f "u"\n\r\t\f )\n\r\t\f ;': + u'@namespace p "u";', + u'@namespace\n\r\t\f p\n\r\t\f "str"\n\r\t\f ;': + u'@namespace p "str";', + u'@namespace\n\r\t\f "str"\n\r\t\f ;': + u'@namespace "str";' + } + self.do_equal_p(tests) + #self.do_equal_r(tests) # cannot use here as always new r is needed + for test, expected in tests.items(): + r = cssutils.css.CSSNamespaceRule(cssText=test) + if expected is None: + expected = test + self.assertEqual(expected, r.cssText) + + tests = { + u'@namespace;': xml.dom.SyntaxErr, # nothing + u'@namespace p;': xml.dom.SyntaxErr, # no namespaceURI + u'@namespace "u" p;': xml.dom.SyntaxErr, # order + u'@namespace "u";EXTRA': xml.dom.SyntaxErr, + u'@namespace p "u";EXTRA': xml.dom.SyntaxErr, + } + self.do_raise_p(tests) # parse + tests.update({ + u'@namespace p url(x)': xml.dom.SyntaxErr, # missing ; + u'@namespace p "u"': xml.dom.SyntaxErr, # missing ; + # trailing + u'@namespace "u"; ': xml.dom.SyntaxErr, + u'@namespace "u";/**/': xml.dom.SyntaxErr, + u'@namespace p "u"; ': xml.dom.SyntaxErr, + u'@namespace p "u";/**/': xml.dom.SyntaxErr, + }) + def _do(test): + r = cssutils.css.CSSNamespaceRule(cssText=test) + for test, expected in tests.items(): + self.assertRaises(expected, _do, test) + + def test_namespaceURI(self): + "CSSNamespaceRule.namespaceURI" + # set only initially + r = cssutils.css.CSSNamespaceRule(namespaceURI='x') + self.assertEqual(u'x' , r.namespaceURI) + self.assertEqual(u'@namespace "x";', r.cssText) + + r = cssutils.css.CSSNamespaceRule(namespaceURI='"') + self.assertEqual(u'@namespace "\\"";', r.cssText) + + self.assertRaises(xml.dom.NoModificationAllowedErr, + r._setNamespaceURI, u'x') + + self.assertRaises(xml.dom.NoModificationAllowedErr, + r._setCssText, u'@namespace "u";') + + r._replaceNamespaceURI(u'http://example.com/new') + self.assertEqual(u'http://example.com/new' , r.namespaceURI) + + def test_prefix(self): + "CSSNamespaceRule.prefix" + r = cssutils.css.CSSNamespaceRule(namespaceURI='u') + r.prefix = 'p' + self.assertEqual('p' , r.prefix) + self.assertEqual(u'@namespace p "u";', r.cssText) + + r = cssutils.css.CSSNamespaceRule(cssText='@namespace x "u";') + r.prefix = 'p' + self.assertEqual('p' , r.prefix) + self.assertEqual(u'@namespace p "u";', r.cssText) + + valid = (None, u'') + for prefix in valid: + r.prefix = prefix + self.assertEqual(r.prefix, u'') + self.assertEqual(u'@namespace "u";', r.cssText) + + valid = ('a', '_x', 'a1', 'a-1') + for prefix in valid: + r.prefix = prefix + self.assertEqual(r.prefix, prefix) + self.assertEqual(u'@namespace %s "u";' % prefix, r.cssText) + + invalid = ('1', ' x', ' ', ',') + for prefix in invalid: + self.assertRaises(xml.dom.SyntaxErr, r._setPrefix, prefix) + + def test_InvalidModificationErr(self): + "CSSNamespaceRule.cssText InvalidModificationErr" + self._test_InvalidModificationErr(u'@namespace') + + def test_incomplete(self): + "CSSNamespaceRule (incomplete)" + tests = { + u'@namespace "uri': u'@namespace "uri";', + u"@namespace url(x": u'@namespace "x";', + u"@namespace url('x": u'@namespace "x";', + u'@namespace url("x;': u'@namespace "x;";', + u'@namespace url( "x;': u'@namespace "x;";', + u'@namespace url("x ': u'@namespace "x ";', + u'@namespace url(x ': u'@namespace "x";', + } + self.do_equal_p(tests) # parse + tests = { + u'@namespace "uri': xml.dom.SyntaxErr, + u"@namespace url(x": xml.dom.SyntaxErr, + u"@namespace url('x": xml.dom.SyntaxErr, + u'@namespace url("x;': xml.dom.SyntaxErr, + u'@namespace url( "x;': xml.dom.SyntaxErr, + u'@namespace url("x ': xml.dom.SyntaxErr, + u'@namespace url(x ': xml.dom.SyntaxErr + } + self.do_raise_r(tests) # set cssText + + def test_reprANDstr(self): + "CSSNamespaceRule.__repr__(), .__str__()" + namespaceURI=u'http://example.com' + prefix=u'prefix' + + s = cssutils.css.CSSNamespaceRule(namespaceURI=namespaceURI, prefix=prefix) + + self.assert_(namespaceURI in str(s)) + self.assert_(prefix in str(s)) + + s2 = eval(repr(s)) + self.assert_(isinstance(s2, s.__class__)) + self.assert_(namespaceURI == s2.namespaceURI) + self.assert_(prefix == s2.prefix) + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_csspagerule.py cssutils-0.9.10/src/cssutils/tests/test_csspagerule.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_csspagerule.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_csspagerule.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,433 @@ +"""Testcases for cssutils.css.CSSPageRule""" + +import xml.dom +import test_cssrule +import cssutils + +class CSSPageRuleTestCase(test_cssrule.CSSRuleTestCase): + + def setUp(self): + super(CSSPageRuleTestCase, self).setUp() + + cssutils.ser.prefs.useDefaults() + self.r = cssutils.css.CSSPageRule() + self.rRO = cssutils.css.CSSPageRule(readonly=True) + self.r_type = cssutils.css.CSSPageRule.PAGE_RULE# + self.r_typeString = 'PAGE_RULE' + + def tearDown(self): + cssutils.ser.prefs.useDefaults() + + def test_init(self): + "CSSPageRule.__init__()" + super(CSSPageRuleTestCase, self).test_init() + + r = cssutils.css.CSSPageRule() + self.assertEqual(u'', r.selectorText) + self.assertEqual(cssutils.css.CSSStyleDeclaration, type(r.style)) + self.assertEqual(r, r.style.parentRule) + + # until any properties + self.assertEqual(u'', r.cssText) + + # only possible to set @... similar name + self.assertRaises(xml.dom.InvalidModificationErr, self.r._setAtkeyword, 'x') + + def checkrefs(ff): + self.assertEqual(ff, ff.style.parentRule) + for p in ff.style: + self.assertEqual(ff.style, p.parent) + + checkrefs(cssutils.css.CSSPageRule( + style=cssutils.css.CSSStyleDeclaration('font-family: x'))) + + r = cssutils.css.CSSPageRule() + r.cssText = '@page { font-family: x }' + checkrefs(r) + + r = cssutils.css.CSSPageRule() + r.style.setProperty('font-family', 'y') + checkrefs(r) + + r = cssutils.css.CSSPageRule() + r.style['font-family'] = 'z' + checkrefs(r) + + r = cssutils.css.CSSPageRule() + r.style.fontFamily = 'a' + checkrefs(r) + + def test_InvalidModificationErr(self): + "CSSPageRule.cssText InvalidModificationErr" + self._test_InvalidModificationErr(u'@page') + tests = { + u'@pag {}': xml.dom.InvalidModificationErr, + } + self.do_raise_r(tests) + + def test_incomplete(self): + "CSSPageRule (incomplete)" + tests = { + u'@page :left { ': + u'', # no } and no content + u'@page :left { color: red': + u'@page :left {\n color: red\n }', # no } + } + self.do_equal_p(tests) # parse + + def test_cssText(self): + "CSSPageRule.cssText" + EXP = u'@page %s {\n margin: 0\n }' + tests = { + u'@page {}': u'', + u'@page:left{}': u'', + u'@page :right {}': u'', + u'@page {margin:0;}': u'@page {\n margin: 0\n }', + + u'@page name { margin: 0 }': EXP % u'name', + u'@page name:left { margin: 0 }': EXP % u'name:left', + u'@page name:right { margin: 0 }': EXP % u'name:right', + u'@page name:first { margin: 0 }': EXP % u'name:first', + u'@page :left { margin: 0 }': EXP % u':left', + u'@page:left { margin: 0 }': EXP % u':left', + u'@page :right { margin: 0 }': EXP % u':right', + u'@page :first { margin: 0 }': EXP % u':first', + u'@page :UNKNOWNIDENT { margin: 0 }': EXP % u':UNKNOWNIDENT', + + u'@PAGE:left{margin:0;}': u'@page :left {\n margin: 0\n }', + u'@\\page:left{margin:0;}': u'@page :left {\n margin: 0\n }', + + # comments + u'@page/*1*//*2*/:left/*3*//*4*/{margin:0;}': + u'@page /*1*/ /*2*/ :left /*3*/ /*4*/ {\n margin: 0\n }', + # WS + u'@page:left{margin:0;}': + u'@page :left {\n margin: 0\n }', + u'@page\n\r\f\t :left\n\r\f\t {margin:0;}': + u'@page :left {\n margin: 0\n }', + + # MarginRule + u'@page { @top-right { content: "2" } }': + u'@page {\n @top-right {\n content: "2"\n }\n }', + u'@page {padding: 1cm; margin: 1cm; @top-left {content: "1"}@top-right {content: "2";left: 1}}': + u'@page {\n padding: 1cm;\n margin: 1cm;\n @top-left {\n content: "1"\n }\n @top-right {\n content: "2";\n left: 1\n }\n }', + u'@page {@top-right { content: "1a"; content: "1b"; x: 1 }@top-right { content: "2"; y: 2 }}': + u'''@page {\n @top-right { + content: "1a"; + content: "1b"; + x: 1; + content: "2"; + y: 2 + }\n }''', + + } + self.do_equal_r(tests) + self.do_equal_p(tests) + + tests = { + # auto is not allowed + u'@page AUto {}': xml.dom.SyntaxErr, + u'@page AUto:left {}': xml.dom.SyntaxErr, + + u'@page : {}': xml.dom.SyntaxErr, + u'@page :/*1*/left {}': xml.dom.SyntaxErr, + u'@page : left {}': xml.dom.SyntaxErr, + u'@page :left :right {}': xml.dom.SyntaxErr, + u'@page :left a {}': xml.dom.SyntaxErr, + # no S between IDENT and PSEUDO + u'@page a :left {}': xml.dom.SyntaxErr, + + u'@page :left;': xml.dom.SyntaxErr, + u'@page :left }': xml.dom.SyntaxErr, + } + self.do_raise_p(tests) # parse + tests.update({ + # false selector + u'@page :right :left {}': xml.dom.SyntaxErr, # no } + u'@page :right X {}': xml.dom.SyntaxErr, # no } + u'@page X Y {}': xml.dom.SyntaxErr, # no } + + u'@page :left {': xml.dom.SyntaxErr, # no } + # trailing + u'@page :left {}1': xml.dom.SyntaxErr, # no } + u'@page :left {}/**/': xml.dom.SyntaxErr, # no } + u'@page :left {} ': xml.dom.SyntaxErr, # no } + }) + self.do_raise_r(tests) # set cssText + + def test_cssText2(self): + "CSSPageRule.cssText 2" + r = cssutils.css.CSSPageRule() + s = u'a:left' + r.selectorText = s + self.assertEqual(r.selectorText, s) + + st = 'size: a4' + r.style = st + self.assertEqual(r.style.cssText, st) + + # invalid selector + self.assertRaises(xml.dom.SyntaxErr, r._setStyle, '$') + self.assertEqual(r.selectorText, s) + self.assertEqual(r.style.cssText, st) + + self.assertRaises(xml.dom.SyntaxErr, r._setCssText, '@page $ { color: red }') + self.assertEqual(r.selectorText, s) + self.assertEqual(r.style.cssText, st) + + + # invalid style + self.assertRaises(xml.dom.SyntaxErr, r._setSelectorText, '$') + self.assertEqual(r.selectorText, s) + self.assertEqual(r.style.cssText, st) + + self.assertRaises(xml.dom.SyntaxErr, r._setCssText, '@page b:right { x }') + self.assertEqual(r.selectorText, s) + self.assertEqual(r.style.cssText, st) + + def test_selectorText(self): + "CSSPageRule.selectorText" + r = cssutils.css.CSSPageRule() + r.selectorText = u'a:left' + self.assertEqual(r.selectorText, u'a:left') + + tests = { + u'': u'', + u'name': None, + u':left': None, + u':right': None, + u':first': None, + u':UNKNOWNIDENT': None, + u'name:left': None, + u' :left': u':left', + u':left': u':left', + u'/*1*/:left/*a*/': u'/*1*/ :left /*a*/', + u'/*1*/ :left /*a*/ /*b*/': None, + u':left/*a*/': u':left /*a*/', + u'/*1*/:left': u'/*1*/ :left', + } + self.do_equal_r(tests, att='selectorText') + + tests = { + u':': xml.dom.SyntaxErr, + u':/*1*/left': xml.dom.SyntaxErr, + u': left': xml.dom.SyntaxErr, + u':left :right': xml.dom.SyntaxErr, + u':left a': xml.dom.SyntaxErr, + u'name :left': xml.dom.SyntaxErr, + } + self.do_raise_r(tests, att='_setSelectorText') + + def test_specificity(self): + "CSSPageRule.specificity" + r = cssutils.css.CSSPageRule() + tests = { + u'': (0, 0, 0), + u'name': (1, 0, 0), + u':first': (0, 1, 0), + u':left': (0, 0, 1), + u':right': (0, 0, 1), + u':UNKNOWNIDENT': (0, 0, 1), + u'name:first': (1, 1, 0), + u'name:left': (1, 0, 1), + u'name:right': (1, 0, 1), + u'name:X': (1, 0, 1) + } + for sel, exp in tests.items(): + r.selectorText = sel + self.assertEqual(r.specificity, exp) + + r = cssutils.css.CSSPageRule() + r.cssText = u'@page %s {}' % sel + self.assertEqual(r.specificity, exp) + + def test_cssRules(self): + "CSSPageRule.cssRules" + s = cssutils.parseString(u'@page {}') + p = s.cssRules[0] + + self.assertEqual(len(p.cssRules), 0) + + # add and insert + m1 = cssutils.css.MarginRule(u'@top-left', u'color: red') + i = p.add(m1) + self.assertEqual(i, 0) + self.assertEqual(len(p.cssRules), 1) + + m3 = cssutils.css.MarginRule() + m3.cssText = u'@top-right { color: blue }' + i = p.insertRule(m3) + self.assertEqual(i, 1) + self.assertEqual(len(p.cssRules), 2) + + m2 = cssutils.css.MarginRule() + m2.margin = u'@top-center' + m2.style = u'color: green' + i = p.insertRule(m2, 1) + self.assertEqual(i, 1) + self.assertEqual(len(p.cssRules), 3) + + self.assertEqual(p.cssText, u'''@page { + @top-left { + color: red + } + @top-center { + color: green + } + @top-right { + color: blue + } + }''') + + # keys and dict index + self.assertEqual(u'@top-left' in p, True) + self.assertEqual(u'@bottom-left' in p, False) + + self.assertEqual(p.keys(), [u'@top-left', + u'@top-center', + u'@top-right']) + + self.assertEqual(p[u'@bottom-left'], None) + self.assertEqual(p[u'@top-left'].cssText, u'color: red') + p[u'@top-left'] = u'color: #f00' + self.assertEqual(p[u'@top-left'].cssText, u'color: #f00') + + # delete + p.deleteRule(m2) + self.assertEqual(len(p.cssRules), 2) + self.assertEqual(p.cssText, u'''@page { + @top-left { + color: #f00 + } + @top-right { + color: blue + } + }''') + + p.deleteRule(0) + self.assertEqual(len(p.cssRules), 1) + self.assertEqual(m3, p.cssRules[0]) + self.assertEqual(p.cssText, u'''@page { + @top-right { + color: blue + } + }''') + + del p['@top-right'] + self.assertEqual(len(p.cssRules), 0) + + + def test_style(self): + "CSSPageRule.style (and references)" + r = cssutils.css.CSSPageRule() + s1 = r.style + self.assertEqual(r, s1.parentRule) + self.assertEqual(u'', s1.cssText) + + # set rule.cssText + r.cssText = '@page { font-family: x1 }' + self.failIfEqual(r.style, s1) + self.assertEqual(r, r.style.parentRule) + self.assertEqual(r.cssText, u'@page {\n font-family: x1\n }') + self.assertEqual(r.style.cssText, u'font-family: x1') + self.assertEqual(s1.cssText, u'') + s2 = r.style + + # set invalid rule.cssText + try: + r.cssText = '@page { $ }' + except xml.dom.SyntaxErr, e: + pass + self.assertEqual(r.style, s2) + self.assertEqual(r, r.style.parentRule) + self.assertEqual(r.cssText, u'@page {\n font-family: x1\n }') + self.assertEqual(r.style.cssText, u'font-family: x1') + self.assertEqual(s2.cssText, u'font-family: x1') + s3 = r.style + + # set rule.style.cssText + r.style.cssText = 'font-family: x2' + self.assertEqual(r.style, s3) + self.assertEqual(r, r.style.parentRule) + self.assertEqual(r.cssText, u'@page {\n font-family: x2\n }') + self.assertEqual(r.style.cssText, u'font-family: x2') + + # set new style object s2 + s2 = cssutils.css.CSSStyleDeclaration('font-family: y1') + r.style = s2 + self.assertEqual(r.style, s2) + self.assertEqual(r, s2.parentRule) + self.assertEqual(r.cssText, u'@page {\n font-family: y1\n }') + self.assertEqual(s2.cssText, u'font-family: y1') + self.assertEqual(r.style.cssText, u'font-family: y1') + self.assertEqual(s3.cssText, u'font-family: x2') # old + + # set s2.cssText + s2.cssText = 'font-family: y2' + self.assertEqual(r.style, s2) + self.assertEqual(r.cssText, u'@page {\n font-family: y2\n }') + self.assertEqual(r.style.cssText, u'font-family: y2') + self.assertEqual(s3.cssText, u'font-family: x2') # old + # set invalid s2.cssText + try: + s2.cssText = '$' + except xml.dom.SyntaxErr, e: + pass + self.assertEqual(r.style, s2) + self.assertEqual(r.cssText, u'@page {\n font-family: y2\n }') + self.assertEqual(r.style.cssText, u'font-family: y2') + self.assertEqual(s3.cssText, u'font-family: x2') # old + + # set r.style with text + r.style = 'font-family: z' + self.failIfEqual(r.style, s2) + self.assertEqual(r.cssText, u'@page {\n font-family: z\n }') + self.assertEqual(r.style.cssText, u'font-family: z') + + def test_properties(self): + "CSSPageRule.style properties" + r = cssutils.css.CSSPageRule() + r.style.cssText = ''' + margin-top: 0; + margin-right: 0; + margin-bottom: 0; + margin-left: 0; + margin: 0; + + page-break-before: auto; + page-break-after: auto; + page-break-inside: auto; + + orphans: 3; + widows: 3; + ''' + exp = u'''@page { + margin-top: 0; + margin-right: 0; + margin-bottom: 0; + margin-left: 0; + margin: 0; + page-break-before: auto; + page-break-after: auto; + page-break-inside: auto; + orphans: 3; + widows: 3 + }''' + self.assertEqual(exp, r.cssText) + + def test_reprANDstr(self): + "CSSPageRule.__repr__(), .__str__()" + sel=u':left' + + s = cssutils.css.CSSPageRule(selectorText=sel) + + self.assert_(sel in str(s)) + + s2 = eval(repr(s)) + self.assert_(isinstance(s2, s.__class__)) + self.assert_(sel == s2.selectorText) + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_cssproperties.py cssutils-0.9.10/src/cssutils/tests/test_cssproperties.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_cssproperties.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_cssproperties.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,63 @@ +"""Testcases for cssutils.css.cssproperties.""" + +import xml.dom +import basetest +import cssutils.css +import cssutils.profiles + +class CSSPropertiesTestCase(basetest.BaseTestCase): + +# def test_cssvalues(self): +# "cssproperties cssvalues" +# # does actually return match object, so a very simplified test... +# match = cssutils.css.cssproperties.cssvalues +# +# self.assertEquals(True, bool(match['color']('red'))) +# self.assertEquals(False, bool(match['top']('red'))) +# +# self.assertEquals(True, bool(match['left']('0'))) +# self.assertEquals(True, bool(match['left']('1px'))) +# self.assertEquals(True, bool(match['left']('.1px'))) +# self.assertEquals(True, bool(match['left']('-1px'))) +# self.assertEquals(True, bool(match['left']('-.1px'))) +# self.assertEquals(True, bool(match['left']('-0.1px'))) + + def test_toDOMname(self): + "cssproperties _toDOMname(CSSname)" + _toDOMname = cssutils.css.cssproperties._toDOMname + + self.assertEquals('color', _toDOMname('color')) + self.assertEquals('fontStyle', _toDOMname('font-style')) + self.assertEquals('MozOpacity', _toDOMname('-moz-opacity')) + self.assertEquals('UNKNOWN', _toDOMname('UNKNOWN')) + self.assertEquals('AnUNKNOWN', _toDOMname('-anUNKNOWN')) + + def test_toCSSname(self): + "cssproperties _toCSSname(DOMname)" + _toCSSname = cssutils.css.cssproperties._toCSSname + + self.assertEquals('color', _toCSSname('color')) + self.assertEquals('font-style', _toCSSname('fontStyle')) + self.assertEquals('-moz-opacity', _toCSSname('MozOpacity')) + self.assertEquals('UNKNOWN', _toCSSname('UNKNOWN')) + self.assertEquals('-anUNKNOWN', _toCSSname('AnUNKNOWN')) + + def test_CSS2Properties(self): + "CSS2Properties" + CSS2Properties = cssutils.css.cssproperties.CSS2Properties + self.assertEquals(type(property()), type(CSS2Properties.color)) + self.assertEquals(sum([len(x) for x in cssutils.profiles.properties.values()]), + len(CSS2Properties._properties)) + + c2 = CSS2Properties() + # CSS2Properties has simplified implementation return always None + self.assertEquals(None, c2.color) + self.assertEquals(None, c2.__setattr__('color', 1)) + self.assertEquals(None, c2.__delattr__('color')) + # only defined properties + self.assertRaises(AttributeError, c2.__getattribute__, 'UNKNOWN') + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_cssrule.py cssutils-0.9.10/src/cssutils/tests/test_cssrule.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_cssrule.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_cssrule.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,238 @@ +"""Testcases for cssutils.css.CSSRule""" + +import xml.dom +import basetest +import cssutils.css + +class CSSRuleTestCase(basetest.BaseTestCase): + """ + base class for all CSSRule subclass tests + + overwrite setUp with the appriopriate values, will be used in + test_init and test_readonly + overwrite all tests as you please, use:: + + super(CLASSNAME, self).test_TESTNAME(params) + + to use the base class tests too + """ + def setUp(self): + """ + OVERWRITE! + self.r is the rule + self.rRO the readonly rule + relf.r_type the type as defined in CSSRule + """ + super(CSSRuleTestCase, self).setUp() + + self.sheet = cssutils.css.CSSStyleSheet() + self.r = cssutils.css.CSSRule() + self.rRO = cssutils.css.CSSRule() + self.rRO._readonly = True # must be set here! + self.r_type = cssutils.css.CSSRule.UNKNOWN_RULE + self.r_typeString = 'UNKNOWN_RULE' + + def tearDown(self): + cssutils.ser.prefs.useDefaults() + + def test_init(self): + "CSSRule.type and init" + self.assertEqual(self.r_type, self.r.type) + self.assertEqual(self.r_typeString, self.r.typeString) + self.assertEqual(u'', self.r.cssText) + self.assertEqual(None, self.r.parentRule) + self.assertEqual(None, self.r.parentStyleSheet) + + def test_parentRule_parentStyleSheet_type(self): + "CSSRule.parentRule .parentStyleSheet .type" + rules = [ + ('@charset "ascii";', cssutils.css.CSSRule.CHARSET_RULE), + ('@import "x";', cssutils.css.CSSRule.IMPORT_RULE), + ('@namespace "x";', cssutils.css.CSSRule.NAMESPACE_RULE), + ('@font-face { src: url(x) }', cssutils.css.CSSRule.FONT_FACE_RULE), + ('''@media all { + @x; + a { color: red } + /* c */ + }''', cssutils.css.CSSRule.MEDIA_RULE), + ('@page :left { color: red }', cssutils.css.CSSRule.PAGE_RULE), + ('@unknown;', cssutils.css.CSSRule.UNKNOWN_RULE), + ('b { left: 0 }', cssutils.css.CSSRule.STYLE_RULE), + ('/*1*/', cssutils.css.CSSRule.COMMENT) # must be last for add test + ] + mrt = [cssutils.css.CSSRule.UNKNOWN_RULE, + cssutils.css.CSSRule.STYLE_RULE, + cssutils.css.CSSRule.COMMENT] + def test(s): + for i, rule in enumerate(s): + self.assertEqual(rule.parentRule, None) + self.assertEqual(rule.parentStyleSheet, s) + #self.assertEqual(rule.type, rules[i][1]) + if rule.MEDIA_RULE == rule.type: + for j, r in enumerate(rule): + self.assertEqual(r.parentRule, rule) + self.assertEqual(r.parentStyleSheet, s) + self.assertEqual(r.type, mrt[j]) + + if i == 0: # check encoding + self.assertEqual('ascii', s.encoding) + elif i == 2: # check namespaces + self.assertEqual('x', s.namespaces['']) + + cssText = u''.join(r[0] for r in rules) + # parsing + s = cssutils.parseString(cssText) + test(s) + # sheet.cssText + s = cssutils.css.CSSStyleSheet() + s.cssText = cssText + test(s) + # sheet.add CSS + s = cssutils.css.CSSStyleSheet() + for css, type_ in rules: + s.add(css) + test(s) + # sheet.insertRule CSS + s = cssutils.css.CSSStyleSheet() + for css, type_ in rules: + s.insertRule(css) + test(s) + + types = [cssutils.css.CSSCharsetRule, + cssutils.css.CSSImportRule, + cssutils.css.CSSNamespaceRule, + cssutils.css.CSSFontFaceRule, + cssutils.css.CSSMediaRule, + cssutils.css.CSSPageRule, + cssutils.css.CSSUnknownRule, + cssutils.css.CSSStyleRule, + cssutils.css.CSSComment] + # sheet.add CSSRule + s = cssutils.css.CSSStyleSheet() + for i, (css, type_) in enumerate(rules): + rule = types[i]() + rule.cssText = css + s.add(rule) + test(s) + # sheet.insertRule CSSRule + s = cssutils.css.CSSStyleSheet() + for i, (css, type_) in enumerate(rules): + rule = types[i]() + rule.cssText = css + s.insertRule(rule) + test(s) + + def test_CSSMediaRule_cssRules_parentRule_parentStyleSheet_type(self): + "CSSMediaRule.cssRules.parentRule .parentStyleSheet .type" + rules = [ + ('b { left: 0 }', cssutils.css.CSSRule.STYLE_RULE), + ('/*1*/', cssutils.css.CSSRule.COMMENT), + ('@x;', cssutils.css.CSSRule.UNKNOWN_RULE) + ] + def test(s): + mr = s.cssRules[0] + for i, rule in enumerate(mr): + self.assertEqual(rule.parentRule, mr) + self.assertEqual(rule.parentStyleSheet, s) + self.assertEqual(rule.parentStyleSheet, mr.parentStyleSheet) + self.assertEqual(rule.type, rules[i][1]) + + cssText = '@media all { %s }' % u''.join(r[0] for r in rules) + # parsing + s = cssutils.parseString(cssText) + test(s) + # sheet.cssText + s = cssutils.css.CSSStyleSheet() + s.cssText = cssText + test(s) + + def getMediaSheet(): + s = cssutils.css.CSSStyleSheet() + s.cssText = '@media all {}' + return s, s.cssRules[0] + # sheet.add CSS + s, mr = getMediaSheet() + for css, type_ in rules: + mr.add(css) + test(s) + # sheet.insertRule CSS + s, mr = getMediaSheet() + for css, type_ in rules: + mr.insertRule(css) + test(s) + + types = [cssutils.css.CSSStyleRule, + cssutils.css.CSSComment, + cssutils.css.CSSUnknownRule] + # sheet.add CSSRule + s, mr = getMediaSheet() + for i, (css, type_) in enumerate(rules): + rule = types[i]() + rule.cssText = css + mr.add(rule) + test(s) + # sheet.insertRule CSSRule + s, mr = getMediaSheet() + for i, (css, type_) in enumerate(rules): + rule = types[i]() + rule.cssText = css + mr.insertRule(rule) + test(s) + + def test_readonly(self): + "CSSRule readonly" + self.rRO = cssutils.css.CSSRule() + self.rRO._readonly = True + self.assertEqual(True, self.rRO._readonly) + self.assertEqual(u'', self.rRO.cssText) + self.assertRaises(xml.dom.NoModificationAllowedErr, + self.rRO._setCssText, u'x') + self.assertEqual(u'', self.rRO.cssText) + + def _test_InvalidModificationErr(self, startwithspace): + """ + CSSRule.cssText InvalidModificationErr + + called by subclasses + + startwithspace + + for test starting with this not the test but " test" is tested + e.g. " @page {}" + exception is the style rule test + """ + tests = (u'', + u'/* comment */', + u'@charset "utf-8";', + u'@font-face {}', + u'@import url(x);', + u'@media all {}', + u'@namespace "x";' + u'@page {}', + u'@unknown;', + u'@variables;', + # TODO: + #u'@top-left {}' + u'a style rule {}' + ) + for test in tests: + if startwithspace in (u'a style rule', ) and test in ( + u'/* comment */', u'a style rule {}'): + continue + + if test.startswith(startwithspace): + test = u' %s' % test + + self.assertRaises(xml.dom.InvalidModificationErr, + self.r._setCssText, test) + + # check that type is readonly + self.assertRaises(AttributeError, self.r.__setattr__, 'parentRule', None) + self.assertRaises(AttributeError, self.r.__setattr__, 'parentStyleSheet', None) + self.assertRaises(AttributeError, self.r.__setattr__, 'type', 1) + self.assertRaises(AttributeError, self.r.__setattr__, 'typeString', "") + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_cssrulelist.py cssutils-0.9.10/src/cssutils/tests/test_cssrulelist.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_cssrulelist.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_cssrulelist.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,37 @@ +"""Testcases for cssutils.css.CSSRuleList""" + +import basetest +import cssutils + +class CSSRuleListTestCase(basetest.BaseTestCase): + + def test_init(self): + "CSSRuleList.__init__()" + r = cssutils.css.CSSRuleList() + self.assertEqual(0, r.length) + self.assertEqual(None, r.item(2)) + + # subclasses list but all setting options like append, extend etc + # need to be added to an instance of this class by a using class! + self.assertRaises(NotImplementedError, r.append, 1) + + def test_rulesOfType(self): + "CSSRuleList.rulesOfType()" + s = cssutils.parseString(''' + /*c*/ + @namespace "a"; + a { color: red} + b { left: 0 }''') + + c = list(s.cssRules.rulesOfType(cssutils.css.CSSRule.COMMENT)) + self.assertEqual(1, len(c)) + self.assertEqual('/*c*/', c[0].cssText) + + r = list(s.cssRules.rulesOfType(cssutils.css.CSSRule.STYLE_RULE)) + self.assertEqual(2, len(r)) + self.assertEqual('b {\n left: 0\n }', r[1].cssText) + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_cssstyledeclaration.py cssutils-0.9.10/src/cssutils/tests/test_cssstyledeclaration.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_cssstyledeclaration.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_cssstyledeclaration.py 2013-03-31 19:20:00.000000000 +0000 @@ -0,0 +1,594 @@ +"""Testcases for cssutils.css.cssstyledelaration.CSSStyleDeclaration.""" + +import xml.dom +import basetest +import cssutils + +class CSSStyleDeclarationTestCase(basetest.BaseTestCase): + + def setUp(self): + self.r = cssutils.css.CSSStyleDeclaration() + + def test_init(self): + "CSSStyleDeclaration.__init__()" + s = cssutils.css.CSSStyleDeclaration() + self.assertEqual(u'', s.cssText) + self.assertEqual(0, s.length) + self.assertEqual(None, s.parentRule) + + s = cssutils.css.CSSStyleDeclaration(cssText='left: 0') + self.assertEqual(u'left: 0', s.cssText) + self.assertEqual('0', s.getPropertyValue('left')) + + sheet = cssutils.css.CSSStyleRule() + s = cssutils.css.CSSStyleDeclaration(parentRule=sheet) + self.assertEqual(sheet, s.parentRule) + + # should not be used but ordered parameter test + s = cssutils.css.CSSStyleDeclaration('top: 0', sheet) + self.assertEqual(u'top: 0', s.cssText) + self.assertEqual(sheet, s.parentRule) + + def test_items(self): + "CSSStyleDeclaration[CSSName]" + s = cssutils.css.CSSStyleDeclaration() + name, value, priority = 'color', 'name', '' + s[name] = value + self.assertEqual(value, s[name]) + self.assertEqual(value, s.__getattribute__(name)) + self.assertEqual(value, s.getProperty(name).value) + self.assertEqual(priority, s.getProperty(name).priority) + + name, value, priority = 'UnKnown-ProPERTY', 'unknown value', 'important' + s[name] = (value, priority) + self.assertEqual(value, s[name]) + self.assertEqual(value, s[name.lower()]) # will be normalized + self.assertRaises(AttributeError, s.__getattribute__, name) + self.assertEqual(value, s.getProperty(name).value) + self.assertEqual(priority, s.getProperty(name).priority) + + name, value, priority = 'item', '1', '' + s[name] = value + self.assertEqual(value, s[name]) + self.assertEqual(value, s.getProperty(name).value) + self.assertEqual(priority, s.getProperty(name).priority) + + del s[name] + self.assertEqual(u'', s[name]) + self.assertEqual(u'', s['never set']) + + def test__contains__(self): + "CSSStyleDeclaration.__contains__(nameOrProperty)" + s = cssutils.css.CSSStyleDeclaration(cssText=r'x: 1;\y: 2') + for test in ('x', r'x', 'y', r'y'): + self.assert_(test in s) + self.assert_(test.upper() in s) + self.assert_(cssutils.css.Property(test, '1') in s) + self.assert_('z' not in s) + self.assert_(cssutils.css.Property('z', '1') not in s) + + def test__iter__item(self): + "CSSStyleDeclaration.__iter__ and .item" + s = cssutils.css.CSSStyleDeclaration() + s.cssText = ur''' + color: red; c\olor: blue; CO\lor: green; + left: 1px !important; left: 0; + border: 0; + ''' + # __iter__ + ps = [] + for p in s: + ps.append((p.literalname, p.value, p.priority)) + self.assertEqual(len(ps), 3) + self.assertEqual(ps[0], (ur'co\lor', 'green', '')) + self.assertEqual(ps[1], (ur'left', '1px', 'important')) + self.assertEqual(ps[2], (ur'border', '0', '')) + + # item + self.assertEqual(s.length, 3) + self.assertEqual(s.item(0), u'color') + self.assertEqual(s.item(1), u'left') + self.assertEqual(s.item(2), u'border') + self.assertEqual(s.item(10), u'') + + def test_keys(self): + "CSSStyleDeclaration.keys()" + s = cssutils.parseStyle('x:1; x:2; y:1') + self.assertEqual(['x', 'y'], s.keys()) + self.assertEqual(s['x'], '2') + self.assertEqual(s['y'], '1') + + def test_parse(self): + "CSSStyleDeclaration parse" + # error but parse + tests = { + # property names are caseinsensitive + u'TOP:0': u'top: 0', + u'top:0': u'top: 0', + # simple escape + u'c\\olor: red; color:green': u'color: green', + u'color:g\\reen': u'color: g\\reen', + # http://www.w3.org/TR/2009/CR-CSS2-20090423/syndata.html#illegalvalues + u'color:green': u'color: green', + u'color:green; color': u'color: green', + u'color:red; color; color:green': u'color: green', + u'color:green; color:': u'color: green', + u'color:red; color:; color:green': u'color: green', + u'color:green; color{;color:maroon}': u'color: green', + u'color:red; color{;color:maroon}; color:green': u'color: green', + # tantek hack + ur'''color: red; +voice-family: "\"}\""; +voice-family:inherit; +color: green;''': 'voice-family: inherit;\ncolor: green', + ur'''col\or: blue; + font-family: 'Courier New Times + color: red; + color: green;''': u'color: green', + + # special IE hacks are not preserved anymore (>=0.9.5b3) + u'/color: red; color: green': u'color: green', + u'/ color: red; color: green': u'color: green', + u'1px: red; color: green': u'color: green', + u'0: red; color: green': u'color: green', + u'1px:: red; color: green': u'color: green', + ur'$top: 0': u'', + ur'$: 0': u'', # really invalid! + # unknown rule but valid + u'@x;\ncolor: red': None, + u'@x {\n }\ncolor: red': None, + u'/**/\ncolor: red': None, + u'/**/\ncolor: red;\n/**/': None, + #issue #28 + u';color: red': u'color: red', + u';;color: red;;': u'color: red' + } + cssutils.ser.prefs.keepAllProperties = False + for test, exp in tests.items(): + sh = cssutils.parseString('a { %s }' % test) + if exp is None: + exp = u'%s' % test + elif exp != u'': + exp = u'%s' % exp + self.assertEqual(exp, sh.cssRules[0].style.cssText) + + cssutils.ser.prefs.useDefaults() + + def test_serialize(self): + "CSSStyleDeclaration serialize" + s = cssutils.css.CSSStyleDeclaration() + tests = { + u'a:1 !important; a:2;b:1': (u'a: 1 !important;\nb: 1', + u'a: 1 !important;\na: 2;\nb: 1') + } + for test, exp in tests.items(): + s.cssText = test + cssutils.ser.prefs.keepAllProperties = False + self.assertEqual(exp[0], s.cssText) + cssutils.ser.prefs.keepAllProperties = True + self.assertEqual(exp[1], s.cssText) + + cssutils.ser.prefs.useDefaults() + + def test_children(self): + "CSSStyleDeclaration.children()" + style = u'/*1*/color: red; color: green; @x;' + types = [ + cssutils.css.CSSComment, + cssutils.css.Property, + cssutils.css.Property, + cssutils.css.CSSUnknownRule + ] + def t(s): + for i, x in enumerate(s.children()): + self.assertEqual(types[i], type(x)) + self.assertEqual(x.parent, s) + + t(cssutils.parseStyle(style)) + t(cssutils.parseString(u'a {'+style+'}').cssRules[0].style) + t(cssutils.parseString(u'@media all {a {'+style+'}}').cssRules[0].cssRules[0].style) + + s = cssutils.parseStyle(style) + s['x'] = '0' + self.assertEqual(s, s.getProperty('x').parent) + s.setProperty('y', '1') + self.assertEqual(s, s.getProperty('y').parent) + + def test_cssText(self): + "CSSStyleDeclaration.cssText" + # empty + s = cssutils.css.CSSStyleDeclaration() + tests = { + u'': u'', + u' ': u'', + u' \t \n ': u'', + u'/*x*/': u'/*x*/' + } + for test, exp in tests.items(): + s.cssText = 'left: 0;' # dummy to reset s + s.cssText = test + self.assertEqual(exp, s.cssText) + + # normal + s = cssutils.css.CSSStyleDeclaration() + tests = { + u';': u'', + u'left: 0': u'left: 0', + u'left:0': u'left: 0', + u' left : 0 ': u'left: 0', + u'left: 0;': u'left: 0', + u'left: 0 !important ': u'left: 0 !important', + u'left:0!important': u'left: 0 !important', + u'left: 0; top: 1': u'left: 0;\ntop: 1', + # comments + # TODO: spaces? + u'/*1*//*2*/left/*3*//*4*/:/*5*//*6*/0/*7*//*8*/!/*9*//*a*/important/*b*//*c*/;': + u'/*1*/\n/*2*/\nleft/*3*//*4*/: /*5*/ /*6*/ 0 /*7*/ /*8*/ !/*9*//*a*/important/*b*//*c*/', + u'/*1*/left: 0;/*2*/ top: 1/*3*/': + u'/*1*/\nleft: 0;\n/*2*/\ntop: 1 /*3*/', + u'left:0; top:1;': u'left: 0;\ntop: 1', + u'/*1*/left: 0;/*2*/ top: 1;/*3*/': + u'/*1*/\nleft: 0;\n/*2*/\ntop: 1;\n/*3*/', + # WS + u'left:0!important;margin:1px 2px 3px 4px!important;': u'left: 0 !important;\nmargin: 1px 2px 3px 4px !important', + u'\n\r\f\t left\n\r\f\t :\n\r\f\t 0\n\r\f\t !\n\r\f\t important\n\r\f\t ;\n\r\f\t margin\n\r\f\t :\n\r\f\t 1px\n\r\f\t 2px\n\r\f\t 3px\n\r\f\t 4px;': + u'left: 0 !important;\nmargin: 1px 2px 3px 4px', + } + for test, exp in tests.items(): + s.cssText = test + self.assertEqual(exp, s.cssText) + + # exception + tests = { + u'color: #xyz': xml.dom.SyntaxErr, + u'top': xml.dom.SyntaxErr, + u'top:': xml.dom.SyntaxErr, + u'top : ': xml.dom.SyntaxErr, + u'top:!important': xml.dom.SyntaxErr, + u'top:!important;': xml.dom.SyntaxErr, + u'top:;': xml.dom.SyntaxErr, + u'top 0': xml.dom.SyntaxErr, + u'top 0;': xml.dom.SyntaxErr, + + u':': xml.dom.SyntaxErr, + u':0': xml.dom.SyntaxErr, + u':0;': xml.dom.SyntaxErr, + u':0!important': xml.dom.SyntaxErr, + u':;': xml.dom.SyntaxErr, + u': ;': xml.dom.SyntaxErr, + u':!important;': xml.dom.SyntaxErr, + u': !important;': xml.dom.SyntaxErr, + + u'0': xml.dom.SyntaxErr, + u'0!important': xml.dom.SyntaxErr, + u'0!important;': xml.dom.SyntaxErr, + u'0;': xml.dom.SyntaxErr, + + u'!important': xml.dom.SyntaxErr, + u'!important;': xml.dom.SyntaxErr, + } + self.do_raise_r(tests) + + def test_getCssText(self): + "CSSStyleDeclaration.getCssText(separator)" + s = cssutils.css.CSSStyleDeclaration(cssText=u'a:1;b:2') + self.assertEqual(u'a: 1;\nb: 2', s.getCssText()) + self.assertEqual(u'a: 1;b: 2', s.getCssText(separator=u'')) + self.assertEqual(u'a: 1;/*x*/b: 2', s.getCssText(separator=u'/*x*/')) + + def test_parentRule(self): + "CSSStyleDeclaration.parentRule" + s = cssutils.css.CSSStyleDeclaration() + sheet = cssutils.css.CSSStyleRule() + s.parentRule = sheet + self.assertEqual(sheet, s.parentRule) + + sheet = cssutils.parseString(u'a{x:1}') + s = sheet.cssRules[0] + d = s.style + self.assertEqual(s, d.parentRule) + + s = cssutils.parseString(''' + @font-face { + font-weight: bold; + } + a { + font-weight: bolder; + } + @page { + font-weight: bolder; + } + ''') + for r in s: + self.assertEqual(r.style.parentRule, r) + + def test_getProperty(self): + "CSSStyleDeclaration.getProperty" + s = cssutils.css.CSSStyleDeclaration() + P = cssutils.css.Property + s.cssText = ur''' + color: red; c\olor: blue; CO\lor: green; + left: 1px !important; left: 0; + border: 0; + ''' + self.assertEqual(s.getProperty('color').cssText, ur'co\lor: green') + self.assertEqual(s.getProperty(r'COLO\r').cssText, ur'co\lor: green') + self.assertEqual(s.getProperty('left').cssText, ur'left: 1px !important') + self.assertEqual(s.getProperty('border').cssText, ur'border: 0') + + def test_getProperties(self): + "CSSStyleDeclaration.getProperties()" + s = cssutils.css.CSSStyleDeclaration(cssText= + u'/*1*/y:0;x:a !important;y:1; \\x:b;') + tests = { + # name, all + (None, False): [(u'y', u'1', u''), + (u'x', u'a', u'important')], + (None, True): [(u'y', u'0', u''), + (u'x', u'a', u'important'), + (u'y', u'1', u''), + (u'\\x', u'b', u'') + ], + ('x', False): [(u'x', u'a', u'important')], + ('\\x', False): [(u'x', u'a', u'important')], + ('x', True): [(u'x', u'a', u'important'), + (u'\\x', u'b', u'')], + ('\\x', True): [(u'x', u'a', u'important'), + (u'\\x', u'b', u'')], + } + for test in tests: + name, all = test + expected = tests[test] + actual = s.getProperties(name, all) + self.assertEqual(len(expected), len(actual)) + for i, ex in enumerate(expected): + a = actual[i] + self.assertEqual(ex, (a.literalname, a.value, a.priority)) + + # order is be effective properties set + s = cssutils.css.CSSStyleDeclaration(cssText= + u'a:0;b:1;a:1') + self.assertEqual(u'ba', u''.join([p.name for p in s])) + + def test_getPropertyCSSValue(self): + "CSSStyleDeclaration.getPropertyCSSValue()" + s = cssutils.css.CSSStyleDeclaration(cssText='color: red;c\\olor: green') + self.assertEqual(u'green', s.getPropertyCSSValue('color').cssText) + self.assertEqual(u'green', s.getPropertyCSSValue('c\\olor').cssText) + self.assertEqual(u'red', s.getPropertyCSSValue('color', False).cssText) + self.assertEqual(u'green', s.getPropertyCSSValue('c\\olor', False).cssText) +# # shorthand CSSValue should be None +# SHORTHAND = [ +# u'background', +# u'border', +# u'border-left', u'border-right', +# u'border-top', u'border-bottom', +# u'border-color', u'border-style', u'border-width', +# u'cue', +# u'font', +# u'list-style', +# u'margin', +# u'outline', +# u'padding', +# u'pause'] +# for short in SHORTHAND: +# s.setProperty(short, u'inherit') +# self.assertEqual(None, s.getPropertyCSSValue(short)) + + def test_getPropertyValue(self): + "CSSStyleDeclaration.getPropertyValue()" + s = cssutils.css.CSSStyleDeclaration() + self.assertEqual(u'', s.getPropertyValue('unset')) + + s.setProperty(u'left', '0') + self.assertEqual(u'0', s.getPropertyValue('left')) + + s.setProperty(u'border', '1px solid green') + self.assertEqual(u'1px solid green', s.getPropertyValue('border')) + + s = cssutils.css.CSSStyleDeclaration(cssText='color: red;c\\olor: green') + self.assertEqual(u'green', s.getPropertyValue('color')) + self.assertEqual(u'green', s.getPropertyValue('c\\olor')) + self.assertEqual(u'red', s.getPropertyValue('color', False)) + self.assertEqual(u'green', s.getPropertyValue('c\\olor', False)) + + tests = { + ur'color: red; color: green': 'green', + ur'c\olor: red; c\olor: green': 'green', + ur'color: red; c\olor: green': 'green', + ur'color: red !important; color: green !important': 'green', + ur'color: green !important; color: red': 'green', + } + for test in tests: + s = cssutils.css.CSSStyleDeclaration(cssText=test) + self.assertEqual(tests[test], s.getPropertyValue('color')) + + def test_getPropertyPriority(self): + "CSSStyleDeclaration.getPropertyPriority()" + s = cssutils.css.CSSStyleDeclaration() + self.assertEqual(u'', s.getPropertyPriority('unset')) + + s.setProperty(u'left', u'0', u'!important') + self.assertEqual(u'important', s.getPropertyPriority('left')) + + s = cssutils.css.CSSStyleDeclaration(cssText= + 'x: 1 !important;\\x: 2;x: 3 !important;\\x: 4') + self.assertEqual(u'important', s.getPropertyPriority('x')) + self.assertEqual(u'important', s.getPropertyPriority('\\x')) + self.assertEqual(u'important', s.getPropertyPriority('x', True)) + self.assertEqual(u'', s.getPropertyPriority('\\x', False)) + + def test_removeProperty(self): + "CSSStyleDeclaration.removeProperty()" + cssutils.ser.prefs.useDefaults() + s = cssutils.css.CSSStyleDeclaration() + css = ur'\x:0 !important; x:1; \x:2; x:3' + + # normalize=True DEFAULT + s.cssText = css + self.assertEqual(u'0', s.removeProperty('x')) + self.assertEqual(u'', s.cssText) + + # normalize=False + s.cssText = css + self.assertEqual(u'3', s.removeProperty('x', normalize=False)) + self.assertEqual(ur'\x: 0 !important;\x: 2', s.getCssText(separator=u'')) + self.assertEqual(u'0', s.removeProperty(r'\x', normalize=False)) + self.assertEqual(u'', s.cssText) + + s.cssText = css + self.assertEqual(u'0', s.removeProperty(r'\x', normalize=False)) + self.assertEqual(ur'x: 1;x: 3', s.getCssText(separator=u'')) + self.assertEqual(u'3', s.removeProperty('x', normalize=False)) + self.assertEqual(u'', s.cssText) + + def test_setProperty(self): + "CSSStyleDeclaration.setProperty()" + s = cssutils.css.CSSStyleDeclaration() + s.setProperty('top', '0', '!important') + self.assertEqual('0', s.getPropertyValue('top')) + self.assertEqual('important', s.getPropertyPriority('top')) + s.setProperty('top', '1px') + self.assertEqual('1px', s.getPropertyValue('top')) + self.assertEqual('', s.getPropertyPriority('top')) + + s.setProperty('top', '2px') + self.assertEqual('2px', s.getPropertyValue('top')) + + s.setProperty('\\top', '3px') + self.assertEqual('3px', s.getPropertyValue('top')) + + s.setProperty('\\top', '4px', normalize=False) + self.assertEqual('4px', s.getPropertyValue('top')) + self.assertEqual('4px', s.getPropertyValue('\\top', False)) + self.assertEqual('3px', s.getPropertyValue('top', False)) + + # case insensitive + s.setProperty('TOP', '0', '!IMPORTANT') + self.assertEqual('0', s.getPropertyValue('top')) + self.assertEqual('important', s.getPropertyPriority('top')) + + tests = { + (u'left', u'0', u''): u'left: 0', + (u'left', u'0', u'important'): u'left: 0 !important', + (u'LEFT', u'0', u'important'): u'left: 0 !important', + (u'left', u'0', u'important'): u'left: 0 !important', + } + for test, exp in tests.items(): + s = cssutils.css.CSSStyleDeclaration() + n, v, p = test + s.setProperty(n, v, p) + self.assertEqual(exp, s.cssText) + self.assertEqual(v, s.getPropertyValue(n)) + self.assertEqual(p, s.getPropertyPriority(n)) + + # empty + s = cssutils.css.CSSStyleDeclaration() + self.assertEqual('', s.top) + s.top = '0' + self.assertEqual('0', s.top) + s.top = '' + self.assertEqual('', s.top) + s.top = None + self.assertEqual('', s.top) + + def test_setProperty(self): + "CSSStyleDeclaration.setProperty(replace=)" + s = cssutils.css.CSSStyleDeclaration() + s.setProperty('top', '1px') + self.assertEqual(len(s.getProperties('top', all=True)), 1) + + s.setProperty('top', '2px') + self.assertEqual(len(s.getProperties('top', all=True)), 1) + self.assertEqual(s.getPropertyValue('top'), '2px') + + s.setProperty('top', '3px', replace=False) + self.assertEqual(len(s.getProperties('top', all=True)), 2) + self.assertEqual(s.getPropertyValue('top'), '3px') + + def test_length(self): + "CSSStyleDeclaration.length" + s = cssutils.css.CSSStyleDeclaration() + + # cssText + s.cssText = u'left: 0' + self.assertEqual(1, s.length) + self.assertEqual(1, len(s.seq)) + s.cssText = u'/*1*/left/*x*/:/*x*/0/*x*/;/*2*/ top: 1;/*3*/' + self.assertEqual(2, s.length) + self.assertEqual(5, len(s.seq)) + + # set + s = cssutils.css.CSSStyleDeclaration() + s.setProperty('top', '0', '!important') + self.assertEqual(1, s.length) + s.setProperty('top', '1px') + self.assertEqual(1, s.length) + s.setProperty('left', '1px') + + def test_nameParameter(self): + "CSSStyleDeclaration.XXX(name)" + s = cssutils.css.CSSStyleDeclaration() + s.setProperty('top', '1px', '!important') + + self.assertEqual('1px', s.getPropertyValue('top')) + self.assertEqual('1px', s.getPropertyValue('TOP')) + self.assertEqual('1px', s.getPropertyValue('T\op')) + + self.assertEqual('important', s.getPropertyPriority('top')) + self.assertEqual('important', s.getPropertyPriority('TOP')) + self.assertEqual('important', s.getPropertyPriority('T\op')) + + s.setProperty('top', '2px', '!important') + self.assertEqual('2px', s.removeProperty('top')) + s.setProperty('top', '2px', '!important') + self.assertEqual('2px', s.removeProperty('TOP')) + s.setProperty('top', '2px', '!important') + self.assertEqual('2px', s.removeProperty('T\op')) + + def test_css2properties(self): + "CSSStyleDeclaration.$css2property get set del" + s = cssutils.css.CSSStyleDeclaration( + cssText='left: 1px;color: red; font-style: italic') + + s.color = 'green' + s.fontStyle = 'normal' + self.assertEqual('green', s.color) + self.assertEqual('normal', s.fontStyle) + self.assertEqual('green', s.getPropertyValue('color')) + self.assertEqual('normal', s.getPropertyValue('font-style')) + self.assertEqual( + u'''left: 1px;\ncolor: green;\nfont-style: normal''', + s.cssText) + + del s.color + self.assertEqual( + u'''left: 1px;\nfont-style: normal''', + s.cssText) + del s.fontStyle + self.assertEqual(u'left: 1px', s.cssText) + + self.assertRaises(AttributeError, s.__setattr__, 'UNKNOWN', 'red') + # unknown properties must be set with setProperty! + s.setProperty('UNKNOWN', 'red') + # but are still not usable as property! + self.assertRaises(AttributeError, s.__getattribute__, 'UNKNOWN') + self.assertRaises(AttributeError, s.__delattr__, 'UNKNOWN') + # but are kept + self.assertEqual('red', s.getPropertyValue('UNKNOWN')) + self.assertEqual( + '''left: 1px;\nunknown: red''', s.cssText) + + def test_reprANDstr(self): + "CSSStyleDeclaration.__repr__(), .__str__()" + s = cssutils.css.CSSStyleDeclaration(cssText='a:1;b:2') + + self.assert_("2" in str(s)) # length + + s2 = eval(repr(s)) + self.assert_(isinstance(s2, s.__class__)) + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_cssstylerule.py cssutils-0.9.10/src/cssutils/tests/test_cssstylerule.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_cssstylerule.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_cssstylerule.py 2013-03-31 18:09:36.000000000 +0000 @@ -0,0 +1,250 @@ +"""Testcases for cssutils.css.CSSStyleRuleTestCase""" + +import xml.dom +import test_cssrule +import cssutils + +class CSSStyleRuleTestCase(test_cssrule.CSSRuleTestCase): + + def setUp(self): + super(CSSStyleRuleTestCase, self).setUp() + self.r = cssutils.css.CSSStyleRule() + self.rRO = cssutils.css.CSSStyleRule(readonly=True) + self.r_type = cssutils.css.CSSStyleRule.STYLE_RULE + self.r_typeString = 'STYLE_RULE' + + def test_init(self): + "CSSStyleRule.type and init" + super(CSSStyleRuleTestCase, self).test_init() + self.assertEqual(u'', self.r.cssText) + self.assertEqual(cssutils.css.selectorlist.SelectorList, + type(self.r.selectorList)) + self.assertEqual(u'', self.r.selectorText) + self.assertEqual(cssutils.css.CSSStyleDeclaration, + type(self.r.style)) + self.assertEqual(self.r, self.r.style.parentRule) + + def test_refs(self): + "CSSStyleRule references" + s = cssutils.css.CSSStyleRule() + sel, style = s.selectorList, s.style + + self.assertEqual(s, sel.parentRule) + self.assertEqual(s, style.parentRule) + + s.cssText = 'a { x:1 }' + self.failIfEqual(sel, s.selectorList) + self.assertEqual('a', s.selectorList.selectorText) + self.failIfEqual(style, s.style) + self.assertEqual('1', s.style.getPropertyValue('x')) + + sel, style = s.selectorList, s.style + + invalids = ('$b { x:2 }', # invalid selector + 'c { $x3 }', # invalid style + '/b { 2 }' # both invalid + ) + for invalid in invalids: + try: + s.cssText = invalid + except xml.dom.DOMException, e: + pass + self.assertEqual(sel, s.selectorList) + self.assertEqual(u'a', s.selectorList.selectorText) + self.assertEqual(style, s.style) + self.assertEqual(u'1', s.style.getPropertyValue('x')) + + # CHANGING + s = cssutils.parseString(u'a {s1: 1}') + r = s.cssRules[0] + sel1 = r.selectorList + st1 = r.style + + # selectorList + r.selectorText = 'b' + self.failIfEqual(sel1, r.selectorList) + self.assertEqual('b', r.selectorList.selectorText) + self.assertEqual('b', r.selectorText) + sel1b = r.selectorList + + sel1b.selectorText = 'c' + self.assertEqual(sel1b, r.selectorList) + self.assertEqual('c', r.selectorList.selectorText) + self.assertEqual('c', r.selectorText) + + sel2 = cssutils.css.SelectorList('sel2') + s.selectorList = sel2 + self.assertEqual(sel2, s.selectorList) + self.assertEqual('sel2', s.selectorList.selectorText) + + sel2.selectorText = 'sel2b' + self.assertEqual('sel2b', sel2.selectorText) + self.assertEqual('sel2b', s.selectorList.selectorText) + + s.selectorList.selectorText = 'sel2c' + self.assertEqual('sel2c', sel2.selectorText) + self.assertEqual('sel2c', s.selectorList.selectorText) + + # style + r.style = 's1: 2' + self.failIfEqual(st1, r.style) + self.assertEqual('s1: 2', r.style.cssText) + + st2 = cssutils.parseStyle(u's2: 1') + r.style = st2 + self.assertEqual(st2, r.style) + self.assertEqual('s2: 1', r.style.cssText) + + # cssText + sl, st = r.selectorList, r.style + # fails + try: + r.cssText = '$ {content: "new"}' + except xml.dom.SyntaxErr, e: + pass + self.assertEqual(sl, r.selectorList) + self.assertEqual(st, r.style) + + r.cssText = 'a {content: "new"}' + self.failIfEqual(sl, r.selectorList) + self.failIfEqual(st, r.style) + + def test_cssText(self): + "CSSStyleRule.cssText" + tests = { + u'* {}': u'', + u'a {}': u'', + } + self.do_equal_p(tests) # parse + #self.do_equal_r(tests) # set cssText # TODO: WHY? + + cssutils.ser.prefs.keepEmptyRules = True + tests = { + #u'''a{;display:block;float:left}''': 'a {\n display:block;\n float:left\n }', # issue 28 + + u'''a\n{color: #000}''': 'a {\n color: #000\n }', # issue 4 + u'''a\n{color: #000000}''': 'a {\n color: #000\n }', # issue 4 + u'''a\n{color: #abc}''': 'a {\n color: #abc\n }', # issue 4 + u'''a\n{color: #abcdef}''': 'a {\n color: #abcdef\n }', # issue 4 + u'''a\n{color: #00a}''': 'a {\n color: #00a\n }', # issue 4 + u'''a\n{color: #1a1a1a}''': 'a {\n color: #1a1a1a\n }', # issue 4 + u'''#id\n{ color: red }''': '#id {\n color: red\n }', # issue 3 + u'''* {}''': None, + u'a {}': None, + u'b { a: 1; }': u'b {\n a: 1\n }', + # mix of comments and properties + u'c1 {/*1*/a:1;}': u'c1 {\n /*1*/\n a: 1\n }', + u'c2 {a:1;/*2*/}': u'c2 {\n a: 1;\n /*2*/\n }', + u'd1 {/*0*/}': u'd1 {\n /*0*/\n }', + u'd2 {/*0*//*1*/}': u'd2 {\n /*0*/\n /*1*/\n }', + # comments + # TODO: spaces? + u'''a/*1*//*2*/,/*3*//*4*/b/*5*//*6*/{color: #000}''': + u'a/*1*//*2*/, /*3*//*4*/b/*5*//*6*/ {\n color: #000\n }', + + u'''a,b{color: #000}''': 'a, b {\n color: #000\n }', # issue 4 + u'''a\n\r\t\f ,\n\r\t\f b\n\r\t\f {color: #000}''': 'a, b {\n color: #000\n }', # issue 4 + } + self.do_equal_p(tests) # parse + self.do_equal_r(tests) # set cssText + + tests = { + u'''a;''': xml.dom.SyntaxErr, + u'''a {{}''': xml.dom.SyntaxErr, + u'''a }''': xml.dom.SyntaxErr, + } + self.do_raise_p(tests) # parse + tests.update({ + u'''/*x*/''': xml.dom.SyntaxErr, + u'''a {''': xml.dom.SyntaxErr, + # trailing + u'''a {}x''': xml.dom.SyntaxErr, + u'''a {/**/''': xml.dom.SyntaxErr, + u'''a {} ''': xml.dom.SyntaxErr, + }) + self.do_raise_r(tests) # set cssText + cssutils.ser.prefs.useDefaults() + + def test_selectorList(self): + "CSSStyleRule.selectorList" + r = cssutils.css.CSSStyleRule() + + r.selectorList.appendSelector(u'a') + self.assertEqual(1, r.selectorList.length) + self.assertEqual(u'a', r.selectorText) + + r.selectorList.appendSelector(u' b ') + # only simple selector! + self.assertRaises(xml.dom.InvalidModificationErr, + r.selectorList.appendSelector, u' h1, x ') + + self.assertEqual(2, r.selectorList.length) + self.assertEqual(u'a, b', r.selectorText) + + def test_selectorText(self): + "CSSStyleRule.selectorText" + r = cssutils.css.CSSStyleRule() + + r.selectorText = u'a' + self.assertEqual(1, r.selectorList.length) + self.assertEqual(u'a', r.selectorText) + + r.selectorText = u' b, h1 ' + self.assertEqual(2, r.selectorList.length) + self.assertEqual(u'b, h1', r.selectorText) + + def test_style(self): + "CSSStyleRule.style" + d = cssutils.css.CSSStyleDeclaration() + self.r.style = d + self.assertEqual(d.cssText, self.r.style.cssText) + + # check if parentRule of d is set + self.assertEqual(self.r, d.parentRule) + + def test_incomplete(self): + "CSSStyleRule (incomplete)" + cssutils.ser.prefs.keepEmptyRules = True + tests = { + u'a {': u'a {}', # no } + u'a { font-family: "arial sans': # no "} + u'a {\n font-family: "arial sans"\n }', + u'a { font-family: "arial sans";': # no } + u'a {\n font-family: "arial sans"\n }', + u'''p { + color: green; + font-family: 'Courier New Times + color: red; + color: green; + }''': u'''p {\n color: green;\n color: green\n }''', + # no ; + u'''p { + color: green; + font-family: 'Courier New Times' + color: red; + color: green; + ''': u'''p {\n color: green;\n color: green\n }''' + } + self.do_equal_p(tests, raising=False) # parse + cssutils.ser.prefs.useDefaults() + +# TODO: def test_InvalidModificationErr(self): +# "CSSStyleRule.cssText InvalidModificationErr" +# self._test_InvalidModificationErr(u'@a a {}') + + def test_reprANDstr(self): + "CSSStyleRule.__repr__(), .__str__()" + sel=u'a > b + c' + + s = cssutils.css.CSSStyleRule(selectorText=sel) + + self.assert_(sel in str(s)) + + s2 = eval(repr(s)) + self.assert_(isinstance(s2, s.__class__)) + self.assert_(sel == s2.selectorText) + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_cssstylesheet.py cssutils-0.9.10/src/cssutils/tests/test_cssstylesheet.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_cssstylesheet.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_cssstylesheet.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,879 @@ +# -*- coding: utf-8 -*- +"""Tests for css.CSSStyleSheet""" + +import xml.dom +import basetest +import cssutils.css + +class CSSStyleSheetTestCase(basetest.BaseTestCase): + + def setUp(self): + super(CSSStyleSheetTestCase, self).setUp() + self.r = cssutils.css.CSSStyleSheet() # used by basetest + self.s = self.r # used here + self.rule = cssutils.css.CSSStyleRule() + + def tearDown(self): + cssutils.ser.prefs.useDefaults() + + def test_init(self): + "CSSStyleSheet.__init__()" + self.assertEqual('text/css', self.s.type) + self.assertEqual(False, self.s._readonly) + self.assertEqual([], self.s.cssRules) + self.assertEqual(False, self.s.disabled) + self.assertEqual(None, self.s.href) + self.assertEqual(None, self.s.media) + self.assertEqual(None, self.s.ownerNode) + self.assertEqual(None, self.s.parentStyleSheet) + self.assertEqual(u'', self.s.title) + + # check that type is readonly + self.assertRaises(AttributeError, self.r.__setattr__, 'href', 'x') + self.assertRaises(AttributeError, self.r.__setattr__, 'parentStyleSheet', 'x') + self.assertRaises(AttributeError, self.r.__setattr__, 'ownerNode', 'x') + self.assertRaises(AttributeError, self.r.__setattr__, 'type', 'x') + + def test_iter(self): + "CSSStyleSheet.__iter__()" + s = cssutils.css.CSSStyleSheet() + s.cssText = '''@import "x";@import "y";@namespace "u";''' + types = [cssutils.css.CSSRule.IMPORT_RULE, + cssutils.css.CSSRule.IMPORT_RULE, + cssutils.css.CSSRule.NAMESPACE_RULE] + for i, rule in enumerate(s): + self.assertEqual(rule, s.cssRules[i]) + self.assertEqual(rule.type, types[i]) + + def test_refs(self): + """CSSStylesheet references""" + s = cssutils.parseString('a {}') + rules = s.cssRules + self.assertEqual(s.cssRules[0].parentStyleSheet, s) + self.assertEqual(rules[0].parentStyleSheet, s) + + # set cssText + s.cssText = 'b{}' + + # from 0.9.7b1 + self.assertNotEqual(rules, s.cssRules) + + # set cssRules + s.cssRules = cssutils.parseString(''' + @charset "ascii"; + /**/ + @import "x"; + @namespace "http://example.com/ns0"; + @media all { + a { color: green; } + } + @font-face { + font-family: x; + } + @page { + font-family: Arial; + } + @x; + b {}').cssRules''').cssRules + # new object + self.assertNotEqual(rules, s.cssRules) + for i, r in enumerate(s.cssRules): + self.assertEqual(r.parentStyleSheet, s) + + # namespaces + s = cssutils.parseString('@namespace "http://example.com/ns1"; a {}') + namespaces = s.namespaces + self.assertEqual(s.namespaces.items(), [(u'', 'http://example.com/ns1')]) + s.cssText = '@namespace x "http://example.com/ns2"; x|a {}' + # not anymore! + self.assertNotEqual(namespaces, s.namespaces) + self.assertEqual(s.namespaces.items(), [(u'x', 'http://example.com/ns2')]) + + # variables + s = cssutils.parseString(u'@variables { a:1}') + vars1 = s.variables + self.assertEqual(vars1[u'a'], u'1') + + s = cssutils.parseString(u'@variables { a:2}') + vars2 = s.variables + self.assertNotEqual(vars1, vars2) + self.assertEqual(vars1[u'a'], u'1') + self.assertEqual(vars2[u'a'], u'2') + + def test_cssRules(self): + "CSSStyleSheet.cssRules" + s = cssutils.parseString('/*1*/a {x:1}') + self.assertEqual(2, s.cssRules.length) + del s.cssRules[0] + self.assertEqual(1, s.cssRules.length) + s.cssRules.append('/*2*/') + self.assertEqual(2, s.cssRules.length) + s.cssRules.extend(cssutils.parseString('/*3*/x {y:2}').cssRules) + self.assertEqual(4, s.cssRules.length) + self.assertEqual(u'a {\n x: 1\n }\n/*2*/\n/*3*/\nx {\n y: 2\n }'.encode(), + s.cssText) + + for r in s.cssRules: + self.assertEqual(r.parentStyleSheet, s) + + def test_cssText(self): + "CSSStyleSheet.cssText" + tests = { + '': ''.encode(), + # @charset + '@charset "ascii";\n@import "x";': + '@charset "ascii";\n@import "x";'.encode(), + '@charset "ascii";\n@media all {}': '@charset "ascii";'.encode(), + '@charset "ascii";\n@x;': '@charset "ascii";\n@x;'.encode(), + '@charset "ascii";\na {\n x: 1\n }': + '@charset "ascii";\na {\n x: 1\n }'.encode(), + # @import + '@x;\n@import "x";': '@x;\n@import "x";'.encode(), + '@import "x";\n@import "y";': '@import "x";\n@import "y";'.encode(), + '@import "x";\n@media all {}': '@import "x";'.encode(), + '@import "x";\n@x;': '@import "x";\n@x;'.encode(), + '@import "x";\na {\n x: 1\n }': + '@import "x";\na {\n x: 1\n }'.encode(), + # @namespace + '@x;\n@namespace a "x";': '@x;\n@namespace a "x";'.encode(), + '@namespace a "x";\n@namespace b "y";': + '@namespace a "x";\n@namespace b "y";'.encode(), + '@import "x";\n@namespace a "x";\n@media all {}': + '@import "x";\n@namespace a "x";'.encode(), + '@namespace a "x";\n@x;': '@namespace a "x";\n@x;'.encode(), + '@namespace a "x";\na {\n x: 1\n }': + '@namespace a "x";\na {\n x: 1\n }'.encode(), + """@namespace url("e1"); + @namespace url("e2"); + @namespace x url("x1"); + @namespace x url("x2"); + test{color: green} + x|test {color: green}""": """@namespace "e2"; +@namespace x "x2"; +test { + color: green + } +x|test { + color: green + }""".encode() +# ur'\1 { \2: \3 }': ur'''\x01 { +# \x02: \x03 +# }''', +# ur''' +# \@ { \@: \@ } +# \1 { \2: \3 } +# \{{\::\;;} +# ''': ur'''\@ { +# \@: \@ +# } +#\1 { +# \2: \3 +# } +#\{ +# {\:: \; +# }''' + } + self.do_equal_r(tests) + + tests = { + '': None, + # @charset + '@charset "ascii";\n@import "x";': None, + '@charset "ascii";\n@media all {}': '@charset "ascii";', + '@charset "ascii";\n@x;': None, + '@charset "ascii";\na {\n x: 1\n }': None, + # @import + '@x;\n@import "x";': None, + '@import "x";\n@import "y";': None, + '@import "x";\n@media all {}': '@import "x";', + '@import "x";\n@x;': None, + '@import "x";\na {\n x: 1\n }': None, + # @namespace + '@x;\n@namespace a "x";': None, + '@namespace a "x";\n@namespace b "y";': None, + '@import "x";\n@namespace a "x";\n@media all {}': + '@import "x";\n@namespace a "x";', + '@namespace a "x";\n@x;': None, + '@namespace a "x";\na {\n x: 1\n }': None, + """@namespace url("e1"); + @namespace url("e2"); + @namespace x url("x1"); + @namespace x url("x2"); + test{color: green} + x|test {color: green}""": """@namespace "e2"; +@namespace x "x2"; +test { + color: green + } +x|test { + color: green + }""" +# ur'\1 { \2: \3 }': ur'''\x01 { +# \x02: \x03 +# }''', +# ur''' +# \@ { \@: \@ } +# \1 { \2: \3 } +# \{{\::\;;} +# ''': ur'''\@ { +# \@: \@ +# } +#\1 { +# \2: \3 +# } +#\{ +# {\:: \; +# }''' + } + self.do_equal_p(tests) + + s = cssutils.css.CSSStyleSheet() + s.cssText = u'''@charset "ascii";@import "x";@namespace a "x"; + @media all {/*1*/}@page {margin: 0}a {\n x: 1\n }@unknown;/*comment*/''' + for r in s.cssRules: + self.assertEqual(s, r.parentStyleSheet) + + def test_cssText_HierarchyRequestErr(self): + "CSSStyleSheet.cssText HierarchyRequestErr" + tests = { + # @charset: only one and always 1st + u' @charset "utf-8";': xml.dom.HierarchyRequestErr, + u'@charset "ascii";@charset "ascii";': xml.dom.HierarchyRequestErr, u'/*c*/@charset "ascii";': xml.dom.HierarchyRequestErr, + u'@import "x"; @charset "ascii";': xml.dom.HierarchyRequestErr, + u'@namespace a "x"; @charset "ascii";': xml.dom.HierarchyRequestErr, + u'@media all {} @charset "ascii";': xml.dom.HierarchyRequestErr, + u'@page {} @charset "ascii";': xml.dom.HierarchyRequestErr, + u'a {} @charset "ascii";': xml.dom.HierarchyRequestErr, + + # @import: before @namespace, @media, @page, sr + u'@namespace a "x"; @import "x";': xml.dom.HierarchyRequestErr, + u'@media all {} @import "x";': xml.dom.HierarchyRequestErr, + u'@page {} @import "x";': xml.dom.HierarchyRequestErr, + u'a {} @import "x";': xml.dom.HierarchyRequestErr, + + # @namespace: before @media, @page, sr + u'@media all {} @namespace a "x";': xml.dom.HierarchyRequestErr, + u'@page {} @namespace a "x";': xml.dom.HierarchyRequestErr, + u'a {} @namespace a "x";': xml.dom.HierarchyRequestErr, + } + self.do_raise_r(tests) + self.do_raise_p(tests) + + def test_cssText_SyntaxErr(self): + """CSSStyleSheet.cssText SyntaxErr + + for single {, } or ; + """ + tests = { + u'{': xml.dom.SyntaxErr, + u'}': xml.dom.SyntaxErr, + u';': xml.dom.SyntaxErr, + u'@charset "ascii";{': xml.dom.SyntaxErr, + u'@charset "ascii";}': xml.dom.SyntaxErr, + u'@charset "ascii";;': xml.dom.SyntaxErr, + } + self.do_raise_r(tests) + self.do_raise_p(tests) + + def test_encoding(self): + "CSSStyleSheet.encoding" + self.s.cssText='' + self.assertEqual('utf-8', self.s.encoding) + + self.s.encoding = 'ascii' + self.assertEqual('ascii', self.s.encoding) + self.assertEqual(1, self.s.cssRules.length) + self.assertEqual('ascii', self.s.cssRules[0].encoding) + + self.s.encoding = None + self.assertEqual('utf-8', self.s.encoding) + self.assertEqual(0, self.s.cssRules.length) + + self.s.encoding = 'UTF-8' + self.assertEqual('utf-8', self.s.encoding) + self.assertEqual(1, self.s.cssRules.length) + + self.assertRaises(xml.dom.SyntaxErr, self.s._setEncoding, + 'INVALID ENCODING') + self.assertEqual('utf-8', self.s.encoding) + self.assertEqual(1, self.s.cssRules.length) + + def test_namespaces1(self): + "CSSStyleSheet.namespaces.namespaces" + # tests for namespaces internal methods + s = cssutils.css.CSSStyleSheet() + self.assertEqual(0, len(s.namespaces)) + + css = u'''@namespace "default"; +@namespace ex "example"; +@namespace ex2 "example"; +ex2|x { top: 0 }''' + expcss = u'''@namespace "default"; +@namespace ex2 "example"; +ex2|x { + top: 0 + }''' + s.cssText = css + self.assertEqual(s.cssText, expcss.encode()) + self.assertEqual(s.namespaces.namespaces, + { u'': u'default', u'ex2': u'example'}) + + # __contains__ + self.assertTrue('' in s.namespaces) + self.assertTrue('ex2' in s.namespaces) + self.assertFalse('NOTSET' in s.namespaces) + # __delitem__ + self.assertRaises(xml.dom.NoModificationAllowedErr, + s.namespaces.__delitem__, 'ex2') + s.namespaces['del'] = 'del' + del s.namespaces['del'] + self.assertRaises(xml.dom.NamespaceErr, s.namespaces.__getitem__, 'del') + # __getitem__ + self.assertEquals('default', s.namespaces['']) + self.assertEquals('example', s.namespaces['ex2']) + self.assertRaises(xml.dom.NamespaceErr, s.namespaces.__getitem__, 'UNSET') + # __iter__ + self.assertEquals(['', 'ex2'], list(s.namespaces)) + # __len__ + self.assertEqual(2, len(s.namespaces)) + # __setitem__ + self.assertRaises(xml.dom.NoModificationAllowedErr, + s.namespaces.__setitem__, 'ex2', 'NEWURI') + s.namespaces['n1'] = 'new' + self.assertEqual(s.namespaces.namespaces, + { u'': u'default', u'ex2': u'example', u'n1': 'new'}) + s.namespaces['n'] = 'new' # replaces prefix! + self.assertEqual(s.namespaces.namespaces, + { u'': u'default', u'ex2': u'example', u'n': 'new'}) + # prefixForNamespaceURI + self.assertEquals('', s.namespaces.prefixForNamespaceURI('default')) + self.assertEquals('ex2', s.namespaces.prefixForNamespaceURI('example')) + self.assertRaises(IndexError, + s.namespaces.prefixForNamespaceURI, 'UNSET') + # .keys + self.assertEqual(set(s.namespaces.keys()), set(['', 'ex2', 'n'])) + # .get + self.assertEqual('x', s.namespaces.get('UNKNOWN', 'x')) + self.assertEqual('example', s.namespaces.get('ex2', 'not used defa')) + + def test_namespaces2(self): + "CSSStyleSheet.namespaces" + # tests using CSSStyleSheet.namespaces + + s = cssutils.css.CSSStyleSheet() + css = '@namespace n "new";' + # doubles will be removed + s.insertRule(css + css) + self.assertEqual(s.cssText, css.encode()) + r = cssutils.css.CSSNamespaceRule(prefix='ex2', namespaceURI='example') + s.insertRule(r) + r = cssutils.css.CSSNamespaceRule(namespaceURI='default') + s.insertRule(r) + + expcss = '''@namespace n "new"; +@namespace ex2 "example"; +@namespace "default";''' + self.assertEqual(s.cssText, expcss.encode()) + r.prefix = 'DEFAULT' + expcss = '''@namespace n "new"; +@namespace ex2 "example"; +@namespace DEFAULT "default";''' + self.assertEqual(s.cssText, expcss.encode()) + + # CSSMediaRule + self.assertRaises(xml.dom.NamespaceErr, s.add, '@media all {x|a {left: 0}}') + mcss = '@media all {\n ex2|SEL1 {\n left: 0\n }\n }' + s.add(mcss) + expcss += '\n' + mcss + self.assertEqual(s.cssText, expcss.encode()) + + # CSSStyleRule + self.assertRaises(xml.dom.NamespaceErr, s.add, 'x|a {top: 0}') + scss = 'n|SEL2 {\n top: 0\n }' + s.add(scss) + expcss += '\n' + scss + self.assertEqual(s.cssText, expcss.encode()) + + mr = s.cssRules[3] + sr = s.cssRules[4] + + # SelectorList @media + self.assertRaises(xml.dom.NamespaceErr, + mr.cssRules[0]._setSelectorText, 'x|b') + oldsel, newsel = mr.cssRules[0].selectorText, 'n|SEL3, a' + mr.cssRules[0].selectorText = newsel + expcss = expcss.replace(oldsel, newsel) + self.assertEqual(s.cssText, expcss.encode()) + # SelectorList stylerule + self.assertRaises(xml.dom.NamespaceErr, + sr._setSelectorText, 'x|b') + oldsel, newsel = sr.selectorText, 'ex2|SEL4, a' + sr.selectorText = newsel + expcss = expcss.replace(oldsel, newsel) + self.assertEqual(s.cssText, expcss.encode()) + + # Selector @media + self.assertRaises(xml.dom.NamespaceErr, + mr.cssRules[0].selectorList.append, 'x|b') + oldsel, newsel = mr.cssRules[0].selectorText, 'ex2|SELMR' + mr.cssRules[0].selectorList.append(newsel) + expcss = expcss.replace(oldsel, oldsel + ', ' + newsel) + self.assertEqual(s.cssText, expcss.encode()) + # Selector stylerule + self.assertRaises(xml.dom.NamespaceErr, + sr.selectorList.append, 'x|b') + oldsel, newsel = sr.selectorText, 'ex2|SELSR' + sr.selectorList.append(newsel) + expcss = expcss.replace(oldsel, oldsel + ', ' + newsel) + self.assertEqual(s.cssText, expcss.encode()) + + self.assertEqual(s.cssText, u'''@namespace n "new"; +@namespace ex2 "example"; +@namespace DEFAULT "default"; +@media all { + n|SEL3, a, ex2|SELMR { + left: 0 + } + } +ex2|SEL4, a, ex2|SELSR { + top: 0 + }'''.encode()) + + def test_namespaces3(self): + "CSSStyleSheet.namespaces 3" + # tests setting namespaces with new {} + s = cssutils.css.CSSStyleSheet() + css = u'h|a { top: 0 }' + self.assertRaises(xml.dom.NamespaceErr, s.add, css) + + s.add('@namespace x "html";') + self.assert_(s.namespaces['x'] == 'html') + + r = cssutils.css.CSSStyleRule() + r.cssText = ((css, {'h': 'html'})) + s.add(r) # uses x as set before! h is temporary only + self.assertEqual(s.cssText, '@namespace x "html";\nx|a {\n top: 0\n }'.encode()) + + # prefix is now "x"! + self.assertRaises(xml.dom.NamespaceErr, r.selectorList.append, 'h|b') + self.assertRaises(xml.dom.NamespaceErr, r.selectorList.append, 'y|b') + s.namespaces['y'] = 'html' + r.selectorList.append('y|b') + self.assertEqual(s.cssText, + u'@namespace y "html";\ny|a, y|b {\n top: 0\n }'.encode()) + + self.assertRaises(xml.dom.NoModificationAllowedErr, + s.namespaces.__delitem__, 'y') + self.assertEqual(s.cssText, + u'@namespace y "html";\ny|a, y|b {\n top: 0\n }'.encode()) + + s.cssRules[0].prefix = '' + self.assertEqual(s.cssText, + u'@namespace "html";\na, b {\n top: 0\n }'.encode()) + + # remove need of namespace + s.cssRules[0].prefix = 'x' + s.cssRules[1].selectorText = 'a, b' + self.assertEqual(s.cssText, + u'@namespace x "html";\na, b {\n top: 0\n }'.encode()) + + + def test_namespaces4(self): + "CSSStyleSheet.namespaces 4" + # tests setting namespaces with new {} + s = cssutils.css.CSSStyleSheet() + self.assertEqual({}, s.namespaces.namespaces) + + s.namespaces.namespaces['a'] = 'no setting possible' + self.assertEqual({}, s.namespaces.namespaces) + + s.namespaces[None] = 'default' + self.assertEqual({u'': 'default'}, s.namespaces.namespaces) + + del s.namespaces[''] + self.assertEqual({}, s.namespaces.namespaces) + + s.namespaces[''] = 'default' + self.assertEqual({u'': 'default'}, s.namespaces.namespaces) + + del s.namespaces[None] + self.assertEqual({}, s.namespaces.namespaces) + + s.namespaces['p'] = 'uri' + # cannot use namespaces.namespaces + del s.namespaces.namespaces['p'] + self.assertEqual({u'p': 'uri'}, s.namespaces.namespaces) + + self.assertRaisesMsg(xml.dom.NamespaceErr, u"Prefix undefined not found.", + s.namespaces.__delitem__, 'undefined') + + def test_namespaces5(self): + "CSSStyleSheet.namespaces 5" + # unknown namespace + s = cssutils.parseString('a|a { color: red }') + self.assertEqual(s.cssText, ''.encode()) + + s = cssutils.css.CSSStyleSheet() + self.assertRaisesMsg(xml.dom.NamespaceErr, "Prefix a not found.", + s._setCssText, 'a|a { color: red }') + + def test_deleteRuleIndex(self): + "CSSStyleSheet.deleteRule(index)" + self.s.cssText = u'@charset "ascii"; @import "x"; @x; a {\n x: 1\n }@y;' + self.assertEqual(5, self.s.cssRules.length) + + self.assertRaises(xml.dom.IndexSizeErr, self.s.deleteRule, 5) + + # end -1 + # check parentStyleSheet + r = self.s.cssRules[-1] + self.assertEqual(self.s, r.parentStyleSheet) + self.s.deleteRule(-1) + self.assertEqual(None, r.parentStyleSheet) + + self.assertEqual(4, self.s.cssRules.length) + self.assertEqual( + u'@charset "ascii";\n@import "x";\n@x;\na {\n x: 1\n }'.encode(), self.s.cssText) + # beginning + self.s.deleteRule(0) + self.assertEqual(3, self.s.cssRules.length) + self.assertEqual(u'@import "x";\n@x;\na {\n x: 1\n }'.encode(), self.s.cssText) + # middle + self.s.deleteRule(1) + self.assertEqual(2, self.s.cssRules.length) + self.assertEqual(u'@import "x";\na {\n x: 1\n }'.encode(), self.s.cssText) + # end + self.s.deleteRule(1) + self.assertEqual(1, self.s.cssRules.length) + self.assertEqual(u'@import "x";'.encode(), self.s.cssText) + + def test_deleteRule(self): + "CSSStyleSheet.deleteRule(rule)" + s = cssutils.css.CSSStyleSheet() + s.cssText=''' + @namespace x "http://example.com"; + a { color: red; } + b { color: blue; } + c { color: green; } + ''' + n, s1, s2, s3 = s.cssRules + + r = cssutils.css.CSSStyleRule() + self.assertRaises(xml.dom.IndexSizeErr, s.deleteRule, r) + + self.assertEqual(4, s.cssRules.length) + s.deleteRule(n) + self.assertEqual(3, s.cssRules.length) + self.assertEqual(s.cssText, 'a {\n color: red\n }\nb {\n color: blue\n }\nc {\n color: green\n }'.encode()) + self.assertRaises(xml.dom.IndexSizeErr, s.deleteRule, n) + s.deleteRule(s2) + self.assertEqual(2, s.cssRules.length) + self.assertEqual(s.cssText, 'a {\n color: red\n }\nc {\n color: green\n }'.encode()) + self.assertRaises(xml.dom.IndexSizeErr, s.deleteRule, s2) + + def _gets(self): + # complete + self.cr = cssutils.css.CSSCharsetRule('ascii') + self.c = cssutils.css.CSSComment(u'/*c*/') + self.ur = cssutils.css.CSSUnknownRule('@x;') + self.ir = cssutils.css.CSSImportRule('x') + self.nr = cssutils.css.CSSNamespaceRule('uri', 'p') + self.mr = cssutils.css.CSSMediaRule() + self.mr.cssText = u'@media all { @m; }' + self.pr = cssutils.css.CSSPageRule() + self.pr.style = u'margin: 0;' + self.sr = cssutils.css.CSSStyleRule() + self.sr.cssText = 'a {\n x: 1\n }' + + s = cssutils.css.CSSStyleSheet() + s.insertRule(self.cr) # 0 + s.insertRule(self.ir) # 1 + s.insertRule(self.nr) # 2 + s.insertRule(self.mr) # 3 + s.insertRule(self.sr) # 4 + s.insertRule(self.mr) # 5 + s.insertRule(self.pr) # 6 + s.insertRule(self.sr) # 7 + self.assertEqual(u'@charset "ascii";\n@import url(x);\n@namespace p "uri";\n@media all {\n @m;\n }\na {\n x: 1\n }\n@media all {\n @m;\n }\n@page {\n margin: 0\n }\na {\n x: 1\n }'.encode(), s.cssText) + return s, s.cssRules.length + + def test_add(self): + "CSSStyleSheet.add()" + full = cssutils.css.CSSStyleSheet() + sheet = cssutils.css.CSSStyleSheet() + css = ['@charset "ascii";', + '@import "x";', + '@namespace p "u";', + '@page {\n left: 0\n }', + '@font-face {\n src: local(x)\n }', + '@media all {\n a {\n color: red\n }\n }', + 'a {\n color: green\n }', + '/*comment*/', + '@x;' + ] + + fullcss = u'\n'.join(css) + full.cssText = fullcss + self.assertEqual(full.cssText, fullcss.encode()) + for i, line in enumerate(css): + # sheet without same ruletype + before = css[:i] + after = css[i+1:] + sheet.cssText = u''.join(before + after) + + index = sheet.add(line) + if i < 3: + # specific insertion point + self.assertEqual(fullcss.encode(), sheet.cssText) + self.assertEqual(i, index) + else: + # end of sheet + expected = before + expected.extend(after) + expected.append(line) + self.assertEqual(u'\n'.join(expected).encode(), sheet.cssText) + self.assertEqual(len(expected)-1, index) # no same rule present + + # sheet with the same ruletype + if i == 1: line = '@import "x2";' + if i == 2: line = '@namespace p2 "u2";' + + full.cssText = fullcss + index = full.add(line) + if i < 1: + self.assertEqual(fullcss.encode(), sheet.cssText) + self.assertEqual(i, index) # no same rule present + else: + if i < 3: + # in order + expected = css[:i+1] # including same rule + expected.append(line) + expected.extend(css[i+1:]) + expectedindex = i+1 + else: + # just appended as no order needed + expected = css[:] + expected.append(line) + expectedindex = len(expected) - 1 + + self.assertEqual(u'\n'.join(expected).encode(), full.cssText) + self.assertEqual(expectedindex, index) # no same rule present + + def test_addimport(self): + p = cssutils.CSSParser(fetcher=lambda url: (None, '/**/')) + + cssrulessheet = p.parseString('@import "example.css";') + imports = ( + '@import "example.css";', # string + cssutils.css.CSSImportRule(href="example.css"), # CSSRule + cssrulessheet.cssRules # CSSRuleList + ) + for imp in imports: + sheet = p.parseString('', href='http://example.com') + sheet.add(imp) + added = sheet.cssRules[0] + self.assertEqual(sheet, added.parentStyleSheet) + self.assertEqual(u'example.css', added.href) + self.assertEqual(u'utf-8', added.styleSheet.encoding) + self.assertEqual(u'/**/'.encode(), added.styleSheet.cssText) + + cssrulessheet = p.parseString('@import "example.css";') + imports = ( + ('@import "example.css";', 'ascii'), # string + (cssutils.css.CSSImportRule(href="example.css"), 'ascii'), # CSSRule + # got encoding from old parent already + (cssrulessheet.cssRules, 'utf-8') # CSSRuleList + ) + for imp, enc in imports: + sheet = p.parseString('', href='http://example.com', encoding='ascii') + sheet.add(imp) + added = sheet.cssRules[1] + self.assertEqual(sheet, added.parentStyleSheet) + self.assertEqual(u'example.css', added.href) + self.assertEqual(enc, added.styleSheet.encoding) + if enc == 'ascii': + self.assertEqual(u'@charset "ascii";\n/**/'.encode(), added.styleSheet.cssText) + else: + self.assertEqual(u'/**/'.encode(), added.styleSheet.cssText) + + # if styleSheet is already there encoding is not set new + impsheet = p.parseString('@import "example.css";') + imp = impsheet.cssRules[0] + sheet = p.parseString('', href='http://example.com', encoding='ascii') + sheet.add(imp) + added = sheet.cssRules[1] + self.assertEqual(sheet, added.parentStyleSheet) + self.assertEqual(u'example.css', added.href) + self.assertEqual(u'utf-8', added.styleSheet.encoding) + self.assertEqual(u'/**/'.encode(), added.styleSheet.cssText) + + def test_insertRule(self): + "CSSStyleSheet.insertRule()" + s, L = self._gets() + + # INVALID index + self.assertRaises(xml.dom.IndexSizeErr, + s.insertRule, self.sr, -1) + self.assertRaises(xml.dom.IndexSizeErr, + s.insertRule, self.sr, s.cssRules.length + 1) + # check if rule is really not in + self.assertEqual(L, s.cssRules.length) + + # insert string + s.insertRule('a {}') + self.assertEqual(L+1, s.cssRules.length) + # insert rule + s.insertRule(self.sr) + self.assertEqual(L+2, s.cssRules.length) + # insert rulelist + s2, L2 = self._gets() + rulelist = s2.cssRules + del rulelist[:-2] + s.insertRule(rulelist) + self.assertEqual(L+2 + 2, s.cssRules.length) + + def _insertRule(self, rules, notbefore, notafter, anywhere, + checkdoubles=True): + """ + helper + test if any rule in rules cannot be inserted before rules in before + or after rules in after but before and after rules in anywhere + """ + for rule in rules: + for r in notbefore: + s = cssutils.css.CSSStyleSheet() + s.insertRule(r) + self.assertRaises(xml.dom.HierarchyRequestErr, + s.insertRule, rule, 0) + s = cssutils.css.CSSStyleSheet() + s.add(r) + self.assertRaises(xml.dom.HierarchyRequestErr, + s.insertRule, rule, 0) + for r in notafter: + s = cssutils.css.CSSStyleSheet() + s.insertRule(r) + self.assertRaises(xml.dom.HierarchyRequestErr, + s.insertRule, rule, 1) + s = cssutils.css.CSSStyleSheet() + s.add(r) + s.add(rule) # never raises + self.assertEqual(s, r.parentStyleSheet) + + for r in anywhere: + s = cssutils.css.CSSStyleSheet() + s.insertRule(r) + s.insertRule(rule, 0) # before + s.insertRule(rule) # after + if checkdoubles: + self.assertEqual(s.cssRules.length, 3) + self.assertEqual(s, r.parentStyleSheet) + + def test_insertRule_charset(self): + "CSSStyleSheet.insertRule(@charset)" + s, L = self._gets() + notbefore = (self.cr,) + notafter = (self.cr, self.ir, self.nr, self.mr, self.pr, self.sr, + self.c, self.ur) + anywhere = () + self._insertRule((self.cr,), + notbefore, notafter, anywhere) + + def test_insertRule_import(self): + "CSSStyleSheet.insertRule(@import)" + s, L = self._gets() + notbefore = (self.cr,) + notafter = (self.nr, self.pr, self.mr, self.sr) + anywhere = (self.c, self.ur, self.ir) + self._insertRule((self.ir,), + notbefore, notafter, anywhere) + + def test_insertRule_namespace(self): + "CSSStyleSheet.insertRule(@namespace)" + s, L = self._gets() + notbefore = (self.cr, self.ir) + notafter = (self.pr, self.mr, self.sr) + anywhere = (self.c, self.ur, self.nr) + self._insertRule((self.nr,), notbefore, notafter, anywhere, + checkdoubles=False) + + def test_insertRule_media_page_style(self): + "CSSStyleSheet.insertRule(@media, @page, stylerule)" + s, L = self._gets() + notbefore = (self.cr, self.ir, self.nr) + notafter = () + anywhere = (self.c, self.ur, self.mr, self.pr, self.sr) + self._insertRule((self.pr, self.mr, self.sr), + notbefore, notafter, anywhere) + + def test_insertRule_unknownandcomment(self): + "CSSStyleSheet.insertRule(@ unknown, comment)" + s, L = self._gets() + notbefore = (self.cr,) + notafter = () + anywhere = (self.c, self.ur, self.ir, self.nr, self.mr, self.pr, + self.sr) + self._insertRule((self.ur,), + notbefore, notafter, anywhere) + + def test_HTMLComments(self): + "CSSStyleSheet CDO CDC" + css = u'''body { color: red } + +body { color: blue } +body { color: pink } + +body { color: green } +''' + exp = u'''body { + color: red + } +body { + color: pink + }''' + sheet = cssutils.parseString(css) + self.assertEqual(sheet.cssText, exp.encode()) + + def test_incomplete(self): + "CSSStyleRule (incomplete)" + tests = { + u'@import "a': u'@import "a";', # no } + u'a { x: 1': u'a {\n x: 1\n }', # no } + u'a { font-family: "arial sans': # no " + u'a {\n font-family: "arial sans"\n }', + } + self.do_equal_p(tests) # parse + + def test_NoModificationAllowedErr(self): + "CSSStyleSheet NoModificationAllowedErr" + css = cssutils.css.CSSStyleSheet(readonly=True) + + self.assertEqual(True, css._readonly) # internal... + + self.assertRaises(xml.dom.NoModificationAllowedErr, + css._setCssText, u'@x;') + self.assertRaises(xml.dom.NoModificationAllowedErr, + css.insertRule, self.rule) + self.assertRaises(xml.dom.NoModificationAllowedErr, + css.insertRule, self.rule, 0) + self.assertRaises(xml.dom.NoModificationAllowedErr, + css.deleteRule, 0) + + def test_reprANDstr(self): + "CSSStyleSheet.__repr__(), .__str__()" + href = 'file:foo.css' + title = 'title-of-css' + + s = cssutils.css.CSSStyleSheet(href=href, title=title) + + self.assert_(href in str(s)) + self.assert_(title in str(s)) + + s2 = eval(repr(s)) + self.assert_(isinstance(s2, s.__class__)) + self.assert_(href == s2.href) + self.assert_(title == s2.title) + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_cssunknownrule.py cssutils-0.9.10/src/cssutils/tests/test_cssunknownrule.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_cssunknownrule.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_cssunknownrule.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,151 @@ +"""testcases for cssutils.css.CSSUnkownRule""" + +import xml.dom +import test_cssrule +import cssutils + +class CSSUnknownRuleTestCase(test_cssrule.CSSRuleTestCase): + + def setUp(self): + super(CSSUnknownRuleTestCase, self).setUp() + self.r = cssutils.css.CSSUnknownRule() + self.rRO = cssutils.css.CSSUnknownRule(readonly=True) + self.r_type = cssutils.css.CSSUnknownRule.UNKNOWN_RULE + self.r_typeString = 'UNKNOWN_RULE' + + def tearDown(self): + cssutils.ser.prefs.useDefaults() + + def test_init(self): + "CSSUnknownRule.type and init" + super(CSSUnknownRuleTestCase, self).test_init() + + self.assertFalse(self.r.wellformed) + + # only name + r = cssutils.css.CSSUnknownRule(cssText=u'@init;') + self.assertEqual(u'@init', r.atkeyword) + self.assertEqual(u'@init;', r.cssText) + self.assertTrue(r.wellformed) + + # @-... not allowed? + r = cssutils.css.CSSUnknownRule(cssText=u'@-init;') + self.assertEqual(u'@-init;', r.cssText) + self.assertEqual(u'@-init', r.atkeyword) + self.assertTrue(r.wellformed) + + r = cssutils.css.CSSUnknownRule(cssText=u'@_w-h-a-012;') + self.assertEqual(u'@_w-h-a-012;', r.cssText) + self.assertEqual(u'@_w-h-a-012', r.atkeyword) + self.assertTrue(r.wellformed) + + # name and content + r = cssutils.css.CSSUnknownRule(cssText=u'@init xxx;') + self.assertEqual(u'@init', r.atkeyword) + self.assertEqual(u'@init xxx;', r.cssText) + self.assertTrue(r.wellformed) + + # name and block + r = cssutils.css.CSSUnknownRule(cssText=u'@init { xxx }') + self.assertEqual(u'@init', r.atkeyword) + self.assertEqual(u'@init {\n xxx\n }', r.cssText) + self.assertTrue(r.wellformed) + + # name and content and block + r = cssutils.css.CSSUnknownRule(cssText=u'@init xxx { yyy }') + self.assertEqual(u'@init', r.atkeyword) + self.assertEqual(u'@init xxx {\n yyy\n }', r.cssText) + self.assertTrue(r.wellformed) + + def test_cssText(self): + "CSSUnknownRule.cssText" + tests = { + # not normal rules! + u'@font-facex{}': u'@font-facex {\n }', + u'@importurl(x.css);': u'@importurl (x . css);', + u'@mediaAll{}': u'@mediaall {\n }', + u'@namespacep"x";': u'@namespacep "x";', + u'@pageX{}': u'@pagex {\n }', + u'@xbottom { content: counter(page) }': u'@xbottom {\n content: counter(page)\n }', + u'@xbottom { content: "x" counter(page) "y"}': u'@xbottom {\n content: "x" counter(page) "y"\n }' + } + self.do_equal_p(tests) + + # expects the same atkeyword for self.r so do a new one each test + oldr = self.r + for t, e in tests.items(): + self.r = cssutils.css.CSSUnknownRule() + self.do_equal_r({t:e}) + self.r = oldr + + tests = { + '@x;': None, + '@x {}': u'@x {\n }', + '@x{ \n \t \f\r}': u'@x {\n }', + '@x {\n [()]([ {\n }]) {\n }\n }': None, + '@x {\n @b;\n }': None, + '''@x { + @b { + x: 1x; + y: 2y; + } + }''': None, + '@x "string" url(x);': None, + + # comments + '@x/*1*//*2*/"str"/*3*//*4*/url("x");': + '@x /*1*/ /*2*/ "str" /*3*/ /*4*/ url(x);', + # WS + '@x"string"url("x");': '@x "string" url(x);', + '@x\n\r\t\f "string"\n\r\t\f url(\n\r\t\f "x"\n\r\t\f )\n\r\t\f ;': + '@x "string" url(x);', + } + self.do_equal_p(tests) + self.do_equal_r(tests) + + tests = { + u'@;': xml.dom.InvalidModificationErr, + u'@{}': xml.dom.InvalidModificationErr, + u'@ ;': xml.dom.InvalidModificationErr, + u'@ {};': xml.dom.InvalidModificationErr, + + u'@x ;{}': xml.dom.SyntaxErr, + u'@x ;;': xml.dom.SyntaxErr, + u'@x } ': xml.dom.SyntaxErr, + u'@x } ;': xml.dom.SyntaxErr, + u'@x { ': xml.dom.SyntaxErr, + u'@x { ;': xml.dom.SyntaxErr, + u'@x ': xml.dom.SyntaxErr, + u'@x (;': xml.dom.SyntaxErr, + u'@x );': xml.dom.SyntaxErr, + u'@x [;': xml.dom.SyntaxErr, + u'@x ];': xml.dom.SyntaxErr, + u'@x {[(]()}': xml.dom.SyntaxErr, + # trailing + u'@x{}{}': xml.dom.SyntaxErr, + u'@x{};': xml.dom.SyntaxErr, + u'@x{}1': xml.dom.SyntaxErr, + u'@x{} ': xml.dom.SyntaxErr, + u'@x{}/**/': xml.dom.SyntaxErr, + u'@x;1': xml.dom.SyntaxErr, + u'@x; ': xml.dom.SyntaxErr, + u'@x;/**/': xml.dom.SyntaxErr, + + } + self.do_raise_r(tests) + + def test_InvalidModificationErr(self): + "CSSUnknownRule.cssText InvalidModificationErr" + self._test_InvalidModificationErr(u'@unknown') + + def test_reprANDstr(self): + "CSSUnknownRule.__repr__(), .__str__()" + s = cssutils.css.CSSUnknownRule(cssText='@x;') + + s2 = eval(repr(s)) + self.assert_(isinstance(s2, s.__class__)) + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_cssutils.py cssutils-0.9.10/src/cssutils/tests/test_cssutils.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_cssutils.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_cssutils.py 2013-03-31 19:50:42.000000000 +0000 @@ -0,0 +1,426 @@ +# -*- coding: utf-8 -*- +"""Testcases for cssutils.css.CSSCharsetRule""" +from __future__ import with_statement + +import basetest +import codecs +import cssutils +import os +import sys +import tempfile +import xml.dom + +try: + import mock +except ImportError: + mock = None + print "install mock library to run all tests" + + +class CSSutilsTestCase(basetest.BaseTestCase): + + def setUp(self): + cssutils.ser.prefs.useDefaults() + + def tearDown(self): + cssutils.ser.prefs.useDefaults() + + exp = u'''@import "import/import2.css"; +.import { + /* ./import.css */ + background-image: url(images/example.gif) + }''' + + def test_VERSION(self): + self.assertEqual('0.9.10', cssutils.VERSION) + + def test_parseString(self): + "cssutils.parseString()" + s = cssutils.parseString(self.exp, + media='handheld, screen', + title='from string') + self.assert_(isinstance(s, cssutils.css.CSSStyleSheet)) + self.assertEqual(None, s.href) + self.assertEqual(self.exp.encode(), s.cssText) + self.assertEqual(u'utf-8', s.encoding) + self.assertEqual(u'handheld, screen', s.media.mediaText) + self.assertEqual(u'from string', s.title) + self.assertEqual(self.exp.encode(), s.cssText) + + ir = s.cssRules[0] + self.assertEqual('import/import2.css', ir.href) + irs = ir.styleSheet + self.assertEqual(cssutils.css.CSSStyleSheet, type(irs)) + + href = os.path.join(os.path.dirname(__file__), + '..', '..', '..', 'sheets', 'import.css') + href = cssutils.helper.path2url(href) + s = cssutils.parseString(self.exp, + href=href) + self.assertEqual(href, s.href) + + ir = s.cssRules[0] + self.assertEqual('import/import2.css', ir.href) + irs = ir.styleSheet + self.assert_(isinstance(irs, cssutils.css.CSSStyleSheet)) + self.assertEqual(irs.cssText, '@import "../import3.css";\n@import "import-impossible.css" print;\n.import2 {\n /* sheets/import2.css */\n background: url(http://example.com/images/example.gif);\n background: url(//example.com/images/example.gif);\n background: url(/images/example.gif);\n background: url(images2/example.gif);\n background: url(./images2/example.gif);\n background: url(../images/example.gif);\n background: url(./../images/example.gif)\n }'.encode()) + + tests = { + 'a {color: red}': u'a {\n color: red\n }', + 'a {color: rgb(1,2,3)}': u'a {\n color: rgb(1, 2, 3)\n }' + } + self.do_equal_p(tests) + + def test_parseFile(self): + "cssutils.parseFile()" + # name if used with open, href used for @import resolving + name = os.path.join(os.path.dirname(__file__), + '..', '..', '..', 'sheets', 'import.css') + href = cssutils.helper.path2url(name) + + s = cssutils.parseFile(name, href=href, media='screen', title='from file') + self.assert_(isinstance(s, cssutils.css.CSSStyleSheet)) + if sys.platform.startswith('java'): + # on Jython only file: + self.assert_(s.href.startswith('file:')) + else: + # normally file:/// on win and file:/ on unix + self.assert_(s.href.startswith('file:/')) + self.assert_(s.href.endswith('/sheets/import.css')) + self.assertEqual(u'utf-8', s.encoding) + self.assertEqual(u'screen', s.media.mediaText) + self.assertEqual(u'from file', s.title) + self.assertEqual(self.exp.encode(), s.cssText) + + ir = s.cssRules[0] + self.assertEqual('import/import2.css', ir.href) + irs = ir.styleSheet + self.assert_(isinstance(irs, cssutils.css.CSSStyleSheet)) + self.assertEqual(irs.cssText, '@import "../import3.css";\n@import "import-impossible.css" print;\n.import2 {\n /* sheets/import2.css */\n background: url(http://example.com/images/example.gif);\n background: url(//example.com/images/example.gif);\n background: url(/images/example.gif);\n background: url(images2/example.gif);\n background: url(./images2/example.gif);\n background: url(../images/example.gif);\n background: url(./../images/example.gif)\n }'.encode()) + + # name is used for open and setting of href automatically + # test needs to be relative to this test file! + os.chdir(os.path.dirname(__file__)) + name = os.path.join('..', '..', '..', 'sheets', 'import.css') + + s = cssutils.parseFile(name, media='screen', title='from file') + self.assert_(isinstance(s, cssutils.css.CSSStyleSheet)) + if sys.platform.startswith('java'): + # on Jython only file: + self.assert_(s.href.startswith('file:')) + else: + # normally file:/// on win and file:/ on unix + self.assert_(s.href.startswith('file:/')) + self.assert_(s.href.endswith('/sheets/import.css')) + self.assertEqual(u'utf-8', s.encoding) + self.assertEqual(u'screen', s.media.mediaText) + self.assertEqual(u'from file', s.title) + self.assertEqual(self.exp.encode(), s.cssText) + + ir = s.cssRules[0] + self.assertEqual('import/import2.css', ir.href) + irs = ir.styleSheet + self.assert_(isinstance(irs, cssutils.css.CSSStyleSheet)) + self.assertEqual(irs.cssText, '@import "../import3.css";\n@import "import-impossible.css" print;\n.import2 {\n /* sheets/import2.css */\n background: url(http://example.com/images/example.gif);\n background: url(//example.com/images/example.gif);\n background: url(/images/example.gif);\n background: url(images2/example.gif);\n background: url(./images2/example.gif);\n background: url(../images/example.gif);\n background: url(./../images/example.gif)\n }'.encode()) + + # next test + css = u'a:after { content: "羊蹄€\u2020" }' + + fd, name = tempfile.mkstemp('_cssutilstest.css') + t = os.fdopen(fd, 'wb') + t.write(css.encode('utf-8')) + t.close() + + self.assertRaises(UnicodeDecodeError, cssutils.parseFile, name, 'ascii') + + # ??? + s = cssutils.parseFile(name, encoding='iso-8859-1') + self.assertEqual(cssutils.css.CSSStyleSheet, type(s)) + self.assertEqual(s.cssRules[1].selectorText, 'a:after') + + s = cssutils.parseFile(name, encoding='utf-8') + self.assertEqual(cssutils.css.CSSStyleSheet, type(s)) + self.assertEqual(s.cssRules[1].selectorText, 'a:after') + + css = u'@charset "iso-8859-1"; a:after { content: "ä" }' + t = codecs.open(name, 'w', 'iso-8859-1') + t.write(css) + t.close() + + self.assertRaises( + UnicodeDecodeError, cssutils.parseFile, name, 'ascii') + + s = cssutils.parseFile(name, encoding='iso-8859-1') + self.assertEqual(cssutils.css.CSSStyleSheet, type(s)) + self.assertEqual(s.cssRules[1].selectorText, 'a:after') + + self.assertRaises( + UnicodeDecodeError, cssutils.parseFile, name, 'utf-8') + + # clean up + try: + os.remove(name) + except OSError, e: + pass + + def test_parseUrl(self): + "cssutils.parseUrl()" + href = os.path.join(os.path.dirname(__file__), + '..', '..', '..', 'sheets', 'import.css') + #href = u'file:' + urllib.pathname2url(href) + href = cssutils.helper.path2url(href) + #href = 'http://seewhatever.de/sheets/import.css' + s = cssutils.parseUrl(href, + media='tv, print', + title='from url') + self.assert_(isinstance(s, cssutils.css.CSSStyleSheet)) + self.assertEqual(href, s.href) + self.assertEqual(self.exp.encode(), s.cssText) + self.assertEqual(u'utf-8', s.encoding) + self.assertEqual(u'tv, print', s.media.mediaText) + self.assertEqual('from url', s.title) + + sr = s.cssRules[1] + img = sr.style.getProperty('background-image').propertyValue[0].value + self.assertEqual(img, 'images/example.gif') + + ir = s.cssRules[0] + self.assertEqual(u'import/import2.css', ir.href) + irs = ir.styleSheet + self.assertEqual(irs.cssText, '@import "../import3.css";\n@import "import-impossible.css" print;\n.import2 {\n /* sheets/import2.css */\n background: url(http://example.com/images/example.gif);\n background: url(//example.com/images/example.gif);\n background: url(/images/example.gif);\n background: url(images2/example.gif);\n background: url(./images2/example.gif);\n background: url(../images/example.gif);\n background: url(./../images/example.gif)\n }'.encode()) + + ir2 = irs.cssRules[0] + self.assertEqual(u'../import3.css', ir2.href) + irs2 = ir2.styleSheet + self.assertEqual(irs2.cssText, '/* import3 */\n.import3 {\n /* from ./import/../import3.css */\n background: url(images/example3.gif);\n background: url(./images/example3.gif);\n background: url(import/images2/example2.gif);\n background: url(./import/images2/example2.gif);\n background: url(import/images2/../../images/example3.gif)\n }'.encode()) + + def test_setCSSSerializer(self): + "cssutils.setSerializer() and cssutils.ser" + s = cssutils.parseString('a { left: 0 }') + exp4 = '''a { + left: 0 + }''' + exp1 = '''a { + left: 0 + }''' + self.assertEqual(exp4.encode(), s.cssText) + newser = cssutils.CSSSerializer(cssutils.serialize.Preferences(indent=' ')) + cssutils.setSerializer(newser) + self.assertEqual(exp1.encode(), s.cssText) + newser = cssutils.CSSSerializer(cssutils.serialize.Preferences(indent=' ')) + cssutils.ser = newser + self.assertEqual(exp4.encode(), s.cssText) + + def test_parseStyle(self): + "cssutils.parseStyle()" + s = cssutils.parseStyle('x:0; y:red') + self.assertEqual(type(s), cssutils.css.CSSStyleDeclaration) + self.assertEqual(s.cssText, u'x: 0;\ny: red') + + s = cssutils.parseStyle('@import "x";') + self.assertEqual(type(s), cssutils.css.CSSStyleDeclaration) + self.assertEqual(s.cssText, u'') + + tests = [ + (u'content: "ä"', 'iso-8859-1'), + (u'content: "€"', 'utf-8') + ] + for v, e in tests: + s = cssutils.parseStyle(v.encode(e), encoding=e) + self.assertEqual(s.cssText, v) + + self.assertRaises(UnicodeDecodeError, cssutils.parseStyle, + u'content: "ä"'.encode('utf-8'), 'ascii') + + + def test_getUrls(self): + "cssutils.getUrls()" + cssutils.ser.prefs.keepAllProperties = True + + css=''' + @import "im1"; + @import url(im2); + @import url( im3 ); + @import url( "im4" ); + @import url( 'im5' ); + a { + background-image: url(a) !important; + background-\image: url(b); + background: url(c) no-repeat !important; + /* issue #46 */ + src: local("xx"), + url("f.woff") format("woff"), + url("f.otf") format("opentype"), + url("f.svg#f") format("svg"); + }''' + urls = set(cssutils.getUrls(cssutils.parseString(css))) + self.assertEqual(urls, set(["im1", "im2", "im3", "im4", "im5", + "a", "b", "c", + u'f.woff', u'f.svg#f', u'f.otf'])) + cssutils.ser.prefs.keepAllProperties = False + + def test_replaceUrls(self): + "cssutils.replaceUrls()" + cssutils.ser.prefs.keepAllProperties = True + + css=''' + @import "im1"; + @import url(im2); + a { + background-image: url(c) !important; + background-\image: url(b); + background: url(a) no-repeat !important; + }''' + s = cssutils.parseString(css) + cssutils.replaceUrls(s, lambda old: "NEW" + old) + self.assertEqual(u'@import "NEWim1";', s.cssRules[0].cssText) + self.assertEqual(u'NEWim2', s.cssRules[1].href) + self.assertEqual(u'''background-image: url(NEWc) !important; +background-\\image: url(NEWb); +background: url(NEWa) no-repeat !important''', s.cssRules[2].style.cssText) + + cssutils.ser.prefs.keepAllProperties = False + + # CSSStyleDeclaration + style = cssutils.parseStyle(u'''color: red; + background-image: + url(1.png), + url('2.png')''') + cssutils.replaceUrls(style, lambda url: 'prefix/'+url) + self.assertEqual(style.cssText, u'''color: red; +background-image: url(prefix/1.png), url(prefix/2.png)''') + + + def test_resolveImports(self): + "cssutils.resolveImports(sheet)" + if mock: + self._tempSer() + cssutils.ser.prefs.useMinified() + + a = u'@charset "iso-8859-1";@import"b.css";\xe4{color:green}'.encode('iso-8859-1') + b = u'@charset "ascii";\\E4 {color:red}'.encode('ascii') + + # normal + m = mock.Mock() + with mock.patch('cssutils.util._defaultFetcher', m): + m.return_value = (None, b) + s = cssutils.parseString(a) + + # py3 TODO + self.assertEqual(a, s.cssText) + self.assertEqual(b, s.cssRules[1].styleSheet.cssText) + + c = cssutils.resolveImports(s) + + # py3 TODO + self.assertEqual(u'\xc3\xa4{color:red}\xc3\xa4{color:green}'.encode('iso-8859-1'), + c.cssText) + + c.encoding = 'ascii' + self.assertEqual(ur'@charset "ascii";\E4 {color:red}\E4 {color:green}'.encode(), + c.cssText) + + # b cannot be found + m = mock.Mock() + with mock.patch('cssutils.util._defaultFetcher', m): + m.return_value = (None, None) + s = cssutils.parseString(a) + + # py3 TODO + self.assertEqual(a, s.cssText) + self.assertEqual(cssutils.css.CSSStyleSheet, + type(s.cssRules[1].styleSheet)) + c = cssutils.resolveImports(s) + # py3 TODO + self.assertEqual(u'@import"b.css";\xc3\xa4{color:green}'.encode('iso-8859-1'), + c.cssText) + + # @import with media + a = u'@import"b.css";@import"b.css" print, tv ;@import"b.css" all;' + b = u'a {color: red}' + m = mock.Mock() + with mock.patch('cssutils.util._defaultFetcher', m): + m.return_value = (None, b) + s = cssutils.parseString(a) + + c = cssutils.resolveImports(s) + + self.assertEqual('a{color:red}@media print,tv{a{color:red}}a{color:red}'.encode(), + c.cssText) + + # cannot resolve with media => keep original + a = u'@import"b.css"print;' + b = u'@namespace "http://example.com";' + m = mock.Mock() + with mock.patch('cssutils.util._defaultFetcher', m): + m.return_value = (None, b) + s = cssutils.parseString(a) + c = cssutils.resolveImports(s) + self.assertEqual(a.encode(), c.cssText) + + # urls are adjusted too, layout: + # a.css + # c.css + # img/img.gif + # b/ + # b.css + # subimg/subimg.gif + a = u''' + @import"b/b.css"; + a { + x: url(/img/abs.gif); + y: url(img/img.gif); + z: url(b/subimg/subimg.gif); + }''' + def fetcher(url): + c = { + 'b.css': u''' + @import"../c.css"; + b { + x: url(/img/abs.gif); + y: url(../img/img.gif); + z: url(subimg/subimg.gif); + }''', + 'c.css': u''' + c { + x: url(/img/abs.gif); + y: url(./img/img.gif); + z: url(./b/subimg/subimg.gif); + }''' + } + return 'utf-8', c[os.path.split(url)[1]] + + @mock.patch.object(cssutils.util, '_defaultFetcher', + new=fetcher) + def do(): + s = cssutils.parseString(a) + r = cssutils.resolveImports(s) + return s, r + + s, r = do() + + cssutils.ser.prefs.useDefaults() + cssutils.ser.prefs.keepComments = False + self.assertEqual(u'''c { + x: url(/img/abs.gif); + y: url(img/img.gif); + z: url(b/subimg/subimg.gif) + } +b { + x: url(/img/abs.gif); + y: url(img/img.gif); + z: url(b/subimg/subimg.gif) + } +a { + x: url(/img/abs.gif); + y: url(img/img.gif); + z: url(b/subimg/subimg.gif) + }'''.encode(), r.cssText) + + cssutils.ser.prefs.useDefaults() + else: + self.assertEqual(False, u'Mock needed for this test') + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_cssutilsimport.py cssutils-0.9.10/src/cssutils/tests/test_cssutilsimport.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_cssutilsimport.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_cssutilsimport.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,34 @@ +"""Testcase for cssutils imports""" + +before = len(locals()) # to check is only exp amount is imported +from cssutils import * +after = len(locals()) # to check is only exp amount is imported + +import unittest + +class CSSutilsImportTestCase(unittest.TestCase): + + def test_import_all(self): + "from cssutils import *" + import cssutils + + act = globals() + exp = {'CSSParser': CSSParser, + 'CSSSerializer': CSSSerializer, + 'css': cssutils.css, + 'stylesheets': cssutils.stylesheets, + } + exptotal = before + len(exp) + 1 + # imports before + * + "after" + self.assert_(after == exptotal, 'too many imported') + + found = 0 + for e in exp: + self.assert_(e in act, '%s not found' %e) + self.assert_(act[e] == exp[e], '%s not the same' %e) + found += 1 + self.assert_(found == len(exp)) + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_cssvalue.py cssutils-0.9.10/src/cssutils/tests/test_cssvalue.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_cssvalue.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_cssvalue.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,819 @@ +"""Testcases for cssutils.css.CSSValue and CSSPrimitiveValue.""" + +# +## from decimal import Decimal # maybe for later tests? +#import xml.dom +#import basetest +#import cssutils +#import types +# +#class CSSValueTestCase(basetest.BaseTestCase): +# +# def setUp(self): +# self.r = cssutils.css.CSSValue() # needed for tests +# +# def test_init(self): +# "CSSValue.__init__()" +# v = cssutils.css.CSSValue() +# self.assert_(u'' == v.cssText) +# self.assert_(None is v.cssValueType) +# self.assert_(None == v.cssValueTypeString) +# +# def test_escapes(self): +# "CSSValue Escapes" +# v = cssutils.css.CSSValue() +# v.cssText = u'1px' +# self.assert_(v.CSS_PRIMITIVE_VALUE == v.cssValueType) +# self.assert_(v.CSS_PX == v.primitiveType) +# self.assert_(u'1px' == v.cssText) +# +# v.cssText = u'1PX' +# self.assert_(v.CSS_PRIMITIVE_VALUE == v.cssValueType) +# self.assert_(v.CSS_PX == v.primitiveType) +# self.assert_(u'1px' == v.cssText) +# +# v.cssText = u'1p\\x' +# self.assert_(v.CSS_PRIMITIVE_VALUE == v.cssValueType) +# self.assert_(v.CSS_PX == v.primitiveType) +# self.assert_(u'1px' == v.cssText) +# +# def test_cssText(self): +# "CSSValue.cssText" +# v = cssutils.css.CSSValue() +# v.cssText = u'1px' +# self.assert_(v.CSS_PRIMITIVE_VALUE == v.cssValueType) +# self.assert_(v.CSS_PX == v.primitiveType) +# self.assert_(u'1px' == v.cssText) +# +# v = cssutils.css.CSSValue() +# v.cssText = u'1px' +# self.assert_(v.CSS_PRIMITIVE_VALUE == v.cssValueType) +# self.assert_(v.CSS_PX == v.primitiveType) +# self.assert_(u'1px' == v.cssText) +# +# v = cssutils.css.CSSValue() +# v.cssText = u'a ,b, c ,"d or d", "e, " ' +# self.assertEqual(v.CSS_PRIMITIVE_VALUE, v.cssValueType) +# self.assertEqual(v.CSS_STRING, v.primitiveType) +# self.assertEqual(u'a, b, c, "d or d", "e, "', v.cssText) +# +# v.cssText = u' 1 px ' +# self.assert_(v.CSS_VALUE_LIST == v.cssValueType) +# self.assert_('1 px' == v.cssText) +# +# v.cssText = u' normal 1px a, b, "c" end ' +# self.assert_(v.CSS_VALUE_LIST == v.cssValueType) +# self.assertEqual('normal 1px a, b, "c" end', v.cssText) +# +# for i, x in enumerate(v): +# self.assertEqual(x.CSS_PRIMITIVE_VALUE, x.cssValueType) +# if x == 0: +# self.assertEqual(x.CSS_IDENT, x.primitiveType) +# self.assertEqual(u'normal', x.cssText) +# elif x == 1: +# self.assertEqual(x.CSS_PX, x.primitiveType) +# self.assertEqual(u'1px', x.cssText) +# if x == 2: +# self.assertEqual(x.CSS_STRING, x.primitiveType) +# self.assertEqual(u'a, b, "c"', x.cssText) +# if x == 3: +# self.assertEqual(x.CSS_IDENT, x.primitiveType) +# self.assertEqual(u'end', x.cssText) +# +# +# v = cssutils.css.CSSValue() +# v.cssText = u' 1 px ' +# self.assert_(v.CSS_VALUE_LIST == v.cssValueType) +# self.assert_(u'1 px' == v.cssText) +# +# v.cssText = u'expression(document.body.clientWidth > 972 ? "1014px": "100%" )' +# self.assert_(v.CSS_PRIMITIVE_VALUE == v.cssValueType) +# self.assert_(v.CSS_UNKNOWN == v.primitiveType) +# self.assertEqual(u'expression(document.body.clientWidth > 972?"1014px": "100%")', +# v.cssText) +# +# def test_cssText2(self): +# "CSSValue.cssText 2" +# tests = { +# # mix +# u'a()1,-1,+1,1%,-1%,1px,-1px,"a",a,url(a),#aabb44': +# u'a() 1, -1, 1, 1%, -1%, 1px, -1px, "a", a, url(a), #ab4', +# +# # S or COMMENT +# u'red': u'red', +# u'red ': u'red', +# u' red ': u'red', +# u'/**/red': u'/**/ red', +# u'red/**/': u'red /**/', +# u'/**/red/**/': u'/**/ red /**/', +# u'/**/ red': u'/**/ red', +# u'red /**/': u'red /**/', +# u'/**/ red /**/': u'/**/ red /**/', +# u'red-': u'red-', +# +# # num / dimension +# u'.0': u'0', +# u'0': u'0', +# u'0.0': u'0', +# u'00': u'0', +# u'0%': u'0%', +# u'0px': u'0', +# u'-.0': u'0', +# u'-0': u'0', +# u'-0.0': u'0', +# u'-00': u'0', +# u'-0%': u'0%', +# u'-0px': u'0', +# u'+.0': u'0', +# u'+0': u'0', +# u'+0.0': u'0', +# u'+00': u'0', +# u'+0%': u'0%', +# u'+0px': u'0', +# u'1': u'1', +# u'1.0': u'1', +# u'1px': u'1px', +# u'1%': u'1%', +# u'1px1': u'1px1', +# u'+1': u'1', +# u'-1': u'-1', +# u'+1.0': u'1', +# u'-1.0': u'-1', +# +# # string, escaped nl is removed during tokenizing +# u'"x"': u'"x"', +# u"'x'": u'"x"', +# #ur''' "1\'2" ''': u'''"1'2"''', #??? +# #ur"'x\"'": ur'"x\""', #??? +# ur'''"x\ +#y"''': u'''"xy"''', +# +# # hash and rgb/a +# u'#112234': u'#112234', +# u'#112233': u'#123', +# u'rgb(1,2,3)': u'rgb(1, 2, 3)', +# u'rgb( 1 , 2 , 3 )': u'rgb(1, 2, 3)', +# u'rgb(-1,+2,0)': u'rgb(-1, 2, 0)', +# u'rgba(1,2,3,4)': u'rgba(1, 2, 3, 4)', +# u'rgba( 1 , 2 , 3 , 4 )': u'rgba(1, 2, 3, 4)', +# u'rgba(-1,+2,0, 0)': u'rgba(-1, 2, 0, 0)', +# +# # FUNCTION +# u'f(1,2)': u'f(1, 2)', +# u'f( 1 , 2 )': u'f(1, 2)', +# u'f(-1,+2)': u'f(-1, 2)', +# u'f( -1 , +2 )': u'f(-1, 2)', +# u'fun( -1 , +2 )': u'fun(-1, 2)', +# u'local( x )': u'local(x)', +# u'test(1px, #111, y, 1, 1%, "1", y(), var(x))': +# u'test(1px, #111, y, 1, 1%, "1", y(), var(x))', +# u'test(-1px, #111, y, -1, -1%, "1", -y())': +# u'test(-1px, #111, y, -1, -1%, "1", -y())', +# u'url(y) format( "x" , "y" )': u'url(y) format("x", "y")', +# u'f(1 2,3 4)': u'f(1 2, 3 4)', +# +# # IE expression +# ur'Expression()': u'Expression()', +# ur'expression(-1 < +2)': u'expression(-1< + 2)', +# ur'expression(document.width == "1")': u'expression(document.width=="1")', +# u'alpha(opacity=80)': u'alpha(opacity=80)', +# u'alpha( opacity = 80 , x=2 )': u'alpha(opacity=80, x=2)', +# +# # unicode-range +# 'u+f': 'u+f', +# 'U+ABCdef': 'u+abcdef', +# +# # url +# 'url(a)': 'url(a)', +# 'uRl(a)': 'url(a)', +# 'u\\rl(a)': 'url(a)', +# 'url("a")': 'url(a)', +# 'url( "a" )': 'url(a)', +# 'url(a)': 'url(a)', +# 'url(";")': 'url(";")', +# 'url(",")': 'url(",")', +# 'url(")")': 'url(")")', +# '''url("'")''': '''url("'")''', +# '''url('"')''': '''url("\\"")''', +# '''url("'")''': '''url("'")''', +# +# # operator +# '1': '1', +# '1 2': '1 2', +# '1 2': '1 2', +# '1,2': '1, 2', +# '1, 2': '1, 2', +# '1 ,2': '1, 2', +# '1 , 2': '1, 2', +# '1/2': '1/2', +# '1/ 2': '1/2', +# '1 /2': '1/2', +# '1 / 2': '1/2', +# # comment +# '1/**/2': '1 /**/ 2', +# '1 /**/2': '1 /**/ 2', +# '1/**/ 2': '1 /**/ 2', +# '1 /**/ 2': '1 /**/ 2', +# '1 /*a*/ /*b*/ 2': '1 /*a*/ /*b*/ 2', +# # , before +# '1,/**/2': '1, /**/ 2', +# '1 ,/**/2': '1, /**/ 2', +# '1, /**/2': '1, /**/ 2', +# '1 , /**/2': '1, /**/ 2', +# # , after +# '1/**/,2': '1 /**/, 2', +# '1/**/ ,2': '1 /**/, 2', +# '1/**/, 2': '1 /**/, 2', +# '1/**/ , 2': '1 /**/, 2', +# # all +# '1/*a*/ ,/*b*/ 2': '1 /*a*/, /*b*/ 2', +# '1 /*a*/, /*b*/2': '1 /*a*/, /*b*/ 2', +# '1 /*a*/ , /*b*/ 2': '1 /*a*/, /*b*/ 2', +# +# # list +# 'a b1,b2 b2,b3,b4': 'a b1, b2 b2, b3, b4', +# 'a b1 , b2 b2 , b3 , b4': 'a b1, b2 b2, b3, b4', +# 'u+1 , u+2-5': 'u+1, u+2-5', +# u'local( x ), url(y) format( "x" , "y" )': +# u'local(x), url(y) format("x", "y")', +# # FUNCTION +# u'attr( href )': u'attr(href)', +# # PrinceXML extende FUNC syntax with nested FUNC +# u'target-counter(attr(href),page)': u'target-counter(attr(href), page)' +# } +# +# self.do_equal_r(tests) +# +# tests = { +# u'a+': xml.dom.SyntaxErr, +# u'-': xml.dom.SyntaxErr, +# u'+': xml.dom.SyntaxErr, +# u'-%': xml.dom.SyntaxErr, +# u'+a': xml.dom.SyntaxErr, +# u'--1px': xml.dom.SyntaxErr, +# u'++1px': xml.dom.SyntaxErr, +# u'#': xml.dom.SyntaxErr, +# u'#00': xml.dom.SyntaxErr, +# u'#0000': xml.dom.SyntaxErr, +# u'#00000': xml.dom.SyntaxErr, +# u'#0000000': xml.dom.SyntaxErr, +# u'-#0': xml.dom.SyntaxErr, +# # operator +# u',': xml.dom.SyntaxErr, +# u'1,,2': xml.dom.SyntaxErr, +# u'1,/**/,2': xml.dom.SyntaxErr, +# u'1 , /**/ , 2': xml.dom.SyntaxErr, +# u'1,': xml.dom.SyntaxErr, +# u'1, ': xml.dom.SyntaxErr, +# u'1 ,': xml.dom.SyntaxErr, +# u'1 , ': xml.dom.SyntaxErr, +# u'1 , ': xml.dom.SyntaxErr, +# u'1//2': xml.dom.SyntaxErr, +# # URL +# u'url(x))': xml.dom.SyntaxErr, +# # string +# u'"': xml.dom.SyntaxErr, +# u"'": xml.dom.SyntaxErr, +# # function +# u'f(-)': xml.dom.SyntaxErr, +# u'f(x))': xml.dom.SyntaxErr +# } +# self.do_raise_r(tests) +# +# def test_incomplete(self): +# "CSSValue (incomplete)" +# tests = { +# u'url("a': u'url(a)', +# u'url(a': u'url(a)' +# } +# for v, exp in tests.items(): +# s = cssutils.parseString('a { background: %s' % v) +# v = s.cssRules[0].style.background +# self.assertEqual(v, exp) +# +# def test_cssValueType(self): +# "CSSValue.cssValueType .cssValueTypeString" +# tests = [ +# ([u'inherit', u'INhe\\rit'], 'CSS_INHERIT', cssutils.css.CSSValue), +# (['1', '1%', '1em', '1ex', '1px', '1cm', '1mm', '1in', '1pt', '1pc', +# '1deg', '1rad', '1grad', '1ms', '1s', '1hz', '1khz', '1other', +# '"string"', "'string'", 'url(x)', 'red', +# 'attr(a)', 'counter(x)', 'rect(1px, 2px, 3px, 4px)', +# 'rgb(0, 0, 0)', '#000', '#123456', 'rgba(0, 0, 0, 0)', +# 'hsl(0, 0, 0)', 'hsla(0, 0, 0, 0)', +# ], +# 'CSS_PRIMITIVE_VALUE', cssutils.css.CSSPrimitiveValue), +# ([u'1px 1px', 'red blue green x'], 'CSS_VALUE_LIST', cssutils.css.CSSValueList), +# # what is a custom value? +# #([], 'CSS_CUSTOM', cssutils.css.CSSValue) +# ] +# for values, name, cls in tests: +# for value in values: +# v = cssutils.css.CSSValue(cssText=value) +# if value == "'string'": +# # will be changed to " always +# value = '"string"' +# self.assertEqual(value, v.cssText) +# self.assertEqual(name, v.cssValueTypeString) +# self.assertEqual(getattr(v, name), v.cssValueType) +# self.assertEqual(cls, type(v)) +# +# def test_readonly(self): +# "(CSSValue._readonly)" +# v = cssutils.css.CSSValue(cssText='inherit') +# self.assert_(False is v._readonly) +# +# v = cssutils.css.CSSValue(cssText='inherit', readonly=True) +# self.assert_(True is v._readonly) +# self.assert_(u'inherit', v.cssText) +# self.assertRaises(xml.dom.NoModificationAllowedErr, v._setCssText, u'x') +# self.assert_(u'inherit', v.cssText) +# +# def test_reprANDstr(self): +# "CSSValue.__repr__(), .__str__()" +# cssText='inherit' +# +# s = cssutils.css.CSSValue(cssText=cssText) +# +# self.assert_(cssText in str(s)) +# +# s2 = eval(repr(s)) +# self.assert_(isinstance(s2, s.__class__)) +# self.assert_(cssText == s2.cssText) +# +# +#class CSSPrimitiveValueTestCase(basetest.BaseTestCase): +# +# def test_init(self): +# "CSSPrimitiveValue.__init__()" +# v = cssutils.css.CSSPrimitiveValue(u'1') +# self.assert_(u'1' == v.cssText) +# +# self.assert_(v.CSS_PRIMITIVE_VALUE == v.cssValueType) +# self.assert_("CSS_PRIMITIVE_VALUE" == v.cssValueTypeString) +# +# self.assert_(v.CSS_NUMBER == v.primitiveType) +# self.assert_("CSS_NUMBER" == v.primitiveTypeString) +# +# # DUMMY to be able to test empty constructor call +# #self.assertRaises(xml.dom.SyntaxErr, v.__init__, None) +# +# self.assertRaises(xml.dom.InvalidAccessErr, v.getCounterValue) +# self.assertRaises(xml.dom.InvalidAccessErr, v.getRGBColorValue) +# self.assertRaises(xml.dom.InvalidAccessErr, v.getRectValue) +# self.assertRaises(xml.dom.InvalidAccessErr, v.getStringValue) +# +# def test_CSS_UNKNOWN(self): +# "CSSPrimitiveValue.CSS_UNKNOWN" +# v = cssutils.css.CSSPrimitiveValue(u'expression(false)') +# self.assert_(v.CSS_UNKNOWN == v.primitiveType) +# self.assert_('CSS_UNKNOWN' == v.primitiveTypeString) +# +# def test_CSS_NUMBER_AND_OTHER_DIMENSIONS(self): +# "CSSPrimitiveValue.CSS_NUMBER .. CSS_DIMENSION" +# defs = [ +# ('', 'CSS_NUMBER'), +# ('%', 'CSS_PERCENTAGE'), +# ('em', 'CSS_EMS'), +# ('ex', 'CSS_EXS'), +# ('px', 'CSS_PX'), +# ('cm', 'CSS_CM'), +# ('mm', 'CSS_MM'), +# ('in', 'CSS_IN'), +# ('pt', 'CSS_PT'), +# ('pc', 'CSS_PC'), +# ('deg', 'CSS_DEG'), +# ('rad', 'CSS_RAD'), +# ('grad', 'CSS_GRAD'), +# ('ms', 'CSS_MS'), +# ('s', 'CSS_S'), +# ('hz', 'CSS_HZ'), +# ('khz', 'CSS_KHZ'), +# ('other_dimension', 'CSS_DIMENSION') +# ] +# for dim, name in defs: +# for n in (0, 1, 1.1, -1, -1.1, -0): +# v = cssutils.css.CSSPrimitiveValue('%i%s' % (n, dim)) +# self.assertEqual(name, v.primitiveTypeString) +# self.assertEqual(getattr(v, name), v.primitiveType) +# +# def test_CSS_STRING_AND_OTHER(self): +# "CSSPrimitiveValue.CSS_STRING .. CSS_RGBCOLOR" +# defs = [ +# (('""', "''", '"some thing"', "' A\\ND '", +# # comma separated lists are STRINGS FOR NOW! +# 'a, b', +# '"a", "b"', +# ), 'CSS_STRING'), +# (('url(a)', 'url("a b")', "url(' ')"), 'CSS_URI'), +# (('some', 'or_anth-er'), 'CSS_IDENT'), +# (('attr(a)', 'attr(b)'), 'CSS_ATTR'), +# (('counter(1)', 'counter(2)'), 'CSS_COUNTER'), +# (('rect(1,2,3,4)',), 'CSS_RECT'), +# (('rgb(1,2,3)', 'rgb(10%, 20%, 30%)', '#123', '#123456'), +# 'CSS_RGBCOLOR'), +# (('rgba(1,2,3,4)','rgba(10%, 20%, 30%, 40%)', ), +# 'CSS_RGBACOLOR'), +# (('U+0', 'u+ffffff', 'u+000000-f', +# 'u+0-f, U+ee-ff'), 'CSS_UNICODE_RANGE') +# ] +# +# for examples, name in defs: +# for x in examples: +# v = cssutils.css.CSSPrimitiveValue(x) +# self.assertEqual(getattr(v, name), v.primitiveType) +# self.assertEqual(name, v.primitiveTypeString) +# +# def test_getFloat(self): +# "CSSPrimitiveValue.getFloatValue()" +# # NOT TESTED are float values as it seems difficult to +# # compare these. Maybe use decimal.Decimal? +# +# v = cssutils.css.CSSPrimitiveValue(u'1px') +# tests = { +# '0': (v.CSS_NUMBER, 0), +# '-1.1': (v.CSS_NUMBER, -1.1), +# '1%': (v.CSS_PERCENTAGE, 1), +# '-1%': (v.CSS_PERCENTAGE, -1), +# '1em': (v.CSS_EMS, 1), +# '-1.1em': (v.CSS_EMS, -1.1), +# '1ex': (v.CSS_EXS, 1), +# '1px': (v.CSS_PX, 1), +# +# '1cm': (v.CSS_CM, 1), +# '1cm': (v.CSS_MM, 10), +# '254cm': (v.CSS_IN, 100), +# '1mm': (v.CSS_MM, 1), +# '10mm': (v.CSS_CM, 1), +# '254mm': (v.CSS_IN, 10), +# '1in': (v.CSS_IN, 1), +# '100in': (v.CSS_CM, 254), # ROUNDED!!! +# '10in': (v.CSS_MM, 254), # ROUNDED!!! +# +# '1pt': (v.CSS_PT, 1), +# '1pc': (v.CSS_PC, 1), +# +# '1deg': (v.CSS_DEG, 1), +# '1rad': (v.CSS_RAD, 1), +# '1grad': (v.CSS_GRAD, 1), +# +# '1ms': (v.CSS_MS, 1), +# '1000ms': (v.CSS_S, 1), +# '1s': (v.CSS_S, 1), +# '1s': (v.CSS_MS, 1000), +# +# '1hz': (v.CSS_HZ, 1), +# '1000hz': (v.CSS_KHZ, 1), +# '1khz': (v.CSS_KHZ, 1), +# '1khz': (v.CSS_HZ, 1000), +# +# '1DIMENSION': (v.CSS_DIMENSION, 1), +# } +# for cssText in tests: +# v.cssText = cssText +# unitType, exp = tests[cssText] +# val = v.getFloatValue(unitType) +# if unitType in (v.CSS_IN, v.CSS_CM): +# val = round(val) +# self.assertEqual(val , exp) +# +# def test_setFloat(self): +# "CSSPrimitiveValue.setFloatValue()" +# V = cssutils.css.CSSPrimitiveValue +# +# tests = { +# # unitType, value +# (V.CSS_NUMBER, 1): [ +# # unitType, setvalue, +# # getvalue or expected exception, msg or cssText +# (V.CSS_NUMBER, 0, 0, '0'), +# (V.CSS_NUMBER, 0.1, 0.1, '0.1'), +# (V.CSS_NUMBER, -0, 0, '0'), +# (V.CSS_NUMBER, 2, 2, '2'), +# (V.CSS_NUMBER, 2.0, 2, '2'), +# (V.CSS_NUMBER, 2.1, 2.1, '2.1'), +# (V.CSS_NUMBER, -2.1, -2.1, '-2.1'), +# # setting with string does work +# (V.CSS_NUMBER, '1', 1, '1'), +# (V.CSS_NUMBER, '1.1', 1.1, '1.1'), +# (V.CSS_PX, 1, xml.dom.InvalidAccessErr, None), +# (V.CSS_DEG, 1, xml.dom.InvalidAccessErr, None), +# (V.CSS_RAD, 1, xml.dom.InvalidAccessErr, None), +# (V.CSS_GRAD, 1, xml.dom.InvalidAccessErr, None), +# (V.CSS_S, 1, xml.dom.InvalidAccessErr, None), +# (V.CSS_MS, 1, xml.dom.InvalidAccessErr, None), +# (V.CSS_KHZ, 1, xml.dom.InvalidAccessErr, None), +# (V.CSS_HZ, 1, xml.dom.InvalidAccessErr, None), +# (V.CSS_DIMENSION, 1, xml.dom.InvalidAccessErr, None), +# (V.CSS_MM, 2, xml.dom.InvalidAccessErr, None), +# +# (V.CSS_NUMBER, 'x', xml.dom.InvalidAccessErr, +# "CSSPrimitiveValue: floatValue 'x' is not a float"), +# (V.CSS_NUMBER, '1x', xml.dom.InvalidAccessErr, +# "CSSPrimitiveValue: floatValue '1x' is not a float"), +# +# (V.CSS_STRING, 'x', xml.dom.InvalidAccessErr, +# "CSSPrimitiveValue: unitType 'CSS_STRING' is not a float type"), +# (V.CSS_URI, 'x', xml.dom.InvalidAccessErr, +# "CSSPrimitiveValue: unitType 'CSS_URI' is not a float type"), +# (V.CSS_ATTR, 'x', xml.dom.InvalidAccessErr, +# "CSSPrimitiveValue: unitType 'CSS_ATTR' is not a float type"), +# (V.CSS_IDENT, 'x', xml.dom.InvalidAccessErr, +# "CSSPrimitiveValue: unitType 'CSS_IDENT' is not a float type"), +# (V.CSS_RGBCOLOR, 'x', xml.dom.InvalidAccessErr, +# "CSSPrimitiveValue: unitType 'CSS_RGBCOLOR' is not a float type"), +# (V.CSS_RGBACOLOR, 'x', xml.dom.InvalidAccessErr, +# "CSSPrimitiveValue: unitType 'CSS_RGBACOLOR' is not a float type"), +# (V.CSS_RECT, 'x', xml.dom.InvalidAccessErr, +# "CSSPrimitiveValue: unitType 'CSS_RECT' is not a float type"), +# (V.CSS_COUNTER, 'x', xml.dom.InvalidAccessErr, +# "CSSPrimitiveValue: unitType 'CSS_COUNTER' is not a float type"), +# (V.CSS_EMS, 1, xml.dom.InvalidAccessErr, +# "CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_NUMBER' to 'CSS_EMS'"), +# (V.CSS_EXS, 1, xml.dom.InvalidAccessErr, +# "CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_NUMBER' to 'CSS_EXS'") +# ], +# (V.CSS_MM, '1mm'): [ +# (V.CSS_MM, 2, 2, '2mm'), +# (V.CSS_MM, 0, 0, '0mm'), +# (V.CSS_MM, 0.1, 0.1, '0.1mm'), +# (V.CSS_MM, -0, -0, '0mm'), +# (V.CSS_MM, 3.0, 3, '3mm'), +# (V.CSS_MM, 3.1, 3.1, '3.1mm'), +# (V.CSS_MM, -3.1, -3.1, '-3.1mm'), +# (V.CSS_CM, 1, 10, '10mm'), +# (V.CSS_IN, 10, 254, '254mm'), +# (V.CSS_PT, 1, 1828.8, '1828.8mm'), +# (V.CSS_PX, 1, xml.dom.InvalidAccessErr, None), +# (V.CSS_NUMBER, 2, xml.dom.InvalidAccessErr, None) +# ], +# (V.CSS_PT, '1pt'): [ +# (V.CSS_PT, 2, 2, '2pt'), +# (V.CSS_PC, 12, 1, '1pt'), +# (V.CSS_NUMBER, 1, xml.dom.InvalidAccessErr, None), +# (V.CSS_DEG, 1, xml.dom.InvalidAccessErr, None), +# (V.CSS_PX, 1, xml.dom.InvalidAccessErr, None) +# ], +# (V.CSS_KHZ, '1khz'): [ +# (V.CSS_HZ, 2000, 2, '2khz'), +# (V.CSS_NUMBER, 1, xml.dom.InvalidAccessErr, None), +# (V.CSS_DEG, 1, xml.dom.InvalidAccessErr, None), +# (V.CSS_PX, 1, xml.dom.InvalidAccessErr, None) +# ] +# } +# for test in tests: +# initialType, initialValue = test +# pv = cssutils.css.CSSPrimitiveValue(initialValue) +# for setType, setValue, exp, cssText in tests[test]: +# if type(exp) == types.TypeType or\ +# type(exp) == types.ClassType: # 2.4 compatibility +# if cssText: +# self.assertRaisesMsg( +# exp, cssText, pv.setFloatValue, setType, setValue) +# else: +# self.assertRaises( +# exp, pv.setFloatValue, setType, setValue) +# else: +# pv.setFloatValue(setType, setValue) +# self.assertEqual(pv._value[0], cssText) +# if cssText == '0mm': +# cssText = '0' +# self.assertEqual(pv.cssText, cssText) +# self.assertEqual(pv.getFloatValue(initialType), exp) +# +# def test_getString(self): +# "CSSPrimitiveValue.getStringValue()" +# v = cssutils.css.CSSPrimitiveValue(u'1px') +# self.assert_(v.primitiveType == v.CSS_PX) +# self.assertRaises(xml.dom.InvalidAccessErr, +# v.getStringValue) +# +# pv = cssutils.css.CSSPrimitiveValue +# tests = { +# pv.CSS_STRING: ("'red'", 'red'), +# pv.CSS_STRING: ('"red"', 'red'), +# pv.CSS_URI: ('url(http://example.com)', None), +# pv.CSS_URI: ("url('http://example.com')", +# u"http://example.com"), +# pv.CSS_URI: ('url("http://example.com")', +# u'http://example.com'), +# pv.CSS_URI: ('url("http://example.com?)")', +# u'http://example.com?)'), +# pv.CSS_IDENT: ('red', None), +# pv.CSS_ATTR: ('attr(att-name)', +# u'att-name'), # the name of the attrr +# } +# for t in tests: +# val, exp = tests[t] +# if not exp: +# exp = val +# +# v = cssutils.css.CSSPrimitiveValue(val) +# self.assertEqual(v.primitiveType, t) +# self.assertEqual(v.getStringValue(), exp) +# +# def test_setString(self): +# "CSSPrimitiveValue.setStringValue()" +# # CSS_STRING +# v = cssutils.css.CSSPrimitiveValue(u'"a"') +# self.assert_(v.CSS_STRING == v.primitiveType) +# v.setStringValue(v.CSS_STRING, 'b') +# self.assert_(('b', 'STRING') == v._value) +# self.assertEqual('b', v.getStringValue()) +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_STRING' to 'CSS_URI'", +# v.setStringValue, *(v.CSS_URI, 'x')) +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_STRING' to 'CSS_IDENT'", +# v.setStringValue, *(v.CSS_IDENT, 'x')) +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_STRING' to 'CSS_ATTR'", +# v.setStringValue, *(v.CSS_ATTR, 'x')) +# +# # CSS_IDENT +# v = cssutils.css.CSSPrimitiveValue('new') +# v.setStringValue(v.CSS_IDENT, 'ident') +# self.assert_(v.CSS_IDENT == v.primitiveType) +# self.assert_(('ident', 'IDENT') == v._value) +# self.assert_('ident' == v.getStringValue()) +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_IDENT' to 'CSS_URI'", +# v.setStringValue, *(v.CSS_URI, 'x')) +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_IDENT' to 'CSS_STRING'", +# v.setStringValue, *(v.CSS_STRING, '"x"')) +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_IDENT' to 'CSS_ATTR'", +# v.setStringValue, *(v.CSS_ATTR, 'x')) +# +# # CSS_URI +# v = cssutils.css.CSSPrimitiveValue('url(old)') +# v.setStringValue(v.CSS_URI, '(') +# self.assertEqual((u'(', 'URI'), v._value) +# self.assertEqual(u'(', v.getStringValue()) +# +# v.setStringValue(v.CSS_URI, ')') +# self.assertEqual((u')', 'URI'), v._value) +# self.assertEqual(u')', v.getStringValue()) +# +# v.setStringValue(v.CSS_URI, '"') +# self.assertEqual(ur'"', v.getStringValue()) +# self.assertEqual((ur'"', 'URI'), v._value) +# +# v.setStringValue(v.CSS_URI, "''") +# self.assertEqual(ur"''", v.getStringValue()) +# self.assertEqual((ur"''", 'URI'), v._value) +# +# v.setStringValue(v.CSS_URI, ',') +# self.assertEqual(ur',', v.getStringValue()) +# self.assertEqual((ur',', 'URI'), v._value) +# +# v.setStringValue(v.CSS_URI, ' ') +# self.assertEqual((u' ', 'URI'), v._value) +# self.assertEqual(u' ', v.getStringValue()) +# +# v.setStringValue(v.CSS_URI, 'a)') +# self.assertEqual((u'a)', 'URI'), v._value) +# self.assertEqual(u'a)', v.getStringValue()) +# +# v.setStringValue(v.CSS_URI, 'a') +# self.assert_(v.CSS_URI == v.primitiveType) +# self.assertEqual((u'a', 'URI'), v._value) +# self.assertEqual(u'a', v.getStringValue()) +# +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_URI' to 'CSS_IDENT'", +# v.setStringValue, *(v.CSS_IDENT, 'x')) +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_URI' to 'CSS_STRING'", +# v.setStringValue, *(v.CSS_STRING, '"x"')) +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_URI' to 'CSS_ATTR'", +# v.setStringValue, *(v.CSS_ATTR, 'x')) +# +# # CSS_ATTR +# v = cssutils.css.CSSPrimitiveValue('attr(old)') +# v.setStringValue(v.CSS_ATTR, 'a') +# self.assert_(v.CSS_ATTR == v.primitiveType) +# self.assert_('a' == v.getStringValue()) +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_ATTR' to 'CSS_IDENT'", +# v.setStringValue, *(v.CSS_IDENT, 'x')) +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_ATTR' to 'CSS_STRING'", +# v.setStringValue, *(v.CSS_STRING, '"x"')) +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_ATTR' to 'CSS_URI'", +# v.setStringValue, *(v.CSS_URI, 'x')) +# +# # TypeError as 'x' is no valid type +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: stringType 'x' (UNKNOWN TYPE) is not a string type", +# v.setStringValue, *('x', 'brown')) +# # IndexError as 111 is no valid type +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: stringType 111 (UNKNOWN TYPE) is not a string type", +# v.setStringValue, *(111, 'brown')) +# # CSS_PX is no string type +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: stringType CSS_PX is not a string type", +# v.setStringValue, *(v.CSS_PX, 'brown')) +# +# def test_typeRGBColor(self): +# "RGBColor" +# v = cssutils.css.CSSPrimitiveValue('RGB(1, 5, 10)') +# self.assertEqual(v.CSS_RGBCOLOR, v.primitiveType) +# self.assertEqual(u'rgb(1, 5, 10)', v.cssText) +# +# v = cssutils.css.CSSPrimitiveValue('rgb(1, 5, 10)') +# self.assertEqual(v.CSS_RGBCOLOR, v.primitiveType) +# self.assertEqual(u'rgb(1, 5, 10)', v.cssText) +# +# v = cssutils.css.CSSPrimitiveValue('rgb(1%, 5%, 10%)') +# self.assertEqual(v.CSS_RGBCOLOR, v.primitiveType) +# self.assertEqual(u'rgb(1%, 5%, 10%)', v.cssText) +# +# v = cssutils.css.CSSPrimitiveValue(' rgb( 1 ,5, 10 )') +# self.assertEqual(v.CSS_RGBCOLOR, v.primitiveType) +# v = cssutils.css.CSSPrimitiveValue('rgb(1,5,10)') +# self.assertEqual(v.CSS_RGBCOLOR, v.primitiveType) +# v = cssutils.css.CSSPrimitiveValue('rgb(1%, .5%, 10.1%)') +# self.assertEqual(v.CSS_RGBCOLOR, v.primitiveType) +# +# def test_reprANDstr(self): +# "CSSPrimitiveValue.__repr__(), .__str__()" +# v='111' +# +# s = cssutils.css.CSSPrimitiveValue(v) +# +# self.assert_(v in str(s)) +# self.assert_('CSS_NUMBER' in str(s)) +# +# s2 = eval(repr(s)) +# self.assert_(isinstance(s2, s.__class__)) +# self.assert_(v == s2.cssText) +# +# +#class CSSValueListTestCase(basetest.BaseTestCase): +# +# def test_init(self): +# "CSSValueList.__init__()" +# v = cssutils.css.CSSValue(cssText=u'red blue') +# self.assert_(v.CSS_VALUE_LIST == v.cssValueType) +# self.assertEqual('red blue', v.cssText) +# +# self.assert_(2 == v.length) +# +# item = v.item(0) +# item.setStringValue(item.CSS_IDENT, 'green') +# self.assertEqual('green blue', v.cssText) +# +# def test_numbers(self): +# "CSSValueList.cssText" +# tests = { +# u'0 0px -0px +0px': (u'0 0 0 0', 4), +# u'1 2 3 4': (None, 4), +# u'-1 -2 -3 -4': (None, 4), +# u'-1 2': (None, 2), +# u'-1px red "x"': (None, 3), +# u'a, b c': (None, 2), +# u'1px1 2% 3': (u'1px1 2% 3', 3), +# u'f(+1pX, -2, 5%) 1': (u'f(1px, -2, 5%) 1', 2), +# u'0 f()0': (u'0 f() 0', 3), +# u'f()0': (u'f() 0', 2), +# u'f()1%': (u'f() 1%', 2), +# u'f()1px': (u'f() 1px', 2), +# u'f()"str"': (u'f() "str"', 2), +# u'f()ident': (u'f() ident', 2), +# u'f()#123': (u'f() #123', 2), +# u'f()url()': (u'f() url()', 2), +# u'f()f()': (u'f() f()', 2), +# u'url(x.gif)0 0': (u'url(x.gif) 0 0', 3), +# u'url(x.gif)no-repeat': (u'url(x.gif) no-repeat', 2) +# } +# for test in tests: +# exp, num = tests[test] +# if not exp: +# exp = test +# v = cssutils.css.CSSValue(cssText=test) +# self.assert_(v.CSS_VALUE_LIST == v.cssValueType) +# self.assertEqual(num, v.length) +# self.assertEqual(exp, v.cssText) +# +# def test_reprANDstr(self): +# "CSSValueList.__repr__(), .__str__()" +# v='1px 2px' +# +# s = cssutils.css.CSSValue(v) +# self.assert_(isinstance(s, cssutils.css.CSSValueList)) +# +# self.assert_('length=2' in str(s)) +# self.assert_(v in str(s)) +# +# # not "eval()"able! +# #s2 = eval(repr(s)) +# +# +#if __name__ == '__main__': +# import unittest +# unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_cssvariablesdeclaration.py cssutils-0.9.10/src/cssutils/tests/test_cssvariablesdeclaration.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_cssvariablesdeclaration.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_cssvariablesdeclaration.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,350 @@ +"""Testcases for cssutils.css.cssvariablesdelaration.CSSVariablesDeclaration.""" +__version__ = '$Id: test_cssstyledeclaration.py 1869 2009-10-17 19:37:40Z cthedot $' + +import xml.dom +import basetest +import cssutils + +class CSSVariablesDeclarationTestCase(basetest.BaseTestCase): + + def setUp(self): + self.r = cssutils.css.CSSVariablesDeclaration() + cssutils.ser.prefs.useDefaults() + + def tearDown(self): + cssutils.ser.prefs.useDefaults() + + def test_init(self): + "CSSVariablesDeclaration.__init__()" + v = cssutils.css.CSSVariablesDeclaration() + self.assertEqual(u'', v.cssText) + self.assertEqual(0, v.length) + self.assertEqual(None, v.parentRule) + + v = cssutils.css.CSSVariablesDeclaration(cssText='x: 0') + self.assertEqual(u'x: 0', v.cssText) + self.assertEqual('0', v.getVariableValue('x')) + + rule = cssutils.css.CSSVariablesRule() + v = cssutils.css.CSSVariablesDeclaration(cssText='x: 0', + parentRule=rule) + self.assertEqual(rule, v.parentRule) + + def test__contains__(self): + "CSSVariablesDeclaration.__contains__(name)" + v = cssutils.css.CSSVariablesDeclaration(cssText='x: 0; y: 2') + for test in ('x', 'y'): + self.assert_(test in v) + self.assert_(test.upper() in v) + + self.assert_('z' not in v) + + def test_items(self): + "CSSVariablesDeclaration[variableName]" + v = cssutils.css.CSSVariablesDeclaration() + + value = '0' + v['X'] = value + self.assertEqual(value, v['X']) + self.assertEqual(value, v.getVariableValue('X')) + self.assertEqual(value, v['x']) + self.assertEqual(value, v.getVariableValue('x')) + + self.assertEqual(u'', v['y']) + self.assertEqual(u'', v.getVariableValue('y')) + + v['z'] = '1' + self.assertEqual(2, v.length) + + items = [] + # unsorted! + self.assertEquals(sorted(v), ['x', 'z']) + + del v['z'] + self.assertEqual(1, v.length) + self.assertEqual(1, v.length) + + self.assertEqual(u'0', v.removeVariable('x')) + self.assertEqual(u'', v.removeVariable('z')) + self.assertEqual(0, v.length) + + v.cssText = 'x:0; y:1' + keys = [] + # unsorted! + for i in range(0, v.length): + keys.append(v.item(i)) + self.assertEqual(sorted(keys), [u'x', u'y']) + + def test_keys(self): + "CSSVariablesDeclaration.keys()" + v = cssutils.css.CSSVariablesDeclaration(cssText='x: 0; Y: 2') + self.assertEqual(['x', 'y'], sorted(v.keys())) + + def test_cssText(self): + "CSSVariablesDeclaration.cssText" + # empty + tests = { + u'': u'', + u' ': u'', + u' \t \n ': u'', + u'x: 1': None, + u'x: "a"': None, + u'x: rgb(1, 2, 3)': None, + u'x: 1px 2px 3px': None, + + u'x:1': u'x: 1', + u'x:1;': u'x: 1', + + u'x : 1 ': u'x: 1', + u'x : 1 ; ': u'x: 1', + + u'x:1;y:2': u'x: 1;\ny: 2', + u'x:1;y:2;': u'x: 1;\ny: 2', + u'x : 1 ; y : 2 ': u'x: 1;\ny: 2', + u'x : 1 ; y : 2 ; ': u'x: 1;\ny: 2', + + u'/*x*/': u'/*x*/', + u'x555: 5': None, + u'xxx:1;yyy:2': u'xxx: 1;\nyyy: 2', + u'xxx : 1; yyy : 2': u'xxx: 1;\nyyy: 2', + u'x:1;x:2;X:2': u'x: 2', + u'same:1;SAME:2;': u'same: 2', + u'/**/x/**/:/**/1/**/;/**/y/**/:/**/2/**/': + u'/**/ \n /**/ \n /**/ \n x: 1 /**/;\n/**/ \n /**/ \n /**/ \n y: 2 /**/' + } + self.do_equal_r(tests) + + # TODO: Fix? +# def test_cssText2(self): +# "CSSVariablesDeclaration.cssText" +# # exception +# tests = { +# u'top': xml.dom.SyntaxErr, +# u'top:': xml.dom.SyntaxErr, +# u'top : ': xml.dom.SyntaxErr, +# u'top:;': xml.dom.SyntaxErr, +# u'top 0': xml.dom.SyntaxErr, +# u'top 0;': xml.dom.SyntaxErr, +# +# u':': xml.dom.SyntaxErr, +# u':0': xml.dom.SyntaxErr, +# u':0;': xml.dom.SyntaxErr, +# u':;': xml.dom.SyntaxErr, +# u': ;': xml.dom.SyntaxErr, +# +# u'0': xml.dom.SyntaxErr, +# u'0;': xml.dom.SyntaxErr, +# +# u';': xml.dom.SyntaxErr, +# } +# self.do_raise_r(tests) + + def test_xVariable(self): + "CSSVariablesDeclaration.xVariable()" + v = cssutils.css.CSSVariablesDeclaration() + # unset + self.assertEqual(u'', v.getVariableValue('x')) + # set + v.setVariable('x', '0') + self.assertEqual(u'0', v.getVariableValue('x')) + self.assertEqual(u'0', v.getVariableValue('X')) + self.assertEqual(u'x: 0', v.cssText) + v.setVariable('X', '0') + self.assertEqual(u'0', v.getVariableValue('x')) + self.assertEqual(u'0', v.getVariableValue('X')) + self.assertEqual(u'x: 0', v.cssText) + # remove + self.assertEqual(u'0', v.removeVariable('x')) + self.assertEqual(u'', v.removeVariable('x')) + self.assertEqual(u'', v.getVariableValue('x')) + self.assertEqual(u'', v.cssText) + + + def test_imports(self): + "CSSVariables imports" + def fetcher(url): + url = url.replace('\\', '/') + url = url[url.rfind('/')+1:] + return (None, { + '3.css': ''' + @variables { + over3-2-1-0: 3; + over3-2-1: 3; + over3-2: 3; + over3-2-0: 3; + over3-1: 3; + over3-1-0: 3; + over3-0: 3; + local3: 3; + } + + ''', + '2.css': ''' + @variables { + over3-2-1-0: 2; + over3-2-1: 2; + over3-2-0: 2; + over3-2: 2; + over2-1: 2; + over2-1-0: 2; + over2-0: 2; + local2: 2; + } + + ''', + '1.css': ''' + @import "3.css"; + @import "2.css"; + @variables { + over3-2-1-0: 1; + over3-2-1: 1; + over3-1: 1; + over3-1-0: 1; + over2-1: 1; + over2-1-0: 1; + over1-0: 1; + local1: 1; + } + + ''' + }[url]) + + css = ''' + @import "1.css"; + @variables { + over3-2-1-0: 0; + over3-2-0: 0; + over3-1-0: 0; + over2-1-0: 0; + over3-0: 0; + over2-0: 0; + over1-0: 0; + local0: 0; + } + a { + local0: var(local0); + local1: var(local1); + local2: var(local2); + local3: var(local3); + over1-0: var(over1-0); + over2-0: var(over2-0); + over3-0: var(over3-0); + over2-1: var(over2-1); + over3-1: var(over3-1); + over3-2: var(over3-2); + over2-1-0: var(over2-1-0); + over3-2-0: var(over3-2-0); + over3-2-1: var(over3-2-1); + over3-2-1-0: var(over3-2-1-0); + } + ''' + p = cssutils.CSSParser(fetcher=fetcher) + s = p.parseString(css) + + # only these in rule of this sheet + self.assertEqual(s.cssRules[1].variables.length, 8) + # but all vars in s available! + self.assertEqual(s.variables.length, 15) + self.assertEqual([u'local0', u'local1', u'local2', u'local3', + u'over1-0', u'over2-0', u'over2-1', u'over2-1-0', + u'over3-0', u'over3-1', u'over3-1-0', u'over3-2', + u'over3-2-0', u'over3-2-1', u'over3-2-1-0'], + sorted(s.variables.keys())) + + + # test with variables rule + cssutils.ser.prefs.resolveVariables = False + self.assertEqual(s.cssText, '''@import "1.css"; +@variables { + over3-2-1-0: 0; + over3-2-0: 0; + over3-1-0: 0; + over2-1-0: 0; + over3-0: 0; + over2-0: 0; + over1-0: 0; + local0: 0 + } +a { + local0: var(local0); + local1: var(local1); + local2: var(local2); + local3: var(local3); + over1-0: var(over1-0); + over2-0: var(over2-0); + over3-0: var(over3-0); + over2-1: var(over2-1); + over3-1: var(over3-1); + over3-2: var(over3-2); + over2-1-0: var(over2-1-0); + over3-2-0: var(over3-2-0); + over3-2-1: var(over3-2-1); + over3-2-1-0: var(over3-2-1-0) + }'''.encode()) + + # test with resolved vars + cssutils.ser.prefs.resolveVariables = True + self.assertEqual(s.cssText, '''@import "1.css"; +a { + local0: 0; + local1: 1; + local2: 2; + local3: 3; + over1-0: 0; + over2-0: 0; + over3-0: 0; + over2-1: 1; + over3-1: 1; + over3-2: 2; + over2-1-0: 0; + over3-2-0: 0; + over3-2-1: 1; + over3-2-1-0: 0 + }'''.encode()) + + + s = cssutils.resolveImports(s) + self.assertEqual(s.cssText, '''/* START @import "1.css" */ +/* START @import "3.css" */ +/* START @import "2.css" */ +a { + local0: 0; + local1: 1; + local2: 2; + local3: 3; + over1-0: 0; + over2-0: 0; + over3-0: 0; + over2-1: 1; + over3-1: 1; + over3-2: 2; + over2-1-0: 0; + over3-2-0: 0; + over3-2-1: 1; + over3-2-1-0: 0 + }'''.encode()) + + def test_parentRule(self): + "CSSVariablesDeclaration.parentRule" + s = cssutils.parseString(u'@variables { a:1}') + r = s.cssRules[0] + d = r.variables + self.assertEqual(r, d.parentRule) + + d2 = cssutils.css.CSSVariablesDeclaration('b: 2') + r.variables = d2 + self.assertEqual(r, d2.parentRule) + + def test_reprANDstr(self): + "CSSVariablesDeclaration.__repr__(), .__str__()" + s = cssutils.css.CSSVariablesDeclaration(cssText='a:1;b:2') + + self.assert_("2" in str(s)) # length + + s2 = eval(repr(s)) + self.assert_(isinstance(s2, s.__class__)) + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_cssvariablesrule.py cssutils-0.9.10/src/cssutils/tests/test_cssvariablesrule.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_cssvariablesrule.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_cssvariablesrule.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,155 @@ +"""Testcases for cssutils.css.CSSPageRule""" +__version__ = '$Id: test_csspagerule.py 1869 2009-10-17 19:37:40Z cthedot $' + +import xml.dom +import test_cssrule +import cssutils + +class CSSVariablesRuleTestCase(test_cssrule.CSSRuleTestCase): + + def setUp(self): + super(CSSVariablesRuleTestCase, self).setUp() + self.r = cssutils.css.CSSVariablesRule() + self.rRO = cssutils.css.CSSVariablesRule(readonly=True) + self.r_type = cssutils.css.CSSPageRule.VARIABLES_RULE + self.r_typeString = 'VARIABLES_RULE' + + cssutils.ser.prefs.resolveVariables = False + + def test_init(self): + "CSSVariablesRule.__init__()" + super(CSSVariablesRuleTestCase, self).test_init() + + r = cssutils.css.CSSVariablesRule() + self.assertEqual(cssutils.css.CSSVariablesDeclaration, + type(r.variables)) + self.assertEqual(r, r.variables.parentRule) + + # until any variables + self.assertEqual(u'', r.cssText) + + # only possible to set @... similar name + self.assertRaises(xml.dom.InvalidModificationErr, + self.r._setAtkeyword, 'x') + + def test_InvalidModificationErr(self): + "CSSVariablesRule.cssText InvalidModificationErr" + self._test_InvalidModificationErr(u'@variables') + tests = { + u'@var {}': xml.dom.InvalidModificationErr, + } + self.do_raise_r(tests) + + def test_incomplete(self): + "CSSVariablesRule (incomplete)" + tests = { + u'@variables { ': + u'', # no } and no content + u'@variables { x: red': + u'@variables {\n x: red\n }', # no } + } + self.do_equal_p(tests) # parse + + def test_cssText(self): + "CSSVariablesRule" + EXP = u'@variables {\n margin: 0\n }' + tests = { + u'@variables {}': u'', + u'@variables {margin:0;}': EXP, + u'@variables {margin:0}': EXP, + u'@VaRIables { margin : 0 ; }': EXP, + u'@\\VaRIables { margin : 0 }': EXP, + + u'@variables {a:1;b:2}': + u'@variables {\n a: 1;\n b: 2\n }', + + # comments + u'@variables /*1*/ {margin:0;}': + u'@variables /*1*/ {\n margin: 0\n }', + u'@variables/*1*/{margin:0;}': + u'@variables /*1*/ {\n margin: 0\n }', + } + self.do_equal_r(tests) + self.do_equal_p(tests) + + def test_media(self): + "CSSVariablesRule.media" + r = cssutils.css.CSSVariablesRule() + self.assertRaises(AttributeError, r.__getattribute__, 'media') + self.assertRaises(AttributeError, r.__setattr__, 'media', '?') + + def test_variables(self): + "CSSVariablesRule.variables" + r = cssutils.css.CSSVariablesRule( + variables=cssutils.css.CSSVariablesDeclaration('x: 1')) + self.assertEqual(r, r.variables.parentRule) + + # cssText + r = cssutils.css.CSSVariablesRule() + r.cssText = u'@variables { x: 1 }' + vars1 = r.variables + self.assertEqual(r, r.variables.parentRule) + self.assertEqual(vars1, r.variables) + self.assertEqual(r.variables.cssText, u'x: 1') + self.assertEqual(r.cssText, u'@variables {\n x: 1\n }') + + r.cssText = u'@variables {y:2}' + self.assertEqual(r, r.variables.parentRule) + self.failIfEqual(vars1, r.variables) + self.assertEqual(r.variables.cssText, u'y: 2') + self.assertEqual(r.cssText, u'@variables {\n y: 2\n }') + + vars2 = r.variables + + # fail + try: + r.cssText = u'@variables {$:1}' + except xml.dom.DOMException, e: + pass + + self.assertEqual(vars2, r.variables) + self.assertEqual(r.variables.cssText, u'y: 2') + self.assertEqual(r.cssText, u'@variables {\n y: 2\n }') + + # var decl + vars3 = cssutils.css.CSSVariablesDeclaration('z: 3') + r.variables = vars3 + + self.assertEqual(r, r.variables.parentRule) + self.assertEqual(vars3, r.variables) + self.assertEqual(r.variables.cssText, u'z: 3') + self.assertEqual(r.cssText, u'@variables {\n z: 3\n }') + + # string + r.variables = 'a: x' + self.failIfEqual(vars3, r.variables) + self.assertEqual(r, r.variables.parentRule) + self.assertEqual(r.variables.cssText, u'a: x') + self.assertEqual(r.cssText, u'@variables {\n a: x\n }') + vars4 = r.variables + + # string fail + try: + r.variables = '$: x' + except xml.dom.DOMException, e: + pass + self.assertEqual(vars4, r.variables) + self.assertEqual(r, r.variables.parentRule) + self.assertEqual(r.variables.cssText, u'a: x') + self.assertEqual(r.cssText, u'@variables {\n a: x\n }') + + + def test_reprANDstr(self): + "CSSVariablesRule.__repr__(), .__str__()" + r = cssutils.css.CSSVariablesRule() + r.cssText = '@variables { xxx: 1 }' + self.assert_('xxx' in str(r)) + + r2 = eval(repr(r)) + self.assert_(isinstance(r2, r.__class__)) + self.assert_(r.cssText == r2.cssText) + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_domimplementation.py cssutils-0.9.10/src/cssutils/tests/test_domimplementation.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_domimplementation.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_domimplementation.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,42 @@ +"""Testcases for cssutils.css.DOMImplementation""" + +import xml.dom +import unittest +import cssutils + +class DOMImplementationTestCase(unittest.TestCase): + + def setUp(self): + self.domimpl = xml.dom.getDOMImplementation() + + def test_createCSSStyleSheet(self): + "DOMImplementationCSS.createCSSStyleSheet()" + title, media = 'Test Title', cssutils.stylesheets.MediaList('all') + sheet = self.domimpl.createCSSStyleSheet(title, media) + self.assertEqual(True, isinstance(sheet, cssutils.css.CSSStyleSheet)) + self.assertEqual(title, sheet.title) + self.assertEqual(media, sheet.media) + + def test_createDocument(self): + "DOMImplementationCSS.createDocument()" + self.assertRaises(NotImplementedError, self.domimpl.createDocument) + self.assertRaises(NotImplementedError, self.domimpl.createDocument) + + def test_createDocumentType(self): + "DOMImplementationCSS.createDocumentType()" + self.assertRaises(NotImplementedError, self.domimpl.createDocumentType) + + def test_hasFeature(self): + "DOMImplementationCSS.hasFeature()" + tests = [ + ('css', '1.0'), + ('css', '2.0'), + ('stylesheets', '1.0'), + ('stylesheets', '2.0') + ] + for name, version in tests: + self.assertEqual(True, self.domimpl.hasFeature(name, version)) + + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_encutils/__init__.py cssutils-0.9.10/src/cssutils/tests/test_encutils/__init__.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_encutils/__init__.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_encutils/__init__.py 2013-03-31 18:19:52.000000000 +0000 @@ -0,0 +1,409 @@ +# -*- coding: utf-8 -*- +""" +tests for encutils.py +""" +import httplib +from StringIO import StringIO +import sys +import unittest + +PY2x = sys.version_info < (3,0) + +try: + import cssutils.encutils as encutils +except ImportError: + import encutils + +# helper log +log = encutils.buildlog(stream=StringIO()) + +class AutoEncodingTestCase(unittest.TestCase): + + def _fakeRes(self, content): + "build a fake HTTP response" + class FakeRes: + def __init__(self, content): + if PY2x: + fp = StringIO(content) + self._info = httplib.HTTPMessage(fp) + else: + self._info = httplib.HTTPMessage() + # Adjust to testdata. + l = content.split(':') + if len(l) > 1: + # Get the type by just + # using the data at the end. + t = l[-1].strip() + self._info.set_type(t) + + def info(self): + return self._info + + def read(self): + return content + + return FakeRes(content) + + def test_getTextTypeByMediaType(self): + "encutils._getTextTypeByMediaType" + tests = { + 'application/xml': encutils._XML_APPLICATION_TYPE, + 'application/xml-dtd': encutils._XML_APPLICATION_TYPE, + 'application/xml-external-parsed-entity': encutils._XML_APPLICATION_TYPE, + 'application/xhtml+xml': encutils._XML_APPLICATION_TYPE, + 'text/xml': encutils._XML_TEXT_TYPE, + 'text/xml-external-parsed-entity': encutils._XML_TEXT_TYPE, + 'text/xhtml+xml': encutils._XML_TEXT_TYPE, + 'text/html': encutils._HTML_TEXT_TYPE, + 'text/css': encutils._TEXT_UTF8, + 'text/plain': encutils._TEXT_TYPE, + 'x/x': encutils._OTHER_TYPE, + 'ANYTHING': encutils._OTHER_TYPE + } + for test, exp in tests.items(): + self.assertEqual( + exp, encutils._getTextTypeByMediaType(test, log=log)) + + def test_getTextType(self): + "encutils._getTextType" + tests = { + u'\x00\x00\xFE\xFF""": + (None, None), + """""": + (None, None), + + """""": + ('text/html', None), + + """""": + ('text/html', None), + """""": + ('text/html', 'ascii'), + + """""": + ('text/html', 'ascii'), + """""": + ('text/html', 'iso-8859-1'), + """""": + ('text/html', 'ascii'), + + """""": + ('text/html', 'ascii'), + """""": + ('text/html', 'ascii'), + """""": + ('text/html', 'ascii'), + + """""": + ('text/html', 'ascii'), + """""": + ('text/html', 'ascii'), + """""": + ('text/html', 'ascii'), + """""": + ('text/html', 'ascii'), + + """""": + ('text/html', 'ascii'), + """""": + ('text/html', 'ascii'), + """raises exception: """: + (None, None), + """ + """: + ('text/html', 'ascii'), + """ + """: + ('text/html', 'ascii'), + # py 2.7.3 fixed HTMLParser so: (None, None) + """ + + """: + ('text/html', None) + } + for test, exp in tests.items(): + self.assertEqual(exp, encutils.getMetaInfo(test, log=log)) + + def test_detectXMLEncoding(self): + "encutils.detectXMLEncoding" + tests = { + # BOM + ('utf_32_be'): u'\x00\x00\xFE\xFFanything', + ('utf_32_le'): u'\xFF\xFE\x00\x00anything', + ('utf_16_be'): u'\xFE\xFFanything', + ('utf_16_le'): u'\xFF\xFEanything', + ('utf-8'): u'\xef\xbb\xbfanything', + # encoding= + ('ascii'): '', + ('ascii'): "", + ('iso-8859-1'): "", + # default + ('utf-8'): '', + ('utf-8'): '' + } + for exp, test in tests.items(): + self.assertEqual(exp, encutils.detectXMLEncoding(test, log=log)) + + def test_tryEncodings(self): + "encutils.tryEncodings" + try: + import chardet + tests = [ + ('ascii', u'abc'.encode('ascii')), + ('windows-1252', u'€'.encode('windows-1252')), + ('ascii', u'1'.encode('utf-8')) + ] + except ImportError: + tests = [ + ('ascii', u'abc'.encode('ascii')), + ('windows-1252', u'€'.encode('windows-1252')), + ('iso-8859-1', u'äöüß'.encode('iso-8859-1')), + ('iso-8859-1', u'äöüß'.encode('windows-1252')), + #('utf-8', u'\u1111'.encode('utf-8')) + ] + for exp, test in tests: + self.assertEqual(exp, encutils.tryEncodings(test)) + + + def test_getEncodingInfo(self): + "encutils.getEncodingInfo" + # (expectedencoding, expectedmismatch): (httpheader, filecontent) + tests = [ + + # --- application/xhtml+xml --- + + # header default and XML default + (('utf-8', False), ( + '''Content-Type: application/xhtml+xml''', + ''' + + + ''')), + # XML default + (('utf-8', False), ( + None, + ''' + + + ''')), + # meta is ignored! + (('utf-8', False), ( + '''Content-Type: application/xhtml+xml''', + ''' + + + ''')), + + # header enc and XML default + (('iso-h', True), ( + '''Content-Type: application/xhtml+xml;charset=iso-H''', + ''' + + + ''')), + + # mismatch header and XML explicit, header wins + (('iso-h', True), ( + '''Content-Type: application/xhtml+xml;charset=iso-H''', + ''' + ''')), + + # header == XML, meta ignored! + (('iso-h', False), ( + '''Content-Type: application/xhtml+xml;charset=iso-H''', + ''' + + + ''')), + + # XML only, meta ignored! + (('iso-x', False), ( + '''Content-Type: application/xhtml+xml''', + ''' + + + ''')), + + + # no text or not enough text: + (('iso-h', False), ('Content-Type: application/xml;charset=iso-h', + '1')), + (('utf-8', False), ('Content-Type: application/xml', + None)), + ((None, False), ('Content-Type: application/xml', + '1')), + + + # --- text/xml --- + + # default enc + (('ascii', False), ( + '''Content-Type: text/xml''', + ''' + + + ''')), + # default as XML ignored and meta completely ignored + (('ascii', False), ( + '''Content-Type: text/xml''', + ''' + + + ''')), + (('ascii', False), ('Content-Type: text/xml', + '1')), + (('ascii', False), ('Content-Type: text/xml', + None)), + + # header enc + (('iso-h', False), ( + '''Content-Type: text/xml;charset=iso-H''', + ''' + + + ''')), + + # header only, XML and meta ignored! + (('iso-h', False), ( + '''Content-Type: text/xml;charset=iso-H''', + ''' + ''')), + (('iso-h', False), ( + '''Content-Type: text/xml;charset=iso-H''', + ''' + + + ''')), + + + # --- text/html --- + + # default enc + (('iso-8859-1', False), ('Content-Type: text/html;', + '''''')), + (('iso-8859-1', False), ('Content-Type: text/html;', + None)), + + # header enc + (('iso-h', False), ('Content-Type: text/html;charset=iso-H', + '''''')), + # meta enc + (('iso-m', False), ('Content-Type: text/html', + '''''')), + + # mismatch header and meta, header wins + (('iso-h', True), ('Content-Type: text/html;charset=iso-H', + '''''')), + + # no header: + ((None, False), (None, + '''''')), + # no encoding at all + ((None, False), (None, + '''''')), + + + ((None, False), (None, + '''text''')), + + + # --- no header --- + + ((None, False), (None, '')), + (('iso-8859-1', False), ('''NoContentType''', + '''OnlyText''')), + (('iso-8859-1', False), ('Content-Type: text/html;', + None)), + (('iso-8859-1', False), ('Content-Type: text/html;', + '1')), + + # XML + (('utf-8', False), (None, + '''''')), + # meta ignored + (('utf-8', False), (None, + ''' + ''')), + + (('utf-8', False), ('Content-Type: text/css;', + '1')), + (('iso-h', False), ('Content-Type: text/css;charset=iso-h', + '1')), + # only header is used by encutils + (('utf-8', False), ('Content-Type: text/css', + '@charset "ascii";')), + + ] + for exp, test in tests: + header, text = test + if header: + res = encutils.getEncodingInfo(self._fakeRes(header), text) + else: + res = encutils.getEncodingInfo(text=text) + + res = (res.encoding, res.mismatch) + self.assertEqual(exp, res) + + +if __name__ == '__main__': + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_errorhandler.py cssutils-0.9.10/src/cssutils/tests/test_errorhandler.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_errorhandler.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_errorhandler.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,150 @@ +"""Tests for parsing which does not raise Exceptions normally""" +__version__ = '$Id: test_parse.py 1281 2008-06-04 21:12:29Z cthedot $' + +import logging +import StringIO +import sys +import xml.dom +import basetest +import cssutils + +class ErrorHandlerTestCase(basetest.BaseTestCase): + + def setUp(self): + "replace default log and ignore its output" + self._oldlog = cssutils.log._log + self._saved = cssutils.log.raiseExceptions + + cssutils.log.raiseExceptions = False + cssutils.log.setLog(logging.getLogger('IGNORED-CSSUTILS-TEST')) + + def tearDown(self): + "reset default log" + cssutils.log.setLog(self._oldlog) + # for tests only + cssutils.log.setLevel(logging.FATAL) + cssutils.log.raiseExceptions = self._saved + + def _setHandler(self): + "sets new handler and returns StringIO instance to getvalue" + s = StringIO.StringIO() + h = logging.StreamHandler(s) + h.setFormatter(logging.Formatter('%(levelname)s %(message)s')) + # remove if present already + cssutils.log.removeHandler(h) + cssutils.log.addHandler(h) + return s + + def test_calls(self): + "cssutils.log.*" + s = self._setHandler() + cssutils.log.setLevel(logging.DEBUG) + cssutils.log.debug('msg', neverraise=True) + self.assertEqual(s.getvalue(), u'DEBUG msg\n') + + s = self._setHandler() + cssutils.log.setLevel(logging.INFO) + cssutils.log.info('msg', neverraise=True) + self.assertEqual(s.getvalue(), u'INFO msg\n') + + s = self._setHandler() + cssutils.log.setLevel(logging.WARNING) + cssutils.log.warn('msg', neverraise=True) + self.assertEqual(s.getvalue(), u'WARNING msg\n') + + s = self._setHandler() + cssutils.log.setLevel(logging.ERROR) + cssutils.log.error('msg', neverraise=True) + self.assertEqual(s.getvalue(), u'ERROR msg\n') + + s = self._setHandler() + cssutils.log.setLevel(logging.FATAL) + cssutils.log.fatal('msg', neverraise=True) + self.assertEqual(s.getvalue(), u'CRITICAL msg\n') + + s = self._setHandler() + cssutils.log.setLevel(logging.CRITICAL) + cssutils.log.critical('msg', neverraise=True) + self.assertEqual(s.getvalue(), u'CRITICAL msg\n') + + s = self._setHandler() + cssutils.log.setLevel(logging.CRITICAL) + cssutils.log.error('msg', neverraise=True) + self.assertEqual(s.getvalue(), u'') + + def test_linecol(self): + "cssutils.log line col" + o = cssutils.log.raiseExceptions + cssutils.log.raiseExceptions = True + + s = cssutils.css.CSSStyleSheet() + try: + s.cssText = '@import x;' + except xml.dom.DOMException, e: + self.assertEqual(str(e), 'CSSImportRule: Unexpected ident. [1:9: x]') + self.assertEqual(e.line, 1) + self.assertEqual(e.col, 9) + if sys.platform.startswith('java'): + self.assertEqual(e.msg, u'CSSImportRule: Unexpected ident. [1:9: x]') + else: + self.assertEqual(e.args, (u'CSSImportRule: Unexpected ident. [1:9: x]',)) + + cssutils.log.raiseExceptions = o + + def test_handlers(self): + "cssutils.log" + s = self._setHandler() + + cssutils.log.setLevel(logging.FATAL) + self.assertEqual(cssutils.log.getEffectiveLevel(), logging.FATAL) + + cssutils.parseString('a { color: 1 }') + self.assertEqual(s.getvalue(), u'') + + cssutils.log.setLevel(logging.DEBUG) + cssutils.parseString('a { color: 1 }') + # TODO: Fix? +# self.assertEqual(s.getvalue(), +# u'ERROR Property: Invalid value for "CSS Color Module Level 3/CSS Level 2.1" property: 1 [1:5: color]\n') + self.assertEqual(s.getvalue(), + u'ERROR Property: Invalid value for "CSS Level 2.1" property: 1 [1:5: color]\n') + + s = self._setHandler() + + cssutils.log.setLevel(logging.ERROR) + cssutils.parseUrl('http://example.com') + self.assertEqual(s.getvalue()[:38], + u'ERROR Expected "text/css" mime type') + + def test_parsevalidation(self): + style = 'color: 1' + t = 'a { %s }' % style + + cssutils.log.setLevel(logging.DEBUG) + + # sheet + s = self._setHandler() + cssutils.parseString(t) + self.assertNotEqual(len(s.getvalue()), 0) + + s = self._setHandler() + cssutils.parseString(t, validate=False) + self.assertEqual(s.getvalue(), '') + + # style + s = self._setHandler() + cssutils.parseStyle(style) + self.assertNotEqual(len(s.getvalue()), 0) + + s = self._setHandler() + cssutils.parseStyle(style, validate=True) + self.assertNotEqual(len(s.getvalue()), 0) + + s = self._setHandler() + cssutils.parseStyle(style, validate=False) + self.assertEqual(s.getvalue(), '') + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_helper.py cssutils-0.9.10/src/cssutils/tests/test_helper.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_helper.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_helper.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,89 @@ +# -*- coding: utf-8 -*- +"""Testcases for cssutils.helper""" +__version__ = '$Id: test_util.py 1437 2008-08-18 20:30:38Z cthedot $' + +import basetest +from cssutils.helper import * + +class HelperTestCase(basetest.BaseTestCase): + + def test_normalize(self): + "helper._normalize()" + tests = {u'abcdefg ABCDEFG äöü߀ AÖÜ': ur'abcdefg abcdefg äöü߀ aöü', + ur'\ga\Ga\\\ ': ur'gaga\ ', + ur'0123456789': ur'0123456789', + ur'"\x"': ur'"x"', + # unicode escape seqs should have been done by + # the tokenizer... + } + for test, exp in tests.items(): + self.assertEqual(normalize(test), exp) + # static too + self.assertEqual(normalize(test), exp) + +# def test_normalnumber(self): +# "helper.normalnumber()" +# tests = { +# '0': '0', +# '00': '0', +# '0.0': '0', +# '00.0': '0', +# '1': '1', +# '01': '1', +# '00.1': '0.1', +# '0.00001': '0.00001', +# '-0': '0', +# '-00': '0', +# '-0.0': '0', +# '-00.0': '0', +# '-1': '-1', +# '-01': '-1', +# '-00.1': '-0.1', +# '-0.00001': '-0.00001', +# } +# for test, exp in tests.items(): +# self.assertEqual(exp, normalnumber(test)) + + def test_string(self): + "helper.string()" + self.assertEqual(u'"x"', string(u'x')) + self.assertEqual(u'"1 2ä€"', string(u'1 2ä€')) + self.assertEqual(ur'''"'"''', string(u"'")) + self.assertEqual(ur'"\""', string(u'"')) + # \n = 0xa, \r = 0xd, \f = 0xc + self.assertEqual(ur'"\a "', string(''' +''')) + self.assertEqual(ur'"\c "', string('\f')) + self.assertEqual(ur'"\d "', string('\r')) + self.assertEqual(ur'"\d \a "', string('\r\n')) + + def test_stringvalue(self): + "helper.stringvalue()" + self.assertEqual(u'x', stringvalue(u'"x"')) + self.assertEqual(u'"', stringvalue(u'"\\""')) + self.assertEqual(ur'x', stringvalue(ur"\x ")) + + # escapes should have been done by tokenizer + # so this shoule not happen at all: + self.assertEqual(ur'a', stringvalue(ur"\a ")) + + def test_uri(self): + "helper.uri()" + self.assertEqual(u'url(x)', uri('x')) + self.assertEqual(u'url("(")', uri('(')) + self.assertEqual(u'url(")")', uri(')')) + self.assertEqual(u'url(" ")', uri(' ')) + self.assertEqual(u'url(";")', uri(';')) + self.assertEqual(u'url(",")', uri(',')) + self.assertEqual(u'url("x)x")', uri('x)x')) + + def test_urivalue(self): + "helper.urivalue()" + self.assertEqual(u'x', urivalue('url(x)')) + self.assertEqual(u'x', urivalue('url("x")')) + self.assertEqual(u')', urivalue('url(")")')) + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_marginrule.py cssutils-0.9.10/src/cssutils/tests/test_marginrule.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_marginrule.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_marginrule.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,97 @@ +"""Testcases for cssutils.css.CSSPageRule""" + +import xml.dom +import test_cssrule +import cssutils + +class MarginRuleTestCase(test_cssrule.CSSRuleTestCase): + + def setUp(self): + super(MarginRuleTestCase, self).setUp() + + cssutils.ser.prefs.useDefaults() + self.r = cssutils.css.MarginRule() + self.rRO = cssutils.css.MarginRule(readonly=True) + self.r_type = cssutils.css.MarginRule.MARGIN_RULE + self.r_typeString = 'MARGIN_RULE' + + def tearDown(self): + cssutils.ser.prefs.useDefaults() + + def test_init(self): + "MarginRule.__init__()" + + r = cssutils.css.MarginRule() + self.assertEqual(r.margin, None) + self.assertEqual(r.atkeyword, None) + self.assertEqual(r._keyword, None) + self.assertEqual(r.style.cssText, u'') + self.assertEqual(r.cssText, u'') + + r = cssutils.css.MarginRule(margin=u'@TOP-left') + self.assertEqual(r.margin, u'@top-left') + self.assertEqual(r.atkeyword, u'@top-left') + self.assertEqual(r._keyword, u'@TOP-left') + self.assertEqual(r.style.cssText, u'') + self.assertEqual(r.cssText, u'') + + self.assertRaises(xml.dom.InvalidModificationErr, cssutils.css.MarginRule, u'@x') + + def test_InvalidModificationErr(self): + "MarginRule.cssText InvalidModificationErr" + # TODO: !!! +# self._test_InvalidModificationErr(u'@top-left') +# tests = { +# u'@x {}': xml.dom.InvalidModificationErr, +# } +# self.do_raise_r(tests) + + def test_incomplete(self): + "MarginRule (incomplete)" + # must be inside @page as not valid outside + tests = { + u'@page { @top-left { ': u'', # no } and no content + u'@page { @top-left { /*1*/ ': u'', # no } and no content + u'@page { @top-left { color: red': + u'@page {\n @top-left {\n color: red\n }\n }' + } + self.do_equal_p(tests) # parse + + def test_cssText(self): + tests = { + u'@top-left {}': u'', + u'@top-left { /**/ }': u'', + u'@top-left { color: red }': u'@top-left {\n color: red\n }', + u'@top-left{color:red;}': u'@top-left {\n color: red\n }', + u'@top-left{color:red}': u'@top-left {\n color: red\n }', + u'@top-left { color: red; left: 0 }': u'@top-left {\n color: red;\n left: 0\n }' + } + self.do_equal_r(tests) + + # TODO + tests.update({ + # false selector +# u'@top-left { color:': xml.dom.SyntaxErr, # no } +# u'@top-left { color': xml.dom.SyntaxErr, # no } +# u'@top-left {': xml.dom.SyntaxErr, # no } +# u'@top-left': xml.dom.SyntaxErr, # no } +# u'@top-left;': xml.dom.SyntaxErr, # no } + }) +# self.do_raise_r(tests) # set cssText + + + def test_reprANDstr(self): + "MarginRule.__repr__(), .__str__()" + margin = u'@top-left' + + s = cssutils.css.MarginRule(margin=margin, style=u'left: 0') + + self.assert_(margin in str(s)) + + s2 = eval(repr(s)) + self.assert_(isinstance(s2, s.__class__)) + self.assert_(margin == s2.margin) + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_medialist.py cssutils-0.9.10/src/cssutils/tests/test_medialist.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_medialist.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_medialist.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,196 @@ +# -*- coding: iso-8859-1 -*- +"""Testcases for cssutils.stylesheets.MediaList""" + +import xml.dom +import basetest +import cssutils.stylesheets + +class MediaListTestCase(basetest.BaseTestCase): + + def setUp(self): + super(MediaListTestCase, self).setUp() + self.r = cssutils.stylesheets.MediaList() + + def test_set(self): + "MediaList.mediaText 1" + ml = cssutils.stylesheets.MediaList() + + self.assertEqual(0, ml.length) + self.assertEqual(u'all', ml.mediaText) + + ml.mediaText = u' print , screen ' + self.assertEqual(2, ml.length) + self.assertEqual(u'print, screen', ml.mediaText) + + self.assertRaisesMsg(xml.dom.InvalidModificationErr, + basetest.msg3x('''MediaList: Ignoring new medium cssutils.stylesheets.MediaQuery(mediaText=u'tv') as already specified "all" (set ``mediaText`` instead).'''), + ml._setMediaText, u' print , all , tv ') + + self.assertEqual(u'all', ml.mediaText) + self.assertEqual(1, ml.length) + + self.assertRaises(xml.dom.InvalidCharacterErr, + ml.appendMedium, u'test') + + def test_appendMedium(self): + "MediaList.appendMedium() 1" + ml = cssutils.stylesheets.MediaList() + + ml.appendMedium(u'print') + self.assertEqual(1, ml.length) + self.assertEqual(u'print', ml.mediaText) + + ml.appendMedium(u'screen') + self.assertEqual(2, ml.length) + self.assertEqual(u'print, screen', ml.mediaText) + + # automatic del and append! + ml.appendMedium(u'print') + self.assertEqual(2, ml.length) + self.assertEqual(u'screen, print', ml.mediaText) + + # automatic del and append! + ml.appendMedium(u'SCREEN') + self.assertEqual(2, ml.length) + self.assertEqual(u'print, SCREEN', ml.mediaText) + + # append invalid MediaQuery + mq = cssutils.stylesheets.MediaQuery() + ml.appendMedium(mq) + self.assertEqual(2, ml.length) + self.assertEqual(u'print, SCREEN', ml.mediaText) + + # append() + mq = cssutils.stylesheets.MediaQuery('tv') + ml.append(mq) + self.assertEqual(3, ml.length) + self.assertEqual(u'print, SCREEN, tv', ml.mediaText) + + # __setitem__ + self.assertRaises(IndexError, ml.__setitem__, 10, 'all') + ml[0] = 'handheld' + self.assertEqual(3, ml.length) + self.assertEqual(u'handheld, SCREEN, tv', ml.mediaText) + + def test_appendAll(self): + "MediaList.append() 2" + ml = cssutils.stylesheets.MediaList() + ml.appendMedium(u'print') + ml.appendMedium(u'tv') + self.assertEqual(2, ml.length) + self.assertEqual(u'print, tv', ml.mediaText) + + ml.appendMedium(u'all') + self.assertEqual(1, ml.length) + self.assertEqual(u'all', ml.mediaText) + + self.assertRaisesMsg(xml.dom.InvalidModificationErr, + basetest.msg3x('''MediaList: Ignoring new medium cssutils.stylesheets.MediaQuery(mediaText=u'tv') as already specified "all" (set ``mediaText`` instead).'''), + ml.appendMedium, 'tv') + self.assertEqual(1, ml.length) + self.assertEqual(u'all', ml.mediaText) + + self.assertRaises(xml.dom.InvalidCharacterErr, ml.appendMedium, u'test') + + def test_append2All(self): + "MediaList all" + ml = cssutils.stylesheets.MediaList() + ml.appendMedium(u'all') + self.assertRaisesMsg(xml.dom.InvalidModificationErr, + basetest.msg3x('''MediaList: Ignoring new medium cssutils.stylesheets.MediaQuery(mediaText=u'print') as already specified "all" (set ``mediaText`` instead).'''), + ml.appendMedium, 'print') + + sheet = cssutils.parseString('@media all, print { /**/ }') + self.assertEqual(u'@media all {\n /**/\n }'.encode(), sheet.cssText) + + def test_delete(self): + "MediaList.deleteMedium()" + ml = cssutils.stylesheets.MediaList() + + self.assertRaises(xml.dom.NotFoundErr, ml.deleteMedium, u'all') + self.assertRaises(xml.dom.NotFoundErr, ml.deleteMedium, u'test') + + ml.appendMedium(u'print') + ml.deleteMedium(u'print') + ml.appendMedium(u'tV') + ml.deleteMedium(u'Tv') + self.assertEqual(0, ml.length) + self.assertEqual(u'all', ml.mediaText) + + def test_item(self): + "MediaList.item()" + ml = cssutils.stylesheets.MediaList() + ml.appendMedium(u'print') + ml.appendMedium(u'screen') + + self.assertEqual(u'print', ml.item(0)) + self.assertEqual(u'screen', ml.item(1)) + self.assertEqual(None, ml.item(2)) + + def test_handheld(self): + "MediaList handheld" + ml = cssutils.stylesheets.MediaList() + + ml.mediaText = u' handheld , all ' + self.assertEqual(2, ml.length) + self.assertEqual(u'all, handheld', ml.mediaText) + + self.assertRaisesMsg(xml.dom.InvalidModificationErr, + basetest.msg3x('''MediaList: Ignoring new medium cssutils.stylesheets.MediaQuery(mediaText=u'tv') as already specified "all" (set ``mediaText`` instead).'''), + ml._setMediaText, u' handheld , all , tv ') + + def test_mediaText(self): + "MediaList.mediaText 2" + tests = { + u'': u'all', + u'ALL': u'ALL', + u'Tv': u'Tv', + u'all': None, + u'all, handheld': None, + u'tv': None, + u'tv, handheld, print': None, + u'tv and (color), handheld and (width: 1px) and (color)': None, + } + self.do_equal_r(tests, att='mediaText') + + tests = { + u'UNKNOWN': xml.dom.InvalidCharacterErr, + u'a,b': xml.dom.InvalidCharacterErr, + u'a and (color)': xml.dom.InvalidCharacterErr, + u'not': xml.dom.SyntaxErr, # known but need media + u'only': xml.dom.SyntaxErr, # known but need media + u'not tv,': xml.dom.SyntaxErr, # known but need media + u'all;': xml.dom.SyntaxErr, + u'all, and(color)': xml.dom.SyntaxErr, + u'all,': xml.dom.SyntaxErr, + u'all, ': xml.dom.SyntaxErr, + u'all ,': xml.dom.SyntaxErr, + u'all, /*1*/': xml.dom.SyntaxErr, + u'all and (color),': xml.dom.SyntaxErr, + u'all tv, print': xml.dom.SyntaxErr, + } + self.do_raise_r(tests, att='_setMediaText') + + def test_comments(self): + "MediaList.mediaText comments" + tests = { + u'/*1*/ tv /*2*/, /*3*/ handheld /*4*/, print': None, + } + self.do_equal_r(tests, att='mediaText') + + def test_reprANDstr(self): + "MediaList.__repr__(), .__str__()" + mediaText='tv, print' + + s = cssutils.stylesheets.MediaList(mediaText=mediaText) + + self.assert_(mediaText in str(s)) + + s2 = eval(repr(s)) + self.assert_(isinstance(s2, s.__class__)) + self.assert_(mediaText == s2.mediaText) + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_mediaquery.py cssutils-0.9.10/src/cssutils/tests/test_mediaquery.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_mediaquery.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_mediaquery.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,102 @@ +# -*- coding: iso-8859-1 -*- +"""Testcases for cssutils.stylesheets.MediaList""" + +import xml.dom +import basetest +import cssutils.stylesheets + +class MediaQueryTestCase(basetest.BaseTestCase): + + def setUp(self): + super(MediaQueryTestCase, self).setUp() + self.r = cssutils.stylesheets.MediaQuery() + + def test_mediaText(self): + "MediaQuery.mediaText" + tests = { + u'all': None, + u'braille': None, + u'embossed': None, + u'handheld': None, + u'print': None, + u'projection': None, + u'screen': None, + u'speech': None, + u'tty': None, + u'tv': None, + u'ALL': None, + u'a\\ll': None, + u'not tv': None, + u'n\\ot t\\v': None, + u'only tv': None, + u'\\only \\tv': None, + u'PRINT': None, + u'NOT PRINT': None, + u'ONLY PRINT': None, + u'tv and (color)': None, + u'not tv and (color)': None, + u'only tv and (color)': None, + } + self.do_equal_r(tests, att='mediaText') + + tests = { + u'': xml.dom.SyntaxErr, + u'two values': xml.dom.SyntaxErr, + u'or even three': xml.dom.SyntaxErr, + u'print and(color)': xml.dom.SyntaxErr, # a function + u'aural': xml.dom.InvalidCharacterErr, # a dimension + u'3d': xml.dom.InvalidCharacterErr, # a dimension + } + self.do_raise_r(tests, att='_setMediaText') + + def test_mediaType(self): + "MediaQuery.mediaType" + mq = cssutils.stylesheets.MediaQuery() + + self.assertEqual(u'', mq.mediaText) + + for mt in cssutils.stylesheets.MediaQuery.MEDIA_TYPES: + mq.mediaType = mt + self.assertEqual(mq.mediaType, mt) + mq.mediaType = mt.upper() + self.assertEqual(mq.mediaType, mt.upper()) + + mt = u'3D-UNKOwn-MEDIAtype0123' + #mq.mediaType = mt + self.assertRaises(xml.dom.InvalidCharacterErr, mq._setMediaType, mt) + + def test_comments(self): + "MediaQuery.mediaText comments" + tests = { + u'all': None, + u'print': None, + u'not print': None, + u'only print': None, + u'print and (color)': None, + u'print and (color) and (width)': None, + u'print and (color: 2)': None, + u'print and (min-width: 100px)': None, + u'print and (min-width: 100px) and (color: red)': None, + u'not print and (min-width: 100px)': None, + u'only print and (min-width: 100px)': None, + u'/*1*/ tv /*2*/': None, + u'/*0*/ only /*1*/ tv /*2*/': None, + u'/*0* /not /*1*/ tv /*2*/': None, + u'/*x*/ only /*x*/ print /*x*/ and /*x*/ (/*x*/min-width/*x*/: /*x*/ 100px /*x*/)': None, + u'print and/*1*/(color)': u'print and /*1*/ (color)' + } + self.do_equal_r(tests, att='mediaText') + + def test_reprANDstr(self): + "MediaQuery.__repr__(), .__str__()" + mediaText='tv and (color)' + s = cssutils.stylesheets.MediaQuery(mediaText=mediaText) + self.assert_(mediaText in str(s)) + s2 = eval(repr(s)) + self.assertEqual(mediaText, s2.mediaText) + self.assert_(isinstance(s2, s.__class__)) + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_parse.py cssutils-0.9.10/src/cssutils/tests/test_parse.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_parse.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_parse.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,496 @@ +# -*- coding: utf-8 -*- +"""Tests for parsing which does not raise Exceptions normally""" +from __future__ import with_statement + + +import sys +import xml.dom +import basetest +import cssutils +import urllib2 + +try: + import mock +except ImportError: + mock = None + print "install mock library to run all tests" + + +class CSSParserTestCase(basetest.BaseTestCase): + + def _make_fetcher(self, encoding, content): + "make an URL fetcher with specified data" + def fetcher(url): + return encoding, content + return fetcher + + def setUp(self): + self._saved = cssutils.log.raiseExceptions + + def tearDown(self): + cssutils.log.raiseExceptions = self._saved + + def test_init(self): + "CSSParser.__init__()" + self.assertEqual(True, cssutils.log.raiseExceptions) + + # also the default: + cssutils.log.raiseExceptions = True + + # default non raising parser + p = cssutils.CSSParser() + s = p.parseString('$') + self.assertEqual(s.cssText, u''.encode()) + + # explicit raiseExceptions=False + p = cssutils.CSSParser(raiseExceptions=False) + s = p.parseString('$') + self.assertEqual(s.cssText, u''.encode()) + + # working with sheet does raise though! + self.assertRaises(xml.dom.DOMException, s.__setattr__, u'cssText', u'$') + + # ---- + + # raiseExceptions=True + p = cssutils.CSSParser(raiseExceptions=True) + self.assertRaises(xml.dom.SyntaxErr, p.parseString, u'$') + + # working with a sheet does raise too + s = cssutils.css.CSSStyleSheet() + self.assertRaises(xml.dom.DOMException, s.__setattr__, u'cssText', u'$') + + # RESET cssutils.log.raiseExceptions + cssutils.log.raiseExceptions = False + s = cssutils.css.CSSStyleSheet() + # does not raise! + s.__setattr__(u'cssText', u'$') + self.assertEqual(s.cssText, ''.encode()) + + def test_parseComments(self): + "cssutils.CSSParser(parseComments=False)" + css = u'/*1*/ a { color: /*2*/ red; }' + + p = cssutils.CSSParser(parseComments=False) + self.assertEqual(p.parseString(css).cssText, + u'a {\n color: red\n }'.encode()) + p = cssutils.CSSParser(parseComments=True) + self.assertEqual(p.parseString(css).cssText, + u'/*1*/\na {\n color: /*2*/ red\n }'.encode()) + +# def test_parseFile(self): +# "CSSParser.parseFile()" +# # see test_cssutils + + def test_parseUrl(self): + "CSSParser.parseUrl()" + if mock: + # parseUrl(self, href, encoding=None, media=None, title=None): + parser = cssutils.CSSParser() + m = mock.Mock() + with mock.patch('cssutils.util._defaultFetcher', m): + m.return_value = (None, '') + sheet = parser.parseUrl('http://example.com', + media='tv,print', + title='test') + + self.assertEqual(sheet.href, u'http://example.com') + self.assertEqual(sheet.encoding, u'utf-8') + self.assertEqual(sheet.media.mediaText, u'tv, print') + self.assertEqual(sheet.title, u'test') + + # URL and content tests + tests = { + # (url, content): isSheet, encoding, cssText + ('', None): (False, None, None), + ('1', None): (False, None, None), + ('mailto:a@bb.cd', None): (False, None, None), + ('http://cthedot.de/test.css', None): (False, None, None), + ('http://cthedot.de/test.css', ''): (True, u'utf-8', u''), + ('http://cthedot.de/test.css', 'a'): (True, u'utf-8', u''), + ('http://cthedot.de/test.css', 'a {color: red}'): (True, u'utf-8', + u'a {\n color: red\n }'), + ('http://cthedot.de/test.css', 'a {color: red}'): (True, u'utf-8', + u'a {\n color: red\n }'), + ('http://cthedot.de/test.css', '@charset "ascii";a {color: red}'): (True, u'ascii', + u'@charset "ascii";\na {\n color: red\n }'), + } + override = 'iso-8859-1' + overrideprefix = u'@charset "iso-8859-1";' + httpencoding = None + + for (url, content), (isSheet, expencoding, cssText) in tests.items(): + parser.setFetcher(self._make_fetcher(httpencoding, content)) + sheet1 = parser.parseUrl(url) + sheet2 = parser.parseUrl(url, encoding=override) + if isSheet: + self.assertEqual(sheet1.encoding, expencoding) + self.assertEqual(sheet1.cssText, cssText.encode()) + self.assertEqual(sheet2.encoding, override) + if sheet1.cssText and cssText.startswith('@charset'): + self.assertEqual(sheet2.cssText, (cssText.replace('ascii', override).encode())) + elif sheet1.cssText: + self.assertEqual(sheet2.cssText, (overrideprefix + '\n' + cssText).encode()) + else: + self.assertEqual(sheet2.cssText, (overrideprefix + cssText).encode()) + else: + self.assertEqual(sheet1, None) + self.assertEqual(sheet2, None) + + parser.setFetcher(None) + + self.assertRaises(ValueError, parser.parseUrl, '../not-valid-in-urllib') + self.assertRaises(urllib2.HTTPError, parser.parseUrl, 'http://cthedot.de/not-present.css') + + else: + self.assertEqual(False, u'Mock needed for this test') + + def test_parseString(self): + "CSSParser.parseString()" + tests = { + # (byte) string, encoding: encoding, cssText + ('/*a*/', None): (u'utf-8', u'/*a*/'.encode('utf-8')), + ('/*a*/', 'ascii'): (u'ascii', u'@charset "ascii";\n/*a*/'.encode('ascii')), + + # org + #('/*\xc3\xa4*/', None): (u'utf-8', u'/*\xc3\xa4*/'.encode('utf-8')), + #('/*\xc3\xa4*/', 'utf-8'): (u'utf-8', u'@charset "utf-8";\n/*\xc3\xa4*/'.encode('utf-8')), + # new for 2.x and 3.x + (u'/*\xe4*/'.encode('utf-8'), None): (u'utf-8', u'/*\xe4*/'.encode('utf-8')), + (u'/*\xe4*/'.encode('utf-8'), 'utf-8'): (u'utf-8', u'@charset "utf-8";\n/*\xe4*/'.encode('utf-8')), + + ('@charset "ascii";/*a*/', None): (u'ascii', u'@charset "ascii";\n/*a*/'.encode('ascii')), + ('@charset "utf-8";/*a*/', None): (u'utf-8', u'@charset "utf-8";\n/*a*/'.encode('utf-8')), + ('@charset "iso-8859-1";/*a*/', None): (u'iso-8859-1', u'@charset "iso-8859-1";\n/*a*/'.encode('iso-8859-1')), + + # unicode string, no encoding: encoding, cssText + (u'/*€*/', None): ( + u'utf-8', u'/*€*/'.encode('utf-8')), + (u'@charset "iso-8859-1";/*ä*/', None): ( + u'iso-8859-1', u'@charset "iso-8859-1";\n/*ä*/'.encode('iso-8859-1')), + (u'@charset "utf-8";/*€*/', None): ( + u'utf-8', u'@charset "utf-8";\n/*€*/'.encode('utf-8')), + (u'@charset "utf-16";/**/', None): ( + u'utf-16', u'@charset "utf-16";\n/**/'.encode('utf-16')), + # unicode string, encoding utf-8: encoding, cssText + (u'/*€*/', 'utf-8'): ('utf-8', + u'@charset "utf-8";\n/*€*/'.encode('utf-8')), + (u'@charset "iso-8859-1";/*ä*/', 'utf-8'): ( + u'utf-8', u'@charset "utf-8";\n/*ä*/'.encode('utf-8')), + (u'@charset "utf-8";/*€*/', 'utf-8'): ( + u'utf-8', u'@charset "utf-8";\n/*€*/'.encode('utf-8')), + (u'@charset "utf-16";/**/', 'utf-8'): ( + u'utf-8', u'@charset "utf-8";\n/**/'.encode('utf-8')), + # probably not what is wanted but does not raise: + (u'/*€*/', 'ascii'): ( + u'ascii', u'@charset "ascii";\n/*\\20AC */'.encode('utf-8')), + (u'/*€*/', 'iso-8859-1'): ( + u'iso-8859-1', u'@charset "iso-8859-1";\n/*\\20AC */'.encode('utf-8')), + } + for test in tests: + css, encoding = test + sheet = cssutils.parseString(css, encoding=encoding) + encoding, cssText = tests[test] + self.assertEqual(encoding, sheet.encoding) + self.assertEqual(cssText, sheet.cssText) + + tests = [ + # encoded css, overiding encoding + (u'/*€*/'.encode('utf-16'), 'utf-8'), + (u'/*ä*/'.encode('iso-8859-1'), 'ascii'), + (u'/*€*/'.encode('utf-8'), 'ascii'), + (u'a'.encode('ascii'), 'utf-16'), + ] + for test in tests: + #self.assertEqual(None, cssutils.parseString(css, encoding=encoding)) + self.assertRaises(UnicodeDecodeError, cssutils.parseString, test[0], test[1]) + + def test_validate(self): + """CSSParser(validate)""" + style = 'color: red' + t = 'a { %s }' % style + + # helper + s = cssutils.parseString(t) + self.assertEqual(s.validating, True) + s = cssutils.parseString(t, validate=False) + self.assertEqual(s.validating, False) + s = cssutils.parseString(t, validate=True) + self.assertEqual(s.validating, True) + + d = cssutils.parseStyle(style) + self.assertEqual(d.validating, True) + d = cssutils.parseStyle(style, validate=True) + self.assertEqual(d.validating, True) + d = cssutils.parseStyle(style, validate=False) + self.assertEqual(d.validating, False) + + # parser + p = cssutils.CSSParser() + s = p.parseString(t) + self.assertEqual(s.validating, True) + s = p.parseString(t, validate=False) + self.assertEqual(s.validating, False) + s = p.parseString(t, validate=True) + self.assertEqual(s.validating, True) + d = p.parseStyle(style) + self.assertEqual(d.validating, True) + + p = cssutils.CSSParser(validate=True) + s = p.parseString(t) + self.assertEqual(s.validating, True) + s = p.parseString(t, validate=False) + self.assertEqual(s.validating, False) + s = p.parseString(t, validate=True) + self.assertEqual(s.validating, True) + d = p.parseStyle(style) + self.assertEqual(d.validating, True) + + p = cssutils.CSSParser(validate=False) + s = p.parseString(t) + self.assertEqual(s.validating, False) + s = p.parseString(t, validate=False) + self.assertEqual(s.validating, False) + s = p.parseString(t, validate=True) + self.assertEqual(s.validating, True) + d = p.parseStyle(style) + self.assertEqual(d.validating, False) + + # url + p = cssutils.CSSParser(validate=False) + p.setFetcher(self._make_fetcher('utf-8', t)) + u = 'url' + s = p.parseUrl(u) + self.assertEqual(s.validating, False) + s = p.parseUrl(u, validate=False) + self.assertEqual(s.validating, False) + s = p.parseUrl(u, validate=True) + self.assertEqual(s.validating, True) + + # check if it raises see log test + + + def test_fetcher(self): + """CSSParser.fetcher + + order: + 0. explicity given encoding OVERRIDE (cssutils only) + + 1. An HTTP "charset" parameter in a "Content-Type" field (or similar parameters in other protocols) + 2. BOM and/or @charset (see below) + 3. or other metadata from the linking mechanism (if any) + 4. charset of referring style sheet or document (if any) + 5. Assume UTF-8 + """ + tests = { + # css, encoding, (mimetype, encoding, importcss): + # encoding, importIndex, importEncoding, importText + + # 0/0 override/override => ASCII/ASCII + (u'@charset "utf-16"; @import "x";', 'ASCII', ('iso-8859-1', + u'@charset "latin1";/*t*/')): ( + 'ascii', 1, 'ascii', u'@charset "ascii";\n/*t*/'.encode()), + # 1/1 not tested her but same as next + # 2/1 @charset/HTTP => UTF-16/ISO-8859-1 + (u'@charset "UTF-16"; @import "x";', None, ('ISO-8859-1', + u'@charset "latin1";/*t*/')): ( + 'utf-16', 1, 'iso-8859-1', u'@charset "iso-8859-1";\n/*t*/'.encode('iso-8859-1')), + # 2/2 @charset/@charset => UTF-16/ISO-8859-1 + (u'@charset "UTF-16"; @import "x";', None, + (None, u'@charset "ISO-8859-1";/*t*/')): ( + 'utf-16', 1, 'iso-8859-1', u'@charset "iso-8859-1";\n/*t*/'.encode('iso-8859-1')), + # 2/4 @charset/referrer => ASCII/ASCII + ('@charset "ASCII"; @import "x";', None, (None, u'/*t*/')): ( + 'ascii', 1, 'ascii', u'@charset "ascii";\n/*t*/'.encode()), + # 5/5 default/default or referrer + ('@import "x";', None, (None, u'/*t*/')): ( + 'utf-8', 0, 'utf-8', u'/*t*/'.encode()), + # 0/0 override/override+unicode + ('@charset "utf-16"; @import "x";', 'ASCII', ( + None, u'@charset "latin1";/*\u0287*/')): ( + 'ascii', 1, 'ascii', u'@charset "ascii";\n/*\\287 */'.encode()), + # 2/1 @charset/HTTP+unicode + ('@charset "ascii"; @import "x";', None, ('iso-8859-1', u'/*\u0287*/')): ( + 'ascii', 1, 'iso-8859-1', u'@charset "iso-8859-1";\n/*\\287 */'.encode()), + # 2/4 @charset/referrer+unicode + ('@charset "ascii"; @import "x";', None, (None, u'/*\u0287*/')): ( + 'ascii', 1, 'ascii', u'@charset "ascii";\n/*\\287 */'.encode()), + # 5/1 default/HTTP+unicode + ('@import "x";', None, ('ascii', u'/*\u0287*/')): ( + 'utf-8', 0, 'ascii', u'@charset "ascii";\n/*\\287 */'.encode()), + # 5/5 default+unicode/default+unicode + ('@import "x";', None, (None, u'/*\u0287*/')): ( + 'utf-8', 0, 'utf-8', u'/*\u0287*/'.encode('utf-8')) + } + parser = cssutils.CSSParser() + for test in tests: + css, encoding, fetchdata = test + sheetencoding, importIndex, importEncoding, importText = tests[test] + + # use setFetcher + parser.setFetcher(self._make_fetcher(*fetchdata)) + # use init + parser2 = cssutils.CSSParser(fetcher=self._make_fetcher(*fetchdata)) + + sheet = parser.parseString(css, encoding=encoding) + sheet2 = parser2.parseString(css, encoding=encoding) + + # sheet + self.assertEqual(sheet.encoding, sheetencoding) + self.assertEqual(sheet2.encoding, sheetencoding) + # imported sheet + self.assertEqual(sheet.cssRules[importIndex].styleSheet.encoding, + importEncoding) + self.assertEqual(sheet2.cssRules[importIndex].styleSheet.encoding, + importEncoding) + self.assertEqual(sheet.cssRules[importIndex].styleSheet.cssText, + importText) + self.assertEqual(sheet2.cssRules[importIndex].styleSheet.cssText, + importText) + + def test_roundtrip(self): + "cssutils encodings" + css1 = ur'''@charset "utf-8"; +/* ä */''' + s = cssutils.parseString(css1) + css2 = unicode(s.cssText, 'utf-8') + self.assertEqual(css1, css2) + + s = cssutils.parseString(css2) + s.cssRules[0].encoding='ascii' + css3 = ur'''@charset "ascii"; +/* \E4 */''' + self.assertEqual(css3, unicode(s.cssText, 'utf-8')) + + def test_escapes(self): + "cssutils escapes" + css = ur'\43\x { \43\x: \43\x !import\41nt }' + sheet = cssutils.parseString(css) + self.assertEqual(sheet.cssText, ur'''C\x { + c\x: C\x !important + }'''.encode()) + + css = ur'\ x{\ x :\ x ;y:1} ' + sheet = cssutils.parseString(css) + self.assertEqual(sheet.cssText, ur'''\ x { + \ x: \ x; + y: 1 + }'''.encode()) + + def test_invalidstring(self): + "cssutils.parseString(INVALID_STRING)" + validfromhere = '@namespace "x";' + csss = ( + u'''@charset "ascii + ;''' + validfromhere, + u'''@charset 'ascii + ;''' + validfromhere, + u'''@namespace "y + ;''' + validfromhere, + u'''@import "y + ;''' + validfromhere, + u'''@import url('a + );''' + validfromhere, + u'''@unknown "y + ;''' + validfromhere) + for css in csss: + s = cssutils.parseString(css) + self.assertEqual(validfromhere.encode(), s.cssText) + + csss = (u'''a { font-family: "Courier + ; }''', + ur'''a { content: "\"; } + ''', + ur'''a { content: "\\\"; } + ''' + ) + for css in csss: + self.assertEqual(u''.encode(), cssutils.parseString(css).cssText) + + def test_invalid(self): + "cssutils.parseString(INVALID_CSS)" + tests = { + u'a {color: blue}} a{color: red} a{color: green}': + u'''a { + color: blue + } +a { + color: green + }''', + u'p @here {color: red} p {color: green}': u'p {\n color: green\n }' + } + + for css in tests: + exp = tests[css] + if exp == None: + exp = css + s = cssutils.parseString(css) + self.assertEqual(exp.encode(), s.cssText) + + def test_nesting(self): + "cssutils.parseString nesting" + # examples from csslist 27.11.2007 + tests = { + '@1; div{color:green}': u'div {\n color: green\n }', + '@1 []; div{color:green}': u'div {\n color: green\n }', + '@1 [{}]; div { color:green; }': u'div {\n color: green\n }', + '@media all { @ } div{color:green}': + u'div {\n color: green\n }', + # should this be u''? + '@1 { [ } div{color:green}': u'', + # red was eaten: + '@1 { [ } ] div{color:red}div{color:green}': u'div {\n color: green\n }', + } + for css, exp in tests.items(): + self.assertEqual(exp.encode(), cssutils.parseString(css).cssText) + + def test_specialcases(self): + "cssutils.parseString(special_case)" + tests = { + u''' + a[title="a not s\ +o very long title"] {/*...*/}''': u'''a[title="a not so very long title"] { + /*...*/ + }''' + } + for css in tests: + exp = tests[css] + if exp == None: + exp = css + s = cssutils.parseString(css) + self.assertEqual(exp.encode(), s.cssText) + + def test_iehack(self): + "IEhack: $property (not since 0.9.5b3)" + # $color is not color! + css = 'a { color: green; $color: red; }' + s = cssutils.parseString(css) + + p1 = s.cssRules[0].style.getProperty('color') + self.assertEqual('color', p1.name) + self.assertEqual('color', p1.literalname) + self.assertEqual('', s.cssRules[0].style.getPropertyValue('$color')) + + p2 = s.cssRules[0].style.getProperty('$color') + self.assertEqual(None, p2) + + self.assertEqual('green', s.cssRules[0].style.getPropertyValue('color')) + self.assertEqual('green', s.cssRules[0].style.color) + + def test_attributes(self): + "cssutils.parseString(href, media)" + s = cssutils.parseString("a{}", href="file:foo.css", media="screen, projection, tv") + self.assertEqual(s.href, "file:foo.css") + self.assertEqual(s.media.mediaText, "screen, projection, tv") + + s = cssutils.parseString("a{}", href="file:foo.css", media=["screen", "projection", "tv"]) + self.assertEqual(s.media.mediaText, "screen, projection, tv") + + def tearDown(self): + # needs to be reenabled here for other tests + cssutils.log.raiseExceptions = True + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_prodparser.py cssutils-0.9.10/src/cssutils/tests/test_prodparser.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_prodparser.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_prodparser.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,397 @@ +"""Testcases for cssutils.css.CSSCharsetRule""" +__version__ = '$Id: test_csscharsetrule.py 1356 2008-07-13 17:29:09Z cthedot $' + +import sys +import xml.dom +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.maxint + 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, u'Extra token')], + [(t1, p1), (t2, u'Extra token')] + ), + (p2, ): ([(t2, p2)], + [(t2, p2), (t2, u'Extra token')], + [(t2, p2), (t1, u'Extra token')], + [(t1, 'Missing token for production p2')] + ), + (p1, p2): ([(t1, p1), (t2, p2)], + [(t1, p1), (t1, u'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, u'Extra token')], + ), + (p1, ): ([(t1, p1)], + [(t2, 'Extra token')], + [(t1, p1), (t1, p1)], + [(t1, p1), (t2, 'Extra token')], + [(t1, p1), (t1, p1), (t1, u'Extra token')], + [(t1, p1), (t1, p1), (t2, u'Extra token')] + ), + # as p2 NOT optional + (p2, ): ([(t2, p2)], + [(t1, 'Missing token for production p2')], + [(t2, p2), (t2, p2)], + [(t2, p2), (t1, u'No matching production for token')], + [(t2, p2), (t2, p2), (t2, u'Extra token')], + [(t2, p2), (t2, p2), (t1, u'Extra token')] + ), + (p1, p2): ([(t1, p1), (t1, u'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, u'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, u'No match in Choice(p1, p2)', ch.nextProd, t0) + self.assertEqual(p1, ch.nextProd(t1)) + self.assertRaisesMsg(Exhausted, u'Extra token', ch.nextProd, t1) + + ch = Choice(p1, p2) + self.assertEqual(p2, ch.nextProd(t2)) + self.assertRaisesMsg(Exhausted, u'Extra token', ch.nextProd, t2) + + ch = Choice(p2, p1) + self.assertRaisesMsg(ParseError, 'No match in Choice(p2, p1)', ch.nextProd, t0) + self.assertEqual(p1, ch.nextProd(t1)) + self.assertRaisesMsg(Exhausted, u'Extra token', ch.nextProd, t1) + + ch = Choice(p2, p1) + self.assertEqual(p2, ch.nextProd(t2)) + self.assertRaisesMsg(Exhausted, u'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, u'No match in Choice(Sequence(p1, p1), Sequence(p2, p2))', ch.nextProd, t0) + self.assertEqual(s1, ch.nextProd(t1)) + self.assertRaisesMsg(Exhausted, u'Extra token', ch.nextProd, t1) + + ch = Choice(s1, s2) + self.assertEqual(s2, ch.nextProd(t2)) + self.assertRaisesMsg(Exhausted, u'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(';', u';'), + PreDef.char(':', u':') + ) + + 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(): + 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, u'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(): + 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, u'T: %s' % exp, + ProdParser().parse, text, 'T', prods) + + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_profiles.py cssutils-0.9.10/src/cssutils/tests/test_profiles.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_profiles.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_profiles.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,542 @@ +"""Testcases for cssutils.css.CSSValue and CSSPrimitiveValue.""" +__version__ = '$Id: test_cssvalue.py 1443 2008-08-31 13:54:39Z cthedot $' + +import sys +import basetest +import cssutils + +CSS2 = (cssutils.profile.CSS_LEVEL_2,) +C3BUI = (cssutils.profile.CSS3_BASIC_USER_INTERFACE,) +C3BB = (cssutils.profile.CSS3_BACKGROUNDS_AND_BORDERS,) +CM3 = (cssutils.profile.CSS3_COLOR,) +FM3 = (cssutils.profile.CSS3_FONTS,) +C3PM = (cssutils.profile.CSS3_PAGED_MEDIA,) +C3T = (cssutils.profile.CSS3_TEXT,) +FM3FF = (cssutils.profile.CSS3_FONT_FACE,) +CSS2_CM3 = (CM3[0], CSS2[0]) +CSS2_FM3 = (FM3[0], CSS2[0]) + + +class ProfilesTestCase(basetest.BaseTestCase): + M1 = { + 'testvalue': 'x' + } + P1 = { + '-test-tokenmacro': '({num}{w}){1,2}', + '-test-macro': '{ident}|{percentage}', + '-test-custommacro': '{testvalue}', + # custom validation function + '-test-funcval': lambda(v): int(v) > 0 + } + + def test_knownNames(self): + "Profiles.knownNames" + p = cssutils.profiles.Profiles() + p.removeProfile(all=True) + p.addProfile('test', self.P1, self.M1) + self.assertEqual(p.knownNames, self.P1.keys()) + p.removeProfile(all=True) + self.assertEqual(p.knownNames, []) + + def test_profiles(self): + "Profiles.profiles" + p = cssutils.profiles.Profiles() + p.removeProfile(all=True) + p.addProfile('test', self.P1, self.M1) + self.assertEqual(p.profiles, ['test']) + p.removeProfile(all=True) + self.assertEqual(p.profiles, []) + + def test_validate2(self): + "Profiles.validate()" + #save + saved = cssutils.profile + + # test + p = cssutils.profiles.Profiles() + cssutils.profile = p + + pvs = [('color', 'red'), + ('color', 'rgba(0,0,0,0)'), + ('color', 'XXX') + ] + + def check(*results): + for i, pv in enumerate(pvs): + self.assertEqual(p.validate(*pv), results[i]) + + check(True, True, False) + + p.removeProfile(p.CSS3_COLOR) + check(True, False, False) + + cssutils.profile.addProfile('test', {}, {'color': 'XXX'}) + check(False, False, True) + + p.removeProfile(all=True) + check(False, False, False) + + # TODO: validateWithProfile + + # restore + cssutils.profile = saved + + def test_addProfile(self): + "Profiles.addProfile with custom validation function" + # unknown profile + self.assertRaises(cssutils.profiles.NoSuchProfileException, + lambda: list(cssutils.profile.propertiesByProfile('NOTSET')) ) + + # new profile + cssutils.profile.addProfile('test', self.P1, self.M1) + + props = self.P1.keys() + props.sort() + self.assertEqual(props, list(cssutils.profile.propertiesByProfile('test'))) + + cssutils.log.raiseExceptions = False + tests = { + ('-test-tokenmacro', '1'): True, + ('-test-tokenmacro', '1 -2'): True, + ('-test-tokenmacro', '1 2 3'): False, + ('-test-tokenmacro', 'a'): False, + ('-test-macro', 'a'): True, + ('-test-macro', '0.1%'): True, + ('-test-custommacro', 'x'): True, + ('-test-custommacro', '1'): False, + ('-test-custommacro', 'y'): False, + ('-test-funcval', '1'): True, + ('-test-funcval', '-1'): False, + ('-test-funcval', 'x'): False + } + for test, v in tests.items(): + self.assertEqual(v, cssutils.profile.validate(*test)) + + self.assertEqual((v, v, ['test']), + cssutils.profile.validateWithProfile(*test)) + + cssutils.log.raiseExceptions = True + + # raises: + expmsg = u"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 = u"invalid literal for int(): x" + elif sys.platform.startswith('java'): + expmsg = u"invalid literal for int() with base 10: x" + + self.assertRaisesMsg(Exception, expmsg, + cssutils.profile.validate, u'-test-funcval', u'x') + + def test_removeProfile(self): + "Profiles.removeProfile()" + p = cssutils.profiles.Profiles() + self.assertEqual(9, len(p.profiles)) + p.removeProfile(p.CSS_LEVEL_2) + self.assertEqual(8, len(p.profiles)) + p.removeProfile(all=True) + self.assertEqual(0, len(p.profiles)) + + # TODO: FIX +# def test_validateWithProfile(self): +# "Profiles.validate(), Profiles.validateWithProfile()" +# p = cssutils.profiles.Profiles() +# tests = { +# ('color', 'red', None): (True, True, [p.CSS_LEVEL_2]), +# ('color', 'red', p.CSS_LEVEL_2): (True, True,[p.CSS_LEVEL_2]), +# ('color', 'red', p.CSS3_COLOR): (True, False, [p.CSS_LEVEL_2]), +# ('color', 'rgba(0,0,0,0)', None): (True, True, [p.CSS3_COLOR]), +# ('color', 'rgba(0,0,0,0)', p.CSS_LEVEL_2): (True, False, [p.CSS3_COLOR]), +# ('color', 'rgba(0,0,0,0)', p.CSS3_COLOR): (True, True, [p.CSS3_COLOR]), +# ('color', '1px', None): (False, False, [p.CSS3_COLOR, p.CSS_LEVEL_2]), +# ('color', '1px', p.CSS_LEVEL_2): (False, False, [p.CSS3_COLOR, p.CSS_LEVEL_2]), +# ('color', '1px', p.CSS3_COLOR): (False, False, [p.CSS3_COLOR, p.CSS_LEVEL_2]), +# ('color', 'aliceblue', None): (True, True, [p.CSS_LEVEL_2]), +# +# ('opacity', '1', None): (True, True, [p.CSS3_COLOR]), +# ('opacity', '1', p.CSS_LEVEL_2): (True, False, [p.CSS3_COLOR]), +# ('opacity', '1', p.CSS3_COLOR): (True, True, [p.CSS3_COLOR]), +# ('opacity', '1px', None): (False, False, [p.CSS3_COLOR]), +# ('opacity', '1px', p.CSS_LEVEL_2): (False, False, [p.CSS3_COLOR]), +# ('opacity', '1px', p.CSS3_COLOR): (False, False, [p.CSS3_COLOR]), +# +# ('-x', '1', None): (False, False, []), +# ('-x', '1', p.CSS_LEVEL_2): (False, False, []), +# ('-x', '1', p.CSS3_COLOR): (False, False, []), +# } +# for test, r in tests.items(): +# self.assertEqual(p.validate(test[0], test[1]), r[0]) +# self.assertEqual(p.validateWithProfile(*test), r) + + def test_propertiesByProfile(self): + "Profiles.propertiesByProfile" + self.assertEqual(['opacity'], #'color', + list(cssutils.profile.propertiesByProfile( + cssutils.profile.CSS3_COLOR))) + + def test_csscolorlevel3(self): + "CSS Color Module Level 3" + # (propname, propvalue): (valid, validprofile) + namedcolors = '''transparent, orange, + aqua, black, blue, fuchsia, gray, green, lime, maroon, + navy, olive, purple, red, silver, teal, white, yellow''' + for color in namedcolors.split(','): + color = color.strip() + self.assertEqual(True, cssutils.profile.validate('color', color)) + + self.assertEqual((True, True, list(CSS2)), + cssutils.profile.validateWithProfile('color', color)) + + # CSS2 only: + uicolor = 'ActiveBorder|ActiveCaption|AppWorkspace|Background|ButtonFace|ButtonHighlight|ButtonShadow|ButtonText|CaptionText|GrayText|Highlight|HighlightText|InactiveBorder|InactiveCaption|InactiveCaptionText|InfoBackground|InfoText|Menu|MenuText|Scrollbar|ThreeDDarkShadow|ThreeDFace|ThreeDHighlight|ThreeDLightShadow|ThreeDShadow|Window|WindowFrame|WindowText' + for color in uicolor.split('|'): + self.assertEqual(False, cssutils.profile.validate('color', color)) + + # TODO: Fix + #self.assertEqual((True, True, list(CSS2)), + # cssutils.profile.validateWithProfile('color', color)) + + def test_validate(self): + "Profiles.validate()" + tests = { + # name, values: valid, matching, profile + + # background-position + ('background-position', ('inherit', + '0', + '1%', + '1px', + '0 0', + '1% 1%', + '1px 1px', + '1px 1%', + 'top', 'bottom', + 'left', 'right', + 'center center', + 'center', + 'top left', 'top center', 'top right', + 'bottom left', 'bottom center', 'bottom right', + 'center left', 'center center', 'center right', + '0 center', 'center 0', + '0 top', '10% bottom', + 'left 0', 'right 10%', + '1% center', 'center 1%' + )): (True, True, CSS2), + ('background-position', ('0 left', + 'top 0' + )): (False, False, CSS2), + + + ('border-top-right-radius', ('1px', + '1%', + '1% -1px', + '1% 0', + )): (True, True, C3BB), + ('border-top-right-radius', ('1px 2px 2px', + '/ 1px', + 'black')): (False, False, C3BB), + + ('border-radius', ('1px', + '1%', + '0', + '1px 1px', + '1px/ 1px', + '1px /1px', + '1px / 1px', + '1px 1px 1px 1px', + '1px 1px 1px 1px / 1px 1px 1px 1px', + )): (True, True, C3BB), + ('border-radius', ('1px /', + '/ 1px', + '1px / 1px / 1px', + '1px 1px 1px 1px 1px', + '1px / 1px 1px 1px 1px 1px', + 'black')): (False, False, C3BB), + + ('border', ('1px', + 'solid', + 'red', + '1px solid red', + '1px red solid', + 'red 1px solid', + 'red solid 1px', + 'solid 1px red', + 'solid red 1px', + )): (True, True, C3BB), + ('border', ('1px 1px', + 'red red 1px', + )): (False, False, C3BB), + + ('box-shadow', ('none', + '1px 1px', + '1px 1px 1px', + '1px 1px 1px 1px', + '1px 1px 1px 1px red', + 'inset 1px 1px', + 'inset 1px 1px 1px 1px black')): (True, True, C3BB), + ('box-shadow', ('1px', + '1px 1px 1px 1px 1px', + 'x 1px 1px', + 'inset', + '1px black', + 'black')): (False, False, C3BB), + + # color + ('color', ('x', + '#', + '#0', + '#00', + '#0000', + '#00000', + '#0000000', + '#00j', + '#j00000', + 'rgb(0.0,1,1)', + 'rgb(0)', + 'rgb(0, 1)', + 'rgb(0, 1, 1, 1)', + 'rgb(0, 1, 0%)', + 'rgba(0)', + 'rgba(0, 1, 1.0, 1)', + 'rgba(0, 1)', + 'rgba(0, 1, 1, 1, 1)', + 'rgba(100%, 0%, 0%, 1%)', + 'rgba(100%, 0%, 0, 1)', + 'hsl(1.5,1%,1%)', + 'hsl(1,1,1%)', + 'hsl(1,1%,1)', + 'hsla(1.5,1%,1%, 1)', + 'hsla(1,1,1%, 1)', + 'hsla(1,1%,1, 1)', + 'hsla(1,1%,1%, 1%)' + )): (False,False, CSS2_CM3), + ('color', ('inherit', + 'black', + '#000', + '#000000', + 'rgb(0,1,1)', + 'rgb( 0 , 1 , 1 )', + 'rgb(-10,555,1)', + 'rgb(100%, 1.5%, 0%)', + 'rgb(150%, -20%, 0%)', + )): (True, True, CSS2), + ('color', ('currentcolor', + 'aliceblue', + 'rgba(1,1,1,1)', + 'rgba( 1 , 1 , 1 , 1 )', + 'rgba(100%, 0%, 0%, 1)', + 'hsl(1,1%,1%)', + 'hsl( 1 , 1% , 1% )', + 'hsl(-1000,555.5%,-61.5%)', + 'hsla(1,1%,1%,1)', + 'hsla( 1, 1% , 1% , 1 )', + 'hsla(-1000,555.5%,-61.5%, 0.5)' + )): (True, True, CM3), + # TODO?: + #('color', 'rgb(/**/ 0 /**/ , /**/ 1 /**/ , /**/ 1 /**/ )'): (True, True, CSS2), + + # content + ('content', ('none', + 'normal', + '""', + "'x'", + )): (True, True, CSS2), + + ('cursor', ('url(1), auto', + 'url(1) 2 3, help', + 'wait', + 'inherit', + 'none')): (True, True, C3BUI), + ('cursor', ('url(1), auto, wait', + 'url(1) 2, help', + '1')): (False, False, C3BUI), + + # FONTS + ('font-family', ('serif, x', + )): (True, True, CSS2), #CSS2_FM3), + + ('font-family', ('inherit', + 'a, b', + 'a,b,c', + 'a, "b", c', + '"a", b, "c"', + '"a", "b", "c"', + '"x y"', + 'serif', + '"serif"', # valid but CSS2: font with name serif, CSS3: same as `serif` + 'a b', # should use quotes but valid + 'a, b b, d', + )): (True, True, CSS2), + + ('font-weight', ('normal', 'bold', 'bolder', 'lighter', 'inherit', + '100', '200', '300', '400', '500', '600', '700', '800', '900' + )): (True, True, CSS2), + + ('font-stretch', ('normal', 'wider', 'narrower', 'ultra-condensed', + 'extra-condensed', 'condensed', 'semi-condensed', + 'semi-expanded', 'expanded', 'extra-expanded', + 'ultra-expanded', 'inherit' + )): (True, True, FM3), + + ('font-style', ('normal', 'italic', 'oblique', 'inherit' + )): (True, True, CSS2), + + ('font-variant', ('normal', 'small-caps', 'inherit' + )): (True, True, CSS2), + ('font-size', ('-1em', + )): (False, False, CSS2), + ('font-size', ('xx-small', 'x-small', 'small', 'medium', 'large', + 'x-large', 'xx-large', 'larger', 'smaller', + '1em', '1%', 'inherit' + )): (True, True, CSS2), + + ('font-size-adjust', ('1.0', + 'none', 'inherit' + )): (True, True, FM3), + + ('font', ('italic small-caps bold 1px/3 a, "b", serif', + '12pt/14pt sans-serif', + '80% sans-serif', + 'x-large/110% "new century schoolbook", serif', + 'bold italic large Palatino, serif', + 'normal small-caps 120%/120% fantasy', + 'oblique 12pt "Helvetica Nue", serif', + 'caption', 'icon', 'menu', 'message-box', 'small-caption', + 'status-bar', 'inherit' + )): (True, True, CSS2), + + ('nav-index', ('1', 'auto', 'inherit')): (True, True, C3BUI), + ('nav-index', ('x', '1 2', '1px')): (False, False, C3BUI), + + ('opacity', ('inherit', + '0', '0.0', '0.42342', '1', '1.0', + # should be clipped but valid + '-0', '-0.1', '-10', '2' + )): (True, True, CM3), + ('opacity', ('a', '#000', '+1')): (False, False, CM3), + + ('outline', ('red dotted 1px', + 'dotted 1px red', + '1px red dotted', + 'red', '1px', 'dotted', + 'red 1px', '1px dotted', 'red dotted', + 'inherit' + )): (True, True, C3BUI), + ('outline', ('red #fff', 'solid dotted', 'Url(x)', '1px 1px' + )): (False, False, C3BUI), + ('outline-color', ('red', '#fff', 'inherit' + )): (True, True, C3BUI), + ('outline-color', ('0', '1em' + )): (False, False, C3BUI), + ('outline-offset', ('0', '1em', 'inherit' + )): (True, True, C3BUI), + ('outline-offset', ('1%', 'red' + )): (False, False, C3BUI), + ('outline-style', ('auto', 'dotted', 'inherit' + )): (True, True, C3BUI), + ('outline-style', ('0', '1em', 'red' + )): (False, False, C3BUI), + ('outline-width', ('0', '1em', 'inherit' + )): (True, True, C3BUI), + ('outline-width', ('auto', 'red', 'dotted' + )): (False, False, C3BUI), + + ('resize', ('none', + 'both', + 'horizontal', + 'vertical', + 'inherit')): (True, True, C3BUI), + ('resize', ('1', + 'auto', + '1px', + '2%')): (False, False, C3BUI), + + ('size', ('1cm', + '1mm 20cm', + 'auto', + 'landscape letter', + 'a4 portrait', + 'landscape', + 'a5', + #'inherit' + )): (True, True, C3PM), + ('size', ( + 'portrait landscape', + 'a5 letter', + '2%')): (False, False, C3PM), + + ('src', ('url( a )', + 'local( x )', + 'local("x")', + 'local( "x" )', + 'url(../fonts/LateefRegAAT.ttf) format( "truetype-aat" )', + 'url(a) format( "123x" , "a" )', + 'url(a) format( "123x" , "a" ), url(a) format( "123x" , "a" )', + 'local(HiraKakuPro-W3), local(Meiryo), local(IPAPGothic)', + 'local(Gentium), url(/fonts/Gentium.ttf)', + 'local("Gentium"), url("/fonts/Gentium.ttf")', + 'local(Futura-Medium), url(fonts.svg#MyGeometricModern) format("svg")', + )): (True, True, FM3FF), + + + ('text-shadow', ('none', + '1px 1px', + '1px 1px 1px', + '1px 1px 1px 1px', + '1px 1px 1px 1px red', + 'inset 1px 1px', + 'inset 1px 1px 1px 1px black')): (True, True, C3T), + ('text-shadow', ('1px', + '1px 1px 1px 1px 1px', + 'x 1px 1px', + 'inset', + '1px black', + 'black')): (False, False, C3T), + + ('unicode-range', ('u+1', 'U+111111-ffffff', + 'u+123456 , U+1-f' + )): (True, True, FM3FF), + + } + # TODO!!! + for (name, values), (valid, matching, profile) in tests.items(): + for value in values: + self.assertEqual(valid, cssutils.profile.validate(name, value)) + + +# if (valid, matching, list(profile)) != cssutils.profile.validateWithProfile(name, value): +# print +# print '###############', name, value +# print (valid, matching, list(profile)), cssutils.profile.validateWithProfile(name, value) + + # TODO: fix +# self.assertEqual((valid, matching, list(profile)), +# cssutils.profile.validateWithProfile(name, value)) + + # TODO: fix +# def test_validateByProfile(self): +# "Profiles.validateByProfile()" +# # testing for valid values overwritten in a profile +# tests = { +# (FM3FF, 'font-family', ('y', '"y"' # => name should be "y"!!! +# )): (True, True, FM3FF), +# (FM3FF, 'font-family', ('"y", "a"', 'a, b', 'a a' +# )): (True, False, CSS2), +# (FM3FF, 'font-stretch', ('normal', 'wider', 'narrower', 'inherit' +# )): (True, False, FM3), +# (FM3FF, 'font-style', ('inherit', +# )): (True, False, CSS2), +# (FM3FF, 'font-weight', ('bolder', 'lighter', 'inherit', +# )): (True, False, CSS2), +# } +# for (profiles, name, values), (v, m, p) in tests.items(): +# for value in values: +# self.assertEqual((v, m, list(p)), +# cssutils.profile.validateWithProfile(name, +# value, +# profiles)) + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_properties.py cssutils-0.9.10/src/cssutils/tests/test_properties.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_properties.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_properties.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,209 @@ +"""Testcases for cssutils.css.property._Property.""" +__version__ = '$Id: test_property.py 1529 2008-11-30 15:12:01Z cthedot $' + +import copy +import xml.dom +import basetest +import cssutils +from cssutils.css.property import Property + +debug = False + +class PropertiesTestCase(basetest.BaseTestCase): + + def setUp(self): + "init test values" + V = { + '0': ('0', '-0'),#, '+0'), + 'NUMBER': ('0', '-0', '100.1', '-100.1'),#, '+0', '+100.1'), + 'PERCENTAGE': ('0%', '-0%', '100.1%', '-100.1%'),#, '+0%', '+100.1%'), + + 'EM': '1.2em', + 'EX': '1.2ex', + 'PX': '1.2px', + 'CM': '1.2cm', + 'MM': '1.2mm', + 'IN': '1.2in', + 'PT': '1.2pt', + 'PC': '1.2pc', + + 'ANGLES': ('1deg', '1rad', '1grad'), + 'TIMES': ('1s', '1ms'), + 'FREQUENCIES': ('1hz', '1khz'), + 'DIMENSION': ('1dimension', '1_dimension', '1dimension2'), + 'STRING': ('"string"', "'STRING'"), + 'URI': ('url(x)', 'URL("x")', "url(')')"), + 'IDENT': ('ident', 'IDENT', '_IDENT', '_2', 'i-2'), + #'AUTO': 'auto', # explicit in list as an IDENT too + #'INHERIT': 'inherit', # explicit in list as an IDENT too + 'ATTR': ('attr(x)'), + 'RECT': ('rect(1,2,3,4)'), + #? + 'CLIP': ('rect(1,2,3,4)'), + 'FUNCTION': (), + + 'HEX3': '#123', + 'HEX6': '#123abc', + 'RGB': 'rgb(1,2,3)', + 'RGB100': 'rgb(1%,2%,100%)', + 'RGBA': 'rgba(1,2,3, 1)', + 'RGBA100': 'rgba(1%,2%,100%, 0)', + 'HSL': 'hsl(1,2%,3%)', + 'HSLA': 'hsla(1,2%,3%, 1.0)' + } + def expanded(*keys): + r = [] + for k in keys: + if isinstance(V[k], basestring): + r.append(V[k]) + else: + r.extend(list(V[k])) + return r + + # before adding combined + self.V = V + self.ALL = list(self._valuesofkeys(V.keys())) + + # combined values, only keys of V may be used! + self.V['LENGTHS'] = expanded('0', 'EM', 'EX', 'PX', 'CM', 'MM', 'IN', 'PT', 'PC') + self.V['COLORS'] = expanded('HEX3', 'HEX6', 'RGB', 'RGB100') + self.V['COLORS3'] = expanded('RGBA', 'RGBA100', 'HSL', 'HSLA') + + def _allvalues(self): + "Return list of **all** possible values as simple list" + return copy.copy(self.ALL) + + def _valuesofkeys(self, keys): + "Generate all distinct values in given keys of self.V" + done = [] + for key in keys: + if isinstance(key, list): + # not a key but a list of values, return directly + for v in key: + yield v + else: + v = self.V[key] + if isinstance(v, basestring): + # single value + if v not in done: + done.append(v) + yield v + else: + # a list of values + for value in v: + if value not in done: + done.append(value) + yield value + + def _check(self, name, keys): + """ + Check each value in values if for property name p.name==exp. + """ + notvalid = self._allvalues() + + for value in self._valuesofkeys(keys): + if name == debug: + print '+True?', Property(name, value).valid, value + self.assertEqual(True, Property(name, value).valid) + if value in notvalid: + notvalid.remove(value) + for value in notvalid: + if name == debug: + print '-False?', Property(name, value).valid, value + self.assertEqual(False, Property(name, value).valid) + + def test_properties(self): + "properties" + tests = { + # propname: key or [list of values] + 'color': ('COLORS', 'COLORS3', ['inherit', 'red']), + + 'fit': (['fill', 'hidden', 'meet', 'slice'],), + 'fit-position': ('LENGTHS', 'PERCENTAGE', + ['auto', + 'top left', + '0% 50%', + '1cm 5em', + 'bottom']), + 'font-family': ('STRING', 'IDENT', ['a, b', + '"a", "b"', + 'a, "b"', + '"a", b', + r'a\{b', + r'a\ b', + 'a b' + 'a b, c d , e' + ]), + #'src': ('STRING',), + + 'font-weight': (['normal', 'bold', 'bolder', 'lighter', 'inherit', + '100', '200', '300', '400', '500', '600', '700', + '800', '900'],), + 'font-stretch': (['normal', 'wider', 'narrower', 'ultra-condensed', + 'extra-condensed', 'condensed', 'semi-condensed', + 'semi-expanded', 'expanded', 'extra-expanded', + 'ultra-expanded', 'inherit'],), + 'font-style': (['normal', 'italic', 'oblique', 'inherit'],), + 'font-variant': (['normal', 'small-caps', 'inherit'],), + 'font-size': ('LENGTHS', 'PERCENTAGE', ['xx-small', 'x-small', + 'small', 'medium', 'large', + 'x-large', 'xx-large', + 'larger', 'smaller', + '1em', '1%', 'inherit']), + 'font-size-adjust': ('NUMBER', ['none', 'inherit']), +# 'font': (['italic small-caps bold 1px/3 a, "b", serif', +# 'caption', 'icon', 'menu', 'message-box', 'small-caption', +# 'status-bar', 'inherit'],), + + 'image-orientation': ('0', 'ANGLES', ['auto']), + 'left': ('LENGTHS', 'PERCENTAGE', ['inherit', 'auto']), + 'opacity': ('NUMBER', ['inherit']), + + 'orphans': ('0', ['1', '99999', 'inherit']), + 'page': ('IDENT',), + 'page-break-inside': (['auto', 'inherit', 'avoid'],), + 'size': ('LENGTHS', ['auto', + '1em 1em', + 'a4 portrait', + 'b4 landscape', + 'A5 PORTRAIT']), + + 'widows': ('0', ['1', '99999', 'inherit']) + } + for name, keys in tests.items(): + # keep track of valid keys + self._check(name, keys) + + def test_validate(self): + "Property.validate() and Property.valid" + tests = { + # (default L2, no default, no profile, L2, Color L3) + 'red': (True, True, True, True, True), + 'rgba(1,2,3,1)': (False, True, True, False, True), + '1': (False, False, False, False, False) + } + for v, rs in tests.items(): + p = Property('color', v) + + # TODO: Fix +# cssutils.profile.defaultProfiles = \ +# cssutils.profile.CSS_LEVEL_2 +# self.assertEqual(rs[0], p.valid) + + cssutils.profile.defaultProfiles = None + self.assertEqual(rs[1], p.valid) + + self.assertEqual(rs[2], p.validate()) +# self.assertEqual(rs[3], p.validate( +# profiles=cssutils.profile.CSS_LEVEL_2)) +# self.assertEqual(rs[4], p.validate( +# cssutils.profile.CSS3_COLOR)) + + +if __name__ == '__main__': + debug = 'font-family' + import logging + import unittest + cssutils.log.setLevel(logging.FATAL) + #debug = True + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_property.py cssutils-0.9.10/src/cssutils/tests/test_property.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_property.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_property.py 2013-03-31 19:18:28.000000000 +0000 @@ -0,0 +1,269 @@ +"""Testcases for cssutils.css.property._Property.""" + +import xml.dom +import basetest +import cssutils + +class PropertyTestCase(basetest.BaseTestCase): + + def setUp(self): + self.r = cssutils.css.property.Property('top', '1px')#, 'important') + + def test_init(self): + "Property.__init__()" + p = cssutils.css.property.Property('top', '1px') + self.assertEqual('top: 1px', p.cssText) + self.assertEqual('top', p.literalname) + self.assertEqual('top', p.name) + self.assertEqual('1px', p.value) + self.assertEqual('1px', p.cssValue.cssText) + self.assertEqual(u'', p.priority) + self.assertEqual(True, p.valid) + self.assertEqual(True, p.wellformed) + + self.assertEqual([u'top'], p.seqs[0]) + self.assertEqual(type(cssutils.css.PropertyValue(cssText="2px")), type(p.seqs[1])) + self.assertEqual([], p.seqs[2]) + + self.assertEqual(True, p.valid) + + # Prop of MediaQuery + p = cssutils.css.property.Property('top', _mediaQuery=True) + self.assertEqual('top', p.cssText) + self.assertEqual('top', p.literalname) + self.assertEqual('top', p.name) + self.assertEqual('', p.value) + self.assertEqual('', p.cssValue.cssText) + self.assertEqual(u'', p.priority) + self.assertEqual(False, p.valid) + p.cssValue.cssText = '1px' + self.assertEqual('top: 1px', p.cssText) + p.cssValue = '' + self.assertEqual('top', p.cssText) + + self.assertRaises(xml.dom.SyntaxErr, cssutils.css.property.Property, 'top', '') + self.assertRaises(xml.dom.SyntaxErr, cssutils.css.property.Property, 'top') + p = cssutils.css.property.Property('top', '0') + self.assertEqual('0', p.value) + self.assertEqual(True, p.wellformed) + self.assertRaises(xml.dom.SyntaxErr, p._setValue, '') + self.assertEqual('0', p.value) + self.assertEqual(True, p.wellformed) + +# self.assertEqual(True, p.valid) + +# def test_valid(self): +# "Property.valid" +# # context property must be set +# tests = [ +# ('color', r'INHe\rIT', True), +# ('color', '1', False), +# ('color', 'red', True), +# ('left', '1', False), +# ('left', '1px', True), +# ('font', 'normal 1em/1.5 serif', True), +# ('background', 'url(x.gif) 1 0', False) +# ] +# for n, v, exp in tests: +# v = cssutils.css.CSSValue(cssText=v) +# self.assert_(v.wellformed, True) + + def test_cssText(self): + "Property.cssText" + p = cssutils.css.property.Property() + + tests = { + u'a: 1': None, + u'a: 1px 2px': None, + u'a: 1 !important': None, + u'a: 1 !IMPORTANT': u'a: 1 !important', + u'a: 1 !impor\\tant': u'a: 1 !important', + # TODO: important with unicode escapes! + u'font: normal 1em/1.5 serif': None, + u'font: normal 1em/serif': None + } + self.do_equal_r(tests) + + tests = { + u'': (xml.dom.SyntaxErr, + u'Property: No property name found: '), + u':': (xml.dom.SyntaxErr, + u'Property: No property name found: : [1:1: :]'), + u'a': (xml.dom.SyntaxErr, + u'Property: No ":" after name found: a [1:1: a]'), + u'a !': (xml.dom.SyntaxErr, + u'Property: No ":" after name found: a ! [1:3: !]'), + u'a:': (xml.dom.SyntaxErr, + u'Property: No property value found: a: [1:2: :]'), + u'/**/a': (xml.dom.SyntaxErr, + u'Property: No ":" after name found: /**/a [1:5: a]'), + # somehow 'a: ' fails?!? + u'a111: ': (xml.dom.SyntaxErr, + u"PropertyValue: Unknown syntax or no value: "), + u'a: 1!': (xml.dom.SyntaxErr, + u'Property: Invalid priority: !'), + u'a: 1!importantX': (xml.dom.SyntaxErr, + u"Property: No CSS priority value: importantx"), + u'a:!important': (xml.dom.SyntaxErr, + u"PropertyValue: Unknown syntax or no value: "), + + # TODO? +# u'a: 1;': (xml.dom.SyntaxErr, +# u'''CSSValue: No match: ('CHAR', u';', 1, 5)''') + } + for test in tests: + ecp, msg = tests[test] + self.assertRaisesMsg(ecp, msg, p._setCssText, test) + + def test_name(self): + "Property.name" + p = cssutils.css.property.Property('top', '1px') + p.name = 'left' + self.assertEqual('left', p.name) + + tests = { + u'top': None, + u' top': u'top', + u'top ': u'top', + u' top ': u'top', + u'/*x*/ top ': u'top', + u' top /*x*/': u'top', + u'/*x*/top/*x*/': u'top', + u'\\x': u'x', + u'a\\010': u'a\x10', + u'a\\01': u'a\x01' + } + self.do_equal_r(tests, att='name') + + tests = { + u'': xml.dom.SyntaxErr, + u' ': xml.dom.SyntaxErr, + u'"\n': xml.dom.SyntaxErr, + u'/*x*/': xml.dom.SyntaxErr, + u':': xml.dom.SyntaxErr, + u';': xml.dom.SyntaxErr, + u'top:': xml.dom.SyntaxErr, + u'top;': xml.dom.SyntaxErr, + u'color: #xyz': xml.dom.SyntaxErr, + } + self.do_raise_r(tests, att='_setName') + + p = cssutils.css.property.Property(r'c\olor', 'red') + self.assertEqual(r'c\olor', p.literalname) + self.assertEqual('color', p.name) + + def test_literalname(self): + "Property.literalname" + p = cssutils.css.property.Property(r'c\olor', 'red') + self.assertEqual(r'c\olor', p.literalname) + self.assertRaisesMsg(AttributeError, "can't set attribute", p.__setattr__, + 'literalname', 'color') + + def test_validate(self): + "Property.valid" + p = cssutils.css.property.Property('left', '1px', '') + + self.assertEqual(p.valid, True) + + p.name = 'color' + self.assertEqual(p.valid, False) + + p.name = 'top' + self.assertEqual(p.valid, True) + + p.value = 'red' + self.assertEqual(p.valid, False) + + def test_cssValue(self): + "Property.cssValue" + pass + #TODO + + def test_priority(self): + "Property.priority" + p = cssutils.css.property.Property('top', '1px', 'important') + + for prio in (None, u''): + p.priority = prio + self.assertEqual(u'', p.priority) + self.assertEqual(u'', p.literalpriority) + + for prio in (u'!important', + u'! important', + u'!/* x */ important', + u'!/* x */ important /**/', + u'important', + u'IMPORTANT', + ur'im\portant' + ): + p.priority = prio + self.assertEqual(u'important', p.priority) + if prio.startswith('!'): + prio = prio[1:].strip() + if u'/*' in prio: + check = 'important' + else: + check = prio + self.assertEqual(check, p.literalpriority) + + tests = { + u' ': xml.dom.SyntaxErr, + u'"\n': xml.dom.SyntaxErr, + #u'important': xml.dom.SyntaxErr, + u';': xml.dom.SyntaxErr, + u'!important !important': xml.dom.SyntaxErr + } + self.do_raise_r(tests, att='_setPriority') + + def test_value(self): + "Property.value" + p = cssutils.css.property.Property('top', u'1px') + self.assertEqual('1px', p.value) + p.value = '2px' + self.assertEqual('2px', p.value) + + tests = { + u'1px': None, + u' 2px': u'2px', + u'3px ': u'3px', + u' 4px ': u'4px', + u'5px 1px': u'5px 1px', + } + self.do_equal_r(tests, att='value') + + tests = { + # no value + None: xml.dom.SyntaxErr, + u'': xml.dom.SyntaxErr, + u' ': xml.dom.SyntaxErr, + u'"\n': xml.dom.SyntaxErr, + u'/*x*/': xml.dom.SyntaxErr, + # not allowed: + u':': xml.dom.SyntaxErr, + u';': xml.dom.SyntaxErr, + u'!important': xml.dom.SyntaxErr, + } + self.do_raise_r(tests, att='_setValue') + + def test_reprANDstr(self): + "Property.__repr__(), .__str__()" + name="color" + value="red" + priority="important" + + s = cssutils.css.property.Property(name=name, value=value, priority=priority) + + self.assert_(name in str(s)) + self.assert_(value in str(s)) + self.assert_(priority in str(s)) + + s2 = eval(repr(s)) + self.assert_(isinstance(s2, s.__class__)) + self.assert_(name == s2.name) + self.assert_(value == s2.value) + self.assert_(priority == s2.priority) + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_scripts_csscombine.py cssutils-0.9.10/src/cssutils/tests/test_scripts_csscombine.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_scripts_csscombine.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_scripts_csscombine.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,74 @@ +"""Testcases for cssutils.scripts.csscombine""" + +from cssutils.script import csscombine +import basetest +import cssutils +import os + +class CSSCombine(basetest.BaseTestCase): + + C = '@namespace s2"uri";s2|sheet-1{top:1px}s2|sheet-2{top:2px}proxy{top:3px}' + + def setUp(self): + self._saved = cssutils.log.raiseExceptions + + def tearDown(self): + cssutils.log.raiseExceptions = self._saved + + def test_combine(self): + "scripts.csscombine()" + + # path, SHOULD be keyword argument! + csspath = os.path.join(os.path.dirname(__file__), '..', '..', '..', + 'sheets', 'csscombine-proxy.css') + combined = csscombine(csspath) + self.assertEqual(combined, self.C.encode()) + combined = csscombine(path=csspath, targetencoding='ascii') + self.assertEqual(combined, ('@charset "ascii";' + self.C).encode()) + + # url + cssurl = cssutils.helper.path2url(csspath) + combined = csscombine(url=cssurl) + self.assertEqual(combined, self.C.encode()) + combined = csscombine(url=cssurl, targetencoding='ascii') + self.assertEqual(combined, ('@charset "ascii";' + self.C).encode()) + + # cssText + # TODO: really need binary or can handle str too? + cssText=open(csspath, mode="rb").read() + combined = csscombine(cssText=cssText, href=cssurl) + self.assertEqual(combined, self.C.encode()) + combined = csscombine(cssText=cssText, href=cssurl, + targetencoding='ascii') + self.assertEqual(combined, ('@charset "ascii";' + self.C).encode()) + + def test_combine_resolveVariables(self): + "scripts.csscombine(minify=..., resolveVariables=...)" + # no actual imports but checking if minify and resolveVariables work + cssText = ''' + @variables { + c: #0f0; + } + a { + color: var(c); + } + ''' + # default minify + self.assertEqual(csscombine(cssText=cssText, + resolveVariables=False), + '@variables{c:#0f0}a{color:var(c)}'.encode()) + self.assertEqual(csscombine(cssText=cssText), + 'a{color:#0f0}'.encode()) + + # no minify + self.assertEqual(csscombine(cssText=cssText, + minify=False, + resolveVariables=False), + '@variables {\n c: #0f0\n }\na {\n color: var(c)\n }'.encode()) + self.assertEqual(csscombine(cssText=cssText, minify=False), + 'a {\n color: #0f0\n }'.encode()) + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_selector.py cssutils-0.9.10/src/cssutils/tests/test_selector.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_selector.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_selector.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,495 @@ +"""Testcases for cssutils.css.selector.Selector. + +what should happen here? + - star 7 hack:: + x* + does not validate but works in IE>5 and FF, does it??? + +""" +import xml.dom +import basetest +import cssutils + +class SelectorTestCase(basetest.BaseTestCase): + + def setUp(self): + self.r = cssutils.css.Selector('*') + + def test_init(self): + "Selector.__init__()" + s = cssutils.css.Selector('*') + self.assertEqual((None, '*'), s.element) + self.assertEqual({}, s._namespaces.namespaces) + self.assertEqual(None, s.parent) + self.assertEqual('*', s.selectorText) + self.assertEqual((0,0,0,0), s.specificity) + self.assertEqual(True, s.wellformed) + + s = cssutils.css.Selector(('p|b', {'p': 'URI'}) ) + self.assertEqual(('URI', 'b'), s.element) + self.assertEqual({'p': 'URI'}, s._namespaces.namespaces) + self.assertEqual(None, s.parent) + self.assertEqual('p|b', s.selectorText) + self.assertEqual((0,0,0,1), s.specificity) + self.assertEqual(True, s.wellformed) + + self.assertRaisesEx(xml.dom.NamespaceErr, cssutils.css.Selector, 'p|b') + + def test_element(self): + "Selector.element (TODO: RESOLVE)" + tests = { + '*': (None, '*'), + 'x': (None, 'x'), + '\\x': (None, '\\x'), + '|x': (u'', 'x'), + '*|x': (cssutils._ANYNS, 'x'), + 'ex|x': (u'example', 'x'), + 'a x': (None, 'x'), + 'a+x': (None, 'x'), + 'a>x': (None, 'x'), + 'a~x': (None, 'x'), + 'a+b~c x': (None, 'x'), + 'x[href]': (None, 'x'), + 'x[href="123"]': (None, 'x'), + 'x:hover': (None, 'x'), + 'x:first-letter': (None, 'x'), # TODO: Really? + 'x::first-line': (None, 'x'), # TODO: Really? + 'x:not(href)': (None, 'x'), # TODO: Really? + + '#id': None, + '.c': None, + 'x#id': (None, 'x'), + 'x.c': (None, 'x') + } + for test, ele in tests.items(): + s = cssutils.css.Selector((test,{'ex': 'example'})) + self.assertEqual(ele, s.element) + + def test_namespaces(self): + "Selector.namespaces" + namespaces = [ + {'p': 'other'}, # no default + {'': 'default', 'p': 'other'}, # with default + {'': 'default', 'p': 'default' } # same default + ] + tests = { + # selector: with default, no default, same default + '*': ('*', '*', '*'), + 'x': ('x', 'x', 'x'), + '|*': ('|*', '|*', '|*'), + '|x': ('|x', '|x', '|x'), + '*|*': ('*|*', '*|*', '*|*'), + '*|x': ('*|x', '*|x', '*|x'), + 'p|*': ('p|*', 'p|*', '*'), + 'p|x': ('p|x', 'p|x', 'x'), + 'x[a][|a][*|a][p|a]': ('x[a][a][*|a][p|a]', + 'x[a][a][*|a][p|a]', + 'x[a][a][*|a][a]') + } + for sel, exp in tests.items(): + for i, result in enumerate(exp): + s = cssutils.css.Selector((sel, namespaces[i])) + self.assertEqual(result, s.selectorText) + + # add to CSSStyleSheet + sheet = cssutils.css.CSSStyleSheet() + sheet.cssText = '@namespace p "u"; a { color: green }' + + r = sheet.cssRules[1] + + self.assertEqual(r.selectorText, u'a') + + # add default namespace + sheet.namespaces[''] = 'a'; + self.assertEqual(r.selectorText, u'|a') + + del sheet.namespaces['']; + self.assertEqual(r.selectorText, u'a') + +# r.selectorList.append('a') +# self.assertEqual(r.selectorText, u'|a, a') +# r.selectorList.append('*|a') +# self.assertEqual(r.selectorText, u'|a, a, *|a') + + def test_default_namespace(self): + "Selector.namespaces default" + css = '''@namespace "default"; + a[att] { color:green; } + ''' + sheet = cssutils.css.CSSStyleSheet() + sheet.cssText = css + self.assertEqual(sheet.cssText, + u'@namespace "default";\na[att] {\n color: green\n }'.encode()) + # use a prefix for default namespace, does not goes for atts! + sheet.namespaces['p'] = 'default' + self.assertEqual(sheet.cssText, + u'@namespace p "default";\np|a[att] {\n color: green\n }'.encode()) + + def test_parent(self): + "Selector.parent" + sl = cssutils.css.SelectorList('a, b') + for sel in sl: + self.assertEqual(sl, sel.parent) + + newsel = cssutils.css.Selector('x') + sl.append(newsel) + self.assertEqual(sl, newsel.parent) + + newsel = cssutils.css.Selector('y') + sl.appendSelector(newsel) + self.assertEqual(sl, newsel.parent) + + def test_selectorText(self): + "Selector.selectorText" + tests = { + # combinators + u'a+b>c~e f': u'a + b > c ~ e f', + u'a + b > c ~ e f': u'a + b > c ~ e f', + u'a+b': u'a + b', + u'a + b': 'a + b', + u'a\n +\t b': 'a + b', + u'a~b': u'a ~ b', + u'a b': None, + u'a b': 'a b', + u'a\nb': 'a b', + u'a\tb': 'a b', + u'a #b': 'a #b', + u'a .b': 'a .b', + u'a * b': None, + # > + u'a>b': u'a > b', + u'a> b': 'a > b', + u'a >b': 'a > b', + u'a > b': 'a > b', + # + + u'a+b': u'a + b', + u'a+ b': 'a + b', + u'a +b': 'a + b', + u'a + b': 'a + b', + # ~ + u'a~b': u'a ~ b', + u'a~ b': 'a ~ b', + u'a ~b': 'a ~ b', + u'a ~ b': 'a ~ b', + + # type selector + u'a': None, + u'h1-a_x__--': None, + u'a-a': None, + u'a_a': None, + u'-a': None, + u'_': None, + u'-_': None, + ur'-\72': u'-r', + #ur'\25': u'%', # TODO: should be escaped! + u'.a a': None, + u'a1': None, + u'a1-1': None, + u'.a1-1': None, + + # universal + u'*': None, + u'*/*x*/': None, + u'* /*x*/': None, + u'*:hover': None, + u'* :hover': None, + u'*:lang(fr)': None, + u'* :lang(fr)': None, + u'*::first-line': None, + u'* ::first-line': None, + u'*[lang=fr]': None, + u'[lang=fr]': None, + + # HASH + u'''#a''': None, + u'''#a1''': None, + u'''#1a''': None, # valid to grammar but not for HTML + u'''#1''': None, # valid to grammar but not for HTML + u'''a#b''': None, + u'''a #b''': None, + u'''a#b.c''': None, + u'''a.c#b''': None, + u'''a #b.c''': None, + u'''a .c#b''': None, + + # class + u'ab': 'ab', + u'a.b': None, + u'a.b.c': None, + u'.a1._1': None, + + # attrib + u'''[x]''': None, + u'''*[x]''': None, + u'''a[x]''': None, + u'''a[ x]''': 'a[x]', + u'''a[x ]''': 'a[x]', + u'''a [x]''': 'a [x]', + u'''* [x]''': None, # is really * *[x] + + u'''a[x="1"]''': None, + u'''a[x ="1"]''': 'a[x="1"]', + u'''a[x= "1"]''': 'a[x="1"]', + u'''a[x = "1"]''': 'a[x="1"]', + u'''a[ x = "1"]''': 'a[x="1"]', + u'''a[x = "1" ]''': 'a[x="1"]', + u'''a[ x = "1" ]''': 'a[x="1"]', + u'''a [ x = "1" ]''': 'a [x="1"]', + + u'''a[x~=a1]''': None, + u'''a[x ~=a1]''': 'a[x~=a1]', + u'''a[x~= a1]''': 'a[x~=a1]', + u'''a[x ~= a1]''': 'a[x~=a1]', + u'''a[ x ~= a1]''': 'a[x~=a1]', + u'''a[x ~= a1 ]''': 'a[x~=a1]', + u'''a[ x ~= a1 ]''': 'a[x~=a1]', + u'''a [ x ~= a1 ]''': 'a [x~=a1]', # same as next! + u'''a *[ x ~= a1 ]''': 'a *[x~=a1]', + + u'''a[x|=en]''': None, + u'''a[x|= en]''': 'a[x|=en]', + u'''a[x |=en]''': 'a[x|=en]', + u'''a[x |= en]''': 'a[x|=en]', + u'''a[ x |= en]''': 'a[x|=en]', + u'''a[x |= en ]''': 'a[x|=en]', + u'''a[ x |= en]''': 'a[x|=en]', + u'''a [ x |= en]''': 'a [x|=en]', + # CSS3 + u'''a[x^=en]''': None, + u'''a[x$=en]''': None, + u'''a[x*=en]''': None, + + u'''a[/*1*/x/*2*/]''': None, + u'''a[/*1*/x/*2*/=/*3*/a/*4*/]''': None, + u'''a[/*1*/x/*2*/~=/*3*/a/*4*/]''': None, + u'''a[/*1*/x/*2*/|=/*3*/a/*4*/]''': None, + + # pseudo-elements + u'a x:first-line': None, + u'a x:first-letter': None, + u'a x:before': None, + u'a x:after': None, + u'a x::selection': None, + u'a:hover+b:hover>c:hover~e:hover f:hover': + u'a:hover + b:hover > c:hover ~ e:hover f:hover', + u'a:hover + b:hover > c:hover ~ e:hover f:hover': + u'a:hover + b:hover > c:hover ~ e:hover f:hover', + u'a::selection+b::selection>c::selection~e::selection f::selection': + u'a::selection + b::selection > c::selection ~ e::selection f::selection', + u'a::selection + b::selection > c::selection ~ e::selection f::selection': + u'a::selection + b::selection > c::selection ~ e::selection f::selection', + + u'x:lang(de) y': None, + u'x:nth-child(odd) y': None, + # functional pseudo + u'x:func(a + b-2px22.3"s"i)': None, + u'x:func(1 + 1)': None, + u'x:func(1+1)': u'x:func(1 + 1)', + u'x:func(1 + 1)': u'x:func(1 + 1)', + u'x:func(1-1)': u'x:func(1-1)', + u'x:func(1 - 1)': u'x:func(1 -1)', + u'x:func(a-1)': u'x:func(a-1)', + u'x:func(a -1px)': u'x:func(a -1px)', + u'x:func(1px)': None, + u'x:func(23.4)': None, + u'x:func("s")': None, + u'x:func(i)': None, + + # negation + u':not(y)': None, + u':not( y \t\n)': u':not(y)', + u'*:not(y)': None, + u'x:not(y)': None, + u'.x:not(y)': None, + u':not(*)': None, + u':not(#a)': None, + u':not(.a)': None, + u':not([a])': None, + u':not(:first-letter)': None, + u':not(::first-letter)': None, + + # escapes + ur'\74\72 td': 'trtd', + ur'\74\72 td': 'tr td', + ur'\74\000072 td': 'trtd', + ur'\74\000072 td': 'tr td', + + # comments + u'a/**/ b': None, + u'a /**/b': None, + u'a /**/ b': None, + u'a /**/ b': u'a /**/ b', + u'a /**/ b': u'a /**/ b', + + # namespaces + u'|e': None, + u'*|e': None, + u'*|*': None, + (u'p|*', (('p', 'uri'),)): u'p|*', + (u'p|e', (('p', 'uri'),)): u'p|e', + (u'-a_x12|e', (('-a_x12', 'uri'),)): u'-a_x12|e', + (u'*|b[p|a]', (('p', 'uri'),)): '*|b[p|a]', + + # case + u'elemenT.clasS#iD[atT="valuE"]:noT(x)::firsT-linE': + u'elemenT.clasS#iD[atT="valuE"]:not(x)::first-line' + } + # do not parse as not complete + self.do_equal_r(tests, att='selectorText') + + tests = { + u'x|a': xml.dom.NamespaceErr, + (u'p|*', (('x', 'uri'),)): xml.dom.NamespaceErr, + + u'': xml.dom.SyntaxErr, + u'1': xml.dom.SyntaxErr, + u'-1': xml.dom.SyntaxErr, + u'a*b': xml.dom.SyntaxErr, + u'a *b': xml.dom.SyntaxErr, + u'a* b': xml.dom.SyntaxErr, + u'a/**/b': xml.dom.SyntaxErr, + + u'#': xml.dom.SyntaxErr, + u'|': xml.dom.SyntaxErr, + + u':': xml.dom.SyntaxErr, + u'::': xml.dom.SyntaxErr, + u': a': xml.dom.SyntaxErr, + u':: a': xml.dom.SyntaxErr, + u':a()': xml.dom.SyntaxErr, # no value + u'::a()': xml.dom.SyntaxErr, # no value + u':::a': xml.dom.SyntaxErr, + u':1': xml.dom.SyntaxErr, + + u'#.x': xml.dom.SyntaxErr, + u'.': xml.dom.SyntaxErr, + u'.1': xml.dom.SyntaxErr, + u'.a.1': xml.dom.SyntaxErr, + + u'[a': xml.dom.SyntaxErr, + u'a]': xml.dom.SyntaxErr, + u'[a b]': xml.dom.SyntaxErr, + u'[=b]': xml.dom.SyntaxErr, + u'[a=]': xml.dom.SyntaxErr, + u'[a|=]': xml.dom.SyntaxErr, + u'[a~=]': xml.dom.SyntaxErr, + u'[a=1]': xml.dom.SyntaxErr, + + u'a +': xml.dom.SyntaxErr, + u'a >': xml.dom.SyntaxErr, + u'a ++ b': xml.dom.SyntaxErr, + u'a + > b': xml.dom.SyntaxErr, + + # functional pseudo + u'*:lang(': xml.dom.SyntaxErr, + u'*:lang()': xml.dom.SyntaxErr, # no arg + + # negation + u'not(x)': xml.dom.SyntaxErr, # no valid function + u':not()': xml.dom.SyntaxErr, # no arg + u':not(x': xml.dom.SyntaxErr, # no ) + u':not(-': xml.dom.SyntaxErr, # not allowed + u':not(+': xml.dom.SyntaxErr, # not allowed + + # only one selector! + u',': xml.dom.InvalidModificationErr, + u',a': xml.dom.InvalidModificationErr, + u'a,': xml.dom.InvalidModificationErr, + + # @ + u'p @here': xml.dom.SyntaxErr, # not allowed + + } + # only set as not complete + self.do_raise_r(tests, att='_setSelectorText') + + def test_specificity(self): + "Selector.specificity" + selector = cssutils.css.Selector() + + # readonly + def _set(): selector.specificity = 1 + self.assertRaisesMsg(AttributeError, "can't set attribute", _set) + + tests = { + u'*': (0,0,0,0), + u'li': (0,0,0,1), + u'li:first-line': (0,0,0,2), + u'ul li': (0,0,0,2), + u'ul ol+li': (0,0,0,3), + u'h1 + *[rel=up]': (0,0,1,1), + u'ul ol li.red': (0,0,1,3), + u'li.red.level': (0,0,2,1), + u'#x34y': (0,1,0,0), + + u'UL OL LI.red': (0,0,1,3), + u'LI.red.level': (0,0,2,1), + u'#s12:not(FOO)': (0,1,0,1), + u'button:not([DISABLED])': (0,0,1,1), #? + u'*:not(FOO)': (0,0,0,1), + + # elements + u'a+b': (0,0,0,2), + u'a>b': (0,0,0,2), + u'a b': (0,0,0,2), + u'* a': (0,0,0,1), + u'a *': (0,0,0,1), + u'a * b': (0,0,0,2), + + u'a:hover': (0,0,0,1), + + u'a:first-line': (0,0,0,2), + u'a:first-letter': (0,0,0,2), + u'a:before': (0,0,0,2), + u'a:after': (0,0,0,2), + + # classes and attributes + u'.a': (0,0,1,0), + u'*.a': (0,0,1,0), + u'a.a': (0,0,1,1), + u'.a.a': (0,0,2,0), # IE<7 False (0,0,1,0) + u'a.a.a': (0,0,2,1), + u'.a.b': (0,0,2,0), + u'a.a.b': (0,0,2,1), + u'.a .a': (0,0,2,0), + u'*[x]': (0,0,1,0), + u'*[x]': (0,0,1,0), + u'*[x]': (0,0,1,0), + u'*[x=a]': (0,0,1,0), + u'*[x~=a]': (0,0,1,0), + u'*[x|=a]': (0,0,1,0), + u'*[x^=a]': (0,0,1,0), + u'*[x*=a]': (0,0,1,0), + u'*[x$=a]': (0,0,1,0), + u'*[x][y]': (0,0,2,0), + + # ids + u'#a': (0,1,0,0), + u'*#a': (0,1,0,0), + u'x#a': (0,1,0,1), + u'.x#a': (0,1,1,0), + u'a.x#a': (0,1,1,1), + u'#a#a': (0,2,0,0), # e.g. html:id + xml:id + u'#a#b': (0,2,0,0), + u'#a #b': (0,2,0,0), + } + for text in tests: + selector.selectorText = text + self.assertEqual(tests[text], selector.specificity) + + def test_reprANDstr(self): + "Selector.__repr__(), .__str__()" + sel=u'a + b' + + s = cssutils.css.Selector(selectorText=sel) + + self.assert_(sel in str(s)) + + s2 = eval(repr(s)) + self.assert_(isinstance(s2, s.__class__)) + self.assert_(sel == s2.selectorText) + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_selectorlist.py cssutils-0.9.10/src/cssutils/tests/test_selectorlist.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_selectorlist.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_selectorlist.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,147 @@ +"""Testcases for cssutils.css.selectorlist.SelectorList.""" + +import xml.dom +import basetest +import cssutils +from cssutils.css.selectorlist import SelectorList + +class SelectorListTestCase(basetest.BaseTestCase): + + def setUp(self): + self.r = SelectorList() + + def test_init(self): + "SelectorList.__init__() and .length" + s = SelectorList() + self.assertEqual(0, s.length) + + s = SelectorList('a, b') + self.assertEqual(2, s.length) + self.assertEqual(u'a, b', s.selectorText) + + s = SelectorList(selectorText='a') + self.assertEqual(1, s.length) + self.assertEqual(u'a', s.selectorText) + + s = SelectorList(selectorText=('p|a', {'p': 'uri'})) # n-dict + self.assertEqual(1, s.length) + self.assertEqual(u'p|a', s.selectorText) + + s = SelectorList(selectorText=('p|a', (('p', 'uri'),))) # n-tuples + self.assertEqual(1, s.length) + self.assertEqual(u'p|a', s.selectorText) + + def test_parentRule(self): + "Selector.parentRule" + def check(style): + self.assertEqual(style, style.selectorList.parentRule) + for sel in style.selectorList: + self.assertEqual(style.selectorList, sel.parent) + + style = cssutils.css.CSSStyleRule('a, b') + check(style) + + # add new selector + style.selectorList.append(cssutils.css.Selector('x')) + check(style) + + # replace selectorList + style.selectorList = cssutils.css.SelectorList('x') + check(style) + + # replace selectorText + style.selectorText = ('x, y') + check(style) + + def test_appendSelector(self): + "SelectorList.appendSelector() and .length" + s = SelectorList() + s.appendSelector('a') + self.assertEqual(1, s.length) + + self.assertRaises(xml.dom.InvalidModificationErr, + s.appendSelector, 'b,') + self.assertEqual(1, s.length) + + self.assertEqual(u'a', s.selectorText) + + s.append('b') + self.assertEqual(2, s.length) + self.assertEqual(u'a, b', s.selectorText) + + s.append('a') + self.assertEqual(2, s.length) + self.assertEqual(u'b, a', s.selectorText) + + # __setitem__ + self.assertRaises(IndexError, s.__setitem__, 4, 'x') + s[1] = 'c' + self.assertEqual(2, s.length) + self.assertEqual(u'b, c', s.selectorText) + # TODO: remove duplicates? +# s[0] = 'c' +# self.assertEqual(1, s.length) +# self.assertEqual(u'c', s.selectorText) + + s = SelectorList() + s.appendSelector(('p|a', {'p': 'uri', 'x': 'xxx'})) + self.assertEqual(u'p|a', s.selectorText) + # x gets lost as not used + self.assertRaises(xml.dom.NamespaceErr, s.append, 'x|a') + # not set at all + self.assertRaises(xml.dom.NamespaceErr, s.append, 'y|a') + # but p is retained + s.append('p|b') + self.assertEqual(u'p|a, p|b', s.selectorText) + + def test_selectorText(self): + "SelectorList.selectorText" + s = SelectorList() + s.selectorText = u'a, b' + self.assertEqual(u'a, b', s.selectorText) + self.assertRaises(xml.dom.SyntaxErr, s._setSelectorText, u',') + # not changed as invalid! + self.assertEqual(u'a, b', s.selectorText) + + tests = { + u'*': None, + u'/*1*/*': None, + u'/*1*/*, a': None, + u'a, b': None, + u'a ,b': u'a, b', + u'a , b': u'a, b', + u'a, b, c': u'a, b, c', + u'#a, x#a, .b, x.b': u'#a, x#a, .b, x.b', + (u'[p|a], p|*', (('p', 'uri'),)): u'[p|a], p|*', + } + # do not parse as not complete + self.do_equal_r(tests, att='selectorText') + + tests = { + u'x|*': xml.dom.NamespaceErr, + u'': xml.dom.SyntaxErr, + u' ': xml.dom.SyntaxErr, + u',': xml.dom.SyntaxErr, + u'a,': xml.dom.SyntaxErr, + u',a': xml.dom.SyntaxErr, + u'/* 1 */,a': xml.dom.SyntaxErr, + } + # only set as not complete + self.do_raise_r(tests, att='_setSelectorText') + + def test_reprANDstr(self): + "SelectorList.__repr__(), .__str__()" + sel=(u'a, p|b', { 'p': 'uri'}) + + s = cssutils.css.SelectorList(selectorText=sel) + + self.assert_(sel[0] in str(s)) + + s2 = eval(repr(s)) + self.assert_(isinstance(s2, s.__class__)) + self.assertEqual(sel[0], s2.selectorText) + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_serialize.py cssutils-0.9.10/src/cssutils/tests/test_serialize.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_serialize.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_serialize.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,740 @@ +# -*- coding: utf-8 -*- +"""Testcases for cssutils.CSSSerializer""" + +import basetest +import cssutils +import sys + + +class PreferencesTestCase(basetest.BaseTestCase): + """ + testcases for cssutils.serialize.Preferences + """ + def setUp(self): + cssutils.ser.prefs.useDefaults() + + def tearDown(self): + cssutils.ser.prefs.useDefaults() + +# def testkeepUnkownAtRules(self): +# "Preferences.keepUnkownAtRules" +# # py >=2.6 only +# # v = sys.version_info; if v[0]*10+v[1] >= 26: +# from warnings import catch_warnings +# with catch_warnings(record=True) as log: +# x = cssutils.ser.prefs.keepUnkownAtRules +# +# if log: +# # unpack the only member of log +# warning, = log +# self.assertEqual(warning.category, DeprecationWarning) + + def test_resolveVariables(self): + "Preferences.resolveVariables" + self.assertEqual(cssutils.ser.prefs.resolveVariables, True) + + cssutils.ser.prefs.resolveVariables = False + + vars = u''' + @variables { + c1: red; + c2: #0f0; + px: 1px 2px; + } + ''' + tests = { + u'''a {\n color: var(c1)\n }''': + u'''a {\n color: red\n }''', + u'''a {\n color: var(c1)\n; color: var( c2 ) }''': + u'''a {\n color: red;\n color: #0f0\n }''', + u'''a {\n margin: var(px)\n }''': + u'''a {\n margin: 1px 2px\n }''', + u'''@media all { + a { + margin: var(px) var(px); + color: var(c1); + left: var(unknown) + } + }''': + u'''@media all {\n a {\n margin: 1px 2px 1px 2px;\n color: red;\n left: var(unknown)\n }\n }''', + } + cssutils.ser.prefs.resolveVariables = True + + for test, exp in tests.items(): + s = cssutils.parseString(vars + test) + self.assertEqual(exp.encode(), s.cssText) + + cssutils.ser.prefs.resolveVariables = True + + + def test_useDefaults(self): + "Preferences.useDefaults()" + cssutils.ser.prefs.useMinified() + cssutils.ser.prefs.useDefaults() + self.assertEqual(cssutils.ser.prefs.defaultAtKeyword, True) + self.assertEqual(cssutils.ser.prefs.defaultPropertyName, True) + self.assertEqual(cssutils.ser.prefs.defaultPropertyPriority, True) + self.assertEqual(cssutils.ser.prefs.importHrefFormat, None) + self.assertEqual(cssutils.ser.prefs.indent, 4 * u' ') + self.assertEqual(cssutils.ser.prefs.indentClosingBrace, True) + self.assertEqual(cssutils.ser.prefs.keepAllProperties, True) + self.assertEqual(cssutils.ser.prefs.keepComments, True) + self.assertEqual(cssutils.ser.prefs.keepEmptyRules, False) + self.assertEqual(cssutils.ser.prefs.keepUnknownAtRules, True) + self.assertEqual(cssutils.ser.prefs.keepUsedNamespaceRulesOnly, False) + self.assertEqual(cssutils.ser.prefs.lineNumbers, False) + self.assertEqual(cssutils.ser.prefs.lineSeparator, u'\n') + self.assertEqual(cssutils.ser.prefs.listItemSpacer, u' ') + self.assertEqual(cssutils.ser.prefs.omitLastSemicolon, True) + self.assertEqual(cssutils.ser.prefs.omitLeadingZero, False) + self.assertEqual(cssutils.ser.prefs.paranthesisSpacer, u' ') + self.assertEqual(cssutils.ser.prefs.propertyNameSpacer, u' ') + self.assertEqual(cssutils.ser.prefs.selectorCombinatorSpacer, u' ') + self.assertEqual(cssutils.ser.prefs.spacer, u' ') + self.assertEqual(cssutils.ser.prefs.validOnly, False) + css = u''' + /*1*/ + @import url(x) tv , print; + @namespace prefix "uri"; + @namespace unused "unused"; + @media all {} + @media all { + a {} + } + @media all { + a { color: red; } + } + @page { left: 0; } + a {} + prefix|x, a + b > c ~ d , b { top : 1px ; + font-family : arial ,'some' + } + ''' + parsedcss = u'''/*1*/ +@import url(x) tv, print; +@namespace prefix "uri"; +@namespace unused "unused"; +@media all { + a { + color: red + } + } +@page { + left: 0 + } +prefix|x, a + b > c ~ d, b { + top: 1px; + font-family: arial, "some" + }''' + s = cssutils.parseString(css) + self.assertEqual(s.cssText, parsedcss.encode()) + + tests = { + u'0.1 .1 0.1px .1px 0.1% .1% +0.1 +.1 +0.1px +.1px +0.1% +.1% -0.1 -.1 -0.1px -.1px -0.1% -.1%': + u'0.1 0.1 0.1px 0.1px 0.1% 0.1% +0.1 +0.1 +0.1px +0.1px +0.1% +0.1% -0.1 -0.1 -0.1px -0.1px -0.1% -0.1%' + } + cssutils.ser.prefs.useDefaults() + for test, exp in tests.items(): + s = cssutils.parseString(u'a{x:%s}' % test) + self.assertEqual((u'a {\n x: %s\n }' % exp).encode(), s.cssText) + + + def test_useMinified(self): + "Preferences.useMinified()" + cssutils.ser.prefs.useDefaults() + cssutils.ser.prefs.useMinified() + self.assertEqual(cssutils.ser.prefs.defaultAtKeyword, True) + self.assertEqual(cssutils.ser.prefs.defaultPropertyName, True) + self.assertEqual(cssutils.ser.prefs.importHrefFormat, 'string') + self.assertEqual(cssutils.ser.prefs.indent, u'') + self.assertEqual(cssutils.ser.prefs.keepAllProperties, True) + self.assertEqual(cssutils.ser.prefs.keepComments, False) + self.assertEqual(cssutils.ser.prefs.keepEmptyRules, False) + self.assertEqual(cssutils.ser.prefs.keepUnknownAtRules, False) + self.assertEqual(cssutils.ser.prefs.keepUsedNamespaceRulesOnly, True) + self.assertEqual(cssutils.ser.prefs.lineNumbers, False) + self.assertEqual(cssutils.ser.prefs.lineSeparator, u'') + self.assertEqual(cssutils.ser.prefs.listItemSpacer, u'') + self.assertEqual(cssutils.ser.prefs.omitLastSemicolon, True) + self.assertEqual(cssutils.ser.prefs.omitLeadingZero, True) + self.assertEqual(cssutils.ser.prefs.paranthesisSpacer, u'') + self.assertEqual(cssutils.ser.prefs.propertyNameSpacer, u'') + self.assertEqual(cssutils.ser.prefs.selectorCombinatorSpacer, u'') + self.assertEqual(cssutils.ser.prefs.spacer, u'') + self.assertEqual(cssutils.ser.prefs.validOnly, False) + + css = u''' + /*1*/ + @import url(x) tv , print; + @namespace prefix "uri"; + @namespace unused "unused"; + @media all {} + @media all { + a {} + } + @media all "name" { + a { color: red; } + } + @page:left { + left: 0 + } + a {} + prefix|x, a + b > c ~ d , b { top : 1px ; + font-family : arial , 'some' + } + @x x; + ''' + s = cssutils.parseString(css) + cssutils.ser.prefs.keepUnknownAtRules = True + self.assertEqual(s.cssText, + u'''@import"x"tv,print;@namespace prefix"uri";@media all"name"{a{color:red}}@page :left{left:0}prefix|x,a+b>c~d,b{top:1px;font-family:arial,"some"}@x x;'''.encode() + ) + cssutils.ser.prefs.keepUnknownAtRules = False + self.assertEqual(s.cssText, + u'''@import"x"tv,print;@namespace prefix"uri";@media all"name"{a{color:red}}@page :left{left:0}prefix|x,a+b>c~d,b{top:1px;font-family:arial,"some"}'''.encode() + ) + # Values + valuetests = { + u' a a1 a-1 a-1a ': 'a a1 a-1 a-1a', + u'a b 1 c 1em d -1em e': u'a b 1 c 1em d -1em e', + u' 1em / 5 ': u'1em/5', + u'1em/5': u'1em/5', + u'a 0 a .0 a 0.0 a -0 a -.0 a -0.0 a +0 a +.0 a +0.0': + u'a 0 a 0 a 0 a 0 a 0 a 0 a 0 a 0 a 0', + u'a 0px a .0px a 0.0px a -0px a -.0px a -0.0px a +0px a +.0px a +0.0px ': + u'a 0 a 0 a 0 a 0 a 0 a 0 a 0 a 0 a 0', + u'a 1 a .1 a 1.0 a 0.1 a -1 a -.1 a -1.0 a -0.1 a +1 a +.1 a +1.0': + u'a 1 a .1 a 1 a .1 a -1 a -.1 a -1 a -.1 a +1 a +.1 a +1', + u' url(x) f()': 'url(x) f()', + u'#112233': '#123', + u'#112234': '#112234', + u'#123': '#123', + u'#123 url() f()': '#123 url() f()', + u'1 +2 +3 -4': u'1 +2 +3 -4', # ? + u'0.1 .1 0.1px .1px 0.1% .1% +0.1 +.1 +0.1px +.1px +0.1% +.1% -0.1 -.1 -0.1px -.1px -0.1% -.1%': + u'.1 .1 .1px .1px .1% .1% +.1 +.1 +.1px +.1px +.1% +.1% -.1 -.1 -.1px -.1px -.1% -.1%' + } + for test, exp in valuetests.items(): + s = cssutils.parseString(u'a{x:%s}' % test) + self.assertEqual((u'a{x:%s}' % exp).encode(), s.cssText) + + + + def test_defaultAtKeyword(self): + "Preferences.defaultAtKeyword" + s = cssutils.parseString(u'@im\\port "x";') + self.assertEqual(u'@import "x";'.encode(), s.cssText) + cssutils.ser.prefs.defaultAtKeyword = True + self.assertEqual(u'@import "x";'.encode(), s.cssText) + cssutils.ser.prefs.defaultAtKeyword = False + self.assertEqual(u'@im\\port "x";'.encode(), s.cssText) + + def test_defaultPropertyName(self): + "Preferences.defaultPropertyName" + cssutils.ser.prefs.keepAllProperties = False + + # does not actually work as once the name is set it is used also + # if used with a backslash in it later... + + s = cssutils.parseString(ur'a { c\olor: green; }') + self.assertEqual(u'a {\n color: green\n }'.encode(), s.cssText) + cssutils.ser.prefs.defaultPropertyName = True + self.assertEqual(u'a {\n color: green\n }'.encode(), s.cssText) + cssutils.ser.prefs.defaultPropertyName = False + self.assertEqual(u'a {\n c\\olor: green\n }'.encode(), s.cssText) + + s = cssutils.parseString(u'a { color: red; c\olor: green; }') + self.assertEqual(u'a {\n c\\olor: green\n }'.encode(), s.cssText) + cssutils.ser.prefs.defaultPropertyName = False + self.assertEqual(u'a {\n c\\olor: green\n }'.encode(), s.cssText) + cssutils.ser.prefs.defaultPropertyName = True + self.assertEqual(u'a {\n color: green\n }'.encode(), s.cssText) + + def test_defaultPropertyPriority(self): + "Preferences.defaultPropertyPriority" + css = u'a {\n color: green !IM\\portant\n }' + s = cssutils.parseString(css) + self.assertEqual(s.cssText, u'a {\n color: green !important\n }'.encode()) + cssutils.ser.prefs.defaultPropertyPriority = False + self.assertEqual(s.cssText, css.encode()) + + def test_importHrefFormat(self): + "Preferences.importHrefFormat" + r0 = cssutils.css.CSSImportRule() + r0.cssText=u'@import url("not");' + r1 = cssutils.css.CSSImportRule() + r1.cssText=u'@import "str";' + self.assertEqual(u'@import url(not);', r0.cssText) + self.assertEqual(u'@import "str";', r1.cssText) + + cssutils.ser.prefs.importHrefFormat = 'string' + self.assertEqual(u'@import "not";', r0.cssText) + self.assertEqual(u'@import "str";', r1.cssText) + + cssutils.ser.prefs.importHrefFormat = 'uri' + self.assertEqual(u'@import url(not);', r0.cssText) + self.assertEqual(u'@import url(str);', r1.cssText) + + cssutils.ser.prefs.importHrefFormat = 'not defined' + self.assertEqual(u'@import url(not);', r0.cssText) + self.assertEqual(u'@import "str";', r1.cssText) + + def test_indent(self): + "Preferences.ident" + s = cssutils.parseString(u'a { left: 0 }') + exp4 = u'''a { + left: 0 + }''' + exp1 = u'''a { + left: 0 + }''' + cssutils.ser.prefs.indent = ' ' + self.assertEqual(exp1.encode(), s.cssText) + cssutils.ser.prefs.indent = 4* ' ' + self.assertEqual(exp4.encode(), s.cssText) + + def test_indentClosingBrace(self): + "Preferences.indentClosingBrace" + s = cssutils.parseString(u'@media all {a {left: 0}} b { top: 0 }') + expT = u'''@media all { + a { + left: 0 + } + } +b { + top: 0 + }''' + expF = u'''@media all { + a { + left: 0 + } +} +b { + top: 0 +}''' + cssutils.ser.prefs.useDefaults() + self.assertEqual(expT.encode(), s.cssText) + cssutils.ser.prefs.indentClosingBrace = False + self.assertEqual(expF.encode(), s.cssText) + + def test_keepAllProperties(self): + "Preferences.keepAllProperties" + css = '''a { + color: pink; + color: red; + c\olor: blue; + c\olor: green; + }''' + s = cssutils.parseString(css) + # keep only last + cssutils.ser.prefs.keepAllProperties = False + self.assertEqual(u'a {\n color: green\n }'.encode(), s.cssText) + # keep all + cssutils.ser.prefs.keepAllProperties = True + self.assertEqual(u'a {\n color: pink;\n color: red;\n c\olor: blue;\n c\olor: green\n }'.encode(), s.cssText) + + def test_keepComments(self): + "Preferences.keepComments" + s = cssutils.parseString('/*1*/ a { /*2*/ }') + cssutils.ser.prefs.keepComments = False + self.assertEqual(''.encode(), s.cssText) + cssutils.ser.prefs.keepEmptyRules = True + self.assertEqual('a {}'.encode(), s.cssText) + + def test_keepEmptyRules(self): + "Preferences.keepEmptyRules" + # CSSStyleRule + css = u'''a {} +a { + /*1*/ + } +a { + color: red + }''' + s = cssutils.parseString(css) + cssutils.ser.prefs.useDefaults() + cssutils.ser.prefs.keepEmptyRules = True + self.assertEqual(css.encode(), s.cssText) + cssutils.ser.prefs.keepEmptyRules = False + self.assertEqual(u'a {\n /*1*/\n }\na {\n color: red\n }'.encode(), + s.cssText) + cssutils.ser.prefs.keepComments = False + self.assertEqual(u'a {\n color: red\n }'.encode(), s.cssText) + + # CSSMediaRule + css = u'''@media tv { + } +@media all { + /*1*/ + } +@media print { + a {} + } +@media print { + a { + /*1*/ + } + } +@media all { + a { + color: red + } + }''' + s = cssutils.parseString(css) + cssutils.ser.prefs.useDefaults() + cssutils.ser.prefs.keepEmptyRules = True + # self.assertEqual(css, s.cssText) + cssutils.ser.prefs.keepEmptyRules = False + self.assertEqual('''@media all { + /*1*/ + } +@media print { + a { + /*1*/ + } + } +@media all { + a { + color: red + } + }'''.encode(), s.cssText) + cssutils.ser.prefs.keepComments = False + self.assertEqual('''@media all { + a { + color: red + } + }'''.encode(), s.cssText) + + def test_keepUnknownAtRules(self): + "Preferences.keepUnknownAtRules" + tests = { + u'''@three-dee { + @background-lighting { + azimuth: 30deg; + elevation: 190deg; + } + h1 { color: red } + } + h1 { color: blue }''': (u'''@three-dee { + @background-lighting { + azimuth: 30deg; + elevation: 190deg; + } h1 { + color: red + } + } +h1 { + color: blue + }''', u'''h1 { + color: blue + }''') + } + for test in tests: + s = cssutils.parseString(test) + expwith, expwithout = tests[test] + cssutils.ser.prefs.keepUnknownAtRules = True + self.assertEqual(s.cssText, expwith.encode()) + cssutils.ser.prefs.keepUnknownAtRules = False + self.assertEqual(s.cssText, expwithout.encode()) + + def test_keepUsedNamespaceRulesOnly(self): + "Preferences.keepUsedNamespaceRulesOnly" + tests = { + # default == prefix => both are combined + '@namespace p "u"; @namespace "u"; p|a, a {top: 0}': + ('@namespace "u";\na, a {\n top: 0\n }', + '@namespace "u";\na, a {\n top: 0\n }'), + '@namespace "u"; @namespace p "u"; p|a, a {top: 0}': + ('@namespace p "u";\np|a, p|a {\n top: 0\n }', + '@namespace p "u";\np|a, p|a {\n top: 0\n }'), + # default and prefix + '@namespace p "u"; @namespace "d"; p|a, a {top: 0}': + ('@namespace p "u";\n@namespace "d";\np|a, a {\n top: 0\n }', + '@namespace p "u";\n@namespace "d";\np|a, a {\n top: 0\n }'), + # prefix only + '@namespace p "u"; @namespace "d"; p|a {top: 0}': + ('@namespace p "u";\n@namespace "d";\np|a {\n top: 0\n }', + '@namespace p "u";\np|a {\n top: 0\n }'), + # default only + '@namespace p "u"; @namespace "d"; a {top: 0}': + ('@namespace p "u";\n@namespace "d";\na {\n top: 0\n }', + '@namespace "d";\na {\n top: 0\n }'), + # prefix-ns only + '@namespace p "u"; @namespace d "d"; p|a {top: 0}': + ('@namespace p "u";\n@namespace d "d";\np|a {\n top: 0\n }', + '@namespace p "u";\np|a {\n top: 0\n }'), + } + for test in tests: + s = cssutils.parseString(test) + expwith, expwithout = tests[test] + cssutils.ser.prefs.keepUsedNamespaceRulesOnly = False + self.assertEqual(s.cssText, expwith.encode()) + cssutils.ser.prefs.keepUsedNamespaceRulesOnly = True + self.assertEqual(s.cssText, expwithout.encode()) + + def test_lineNumbers(self): + "Preferences.lineNumbers" + + s = cssutils.parseString('a {top: 1; left: 2}') + exp0 = '''a { + top: 1; + left: 2 + }''' + exp1 = '''1: a { +2: top: 1; +3: left: 2 +4: }''' + self.assertEqual(False, cssutils.ser.prefs.lineNumbers) + self.assertEqual(exp0.encode(), s.cssText) + cssutils.ser.prefs.lineNumbers = True + self.assertEqual(True, cssutils.ser.prefs.lineNumbers) + self.assertEqual(exp1.encode(), s.cssText) + + def test_lineSeparator(self): + "Preferences.lineSeparator" + s = cssutils.parseString('a { x:1;y:2}') + self.assertEqual('a {\n x: 1;\n y: 2\n }'.encode(), s.cssText) + # cannot be indented as no split possible + cssutils.ser.prefs.lineSeparator = u'' + self.assertEqual('a {x: 1;y: 2 }'.encode(), s.cssText) + # no valid css but should work + cssutils.ser.prefs.lineSeparator = u'XXX' + self.assertEqual('a {XXX x: 1;XXX y: 2XXX }'.encode(), s.cssText) + + def test_listItemSpacer(self): + "Preferences.listItemSpacer" + cssutils.ser.prefs.keepEmptyRules = True + + css = ''' + @import "x" print, tv; +a, b {}''' + s = cssutils.parseString(css) + self.assertEqual(u'@import "x" print, tv;\na, b {}'.encode(), s.cssText) + cssutils.ser.prefs.listItemSpacer = u'' + self.assertEqual(u'@import "x" print,tv;\na,b {}'.encode(), s.cssText) + + def test_omitLastSemicolon(self): + "Preferences.omitLastSemicolon" + css = 'a { x: 1; y: 2 }' + s = cssutils.parseString(css) + self.assertEqual(u'a {\n x: 1;\n y: 2\n }'.encode(), s.cssText) + cssutils.ser.prefs.omitLastSemicolon = False + self.assertEqual(u'a {\n x: 1;\n y: 2;\n }'.encode(), s.cssText) + + def test_normalizedVarNames(self): + "Preferences.normalizedVarNames" + cssutils.ser.prefs.resolveVariables = False + + css = '@variables { A: 1 }' + s = cssutils.parseString(css) + self.assertEqual(u'@variables {\n a: 1\n }'.encode(), s.cssText) + cssutils.ser.prefs.normalizedVarNames = False + self.assertEqual(u'@variables {\n A: 1\n }'.encode(), s.cssText) + + cssutils.ser.prefs.resolveVariables = True + + def test_paranthesisSpacer(self): + "Preferences.paranthesisSpacer" + css = 'a { x: 1; y: 2 }' + s = cssutils.parseString(css) + self.assertEqual(u'a {\n x: 1;\n y: 2\n }'.encode(), s.cssText) + cssutils.ser.prefs.paranthesisSpacer = u'' + self.assertEqual(u'a{\n x: 1;\n y: 2\n }'.encode(), s.cssText) + + def test_propertyNameSpacer(self): + "Preferences.propertyNameSpacer" + css = 'a { x: 1; y: 2 }' + s = cssutils.parseString(css) + self.assertEqual(u'a {\n x: 1;\n y: 2\n }'.encode(), s.cssText) + cssutils.ser.prefs.propertyNameSpacer = u'' + self.assertEqual(u'a {\n x:1;\n y:2\n }'.encode(), s.cssText) + + def test_selectorCombinatorSpacer(self): + "Preferences.selectorCombinatorSpacer" + s = cssutils.css.Selector(selectorText='a+b>c~d e') + self.assertEqual(u'a + b > c ~ d e', s.selectorText) + cssutils.ser.prefs.selectorCombinatorSpacer = u'' + self.assertEqual(u'a+b>c~d e', s.selectorText) + + def test_spacer(self): + cssutils.ser.prefs.spacer = u'' + tests = { + u'@font-face {a:1}': u'@font-face {\n a: 1\n }', + u'@import url( a );': u'@import url(a);', + u'@media all{a{color:red}}': u'@media all {\n a {\n color: red\n }\n }', + u'@namespace "a";': u'@namespace"a";', + u'@namespace a "a";': u'@namespace a"a";', + u'@page :left { a :1 }': u'@page :left {\n a: 1\n }', + u'@x x;': u'@x x;', + u'@import"x"a': u'@import"x"a;' # ? + } + for css, exp in tests.items(): + self.assertEqual(exp.encode(), cssutils.parseString(css).cssText) + + def test_validOnly(self): + "Preferences.validOnly" + # Property + p = cssutils.css.Property('color', '1px') + self.assertEqual(p.cssText, 'color: 1px') + p.value = '1px' + cssutils.ser.prefs.validOnly = True + self.assertEqual(p.cssText, '') + cssutils.ser.prefs.validOnly = False + self.assertEqual(p.cssText, 'color: 1px') + + # CSSStyleDeclaration has no actual property valid + # but is empty if containing invalid Properties only + s = cssutils.css.CSSStyleDeclaration() + s.cssText = u'left: x;top: x' + self.assertEqual(s.cssText, u'left: x;\ntop: x') + cssutils.ser.prefs.validOnly = True + self.assertEqual(s.cssText, u'') + + cssutils.ser.prefs.useDefaults() + cssutils.ser.prefs.keepComments = False + cssutils.ser.prefs.validOnly = True + tests = { + u'h1 { color: red; rotation: 70minutes }': 'h1 {\n color: red;\n }', + u'''img { float: left } /* correct CSS 2.1 */ +img { float: left here } /* "here" is not a value of 'float' */ +img { background: "red" } /* keywords cannot be quoted */ +img { border-width: 3 } /* a unit must be specified for length values */''': 'img {\n float: left\n }' + + } + self.do_equal_p(tests, raising=False) + + +class CSSSerializerTestCase(basetest.BaseTestCase): + """ + testcases for cssutils.CSSSerializer + """ + def setUp(self): + cssutils.ser.prefs.useDefaults() + + def tearDown(self): + cssutils.ser.prefs.useDefaults() + + def test_canonical(self): + tests = { + u'''1''': u'''1''', + # => remove + + u'''+1''': u'''+1''', + # 0 => remove unit + u'''0''': u'''0''', + u'''+0''': u'''0''', + u'''-0''': u'''0''', + u'''0.0''': u'''0''', + u'''00.0''': u'''0''', + u'''00.0px''': u'''0''', + u'''00.0pc''': u'''0''', + u'''00.0em''': u'''0''', + u'''00.0ex''': u'''0''', + u'''00.0cm''': u'''0''', + u'''00.0mm''': u'''0''', + u'''00.0in''': u'''0''', + # 0 => keep unit + u'''00.0%''': u'''0%''', + u'''00.0ms''': u'''0ms''', + u'''00.0s''': u'''0s''', + u'''00.0khz''': u'''0khz''', + u'''00.0hz''': u'''0hz''', + u'''00.0khz''': u'''0khz''', + u'''00.0deg''': u'''0deg''', + u'''00.0rad''': u'''0rad''', + u'''00.0grad''': u'''0grad''', + u'''00.0xx''': u'''0xx''', + # 11. + u'''a, 'b"', serif''': ur'''a, "b\"", serif''', + # SHOULD: \[ => [ but keep! + ur"""url('h)i') '\[\]'""": ur'''url("h)i") "\[\]"''', + u'''rgb(18, 52, 86)''': u'''rgb(18, 52, 86)''', + u'''#123456''': u'''#123456''', + # SHOULD => #112233 + u'''#112233''': u'''#123''', + # SHOULD => #000000 +# u'rgba(000001, 0, 0, 1)': u'#000' + } + for test, exp in tests.items(): + v = cssutils.css.PropertyValue(test) + self.assertEqual(exp, v.cssText) + + + def test_CSSStyleSheet(self): + "CSSSerializer.do_CSSStyleSheet" + css = u'/* κουρος */' + sheet = cssutils.parseString(css) + self.assertEqual(css, unicode(sheet.cssText, 'utf-8')) + + css = u'@charset "utf-8";\n/* κουρος */' + sheet = cssutils.parseString(css) + self.assertEqual(css, unicode(sheet.cssText, 'utf-8')) + sheet.cssRules[0].encoding = 'ascii' + self.assertEqual('@charset "ascii";\n/* \\3BA \\3BF \\3C5 \\3C1 \\3BF \\3C2 */'.encode(), + sheet.cssText) + + def test_Property(self): + "CSSSerializer.do_Property" + + name="color" + value="red" + priority="!important" + + s = cssutils.css.property.Property( + name=name, value=value, priority=priority) + self.assertEqual(u'color: red !important', + cssutils.ser.do_Property(s)) + + s = cssutils.css.property.Property( + name=name, value=value) + self.assertEqual(u'color: red', + cssutils.ser.do_Property(s)) + + def test_escapestring(self): + "CSSSerializer._escapestring" + #'"\a\22\27"' + css = ur'''@import url("ABC\a"); +@import "ABC\a"; +@import 'ABC\a'; +a[href='"\a\22\27"'] { + a: "\a\d\c"; + b: "\a \d \c "; + c: "\""; + d: "\22"; + e: '\''; + f: "\\"; + g: "2\\ 1\ 2\\"; + content: '\27'; + }''' +# exp = ur'''@import url("ABC\a "); +#@import "ABC\a"; +#@import "ABC\a"; +#a[href="\"\a\22\27\""] { +# a: "\a\d\c"; +# b: "\a \d \c "; +# c: "\""; +# d: "\22"; +# e: "'"; +# f: "\\"; +# g: "2\\ 1\ 2\\"; +# content: "\27" +# }''' + exp = ur'''@import url("ABC\a "); +@import "ABC\a "; +@import "ABC\a "; +a[href="\"\a \"'\""] { + a: "\a \d \c "; + b: "\a \d \c "; + c: "\""; + d: "\""; + e: "'"; + f: "\\"; + g: "2\\ 1\ 2\\"; + content: "'" + }''' + sheet = cssutils.parseString(css) + self.assertEqual(sheet.cssText, exp.encode()) + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_settings.py cssutils-0.9.10/src/cssutils/tests/test_settings.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_settings.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_settings.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,26 @@ +"""Testcases for cssutils.settings""" +__version__ = '$Id: test_csscharsetrule.py 1356 2008-07-13 17:29:09Z cthedot $' + +import test_cssrule +import cssutils +import cssutils.settings + +class Settings(test_cssrule.CSSRuleTestCase): + + def test_set(self): + "settings.set()" + cssutils.ser.prefs.useMinified() + text = u'a {filter: progid:DXImageTransform.Microsoft.BasicImage( rotation = 90 )}' + + self.assertEqual(cssutils.parseString(text).cssText, ''.encode()) + + cssutils.settings.set('DXImageTransform.Microsoft', True) + self.assertEqual(cssutils.parseString(text).cssText, + 'a{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=90)}'.encode()) + + cssutils.ser.prefs.useDefaults() + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_stylesheet.py cssutils-0.9.10/src/cssutils/tests/test_stylesheet.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_stylesheet.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_stylesheet.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,44 @@ +"""Testcases for cssutils.stylesheets.StyleSheet""" +__version__ = '$Id: test_csspagerule.py 1869 2009-10-17 19:37:40Z cthedot $' + +import xml.dom +import basetest +import cssutils + +class StyleSheetTestCase(basetest.BaseTestCase): + + def test_init(self): + "StyleSheet.__init__()" + s = cssutils.stylesheets.StyleSheet() + + self.assertEqual(s.type, 'text/css') + self.assertEqual(s.href, None) + self.assertEqual(s.media, None) + self.assertEqual(s.title, u'') + self.assertEqual(s.ownerNode, None) + self.assertEqual(s.parentStyleSheet, None) + self.assertEqual(s.alternate, False) + self.assertEqual(s.disabled, False) + + + s = cssutils.stylesheets.StyleSheet(type='unknown', + href='test.css', + media=None, + title=u'title', + ownerNode=None, + parentStyleSheet=None, + alternate=True, + disabled=True) + + self.assertEqual(s.type, 'unknown') + self.assertEqual(s.href, 'test.css') + self.assertEqual(s.media, None) + self.assertEqual(s.title, u'title') + self.assertEqual(s.ownerNode, None) + self.assertEqual(s.parentStyleSheet, None) + self.assertEqual(s.alternate, True) + self.assertEqual(s.disabled, True) + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_tokenize2.py cssutils-0.9.10/src/cssutils/tests/test_tokenize2.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_tokenize2.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_tokenize2.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,858 @@ +# -*- coding: utf-8 -*- +"""Testcases for new cssutils.tokenize.Tokenizer + +TODO: old tests as new ones are **not complete**! +""" + +import sys +import xml.dom +import basetest +from cssutils.tokenize2 import * + +class TokenizerTestCase(basetest.BaseTestCase): + + testsall = { + # IDENT + u'äöü߀': [('IDENT', u'äöü߀', 1, 1)], + u' a ': [('S', u' ', 1, 1), + ('IDENT', u'a', 1, 2), + ('S', u' ', 1, 3)], + u'_a': [('IDENT', u'_a', 1, 1)], + u'-a': [('IDENT', u'-a', 1, 1)], + u'aA-_\200\377': [('IDENT', u'aA-_\200\377', 1, 1)], + u'a1': [('IDENT', u'a1', 1, 1)], + # escapes must end with S or max 6 digits: + u'\\44 b': [('IDENT', u'Db', 1, 1)], + u'\\44 b': [('IDENT', u'D', 1, 1), + ('S', u' ', 1, 5), + ('IDENT', u'b', 1, 6)], + u'\\44\nb': [('IDENT', u'Db', 1, 1)], + u'\\44\rb': [('IDENT', u'Db', 1, 1)], + u'\\44\fb': [('IDENT', u'Db', 1, 1)], + u'\\44\n*': [('IDENT', u'D', 1, 1), + ('CHAR', u'*', 2, 1)], + u'\\44 a': [('IDENT', u'D', 1, 1), + ('S', u' ', 1, 5), + ('IDENT', u'a', 1, 6)], + # TODO: + # Note that this means that a "real" space after the escape sequence + # must itself either be escaped or doubled: + u'\\44\ x': [('IDENT', u'D\\ x', 1, 1)], + u'\\44 ': [('IDENT', u'D', 1, 1), + ('S', u' ', 1, 5)], + + ur'\44': [('IDENT', u'D', 1, 1)], + ur'\\': [('IDENT', ur'\\', 1, 1)], + ur'\{': [('IDENT', ur'\{', 1, 1)], + ur'\"': [('IDENT', ur'\"', 1, 1)], + ur'\(': [('IDENT', ur'\(', 1, 1)], + ur'\1 \22 \333 \4444 \55555 \666666 \777777 7 \7777777': + [( + ('IDENT', u'\x01"\u0333\u4444\U00055555\\666666 \\777777 7', 1, 1) + if sys.maxunicode > 0x10000 else + ('IDENT', u'\x01"\u0333\u4444\\55555 \\666666 \\777777 7', 1, 1) + ), + ('S', ' ', 1, 43), + ('IDENT', '\\7777777', 1, 44) + ], + + + u'\\1 b': [('IDENT', u'\x01b', 1, 1)], + u'\\44 b': [('IDENT', u'Db', 1, 1)], + u'\\123 b': [('IDENT', u'\u0123b', 1, 1)], + u'\\1234 b': [('IDENT', u'\u1234b', 1, 1)], + u'\\12345 b': + [( + ('IDENT', u'\U00012345b', 1, 1) + if sys.maxunicode > 0x10000 else + ('IDENT', u'\\12345 b', 1, 1) + )], + u'\\123456 b': [('IDENT', u'\\123456 b', 1, 1)], + u'\\1234567 b': [('IDENT', u'\\1234567', 1, 1), + ('S', u' ', 1, 9), + ('IDENT', u'b', 1, 10)], + u'\\{\\}\\(\\)\\[\\]\\#\\@\\.\\,': + [('IDENT', u'\\{\\}\\(\\)\\[\\]\\#\\@\\.\\,', 1, 1)], + + # STRING + u' "" ': [('S', u' ', 1, 1), + ('STRING', u'""', 1, 2), + ('S', u' ', 1, 4)], + u' "\'" ': [('S', u' ', 1, 1), + ('STRING', u'"\'"', 1, 2), + ('S', u' ', 1, 5)], + u" '' ": [('S', u' ', 1, 1), + ('STRING', u"''", 1, 2), + ('S', u' ', 1, 4)], + u" '' ": [('S', u' ', 1, 1), + ('STRING', u"''", 1, 2), + ('S', u' ', 1, 4)], + # until 0.9.5.x + #u"'\\\n'": [('STRING', u"'\\\n'", 1, 1)], + #u"'\\\n\\\n\\\n'": [('STRING', u"'\\\n\\\n\\\n'", 1, 1)], + #u"'\\\f'": [('STRING', u"'\\\f'", 1, 1)], + #u"'\\\r'": [('STRING', u"'\\\r'", 1, 1)], + #u"'\\\r\n'": [('STRING', u"'\\\r\n'", 1, 1)], + #u"'1\\\n2'": [('STRING', u"'1\\\n2'", 1, 1)], + # from 0.9.6a0 escaped nl is removed from string + u"'\\\n'": [('STRING', u"''", 1, 1)], + u"'\\\n\\\n\\\n'": [('STRING', u"''", 1, 1)], + u"'\\\f'": [('STRING', u"''", 1, 1)], + u"'\\\r'": [('STRING', u"''", 1, 1)], + u"'1\\\n2'": [('STRING', u"'12'", 1, 1)], + u"'1\\\r\n2'": [('STRING', u"'12'", 1, 1)], + #ur'"\0020|\0020"': [('STRING', u'"\\0020|\\0020"', 1, 1)], + ur'"\61|\0061"': [('STRING', u'"a|a"', 1, 1)], + + # HASH + u' #a ': [('S', u' ', 1, 1), + ('HASH', u'#a', 1, 2), + ('S', u' ', 1, 4)], + + u'#ccc': [('HASH', u'#ccc', 1, 1)], + u'#111': [('HASH', u'#111', 1, 1)], + u'#a1a1a1': [('HASH', u'#a1a1a1', 1, 1)], + u'#1a1a1a': [('HASH', u'#1a1a1a', 1, 1)], + + # NUMBER, for plus see CSS3 + u' 0 ': [('S', u' ', 1, 1), + ('NUMBER', u'0', 1, 2), + ('S', u' ', 1, 3)], + u' 0.1 ': [('S', u' ', 1, 1), + ('NUMBER', u'0.1', 1, 2), + ('S', u' ', 1, 5)], + u' .0 ': [('S', u' ', 1, 1), + ('NUMBER', u'.0', 1, 2), + ('S', u' ', 1, 4)], + + u' -0 ': [('S', u' ', 1, 1), + ('CHAR', u'-', 1, 2), + ('NUMBER', u'0', 1, 3), + ('S', u' ', 1, 4)], + + # PERCENTAGE + u' 0% ': [('S', u' ', 1, 1), + ('PERCENTAGE', u'0%', 1, 2), + ('S', u' ', 1, 4)], + u' .5% ': [('S', u' ', 1, 1), + ('PERCENTAGE', u'.5%', 1, 2), + ('S', u' ', 1, 5)], + + # URI + u' url() ': [('S', u' ', 1, 1), + ('URI', u'url()', 1, 2), + ('S', u' ', 1, 7)], + u' url(a) ': [('S', u' ', 1, 1), + ('URI', u'url(a)', 1, 2), + ('S', u' ', 1, 8)], + u' url("a") ': [('S', u' ', 1, 1), + ('URI', u'url("a")', 1, 2), + ('S', u' ', 1, 10)], + u' url( a ) ': [('S', u' ', 1, 1), + ('URI', u'url( a )', 1, 2), + ('S', u' ', 1, 10)], + + # UNICODE-RANGE + + # CDO + u' "': [('STRING', u'""', 1, 7)], + + # CDC + u' --> ': [('S', u' ', 1, 1), + ('CDC', u'-->', 1, 2), + ('S', u' ', 1, 5)], + + # S + u' ': [('S', u' ', 1, 1)], + u' ': [('S', u' ', 1, 1)], + u'\r': [('S', u'\r', 1, 1)], + u'\n': [('S', u'\n', 1, 1)], + u'\r\n': [('S', u'\r\n', 1, 1)], + u'\f': [('S', u'\f', 1, 1)], + u'\r': [('S', u'\r', 1, 1)], + u'\t': [('S', u'\t', 1, 1)], + u'\r\n\r\n\f\t ': [('S', u'\r\n\r\n\f\t ', 1, 1)], + + # COMMENT, for incomplete see later + u'/*x*/ ': [('COMMENT', u'/*x*/', 1, 1), + ('S', u' ', 1, 6)], + + # FUNCTION + u' x( ': [('S', u' ', 1, 1), + ('FUNCTION', u'x(', 1, 2), + ('S', u' ', 1, 4)], + + # INCLUDES + u' ~= ': [('S', u' ', 1, 1), + ('INCLUDES', u'~=', 1, 2), + ('S', u' ', 1, 4)], + u'~==': [('INCLUDES', u'~=', 1, 1), ('CHAR', u'=', 1, 3)], + + # DASHMATCH + u' |= ': [('S', u' ', 1, 1), + ('DASHMATCH', u'|=', 1, 2), + ('S', u' ', 1, 4)], + u'|==': [('DASHMATCH', u'|=', 1, 1), ('CHAR', u'=', 1, 3)], + + # CHAR + u' @ ': [('S', u' ', 1, 1), + ('CHAR', u'@', 1, 2), + ('S', u' ', 1, 3)], + + # --- overwritten for CSS 2.1 --- + # LBRACE + u' { ': [('S', u' ', 1, 1), + ('CHAR', u'{', 1, 2), + ('S', u' ', 1, 3)], + # PLUS + u' + ': [('S', u' ', 1, 1), + ('CHAR', u'+', 1, 2), + ('S', u' ', 1, 3)], + # GREATER + u' > ': [('S', u' ', 1, 1), + ('CHAR', u'>', 1, 2), + ('S', u' ', 1, 3)], + # COMMA + u' , ': [('S', u' ', 1, 1), + ('CHAR', u',', 1, 2), + ('S', u' ', 1, 3)], + # class + u' . ': [('S', u' ', 1, 1), + ('CHAR', u'.', 1, 2), + ('S', u' ', 1, 3)], + } + + tests3 = { + # UNICODE-RANGE + u' u+0 ': [('S', u' ', 1, 1), + ('UNICODE-RANGE', u'u+0', 1, 2), + ('S', u' ', 1, 5)], + u' u+01 ': [('S', u' ', 1, 1), + ('UNICODE-RANGE', u'u+01', 1, 2), + ('S', u' ', 1, 6)], + u' u+012 ': [('S', u' ', 1, 1), + ('UNICODE-RANGE', u'u+012', 1, 2), + ('S', u' ', 1, 7)], + u' u+0123 ': [('S', u' ', 1, 1), + ('UNICODE-RANGE', u'u+0123', 1, 2), + ('S', u' ', 1, 8)], + u' u+01234 ': [('S', u' ', 1, 1), + ('UNICODE-RANGE', u'u+01234', 1, 2), + ('S', u' ', 1, 9)], + u' u+012345 ': [('S', u' ', 1, 1), + ('UNICODE-RANGE', u'u+012345', 1, 2), + ('S', u' ', 1, 10)], + u' u+0123456 ': [('S', u' ', 1, 1), + ('UNICODE-RANGE', u'u+012345', 1, 2), + ('NUMBER', u'6', 1, 10), + ('S', u' ', 1, 11)], + u' U+123456 ': [('S', u' ', 1, 1), + ('UNICODE-RANGE', u'U+123456', 1, 2), + ('S', u' ', 1, 10)], + u' \\55+abcdef ': [('S', u' ', 1, 1), + ('UNICODE-RANGE', u'U+abcdef', 1, 2), + ('S', u' ', 1, 12)], + u' \\75+abcdef ': [('S', u' ', 1, 1), + ('UNICODE-RANGE', u'u+abcdef', 1, 2), + ('S', u' ', 1, 12)], + u' u+0-1 ': [('S', u' ', 1, 1), + ('UNICODE-RANGE', u'u+0-1', 1, 2), + ('S', u' ', 1, 7)], + u' u+0-1, u+123456-abcdef ': [('S', u' ', 1, 1), + ('UNICODE-RANGE', u'u+0-1', 1, 2), + ('CHAR', u',', 1, 7), + ('S', u' ', 1, 8), + ('UNICODE-RANGE', u'u+123456-abcdef', 1, 9), + ('S', u' ', 1, 24)], + + # specials + u'c\\olor': [('IDENT', u'c\\olor', 1, 1)], + u'-1': [('CHAR', u'-', 1, 1), ('NUMBER', u'1', 1, 2)], + u'-1px': [('CHAR', u'-', 1, 1), ('DIMENSION', u'1px', 1, 2)], + + # ATKEYWORD + u' @x ': [('S', u' ', 1, 1), + ('ATKEYWORD', u'@x', 1, 2), + ('S', u' ', 1, 4)], + u'@X': [('ATKEYWORD', u'@X', 1, 1)], + u'@\\x': [('ATKEYWORD', u'@\\x', 1, 1)], + # - + u'@1x': [('CHAR', u'@', 1, 1), + ('DIMENSION', u'1x', 1, 2)], + + # DIMENSION + u' 0px ': [('S', u' ', 1, 1), + ('DIMENSION', u'0px', 1, 2), + ('S', u' ', 1, 5)], + u' 1s ': [('S', u' ', 1, 1), + ('DIMENSION', u'1s', 1, 2), + ('S', u' ', 1, 4)], + u'0.2EM': [('DIMENSION', u'0.2EM', 1, 1)], + u'1p\\x': [('DIMENSION', u'1p\\x', 1, 1)], + u'1PX': [('DIMENSION', u'1PX', 1, 1)], + + # NUMBER + u' - 0 ': [('S', u' ', 1, 1), + ('CHAR', u'-', 1, 2), + ('S', u' ', 1, 3), + ('NUMBER', u'0', 1, 4), + ('S', u' ', 1, 5)], + u' + 0 ': [('S', u' ', 1, 1), + ('CHAR', u'+', 1, 2), + ('S', u' ', 1, 3), + ('NUMBER', u'0', 1, 4), + ('S', u' ', 1, 5)], + + # PREFIXMATCH + u' ^= ': [('S', u' ', 1, 1), + ('PREFIXMATCH', u'^=', 1, 2), + ('S', u' ', 1, 4)], + u'^==': [('PREFIXMATCH', u'^=', 1, 1), ('CHAR', u'=', 1, 3)], + + # SUFFIXMATCH + u' $= ': [('S', u' ', 1, 1), + ('SUFFIXMATCH', u'$=', 1, 2), + ('S', u' ', 1, 4)], + u'$==': [('SUFFIXMATCH', u'$=', 1, 1), ('CHAR', u'=', 1, 3)], + + # SUBSTRINGMATCH + u' *= ': [('S', u' ', 1, 1), + ('SUBSTRINGMATCH', u'*=', 1, 2), + ('S', u' ', 1, 4)], + u'*==': [('SUBSTRINGMATCH', u'*=', 1, 1), ('CHAR', u'=', 1, 3)], + + # BOM only at start +# u'\xFEFF ': [('BOM', u'\xfeFF', 1, 1), +# ('S', u' ', 1, 1)], +# u' \xFEFF ': [('S', u' ', 1, 1), +# ('IDENT', u'\xfeFF', 1, 2), +# ('S', u' ', 1, 5)], + u'\xfe\xff ': [('BOM', u'\xfe\xff', 1, 1), + ('S', u' ', 1, 1)], + u' \xfe\xff ': [('S', u' ', 1, 1), + ('IDENT', u'\xfe\xff', 1, 2), + ('S', u' ', 1, 4)], + u'\xef\xbb\xbf ': [('BOM', u'\xef\xbb\xbf', 1, 1), + ('S', u' ', 1, 1)], + u' \xef\xbb\xbf ': [('S', u' ', 1, 1), + ('IDENT', u'\xef\xbb\xbf', 1, 2), + ('S', u' ', 1, 5)], } + + tests2 = { + # escapes work not for a-f! + # IMPORT_SYM + u' @import ': [('S', u' ', 1, 1), + ('IMPORT_SYM', u'@import', 1, 2), + ('S', u' ', 1, 9)], + u'@IMPORT': [('IMPORT_SYM', u'@IMPORT', 1, 1)], + u'@\\49\r\nMPORT': [('IMPORT_SYM', u'@\\49\r\nMPORT', 1, 1)], + ur'@\i\m\p\o\r\t': [('IMPORT_SYM', ur'@\i\m\p\o\r\t', 1, 1)], + ur'@\I\M\P\O\R\T': [('IMPORT_SYM', ur'@\I\M\P\O\R\T', 1, 1)], + ur'@\49 \04d\0050\0004f\000052\54': [('IMPORT_SYM', + ur'@\49 \04d\0050\0004f\000052\54', + 1, 1)], + ur'@\69 \06d\0070\0006f\000072\74': [('IMPORT_SYM', + ur'@\69 \06d\0070\0006f\000072\74', + 1, 1)], + + # PAGE_SYM + u' @page ': [('S', u' ', 1, 1), + ('PAGE_SYM', u'@page', 1, 2), + ('S', u' ', 1, 7)], + u'@PAGE': [('PAGE_SYM', u'@PAGE', 1, 1)], + ur'@\pa\ge': [('PAGE_SYM', ur'@\pa\ge', 1, 1)], + ur'@\PA\GE': [('PAGE_SYM', ur'@\PA\GE', 1, 1)], + ur'@\50\41\47\45': [('PAGE_SYM', ur'@\50\41\47\45', 1, 1)], + ur'@\70\61\67\65': [('PAGE_SYM', ur'@\70\61\67\65', 1, 1)], + + # MEDIA_SYM + u' @media ': [('S', u' ', 1, 1), + ('MEDIA_SYM', u'@media', 1, 2), + ('S', u' ', 1, 8)], + u'@MEDIA': [('MEDIA_SYM', u'@MEDIA', 1, 1)], + ur'@\med\ia': [('MEDIA_SYM', ur'@\med\ia', 1, 1)], + ur'@\MED\IA': [('MEDIA_SYM', ur'@\MED\IA', 1, 1)], + u'@\\4d\n\\45\r\\44\t\\49\r\nA': [('MEDIA_SYM', u'@\\4d\n\\45\r\\44\t\\49\r\nA', 1, 1)], + u'@\\4d\n\\45\r\\44\t\\49\r\\41\f': [('MEDIA_SYM', + u'@\\4d\n\\45\r\\44\t\\49\r\\41\f', + 1, 1)], + u'@\\6d\n\\65\r\\64\t\\69\r\\61\f': [('MEDIA_SYM', + u'@\\6d\n\\65\r\\64\t\\69\r\\61\f', + 1, 1)], + + # FONT_FACE_SYM + u' @font-face ': [('S', u' ', 1, 1), + ('FONT_FACE_SYM', u'@font-face', 1, 2), + ('S', u' ', 1, 12)], + u'@FONT-FACE': [('FONT_FACE_SYM', u'@FONT-FACE', 1, 1)], + ur'@f\o\n\t\-face': [('FONT_FACE_SYM', ur'@f\o\n\t\-face', 1, 1)], + ur'@F\O\N\T\-FACE': [('FONT_FACE_SYM', ur'@F\O\N\T\-FACE', 1, 1)], + # TODO: "-" as hex! + ur'@\46\4f\4e\54\-\46\41\43\45': [('FONT_FACE_SYM', + ur'@\46\4f\4e\54\-\46\41\43\45', 1, 1)], + ur'@\66\6f\6e\74\-\66\61\63\65': [('FONT_FACE_SYM', + ur'@\66\6f\6e\74\-\66\61\63\65', 1, 1)], + + # CHARSET_SYM only if "@charset "! + u'@charset ': [('CHARSET_SYM', u'@charset ', 1, 1), + ('S', u' ', 1, 10)], + u' @charset ': [('S', u' ', 1, 1), + ('CHARSET_SYM', u'@charset ', 1, 2), # not at start + ('S', u' ', 1, 11)], + u'@charset': [('ATKEYWORD', u'@charset', 1, 1)], # no ending S + u'@CHARSET ': [('ATKEYWORD', u'@CHARSET', 1, 1),# uppercase + ('S', u' ', 1, 9)], + u'@cha\\rset ': [('ATKEYWORD', u'@cha\\rset', 1, 1), # not literal + ('S', u' ', 1, 10)], + + # NAMESPACE_SYM + u' @namespace ': [('S', u' ', 1, 1), + ('NAMESPACE_SYM', u'@namespace', 1, 2), + ('S', u' ', 1, 12)], + ur'@NAMESPACE': [('NAMESPACE_SYM', ur'@NAMESPACE', 1, 1)], + ur'@\na\me\s\pace': [('NAMESPACE_SYM', ur'@\na\me\s\pace', 1, 1)], + ur'@\NA\ME\S\PACE': [('NAMESPACE_SYM', ur'@\NA\ME\S\PACE', 1, 1)], + ur'@\4e\41\4d\45\53\50\41\43\45': [('NAMESPACE_SYM', + ur'@\4e\41\4d\45\53\50\41\43\45', 1, 1)], + ur'@\6e\61\6d\65\73\70\61\63\65': [('NAMESPACE_SYM', + ur'@\6e\61\6d\65\73\70\61\63\65', 1, 1)], + + # ATKEYWORD + u' @unknown ': [('S', u' ', 1, 1), + ('ATKEYWORD', u'@unknown', 1, 2), + ('S', u' ', 1, 10)], + + # STRING + # strings with linebreak in it + u' "\\na"\na': [('S', u' ', 1, 1), + ('STRING', u'"\\na"', 1, 2), + ('S', u'\n', 1, 7), + ('IDENT', u'a', 2, 1)], + u" '\\na'\na": [('S', u' ', 1, 1), + ('STRING', u"'\\na'", 1, 2), + ('S', u'\n', 1, 7), + ('IDENT', u'a', 2, 1)], + u' "\\r\\n\\t\\n\\ra"a': [('S', u' ', 1, 1), + ('STRING', u'"\\r\\n\\t\\n\\ra"', 1, 2), + ('IDENT', u'a', 1, 15)], + + # IMPORTANT_SYM is not IDENT!!! + u' !important ': [('S', u' ', 1, 1), + ('CHAR', u'!', 1, 2), + ('IDENT', u'important', 1, 3), + ('S', u' ', 1, 12)], + u'! /*1*/ important ': [ + ('CHAR', u'!', 1, 1), + ('S', u' ', 1, 2), + ('COMMENT', u'/*1*/', 1, 3), + ('S', u' ', 1, 8), + ('IDENT', u'important', 1, 9), + ('S', u' ', 1, 18)], + u'! important': [('CHAR', u'!', 1, 1), + ('S', u' ', 1, 2), + ('IDENT', u'important', 1, 3)], + u'!\n\timportant': [('CHAR', u'!', 1, 1), + ('S', u'\n\t', 1, 2), + ('IDENT', u'important', 2, 2)], + u'!IMPORTANT': [('CHAR', u'!', 1, 1), + ('IDENT', u'IMPORTANT', 1, 2)], + ur'!\i\m\p\o\r\ta\n\t': [('CHAR', u'!', 1, 1), + ('IDENT', + ur'\i\m\p\o\r\ta\n\t', 1, 2)], + ur'!\I\M\P\O\R\Ta\N\T': [('CHAR', u'!', 1, 1), + ('IDENT', + ur'\I\M\P\O\R\Ta\N\T', 1, 2)], + ur'!\49\4d\50\4f\52\54\41\4e\54': [('CHAR', u'!', 1, 1), + ('IDENT', + ur'IMPORTANT', + 1, 2)], + ur'!\69\6d\70\6f\72\74\61\6e\74': [('CHAR', u'!', 1, 1), + ('IDENT', + ur'important', + 1, 2)], + } + + # overwriting tests in testsall + tests2only = { + # LBRACE + u' { ': [('S', u' ', 1, 1), + ('LBRACE', u'{', 1, 2), + ('S', u' ', 1, 3)], + # PLUS + u' + ': [('S', u' ', 1, 1), + ('PLUS', u'+', 1, 2), + ('S', u' ', 1, 3)], + # GREATER + u' > ': [('S', u' ', 1, 1), + ('GREATER', u'>', 1, 2), + ('S', u' ', 1, 3)], + # COMMA + u' , ': [('S', u' ', 1, 1), + ('COMMA', u',', 1, 2), + ('S', u' ', 1, 3)], + # class + u' . ': [('S', u' ', 1, 1), + ('CLASS', u'.', 1, 2), + ('S', u' ', 1, 3)], + } + + testsfullsheet = { + # escape ends with explicit space but \r\n as single space + u'\\65\r\nb': [('IDENT', u'eb', 1, 1)], + + # STRING + ur'"\""': [('STRING', ur'"\""', 1, 1)], + ur'"\" "': [('STRING', ur'"\" "', 1, 1)], + u"""'\\''""": [('STRING', u"""'\\''""", 1, 1)], + u'''"\\""''': [('STRING', u'''"\\""''', 1, 1)], + u' "\na': [('S', u' ', 1, 1), + ('INVALID', u'"', 1, 2), + ('S', u'\n', 1, 3), + ('IDENT', u'a', 2, 1)], + + # strings with linebreak in it + u' "\\na\na': [('S', u' ', 1, 1), + ('INVALID', u'"\\na', 1, 2), + ('S', u'\n', 1, 6), + ('IDENT', u'a', 2, 1)], + u' "\\r\\n\\t\\n\\ra\na': [('S', u' ', 1, 1), + ('INVALID', u'"\\r\\n\\t\\n\\ra', 1, 2), + ('S', u'\n', 1, 14), + ('IDENT', u'a', 2, 1)], + # URI + u'ur\\l(a)': [('URI', u'ur\\l(a)', 1, 1)], + u'url(a)': [('URI', u'url(a)', 1, 1)], + u'\\55r\\4c(a)': [('URI', u'UrL(a)', 1, 1)], + u'\\75r\\6c(a)': [('URI', u'url(a)', 1, 1)], + u' url())': [('S', u' ', 1, 1), + ('URI', u'url()', 1, 2), + ('CHAR', u')', 1, 7)], + u'url("x"))': [('URI', u'url("x")', 1, 1), + ('CHAR', u')', 1, 9)], + u"url('x'))": [('URI', u"url('x')", 1, 1), + ('CHAR', u')', 1, 9)], + } + + # tests if fullsheet=False is set on tokenizer + testsfullsheetfalse = { + # COMMENT incomplete + u'/*': [('CHAR', u'/', 1, 1), + ('CHAR', u'*', 1, 2)], + + # INVALID incomplete + u' " ': [('S', u' ', 1, 1), + ('INVALID', u'" ', 1, 2)], + u" 'abc\"with quote\" in it": [('S', u' ', 1, 1), + ('INVALID', u"'abc\"with quote\" in it", 1, 2)], + + # URI incomplete + u'url(a': [('FUNCTION', u'url(', 1, 1), + ('IDENT', u'a', 1, 5)], + u'url("a': [('FUNCTION', u'url(', 1, 1), + ('INVALID', u'"a', 1, 5)], + u"url('a": [('FUNCTION', u'url(', 1, 1), + ('INVALID', u"'a", 1, 5)], + u"UR\\l('a": [('FUNCTION', u'UR\\l(', 1, 1), + ('INVALID', u"'a", 1, 6)], + } + + # tests if fullsheet=True is set on tokenizer + testsfullsheettrue = { + # COMMENT incomplete + u'/*': [('COMMENT', u'/**/', 1, 1)], + +# # INVALID incomplete => STRING + u' " ': [('S', u' ', 1, 1), + ('STRING', u'" "', 1, 2)], + u" 'abc\"with quote\" in it": [('S', u' ', 1, 1), + ('STRING', u"'abc\"with quote\" in it'", 1, 2)], + + # URI incomplete FUNC => URI + u'url(a': [('URI', u'url(a)', 1, 1)], + u'url( a': [('URI', u'url( a)', 1, 1)], + u'url("a': [('URI', u'url("a")', 1, 1)], + u'url( "a ': [('URI', u'url( "a ")', 1, 1)], + u"url('a": [('URI', u"url('a')", 1, 1)], + u'url("a"': [('URI', u'url("a")', 1, 1)], + u"url('a'": [('URI', u"url('a')", 1, 1)], + } + + def setUp(self): + #log = cssutils.errorhandler.ErrorHandler() + self.tokenizer = Tokenizer() + +# NOT USED +# def test_push(self): +# "Tokenizer.push()" +# r = [] +# def do(): +# T = Tokenizer() +# x = False +# for t in T.tokenize('1 x 2 3'): +# if not x and t[1] == 'x': +# T.push(t) +# x = True +# r.append(t[1]) +# return ''.join(r) +# +# # push reinserts token into token stream, so x is doubled +# self.assertEqual('1 xx 2 3', do()) + +# def test_linenumbers(self): +# "Tokenizer line + col" +# pass + + def test_tokenize(self): + "cssutils Tokenizer().tokenize()" + import cssutils.cssproductions + tokenizer = Tokenizer(cssutils.cssproductions.MACROS, + cssutils.cssproductions.PRODUCTIONS) + tests = {} + tests.update(self.testsall) + tests.update(self.tests2) + tests.update(self.tests3) + tests.update(self.testsfullsheet) + tests.update(self.testsfullsheetfalse) + for css in tests: + # check token format + tokens = tokenizer.tokenize(css) + for i, actual in enumerate(tokens): + expected = tests[css][i] + self.assertEqual(expected, actual) + + # check if all same number of tokens + tokens = list(tokenizer.tokenize(css)) + self.assertEqual(len(tokens), len(tests[css])) + + def test_tokenizefullsheet(self): + "cssutils Tokenizer().tokenize(fullsheet=True)" + import cssutils.cssproductions + tokenizer = Tokenizer(cssutils.cssproductions.MACROS, + cssutils.cssproductions.PRODUCTIONS) + tests = {} + tests.update(self.testsall) + tests.update(self.tests2) + tests.update(self.tests3) + tests.update(self.testsfullsheet) + tests.update(self.testsfullsheettrue) + for css in tests: + # check token format + tokens = tokenizer.tokenize(css, fullsheet=True) + for i, actual in enumerate(tokens): + try: + expected = tests[css][i] + except IndexError: + # EOF is added + self.assertEqual(actual[0], 'EOF') + else: + self.assertEqual(expected, actual) + + # check if all same number of tokens + tokens = list(tokenizer.tokenize(css, fullsheet=True)) + # EOF is added so -1 + self.assertEqual(len(tokens) - 1, len(tests[css])) + + + # -------------- + + def __old(self): + + testsOLD = { + u'x x1 -x .-x #_x -': [(1, 1, tt.IDENT, u'x'), + (1, 2, 'S', u' '), + (1, 3, tt.IDENT, u'x1'), + (1, 5, 'S', u' '), + (1, 6, tt.IDENT, u'-x'), + (1, 8, 'S', u' '), + (1, 9, tt.CLASS, u'.'), + (1, 10, tt.IDENT, u'-x'), + (1, 12, 'S', u' '), + (1, 13, tt.HASH, u'#_x'), + (1, 16, 'S', u' '), + (1, 17, 'DELIM', u'-')], + + # num + u'1 1.1 -1 -1.1 .1 -.1 1.': [(1, 1, tt.NUMBER, u'1'), + (1, 2, 'S', u' '), (1, 3, tt.NUMBER, u'1.1'), + (1, 6, 'S', u' '), (1, 7, tt.NUMBER, u'-1'), + (1, 9, 'S', u' '), (1, 10, tt.NUMBER, u'-1.1'), + (1, 14, 'S', u' '), (1, 15, tt.NUMBER, u'0.1'), + (1, 17, 'S', u' '), (1, 18, tt.NUMBER, u'-0.1'), + (1, 21, 'S', u' '), + (1, 22, tt.NUMBER, u'1'), (1, 23, tt.CLASS, u'.') + ], + # CSS3 pseudo + u'::': [(1, 1, tt.PSEUDO_ELEMENT, u'::')], + + # SPECIALS + u'*+>~{},': [(1, 1, tt.UNIVERSAL, u'*'), + (1, 2, tt.PLUS, u'+'), + (1, 3, tt.GREATER, u'>'), + (1, 4, tt.TILDE, u'~'), + (1, 5, tt.LBRACE, u'{'), + (1, 6, tt.RBRACE, u'}'), + (1, 7, tt.COMMA, u',')], + + # DELIM + u'!%:&$|': [(1, 1, 'DELIM', u'!'), + (1, 2, 'DELIM', u'%'), + (1, 3, 'DELIM', u':'), + (1, 4, 'DELIM', u'&'), + (1, 5, 'DELIM', u'$'), + (1, 6, 'DELIM', u'|')], + + + # DIMENSION + u'5em': [(1, 1, tt.DIMENSION, u'5em')], + u' 5em': [(1, 1, 'S', u' '), (1, 2, tt.DIMENSION, u'5em')], + u'5em ': [(1, 1, tt.DIMENSION, u'5em'), (1, 4, 'S', u' ')], + + u'-5em': [(1, 1, tt.DIMENSION, u'-5em')], + u' -5em': [(1, 1, 'S', u' '), (1, 2, tt.DIMENSION, u'-5em')], + u'-5em ': [(1, 1, tt.DIMENSION, u'-5em'), (1, 5, 'S', u' ')], + + u'.5em': [(1, 1, tt.DIMENSION, u'0.5em')], + u' .5em': [(1, 1, 'S', u' '), (1, 2, tt.DIMENSION, u'0.5em')], + u'.5em ': [(1, 1, tt.DIMENSION, u'0.5em'), (1, 5, 'S', u' ')], + + u'-.5em': [(1, 1, tt.DIMENSION, u'-0.5em')], + u' -.5em': [(1, 1, 'S', u' '), (1, 2, tt.DIMENSION, u'-0.5em')], + u'-.5em ': [(1, 1, tt.DIMENSION, u'-0.5em'), (1, 6, 'S', u' ')], + + u'5em5_-': [(1, 1, tt.DIMENSION, u'5em5_-')], + + u'a a5 a5a 5 5a 5a5': [(1, 1, tt.IDENT, u'a'), + (1, 2, 'S', u' '), + (1, 3, tt.IDENT, u'a5'), + (1, 5, 'S', u' '), + (1, 6, tt.IDENT, u'a5a'), + (1, 9, 'S', u' '), + (1, 10, tt.NUMBER, u'5'), + (1, 11, 'S', u' '), + (1, 12, tt.DIMENSION, u'5a'), + (1, 14, 'S', u' '), + (1, 15, tt.DIMENSION, u'5a5')], + + # URI + u'url()': [(1, 1, tt.URI, u'url()')], + u'url();': [(1, 1, tt.URI, u'url()'), (1, 6, tt.SEMICOLON, ';')], + u'url("x")': [(1, 1, tt.URI, u'url("x")')], + u'url( "x")': [(1, 1, tt.URI, u'url("x")')], + u'url("x" )': [(1, 1, tt.URI, u'url("x")')], + u'url( "x" )': [(1, 1, tt.URI, u'url("x")')], + u' url("x")': [ + (1, 1, 'S', u' '), + (1, 2, tt.URI, u'url("x")')], + u'url("x") ': [ + (1, 1, tt.URI, u'url("x")'), + (1, 9, 'S', u' '), + ], + u'url(ab)': [(1, 1, tt.URI, u'url(ab)')], + u'url($#/ab)': [(1, 1, tt.URI, u'url($#/ab)')], + u'url(\1233/a/b)': [(1, 1, tt.URI, u'url(\1233/a/b)')], + # not URI + u'url("1""2")': [ + (1, 1, tt.FUNCTION, u'url('), + (1, 5, tt.STRING, u'"1"'), + (1, 8, tt.STRING, u'"2"'), + (1, 11, tt.RPARANTHESIS, u')'), + ], + u'url(a"2")': [ + (1, 1, tt.FUNCTION, u'url('), + (1, 5, tt.IDENT, u'a'), + (1, 6, tt.STRING, u'"2"'), + (1, 9, tt.RPARANTHESIS, u')'), + ], + u'url(a b)': [ + (1, 1, tt.FUNCTION, u'url('), + (1, 5, tt.IDENT, u'a'), + (1, 6, 'S', u' '), + (1, 7, tt.IDENT, u'b'), + (1, 8, tt.RPARANTHESIS, u')'), + ], + + # FUNCTION + u' counter("x")': [ + (1,1, 'S', u' '), + (1, 2, tt.FUNCTION, u'counter('), + (1, 10, tt.STRING, u'"x"'), + (1, 13, tt.RPARANTHESIS, u')')], + # HASH + u'# #a #_a #-a #1': [ + (1, 1, 'DELIM', u'#'), + (1, 2, 'S', u' '), + (1, 3, tt.HASH, u'#a'), + (1, 5, 'S', u' '), + (1, 6, tt.HASH, u'#_a'), + (1, 9, 'S', u' '), + (1, 10, tt.HASH, u'#-a'), + (1, 13, 'S', u' '), + (1, 14, tt.HASH, u'#1') + ], + u'#1a1 ': [ + (1, 1, tt.HASH, u'#1a1'), + (1, 5, 'S', u' '), + ], + u'#1a1\n': [ + (1, 1, tt.HASH, u'#1a1'), + (1, 5, 'S', u'\n'), + ], + u'#1a1{': [ + (1, 1, tt.HASH, u'#1a1'), + (1, 5, tt.LBRACE, u'{'), + ], + u'#1a1 {': [ + (1, 1, tt.HASH, u'#1a1'), + (1, 5, 'S', u' '), + (1, 6, tt.LBRACE, u'{'), + ], + u'#1a1\n{': [ + (1, 1, tt.HASH, u'#1a1'), + (1, 5, 'S', u'\n'), + (2, 1, tt.LBRACE, u'{'), + ], + u'#1a1\n {': [ + (1, 1, tt.HASH, u'#1a1'), + (1, 5, 'S', u'\n '), + (2, 2, tt.LBRACE, u'{'), + ], + u'#1a1 \n{': [ + (1, 1, tt.HASH, u'#1a1'), + (1, 5, 'S', u' \n'), + (2, 1, tt.LBRACE, u'{'), + ], + # STRINGS with NL + u'"x\n': [(1,1, tt.INVALID, u'"x\n')], + u'"x\r': [(1,1, tt.INVALID, u'"x\r')], + u'"x\f': [(1,1, tt.INVALID, u'"x\f')], + u'"x\n ': [ + (1,1, tt.INVALID, u'"x\n'), + (2,1, 'S', u' ') + ] + + } + + tests = { + u'/*a': xml.dom.SyntaxErr, + u'"a': xml.dom.SyntaxErr, + u"'a": xml.dom.SyntaxErr, + u"\\0 a": xml.dom.SyntaxErr, + u"\\00": xml.dom.SyntaxErr, + u"\\000": xml.dom.SyntaxErr, + u"\\0000": xml.dom.SyntaxErr, + u"\\00000": xml.dom.SyntaxErr, + u"\\000000": xml.dom.SyntaxErr, + u"\\0000001": xml.dom.SyntaxErr + } +# self.tokenizer.log.raiseExceptions = True #!! +# for css, exception in tests.items(): +# self.assertRaises(exception, self.tokenizer.tokenize, css) + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_util.py cssutils-0.9.10/src/cssutils/tests/test_util.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_util.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_util.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,422 @@ +# -*- coding: utf-8 -*- +"""Testcases for cssutils.util""" +from __future__ import with_statement + +import cgi +from email import message_from_string, message_from_file +import StringIO +import sys +import urllib2 +import xml.dom + +try: + import mock +except ImportError: + mock = None + print "install mock library to run all tests" + +import basetest +import encutils + +from cssutils.util import Base, ListSeq, _readUrl, _defaultFetcher + +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 = {u'abcdefg ABCDEFG äöü߀ AÖÜ': u'abcdefg abcdefg äöü߀ aöü', + ur'\ga\Ga\\\ ': ur'gaga\ ', + ur'0123456789': u'0123456789', + # unicode escape seqs should have been done by + # the tokenizer... + } + for test, exp in 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', u'a[{1}]({2}) { } NOT', u'a[{1}]({2}) { }', False), + ('default', u'a[{1}]({2}) { } NOT', u'a[{1}]func({2}) { }', True), + ('blockstartonly', u'a[{1}]({2}) { NOT', u'a[{1}]({2}) {', False), + ('blockstartonly', u'a[{1}]({2}) { NOT', u'a[{1}]func({2}) {', True), + ('propertynameendonly', u'a[(2)1] { }2 : a;', u'a[(2)1] { }2 :', False), + ('propertynameendonly', u'a[(2)1] { }2 : a;', u'a[func(2)1] { }2 :', True), + ('propertyvalueendonly', u'a{;{;}[;](;)}[;{;}[;](;)](;{;}[;](;)) 1; NOT', + u'a{;{;}[;](;)}[;{;}[;](;)](;{;}[;](;)) 1;', False), + ('propertyvalueendonly', u'a{;{;}[;](;)}[;{;}[;](;)](;{;}[;](;)) 1; NOT', + u'a{;{;}[;]func(;)}[;{;}[;]func(;)]func(;{;}[;]func(;)) 1;', True), + ('funcendonly', u'a{[1]}([3])[{[1]}[2]([3])]) NOT', + u'a{[1]}([3])[{[1]}[2]([3])])', False), + ('funcendonly', u'a{[1]}([3])[{[1]}[2]([3])]) NOT', + u'a{[1]}func([3])[{[1]}[2]func([3])])', True), + ('selectorattendonly', u'[a[()]{()}([()]{()}())] NOT', + u'[a[()]{()}([()]{()}())]', False), + ('selectorattendonly', u'[a[()]{()}([()]{()}())] NOT', + u'[a[func()]{func()}func([func()]{func()}func())]', True), + # issue 50 + ('withstarttoken [', u'a];x', u'[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 u'(' == t[1]: + tokens[i] = ('FUNCTION', u'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 = u''.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, u''), + (None, u'€'.encode('utf-8')): ('utf-8', 5, u'€'), + ('utf-8', u'€'.encode('utf-8')): ('utf-8', 1, u'€'), + ('ISO-8859-1', u'ä'.encode('iso-8859-1')): ('ISO-8859-1', 1, u'ä'), + ('ASCII', u'a'.encode('ascii')): ('ASCII', 1, u'a') + } + + for r, exp in tests.items(): + self.assertEquals(_readUrl(url, fetcher=make_fetcher(r)), exp) + + tests = { + # (overrideEncoding, parentEncoding, (httpencoding, content)): + # readUrl returns + + # ===== 0. OVERRIDE WINS ===== + # override + parent + http + ('latin1', 'ascii', ('utf-16', u''.encode())): ('latin1', 0, u''), + ('latin1', 'ascii', ('utf-16', u'123'.encode())): ('latin1', 0, u'123'), + ('latin1', 'ascii', ('utf-16', u'ä'.encode('iso-8859-1'))): + ('latin1', 0, u'ä'), + ('latin1', 'ascii', ('utf-16', u'a'.encode('ascii'))): + ('latin1',0, u'a'), + # + @charset + ('latin1', 'ascii', ('utf-16', u'@charset "ascii";'.encode())): + ('latin1', 0, u'@charset "latin1";'), + ('latin1', 'ascii', ('utf-16', u'@charset "utf-8";ä'.encode('latin1'))): + ('latin1', 0, u'@charset "latin1";ä'), + ('latin1', 'ascii', ('utf-16', u'@charset "utf-8";ä'.encode('utf-8'))): + ('latin1', 0, u'@charset "latin1";\xc3\xa4'), # read as latin1! + + # override only + ('latin1', None, None): (None, None, None), + ('latin1', None, (None, u''.encode())): ('latin1', 0, u''), + ('latin1', None, (None, u'123'.encode())): ('latin1', 0, u'123'), + ('latin1', None, (None, u'ä'.encode('iso-8859-1'))): + ('latin1', 0, u'ä'), + ('latin1', None, (None, u'a'.encode('ascii'))): + ('latin1', 0, u'a'), + # + @charset + ('latin1', None, (None, u'@charset "ascii";'.encode())): + ('latin1', 0, u'@charset "latin1";'), + ('latin1', None, (None, u'@charset "utf-8";ä'.encode('latin1'))): + ('latin1', 0, u'@charset "latin1";ä'), + ('latin1', None, (None, u'@charset "utf-8";ä'.encode('utf-8'))): + ('latin1', 0, u'@charset "latin1";\xc3\xa4'), # read as latin1! + + # override + parent + ('latin1', 'ascii', None): (None, None, None), + ('latin1', 'ascii', (None, u''.encode())): ('latin1', 0, u''), + ('latin1', 'ascii', (None, u'123'.encode())): ('latin1', 0, u'123'), + ('latin1', 'ascii', (None, u'ä'.encode('iso-8859-1'))): + ('latin1', 0, u'ä'), + ('latin1', 'ascii', (None, u'a'.encode('ascii'))): + ('latin1', 0, u'a'), + # + @charset + ('latin1', 'ascii', (None, u'@charset "ascii";'.encode())): + ('latin1', 0, u'@charset "latin1";'), + ('latin1', 'ascii', (None, u'@charset "utf-8";ä'.encode('latin1'))): + ('latin1', 0, u'@charset "latin1";ä'), + ('latin1', 'ascii', (None, u'@charset "utf-8";ä'.encode('utf-8'))): + ('latin1', 0, u'@charset "latin1";\xc3\xa4'), # read as latin1! + + # override + http + ('latin1', None, ('utf-16', u''.encode())): ('latin1', 0, u''), + ('latin1', None, ('utf-16', u'123'.encode())): ('latin1', 0, u'123'), + ('latin1', None, ('utf-16', u'ä'.encode('iso-8859-1'))): + ('latin1', 0, u'ä'), + ('latin1', None, ('utf-16', u'a'.encode('ascii'))): + ('latin1', 0, u'a'), + # + @charset + ('latin1', None, ('utf-16', u'@charset "ascii";'.encode())): + ('latin1', 0, u'@charset "latin1";'), + ('latin1', None, ('utf-16', u'@charset "utf-8";ä'.encode('latin1'))): + ('latin1', 0, u'@charset "latin1";ä'), + ('latin1', None, ('utf-16', u'@charset "utf-8";ä'.encode('utf-8'))): + ('latin1', 0, u'@charset "latin1";\xc3\xa4'), # read as latin1! + + # override ü @charset + ('latin1', None, (None, u'@charset "ascii";'.encode())): + ('latin1', 0, u'@charset "latin1";'), + ('latin1', None, (None, u'@charset "utf-8";ä'.encode('latin1'))): + ('latin1', 0, u'@charset "latin1";ä'), + ('latin1', None, (None, u'@charset "utf-8";ä'.encode('utf-8'))): + ('latin1', 0, u'@charset "latin1";\xc3\xa4'), # read as latin1! + + + # ===== 1. HTTP WINS ===== + (None, 'ascii', ('latin1', u''.encode())): ('latin1', 1, u''), + (None, 'ascii', ('latin1', u'123'.encode())): ('latin1', 1, u'123'), + (None, 'ascii', ('latin1', u'ä'.encode('iso-8859-1'))): + ('latin1', 1, u'ä'), + (None, 'ascii', ('latin1', u'a'.encode('ascii'))): + ('latin1', 1, u'a'), + # + @charset + (None, 'ascii', ('latin1', u'@charset "ascii";'.encode())): + ('latin1', 1, u'@charset "latin1";'), + (None, 'ascii', ('latin1', u'@charset "utf-8";ä'.encode('latin1'))): + ('latin1', 1, u'@charset "latin1";ä'), + (None, 'ascii', ('latin1', u'@charset "utf-8";ä'.encode('utf-8'))): + ('latin1', 1, u'@charset "latin1";\xc3\xa4'), # read as latin1! + + + # ===== 2. @charset WINS ===== + (None, 'ascii', (None, u'@charset "latin1";'.encode())): + ('latin1', 2, u'@charset "latin1";'), + (None, 'ascii', (None, u'@charset "latin1";ä'.encode('latin1'))): + ('latin1', 2, u'@charset "latin1";ä'), + (None, 'ascii', (None, u'@charset "latin1";ä'.encode('utf-8'))): + ('latin1', 2, u'@charset "latin1";\xc3\xa4'), # read as latin1! + + # ===== 2. BOM WINS ===== + (None, 'ascii', (None, u'ä'.encode('utf-8-sig'))): + ('utf-8-sig', 2, u'\xe4'), # read as latin1! + (None, 'ascii', (None, u'@charset "utf-8";ä'.encode('utf-8-sig'))): + ('utf-8-sig', 2, u'@charset "utf-8";\xe4'), # read as latin1! + (None, 'ascii', (None, u'@charset "latin1";ä'.encode('utf-8-sig'))): + ('utf-8-sig', 2, u'@charset "utf-8";\xe4'), # read as latin1! + + + # ===== 4. parentEncoding WINS ===== + (None, 'latin1', (None, u''.encode())): ('latin1', 4, u''), + (None, 'latin1', (None, u'123'.encode())): ('latin1', 4, u'123'), + (None, 'latin1', (None, u'ä'.encode('iso-8859-1'))): + ('latin1', 4, u'ä'), + (None, 'latin1', (None, u'a'.encode('ascii'))): + ('latin1', 4, u'a'), + (None, 'latin1', (None, u'ä'.encode('utf-8'))): + ('latin1', 4, u'\xc3\xa4'), # read as latin1! + + # ===== 5. default WINS which in this case is None! ===== + (None, None, (None, u''.encode())): ('utf-8', 5, u''), + (None, None, (None, u'123'.encode())): ('utf-8', 5, u'123'), + (None, None, (None, u'a'.encode('ascii'))): + ('utf-8', 5, u'a'), + (None, None, (None, u'ä'.encode('utf-8'))): + ('utf-8', 5, u'ä'), # read as utf-8 + (None, None, (None, u'ä'.encode('iso-8859-1'))): # trigger UnicodeDecodeError! + ('utf-8', 5, None), + + + } + for (override, parent, r), exp in tests.items(): + self.assertEquals(_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', u'€'.encode('utf-8')): + (None, u'€'.encode('utf-8')), + ('text/css;charset=utf-8', u'€'.encode('utf-8')): + ('utf-8', u'€'.encode('utf-8')), + ('text/css;charset=ascii', 'a'): + ('ascii', 'a') + } + url = 'http://example.com/test.css' + for (contenttype, content), exp in 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': (urllib2.URLError, ['urlerror']), + # cannot resolve x, IOError + 'http://x': (urllib2.URLError, ['ioerror']), + } + for url, (exception, args) in 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': (urllib2.HTTPError, ['u', 500, 'server error', {}, None]), + 'e3': (urllib2.HTTPError, ['u', 404, 'not found', {}, None]), + } + for url, (exception, args) in 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, u'Mock needed for this test') + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_value.py cssutils-0.9.10/src/cssutils/tests/test_value.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_value.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_value.py 2013-03-31 19:17:28.000000000 +0000 @@ -0,0 +1,1086 @@ +"""Testcases for cssutils.css.CSSValue and CSSPrimitiveValue.""" + +# from decimal import Decimal # maybe for later tests? +import xml.dom +import basetest +import cssutils +import types + + +class PropertyValueTestCase(basetest.BaseTestCase): + + def setUp(self): + self.r = cssutils.css.PropertyValue() + + def test_init(self): + "PropertyValue.__init__() .item() .length" + pv = cssutils.css.PropertyValue() + self.assertEqual(u'', pv.cssText) + self.assertEqual(0, pv.length) + self.assertEqual(u'', pv.value) + + cssText = u'0, 0/0 1px var(x) url(x)' + items = [u'0', u'0', u'0', u'1px', u'var(x)', 'url(x)'] + pv = cssutils.css.PropertyValue(cssText) + self.assertEqual(cssText, pv.cssText) + self.assertEqual(6, len(pv)) + self.assertEqual(6, pv.length) + + # __iter__ + for i, x in enumerate(pv): + self.assertEqual(x.cssText, items[i]) + + # cssText + for i, item in enumerate(items): + self.assertEqual(item, pv[i].cssText) + self.assertEqual(item, pv.item(i).cssText) + + def test_cssText(self): + "PropertyValue.cssText" + tests = { + u'0': (None, 1, None), + u'0 0': (None, 2, None), + u'0, 0': (None, 2, None), + u'0,0': (u'0, 0', 2, None), + u'0 , 0': (u'0, 0', 2, None), + u'0/0': (None, 2, None), + u'/**/ 0 /**/': (None, 1, u'0'), + u'0 /**/ 0 /**/ 0': (None, 3, u'0 0 0'), + u'0, /**/ 0, /**/ 0': (None, 3, u'0, 0, 0'), + u'0//**/ 0//**/ 0': (None, 3, u'0/0/0'), + u'/**/ red': (None, 1, u'red'), + u'/**/red': (u'/**/ red', 1, u'red'), + u'red /**/': (None, 1, u'red'), + u'red/**/': (u'red /**/', 1, u'red'), + + u'a()1,-1,+1,1%,-1%,1px,-1px,"a",a,url(a),#aabb44': ( + u'a() 1, -1, +1, 1%, -1%, 1px, -1px, "a", a, url(a), #ab4', + 12, u'a() 1, -1, +1, 1%, -1%, 1px, -1px, "a", a, url(a), #ab4'), + + #issue #24 + u'rgb(0, 10, 255)': (None, 1, u'rgb(0, 10, 255)'), + u'hsl(10, 10%, 25%)': (None, 1, u'hsl(10, 10%, 25%)'), + u'rgba(0, 10, 255, 0.5)': (None, 1, u'rgba(0, 10, 255, 0.5)'), + u'hsla(10, 10%, 25%, 0.5)': (None, 1, u'hsla(10, 10%, 25%, 0.5)'), + + #issue #27 + u'matrix(0.000092, 0.2500010, -0.250000, 0.000092, 0, 0)': ( + u'matrix(0.000092, 0.250001, -0.25, 0.000092, 0, 0)', 1, + u'matrix(0.000092, 0.250001, -0.25, 0.000092, 0, 0)') + } + for (cssText, (c, l, v)) in tests.items(): + if c is None: + c = cssText + if v is None: + v = c + + pv = cssutils.css.PropertyValue(cssText) + self.assertEqual(c, pv.cssText) + self.assertEqual(l, pv.length) + self.assertEqual(v, pv.value) + + tests = { + u'0 0px -0px +0px': (u'0 0 0 0', 4), + u'1 2 3 4': (None, 4), + u'-1 -2 -3 -4': (None, 4), + u'-1 2': (None, 2), + u'-1px red "x"': (None, 3), + u'a, b c': (None, 3), + u'1px1 2% 3': (u'1px1 2% 3', 3), + u'f(+1pX, -2, 5%) 1': (u'f(+1px, -2, 5%) 1', 2), + u'0 f()0': (u'0 f() 0', 3), + u'f()0': (u'f() 0', 2), + u'f()1%': (u'f() 1%', 2), + u'f()1px': (u'f() 1px', 2), + u'f()"str"': (u'f() "str"', 2), + u'f()ident': (u'f() ident', 2), + u'f()#123': (u'f() #123', 2), + u'f()url()': (u'f() url()', 2), + u'f()f()': (u'f() f()', 2), + u'url(x.gif)0 0': (u'url(x.gif) 0 0', 3), + u'url(x.gif)no-repeat': (u'url(x.gif) no-repeat', 2) + } + for (cssText, (c, l)) in tests.items(): + if c is None: + c = cssText + pv = cssutils.css.PropertyValue(cssText) + self.assertEqual(c, pv.cssText) + self.assertEqual(l, pv.length) + + tests = { + # hash and rgb/a + u'#112234': u'#112234', + u'#112233': u'#123', + u'rgb(1,2,3)': u'rgb(1, 2, 3)', + u'rgb( 1 , 2 , 3 )': u'rgb(1, 2, 3)', + u'rgba(1,2,3,4)': u'rgba(1, 2, 3, 4)', + u'rgba( 1 , 2 , 3 , 4 )': u'rgba(1, 2, 3, 4)', + u'rgb(-1,+2,0)': u'rgb(-1, +2, 0)', + u'rgba(-1,+2,0, 0)': u'rgba(-1, +2, 0, 0)', + + # FUNCTION + u'f(1,2)': u'f(1, 2)', + u'f( 1 , 2 )': u'f(1, 2)', + u'f(-1,+2)': u'f(-1, +2)', + u'f( -1 , +2 )': u'f(-1, +2)', + u'fun( -1 , +2 )': u'fun(-1, +2)', + u'local( x )': u'local(x)', + u'test(1px, #111, y, 1, 1%, "1", y(), var(x))': + u'test(1px, #111, y, 1, 1%, "1", y(), var(x))', + u'test(-1px, #111, y, -1, -1%, "1", -y())': + u'test(-1px, #111, y, -1, -1%, "1", -y())', + u'url(y) format( "x" , "y" )': u'url(y) format("x", "y")', + u'f(1 2,3 4)': u'f(1 2, 3 4)', + + # IE expression + ur'Expression()': u'Expression()', + ur'expression(-1 < +2)': u'expression(-1<+2)', + ur'expression(document.width == "1")': u'expression(document.width=="1")', + u'alpha(opacity=80)': u'alpha(opacity=80)', + u'alpha( opacity = 80 , x=2 )': u'alpha(opacity=80, x=2)', + u'expression(eval(document.documentElement.scrollTop))': + u'expression(eval(document.documentElement.scrollTop))', + #TODO +# u'expression((function(ele){ele.style.behavior="none";})(this))': +# u'expression((function(ele){ele.style.behavior="none";})(this))', + + # unicode-range + 'u+f': 'u+f', + 'U+ABCdef': 'u+abcdef', + + # url + 'url(a)': 'url(a)', + 'uRl(a)': 'url(a)', + 'u\\rl(a)': 'url(a)', + 'url("a")': 'url(a)', + 'url( "a" )': 'url(a)', + 'url(a)': 'url(a)', + 'url(";")': 'url(";")', + 'url(",")': 'url(",")', + 'url(")")': 'url(")")', + '''url("'")''': '''url("'")''', + '''url('"')''': '''url("\\"")''', + '''url("'")''': '''url("'")''', + + # operator + '1': '1', + '1 2': '1 2', + '1 2': '1 2', + '1,2': '1, 2', + '1, 2': '1, 2', + '1 ,2': '1, 2', + '1 , 2': '1, 2', + '1/2': '1/2', + '1/ 2': '1/2', + '1 /2': '1/2', + '1 / 2': '1/2', + # comment + '1/**/2': '1 /**/ 2', + '1 /**/2': '1 /**/ 2', + '1/**/ 2': '1 /**/ 2', + '1 /**/ 2': '1 /**/ 2', + '1 /*a*/ /*b*/ 2': '1 /*a*/ /*b*/ 2', + # , before + '1,/**/2': '1, /**/ 2', + '1 ,/**/2': '1, /**/ 2', + '1, /**/2': '1, /**/ 2', + '1 , /**/2': '1, /**/ 2', + # , after + '1/**/,2': '1 /**/, 2', + '1/**/ ,2': '1 /**/, 2', + '1/**/, 2': '1 /**/, 2', + '1/**/ , 2': '1 /**/, 2', + # all + '1/*a*/ ,/*b*/ 2': '1 /*a*/, /*b*/ 2', + '1 /*a*/, /*b*/2': '1 /*a*/, /*b*/ 2', + '1 /*a*/ , /*b*/ 2': '1 /*a*/, /*b*/ 2', + + # list + 'a b1,b2 b2,b3,b4': 'a b1, b2 b2, b3, b4', + 'a b1 , b2 b2 , b3 , b4': 'a b1, b2 b2, b3, b4', + 'u+1 , u+2-5': 'u+1, u+2-5', + u'local( x ), url(y) format( "x" , "y" )': + u'local(x), url(y) format("x", "y")', + # FUNCTION + u'attr( href )': u'attr(href)', + # PrinceXML extende FUNC syntax with nested FUNC + u'target-counter(attr(href),page)': u'target-counter(attr(href), page)' + } + self.do_equal_r(tests) + + tests = { u'a+': xml.dom.SyntaxErr, + u'-': xml.dom.SyntaxErr, + u'+': xml.dom.SyntaxErr, + u'-%': xml.dom.SyntaxErr, + u'+a': xml.dom.SyntaxErr, + u'--1px': xml.dom.SyntaxErr, + u'++1px': xml.dom.SyntaxErr, + u'#': xml.dom.SyntaxErr, + u'#00': xml.dom.SyntaxErr, + u'#12x': xml.dom.SyntaxErr, + u'#xyz': xml.dom.SyntaxErr, + u'#0000': xml.dom.SyntaxErr, + u'#00000': xml.dom.SyntaxErr, + u'#0000000': xml.dom.SyntaxErr, + u'-#0': xml.dom.SyntaxErr, + # operator + u',': xml.dom.SyntaxErr, + u'1,,2': xml.dom.SyntaxErr, + u'1,/**/,2': xml.dom.SyntaxErr, + u'1 , /**/ , 2': xml.dom.SyntaxErr, + u'1,': xml.dom.SyntaxErr, + u'1, ': xml.dom.SyntaxErr, + u'1 ,': xml.dom.SyntaxErr, + u'1 , ': xml.dom.SyntaxErr, + u'1 , ': xml.dom.SyntaxErr, + u'1//2': xml.dom.SyntaxErr, + # URL + u'url(x))': xml.dom.SyntaxErr, + # string + u'"': xml.dom.SyntaxErr, + u"'": xml.dom.SyntaxErr, + # function + u'f(-)': xml.dom.SyntaxErr, + u'f(x))': xml.dom.SyntaxErr + } + self.do_raise_r(tests) + + def test_list(self): + "PropertyValue[index]" + # issue #41 + css = """div.one {color: rgb(255, 0, 0);} """ + sheet = cssutils.parseString(css) + pv = sheet.cssRules[0].style.getProperty('color').propertyValue + self.assertEqual(pv.value, 'rgb(255, 0, 0)') + self.assertEqual(pv[0].value, 'rgb(255, 0, 0)') + + # issue #42 + sheet = cssutils.parseString('body { font-family: "A", b, serif }') + pv = sheet.cssRules[0].style.getProperty('font-family').propertyValue + self.assertEqual(3, pv.length) + self.assertEqual(pv[0].value, 'A') + self.assertEqual(pv[1].value, 'b') + self.assertEqual(pv[2].value, 'serif') + + def test_comments(self): + "PropertyValue with comment" + # issue #45 + for t in (u'green', + u'green /* comment */', + u'/* comment */green', + u'/* comment */green/* comment */', + u'/* comment */ green /* comment */', + u'/* comment *//**/ green /* comment *//**/', + ): + sheet = cssutils.parseString('body {color: %s; }' % t) + p = sheet.cssRules[0].style.getProperties()[0] + self.assertEqual(p.valid, True) + for t in (u'gree', + u'gree /* comment */', + u'/* comment */gree', + u'/* comment */gree/* comment */', + u'/* comment */ gree /* comment */', + u'/* comment *//**/ gree /* comment *//**/', + ): + sheet = cssutils.parseString('body {color: %s; }' % t) + p = sheet.cssRules[0].style.getProperties()[0] + self.assertEqual(p.valid, False) + + def test_incomplete(self): + "PropertyValue (incomplete)" + tests = { + u'url("a': u'url(a)', + u'url(a': u'url(a)' + } + for v, exp in tests.items(): + s = cssutils.parseString('a { background: %s' % v) + v = s.cssRules[0].style.background + self.assertEqual(v, exp) + + def test_readonly(self): + "PropertyValue._readonly" + v = cssutils.css.PropertyValue(cssText='inherit') + self.assert_(False is v._readonly) + + v = cssutils.css.PropertyValue(cssText='inherit', readonly=True) + self.assert_(True is v._readonly) + self.assert_(u'inherit', v.cssText) + self.assertRaises(xml.dom.NoModificationAllowedErr, v._setCssText, u'x') + self.assert_(u'inherit', v.cssText) + + def test_reprANDstr(self): + "PropertyValue.__repr__(), .__str__()" + cssText='inherit' + + s = cssutils.css.PropertyValue(cssText=cssText) + + self.assert_(cssText in str(s)) + + s2 = eval(repr(s)) + self.assert_(isinstance(s2, s.__class__)) + self.assert_(cssText == s2.cssText) + + +class ValueTestCase(basetest.BaseTestCase): + + def test_init(self): + "Value.__init__()" + v = cssutils.css.Value() + self.assert_(u'' == v.cssText) + self.assert_(u'' == v.value) + self.assert_(None is v.type) + + def test_cssText(self): + "Value.cssText" + # HASH IDENT STRING UNICODE-RANGE + tests = { + u'#123': (u'#123', u'#123', u'HASH'), + u'#123456': (u'#123456', u'#123456', u'HASH'), + u'#112233': (u'#123', u'#112233', u'HASH'), + u' #112233 ': (u'#123', u'#112233', u'HASH'), + + u'red': (u'red', u'red', u'IDENT'), + u' red ': (u'red', u'red', u'IDENT'), + u'red ': (u'red', u'red', u'IDENT'), + u' red': (u'red', u'red', u'IDENT'), + u'red-': (u'red-', u'red-', u'IDENT'), + u'-red': (u'-red', u'-red', u'IDENT'), + + u'"red"': (u'"red"', u'red', u'STRING'), + u"'red'": (u'"red"', u'red', u'STRING'), + u' "red" ': (u'"red"', u'red', u'STRING'), + ur'"red\""': (ur'"red\""', ur'red"', u'STRING'), + ur"'x\"'": (ur'"x\\""', ur'x\"', 'STRING'), #??? + u'''"x\ +y"''': (u'"xy"', u'xy', u'STRING'), + } + for (p, (r, n, t)) in tests.items(): + v = cssutils.css.Value(p) + self.assertEqual(r, v.cssText) + self.assertEqual(t, v.type) + self.assertEqual(n, v.value) + + +class ColorValueTestCase(basetest.BaseTestCase): + + def test_init(self): + "ColorValue.__init__()" + v = cssutils.css.ColorValue() + self.assertEqual(v.COLOR_VALUE, v.type) + self.assert_(u'' == v.cssText) + self.assert_(u'' == v.value) + self.assertEqual(u'transparent', v.name) + self.assertEqual(None, v.colorType) + + def test_cssText(self): + "ColorValue.cssText" + tests = { + # HASH + u'#123': (u'#123',), + u'#112233': (u'#123',), + # rgb + u'rgb(1,2,3)': (u'rgb(1, 2, 3)',), + u'rgb(1%,2%,3%)': (u'rgb(1%, 2%, 3%)',), + u'rgb(-1,-1,-1)': (u'rgb(-1, -1, -1)',), + u'rgb(-1%,-2%,-3%)': (u'rgb(-1%, -2%, -3%)',), + # rgba + u'rgba(1,2,3, 0)': (u'rgba(1, 2, 3, 0)',), + # hsl + u'hsl(1,2%,3%)': (u'hsl(1, 2%, 3%)',), + u'hsla(1,2%,3%, 1.0)': (u'hsla(1, 2%, 3%, 1)',), + + } + for (p, (r, )) in tests.items(): + v = cssutils.css.ColorValue(p) + self.assertEqual(v.COLOR_VALUE, v.type) + self.assertEqual(r, v.cssText) + self.assertEqual(r, v.value) + + v = cssutils.css.ColorValue() + v.cssText = p + self.assertEqual(v.COLOR_VALUE, v.type) + self.assertEqual(r, v.cssText) + self.assertEqual(r, v.value) + + tests = { + u'1': xml.dom.SyntaxErr, + u'a': xml.dom.SyntaxErr, + + u'#12': xml.dom.SyntaxErr, + u'#1234': xml.dom.SyntaxErr, + u'#1234567': xml.dom.SyntaxErr, + u'#12345678': xml.dom.SyntaxErr, + + u'rgb(1,1%,1%)': xml.dom.SyntaxErr, + u'rgb(1%,1,1)': xml.dom.SyntaxErr, + u'rgb(-1,-1%,-1%)': xml.dom.SyntaxErr, + u'rgb(-1%,-1,-1)': xml.dom.SyntaxErr, + + u'rgb(1,1,1, 0)': xml.dom.SyntaxErr, + u'rgb(1%,1%,1%, 0)': xml.dom.SyntaxErr, + u'rgba(1,1,1)': xml.dom.SyntaxErr, + u'rgba(1%,1%,1%)': xml.dom.SyntaxErr, + u'rgba(1,1,1, 0%)': xml.dom.SyntaxErr, + u'rgba(1%,1%,1%, 0%)': xml.dom.SyntaxErr, + + u'hsl(1,2%,3%, 1)': xml.dom.SyntaxErr, + u'hsla(1,2%,3%)': xml.dom.SyntaxErr, + + u'hsl(1,2,3)': xml.dom.SyntaxErr, + u'hsl(1%,2,3)': xml.dom.SyntaxErr, + u'hsl(1%,2,3%)': xml.dom.SyntaxErr, + u'hsl(1%,2%,3)': xml.dom.SyntaxErr, + + u'hsla(1,2%,3%, 0%)': xml.dom.SyntaxErr, + u'hsla(1,2,3, 0.0)': xml.dom.SyntaxErr, + u'hsla(1%,2,3, 0.0)': xml.dom.SyntaxErr, + u'hsla(1%,2,3%, 0.0)': xml.dom.SyntaxErr, + u'hsla(1%,2%,3, 0.0)': xml.dom.SyntaxErr, + } + self.r = cssutils.css.ColorValue() + self.do_raise_r(tests) + + def test_rgb(self): + "ColorValue.red .green .blue" + tests = { + (u'#0A0AD2', 'rgb(10, 10, 210)' ): (10, 10, 210, 1.0), + # TODO: Fix rounding? + (u'hsl(240, 91%, 43%)', ): (10, 10, 209, 1.0), + (u'#ff8800', u'#f80', + 'rgb(255, 136, 0)', 'rgba(255, 136, 0, 1.0)'): (255, 136, 0, 1.0), + (u'red', u'#ff0000', u'#f00', + u'hsl(0, 100%, 50%)', u'hsla(0, 100%, 50%, 1.0)'): + (255, 0, 0, 1.0), + (u'lime', u'#00ff00', u'#0f0', u'hsl(120, 100%, 50%)'): + (0, 255, 0, 1.0), + (u'rgba(255, 127, 0, .1)', u'rgba(100%, 50%, 0%, .1)'): + (255, 127, 0, 0.1), + (u'transparent', u'rgba(0, 0, 0, 0)'): (0, 0, 0, 0), + (u'aqua',): (0, 255, 255, 1.0) + } + for colors, rgba in tests.items(): + for color in colors: + c = cssutils.css.ColorValue(color); + self.assertEquals(c.red, rgba[0]) + self.assertEquals(c.green, rgba[1]) + self.assertEquals(c.blue, rgba[2]) + self.assertEquals(c.alpha, rgba[3]) + + +class URIValueTestCase(basetest.BaseTestCase): + + def test_init(self): + "URIValue.__init__()" + v = cssutils.css.URIValue() + self.assert_(u'url()' == v.cssText) + self.assert_(u'' == v.value) + self.assert_(u'' == v.uri) + self.assert_(v.URI is v.type) + + v.uri = '1' + self.assert_(u'1' == v.value) + self.assert_(u'1' == v.uri) + self.assertEqual(u'url(1)', v.cssText) + + v.value = '2' + self.assert_(u'2' == v.value) + self.assert_(u'2' == v.uri) + self.assertEqual(u'url(2)', v.cssText) + + def test_absoluteUri(self): + "URIValue.absoluteUri" + s = cssutils.parseString('a { background-image: url(x.gif)}', href="/path/to/x.css") + v = s.cssRules[0].style.getProperty('background-image').propertyValue[0] + self.assertEqual(u'x.gif', v.uri) + self.assertEqual(u'/path/to/x.gif', v.absoluteUri) + + v = cssutils.css.URIValue(u'url(x.gif)') + self.assertEqual(u'x.gif', v.uri) + self.assertEqual(u'x.gif', v.absoluteUri) + + def test_cssText(self): + "URIValue.cssText" + tests = { + u'url()': (u'url()', u'', u'URI'), + # comments are part of the url! + u'url(/**/)': (u'url(/**/)', u'/**/', u'URI'), + u'url(/**/1)': (u'url(/**/1)', u'/**/1', u'URI'), + u'url(1/**/)': (u'url(1/**/)', u'1/**/', u'URI'), + u'url(/**/1/**/)': (u'url(/**/1/**/)', u'/**/1/**/', u'URI'), + u'url(some.gif)': (u'url(some.gif)', u'some.gif', u'URI'), + u' url(some.gif) ': (u'url(some.gif)', u'some.gif', u'URI'), + u'url( some.gif )': (u'url(some.gif)', u'some.gif', u'URI'), + } + for (p, (r, n, t)) in tests.items(): + v = cssutils.css.URIValue(p) + self.assertEqual(r, v.cssText) + self.assertEqual(t, v.type) + self.assertEqual(n, v.value) + self.assertEqual(n, v.uri) + + v = cssutils.css.URIValue() + v.cssText = p + self.assertEqual(r, v.cssText) + self.assertEqual(t, v.type) + self.assertEqual(n, v.value) + self.assertEqual(n, v.uri) + + tests = { + u'a()': xml.dom.SyntaxErr, + u'1': xml.dom.SyntaxErr, + u'url(': xml.dom.SyntaxErr, + u'url("': xml.dom.SyntaxErr, + u'url(\'': xml.dom.SyntaxErr, + } + self.r = cssutils.css.URIValue() + self.do_raise_r(tests) + +class DimensionValueTestCase(basetest.BaseTestCase): + + def test_init(self): + "DimensionValue.__init__()" + v = cssutils.css.DimensionValue() + self.assert_(u'' == v.cssText) + self.assert_(u'' == v.value) + self.assert_(None is v.type) + self.assert_(None is v.dimension) + + def test_cssText(self): + "DimensionValue.cssText" + # NUMBER DIMENSION PERCENTAGE + tests = { + + u'0': (u'0', 0, None, u'NUMBER'), + u'00': (u'0', 0, None, u'NUMBER'), + u'.0': (u'0', 0, None, u'NUMBER'), + u'0.0': (u'0', 0, None, u'NUMBER'), + u'+0': (u'0', 0, None, u'NUMBER'), + u'+00': (u'0', 0, None, u'NUMBER'), + u'+.0': (u'0', 0, None, u'NUMBER'), + u'+0.0': (u'0', 0, None, u'NUMBER'), + u'-0': (u'0', 0, None, u'NUMBER'), + u'-00': (u'0', 0, None, u'NUMBER'), + u'-.0': (u'0', 0, None, u'NUMBER'), + u'-0.0': (u'0', 0, None, u'NUMBER'), + + u'1': (u'1', 1, None, u'NUMBER'), + u'1.0': (u'1', 1.0, None, u'NUMBER'), + u'1.1': (u'1.1', 1.1, None, u'NUMBER'), + u'+1': (u'+1', 1, None, u'NUMBER'), + u'+1.0': (u'+1', 1.0, None, u'NUMBER'), + u'+1.1': (u'+1.1', 1.1, None, u'NUMBER'), + u'-1': (u'-1', -1, None, u'NUMBER'), + u'-1.0': (u'-1', -1, None, u'NUMBER'), + u'-1.1': (u'-1.1', -1.1, None, u'NUMBER'), + + u'0px': (u'0', 0, u'px', u'DIMENSION'), + u'1px': (u'1px', 1, u'px', u'DIMENSION'), + u'1.0px': (u'1px', 1.0, u'px', u'DIMENSION'), + u'1.1px': (u'1.1px', 1.1, u'px', u'DIMENSION'), + u'-1px': (u'-1px', -1, u'px', u'DIMENSION'), + u'-1.1px': (u'-1.1px', -1.1, u'px', u'DIMENSION'), + u'+1px': (u'+1px', 1, u'px', u'DIMENSION'), + + u'1px1': (u'1px1', 1, u'px1', u'DIMENSION'), + + u'0%': (u'0%', 0, u'%', u'PERCENTAGE'), + u'1%': (u'1%', 1, u'%', u'PERCENTAGE'), + u'1.1%': (u'1.1%', 1.1, u'%', u'PERCENTAGE'), + u'-1%': (u'-1%', -1, u'%', u'PERCENTAGE'), + u'-1.1%': (u'-1.1%', -1.1, u'%', u'PERCENTAGE'), + u'+1%': (u'+1%', 1, u'%', u'PERCENTAGE'), + } + for (p, (r, n, d, t)) in tests.items(): + v = cssutils.css.DimensionValue(p) + self.assertEqual(r, v.cssText) + self.assertEqual(t, v.type) + self.assertEqual(n, v.value) + self.assertEqual(d, v.dimension) + + +class CSSFunctionTestCase(basetest.BaseTestCase): + + def test_init(self): + "CSSFunction.__init__()" + v = cssutils.css.CSSFunction() + self.assertEqual(u'', v.cssText) + self.assertEqual(u'FUNCTION', v.type) + self.assertEqual(v.value, u'') + + def test_cssText(self): + "CSSFunction.cssText" + tests = { + u'x(x)': (u'x(x)', None), + u'X( X )': (u'x(X)', None), + u'x(1,2)': (u'x(1, 2)', None), + u'x(1/**/)': (u'x(1 /**/)', u'x(1)'), + u'x(/**/1)': (u'x(/**/ 1)', u'x(1)'), + u'x(/**/1/**/)': (u'x(/**/ 1 /**/)', u'x(1)'), + u'x(/**/1,x/**/)': (u'x(/**/ 1, x /**/)', u'x(1, x)'), + u'x(1,2)': (u'x(1, 2)', None), + } + for (f, (cssText, value)) in tests.items(): + if value is None: + value = cssText + v = cssutils.css.CSSFunction(f) + self.assertEqual(cssText, v.cssText) + self.assertEqual('FUNCTION', v.type) + self.assertEqual(value, v.value) + + +class CSSVariableTestCase(basetest.BaseTestCase): + + def test_init(self): + "CSSVariable.__init__()" + v = cssutils.css.CSSVariable() + self.assertEqual(u'', v.cssText) + self.assertEqual(u'VARIABLE', v.type) + self.assert_(None is v.name) + self.assert_(None is v.value) + + def test_cssText(self): + "CSSVariable.cssText" + tests = { + u'var(x)': (u'var(x)', 'x'), + u'VAR( X )': (u'var(X)', 'X') + } + for (var, (cssText, name)) in tests.items(): + v = cssutils.css.CSSVariable(var) + self.assertEqual(cssText, v.cssText) + self.assertEqual('VARIABLE', v.type) + self.assertEqual(name, v.name) + # not resolved so it is None + self.assertEqual(None, v.value) + + + +# def test_cssValueType(self): +# "CSSValue.cssValueType .cssValueTypeString" +# tests = [ +# ([u'inherit', u'INhe\\rit'], 'CSS_INHERIT', cssutils.css.CSSValue), +# (['1', '1%', '1em', '1ex', '1px', '1cm', '1mm', '1in', '1pt', '1pc', +# '1deg', '1rad', '1grad', '1ms', '1s', '1hz', '1khz', '1other', +# '"string"', "'string'", 'url(x)', 'red', +# 'attr(a)', 'counter(x)', 'rect(1px, 2px, 3px, 4px)', +# 'rgb(0, 0, 0)', '#000', '#123456', 'rgba(0, 0, 0, 0)', +# 'hsl(0, 0, 0)', 'hsla(0, 0, 0, 0)', +# ], +# 'CSS_PRIMITIVE_VALUE', cssutils.css.CSSPrimitiveValue), +# ([u'1px 1px', 'red blue green x'], 'CSS_VALUE_LIST', cssutils.css.CSSValueList), +# # what is a custom value? +# #([], 'CSS_CUSTOM', cssutils.css.CSSValue) +# ] +# for values, name, cls in tests: +# for value in values: +# v = cssutils.css.CSSValue(cssText=value) +# if value == "'string'": +# # will be changed to " always +# value = '"string"' +# self.assertEqual(value, v.cssText) +# self.assertEqual(name, v.cssValueTypeString) +# self.assertEqual(getattr(v, name), v.cssValueType) +# self.assertEqual(cls, type(v)) + + +#class CSSPrimitiveValueTestCase(basetest.BaseTestCase): +# +# def test_init(self): +# "CSSPrimitiveValue.__init__()" +# v = cssutils.css.CSSPrimitiveValue(u'1') +# self.assert_(u'1' == v.cssText) +# +# self.assert_(v.CSS_PRIMITIVE_VALUE == v.cssValueType) +# self.assert_("CSS_PRIMITIVE_VALUE" == v.cssValueTypeString) +# +# self.assert_(v.CSS_NUMBER == v.primitiveType) +# self.assert_("CSS_NUMBER" == v.primitiveTypeString) +# +# # DUMMY to be able to test empty constructor call +# #self.assertRaises(xml.dom.SyntaxErr, v.__init__, None) +# +# self.assertRaises(xml.dom.InvalidAccessErr, v.getCounterValue) +# self.assertRaises(xml.dom.InvalidAccessErr, v.getRGBColorValue) +# self.assertRaises(xml.dom.InvalidAccessErr, v.getRectValue) +# self.assertRaises(xml.dom.InvalidAccessErr, v.getStringValue) +# +# def test_CSS_UNKNOWN(self): +# "CSSPrimitiveValue.CSS_UNKNOWN" +# v = cssutils.css.CSSPrimitiveValue(u'expression(false)') +# self.assert_(v.CSS_UNKNOWN == v.primitiveType) +# self.assert_('CSS_UNKNOWN' == v.primitiveTypeString) +# +# def test_CSS_NUMBER_AND_OTHER_DIMENSIONS(self): +# "CSSPrimitiveValue.CSS_NUMBER .. CSS_DIMENSION" +# defs = [ +# ('', 'CSS_NUMBER'), +# ('%', 'CSS_PERCENTAGE'), +# ('em', 'CSS_EMS'), +# ('ex', 'CSS_EXS'), +# ('px', 'CSS_PX'), +# ('cm', 'CSS_CM'), +# ('mm', 'CSS_MM'), +# ('in', 'CSS_IN'), +# ('pt', 'CSS_PT'), +# ('pc', 'CSS_PC'), +# ('deg', 'CSS_DEG'), +# ('rad', 'CSS_RAD'), +# ('grad', 'CSS_GRAD'), +# ('ms', 'CSS_MS'), +# ('s', 'CSS_S'), +# ('hz', 'CSS_HZ'), +# ('khz', 'CSS_KHZ'), +# ('other_dimension', 'CSS_DIMENSION') +# ] +# for dim, name in defs: +# for n in (0, 1, 1.1, -1, -1.1, -0): +# v = cssutils.css.CSSPrimitiveValue('%i%s' % (n, dim)) +# self.assertEqual(name, v.primitiveTypeString) +# self.assertEqual(getattr(v, name), v.primitiveType) +# +# def test_CSS_STRING_AND_OTHER(self): +# "CSSPrimitiveValue.CSS_STRING .. CSS_RGBCOLOR" +# defs = [ +# (('""', "''", '"some thing"', "' A\\ND '", +# # comma separated lists are STRINGS FOR NOW! +# 'a, b', +# '"a", "b"', +# ), 'CSS_STRING'), +# (('url(a)', 'url("a b")', "url(' ')"), 'CSS_URI'), +# (('some', 'or_anth-er'), 'CSS_IDENT'), +# (('attr(a)', 'attr(b)'), 'CSS_ATTR'), +# (('counter(1)', 'counter(2)'), 'CSS_COUNTER'), +# (('rect(1,2,3,4)',), 'CSS_RECT'), +# (('rgb(1,2,3)', 'rgb(10%, 20%, 30%)', '#123', '#123456'), +# 'CSS_RGBCOLOR'), +# (('rgba(1,2,3,4)','rgba(10%, 20%, 30%, 40%)', ), +# 'CSS_RGBACOLOR'), +# (('U+0', 'u+ffffff', 'u+000000-f', +# 'u+0-f, U+ee-ff'), 'CSS_UNICODE_RANGE') +# ] +# +# for examples, name in defs: +# for x in examples: +# v = cssutils.css.CSSPrimitiveValue(x) +# self.assertEqual(getattr(v, name), v.primitiveType) +# self.assertEqual(name, v.primitiveTypeString) +# +# def test_getFloat(self): +# "CSSPrimitiveValue.getFloatValue()" +# # NOT TESTED are float values as it seems difficult to +# # compare these. Maybe use decimal.Decimal? +# +# v = cssutils.css.CSSPrimitiveValue(u'1px') +# tests = { +# '0': (v.CSS_NUMBER, 0), +# '-1.1': (v.CSS_NUMBER, -1.1), +# '1%': (v.CSS_PERCENTAGE, 1), +# '-1%': (v.CSS_PERCENTAGE, -1), +# '1em': (v.CSS_EMS, 1), +# '-1.1em': (v.CSS_EMS, -1.1), +# '1ex': (v.CSS_EXS, 1), +# '1px': (v.CSS_PX, 1), +# +# '1cm': (v.CSS_CM, 1), +# '1cm': (v.CSS_MM, 10), +# '254cm': (v.CSS_IN, 100), +# '1mm': (v.CSS_MM, 1), +# '10mm': (v.CSS_CM, 1), +# '254mm': (v.CSS_IN, 10), +# '1in': (v.CSS_IN, 1), +# '100in': (v.CSS_CM, 254), # ROUNDED!!! +# '10in': (v.CSS_MM, 254), # ROUNDED!!! +# +# '1pt': (v.CSS_PT, 1), +# '1pc': (v.CSS_PC, 1), +# +# '1deg': (v.CSS_DEG, 1), +# '1rad': (v.CSS_RAD, 1), +# '1grad': (v.CSS_GRAD, 1), +# +# '1ms': (v.CSS_MS, 1), +# '1000ms': (v.CSS_S, 1), +# '1s': (v.CSS_S, 1), +# '1s': (v.CSS_MS, 1000), +# +# '1hz': (v.CSS_HZ, 1), +# '1000hz': (v.CSS_KHZ, 1), +# '1khz': (v.CSS_KHZ, 1), +# '1khz': (v.CSS_HZ, 1000), +# +# '1DIMENSION': (v.CSS_DIMENSION, 1), +# } +# for cssText in tests: +# v.cssText = cssText +# unitType, exp = tests[cssText] +# val = v.getFloatValue(unitType) +# if unitType in (v.CSS_IN, v.CSS_CM): +# val = round(val) +# self.assertEqual(val , exp) +# +# def test_setFloat(self): +# "CSSPrimitiveValue.setFloatValue()" +# V = cssutils.css.CSSPrimitiveValue +# +# tests = { +# # unitType, value +# (V.CSS_NUMBER, 1): [ +# # unitType, setvalue, +# # getvalue or expected exception, msg or cssText +# (V.CSS_NUMBER, 0, 0, '0'), +# (V.CSS_NUMBER, 0.1, 0.1, '0.1'), +# (V.CSS_NUMBER, -0, 0, '0'), +# (V.CSS_NUMBER, 2, 2, '2'), +# (V.CSS_NUMBER, 2.0, 2, '2'), +# (V.CSS_NUMBER, 2.1, 2.1, '2.1'), +# (V.CSS_NUMBER, -2.1, -2.1, '-2.1'), +# # setting with string does work +# (V.CSS_NUMBER, '1', 1, '1'), +# (V.CSS_NUMBER, '1.1', 1.1, '1.1'), +# (V.CSS_PX, 1, xml.dom.InvalidAccessErr, None), +# (V.CSS_DEG, 1, xml.dom.InvalidAccessErr, None), +# (V.CSS_RAD, 1, xml.dom.InvalidAccessErr, None), +# (V.CSS_GRAD, 1, xml.dom.InvalidAccessErr, None), +# (V.CSS_S, 1, xml.dom.InvalidAccessErr, None), +# (V.CSS_MS, 1, xml.dom.InvalidAccessErr, None), +# (V.CSS_KHZ, 1, xml.dom.InvalidAccessErr, None), +# (V.CSS_HZ, 1, xml.dom.InvalidAccessErr, None), +# (V.CSS_DIMENSION, 1, xml.dom.InvalidAccessErr, None), +# (V.CSS_MM, 2, xml.dom.InvalidAccessErr, None), +# +# (V.CSS_NUMBER, 'x', xml.dom.InvalidAccessErr, +# "CSSPrimitiveValue: floatValue 'x' is not a float"), +# (V.CSS_NUMBER, '1x', xml.dom.InvalidAccessErr, +# "CSSPrimitiveValue: floatValue '1x' is not a float"), +# +# (V.CSS_STRING, 'x', xml.dom.InvalidAccessErr, +# "CSSPrimitiveValue: unitType 'CSS_STRING' is not a float type"), +# (V.CSS_URI, 'x', xml.dom.InvalidAccessErr, +# "CSSPrimitiveValue: unitType 'CSS_URI' is not a float type"), +# (V.CSS_ATTR, 'x', xml.dom.InvalidAccessErr, +# "CSSPrimitiveValue: unitType 'CSS_ATTR' is not a float type"), +# (V.CSS_IDENT, 'x', xml.dom.InvalidAccessErr, +# "CSSPrimitiveValue: unitType 'CSS_IDENT' is not a float type"), +# (V.CSS_RGBCOLOR, 'x', xml.dom.InvalidAccessErr, +# "CSSPrimitiveValue: unitType 'CSS_RGBCOLOR' is not a float type"), +# (V.CSS_RGBACOLOR, 'x', xml.dom.InvalidAccessErr, +# "CSSPrimitiveValue: unitType 'CSS_RGBACOLOR' is not a float type"), +# (V.CSS_RECT, 'x', xml.dom.InvalidAccessErr, +# "CSSPrimitiveValue: unitType 'CSS_RECT' is not a float type"), +# (V.CSS_COUNTER, 'x', xml.dom.InvalidAccessErr, +# "CSSPrimitiveValue: unitType 'CSS_COUNTER' is not a float type"), +# (V.CSS_EMS, 1, xml.dom.InvalidAccessErr, +# "CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_NUMBER' to 'CSS_EMS'"), +# (V.CSS_EXS, 1, xml.dom.InvalidAccessErr, +# "CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_NUMBER' to 'CSS_EXS'") +# ], +# (V.CSS_MM, '1mm'): [ +# (V.CSS_MM, 2, 2, '2mm'), +# (V.CSS_MM, 0, 0, '0mm'), +# (V.CSS_MM, 0.1, 0.1, '0.1mm'), +# (V.CSS_MM, -0, -0, '0mm'), +# (V.CSS_MM, 3.0, 3, '3mm'), +# (V.CSS_MM, 3.1, 3.1, '3.1mm'), +# (V.CSS_MM, -3.1, -3.1, '-3.1mm'), +# (V.CSS_CM, 1, 10, '10mm'), +# (V.CSS_IN, 10, 254, '254mm'), +# (V.CSS_PT, 1, 1828.8, '1828.8mm'), +# (V.CSS_PX, 1, xml.dom.InvalidAccessErr, None), +# (V.CSS_NUMBER, 2, xml.dom.InvalidAccessErr, None) +# ], +# (V.CSS_PT, '1pt'): [ +# (V.CSS_PT, 2, 2, '2pt'), +# (V.CSS_PC, 12, 1, '1pt'), +# (V.CSS_NUMBER, 1, xml.dom.InvalidAccessErr, None), +# (V.CSS_DEG, 1, xml.dom.InvalidAccessErr, None), +# (V.CSS_PX, 1, xml.dom.InvalidAccessErr, None) +# ], +# (V.CSS_KHZ, '1khz'): [ +# (V.CSS_HZ, 2000, 2, '2khz'), +# (V.CSS_NUMBER, 1, xml.dom.InvalidAccessErr, None), +# (V.CSS_DEG, 1, xml.dom.InvalidAccessErr, None), +# (V.CSS_PX, 1, xml.dom.InvalidAccessErr, None) +# ] +# } +# for test in tests: +# initialType, initialValue = test +# pv = cssutils.css.CSSPrimitiveValue(initialValue) +# for setType, setValue, exp, cssText in tests[test]: +# if type(exp) == types.TypeType or\ +# type(exp) == types.ClassType: # 2.4 compatibility +# if cssText: +# self.assertRaisesMsg( +# exp, cssText, pv.setFloatValue, setType, setValue) +# else: +# self.assertRaises( +# exp, pv.setFloatValue, setType, setValue) +# else: +# pv.setFloatValue(setType, setValue) +# self.assertEqual(pv._value[0], cssText) +# if cssText == '0mm': +# cssText = '0' +# self.assertEqual(pv.cssText, cssText) +# self.assertEqual(pv.getFloatValue(initialType), exp) +# +# def test_getString(self): +# "CSSPrimitiveValue.getStringValue()" +# v = cssutils.css.CSSPrimitiveValue(u'1px') +# self.assert_(v.primitiveType == v.CSS_PX) +# self.assertRaises(xml.dom.InvalidAccessErr, +# v.getStringValue) +# +# pv = cssutils.css.CSSPrimitiveValue +# tests = { +# pv.CSS_STRING: ("'red'", 'red'), +# pv.CSS_STRING: ('"red"', 'red'), +# pv.CSS_URI: ('url(http://example.com)', None), +# pv.CSS_URI: ("url('http://example.com')", +# u"http://example.com"), +# pv.CSS_URI: ('url("http://example.com")', +# u'http://example.com'), +# pv.CSS_URI: ('url("http://example.com?)")', +# u'http://example.com?)'), +# pv.CSS_IDENT: ('red', None), +# pv.CSS_ATTR: ('attr(att-name)', +# u'att-name'), # the name of the attrr +# } +# for t in tests: +# val, exp = tests[t] +# if not exp: +# exp = val +# +# v = cssutils.css.CSSPrimitiveValue(val) +# self.assertEqual(v.primitiveType, t) +# self.assertEqual(v.getStringValue(), exp) +# +# def test_setString(self): +# "CSSPrimitiveValue.setStringValue()" +# # CSS_STRING +# v = cssutils.css.CSSPrimitiveValue(u'"a"') +# self.assert_(v.CSS_STRING == v.primitiveType) +# v.setStringValue(v.CSS_STRING, 'b') +# self.assert_(('b', 'STRING') == v._value) +# self.assertEqual('b', v.getStringValue()) +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_STRING' to 'CSS_URI'", +# v.setStringValue, *(v.CSS_URI, 'x')) +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_STRING' to 'CSS_IDENT'", +# v.setStringValue, *(v.CSS_IDENT, 'x')) +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_STRING' to 'CSS_ATTR'", +# v.setStringValue, *(v.CSS_ATTR, 'x')) +# +# # CSS_IDENT +# v = cssutils.css.CSSPrimitiveValue('new') +# v.setStringValue(v.CSS_IDENT, 'ident') +# self.assert_(v.CSS_IDENT == v.primitiveType) +# self.assert_(('ident', 'IDENT') == v._value) +# self.assert_('ident' == v.getStringValue()) +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_IDENT' to 'CSS_URI'", +# v.setStringValue, *(v.CSS_URI, 'x')) +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_IDENT' to 'CSS_STRING'", +# v.setStringValue, *(v.CSS_STRING, '"x"')) +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_IDENT' to 'CSS_ATTR'", +# v.setStringValue, *(v.CSS_ATTR, 'x')) +# +# # CSS_URI +# v = cssutils.css.CSSPrimitiveValue('url(old)') +# v.setStringValue(v.CSS_URI, '(') +# self.assertEqual((u'(', 'URI'), v._value) +# self.assertEqual(u'(', v.getStringValue()) +# +# v.setStringValue(v.CSS_URI, ')') +# self.assertEqual((u')', 'URI'), v._value) +# self.assertEqual(u')', v.getStringValue()) +# +# v.setStringValue(v.CSS_URI, '"') +# self.assertEqual(ur'"', v.getStringValue()) +# self.assertEqual((ur'"', 'URI'), v._value) +# +# v.setStringValue(v.CSS_URI, "''") +# self.assertEqual(ur"''", v.getStringValue()) +# self.assertEqual((ur"''", 'URI'), v._value) +# +# v.setStringValue(v.CSS_URI, ',') +# self.assertEqual(ur',', v.getStringValue()) +# self.assertEqual((ur',', 'URI'), v._value) +# +# v.setStringValue(v.CSS_URI, ' ') +# self.assertEqual((u' ', 'URI'), v._value) +# self.assertEqual(u' ', v.getStringValue()) +# +# v.setStringValue(v.CSS_URI, 'a)') +# self.assertEqual((u'a)', 'URI'), v._value) +# self.assertEqual(u'a)', v.getStringValue()) +# +# v.setStringValue(v.CSS_URI, 'a') +# self.assert_(v.CSS_URI == v.primitiveType) +# self.assertEqual((u'a', 'URI'), v._value) +# self.assertEqual(u'a', v.getStringValue()) +# +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_URI' to 'CSS_IDENT'", +# v.setStringValue, *(v.CSS_IDENT, 'x')) +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_URI' to 'CSS_STRING'", +# v.setStringValue, *(v.CSS_STRING, '"x"')) +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_URI' to 'CSS_ATTR'", +# v.setStringValue, *(v.CSS_ATTR, 'x')) +# +# # CSS_ATTR +# v = cssutils.css.CSSPrimitiveValue('attr(old)') +# v.setStringValue(v.CSS_ATTR, 'a') +# self.assert_(v.CSS_ATTR == v.primitiveType) +# self.assert_('a' == v.getStringValue()) +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_ATTR' to 'CSS_IDENT'", +# v.setStringValue, *(v.CSS_IDENT, 'x')) +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_ATTR' to 'CSS_STRING'", +# v.setStringValue, *(v.CSS_STRING, '"x"')) +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_ATTR' to 'CSS_URI'", +# v.setStringValue, *(v.CSS_URI, 'x')) +# +# # TypeError as 'x' is no valid type +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: stringType 'x' (UNKNOWN TYPE) is not a string type", +# v.setStringValue, *('x', 'brown')) +# # IndexError as 111 is no valid type +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: stringType 111 (UNKNOWN TYPE) is not a string type", +# v.setStringValue, *(111, 'brown')) +# # CSS_PX is no string type +# self.assertRaisesMsg(xml.dom.InvalidAccessErr, +# u"CSSPrimitiveValue: stringType CSS_PX is not a string type", +# v.setStringValue, *(v.CSS_PX, 'brown')) +# +# def test_typeRGBColor(self): +# "RGBColor" +# v = cssutils.css.CSSPrimitiveValue('RGB(1, 5, 10)') +# self.assertEqual(v.CSS_RGBCOLOR, v.primitiveType) +# self.assertEqual(u'rgb(1, 5, 10)', v.cssText) +# +# v = cssutils.css.CSSPrimitiveValue('rgb(1, 5, 10)') +# self.assertEqual(v.CSS_RGBCOLOR, v.primitiveType) +# self.assertEqual(u'rgb(1, 5, 10)', v.cssText) +# +# v = cssutils.css.CSSPrimitiveValue('rgb(1%, 5%, 10%)') +# self.assertEqual(v.CSS_RGBCOLOR, v.primitiveType) +# self.assertEqual(u'rgb(1%, 5%, 10%)', v.cssText) +# +# v = cssutils.css.CSSPrimitiveValue(' rgb( 1 ,5, 10 )') +# self.assertEqual(v.CSS_RGBCOLOR, v.primitiveType) +# v = cssutils.css.CSSPrimitiveValue('rgb(1,5,10)') +# self.assertEqual(v.CSS_RGBCOLOR, v.primitiveType) +# v = cssutils.css.CSSPrimitiveValue('rgb(1%, .5%, 10.1%)') +# self.assertEqual(v.CSS_RGBCOLOR, v.primitiveType) + + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils/tests/test_x.py cssutils-0.9.10/src/cssutils/tests/test_x.py --- cssutils-0.9.10~b1/src/cssutils/tests/test_x.py 1970-01-01 00:00:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils/tests/test_x.py 2013-03-31 15:42:26.000000000 +0000 @@ -0,0 +1,54 @@ +"""Testcases for cssutils.css.CSSValue and CSSPrimitiveValue.""" +__version__ = '$Id: test_cssvalue.py 1473 2008-09-15 21:15:54Z cthedot $' + +# from decimal import Decimal # maybe for later tests? +import xml.dom +import basetest +import cssutils +import types + +class XTestCase(basetest.BaseTestCase): + + def setUp(self): + cssutils.ser.prefs.useDefaults() + + def tearDown(self): + cssutils.ser.prefs.useDefaults() + + def test_prioriy(self): + "Property.priority" + s = cssutils.parseString(u'a { color: red }') + self.assertEqual(s.cssText, u'a {\n color: red\n }'.encode()) +# self.assertEqual(u'', s.cssRules[0].style.getPropertyPriority('color')) +# +# s = cssutils.parseString('a { color: red !important }') +# self.assertEqual(u'a {\n color: red !important\n }', s.cssText) +# self.assertEqual(u'important', s.cssRules[0].style.getPropertyPriority('color')) +# +# cssutils.log.raiseExceptions = True +# p = cssutils.css.Property(u'color', u'red', u'') +# self.assertEqual(p.priority, u'') +# p = cssutils.css.Property(u'color', u'red', u'!important') +# self.assertEqual(p.priority, u'important') +# self.assertRaisesMsg(xml.dom.SyntaxErr, +# u'', +# cssutils.css.Property, u'color', u'red', u'x') +# +# cssutils.log.raiseExceptions = False +# p = cssutils.css.Property(u'color', u'red', u'!x') +# self.assertEqual(p.priority, u'x') +# p = cssutils.css.Property(u'color', u'red', u'!x') +# self.assertEqual(p.priority, u'x') +# cssutils.log.raiseExceptions = True +# +# +# # invalid but kept! +## #cssutils.log.raiseExceptions = False +## s = cssutils.parseString('a { color: red !x }') +## self.assertEqual(u'a {\n color: red !x\n }', s.cssText) +## self.assertEqual(u'x', s.cssRules[0].style.getPropertyPriority('color')) +# + +if __name__ == '__main__': + import unittest + unittest.main() diff -Nru cssutils-0.9.10~b1/src/cssutils.egg-info/PKG-INFO cssutils-0.9.10/src/cssutils.egg-info/PKG-INFO --- cssutils-0.9.10~b1/src/cssutils.egg-info/PKG-INFO 2012-04-28 15:10:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils.egg-info/PKG-INFO 2013-03-31 20:03:46.000000000 +0000 @@ -1,6 +1,6 @@ -Metadata-Version: 1.0 +Metadata-Version: 1.1 Name: cssutils -Version: 0.9.10b1 +Version: 0.9.10 Summary: A CSS Cascading Style Sheets library for Python Home-page: http://cthedot.de/cssutils/ Author: Christof Hoeke @@ -16,7 +16,7 @@ ------------------------------------------------------- cssutils: CSS Cascading Style Sheets library for Python ------------------------------------------------------- - :Copyright: 2004-2012 Christof Hoeke + :Copyright: 2004-2013 Christof Hoeke Overview ======== @@ -61,11 +61,11 @@ Compatibility ============= - cssutils is developed on standard Python but works under Python 2.x (from 2.5, v2.5.4 tested), 3.x (v3.2.2 tested) and Jython (from 2.5.1). IronPython has not been tested yet but might work? Python 2.4 and older are not supported since cssutils 0.9.8 anymore. + cssutils is developed on standard Python but works under Python 2.x (from 2.5, 2.7.3 tested), 3.x (v3.3 tested) and Jython (from 2.5.1). IronPython has not been tested yet but might work? Python 2.4 and older are not supported since cssutils 0.9.8 anymore. License ======= - Copyright 2005 - 2012 Christof Hoeke + Copyright 2005 - 2013 Christof Hoeke cssutils is published under the LGPL 3 or later @@ -171,6 +171,7 @@ Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3.2 +Classifier: Programming Language :: Python :: 3.3 Classifier: Topic :: Internet Classifier: Topic :: Software Development :: Libraries :: Python Modules Classifier: Topic :: Text Processing :: Markup :: HTML diff -Nru cssutils-0.9.10~b1/src/cssutils.egg-info/SOURCES.txt cssutils-0.9.10/src/cssutils.egg-info/SOURCES.txt --- cssutils-0.9.10~b1/src/cssutils.egg-info/SOURCES.txt 2012-04-28 15:10:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils.egg-info/SOURCES.txt 2013-03-31 20:03:46.000000000 +0000 @@ -2,6 +2,7 @@ COPYING.LESSER README.txt setup.py +setup3.py examples/build.py examples/codec.py examples/cssencodings.py @@ -66,12 +67,6 @@ sheets/xhtml2.css sheets/xhtml22.css sheets/yuck.css -sheets/import/import-impossible.css -sheets/import/import2.css -sheets/var/start.css -sheets/var/use.css -sheets/var/vars.css -sheets/var/vars2.css src/cssutils/__init__.py src/cssutils/_codec2.py src/cssutils/_codec3.py @@ -129,48 +124,48 @@ src/cssutils/stylesheets/mediaquery.py src/cssutils/stylesheets/stylesheet.py src/cssutils/stylesheets/stylesheetlist.py -src/encutils/__init__.py -src/tests/__init__.py -src/tests/basetest.py -src/tests/test_codec.py -src/tests/test_csscharsetrule.py -src/tests/test_csscomment.py -src/tests/test_cssfontfacerule.py -src/tests/test_cssimportrule.py -src/tests/test_cssmediarule.py -src/tests/test_cssnamespacerule.py -src/tests/test_csspagerule.py -src/tests/test_cssproperties.py -src/tests/test_cssrule.py -src/tests/test_cssrulelist.py -src/tests/test_cssstyledeclaration.py -src/tests/test_cssstylerule.py -src/tests/test_cssstylesheet.py -src/tests/test_cssunknownrule.py -src/tests/test_cssutils.py -src/tests/test_cssutilsimport.py -src/tests/test_cssvalue.py -src/tests/test_cssvariablesdeclaration.py -src/tests/test_cssvariablesrule.py -src/tests/test_domimplementation.py -src/tests/test_errorhandler.py -src/tests/test_helper.py -src/tests/test_marginrule.py -src/tests/test_medialist.py -src/tests/test_mediaquery.py -src/tests/test_parse.py -src/tests/test_prodparser.py -src/tests/test_profiles.py -src/tests/test_properties.py -src/tests/test_property.py -src/tests/test_scripts_csscombine.py -src/tests/test_selector.py -src/tests/test_selectorlist.py -src/tests/test_serialize.py -src/tests/test_settings.py -src/tests/test_stylesheet.py -src/tests/test_tokenize2.py -src/tests/test_util.py -src/tests/test_value.py -src/tests/test_x.py -src/tests/test_encutils/__init__.py \ No newline at end of file +src/cssutils/tests/__init__.py +src/cssutils/tests/basetest.py +src/cssutils/tests/test_codec.py +src/cssutils/tests/test_csscharsetrule.py +src/cssutils/tests/test_csscomment.py +src/cssutils/tests/test_cssfontfacerule.py +src/cssutils/tests/test_cssimportrule.py +src/cssutils/tests/test_cssmediarule.py +src/cssutils/tests/test_cssnamespacerule.py +src/cssutils/tests/test_csspagerule.py +src/cssutils/tests/test_cssproperties.py +src/cssutils/tests/test_cssrule.py +src/cssutils/tests/test_cssrulelist.py +src/cssutils/tests/test_cssstyledeclaration.py +src/cssutils/tests/test_cssstylerule.py +src/cssutils/tests/test_cssstylesheet.py +src/cssutils/tests/test_cssunknownrule.py +src/cssutils/tests/test_cssutils.py +src/cssutils/tests/test_cssutilsimport.py +src/cssutils/tests/test_cssvalue.py +src/cssutils/tests/test_cssvariablesdeclaration.py +src/cssutils/tests/test_cssvariablesrule.py +src/cssutils/tests/test_domimplementation.py +src/cssutils/tests/test_errorhandler.py +src/cssutils/tests/test_helper.py +src/cssutils/tests/test_marginrule.py +src/cssutils/tests/test_medialist.py +src/cssutils/tests/test_mediaquery.py +src/cssutils/tests/test_parse.py +src/cssutils/tests/test_prodparser.py +src/cssutils/tests/test_profiles.py +src/cssutils/tests/test_properties.py +src/cssutils/tests/test_property.py +src/cssutils/tests/test_scripts_csscombine.py +src/cssutils/tests/test_selector.py +src/cssutils/tests/test_selectorlist.py +src/cssutils/tests/test_serialize.py +src/cssutils/tests/test_settings.py +src/cssutils/tests/test_stylesheet.py +src/cssutils/tests/test_tokenize2.py +src/cssutils/tests/test_util.py +src/cssutils/tests/test_value.py +src/cssutils/tests/test_x.py +src/cssutils/tests/test_encutils/__init__.py +src/encutils/__init__.py \ No newline at end of file diff -Nru cssutils-0.9.10~b1/src/cssutils.egg-info/top_level.txt cssutils-0.9.10/src/cssutils.egg-info/top_level.txt --- cssutils-0.9.10~b1/src/cssutils.egg-info/top_level.txt 2012-04-28 15:10:00.000000000 +0000 +++ cssutils-0.9.10/src/cssutils.egg-info/top_level.txt 2013-03-31 20:03:46.000000000 +0000 @@ -1,3 +1,2 @@ cssutils -tests encutils diff -Nru cssutils-0.9.10~b1/src/tests/__init__.py cssutils-0.9.10/src/tests/__init__.py --- cssutils-0.9.10~b1/src/tests/__init__.py 2011-07-26 18:20:08.000000000 +0000 +++ cssutils-0.9.10/src/tests/__init__.py 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -"""cssutils unittests""" diff -Nru cssutils-0.9.10~b1/src/tests/basetest.py cssutils-0.9.10/src/tests/basetest.py --- cssutils-0.9.10~b1/src/tests/basetest.py 2011-12-25 22:34:02.000000000 +0000 +++ cssutils-0.9.10/src/tests/basetest.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,168 +0,0 @@ -"""Base class for all tests""" - -import logging -import os -import sys -import StringIO -import unittest -import urllib2 -from email import message_from_string, message_from_file - -# add src to PYTHONPATH -sys.path.append(os.path.join(os.path.abspath('.'), '..')) - -import cssutils - - -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 - - -class BaseTestCase(unittest.TestCase): - - def _tempSer(self): - "Replace default ser with temp ser." - self._ser = cssutils.ser - cssutils.ser = cssutils.serialize.CSSSerializer() - - def _restoreSer(self): - "Restore the default ser." - cssutils.ser = self._ser - - def setUp(self): - # a raising parser!!! - cssutils.log.raiseExceptions = True - cssutils.log.setLevel(logging.FATAL) - self.p = cssutils.CSSParser(raiseExceptions=True) - - def tearDown(self): - 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, 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.failUnless(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: - exc_info = sys.exc_info() - print 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 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) - ) - - from - http://www.nedbatchelder.com/blog/200609.html#e20060905T064418 - """ - try: - callableObj(*args, **kwargs) - except excClass, exc: - excMsg = unicode(exc) - if not msg: - # No message provided: any message is fine. - return - elif excMsg == msg: - # Message provided, and we got the right message: passes. - return - else: - # Message provided, and it didn't match: fail! - raise self.failureException( - u"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 do_equal_p(self, tests, att='cssText', debug=False, raising=True): - """ - if raising self.p is used for parsing, else self.pf - """ - p = cssutils.CSSParser(raiseExceptions=raising) - # parses with self.p and checks att of result - for test, expected in tests.items(): - if debug: - print '"%s"' % test - s = p.parseString(test) - if expected is None: - expected = test - self.assertEqual(expected, unicode(s.__getattribute__(att), 'utf-8')) - - def do_raise_p(self, tests, debug=False, raising=True): - # parses with self.p and expects raise - p = cssutils.CSSParser(raiseExceptions=raising) - for test, expected in tests.items(): - if debug: - print '"%s"' % test - self.assertRaises(expected, p.parseString, test) - - def do_equal_r(self, tests, att='cssText', debug=False): - # sets attribute att of self.r and asserts Equal - for test, expected in tests.items(): - if debug: - print '"%s"' % test - self.r.__setattr__(att, test) - if expected is None: - expected = test - self.assertEqual(expected, self.r.__getattribute__(att)) - - def do_raise_r(self, tests, att='_setCssText', debug=False): - # sets self.r and asserts raise - for test, expected in tests.items(): - if debug: - print '"%s"' % test - self.assertRaises(expected, self.r.__getattribute__(att), test) diff -Nru cssutils-0.9.10~b1/src/tests/test_codec.py cssutils-0.9.10/src/tests/test_codec.py --- cssutils-0.9.10~b1/src/tests/test_codec.py 2011-12-25 13:05:56.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_codec.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,342 +0,0 @@ -"""Testcases for cssutils.codec""" - -import codecs -import unittest -import sys - -PY2x = sys.version_info < (3,0) -if PY2x: - import StringIO - iostream = StringIO.StringIO -else: - import io - iostream = io.BytesIO - -from cssutils import codec - -try: - codecs.lookup("utf-32") -except LookupError: - haveutf32 = False -else: - haveutf32 = True - - -class Queue(object): - """ - queue: write bytes at one end, read bytes from the other end - """ - def __init__(self): - self._buffer = "".encode() - - def write(self, chars): - # TODO ??? - if not PY2x: - if isinstance(chars, str): - chars = chars.encode() - elif isinstance(chars, int): - chars = bytes([chars]) - - self._buffer += chars - - def read(self, size=-1): - if size<0: - s = self._buffer - self._buffer = "".encode() - return s - else: - s = self._buffer[:size] - self._buffer = self._buffer[size:] - return s - - -class CodecTestCase(unittest.TestCase): - - def test_detectencoding_str(self): - "codec.detectencoding_str()" - self.assertEqual(codec.detectencoding_str(u''.encode()), (None, False)) - self.assertEqual(codec.detectencoding_str(u'\xef'.encode('latin1')), (None, False)) - self.assertEqual(codec.detectencoding_str(u'\xef\x33'.encode("utf-8")), ("utf-8", False)) - self.assertEqual(codec.detectencoding_str(u'\xc3\xaf3'.encode("utf-8")), ("utf-8", False)) - self.assertEqual(codec.detectencoding_str(u'\xef\xbb'.encode("latin1")), (None, False)) - self.assertEqual(codec.detectencoding_str(u'\xef\xbb\x33'.encode("utf-8")), ("utf-8", False)) - self.assertEqual(codec.detectencoding_str(u'\xef\xbb\xbf'.encode("utf-8-sig")), ("utf-8-sig", True)) - self.assertEqual(codec.detectencoding_str(u'\xff'.encode("latin1")), (None, False)) - self.assertEqual(codec.detectencoding_str(u'\xff\x33'.encode("utf-8")), ("utf-8", False)) - self.assertEqual(codec.detectencoding_str(u'\xff\xfe'.encode("latin1")), (None, False)) - self.assertEqual(codec.detectencoding_str(u'\xff\xfe\x33'.encode("utf-16")), ("utf-16", True)) - self.assertEqual(codec.detectencoding_str(u'\xff\xfe\x00'.encode("latin1")), (None, False)) - self.assertEqual(codec.detectencoding_str(u'\xff\xfe\x00\x33'.encode("utf-16")), ("utf-16", True)) - if haveutf32: - self.assertEqual(codec.detectencoding_str(u'\xff\xfe\x00\x00'.encode("utf-32")), ("utf-32", True)) - self.assertEqual(codec.detectencoding_str(u'\x00'.encode()), (None, False)) - self.assertEqual(codec.detectencoding_str(u'\x00\x33'.encode()), ("utf-8", False)) - self.assertEqual(codec.detectencoding_str(u'\x00\x00'.encode()), (None, False)) - self.assertEqual(codec.detectencoding_str(u'\x00\x00\x33'.encode()), ("utf-8", False)) - self.assertEqual(codec.detectencoding_str(u'\x00\x00\xfe'.encode('latin1')), (None, False)) - self.assertEqual(codec.detectencoding_str(u'\x00\x00\x00\x33'.encode()), ("utf-8", False)) - if haveutf32: - self.assertEqual(codec.detectencoding_str(u'\x00\x00\x00@'.encode()), ("utf-32-be", False)) - self.assertEqual(codec.detectencoding_str(u'\x00\x00\xfe\xff'.encode('utf-32')), ("utf-32", True)) - self.assertEqual(codec.detectencoding_str(u'@'.encode()), (None, False)) - self.assertEqual(codec.detectencoding_str(u'@\x33'.encode()), ("utf-8", False)) - self.assertEqual(codec.detectencoding_str(u'@\x00'.encode()), (None, False)) - self.assertEqual(codec.detectencoding_str(u'@\x00\x33'.encode()), ("utf-8", False)) - self.assertEqual(codec.detectencoding_str(u'@\x00\x00'.encode()), (None, False)) - self.assertEqual(codec.detectencoding_str(u'@\x00\x00\x33'.encode()), ("utf-8", False)) - if haveutf32: - self.assertEqual(codec.detectencoding_str(u'@\x00\x00\x00'.encode()), ("utf-32-le", False)) - self.assertEqual(codec.detectencoding_str(u'@c'.encode()), (None, False)) - self.assertEqual(codec.detectencoding_str(u'@ch'.encode()), (None, False)) - self.assertEqual(codec.detectencoding_str(u'@cha'.encode()), (None, False)) - self.assertEqual(codec.detectencoding_str(u'@char'.encode()), (None, False)) - self.assertEqual(codec.detectencoding_str(u'@chars'.encode()), (None, False)) - self.assertEqual(codec.detectencoding_str(u'@charse'.encode()), (None, False)) - self.assertEqual(codec.detectencoding_str(u'@charset'.encode()), (None, False)) - self.assertEqual(codec.detectencoding_str(u'@charset '.encode()), (None, False)) - self.assertEqual(codec.detectencoding_str(u'@charset "'.encode()), (None, False)) - self.assertEqual(codec.detectencoding_str(u'@charset "x'.encode()), (None, False)) - self.assertEqual(codec.detectencoding_str(u'@charset ""'.encode()), ("", True)) - self.assertEqual(codec.detectencoding_str(u'@charset "x"'.encode()), ("x", True)) - self.assertEqual(codec.detectencoding_str(u"@".encode(), False), (None, False)) - self.assertEqual(codec.detectencoding_str(u"@".encode(), True), ("utf-8", False)) - self.assertEqual(codec.detectencoding_str(u"@c".encode(), False), (None, False)) - self.assertEqual(codec.detectencoding_str(u"@c".encode(), True), ("utf-8", False)) - - def test_detectencoding_unicode(self): - "codec.detectencoding_unicode()" - # Unicode version (only parses the header) - self.assertEqual(codec.detectencoding_unicode(u'@charset "x'), (None, False)) - self.assertEqual(codec.detectencoding_unicode(u'a {}'), ("utf-8", False)) - self.assertEqual(codec.detectencoding_unicode(u'@charset "x', True), (None, False)) - self.assertEqual(codec.detectencoding_unicode(u'@charset "x"'), ("x", True)) - - def test_fixencoding(self): - "codec._fixencoding()" - s = u'@charset "' - self.assert_(codec._fixencoding(s, u"utf-8") is None) - - s = u'@charset "x' - self.assert_(codec._fixencoding(s, u"utf-8") is None) - - s = u'@charset "x' - self.assertEqual(codec._fixencoding(s, u"utf-8", True), s) - - s = u'@charset x' - self.assertEqual(codec._fixencoding(s, u"utf-8"), s) - - s = u'@charset "x"' - self.assertEqual(codec._fixencoding(s, u"utf-8"), s.replace('"x"', '"utf-8"')) - - def test_decoder(self): - "codecs.decoder" - def checkauto(encoding, input=u'@charset "x";g\xfcrk\u20ac{}'): - outputencoding = encoding - if outputencoding == "utf-8-sig": - outputencoding = "utf-8" - # Check stateless decoder with encoding autodetection - d = codecs.getdecoder("css") - self.assertEqual(d(input.encode(encoding))[0], input.replace('"x"', '"%s"' % outputencoding)) - - # Check stateless decoder with specified encoding - self.assertEqual(d(input.encode(encoding), encoding=encoding)[0], input.replace('"x"', '"%s"' % outputencoding)) - - if hasattr(codec, "getincrementaldecoder"): - # Check incremental decoder with encoding autodetection - id = codecs.getincrementaldecoder("css")() - self.assertEqual("".join(id.iterdecode(input.encode(encoding))), input.replace('"x"', '"%s"' % outputencoding)) - - # Check incremental decoder with specified encoding - id = codecs.getincrementaldecoder("css")(encoding=encoding) - self.assertEqual("".join(id.iterdecode(input.encode(encoding))), input.replace('"x"', '"%s"' % outputencoding)) - - # Check stream reader with encoding autodetection - q = Queue() - sr = codecs.getreader("css")(q) - result = [] - # TODO: py3 only??? - for c in input.encode(encoding): - q.write(c) - result.append(sr.read()) - self.assertEqual("".join(result), input.replace('"x"', '"%s"' % outputencoding)) - - # Check stream reader with specified encoding - q = Queue() - sr = codecs.getreader("css")(q, encoding=encoding) - result = [] - for c in input.encode(encoding): - q.write(c) - result.append(sr.read()) - self.assertEqual("".join(result), input.replace('"x"', '"%s"' % outputencoding)) - - # Autodetectable encodings - checkauto("utf-8-sig") - checkauto("utf-16") - checkauto("utf-16-le") - checkauto("utf-16-be") - if haveutf32: - checkauto("utf-32") - checkauto("utf-32-le") - checkauto("utf-32-be") - - def checkdecl(encoding, input=u'@charset "%s";g\xfcrk{}'): - # Check stateless decoder with encoding autodetection - d = codecs.getdecoder("css") - input = input % encoding - outputencoding = encoding - if outputencoding == "utf-8-sig": - outputencoding = "utf-8" - self.assertEqual(d(input.encode(encoding))[0], input) - - # Check stateless decoder with specified encoding - self.assertEqual(d(input.encode(encoding), encoding=encoding)[0], input) - - if hasattr(codec, "getincrementaldecoder"): - # Check incremental decoder with encoding autodetection - id = codecs.getincrementaldecoder("css")() - self.assertEqual("".join(id.iterdecode(input.encode(encoding))), input) - - # Check incremental decoder with specified encoding - id = codecs.getincrementaldecoder("css")(encoding) - self.assertEqual("".join(id.iterdecode(input.encode(encoding))), input) - - # Check stream reader with encoding autodetection - q = Queue() - sr = codecs.getreader("css")(q) - result = [] - for c in input.encode(encoding): - q.write(c) - result.append(sr.read()) - self.assertEqual("".join(result), input) - - # Check stream reader with specified encoding - q = Queue() - sr = codecs.getreader("css")(q, encoding=encoding) - result = [] - for c in input.encode(encoding): - q.write(c) - result.append(sr.read()) - self.assertEqual("".join(result), input) - - # Use correct declaration - checkdecl("utf-8") - checkdecl("iso-8859-1", u'@charset "%s";g\xfcrk') - checkdecl("iso-8859-15") - checkdecl("cp1252") - - # No recursion - self.assertRaises(ValueError, u'@charset "css";div{}'.encode().decode, "css") - - def test_encoder(self): - "codec.encoder" - def check(encoding, input=u'@charset "x";g\xfcrk\u20ac{}'): - outputencoding = encoding - if outputencoding == "utf-8-sig": - outputencoding = "utf-8" - - # Check stateless encoder with encoding autodetection - e = codecs.getencoder("css") - inputdecl = input.replace('"x"', '"%s"' % encoding) - outputdecl = input.replace('"x"', '"%s"' % outputencoding) - self.assertEqual(e(inputdecl)[0].decode(encoding), outputdecl) - - # Check stateless encoder with specified encoding - self.assertEqual(e(input, encoding=encoding)[0].decode(encoding), outputdecl) - - if hasattr(codec, "getincrementalencoder"): - # Check incremental encoder with encoding autodetection - ie = codecs.getincrementalencoder("css")() - self.assertEqual("".join(ie.iterencode(inputdecl)).decode(encoding), outputdecl) - - # Check incremental encoder with specified encoding - ie = codecs.getincrementalencoder("css")(encoding=encoding) - self.assertEqual("".join(ie.iterencode(input)).decode(encoding), outputdecl) - - # Check stream writer with encoding autodetection - q = Queue() - sw = codecs.getwriter("css")(q) - for c in inputdecl:#.encode(outputencoding): # TODO: .encode()??? - sw.write(c) - self.assertEqual(q.read().decode(encoding), input.replace('"x"', '"%s"' % outputencoding)) - - # Check stream writer with specified encoding - q = Queue() - sw = codecs.getwriter("css")(q, encoding=encoding) - for c in input: - sw.write(c) - self.assertEqual(q.read().decode(encoding), input.replace('"x"', '"%s"' % outputencoding)) - - # Autodetectable encodings - check("utf-8-sig") - check("utf-16") - check("utf-16-le") - check("utf-16-be") - if haveutf32: - check("utf-32") - check("utf-32-le") - check("utf-32-be") - check("utf-8") - check("iso-8859-1", u'@charset "x";g\xfcrk{}') - check("iso-8859-15") - check("cp1252") - - # No recursion - self.assertRaises(ValueError, u'@charset "css";div{}'.encode, "css") - - def test_decode_force(self): - "codec.decode (force)" - info = codecs.lookup("css") - - def decodeall(input, **kwargs): - # Py 2.5: info.decode('@charset "utf-8"; x') - return info[1](input, **kwargs)[0] - - def incdecode(input, **kwargs): - decoder = info.incrementaldecoder(**kwargs) - return decoder.decode(input) - - def streamdecode(input, **kwargs): - stream = iostream(input) # py3 .decode('utf-8') but still error?! - reader = info.streamreader(stream, **kwargs) - return reader.read() - - for d in (decodeall, incdecode, streamdecode): -# input = '@charset "utf-8"; \xc3\xbf' -# output = u'@charset "utf-8"; \xff' -# self.assertEqual(d(input), output) -# -# input = '@charset "utf-8"; \xc3\xbf' -# output = u'@charset "iso-8859-1"; \xc3\xbf' -# self.assertEqual(d(input, encoding="iso-8859-1", force=True), output) -# -# input = '\xc3\xbf' -# output = u'\xc3\xbf' -# self.assertEqual(d(input, encoding="iso-8859-1", force=True), output) -# -# input = '@charset "utf-8"; \xc3\xbf' -# output = u'@charset "utf-8"; \xff' -# self.assertEqual(d(input, encoding="iso-8859-1", force=False), output) - - input = u'@charset "utf-8"; \xff'.encode('utf-8') - output = u'@charset "utf-8"; \xff' - self.assertEqual(d(input), output) - - #input = b'@charset "utf-8"; \xc3\xbf' - input = u'@charset "utf-8"; \xff'.encode('utf-8') - output = u'@charset "iso-8859-1"; \xc3\xbf' - self.assertEqual(d(input, encoding="iso-8859-1", force=True), output) - - #input = b'\xc3\xbf' - input = u'\xff'.encode('utf-8') - output = u'\xc3\xbf' - self.assertEqual(d(input, encoding="iso-8859-1", force=True), output) - - #input = b'@charset "utf-8"; \xc3\xbf' - input = u'@charset "utf-8"; \xff'.encode('utf-8') - output = u'@charset "utf-8"; \xff' - self.assertEqual(d(input, encoding="iso-8859-1", force=False), output) - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_csscharsetrule.py cssutils-0.9.10/src/tests/test_csscharsetrule.py --- cssutils-0.9.10~b1/src/tests/test_csscharsetrule.py 2011-07-26 18:22:54.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_csscharsetrule.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,123 +0,0 @@ -"""Testcases for cssutils.css.CSSCharsetRule""" - -import re -import xml.dom -import test_cssrule -import cssutils.css - -class CSSCharsetRuleTestCase(test_cssrule.CSSRuleTestCase): - - def setUp(self): - super(CSSCharsetRuleTestCase, self).setUp() - self.r = cssutils.css.CSSCharsetRule() - self.rRO = cssutils.css.CSSCharsetRule(readonly=True) - self.r_type = cssutils.css.CSSCharsetRule.CHARSET_RULE - self.r_typeString = 'CHARSET_RULE' - - def test_init(self): - "CSSCharsetRule.__init__()" - super(CSSCharsetRuleTestCase, self).test_init() - self.assertEqual(None, self.r.encoding) - self.assertEqual(u'', self.r.cssText) - - self.assertRaises(xml.dom.InvalidModificationErr, self.r._setCssText, u'xxx') - - def test_InvalidModificationErr(self): - "CSSCharsetRule InvalidModificationErr" - self._test_InvalidModificationErr(u'@charset') - - def test_init_encoding(self): - "CSSCharsetRule.__init__(encoding)" - for enc in (None, u'UTF-8', u'utf-8', u'iso-8859-1', u'ascii'): - r = cssutils.css.CSSCharsetRule(enc) - if enc is None: - self.assertEqual(None, r.encoding) - self.assertEqual(u'', r.cssText) - else: - self.assertEqual(enc.lower(), r.encoding) - self.assertEqual( - u'@charset "%s";' % enc.lower(), r.cssText) - - for enc in (' ascii ', ' ascii', 'ascii '): - self.assertRaisesEx(xml.dom.SyntaxErr, - cssutils.css.CSSCharsetRule, enc, - exc_pattern=re.compile("Syntax Error")) - - for enc in (u'unknown', ): - self.assertRaisesEx(xml.dom.SyntaxErr, - cssutils.css.CSSCharsetRule, enc, - exc_pattern=re.compile("Unknown \(Python\) encoding")) - - def test_encoding(self): - "CSSCharsetRule.encoding" - for enc in (u'UTF-8', u'utf-8', u'iso-8859-1', u'ascii'): - self.r.encoding = enc - self.assertEqual(enc.lower(), self.r.encoding) - self.assertEqual( - u'@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")) - - for enc in (u'unknown', ): - self.assertRaisesEx(xml.dom.SyntaxErr, - self.r.__setattr__, 'encoding', enc, - exc_pattern=re.compile("Unknown \(Python\) encoding")) - - def test_cssText(self): - """CSSCharsetRule.cssText - - setting cssText is ok to use @CHARSET or other but a file - using parse MUST use ``@charset "ENCODING";`` - """ - tests = { - u'@charset "utf-8";': None, - u"@charset 'utf-8';": u'@charset "utf-8";', - } - self.do_equal_r(tests) - self.do_equal_p(tests) # also parse - - tests = { - # token is "@charset " with space! - u'@charset;"': xml.dom.InvalidModificationErr, - u'@CHARSET "UTF-8";': xml.dom.InvalidModificationErr, - u'@charset "";': xml.dom.SyntaxErr, - u'''@charset /*1*/"utf-8"/*2*/;''': xml.dom.SyntaxErr, - u'''@charset /*1*/"utf-8";''': xml.dom.SyntaxErr, - u'''@charset "utf-8"/*2*/;''': xml.dom.SyntaxErr, - u'@charset { utf-8 }': xml.dom.SyntaxErr, - u'@charset "utf-8"': xml.dom.SyntaxErr, - u'@charset a;': xml.dom.SyntaxErr, - u'@charset /**/;': xml.dom.SyntaxErr, - # trailing content - u'@charset "utf-8";s': xml.dom.SyntaxErr, - u'@charset "utf-8";/**/': xml.dom.SyntaxErr, - u'@charset "utf-8"; ': xml.dom.SyntaxErr, - - # comments do not work in this rule! - u'@charset "utf-8"/*1*//*2*/;': xml.dom.SyntaxErr - } - self.do_raise_r(tests) - - def test_repr(self): - "CSSCharsetRule.__repr__()" - self.r.encoding = 'utf-8' - self.assert_('utf-8' in repr(self.r)) - - def test_reprANDstr(self): - "CSSCharsetRule.__repr__(), .__str__()" - encoding='utf-8' - - s = cssutils.css.CSSCharsetRule(encoding=encoding) - - self.assert_(encoding in str(s)) - - s2 = eval(repr(s)) - self.assert_(isinstance(s2, s.__class__)) - self.assert_(encoding == s2.encoding) - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_csscomment.py cssutils-0.9.10/src/tests/test_csscomment.py --- cssutils-0.9.10~b1/src/tests/test_csscomment.py 2011-07-26 18:22:54.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_csscomment.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,71 +0,0 @@ -# -*- coding: utf-8 -*- -"""Testcases for cssutils.css.CSSComment""" - -import xml -import test_cssrule -import cssutils.css - -class CSSCommentTestCase(test_cssrule.CSSRuleTestCase): - - def setUp(self): - super(CSSCommentTestCase, self).setUp() - self.r = cssutils.css.CSSComment() - self.rRO = cssutils.css.CSSComment(readonly=True) - self.r_type = cssutils.css.CSSComment.COMMENT - self.r_typeString = 'COMMENT' - - def test_init(self): - "CSSComment.type and init" - super(CSSCommentTestCase, self).test_init() - - def test_csstext(self): - "CSSComment.cssText" - tests = { - u'/*öäü߀ÖÄÜ*/': u'/*\xf6\xe4\xfc\xdf\u20ac\xd6\xc4\xdc*/', - u'/*x*/': None, - u'/* x */': None, - u'/*\t12\n*/': None, - u'/* /* */': None, - u'/* \\*/': None, - u'/*"*/': None, - u'''/*" - */''': None, - u'/** / ** //*/': None - } - self.do_equal_r(tests) # set cssText - tests.update({ - u'/*x': u'/*x*/', - u'\n /*': u'/**/', - }) - self.do_equal_p(tests) # parse - - tests = { - u'/* */ ': xml.dom.InvalidModificationErr, - u'/* *//**/': xml.dom.InvalidModificationErr, - u'/* */1': xml.dom.InvalidModificationErr, - u'/* */ */': xml.dom.InvalidModificationErr, - u' */ /* ': xml.dom.InvalidModificationErr, - u'*/': xml.dom.InvalidModificationErr, - u'@x /* x */': xml.dom.InvalidModificationErr - } - self.do_raise_r(tests) # set cssText - # no raising of error possible? - # self.do_raise_p(tests) # parse - - def test_InvalidModificationErr(self): - "CSSComment.cssText InvalidModificationErr" - self._test_InvalidModificationErr(u'/* comment */') - - def test_reprANDstr(self): - "CSSComment.__repr__(), .__str__()" - text = '/* test */' - - s = cssutils.css.CSSComment(cssText=text) - - s2 = eval(repr(s)) - self.assert_(isinstance(s2, s.__class__)) - self.assert_(text == s2.cssText) - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_cssfontfacerule.py cssutils-0.9.10/src/tests/test_cssfontfacerule.py --- cssutils-0.9.10~b1/src/tests/test_cssfontfacerule.py 2011-07-26 19:13:58.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_cssfontfacerule.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,241 +0,0 @@ -"""Testcases for cssutils.css.CSSFontFaceRule""" - -import xml.dom -import test_cssrule -import cssutils - -class CSSFontFaceRuleTestCase(test_cssrule.CSSRuleTestCase): - - def setUp(self): - super(CSSFontFaceRuleTestCase, self).setUp() - self.r = cssutils.css.CSSFontFaceRule() - self.rRO = cssutils.css.CSSFontFaceRule(readonly=True) - self.r_type = cssutils.css.CSSFontFaceRule.FONT_FACE_RULE# - self.r_typeString = 'FONT_FACE_RULE' - - def test_init(self): - "CSSFontFaceRule.__init__()" - super(CSSFontFaceRuleTestCase, self).test_init() - - r = cssutils.css.CSSFontFaceRule() - self.assert_(isinstance(r.style, cssutils.css.CSSStyleDeclaration)) - self.assertEqual(r, r.style.parentRule) - - # until any properties - self.assertEqual(u'', r.cssText) - - # only possible to set @... similar name - self.assertRaises(xml.dom.InvalidModificationErr, self.r._setAtkeyword, 'x') - - def checkrefs(ff): - self.assertEqual(ff, ff.style.parentRule) - for p in ff.style: - self.assertEqual(ff.style, p.parent) - - checkrefs(cssutils.css.CSSFontFaceRule( - style=cssutils.css.CSSStyleDeclaration('font-family: x'))) - - r = cssutils.css.CSSFontFaceRule() - r.cssText = '@font-face { font-family: x }' - checkrefs(r) - - r = cssutils.css.CSSFontFaceRule() - r.style.setProperty('font-family', 'y') - checkrefs(r) - - r = cssutils.css.CSSFontFaceRule() - r.style['font-family'] = 'z' - checkrefs(r) - - r = cssutils.css.CSSFontFaceRule() - r.style.fontFamily = 'a' - checkrefs(r) - - def test_cssText(self): - "CSSFontFaceRule.cssText" - tests = { - u'''@font-face { - font-family: x; - src: url(../fonts/LateefRegAAT.ttf) format("truetype-aat"), url(../fonts/LateefRegOT.ttf) format("opentype"); - font-style: italic; - font-weight: 500; - font-stretch: condensed; - unicode-range: u+1-ff, u+111 - }''': None, - u'@font-face{font-family: x;}': u'@font-face {\n font-family: x\n }', - u'@font-face { font-family: x; }': u'@font-face {\n font-family: x\n }', - u'@f\\ont\\-face{font-family : x;}': u'@font-face {\n font-family: x\n }', - # comments - u'@font-face/*1*//*2*/{font-family: x;}': - u'@font-face /*1*/ /*2*/ {\n font-family: x\n }', - # WS - u'@font-face\n\t\f {\n\t\f font-family:x;\n\t\f }': - u'@font-face {\n font-family: x\n }', - } - self.do_equal_r(tests) - self.do_equal_p(tests) - - tests = { - u'@font-face;': xml.dom.SyntaxErr, - u'@font-face }': xml.dom.SyntaxErr, - } - self.do_raise_p(tests) # parse - tests.update({ - u'@font-face {': xml.dom.SyntaxErr, # no } - # trailing - u'@font-face {}1': xml.dom.SyntaxErr, - u'@font-face {}/**/': xml.dom.SyntaxErr, - u'@font-face {} ': xml.dom.SyntaxErr, - }) - self.do_raise_r(tests) # set cssText - - def test_style(self): - "CSSFontFaceRule.style (and references)" - r = cssutils.css.CSSFontFaceRule() - s1 = r.style - self.assertEqual(r, s1.parentRule) - self.assertEqual(u'', s1.cssText) - - # set rule.cssText - r.cssText = '@font-face { font-family: x1 }' - self.failIfEqual(r.style, s1) - self.assertEqual(r, r.style.parentRule) - self.assertEqual(r.cssText, u'@font-face {\n font-family: x1\n }') - self.assertEqual(r.style.cssText, u'font-family: x1') - self.assertEqual(s1.cssText, u'') - s2 = r.style - - # set invalid rule.cssText - try: - r.cssText = '@font-face { $ }' - except xml.dom.SyntaxErr, e: - pass - self.assertEqual(r.style, s2) - self.assertEqual(r, s2.parentRule) - self.assertEqual(r.cssText, u'@font-face {\n font-family: x1\n }') - self.assertEqual(s2.cssText, u'font-family: x1') - self.assertEqual(r.style.cssText, u'font-family: x1') - - # set rule.style.cssText - r.style.cssText = 'font-family: x2' - self.assertEqual(r.style, s2) - self.assertEqual(r, s2.parentRule) - self.assertEqual(r.cssText, u'@font-face {\n font-family: x2\n }') - self.assertEqual(s2.cssText, u'font-family: x2') - self.assertEqual(r.style.cssText, u'font-family: x2') - - # set new style object s2 - sn = cssutils.css.CSSStyleDeclaration('font-family: y1') - r.style = sn - self.assertEqual(r.style, sn) - self.assertEqual(r, sn.parentRule) - self.assertEqual(r.cssText, u'@font-face {\n font-family: y1\n }') - self.assertEqual(sn.cssText, u'font-family: y1') - self.assertEqual(r.style.cssText, u'font-family: y1') - self.assertEqual(s2.cssText, u'font-family: x2') # old - - # set s2.cssText - sn.cssText = 'font-family: y2' - self.assertEqual(r.style, sn) - self.assertEqual(r.cssText, u'@font-face {\n font-family: y2\n }') - self.assertEqual(r.style.cssText, u'font-family: y2') - self.assertEqual(s2.cssText, u'font-family: x2') # old - - # set invalid s2.cssText - try: - sn.cssText = '$' - except xml.dom.SyntaxErr, e: - pass - self.assertEqual(r.style, sn) - self.assertEqual(r.style.cssText, u'font-family: y2') - self.assertEqual(r.cssText, u'@font-face {\n font-family: y2\n }') - - # set r.style with text - r.style = 'font-family: z' - self.failIfEqual(r.style, sn) - self.assertEqual(r.cssText, u'@font-face {\n font-family: z\n }') - self.assertEqual(r.style.cssText, u'font-family: z') - self.assertEqual(sn.cssText, u'font-family: y2') - - def test_properties(self): - "CSSFontFaceRule.style properties" - r = cssutils.css.CSSFontFaceRule() - r.style.cssText = ''' - src: url(x) - ''' - exp = u'''@font-face { - src: url(x) - }''' - self.assertEqual(exp, r.cssText) - - tests = { - 'font-family': [#('serif', True), -# ('x', True), -# ('"x"', True), - ('x, y', False), - ('"x", y', False), - ('x, "y"', False), -# ('"x", "y"', False) - ] - } - for n, t in tests.items(): - for (v, valid) in t: - r = cssutils.css.CSSFontFaceRule() - r.style[n] = v - self.assertEqual(r.style.getProperty(n).parent, r.style) - self.assertEqual(r.style.getProperty(n).valid, valid) - - def test_incomplete(self): - "CSSFontFaceRule (incomplete)" - tests = { - u'@font-face{': - u'', # no } and no content - u'@font-face { ': - u'', # no } and no content - u'@font-face { font-family: x': - u'@font-face {\n font-family: x\n }', # no } - } - self.do_equal_p(tests) # parse - - def test_InvalidModificationErr(self): - "CSSFontFaceRule.cssText InvalidModificationErr" - self._test_InvalidModificationErr(u'@font-face') - tests = { - u'@font-fac {}': xml.dom.InvalidModificationErr, - } - self.do_raise_r(tests) - - def test_valid(self): - "CSSFontFaceRule.valid" - r = cssutils.css.CSSFontFaceRule() - self.assertEqual(False, r.valid) - N = 'font-family: x; src: local(x);' - tests = { - True: (N, - N + 'font-style: italic; font-weight: bold', - ), - False: ('', - 'font-family: x, y; src: local(x);', - N + 'font-style: inherit', - N + 'invalid: 1') - } - for valid, testlist in tests.items(): - for test in testlist: - r.style.cssText = test - self.assertEqual(valid, r.valid) - - def test_reprANDstr(self): - "CSSFontFaceRule.__repr__(), .__str__()" - style='src: url(x)' - s = cssutils.css.CSSFontFaceRule(style=style) - - self.assert_(style in str(s)) - - s2 = eval(repr(s)) - self.assert_(isinstance(s2, s.__class__)) - self.assert_(style == s2.style.cssText) - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_cssimportrule.py cssutils-0.9.10/src/tests/test_cssimportrule.py --- cssutils-0.9.10~b1/src/tests/test_cssimportrule.py 2011-07-26 18:22:54.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_cssimportrule.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,436 +0,0 @@ -"""Testcases for cssutils.css.CSSImportRule""" - -import xml.dom -import test_cssrule -import cssutils - -import basetest - -class CSSImportRuleTestCase(test_cssrule.CSSRuleTestCase): - - def setUp(self): - super(CSSImportRuleTestCase, self).setUp() - self.r = cssutils.css.CSSImportRule() - self.rRO = cssutils.css.CSSImportRule(readonly=True) - self.r_type = cssutils.css.CSSImportRule.IMPORT_RULE - self.r_typeString = 'IMPORT_RULE' - - def test_init(self): - "CSSImportRule.__init__()" - super(CSSImportRuleTestCase, self).test_init() - - # no init param - self.assertEqual(None, self.r.href) - self.assertEqual(None, self.r.hreftype) - self.assertEqual(False, self.r.hrefFound) - self.assertEqual(u'all', self.r.media.mediaText) - self.assertEqual( - cssutils.stylesheets.MediaList, type(self.r.media)) - self.assertEqual(None, self.r.name) - self.assertEqual(cssutils.css.CSSStyleSheet, type(self.r.styleSheet)) - self.assertEqual(0, self.r.styleSheet.cssRules.length) - self.assertEqual(u'', self.r.cssText) - - # all - r = cssutils.css.CSSImportRule(href='href', mediaText='tv', name='name') - self.assertEqual(u'@import url(href) tv "name";', r.cssText) - self.assertEqual("href", r.href) - self.assertEqual(None, r.hreftype) - self.assertEqual(u'tv', r.media.mediaText) - self.assertEqual( - cssutils.stylesheets.MediaList, type(r.media)) - self.assertEqual('name', r.name) - self.assertEqual(None, r.parentRule) # see CSSRule - self.assertEqual(None, r.parentStyleSheet) # see CSSRule - self.assertEqual(cssutils.css.CSSStyleSheet, type(self.r.styleSheet)) - self.assertEqual(0, self.r.styleSheet.cssRules.length) - - # href - r = cssutils.css.CSSImportRule(u'x') - self.assertEqual(u'@import url(x);', r.cssText) - self.assertEqual('x', r.href) - self.assertEqual(None, r.hreftype) - - # href + mediaText - r = cssutils.css.CSSImportRule(u'x', u'print') - self.assertEqual(u'@import url(x) print;', r.cssText) - self.assertEqual('x', r.href) - self.assertEqual('print', r.media.mediaText) - - # href + name - r = cssutils.css.CSSImportRule(u'x', name=u'n') - self.assertEqual(u'@import url(x) "n";', r.cssText) - self.assertEqual('x', r.href) - self.assertEqual('n', r.name) - - # href + mediaText + name - r = cssutils.css.CSSImportRule(u'x', u'print', 'n') - self.assertEqual(u'@import url(x) print "n";', r.cssText) - self.assertEqual('x', r.href) - self.assertEqual('print', r.media.mediaText) - self.assertEqual('n', r.name) - - # media +name only - self.r = cssutils.css.CSSImportRule(mediaText=u'print', name="n") - self.assertEqual(cssutils.stylesheets.MediaList, - type(self.r.media)) - self.assertEqual(u'', self.r.cssText) - self.assertEqual(u'print', self.r.media.mediaText) - self.assertEqual(u'n', self.r.name) - - # only possible to set @... similar name - self.assertRaises(xml.dom.InvalidModificationErr, self.r._setAtkeyword, 'x') - - def test_cssText(self): - "CSSImportRule.cssText" - tests = { - # href string - u'''@import "str";''': None, - u'''@import"str";''': u'''@import "str";''', - u'''@\\import "str";''': u'''@import "str";''', - u'''@IMPORT "str";''': u'''@import "str";''', - u'''@import 'str';''': u'''@import "str";''', - u'''@import 'str' ;''': u'''@import "str";''', - u'''@import "str";''': None, - u'''@import "str" ;''': u'''@import "str";''', - ur'''@import "\"" ;''': ur'''@import "\"";''', - u'''@import '\\'';''': ur'''@import "'";''', - u'''@import '"';''': ur'''@import "\"";''', - # href url - u'''@import url(x.css);''': None, - # nospace - u'''@import url(")");''': u'''@import url(")");''', - u'''@import url("\\"");''': u'''@import url("\\"");''', - u'''@import url('\\'');''': u'''@import url("'");''', - - # href + media - # all is removed - u'''@import "str" all;''': u'''@import "str";''', - u'''@import "str" tv, print;''': None, - u'''@import"str"tv,print;''': u'''@import "str" tv, print;''', - u'''@import "str" tv, print, all;''': u'''@import "str";''', - u'''@import "str" handheld, all;''': u'''@import "str" all, handheld;''', - u'''@import "str" all, handheld;''': None, - u'''@import "str" not tv;''': None, - u'''@import "str" only tv;''': None, - u'''@import "str" only tv and (color: 2);''': None, - - # href + name - u'''@import "str" "name";''': None, - u'''@import "str" 'name';''': u'''@import "str" "name";''', - u'''@import url(x) "name";''': None, - u'''@import "str" "\\"";''': None, - u'''@import "str" '\\'';''': u'''@import "str" "'";''', - - # href + media + name - u'''@import"str"tv"name";''': u'''@import "str" tv "name";''', - u'''@import\t\r\f\n"str"\t\t\r\f\ntv\t\t\r\f\n"name"\t;''': - u'''@import "str" tv "name";''', - - # comments - u'''@import /*1*/ "str" /*2*/;''': None, - u'@import/*1*//*2*/"str"/*3*//*4*/all/*5*//*6*/"name"/*7*//*8*/ ;': - u'@import /*1*/ /*2*/ "str" /*3*/ /*4*/ all /*5*/ /*6*/ "name" /*7*/ /*8*/;', - u'@import/*1*//*2*/url(u)/*3*//*4*/all/*5*//*6*/"name"/*7*//*8*/ ;': - u'@import /*1*/ /*2*/ url(u) /*3*/ /*4*/ all /*5*/ /*6*/ "name" /*7*/ /*8*/;', - u'@import/*1*//*2*/url("u")/*3*//*4*/all/*5*//*6*/"name"/*7*//*8*/ ;': - u'@import /*1*/ /*2*/ url(u) /*3*/ /*4*/ all /*5*/ /*6*/ "name" /*7*/ /*8*/;', - # WS - u'@import\n\t\f "str"\n\t\f tv\n\t\f "name"\n\t\f ;': - u'@import "str" tv "name";', - u'@import\n\t\f url(\n\t\f u\n\t\f )\n\t\f tv\n\t\f "name"\n\t\f ;': - u'@import url(u) tv "name";', - u'@import\n\t\f url("u")\n\t\f tv\n\t\f "name"\n\t\f ;': - u'@import url(u) tv "name";', - u'@import\n\t\f url(\n\t\f "u"\n\t\f )\n\t\f tv\n\t\f "name"\n\t\f ;': - u'@import url(u) tv "name";', - } - self.do_equal_r(tests) # set cssText - tests.update({ - u'@import "x.css" tv': '@import "x.css" tv;', - u'@import "x.css"': '@import "x.css";', # no ; - u"@import 'x.css'": '@import "x.css";', # no ; - u'@import url(x.css)': '@import url(x.css);', # no ; - u'@import "x;': '@import "x;";', # no "! - }) - self.do_equal_p(tests) # parse - - tests = { - u'''@import;''': xml.dom.SyntaxErr, - u'''@import all;''': xml.dom.SyntaxErr, - u'''@import all"name";''': xml.dom.SyntaxErr, - u'''@import;''': xml.dom.SyntaxErr, - u'''@import x";''': xml.dom.SyntaxErr, - u'''@import "str" ,all;''': xml.dom.SyntaxErr, - u'''@import "str" all,;''': xml.dom.SyntaxErr, - u'''@import "str" all tv;''': xml.dom.SyntaxErr, - u'''@import "str" "name" all;''': xml.dom.SyntaxErr, - } - self.do_raise_p(tests) # parse - tests.update({ - u'@import "x.css"': xml.dom.SyntaxErr, - u"@import 'x.css'": xml.dom.SyntaxErr, - u'@import url(x.css)': xml.dom.SyntaxErr, - u'@import "x.css" tv': xml.dom.SyntaxErr, - u'@import "x;': xml.dom.SyntaxErr, - u'''@import url("x);''': xml.dom.SyntaxErr, - # trailing - u'''@import "x";"a"''': xml.dom.SyntaxErr, - # trailing S or COMMENT - u'''@import "x";/**/''': xml.dom.SyntaxErr, - u'''@import "x"; ''': xml.dom.SyntaxErr, - }) - self.do_raise_r(tests) # set cssText - - def test_href(self): - "CSSImportRule.href" - # set - self.r.href = 'x' - self.assertEqual('x', self.r.href) - self.assertEqual(u'@import url(x);', self.r.cssText) - - # http - self.r.href = 'http://www.example.com/x?css=z&v=1' - self.assertEqual('http://www.example.com/x?css=z&v=1' , self.r.href) - self.assertEqual(u'@import url(http://www.example.com/x?css=z&v=1);', - self.r.cssText) - - # also if hreftype changed - self.r.hreftype='string' - self.assertEqual('http://www.example.com/x?css=z&v=1' , self.r.href) - self.assertEqual(u'@import "http://www.example.com/x?css=z&v=1";', - self.r.cssText) - - # string escaping? - self.r.href = '"' - self.assertEqual(u'@import "\\"";', self.r.cssText) - self.r.hreftype='url' - self.assertEqual(u'@import url("\\"");', self.r.cssText) - - # url escaping? - self.r.href = ')' - self.assertEqual(u'@import url(")");', self.r.cssText) - - self.r.hreftype = 'NOT VALID' # using default - self.assertEqual(u'@import url(")");', self.r.cssText) - - def test_hrefFound(self): - "CSSImportRule.hrefFound" - def fetcher(url): - if url == u'http://example.com/yes': - return None, u'/**/' - else: - return None, None - - parser = cssutils.CSSParser(fetcher=fetcher) - sheet = parser.parseString(u'@import "http://example.com/yes" "name"') - - r = sheet.cssRules[0] - self.assertEqual(u'/**/'.encode(), r.styleSheet.cssText) - self.assertEqual(True, r.hrefFound) - self.assertEqual(u'name', r.name) - - r.cssText = '@import url(http://example.com/none) "name2";' - self.assertEqual(u''.encode(), r.styleSheet.cssText) - self.assertEqual(False, r.hrefFound) - self.assertEqual(u'name2', r.name) - - sheet.cssText = '@import url(http://example.com/none);' - self.assertNotEqual(r, sheet.cssRules[0]) - - def test_hreftype(self): - "CSSImportRule.hreftype" - self.r = cssutils.css.CSSImportRule() - - self.r.cssText = '@import /*1*/url(org) /*2*/;' - self.assertEqual('uri', self.r.hreftype) - self.assertEqual(u'@import /*1*/ url(org) /*2*/;', self.r.cssText) - - self.r.cssText = '@import /*1*/"org" /*2*/;' - self.assertEqual('string', self.r.hreftype) - self.assertEqual(u'@import /*1*/ "org" /*2*/;', self.r.cssText) - - self.r.href = 'new' - self.assertEqual(u'@import /*1*/ "new" /*2*/;', self.r.cssText) - - self.r.hreftype='uri' - self.assertEqual(u'@import /*1*/ url(new) /*2*/;', self.r.cssText) - - def test_media(self): - "CSSImportRule.media" - self.r.href = 'x' # @import url(x) - - # media is readonly - self.assertRaises(AttributeError, self.r.__setattr__, 'media', None) - - # but not static - self.r.media.mediaText = 'print' - self.assertEqual(u'@import url(x) print;', self.r.cssText) - self.r.media.appendMedium('tv') - self.assertEqual(u'@import url(x) print, tv;', self.r.cssText) - - # for generated rule - r = cssutils.css.CSSImportRule(href='x') - self.assertRaisesMsg(xml.dom.InvalidModificationErr, - basetest.msg3x('''MediaList: Ignoring new medium cssutils.stylesheets.MediaQuery(mediaText=u'tv') as already specified "all" (set ``mediaText`` instead).'''), - r.media.appendMedium, 'tv') - self.assertEqual(u'@import url(x);', r.cssText) - self.assertRaisesMsg(xml.dom.InvalidModificationErr, - basetest.msg3x('''MediaList: Ignoring new medium cssutils.stylesheets.MediaQuery(mediaText=u'tv') as already specified "all" (set ``mediaText`` instead).'''), - r.media.appendMedium, 'tv') - self.assertEqual(u'@import url(x);', r.cssText) - r.media.mediaText = 'tv' - self.assertEqual(u'@import url(x) tv;', r.cssText) - r.media.appendMedium('print') # all + tv = all! - self.assertEqual(u'@import url(x) tv, print;', r.cssText) - - # for parsed rule without initial media - s = cssutils.parseString('@import url(x);') - r = s.cssRules[0] - - self.assertRaisesMsg(xml.dom.InvalidModificationErr, - basetest.msg3x('''MediaList: Ignoring new medium cssutils.stylesheets.MediaQuery(mediaText=u'tv') as already specified "all" (set ``mediaText`` instead).'''), - r.media.appendMedium, 'tv') - self.assertEqual(u'@import url(x);', r.cssText) - self.assertRaisesMsg(xml.dom.InvalidModificationErr, - basetest.msg3x('''MediaList: Ignoring new medium cssutils.stylesheets.MediaQuery(mediaText=u'tv') as already specified "all" (set ``mediaText`` instead).'''), - r.media.appendMedium, 'tv') - self.assertEqual(u'@import url(x);', r.cssText) - r.media.mediaText = 'tv' - self.assertEqual(u'@import url(x) tv;', r.cssText) - r.media.appendMedium('print') # all + tv = all! - self.assertEqual(u'@import url(x) tv, print;', r.cssText) - - def test_name(self): - "CSSImportRule.name" - r = cssutils.css.CSSImportRule('x', name='a000000') - self.assertEqual('a000000', r.name) - self.assertEqual(u'@import url(x) "a000000";', r.cssText) - - r.name = "n" - self.assertEqual('n', r.name) - self.assertEqual(u'@import url(x) "n";', r.cssText) - r.name = '"' - self.assertEqual('"', r.name) - self.assertEqual(u'@import url(x) "\\"";', r.cssText) - - r.hreftype = 'string' - self.assertEqual(u'@import "x" "\\"";', r.cssText) - r.name = "123" - self.assertEqual(u'@import "x" "123";', r.cssText) - - r.name = None - self.assertEqual(None, r.name) - self.assertEqual(u'@import "x";', r.cssText) - - r.name = "" - self.assertEqual(None, r.name) - self.assertEqual(u'@import "x";', r.cssText) - - self.assertRaises(xml.dom.SyntaxErr, r._setName, 0) - self.assertRaises(xml.dom.SyntaxErr, r._setName, 123) - - def test_styleSheet(self): - "CSSImportRule.styleSheet" - def fetcher(url): - if url == "/root/level1/anything.css": - return None, '@import "level2/css.css" "title2";' - else: - return None, 'a { color: red }' - - parser = cssutils.CSSParser(fetcher=fetcher) - sheet = parser.parseString('''@charset "ascii"; - @import "level1/anything.css" tv "title";''', - href='/root/') - - self.assertEqual(sheet.href, '/root/') - - ir = sheet.cssRules[1] - self.assertEqual(ir.href, 'level1/anything.css') - self.assertEqual(ir.styleSheet.href, '/root/level1/anything.css') - # inherits ascii as no self charset is set - self.assertEqual(ir.styleSheet.encoding, 'ascii') - self.assertEqual(ir.styleSheet.ownerRule, ir) - self.assertEqual(ir.styleSheet.media.mediaText, 'tv') - self.assertEqual(ir.styleSheet.parentStyleSheet, None) # sheet - self.assertEqual(ir.styleSheet.title, 'title') - self.assertEqual(ir.styleSheet.cssText, - '@charset "ascii";\n@import "level2/css.css" "title2";'.encode()) - - ir2 = ir.styleSheet.cssRules[1] - self.assertEqual(ir2.href, 'level2/css.css') - self.assertEqual(ir2.styleSheet.href, '/root/level1/level2/css.css') - # inherits ascii as no self charset is set - self.assertEqual(ir2.styleSheet.encoding, 'ascii') - self.assertEqual(ir2.styleSheet.ownerRule, ir2) - self.assertEqual(ir2.styleSheet.media.mediaText, 'all') - self.assertEqual(ir2.styleSheet.parentStyleSheet, None) #ir.styleSheet - self.assertEqual(ir2.styleSheet.title, 'title2') - self.assertEqual(ir2.styleSheet.cssText, - '@charset "ascii";\na {\n color: red\n }'.encode()) - - sheet = cssutils.parseString('@import "CANNOT-FIND.css";') - ir = sheet.cssRules[0] - self.assertEqual(ir.href, "CANNOT-FIND.css") - self.assertEqual(type(ir.styleSheet), cssutils.css.CSSStyleSheet) - - def fetcher(url): - if url.endswith('level1.css'): - return None, u'@charset "ascii"; @import "level2.css";'.encode() - else: - return None, u'a { color: red }'.encode() - - parser = cssutils.CSSParser(fetcher=fetcher) - - sheet = parser.parseString('@charset "iso-8859-1";@import "level1.css";') - self.assertEqual(sheet.encoding, 'iso-8859-1') - - sheet = sheet.cssRules[1].styleSheet - self.assertEqual(sheet.encoding, 'ascii') - - sheet = sheet.cssRules[1].styleSheet - self.assertEqual(sheet.encoding, 'ascii') - - def test_incomplete(self): - "CSSImportRule (incomplete)" - tests = { - u'@import "x.css': u'@import "x.css";', - u"@import 'x": u'@import "x";', - # TODO: - u"@import url(x": u'@import url(x);', - u"@import url('x": u'@import url(x);', - u'@import url("x;': u'@import url("x;");', - u'@import url( "x;': u'@import url("x;");', - u'@import url("x ': u'@import url("x ");', - u'@import url(x ': u'@import url(x);', - u'''@import "a - @import "b"; - @import "c";''': u'@import "c";' - } - self.do_equal_p(tests, raising=False) # parse - - def test_InvalidModificationErr(self): - "CSSImportRule.cssText InvalidModificationErr" - self._test_InvalidModificationErr(u'@import') - - def test_reprANDstr(self): - "CSSImportRule.__repr__(), .__str__()" - href = 'x.css' - mediaText = 'tv, print' - name = 'name' - s = cssutils.css.CSSImportRule(href=href, mediaText=mediaText, name=name) - - # str(): mediaText nor name are present here - self.assert_(href in str(s)) - - # repr() - s2 = eval(repr(s)) - self.assert_(isinstance(s2, s.__class__)) - self.assert_(href == s2.href) - self.assert_(mediaText == s2.media.mediaText) - self.assert_(name == s2.name) - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_cssmediarule.py cssutils-0.9.10/src/tests/test_cssmediarule.py --- cssutils-0.9.10~b1/src/tests/test_cssmediarule.py 2011-07-26 18:22:54.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_cssmediarule.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,370 +0,0 @@ -"""Testcases for cssutils.css.CSSMediaRule""" - -import xml.dom -import test_cssrule -import cssutils - -class CSSMediaRuleTestCase(test_cssrule.CSSRuleTestCase): - - def setUp(self): - super(CSSMediaRuleTestCase, self).setUp() - self.r = cssutils.css.CSSMediaRule() - self.rRO = cssutils.css.CSSMediaRule(readonly=True) - self.r_type = cssutils.css.CSSMediaRule.MEDIA_RULE - self.r_typeString = 'MEDIA_RULE' - # for tests - self.stylerule = cssutils.css.CSSStyleRule() - self.stylerule.cssText = u'a {}' - - def test_init(self): - "CSSMediaRule.__init__()" - super(CSSMediaRuleTestCase, self).test_init() - - r = cssutils.css.CSSMediaRule() - self.assertEqual(cssutils.css.CSSRuleList, type(r.cssRules)) - self.assertEqual([], r.cssRules) - self.assertEqual(u'', r.cssText) - self.assertEqual(cssutils.stylesheets.MediaList, type(r.media)) - self.assertEqual('all', r.media.mediaText) - self.assertEqual(None, r.name) - - r = cssutils.css.CSSMediaRule(mediaText='print', name='name') - self.assertEqual(cssutils.css.CSSRuleList, type(r.cssRules)) - self.assertEqual([], r.cssRules) - self.assertEqual(u'', r.cssText) - self.assertEqual(cssutils.stylesheets.MediaList, type(r.media)) - self.assertEqual('print', r.media.mediaText) - self.assertEqual('name', r.name) - - # only possible to set @... similar name - self.assertRaises(xml.dom.InvalidModificationErr, self.r._setAtkeyword, 'x') - - def test_iter(self): - "CSSMediaRule.__iter__()" - m = cssutils.css.CSSMediaRule() - m.cssText = '''@media all { /*1*/a { left: 0} b{ top:0} }''' - types = [cssutils.css.CSSRule.COMMENT, - cssutils.css.CSSRule.STYLE_RULE, - cssutils.css.CSSRule.STYLE_RULE] - for i, rule in enumerate(m): - self.assertEqual(rule, m.cssRules[i]) - self.assertEqual(rule.type, types[i]) - self.assertEqual(rule.parentRule, m) - - def test_refs(self): - """CSSStylesheet references""" - s = cssutils.parseString('@media all {a {color: red}}') - r = s.cssRules[0] - rules = r.cssRules - self.assertEqual(r.cssRules[0].parentStyleSheet, s) - self.assertEqual(rules[0].parentStyleSheet, s) - - # set cssText - r.cssText = '@media all {a {color: blue}}' - # not anymore: self.assertEqual(rules, r.cssRules) - - # set cssRules - r.cssRules = cssutils.parseString(''' - /**/ - @x; - b {}').cssRules''').cssRules - # new object - self.assertNotEqual(rules, r.cssRules) - for i, sr in enumerate(r.cssRules): - self.assertEqual(sr.parentStyleSheet, s) - self.assertEqual(sr.parentRule, r) - - def test_cssRules(self): - "CSSMediaRule.cssRules" - r = cssutils.css.CSSMediaRule() - self.assertEqual([], r.cssRules) - sr = cssutils.css.CSSStyleRule() - r.cssRules.append(sr) - self.assertEqual([sr], r.cssRules) - ir = cssutils.css.CSSImportRule() - self.assertRaises(xml.dom.HierarchyRequestErr, r.cssRules.append, ir) - - s = cssutils.parseString('@media all { /*1*/a {x:1} }') - m = s.cssRules[0] - self.assertEqual(2, m.cssRules.length) - del m.cssRules[0] - self.assertEqual(1, m.cssRules.length) - m.cssRules.append('/*2*/') - self.assertEqual(2, m.cssRules.length) - m.cssRules.extend(cssutils.parseString('/*3*/x {y:2}').cssRules) - self.assertEqual(4, m.cssRules.length) - self.assertEqual(u'@media all {\n a {\n x: 1\n }\n /*2*/\n /*3*/\n x {\n y: 2\n }\n }', - m.cssText) - - for rule in m.cssRules: - self.assertEqual(rule.parentStyleSheet, s) - self.assertEqual(rule.parentRule, m) - - def test_cssText(self): - "CSSMediaRule.cssText" - tests = { - u'''@media all "name"{}''': u'', - u'''@media all {}''': u'', - u'''@media/*x*/all{}''': u'', - u'''@media all { a{ x: 1} }''': u'''@media all {\n a {\n x: 1\n }\n }''', - u'''@media all "name" { a{ x: 1} }''': u'''@media all "name" {\n a {\n x: 1\n }\n }''', - u'''@MEDIA all { a{x:1} }''': u'''@media all {\n a {\n x: 1\n }\n }''', - u'''@\\media all { a{x:1} }''': u'''@media all {\n a {\n x: 1\n }\n }''', - u'''@media all {@x some;a{color: red;}b{color: green;}}''': - u'''@media all { - @x some; - a { - color: red - } - b { - color: green - } - }''', - u'@media all { @x{}}': u'@media all {\n @x {\n }\n }', - u'@media all "n" /**/ { @x{}}': - u'@media all "n" /**/ {\n @x {\n }\n }', - # comments - u'@media/*1*//*2*/all/*3*//*4*/{/*5*/a{x:1}}': - u'@media /*1*/ /*2*/ all /*3*/ /*4*/ {\n /*5*/\n a {\n x: 1\n }\n }', - u'@media /*1*/ /*2*/ all /*3*/ /*4*/ { /*5*/ a{ x: 1} }': - u'@media /*1*/ /*2*/ all /*3*/ /*4*/ {\n /*5*/\n a {\n x: 1\n }\n }', - # WS - u'@media\n\t\f all\n\t\f {\n\t\f a{ x: 1}\n\t\f }': - u'@media all {\n a {\n x: 1\n }\n }', - } - self.do_equal_p(tests) - self.do_equal_r(tests) - - tests = { - u'@media {}': xml.dom.SyntaxErr, - u'@media;': xml.dom.SyntaxErr, - u'@media/*only comment*/{}': xml.dom.SyntaxErr, - u'@media all;': xml.dom.SyntaxErr, - u'@media all "n";': xml.dom.SyntaxErr, - u'@media all; @x{}': xml.dom.SyntaxErr, - u'@media { a{ x: 1} }': xml.dom.SyntaxErr, - u'@media "name" { a{ x: 1} }': xml.dom.SyntaxErr, - u'@media "name" all { a{ x: 1} }': xml.dom.SyntaxErr, - u'@media all { @charset "x"; a{}}': xml.dom.HierarchyRequestErr, - u'@media all { @import "x"; a{}}': xml.dom.HierarchyRequestErr, - u'@media all { @media all {} }': xml.dom.HierarchyRequestErr, - u'@media all { , }': xml.dom.SyntaxErr, - u'@media all {}EXTRA': xml.dom.SyntaxErr, - } - self.do_raise_p(tests) - self.do_raise_r(tests) - - tests = { - # extra stuff - '@media all { x{} } a{}': xml.dom.SyntaxErr, - } - self.do_raise_r(tests) - - m = cssutils.css.CSSMediaRule() - m.cssText = u'''@media all {@x; /*1*/a{color: red;}}''' - for r in m.cssRules: - self.assertEqual(m, r.parentRule) - self.assertEqual(m.parentStyleSheet, r.parentStyleSheet) - - cssutils.ser.prefs.useDefaults() - - def test_media(self): - "CSSMediaRule.media" - # see CSSImportRule.media - - # setting not allowed - self.assertRaises(AttributeError, - self.r.__setattr__, 'media', None) - self.assertRaises(AttributeError, - self.r.__setattr__, 'media', 0) - - # set mediaText instead - self.r.media.mediaText = 'print' - self.r.insertRule(self.stylerule) - self.assertEqual(u'', self.r.cssText) - cssutils.ser.prefs.keepEmptyRules = True - self.assertEqual(u'@media print {\n a {}\n }', self.r.cssText) - cssutils.ser.prefs.useDefaults() - - def test_name(self): - "CSSMediaRule.name" - r = cssutils.css.CSSMediaRule() - r.cssText = '@media all "\\n\\"ame" {a{left: 0}}' - - self.assertEqual('\\n"ame', r.name) - r.name = "n" - self.assertEqual('n', r.name) - self.assertEqual(u'@media all "n" {\n a {\n left: 0\n }\n }', - r.cssText) - r.name = '"' - self.assertEqual('"', r.name) - self.assertEqual(u'@media all "\\"" {\n a {\n left: 0\n }\n }', - r.cssText) - - r.name = '' - self.assertEqual(None, r.name) - self.assertEqual(u'@media all {\n a {\n left: 0\n }\n }', - r.cssText) - - r.name = None - self.assertEqual(None, r.name) - self.assertEqual(u'@media all {\n a {\n left: 0\n }\n }', - r.cssText) - - self.assertRaises(xml.dom.SyntaxErr, r._setName, 0) - self.assertRaises(xml.dom.SyntaxErr, r._setName, 123) - - def test_deleteRuleIndex(self): - "CSSMediaRule.deleteRule(index)" - # see CSSStyleSheet.deleteRule - m = cssutils.css.CSSMediaRule() - m.cssText = u'''@media all { - @a; - /* x */ - @b; - @c; - @d; - }''' - self.assertEqual(5, m.cssRules.length) - self.assertRaises(xml.dom.IndexSizeErr, m.deleteRule, 5) - - # end -1 - # check parentRule - r = m.cssRules[-1] - self.assertEqual(m, r.parentRule) - m.deleteRule(-1) - self.assertEqual(None, r.parentRule) - - self.assertEqual(4, m.cssRules.length) - self.assertEqual( - u'@media all {\n @a;\n /* x */\n @b;\n @c;\n }', m.cssText) - # beginning - m.deleteRule(0) - self.assertEqual(3, m.cssRules.length) - self.assertEqual(u'@media all {\n /* x */\n @b;\n @c;\n }', m.cssText) - # middle - m.deleteRule(1) - self.assertEqual(2, m.cssRules.length) - self.assertEqual(u'@media all {\n /* x */\n @c;\n }', m.cssText) - # end - m.deleteRule(1) - self.assertEqual(1, m.cssRules.length) - self.assertEqual(u'@media all {\n /* x */\n }', m.cssText) - - def test_deleteRule(self): - "CSSMediaRule.deleteRule(rule)" - m = cssutils.css.CSSMediaRule() - m.cssText='''@media all { - a { color: red; } - b { color: blue; } - c { color: green; } - }''' - s1, s2, s3 = m.cssRules - - r = cssutils.css.CSSStyleRule() - self.assertRaises(xml.dom.IndexSizeErr, m.deleteRule, r) - - self.assertEqual(3, m.cssRules.length) - m.deleteRule(s2) - self.assertEqual(2, m.cssRules.length) - self.assertEqual(m.cssText, '@media all {\n a {\n color: red\n }\n c {\n color: green\n }\n }') - self.assertRaises(xml.dom.IndexSizeErr, m.deleteRule, s2) - - def test_add(self): - "CSSMediaRule.add()" - # see CSSStyleSheet.add - r = cssutils.css.CSSMediaRule() - stylerule1 = cssutils.css.CSSStyleRule() - stylerule2 = cssutils.css.CSSStyleRule() - r.add(stylerule1) - r.add(stylerule2) - self.assertEqual(r.cssRules[0], stylerule1) - self.assertEqual(r.cssRules[1], stylerule2) - - def test_insertRule(self): - "CSSMediaRule.insertRule" - # see CSSStyleSheet.insertRule - r = cssutils.css.CSSMediaRule() - charsetrule = cssutils.css.CSSCharsetRule('ascii') - importrule = cssutils.css.CSSImportRule('x') - namespacerule = cssutils.css.CSSNamespaceRule() - pagerule = cssutils.css.CSSPageRule() - mediarule = cssutils.css.CSSMediaRule() - unknownrule = cssutils.css.CSSUnknownRule('@x;') - stylerule = cssutils.css.CSSStyleRule('a') - stylerule.cssText = u'a { x: 1}' - comment1 = cssutils.css.CSSComment(u'/*1*/') - comment2 = cssutils.css.CSSComment(u'/*2*/') - - # hierarchy - self.assertRaises(xml.dom.HierarchyRequestErr, - r.insertRule, charsetrule, 0) - self.assertRaises(xml.dom.HierarchyRequestErr, - r.insertRule, importrule, 0) - self.assertRaises(xml.dom.HierarchyRequestErr, - r.insertRule, namespacerule, 0) - self.assertRaises(xml.dom.HierarchyRequestErr, - r.insertRule, pagerule, 0) - self.assertRaises(xml.dom.HierarchyRequestErr, - r.insertRule, mediarule, 0) - - # start insert - r.insertRule(stylerule, 0) - self.assertEqual(r, stylerule.parentRule) - self.assertEqual(r.parentStyleSheet, stylerule.parentStyleSheet) - # before - r.insertRule(comment1, 0) - self.assertEqual(r, comment1.parentRule) - self.assertEqual(r.parentStyleSheet, stylerule.parentStyleSheet) - # end explicit - r.insertRule(unknownrule, 2) - self.assertEqual(r, unknownrule.parentRule) - self.assertEqual(r.parentStyleSheet, stylerule.parentStyleSheet) - # end implicit - r.insertRule(comment2) - self.assertEqual(r, comment2.parentRule) - self.assertEqual(r.parentStyleSheet, stylerule.parentStyleSheet) - self.assertEqual( - '@media all {\n /*1*/\n a {\n x: 1\n }\n @x;\n /*2*/\n }', - r.cssText) - - # index - self.assertRaises(xml.dom.IndexSizeErr, - r.insertRule, stylerule, -1) - self.assertRaises(xml.dom.IndexSizeErr, - r.insertRule, stylerule, r.cssRules.length + 1) - - def test_InvalidModificationErr(self): - "CSSMediaRule.cssText InvalidModificationErr" - self._test_InvalidModificationErr(u'@media') - - def test_incomplete(self): - "CSSMediaRule (incomplete)" - tests = { - u'@media all { @unknown;': # no } - u'@media all {\n @unknown;\n }', - u'@media all { a {x:"1"}': # no } - u'@media all {\n a {\n x: "1"\n }\n }', - u'@media all { a {x:"1"': # no }} - u'@media all {\n a {\n x: "1"\n }\n }', - u'@media all { a {x:"1': # no "}} - u'@media all {\n a {\n x: "1"\n }\n }', - } - self.do_equal_p(tests) # parse - - def test_reprANDstr(self): - "CSSMediaRule.__repr__(), .__str__()" - mediaText='tv, print' - - s = cssutils.css.CSSMediaRule(mediaText=mediaText) - - self.assert_(mediaText in str(s)) - - s2 = eval(repr(s)) - self.assert_(isinstance(s2, s.__class__)) - self.assert_(mediaText == s2.media.mediaText) - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_cssnamespacerule.py cssutils-0.9.10/src/tests/test_cssnamespacerule.py --- cssutils-0.9.10~b1/src/tests/test_cssnamespacerule.py 2011-07-26 18:22:54.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_cssnamespacerule.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,232 +0,0 @@ -"""Testcases for cssutils.css.CSSImportRule""" - -import xml.dom -import test_cssrule -import cssutils - -class CSSNamespaceRuleTestCase(test_cssrule.CSSRuleTestCase): - - def setUp(self): - super(CSSNamespaceRuleTestCase, self).setUp() - self.r = cssutils.css.CSSNamespaceRule(namespaceURI='x') - #self.rRO = cssutils.css.CSSNamespaceRule(namespaceURI='x', - # readonly=True) - self.r_type = cssutils.css.CSSRule.NAMESPACE_RULE - self.r_typeString = 'NAMESPACE_RULE' - - def test_init(self): - "CSSNamespaceRule.__init__()" - # cannot use here as self.r and self rRO and not useful - #super(CSSNamespaceRuleTestCase, self).test_init() - tests = [ - (None, None), - ('', ''), - (None, u''), - (u'', None), - (u'', u'no-uri'), - ] - for uri, p in tests: - r = cssutils.css.CSSNamespaceRule(namespaceURI=uri, prefix=p) - self.assertEqual(None, r.namespaceURI) - self.assertEqual(u'', r.prefix) - self.assertEqual(u'', r.cssText) - self.assertEqual(None, r.parentStyleSheet) - self.assertEqual(None, r.parentRule) - - r = cssutils.css.CSSNamespaceRule(namespaceURI='example') - self.assertEqual('example', r.namespaceURI) - self.assertEqual(u'', r.prefix) - self.assertEqual(u'@namespace "example";', r.cssText) - self.sheet.add(r) - self.assertEqual(self.sheet, r.parentStyleSheet) - - r = cssutils.css.CSSNamespaceRule(namespaceURI='example', prefix='p') - self.assertEqual('example', r.namespaceURI) - self.assertEqual(u'p', r.prefix) - self.assertEqual(u'@namespace p "example";', r.cssText) - - css = u'@namespace p "u";' - r = cssutils.css.CSSNamespaceRule(cssText=css) - self.assertEqual(r.cssText, css) - - # only possible to set @... similar name - self.assertRaises(xml.dom.InvalidModificationErr, self.r._setAtkeyword, 'x') - - def test_cssText(self): - "CSSNamespaceRule.cssText" - # cssText may only be set initalially - r = cssutils.css.CSSNamespaceRule() - css = u'@namespace p "u";' - r.cssText = css - self.assertEqual(r.cssText, css) - self.assertRaises(xml.dom.NoModificationAllowedErr, r._setCssText, - u'@namespace p "OTHER";') - - tests = { - u'@namespace "";': None, - u'@namespace "u";': None, - u'@namespace p "u";': None, - u'@namespace empty "";': None, - - u'@namespace p "p";': None, - u"@namespace p 'u';": u'@namespace p "u";', - - u'@\\namespace p "u";': u'@namespace p "u";', - u'@NAMESPACE p "u";': u'@namespace p "u";', - - u'@namespace p "u" ;': u'@namespace p "u";', - u'@namespace p"u";': u'@namespace p "u";', - u'@namespace p "u";': u'@namespace p "u";', - - u'@namespace/*1*/"u"/*2*/;': u'@namespace /*1*/ "u" /*2*/;', - u'@namespace/*1*/p/*2*/"u"/*3*/;': u'@namespace /*1*/ p /*2*/ "u" /*3*/;', - - u'@namespace p url(u);': u'@namespace p "u";', - u'@namespace p url(\'u\');': u'@namespace p "u";', - u'@namespace p url(\"u\");': u'@namespace p "u";', - u'@namespace p url( \"u\" );': u'@namespace p "u";', - - # comments - u'@namespace/*1*//*2*/p/*3*//*4*/url(u)/*5*//*6*/;': - u'@namespace /*1*/ /*2*/ p /*3*/ /*4*/ "u" /*5*/ /*6*/;', - u'@namespace/*1*//*2*/p/*3*//*4*/"u"/*5*//*6*/;': - u'@namespace /*1*/ /*2*/ p /*3*/ /*4*/ "u" /*5*/ /*6*/;', - u'@namespace/*1*//*2*/p/*3*//*4*/url("u")/*5*//*6*/;': - u'@namespace /*1*/ /*2*/ p /*3*/ /*4*/ "u" /*5*/ /*6*/;', - - u'@namespace/*1*//*2*/url(u)/*5*//*6*/;': - u'@namespace /*1*/ /*2*/ "u" /*5*/ /*6*/;', - - # WS - u'@namespace\n\r\t\f p\n\r\t\f url(\n\r\t\f u\n\r\t\f )\n\r\t\f ;': - u'@namespace p "u";', - u'@namespace\n\r\t\f p\n\r\t\f url(\n\r\t\f "u"\n\r\t\f )\n\r\t\f ;': - u'@namespace p "u";', - u'@namespace\n\r\t\f p\n\r\t\f "str"\n\r\t\f ;': - u'@namespace p "str";', - u'@namespace\n\r\t\f "str"\n\r\t\f ;': - u'@namespace "str";' - } - self.do_equal_p(tests) - #self.do_equal_r(tests) # cannot use here as always new r is needed - for test, expected in tests.items(): - r = cssutils.css.CSSNamespaceRule(cssText=test) - if expected is None: - expected = test - self.assertEqual(expected, r.cssText) - - tests = { - u'@namespace;': xml.dom.SyntaxErr, # nothing - u'@namespace p;': xml.dom.SyntaxErr, # no namespaceURI - u'@namespace "u" p;': xml.dom.SyntaxErr, # order - u'@namespace "u";EXTRA': xml.dom.SyntaxErr, - u'@namespace p "u";EXTRA': xml.dom.SyntaxErr, - } - self.do_raise_p(tests) # parse - tests.update({ - u'@namespace p url(x)': xml.dom.SyntaxErr, # missing ; - u'@namespace p "u"': xml.dom.SyntaxErr, # missing ; - # trailing - u'@namespace "u"; ': xml.dom.SyntaxErr, - u'@namespace "u";/**/': xml.dom.SyntaxErr, - u'@namespace p "u"; ': xml.dom.SyntaxErr, - u'@namespace p "u";/**/': xml.dom.SyntaxErr, - }) - def _do(test): - r = cssutils.css.CSSNamespaceRule(cssText=test) - for test, expected in tests.items(): - self.assertRaises(expected, _do, test) - - def test_namespaceURI(self): - "CSSNamespaceRule.namespaceURI" - # set only initially - r = cssutils.css.CSSNamespaceRule(namespaceURI='x') - self.assertEqual(u'x' , r.namespaceURI) - self.assertEqual(u'@namespace "x";', r.cssText) - - r = cssutils.css.CSSNamespaceRule(namespaceURI='"') - self.assertEqual(u'@namespace "\\"";', r.cssText) - - self.assertRaises(xml.dom.NoModificationAllowedErr, - r._setNamespaceURI, u'x') - - self.assertRaises(xml.dom.NoModificationAllowedErr, - r._setCssText, u'@namespace "u";') - - r._replaceNamespaceURI(u'http://example.com/new') - self.assertEqual(u'http://example.com/new' , r.namespaceURI) - - def test_prefix(self): - "CSSNamespaceRule.prefix" - r = cssutils.css.CSSNamespaceRule(namespaceURI='u') - r.prefix = 'p' - self.assertEqual('p' , r.prefix) - self.assertEqual(u'@namespace p "u";', r.cssText) - - r = cssutils.css.CSSNamespaceRule(cssText='@namespace x "u";') - r.prefix = 'p' - self.assertEqual('p' , r.prefix) - self.assertEqual(u'@namespace p "u";', r.cssText) - - valid = (None, u'') - for prefix in valid: - r.prefix = prefix - self.assertEqual(r.prefix, u'') - self.assertEqual(u'@namespace "u";', r.cssText) - - valid = ('a', '_x', 'a1', 'a-1') - for prefix in valid: - r.prefix = prefix - self.assertEqual(r.prefix, prefix) - self.assertEqual(u'@namespace %s "u";' % prefix, r.cssText) - - invalid = ('1', ' x', ' ', ',') - for prefix in invalid: - self.assertRaises(xml.dom.SyntaxErr, r._setPrefix, prefix) - - def test_InvalidModificationErr(self): - "CSSNamespaceRule.cssText InvalidModificationErr" - self._test_InvalidModificationErr(u'@namespace') - - def test_incomplete(self): - "CSSNamespaceRule (incomplete)" - tests = { - u'@namespace "uri': u'@namespace "uri";', - u"@namespace url(x": u'@namespace "x";', - u"@namespace url('x": u'@namespace "x";', - u'@namespace url("x;': u'@namespace "x;";', - u'@namespace url( "x;': u'@namespace "x;";', - u'@namespace url("x ': u'@namespace "x ";', - u'@namespace url(x ': u'@namespace "x";', - } - self.do_equal_p(tests) # parse - tests = { - u'@namespace "uri': xml.dom.SyntaxErr, - u"@namespace url(x": xml.dom.SyntaxErr, - u"@namespace url('x": xml.dom.SyntaxErr, - u'@namespace url("x;': xml.dom.SyntaxErr, - u'@namespace url( "x;': xml.dom.SyntaxErr, - u'@namespace url("x ': xml.dom.SyntaxErr, - u'@namespace url(x ': xml.dom.SyntaxErr - } - self.do_raise_r(tests) # set cssText - - def test_reprANDstr(self): - "CSSNamespaceRule.__repr__(), .__str__()" - namespaceURI=u'http://example.com' - prefix=u'prefix' - - s = cssutils.css.CSSNamespaceRule(namespaceURI=namespaceURI, prefix=prefix) - - self.assert_(namespaceURI in str(s)) - self.assert_(prefix in str(s)) - - s2 = eval(repr(s)) - self.assert_(isinstance(s2, s.__class__)) - self.assert_(namespaceURI == s2.namespaceURI) - self.assert_(prefix == s2.prefix) - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_csspagerule.py cssutils-0.9.10/src/tests/test_csspagerule.py --- cssutils-0.9.10~b1/src/tests/test_csspagerule.py 2011-12-26 13:31:00.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_csspagerule.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,433 +0,0 @@ -"""Testcases for cssutils.css.CSSPageRule""" - -import xml.dom -import test_cssrule -import cssutils - -class CSSPageRuleTestCase(test_cssrule.CSSRuleTestCase): - - def setUp(self): - super(CSSPageRuleTestCase, self).setUp() - - cssutils.ser.prefs.useDefaults() - self.r = cssutils.css.CSSPageRule() - self.rRO = cssutils.css.CSSPageRule(readonly=True) - self.r_type = cssutils.css.CSSPageRule.PAGE_RULE# - self.r_typeString = 'PAGE_RULE' - - def tearDown(self): - cssutils.ser.prefs.useDefaults() - - def test_init(self): - "CSSPageRule.__init__()" - super(CSSPageRuleTestCase, self).test_init() - - r = cssutils.css.CSSPageRule() - self.assertEqual(u'', r.selectorText) - self.assertEqual(cssutils.css.CSSStyleDeclaration, type(r.style)) - self.assertEqual(r, r.style.parentRule) - - # until any properties - self.assertEqual(u'', r.cssText) - - # only possible to set @... similar name - self.assertRaises(xml.dom.InvalidModificationErr, self.r._setAtkeyword, 'x') - - def checkrefs(ff): - self.assertEqual(ff, ff.style.parentRule) - for p in ff.style: - self.assertEqual(ff.style, p.parent) - - checkrefs(cssutils.css.CSSPageRule( - style=cssutils.css.CSSStyleDeclaration('font-family: x'))) - - r = cssutils.css.CSSPageRule() - r.cssText = '@page { font-family: x }' - checkrefs(r) - - r = cssutils.css.CSSPageRule() - r.style.setProperty('font-family', 'y') - checkrefs(r) - - r = cssutils.css.CSSPageRule() - r.style['font-family'] = 'z' - checkrefs(r) - - r = cssutils.css.CSSPageRule() - r.style.fontFamily = 'a' - checkrefs(r) - - def test_InvalidModificationErr(self): - "CSSPageRule.cssText InvalidModificationErr" - self._test_InvalidModificationErr(u'@page') - tests = { - u'@pag {}': xml.dom.InvalidModificationErr, - } - self.do_raise_r(tests) - - def test_incomplete(self): - "CSSPageRule (incomplete)" - tests = { - u'@page :left { ': - u'', # no } and no content - u'@page :left { color: red': - u'@page :left {\n color: red\n }', # no } - } - self.do_equal_p(tests) # parse - - def test_cssText(self): - "CSSPageRule.cssText" - EXP = u'@page %s {\n margin: 0\n }' - tests = { - u'@page {}': u'', - u'@page:left{}': u'', - u'@page :right {}': u'', - u'@page {margin:0;}': u'@page {\n margin: 0\n }', - - u'@page name { margin: 0 }': EXP % u'name', - u'@page name:left { margin: 0 }': EXP % u'name:left', - u'@page name:right { margin: 0 }': EXP % u'name:right', - u'@page name:first { margin: 0 }': EXP % u'name:first', - u'@page :left { margin: 0 }': EXP % u':left', - u'@page:left { margin: 0 }': EXP % u':left', - u'@page :right { margin: 0 }': EXP % u':right', - u'@page :first { margin: 0 }': EXP % u':first', - u'@page :UNKNOWNIDENT { margin: 0 }': EXP % u':UNKNOWNIDENT', - - u'@PAGE:left{margin:0;}': u'@page :left {\n margin: 0\n }', - u'@\\page:left{margin:0;}': u'@page :left {\n margin: 0\n }', - - # comments - u'@page/*1*//*2*/:left/*3*//*4*/{margin:0;}': - u'@page /*1*/ /*2*/ :left /*3*/ /*4*/ {\n margin: 0\n }', - # WS - u'@page:left{margin:0;}': - u'@page :left {\n margin: 0\n }', - u'@page\n\r\f\t :left\n\r\f\t {margin:0;}': - u'@page :left {\n margin: 0\n }', - - # MarginRule - u'@page { @top-right { content: "2" } }': - u'@page {\n @top-right {\n content: "2"\n }\n }', - u'@page {padding: 1cm; margin: 1cm; @top-left {content: "1"}@top-right {content: "2";left: 1}}': - u'@page {\n padding: 1cm;\n margin: 1cm;\n @top-left {\n content: "1"\n }\n @top-right {\n content: "2";\n left: 1\n }\n }', - u'@page {@top-right { content: "1a"; content: "1b"; x: 1 }@top-right { content: "2"; y: 2 }}': - u'''@page {\n @top-right { - content: "1a"; - content: "1b"; - x: 1; - content: "2"; - y: 2 - }\n }''', - - } - self.do_equal_r(tests) - self.do_equal_p(tests) - - tests = { - # auto is not allowed - u'@page AUto {}': xml.dom.SyntaxErr, - u'@page AUto:left {}': xml.dom.SyntaxErr, - - u'@page : {}': xml.dom.SyntaxErr, - u'@page :/*1*/left {}': xml.dom.SyntaxErr, - u'@page : left {}': xml.dom.SyntaxErr, - u'@page :left :right {}': xml.dom.SyntaxErr, - u'@page :left a {}': xml.dom.SyntaxErr, - # no S between IDENT and PSEUDO - u'@page a :left {}': xml.dom.SyntaxErr, - - u'@page :left;': xml.dom.SyntaxErr, - u'@page :left }': xml.dom.SyntaxErr, - } - self.do_raise_p(tests) # parse - tests.update({ - # false selector - u'@page :right :left {}': xml.dom.SyntaxErr, # no } - u'@page :right X {}': xml.dom.SyntaxErr, # no } - u'@page X Y {}': xml.dom.SyntaxErr, # no } - - u'@page :left {': xml.dom.SyntaxErr, # no } - # trailing - u'@page :left {}1': xml.dom.SyntaxErr, # no } - u'@page :left {}/**/': xml.dom.SyntaxErr, # no } - u'@page :left {} ': xml.dom.SyntaxErr, # no } - }) - self.do_raise_r(tests) # set cssText - - def test_cssText2(self): - "CSSPageRule.cssText 2" - r = cssutils.css.CSSPageRule() - s = u'a:left' - r.selectorText = s - self.assertEqual(r.selectorText, s) - - st = 'size: a4' - r.style = st - self.assertEqual(r.style.cssText, st) - - # invalid selector - self.assertRaises(xml.dom.SyntaxErr, r._setStyle, '$') - self.assertEqual(r.selectorText, s) - self.assertEqual(r.style.cssText, st) - - self.assertRaises(xml.dom.SyntaxErr, r._setCssText, '@page $ { color: red }') - self.assertEqual(r.selectorText, s) - self.assertEqual(r.style.cssText, st) - - - # invalid style - self.assertRaises(xml.dom.SyntaxErr, r._setSelectorText, '$') - self.assertEqual(r.selectorText, s) - self.assertEqual(r.style.cssText, st) - - self.assertRaises(xml.dom.SyntaxErr, r._setCssText, '@page b:right { x }') - self.assertEqual(r.selectorText, s) - self.assertEqual(r.style.cssText, st) - - def test_selectorText(self): - "CSSPageRule.selectorText" - r = cssutils.css.CSSPageRule() - r.selectorText = u'a:left' - self.assertEqual(r.selectorText, u'a:left') - - tests = { - u'': u'', - u'name': None, - u':left': None, - u':right': None, - u':first': None, - u':UNKNOWNIDENT': None, - u'name:left': None, - u' :left': u':left', - u':left': u':left', - u'/*1*/:left/*a*/': u'/*1*/ :left /*a*/', - u'/*1*/ :left /*a*/ /*b*/': None, - u':left/*a*/': u':left /*a*/', - u'/*1*/:left': u'/*1*/ :left', - } - self.do_equal_r(tests, att='selectorText') - - tests = { - u':': xml.dom.SyntaxErr, - u':/*1*/left': xml.dom.SyntaxErr, - u': left': xml.dom.SyntaxErr, - u':left :right': xml.dom.SyntaxErr, - u':left a': xml.dom.SyntaxErr, - u'name :left': xml.dom.SyntaxErr, - } - self.do_raise_r(tests, att='_setSelectorText') - - def test_specificity(self): - "CSSPageRule.specificity" - r = cssutils.css.CSSPageRule() - tests = { - u'': (0, 0, 0), - u'name': (1, 0, 0), - u':first': (0, 1, 0), - u':left': (0, 0, 1), - u':right': (0, 0, 1), - u':UNKNOWNIDENT': (0, 0, 1), - u'name:first': (1, 1, 0), - u'name:left': (1, 0, 1), - u'name:right': (1, 0, 1), - u'name:X': (1, 0, 1) - } - for sel, exp in tests.items(): - r.selectorText = sel - self.assertEqual(r.specificity, exp) - - r = cssutils.css.CSSPageRule() - r.cssText = u'@page %s {}' % sel - self.assertEqual(r.specificity, exp) - - def test_cssRules(self): - "CSSPageRule.cssRules" - s = cssutils.parseString(u'@page {}') - p = s.cssRules[0] - - self.assertEqual(len(p.cssRules), 0) - - # add and insert - m1 = cssutils.css.MarginRule(u'@top-left', u'color: red') - i = p.add(m1) - self.assertEqual(i, 0) - self.assertEqual(len(p.cssRules), 1) - - m3 = cssutils.css.MarginRule() - m3.cssText = u'@top-right { color: blue }' - i = p.insertRule(m3) - self.assertEqual(i, 1) - self.assertEqual(len(p.cssRules), 2) - - m2 = cssutils.css.MarginRule() - m2.margin = u'@top-center' - m2.style = u'color: green' - i = p.insertRule(m2, 1) - self.assertEqual(i, 1) - self.assertEqual(len(p.cssRules), 3) - - self.assertEqual(p.cssText, u'''@page { - @top-left { - color: red - } - @top-center { - color: green - } - @top-right { - color: blue - } - }''') - - # keys and dict index - self.assertEqual(u'@top-left' in p, True) - self.assertEqual(u'@bottom-left' in p, False) - - self.assertEqual(p.keys(), [u'@top-left', - u'@top-center', - u'@top-right']) - - self.assertEqual(p[u'@bottom-left'], None) - self.assertEqual(p[u'@top-left'].cssText, u'color: red') - p[u'@top-left'] = u'color: #f00' - self.assertEqual(p[u'@top-left'].cssText, u'color: #f00') - - # delete - p.deleteRule(m2) - self.assertEqual(len(p.cssRules), 2) - self.assertEqual(p.cssText, u'''@page { - @top-left { - color: #f00 - } - @top-right { - color: blue - } - }''') - - p.deleteRule(0) - self.assertEqual(len(p.cssRules), 1) - self.assertEqual(m3, p.cssRules[0]) - self.assertEqual(p.cssText, u'''@page { - @top-right { - color: blue - } - }''') - - del p['@top-right'] - self.assertEqual(len(p.cssRules), 0) - - - def test_style(self): - "CSSPageRule.style (and references)" - r = cssutils.css.CSSPageRule() - s1 = r.style - self.assertEqual(r, s1.parentRule) - self.assertEqual(u'', s1.cssText) - - # set rule.cssText - r.cssText = '@page { font-family: x1 }' - self.failIfEqual(r.style, s1) - self.assertEqual(r, r.style.parentRule) - self.assertEqual(r.cssText, u'@page {\n font-family: x1\n }') - self.assertEqual(r.style.cssText, u'font-family: x1') - self.assertEqual(s1.cssText, u'') - s2 = r.style - - # set invalid rule.cssText - try: - r.cssText = '@page { $ }' - except xml.dom.SyntaxErr, e: - pass - self.assertEqual(r.style, s2) - self.assertEqual(r, r.style.parentRule) - self.assertEqual(r.cssText, u'@page {\n font-family: x1\n }') - self.assertEqual(r.style.cssText, u'font-family: x1') - self.assertEqual(s2.cssText, u'font-family: x1') - s3 = r.style - - # set rule.style.cssText - r.style.cssText = 'font-family: x2' - self.assertEqual(r.style, s3) - self.assertEqual(r, r.style.parentRule) - self.assertEqual(r.cssText, u'@page {\n font-family: x2\n }') - self.assertEqual(r.style.cssText, u'font-family: x2') - - # set new style object s2 - s2 = cssutils.css.CSSStyleDeclaration('font-family: y1') - r.style = s2 - self.assertEqual(r.style, s2) - self.assertEqual(r, s2.parentRule) - self.assertEqual(r.cssText, u'@page {\n font-family: y1\n }') - self.assertEqual(s2.cssText, u'font-family: y1') - self.assertEqual(r.style.cssText, u'font-family: y1') - self.assertEqual(s3.cssText, u'font-family: x2') # old - - # set s2.cssText - s2.cssText = 'font-family: y2' - self.assertEqual(r.style, s2) - self.assertEqual(r.cssText, u'@page {\n font-family: y2\n }') - self.assertEqual(r.style.cssText, u'font-family: y2') - self.assertEqual(s3.cssText, u'font-family: x2') # old - # set invalid s2.cssText - try: - s2.cssText = '$' - except xml.dom.SyntaxErr, e: - pass - self.assertEqual(r.style, s2) - self.assertEqual(r.cssText, u'@page {\n font-family: y2\n }') - self.assertEqual(r.style.cssText, u'font-family: y2') - self.assertEqual(s3.cssText, u'font-family: x2') # old - - # set r.style with text - r.style = 'font-family: z' - self.failIfEqual(r.style, s2) - self.assertEqual(r.cssText, u'@page {\n font-family: z\n }') - self.assertEqual(r.style.cssText, u'font-family: z') - - def test_properties(self): - "CSSPageRule.style properties" - r = cssutils.css.CSSPageRule() - r.style.cssText = ''' - margin-top: 0; - margin-right: 0; - margin-bottom: 0; - margin-left: 0; - margin: 0; - - page-break-before: auto; - page-break-after: auto; - page-break-inside: auto; - - orphans: 3; - widows: 3; - ''' - exp = u'''@page { - margin-top: 0; - margin-right: 0; - margin-bottom: 0; - margin-left: 0; - margin: 0; - page-break-before: auto; - page-break-after: auto; - page-break-inside: auto; - orphans: 3; - widows: 3 - }''' - self.assertEqual(exp, r.cssText) - - def test_reprANDstr(self): - "CSSPageRule.__repr__(), .__str__()" - sel=u':left' - - s = cssutils.css.CSSPageRule(selectorText=sel) - - self.assert_(sel in str(s)) - - s2 = eval(repr(s)) - self.assert_(isinstance(s2, s.__class__)) - self.assert_(sel == s2.selectorText) - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_cssproperties.py cssutils-0.9.10/src/tests/test_cssproperties.py --- cssutils-0.9.10~b1/src/tests/test_cssproperties.py 2011-07-26 18:22:54.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_cssproperties.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,63 +0,0 @@ -"""Testcases for cssutils.css.cssproperties.""" - -import xml.dom -import basetest -import cssutils.css -import cssutils.profiles - -class CSSPropertiesTestCase(basetest.BaseTestCase): - -# def test_cssvalues(self): -# "cssproperties cssvalues" -# # does actually return match object, so a very simplified test... -# match = cssutils.css.cssproperties.cssvalues -# -# self.assertEquals(True, bool(match['color']('red'))) -# self.assertEquals(False, bool(match['top']('red'))) -# -# self.assertEquals(True, bool(match['left']('0'))) -# self.assertEquals(True, bool(match['left']('1px'))) -# self.assertEquals(True, bool(match['left']('.1px'))) -# self.assertEquals(True, bool(match['left']('-1px'))) -# self.assertEquals(True, bool(match['left']('-.1px'))) -# self.assertEquals(True, bool(match['left']('-0.1px'))) - - def test_toDOMname(self): - "cssproperties _toDOMname(CSSname)" - _toDOMname = cssutils.css.cssproperties._toDOMname - - self.assertEquals('color', _toDOMname('color')) - self.assertEquals('fontStyle', _toDOMname('font-style')) - self.assertEquals('MozOpacity', _toDOMname('-moz-opacity')) - self.assertEquals('UNKNOWN', _toDOMname('UNKNOWN')) - self.assertEquals('AnUNKNOWN', _toDOMname('-anUNKNOWN')) - - def test_toCSSname(self): - "cssproperties _toCSSname(DOMname)" - _toCSSname = cssutils.css.cssproperties._toCSSname - - self.assertEquals('color', _toCSSname('color')) - self.assertEquals('font-style', _toCSSname('fontStyle')) - self.assertEquals('-moz-opacity', _toCSSname('MozOpacity')) - self.assertEquals('UNKNOWN', _toCSSname('UNKNOWN')) - self.assertEquals('-anUNKNOWN', _toCSSname('AnUNKNOWN')) - - def test_CSS2Properties(self): - "CSS2Properties" - CSS2Properties = cssutils.css.cssproperties.CSS2Properties - self.assertEquals(type(property()), type(CSS2Properties.color)) - self.assertEquals(sum([len(x) for x in cssutils.profiles.properties.values()]), - len(CSS2Properties._properties)) - - c2 = CSS2Properties() - # CSS2Properties has simplified implementation return always None - self.assertEquals(None, c2.color) - self.assertEquals(None, c2.__setattr__('color', 1)) - self.assertEquals(None, c2.__delattr__('color')) - # only defined properties - self.assertRaises(AttributeError, c2.__getattribute__, 'UNKNOWN') - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_cssrule.py cssutils-0.9.10/src/tests/test_cssrule.py --- cssutils-0.9.10~b1/src/tests/test_cssrule.py 2011-12-25 16:38:24.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_cssrule.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,238 +0,0 @@ -"""Testcases for cssutils.css.CSSRule""" - -import xml.dom -import basetest -import cssutils.css - -class CSSRuleTestCase(basetest.BaseTestCase): - """ - base class for all CSSRule subclass tests - - overwrite setUp with the appriopriate values, will be used in - test_init and test_readonly - overwrite all tests as you please, use:: - - super(CLASSNAME, self).test_TESTNAME(params) - - to use the base class tests too - """ - def setUp(self): - """ - OVERWRITE! - self.r is the rule - self.rRO the readonly rule - relf.r_type the type as defined in CSSRule - """ - super(CSSRuleTestCase, self).setUp() - - self.sheet = cssutils.css.CSSStyleSheet() - self.r = cssutils.css.CSSRule() - self.rRO = cssutils.css.CSSRule() - self.rRO._readonly = True # must be set here! - self.r_type = cssutils.css.CSSRule.UNKNOWN_RULE - self.r_typeString = 'UNKNOWN_RULE' - - def tearDown(self): - cssutils.ser.prefs.useDefaults() - - def test_init(self): - "CSSRule.type and init" - self.assertEqual(self.r_type, self.r.type) - self.assertEqual(self.r_typeString, self.r.typeString) - self.assertEqual(u'', self.r.cssText) - self.assertEqual(None, self.r.parentRule) - self.assertEqual(None, self.r.parentStyleSheet) - - def test_parentRule_parentStyleSheet_type(self): - "CSSRule.parentRule .parentStyleSheet .type" - rules = [ - ('@charset "ascii";', cssutils.css.CSSRule.CHARSET_RULE), - ('@import "x";', cssutils.css.CSSRule.IMPORT_RULE), - ('@namespace "x";', cssutils.css.CSSRule.NAMESPACE_RULE), - ('@font-face { src: url(x) }', cssutils.css.CSSRule.FONT_FACE_RULE), - ('''@media all { - @x; - a { color: red } - /* c */ - }''', cssutils.css.CSSRule.MEDIA_RULE), - ('@page :left { color: red }', cssutils.css.CSSRule.PAGE_RULE), - ('@unknown;', cssutils.css.CSSRule.UNKNOWN_RULE), - ('b { left: 0 }', cssutils.css.CSSRule.STYLE_RULE), - ('/*1*/', cssutils.css.CSSRule.COMMENT) # must be last for add test - ] - mrt = [cssutils.css.CSSRule.UNKNOWN_RULE, - cssutils.css.CSSRule.STYLE_RULE, - cssutils.css.CSSRule.COMMENT] - def test(s): - for i, rule in enumerate(s): - self.assertEqual(rule.parentRule, None) - self.assertEqual(rule.parentStyleSheet, s) - #self.assertEqual(rule.type, rules[i][1]) - if rule.MEDIA_RULE == rule.type: - for j, r in enumerate(rule): - self.assertEqual(r.parentRule, rule) - self.assertEqual(r.parentStyleSheet, s) - self.assertEqual(r.type, mrt[j]) - - if i == 0: # check encoding - self.assertEqual('ascii', s.encoding) - elif i == 2: # check namespaces - self.assertEqual('x', s.namespaces['']) - - cssText = u''.join(r[0] for r in rules) - # parsing - s = cssutils.parseString(cssText) - test(s) - # sheet.cssText - s = cssutils.css.CSSStyleSheet() - s.cssText = cssText - test(s) - # sheet.add CSS - s = cssutils.css.CSSStyleSheet() - for css, type_ in rules: - s.add(css) - test(s) - # sheet.insertRule CSS - s = cssutils.css.CSSStyleSheet() - for css, type_ in rules: - s.insertRule(css) - test(s) - - types = [cssutils.css.CSSCharsetRule, - cssutils.css.CSSImportRule, - cssutils.css.CSSNamespaceRule, - cssutils.css.CSSFontFaceRule, - cssutils.css.CSSMediaRule, - cssutils.css.CSSPageRule, - cssutils.css.CSSUnknownRule, - cssutils.css.CSSStyleRule, - cssutils.css.CSSComment] - # sheet.add CSSRule - s = cssutils.css.CSSStyleSheet() - for i, (css, type_) in enumerate(rules): - rule = types[i]() - rule.cssText = css - s.add(rule) - test(s) - # sheet.insertRule CSSRule - s = cssutils.css.CSSStyleSheet() - for i, (css, type_) in enumerate(rules): - rule = types[i]() - rule.cssText = css - s.insertRule(rule) - test(s) - - def test_CSSMediaRule_cssRules_parentRule_parentStyleSheet_type(self): - "CSSMediaRule.cssRules.parentRule .parentStyleSheet .type" - rules = [ - ('b { left: 0 }', cssutils.css.CSSRule.STYLE_RULE), - ('/*1*/', cssutils.css.CSSRule.COMMENT), - ('@x;', cssutils.css.CSSRule.UNKNOWN_RULE) - ] - def test(s): - mr = s.cssRules[0] - for i, rule in enumerate(mr): - self.assertEqual(rule.parentRule, mr) - self.assertEqual(rule.parentStyleSheet, s) - self.assertEqual(rule.parentStyleSheet, mr.parentStyleSheet) - self.assertEqual(rule.type, rules[i][1]) - - cssText = '@media all { %s }' % u''.join(r[0] for r in rules) - # parsing - s = cssutils.parseString(cssText) - test(s) - # sheet.cssText - s = cssutils.css.CSSStyleSheet() - s.cssText = cssText - test(s) - - def getMediaSheet(): - s = cssutils.css.CSSStyleSheet() - s.cssText = '@media all {}' - return s, s.cssRules[0] - # sheet.add CSS - s, mr = getMediaSheet() - for css, type_ in rules: - mr.add(css) - test(s) - # sheet.insertRule CSS - s, mr = getMediaSheet() - for css, type_ in rules: - mr.insertRule(css) - test(s) - - types = [cssutils.css.CSSStyleRule, - cssutils.css.CSSComment, - cssutils.css.CSSUnknownRule] - # sheet.add CSSRule - s, mr = getMediaSheet() - for i, (css, type_) in enumerate(rules): - rule = types[i]() - rule.cssText = css - mr.add(rule) - test(s) - # sheet.insertRule CSSRule - s, mr = getMediaSheet() - for i, (css, type_) in enumerate(rules): - rule = types[i]() - rule.cssText = css - mr.insertRule(rule) - test(s) - - def test_readonly(self): - "CSSRule readonly" - self.rRO = cssutils.css.CSSRule() - self.rRO._readonly = True - self.assertEqual(True, self.rRO._readonly) - self.assertEqual(u'', self.rRO.cssText) - self.assertRaises(xml.dom.NoModificationAllowedErr, - self.rRO._setCssText, u'x') - self.assertEqual(u'', self.rRO.cssText) - - def _test_InvalidModificationErr(self, startwithspace): - """ - CSSRule.cssText InvalidModificationErr - - called by subclasses - - startwithspace - - for test starting with this not the test but " test" is tested - e.g. " @page {}" - exception is the style rule test - """ - tests = (u'', - u'/* comment */', - u'@charset "utf-8";', - u'@font-face {}', - u'@import url(x);', - u'@media all {}', - u'@namespace "x";' - u'@page {}', - u'@unknown;', - u'@variables;', - # TODO: - #u'@top-left {}' - u'a style rule {}' - ) - for test in tests: - if startwithspace in (u'a style rule', ) and test in ( - u'/* comment */', u'a style rule {}'): - continue - - if test.startswith(startwithspace): - test = u' %s' % test - - self.assertRaises(xml.dom.InvalidModificationErr, - self.r._setCssText, test) - - # check that type is readonly - self.assertRaises(AttributeError, self.r.__setattr__, 'parentRule', None) - self.assertRaises(AttributeError, self.r.__setattr__, 'parentStyleSheet', None) - self.assertRaises(AttributeError, self.r.__setattr__, 'type', 1) - self.assertRaises(AttributeError, self.r.__setattr__, 'typeString', "") - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_cssrulelist.py cssutils-0.9.10/src/tests/test_cssrulelist.py --- cssutils-0.9.10~b1/src/tests/test_cssrulelist.py 2011-07-26 18:22:54.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_cssrulelist.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -"""Testcases for cssutils.css.CSSRuleList""" - -import basetest -import cssutils - -class CSSRuleListTestCase(basetest.BaseTestCase): - - def test_init(self): - "CSSRuleList.__init__()" - r = cssutils.css.CSSRuleList() - self.assertEqual(0, r.length) - self.assertEqual(None, r.item(2)) - - # subclasses list but all setting options like append, extend etc - # need to be added to an instance of this class by a using class! - self.assertRaises(NotImplementedError, r.append, 1) - - def test_rulesOfType(self): - "CSSRuleList.rulesOfType()" - s = cssutils.parseString(''' - /*c*/ - @namespace "a"; - a { color: red} - b { left: 0 }''') - - c = list(s.cssRules.rulesOfType(cssutils.css.CSSRule.COMMENT)) - self.assertEqual(1, len(c)) - self.assertEqual('/*c*/', c[0].cssText) - - r = list(s.cssRules.rulesOfType(cssutils.css.CSSRule.STYLE_RULE)) - self.assertEqual(2, len(r)) - self.assertEqual('b {\n left: 0\n }', r[1].cssText) - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_cssstyledeclaration.py cssutils-0.9.10/src/tests/test_cssstyledeclaration.py --- cssutils-0.9.10~b1/src/tests/test_cssstyledeclaration.py 2011-12-26 12:33:30.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_cssstyledeclaration.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,591 +0,0 @@ -"""Testcases for cssutils.css.cssstyledelaration.CSSStyleDeclaration.""" - -import xml.dom -import basetest -import cssutils - -class CSSStyleDeclarationTestCase(basetest.BaseTestCase): - - def setUp(self): - self.r = cssutils.css.CSSStyleDeclaration() - - def test_init(self): - "CSSStyleDeclaration.__init__()" - s = cssutils.css.CSSStyleDeclaration() - self.assertEqual(u'', s.cssText) - self.assertEqual(0, s.length) - self.assertEqual(None, s.parentRule) - - s = cssutils.css.CSSStyleDeclaration(cssText='left: 0') - self.assertEqual(u'left: 0', s.cssText) - self.assertEqual('0', s.getPropertyValue('left')) - - sheet = cssutils.css.CSSStyleRule() - s = cssutils.css.CSSStyleDeclaration(parentRule=sheet) - self.assertEqual(sheet, s.parentRule) - - # should not be used but ordered parameter test - s = cssutils.css.CSSStyleDeclaration('top: 0', sheet) - self.assertEqual(u'top: 0', s.cssText) - self.assertEqual(sheet, s.parentRule) - - def test_items(self): - "CSSStyleDeclaration[CSSName]" - s = cssutils.css.CSSStyleDeclaration() - name, value, priority = 'color', 'name', '' - s[name] = value - self.assertEqual(value, s[name]) - self.assertEqual(value, s.__getattribute__(name)) - self.assertEqual(value, s.getProperty(name).value) - self.assertEqual(priority, s.getProperty(name).priority) - - name, value, priority = 'UnKnown-ProPERTY', 'unknown value', 'important' - s[name] = (value, priority) - self.assertEqual(value, s[name]) - self.assertEqual(value, s[name.lower()]) # will be normalized - self.assertRaises(AttributeError, s.__getattribute__, name) - self.assertEqual(value, s.getProperty(name).value) - self.assertEqual(priority, s.getProperty(name).priority) - - name, value, priority = 'item', '1', '' - s[name] = value - self.assertEqual(value, s[name]) - self.assertEqual(value, s.getProperty(name).value) - self.assertEqual(priority, s.getProperty(name).priority) - - del s[name] - self.assertEqual(u'', s[name]) - self.assertEqual(u'', s['never set']) - - def test__contains__(self): - "CSSStyleDeclaration.__contains__(nameOrProperty)" - s = cssutils.css.CSSStyleDeclaration(cssText=r'x: 1;\y: 2') - for test in ('x', r'x', 'y', r'y'): - self.assert_(test in s) - self.assert_(test.upper() in s) - self.assert_(cssutils.css.Property(test, '1') in s) - self.assert_('z' not in s) - self.assert_(cssutils.css.Property('z', '1') not in s) - - def test__iter__item(self): - "CSSStyleDeclaration.__iter__ and .item" - s = cssutils.css.CSSStyleDeclaration() - s.cssText = ur''' - color: red; c\olor: blue; CO\lor: green; - left: 1px !important; left: 0; - border: 0; - ''' - # __iter__ - ps = [] - for p in s: - ps.append((p.literalname, p.value, p.priority)) - self.assertEqual(len(ps), 3) - self.assertEqual(ps[0], (ur'co\lor', 'green', '')) - self.assertEqual(ps[1], (ur'left', '1px', 'important')) - self.assertEqual(ps[2], (ur'border', '0', '')) - - # item - self.assertEqual(s.length, 3) - self.assertEqual(s.item(0), u'color') - self.assertEqual(s.item(1), u'left') - self.assertEqual(s.item(2), u'border') - self.assertEqual(s.item(10), u'') - - def test_keys(self): - "CSSStyleDeclaration.keys()" - s = cssutils.parseStyle('x:1; x:2; y:1') - self.assertEqual(['x', 'y'], s.keys()) - self.assertEqual(s['x'], '2') - self.assertEqual(s['y'], '1') - - def test_parse(self): - "CSSStyleDeclaration parse" - # error but parse - tests = { - # property names are caseinsensitive - u'TOP:0': u'top: 0', - u'top:0': u'top: 0', - # simple escape - u'c\\olor: red; color:green': u'color: green', - u'color:g\\reen': u'color: g\\reen', - # http://www.w3.org/TR/2009/CR-CSS2-20090423/syndata.html#illegalvalues - u'color:green': u'color: green', - u'color:green; color': u'color: green', - u'color:red; color; color:green': u'color: green', - u'color:green; color:': u'color: green', - u'color:red; color:; color:green': u'color: green', - u'color:green; color{;color:maroon}': u'color: green', - u'color:red; color{;color:maroon}; color:green': u'color: green', - # tantek hack - ur'''color: red; -voice-family: "\"}\""; -voice-family:inherit; -color: green;''': 'voice-family: inherit;\ncolor: green', - ur'''col\or: blue; - font-family: 'Courier New Times - color: red; - color: green;''': u'color: green', - - # special IE hacks are not preserved anymore (>=0.9.5b3) - u'/color: red; color: green': u'color: green', - u'/ color: red; color: green': u'color: green', - u'1px: red; color: green': u'color: green', - u'0: red; color: green': u'color: green', - u'1px:: red; color: green': u'color: green', - ur'$top: 0': u'', - ur'$: 0': u'', # really invalid! - # unknown rule but valid - u'@x;\ncolor: red': None, - u'@x {\n }\ncolor: red': None, - u'/**/\ncolor: red': None, - u'/**/\ncolor: red;\n/**/': None, - } - cssutils.ser.prefs.keepAllProperties = False - for test, exp in tests.items(): - sh = cssutils.parseString('a { %s }' % test) - if exp is None: - exp = u'%s' % test - elif exp != u'': - exp = u'%s' % exp - self.assertEqual(exp, sh.cssRules[0].style.cssText) - - cssutils.ser.prefs.useDefaults() - - def test_serialize(self): - "CSSStyleDeclaration serialize" - s = cssutils.css.CSSStyleDeclaration() - tests = { - u'a:1 !important; a:2;b:1': (u'a: 1 !important;\nb: 1', - u'a: 1 !important;\na: 2;\nb: 1') - } - for test, exp in tests.items(): - s.cssText = test - cssutils.ser.prefs.keepAllProperties = False - self.assertEqual(exp[0], s.cssText) - cssutils.ser.prefs.keepAllProperties = True - self.assertEqual(exp[1], s.cssText) - - cssutils.ser.prefs.useDefaults() - - def test_children(self): - "CSSStyleDeclaration.children()" - style = u'/*1*/color: red; color: green; @x;' - types = [ - cssutils.css.CSSComment, - cssutils.css.Property, - cssutils.css.Property, - cssutils.css.CSSUnknownRule - ] - def t(s): - for i, x in enumerate(s.children()): - self.assertEqual(types[i], type(x)) - self.assertEqual(x.parent, s) - - t(cssutils.parseStyle(style)) - t(cssutils.parseString(u'a {'+style+'}').cssRules[0].style) - t(cssutils.parseString(u'@media all {a {'+style+'}}').cssRules[0].cssRules[0].style) - - s = cssutils.parseStyle(style) - s['x'] = '0' - self.assertEqual(s, s.getProperty('x').parent) - s.setProperty('y', '1') - self.assertEqual(s, s.getProperty('y').parent) - - def test_cssText(self): - "CSSStyleDeclaration.cssText" - # empty - s = cssutils.css.CSSStyleDeclaration() - tests = { - u'': u'', - u' ': u'', - u' \t \n ': u'', - u'/*x*/': u'/*x*/' - } - for test, exp in tests.items(): - s.cssText = 'left: 0;' # dummy to reset s - s.cssText = test - self.assertEqual(exp, s.cssText) - - # normal - s = cssutils.css.CSSStyleDeclaration() - tests = { - u'left: 0': u'left: 0', - u'left:0': u'left: 0', - u' left : 0 ': u'left: 0', - u'left: 0;': u'left: 0', - u'left: 0 !important ': u'left: 0 !important', - u'left:0!important': u'left: 0 !important', - u'left: 0; top: 1': u'left: 0;\ntop: 1', - # comments - # TODO: spaces? - u'/*1*//*2*/left/*3*//*4*/:/*5*//*6*/0/*7*//*8*/!/*9*//*a*/important/*b*//*c*/;': - u'/*1*/\n/*2*/\nleft/*3*//*4*/: /*5*/ /*6*/ 0 /*7*/ /*8*/ !/*9*//*a*/important/*b*//*c*/', - u'/*1*/left: 0;/*2*/ top: 1/*3*/': - u'/*1*/\nleft: 0;\n/*2*/\ntop: 1 /*3*/', - u'left:0; top:1;': u'left: 0;\ntop: 1', - u'/*1*/left: 0;/*2*/ top: 1;/*3*/': - u'/*1*/\nleft: 0;\n/*2*/\ntop: 1;\n/*3*/', - # WS - u'left:0!important;margin:1px 2px 3px 4px!important;': u'left: 0 !important;\nmargin: 1px 2px 3px 4px !important', - u'\n\r\f\t left\n\r\f\t :\n\r\f\t 0\n\r\f\t !\n\r\f\t important\n\r\f\t ;\n\r\f\t margin\n\r\f\t :\n\r\f\t 1px\n\r\f\t 2px\n\r\f\t 3px\n\r\f\t 4px;': - u'left: 0 !important;\nmargin: 1px 2px 3px 4px', - } - for test, exp in tests.items(): - s.cssText = test - self.assertEqual(exp, s.cssText) - - # exception - tests = { - u'top': xml.dom.SyntaxErr, - u'top:': xml.dom.SyntaxErr, - u'top : ': xml.dom.SyntaxErr, - u'top:!important': xml.dom.SyntaxErr, - u'top:!important;': xml.dom.SyntaxErr, - u'top:;': xml.dom.SyntaxErr, - u'top 0': xml.dom.SyntaxErr, - u'top 0;': xml.dom.SyntaxErr, - - u':': xml.dom.SyntaxErr, - u':0': xml.dom.SyntaxErr, - u':0;': xml.dom.SyntaxErr, - u':0!important': xml.dom.SyntaxErr, - u':;': xml.dom.SyntaxErr, - u': ;': xml.dom.SyntaxErr, - u':!important;': xml.dom.SyntaxErr, - u': !important;': xml.dom.SyntaxErr, - - u'0': xml.dom.SyntaxErr, - u'0!important': xml.dom.SyntaxErr, - u'0!important;': xml.dom.SyntaxErr, - u'0;': xml.dom.SyntaxErr, - - u'!important': xml.dom.SyntaxErr, - u'!important;': xml.dom.SyntaxErr, - - u';': xml.dom.SyntaxErr, - } - self.do_raise_r(tests) - - def test_getCssText(self): - "CSSStyleDeclaration.getCssText(separator)" - s = cssutils.css.CSSStyleDeclaration(cssText=u'a:1;b:2') - self.assertEqual(u'a: 1;\nb: 2', s.getCssText()) - self.assertEqual(u'a: 1;b: 2', s.getCssText(separator=u'')) - self.assertEqual(u'a: 1;/*x*/b: 2', s.getCssText(separator=u'/*x*/')) - - def test_parentRule(self): - "CSSStyleDeclaration.parentRule" - s = cssutils.css.CSSStyleDeclaration() - sheet = cssutils.css.CSSStyleRule() - s.parentRule = sheet - self.assertEqual(sheet, s.parentRule) - - sheet = cssutils.parseString(u'a{x:1}') - s = sheet.cssRules[0] - d = s.style - self.assertEqual(s, d.parentRule) - - s = cssutils.parseString(''' - @font-face { - font-weight: bold; - } - a { - font-weight: bolder; - } - @page { - font-weight: bolder; - } - ''') - for r in s: - self.assertEqual(r.style.parentRule, r) - - def test_getProperty(self): - "CSSStyleDeclaration.getProperty" - s = cssutils.css.CSSStyleDeclaration() - P = cssutils.css.Property - s.cssText = ur''' - color: red; c\olor: blue; CO\lor: green; - left: 1px !important; left: 0; - border: 0; - ''' - self.assertEqual(s.getProperty('color').cssText, ur'co\lor: green') - self.assertEqual(s.getProperty(r'COLO\r').cssText, ur'co\lor: green') - self.assertEqual(s.getProperty('left').cssText, ur'left: 1px !important') - self.assertEqual(s.getProperty('border').cssText, ur'border: 0') - - def test_getProperties(self): - "CSSStyleDeclaration.getProperties()" - s = cssutils.css.CSSStyleDeclaration(cssText= - u'/*1*/y:0;x:a !important;y:1; \\x:b;') - tests = { - # name, all - (None, False): [(u'y', u'1', u''), - (u'x', u'a', u'important')], - (None, True): [(u'y', u'0', u''), - (u'x', u'a', u'important'), - (u'y', u'1', u''), - (u'\\x', u'b', u'') - ], - ('x', False): [(u'x', u'a', u'important')], - ('\\x', False): [(u'x', u'a', u'important')], - ('x', True): [(u'x', u'a', u'important'), - (u'\\x', u'b', u'')], - ('\\x', True): [(u'x', u'a', u'important'), - (u'\\x', u'b', u'')], - } - for test in tests: - name, all = test - expected = tests[test] - actual = s.getProperties(name, all) - self.assertEqual(len(expected), len(actual)) - for i, ex in enumerate(expected): - a = actual[i] - self.assertEqual(ex, (a.literalname, a.value, a.priority)) - - # order is be effective properties set - s = cssutils.css.CSSStyleDeclaration(cssText= - u'a:0;b:1;a:1') - self.assertEqual(u'ba', u''.join([p.name for p in s])) - - def test_getPropertyCSSValue(self): - "CSSStyleDeclaration.getPropertyCSSValue()" - s = cssutils.css.CSSStyleDeclaration(cssText='color: red;c\\olor: green') - self.assertEqual(u'green', s.getPropertyCSSValue('color').cssText) - self.assertEqual(u'green', s.getPropertyCSSValue('c\\olor').cssText) - self.assertEqual(u'red', s.getPropertyCSSValue('color', False).cssText) - self.assertEqual(u'green', s.getPropertyCSSValue('c\\olor', False).cssText) -# # shorthand CSSValue should be None -# SHORTHAND = [ -# u'background', -# u'border', -# u'border-left', u'border-right', -# u'border-top', u'border-bottom', -# u'border-color', u'border-style', u'border-width', -# u'cue', -# u'font', -# u'list-style', -# u'margin', -# u'outline', -# u'padding', -# u'pause'] -# for short in SHORTHAND: -# s.setProperty(short, u'inherit') -# self.assertEqual(None, s.getPropertyCSSValue(short)) - - def test_getPropertyValue(self): - "CSSStyleDeclaration.getPropertyValue()" - s = cssutils.css.CSSStyleDeclaration() - self.assertEqual(u'', s.getPropertyValue('unset')) - - s.setProperty(u'left', '0') - self.assertEqual(u'0', s.getPropertyValue('left')) - - s.setProperty(u'border', '1px solid green') - self.assertEqual(u'1px solid green', s.getPropertyValue('border')) - - s = cssutils.css.CSSStyleDeclaration(cssText='color: red;c\\olor: green') - self.assertEqual(u'green', s.getPropertyValue('color')) - self.assertEqual(u'green', s.getPropertyValue('c\\olor')) - self.assertEqual(u'red', s.getPropertyValue('color', False)) - self.assertEqual(u'green', s.getPropertyValue('c\\olor', False)) - - tests = { - ur'color: red; color: green': 'green', - ur'c\olor: red; c\olor: green': 'green', - ur'color: red; c\olor: green': 'green', - ur'color: red !important; color: green !important': 'green', - ur'color: green !important; color: red': 'green', - } - for test in tests: - s = cssutils.css.CSSStyleDeclaration(cssText=test) - self.assertEqual(tests[test], s.getPropertyValue('color')) - - def test_getPropertyPriority(self): - "CSSStyleDeclaration.getPropertyPriority()" - s = cssutils.css.CSSStyleDeclaration() - self.assertEqual(u'', s.getPropertyPriority('unset')) - - s.setProperty(u'left', u'0', u'!important') - self.assertEqual(u'important', s.getPropertyPriority('left')) - - s = cssutils.css.CSSStyleDeclaration(cssText= - 'x: 1 !important;\\x: 2;x: 3 !important;\\x: 4') - self.assertEqual(u'important', s.getPropertyPriority('x')) - self.assertEqual(u'important', s.getPropertyPriority('\\x')) - self.assertEqual(u'important', s.getPropertyPriority('x', True)) - self.assertEqual(u'', s.getPropertyPriority('\\x', False)) - - def test_removeProperty(self): - "CSSStyleDeclaration.removeProperty()" - cssutils.ser.prefs.useDefaults() - s = cssutils.css.CSSStyleDeclaration() - css = ur'\x:0 !important; x:1; \x:2; x:3' - - # normalize=True DEFAULT - s.cssText = css - self.assertEqual(u'0', s.removeProperty('x')) - self.assertEqual(u'', s.cssText) - - # normalize=False - s.cssText = css - self.assertEqual(u'3', s.removeProperty('x', normalize=False)) - self.assertEqual(ur'\x: 0 !important;\x: 2', s.getCssText(separator=u'')) - self.assertEqual(u'0', s.removeProperty(r'\x', normalize=False)) - self.assertEqual(u'', s.cssText) - - s.cssText = css - self.assertEqual(u'0', s.removeProperty(r'\x', normalize=False)) - self.assertEqual(ur'x: 1;x: 3', s.getCssText(separator=u'')) - self.assertEqual(u'3', s.removeProperty('x', normalize=False)) - self.assertEqual(u'', s.cssText) - - def test_setProperty(self): - "CSSStyleDeclaration.setProperty()" - s = cssutils.css.CSSStyleDeclaration() - s.setProperty('top', '0', '!important') - self.assertEqual('0', s.getPropertyValue('top')) - self.assertEqual('important', s.getPropertyPriority('top')) - s.setProperty('top', '1px') - self.assertEqual('1px', s.getPropertyValue('top')) - self.assertEqual('', s.getPropertyPriority('top')) - - s.setProperty('top', '2px') - self.assertEqual('2px', s.getPropertyValue('top')) - - s.setProperty('\\top', '3px') - self.assertEqual('3px', s.getPropertyValue('top')) - - s.setProperty('\\top', '4px', normalize=False) - self.assertEqual('4px', s.getPropertyValue('top')) - self.assertEqual('4px', s.getPropertyValue('\\top', False)) - self.assertEqual('3px', s.getPropertyValue('top', False)) - - # case insensitive - s.setProperty('TOP', '0', '!IMPORTANT') - self.assertEqual('0', s.getPropertyValue('top')) - self.assertEqual('important', s.getPropertyPriority('top')) - - tests = { - (u'left', u'0', u''): u'left: 0', - (u'left', u'0', u'important'): u'left: 0 !important', - (u'LEFT', u'0', u'important'): u'left: 0 !important', - (u'left', u'0', u'important'): u'left: 0 !important', - } - for test, exp in tests.items(): - s = cssutils.css.CSSStyleDeclaration() - n, v, p = test - s.setProperty(n, v, p) - self.assertEqual(exp, s.cssText) - self.assertEqual(v, s.getPropertyValue(n)) - self.assertEqual(p, s.getPropertyPriority(n)) - - # empty - s = cssutils.css.CSSStyleDeclaration() - self.assertEqual('', s.top) - s.top = '0' - self.assertEqual('0', s.top) - s.top = '' - self.assertEqual('', s.top) - s.top = None - self.assertEqual('', s.top) - - def test_setProperty(self): - "CSSStyleDeclaration.setProperty(replace=)" - s = cssutils.css.CSSStyleDeclaration() - s.setProperty('top', '1px') - self.assertEqual(len(s.getProperties('top', all=True)), 1) - - s.setProperty('top', '2px') - self.assertEqual(len(s.getProperties('top', all=True)), 1) - self.assertEqual(s.getPropertyValue('top'), '2px') - - s.setProperty('top', '3px', replace=False) - self.assertEqual(len(s.getProperties('top', all=True)), 2) - self.assertEqual(s.getPropertyValue('top'), '3px') - - def test_length(self): - "CSSStyleDeclaration.length" - s = cssutils.css.CSSStyleDeclaration() - - # cssText - s.cssText = u'left: 0' - self.assertEqual(1, s.length) - self.assertEqual(1, len(s.seq)) - s.cssText = u'/*1*/left/*x*/:/*x*/0/*x*/;/*2*/ top: 1;/*3*/' - self.assertEqual(2, s.length) - self.assertEqual(5, len(s.seq)) - - # set - s = cssutils.css.CSSStyleDeclaration() - s.setProperty('top', '0', '!important') - self.assertEqual(1, s.length) - s.setProperty('top', '1px') - self.assertEqual(1, s.length) - s.setProperty('left', '1px') - - def test_nameParameter(self): - "CSSStyleDeclaration.XXX(name)" - s = cssutils.css.CSSStyleDeclaration() - s.setProperty('top', '1px', '!important') - - self.assertEqual('1px', s.getPropertyValue('top')) - self.assertEqual('1px', s.getPropertyValue('TOP')) - self.assertEqual('1px', s.getPropertyValue('T\op')) - - self.assertEqual('important', s.getPropertyPriority('top')) - self.assertEqual('important', s.getPropertyPriority('TOP')) - self.assertEqual('important', s.getPropertyPriority('T\op')) - - s.setProperty('top', '2px', '!important') - self.assertEqual('2px', s.removeProperty('top')) - s.setProperty('top', '2px', '!important') - self.assertEqual('2px', s.removeProperty('TOP')) - s.setProperty('top', '2px', '!important') - self.assertEqual('2px', s.removeProperty('T\op')) - - def test_css2properties(self): - "CSSStyleDeclaration.$css2property get set del" - s = cssutils.css.CSSStyleDeclaration( - cssText='left: 1px;color: red; font-style: italic') - - s.color = 'green' - s.fontStyle = 'normal' - self.assertEqual('green', s.color) - self.assertEqual('normal', s.fontStyle) - self.assertEqual('green', s.getPropertyValue('color')) - self.assertEqual('normal', s.getPropertyValue('font-style')) - self.assertEqual( - u'''left: 1px;\ncolor: green;\nfont-style: normal''', - s.cssText) - - del s.color - self.assertEqual( - u'''left: 1px;\nfont-style: normal''', - s.cssText) - del s.fontStyle - self.assertEqual(u'left: 1px', s.cssText) - - self.assertRaises(AttributeError, s.__setattr__, 'UNKNOWN', 'red') - # unknown properties must be set with setProperty! - s.setProperty('UNKNOWN', 'red') - # but are still not usable as property! - self.assertRaises(AttributeError, s.__getattribute__, 'UNKNOWN') - self.assertRaises(AttributeError, s.__delattr__, 'UNKNOWN') - # but are kept - self.assertEqual('red', s.getPropertyValue('UNKNOWN')) - self.assertEqual( - '''left: 1px;\nunknown: red''', s.cssText) - - def test_reprANDstr(self): - "CSSStyleDeclaration.__repr__(), .__str__()" - s = cssutils.css.CSSStyleDeclaration(cssText='a:1;b:2') - - self.assert_("2" in str(s)) # length - - s2 = eval(repr(s)) - self.assert_(isinstance(s2, s.__class__)) - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_cssstylerule.py cssutils-0.9.10/src/tests/test_cssstylerule.py --- cssutils-0.9.10~b1/src/tests/test_cssstylerule.py 2011-07-26 18:22:54.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_cssstylerule.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,248 +0,0 @@ -"""Testcases for cssutils.css.CSSStyleRuleTestCase""" - -import xml.dom -import test_cssrule -import cssutils - -class CSSStyleRuleTestCase(test_cssrule.CSSRuleTestCase): - - def setUp(self): - super(CSSStyleRuleTestCase, self).setUp() - self.r = cssutils.css.CSSStyleRule() - self.rRO = cssutils.css.CSSStyleRule(readonly=True) - self.r_type = cssutils.css.CSSStyleRule.STYLE_RULE - self.r_typeString = 'STYLE_RULE' - - def test_init(self): - "CSSStyleRule.type and init" - super(CSSStyleRuleTestCase, self).test_init() - self.assertEqual(u'', self.r.cssText) - self.assertEqual(cssutils.css.selectorlist.SelectorList, - type(self.r.selectorList)) - self.assertEqual(u'', self.r.selectorText) - self.assertEqual(cssutils.css.CSSStyleDeclaration, - type(self.r.style)) - self.assertEqual(self.r, self.r.style.parentRule) - - def test_refs(self): - "CSSStyleRule references" - s = cssutils.css.CSSStyleRule() - sel, style = s.selectorList, s.style - - self.assertEqual(s, sel.parentRule) - self.assertEqual(s, style.parentRule) - - s.cssText = 'a { x:1 }' - self.failIfEqual(sel, s.selectorList) - self.assertEqual('a', s.selectorList.selectorText) - self.failIfEqual(style, s.style) - self.assertEqual('1', s.style.getPropertyValue('x')) - - sel, style = s.selectorList, s.style - - invalids = ('$b { x:2 }', # invalid selector - 'c { $x3 }', # invalid style - '/b { 2 }' # both invalid - ) - for invalid in invalids: - try: - s.cssText = invalid - except xml.dom.DOMException, e: - pass - self.assertEqual(sel, s.selectorList) - self.assertEqual(u'a', s.selectorList.selectorText) - self.assertEqual(style, s.style) - self.assertEqual(u'1', s.style.getPropertyValue('x')) - - # CHANGING - s = cssutils.parseString(u'a {s1: 1}') - r = s.cssRules[0] - sel1 = r.selectorList - st1 = r.style - - # selectorList - r.selectorText = 'b' - self.failIfEqual(sel1, r.selectorList) - self.assertEqual('b', r.selectorList.selectorText) - self.assertEqual('b', r.selectorText) - sel1b = r.selectorList - - sel1b.selectorText = 'c' - self.assertEqual(sel1b, r.selectorList) - self.assertEqual('c', r.selectorList.selectorText) - self.assertEqual('c', r.selectorText) - - sel2 = cssutils.css.SelectorList('sel2') - s.selectorList = sel2 - self.assertEqual(sel2, s.selectorList) - self.assertEqual('sel2', s.selectorList.selectorText) - - sel2.selectorText = 'sel2b' - self.assertEqual('sel2b', sel2.selectorText) - self.assertEqual('sel2b', s.selectorList.selectorText) - - s.selectorList.selectorText = 'sel2c' - self.assertEqual('sel2c', sel2.selectorText) - self.assertEqual('sel2c', s.selectorList.selectorText) - - # style - r.style = 's1: 2' - self.failIfEqual(st1, r.style) - self.assertEqual('s1: 2', r.style.cssText) - - st2 = cssutils.parseStyle(u's2: 1') - r.style = st2 - self.assertEqual(st2, r.style) - self.assertEqual('s2: 1', r.style.cssText) - - # cssText - sl, st = r.selectorList, r.style - # fails - try: - r.cssText = '$ {content: "new"}' - except xml.dom.SyntaxErr, e: - pass - self.assertEqual(sl, r.selectorList) - self.assertEqual(st, r.style) - - r.cssText = 'a {content: "new"}' - self.failIfEqual(sl, r.selectorList) - self.failIfEqual(st, r.style) - - def test_cssText(self): - "CSSStyleRule.cssText" - tests = { - u'* {}': u'', - u'a {}': u'', - } - self.do_equal_p(tests) # parse - #self.do_equal_r(tests) # set cssText # TODO: WHY? - - cssutils.ser.prefs.keepEmptyRules = True - tests = { - u'''a\n{color: #000}''': 'a {\n color: #000\n }', # issue 4 - u'''a\n{color: #000000}''': 'a {\n color: #000\n }', # issue 4 - u'''a\n{color: #abc}''': 'a {\n color: #abc\n }', # issue 4 - u'''a\n{color: #abcdef}''': 'a {\n color: #abcdef\n }', # issue 4 - u'''a\n{color: #00a}''': 'a {\n color: #00a\n }', # issue 4 - u'''a\n{color: #1a1a1a}''': 'a {\n color: #1a1a1a\n }', # issue 4 - u'''#id\n{ color: red }''': '#id {\n color: red\n }', # issue 3 - u'''* {}''': None, - u'a {}': None, - u'b { a: 1; }': u'b {\n a: 1\n }', - # mix of comments and properties - u'c1 {/*1*/a:1;}': u'c1 {\n /*1*/\n a: 1\n }', - u'c2 {a:1;/*2*/}': u'c2 {\n a: 1;\n /*2*/\n }', - u'd1 {/*0*/}': u'd1 {\n /*0*/\n }', - u'd2 {/*0*//*1*/}': u'd2 {\n /*0*/\n /*1*/\n }', - # comments - # TODO: spaces? - u'''a/*1*//*2*/,/*3*//*4*/b/*5*//*6*/{color: #000}''': - u'a/*1*//*2*/, /*3*//*4*/b/*5*//*6*/ {\n color: #000\n }', - - u'''a,b{color: #000}''': 'a, b {\n color: #000\n }', # issue 4 - u'''a\n\r\t\f ,\n\r\t\f b\n\r\t\f {color: #000}''': 'a, b {\n color: #000\n }', # issue 4 - } - self.do_equal_p(tests) # parse - self.do_equal_r(tests) # set cssText - - tests = { - u'''a;''': xml.dom.SyntaxErr, - u'''a {{}''': xml.dom.SyntaxErr, - u'''a }''': xml.dom.SyntaxErr, - } - self.do_raise_p(tests) # parse - tests.update({ - u'''/*x*/''': xml.dom.SyntaxErr, - u'''a {''': xml.dom.SyntaxErr, - # trailing - u'''a {}x''': xml.dom.SyntaxErr, - u'''a {/**/''': xml.dom.SyntaxErr, - u'''a {} ''': xml.dom.SyntaxErr, - }) - self.do_raise_r(tests) # set cssText - cssutils.ser.prefs.useDefaults() - - def test_selectorList(self): - "CSSStyleRule.selectorList" - r = cssutils.css.CSSStyleRule() - - r.selectorList.appendSelector(u'a') - self.assertEqual(1, r.selectorList.length) - self.assertEqual(u'a', r.selectorText) - - r.selectorList.appendSelector(u' b ') - # only simple selector! - self.assertRaises(xml.dom.InvalidModificationErr, - r.selectorList.appendSelector, u' h1, x ') - - self.assertEqual(2, r.selectorList.length) - self.assertEqual(u'a, b', r.selectorText) - - def test_selectorText(self): - "CSSStyleRule.selectorText" - r = cssutils.css.CSSStyleRule() - - r.selectorText = u'a' - self.assertEqual(1, r.selectorList.length) - self.assertEqual(u'a', r.selectorText) - - r.selectorText = u' b, h1 ' - self.assertEqual(2, r.selectorList.length) - self.assertEqual(u'b, h1', r.selectorText) - - def test_style(self): - "CSSStyleRule.style" - d = cssutils.css.CSSStyleDeclaration() - self.r.style = d - self.assertEqual(d.cssText, self.r.style.cssText) - - # check if parentRule of d is set - self.assertEqual(self.r, d.parentRule) - - def test_incomplete(self): - "CSSStyleRule (incomplete)" - cssutils.ser.prefs.keepEmptyRules = True - tests = { - u'a {': u'a {}', # no } - u'a { font-family: "arial sans': # no "} - u'a {\n font-family: "arial sans"\n }', - u'a { font-family: "arial sans";': # no } - u'a {\n font-family: "arial sans"\n }', - u'''p { - color: green; - font-family: 'Courier New Times - color: red; - color: green; - }''': u'''p {\n color: green;\n color: green\n }''', - # no ; - u'''p { - color: green; - font-family: 'Courier New Times' - color: red; - color: green; - ''': u'''p {\n color: green;\n color: green\n }''' - } - self.do_equal_p(tests, raising=False) # parse - cssutils.ser.prefs.useDefaults() - -# TODO: def test_InvalidModificationErr(self): -# "CSSStyleRule.cssText InvalidModificationErr" -# self._test_InvalidModificationErr(u'@a a {}') - - def test_reprANDstr(self): - "CSSStyleRule.__repr__(), .__str__()" - sel=u'a > b + c' - - s = cssutils.css.CSSStyleRule(selectorText=sel) - - self.assert_(sel in str(s)) - - s2 = eval(repr(s)) - self.assert_(isinstance(s2, s.__class__)) - self.assert_(sel == s2.selectorText) - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_cssstylesheet.py cssutils-0.9.10/src/tests/test_cssstylesheet.py --- cssutils-0.9.10~b1/src/tests/test_cssstylesheet.py 2011-12-28 18:14:28.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_cssstylesheet.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,879 +0,0 @@ -# -*- coding: utf-8 -*- -"""Tests for css.CSSStyleSheet""" - -import xml.dom -import basetest -import cssutils.css - -class CSSStyleSheetTestCase(basetest.BaseTestCase): - - def setUp(self): - super(CSSStyleSheetTestCase, self).setUp() - self.r = cssutils.css.CSSStyleSheet() # used by basetest - self.s = self.r # used here - self.rule = cssutils.css.CSSStyleRule() - - def tearDown(self): - cssutils.ser.prefs.useDefaults() - - def test_init(self): - "CSSStyleSheet.__init__()" - self.assertEqual('text/css', self.s.type) - self.assertEqual(False, self.s._readonly) - self.assertEqual([], self.s.cssRules) - self.assertEqual(False, self.s.disabled) - self.assertEqual(None, self.s.href) - self.assertEqual(None, self.s.media) - self.assertEqual(None, self.s.ownerNode) - self.assertEqual(None, self.s.parentStyleSheet) - self.assertEqual(u'', self.s.title) - - # check that type is readonly - self.assertRaises(AttributeError, self.r.__setattr__, 'href', 'x') - self.assertRaises(AttributeError, self.r.__setattr__, 'parentStyleSheet', 'x') - self.assertRaises(AttributeError, self.r.__setattr__, 'ownerNode', 'x') - self.assertRaises(AttributeError, self.r.__setattr__, 'type', 'x') - - def test_iter(self): - "CSSStyleSheet.__iter__()" - s = cssutils.css.CSSStyleSheet() - s.cssText = '''@import "x";@import "y";@namespace "u";''' - types = [cssutils.css.CSSRule.IMPORT_RULE, - cssutils.css.CSSRule.IMPORT_RULE, - cssutils.css.CSSRule.NAMESPACE_RULE] - for i, rule in enumerate(s): - self.assertEqual(rule, s.cssRules[i]) - self.assertEqual(rule.type, types[i]) - - def test_refs(self): - """CSSStylesheet references""" - s = cssutils.parseString('a {}') - rules = s.cssRules - self.assertEqual(s.cssRules[0].parentStyleSheet, s) - self.assertEqual(rules[0].parentStyleSheet, s) - - # set cssText - s.cssText = 'b{}' - - # from 0.9.7b1 - self.assertNotEqual(rules, s.cssRules) - - # set cssRules - s.cssRules = cssutils.parseString(''' - @charset "ascii"; - /**/ - @import "x"; - @namespace "http://example.com/ns0"; - @media all { - a { color: green; } - } - @font-face { - font-family: x; - } - @page { - font-family: Arial; - } - @x; - b {}').cssRules''').cssRules - # new object - self.assertNotEqual(rules, s.cssRules) - for i, r in enumerate(s.cssRules): - self.assertEqual(r.parentStyleSheet, s) - - # namespaces - s = cssutils.parseString('@namespace "http://example.com/ns1"; a {}') - namespaces = s.namespaces - self.assertEqual(s.namespaces.items(), [(u'', 'http://example.com/ns1')]) - s.cssText = '@namespace x "http://example.com/ns2"; x|a {}' - # not anymore! - self.assertNotEqual(namespaces, s.namespaces) - self.assertEqual(s.namespaces.items(), [(u'x', 'http://example.com/ns2')]) - - # variables - s = cssutils.parseString(u'@variables { a:1}') - vars1 = s.variables - self.assertEqual(vars1[u'a'], u'1') - - s = cssutils.parseString(u'@variables { a:2}') - vars2 = s.variables - self.assertNotEqual(vars1, vars2) - self.assertEqual(vars1[u'a'], u'1') - self.assertEqual(vars2[u'a'], u'2') - - def test_cssRules(self): - "CSSStyleSheet.cssRules" - s = cssutils.parseString('/*1*/a {x:1}') - self.assertEqual(2, s.cssRules.length) - del s.cssRules[0] - self.assertEqual(1, s.cssRules.length) - s.cssRules.append('/*2*/') - self.assertEqual(2, s.cssRules.length) - s.cssRules.extend(cssutils.parseString('/*3*/x {y:2}').cssRules) - self.assertEqual(4, s.cssRules.length) - self.assertEqual(u'a {\n x: 1\n }\n/*2*/\n/*3*/\nx {\n y: 2\n }'.encode(), - s.cssText) - - for r in s.cssRules: - self.assertEqual(r.parentStyleSheet, s) - - def test_cssText(self): - "CSSStyleSheet.cssText" - tests = { - '': ''.encode(), - # @charset - '@charset "ascii";\n@import "x";': - '@charset "ascii";\n@import "x";'.encode(), - '@charset "ascii";\n@media all {}': '@charset "ascii";'.encode(), - '@charset "ascii";\n@x;': '@charset "ascii";\n@x;'.encode(), - '@charset "ascii";\na {\n x: 1\n }': - '@charset "ascii";\na {\n x: 1\n }'.encode(), - # @import - '@x;\n@import "x";': '@x;\n@import "x";'.encode(), - '@import "x";\n@import "y";': '@import "x";\n@import "y";'.encode(), - '@import "x";\n@media all {}': '@import "x";'.encode(), - '@import "x";\n@x;': '@import "x";\n@x;'.encode(), - '@import "x";\na {\n x: 1\n }': - '@import "x";\na {\n x: 1\n }'.encode(), - # @namespace - '@x;\n@namespace a "x";': '@x;\n@namespace a "x";'.encode(), - '@namespace a "x";\n@namespace b "y";': - '@namespace a "x";\n@namespace b "y";'.encode(), - '@import "x";\n@namespace a "x";\n@media all {}': - '@import "x";\n@namespace a "x";'.encode(), - '@namespace a "x";\n@x;': '@namespace a "x";\n@x;'.encode(), - '@namespace a "x";\na {\n x: 1\n }': - '@namespace a "x";\na {\n x: 1\n }'.encode(), - """@namespace url("e1"); - @namespace url("e2"); - @namespace x url("x1"); - @namespace x url("x2"); - test{color: green} - x|test {color: green}""": """@namespace "e2"; -@namespace x "x2"; -test { - color: green - } -x|test { - color: green - }""".encode() -# ur'\1 { \2: \3 }': ur'''\x01 { -# \x02: \x03 -# }''', -# ur''' -# \@ { \@: \@ } -# \1 { \2: \3 } -# \{{\::\;;} -# ''': ur'''\@ { -# \@: \@ -# } -#\1 { -# \2: \3 -# } -#\{ -# {\:: \; -# }''' - } - self.do_equal_r(tests) - - tests = { - '': None, - # @charset - '@charset "ascii";\n@import "x";': None, - '@charset "ascii";\n@media all {}': '@charset "ascii";', - '@charset "ascii";\n@x;': None, - '@charset "ascii";\na {\n x: 1\n }': None, - # @import - '@x;\n@import "x";': None, - '@import "x";\n@import "y";': None, - '@import "x";\n@media all {}': '@import "x";', - '@import "x";\n@x;': None, - '@import "x";\na {\n x: 1\n }': None, - # @namespace - '@x;\n@namespace a "x";': None, - '@namespace a "x";\n@namespace b "y";': None, - '@import "x";\n@namespace a "x";\n@media all {}': - '@import "x";\n@namespace a "x";', - '@namespace a "x";\n@x;': None, - '@namespace a "x";\na {\n x: 1\n }': None, - """@namespace url("e1"); - @namespace url("e2"); - @namespace x url("x1"); - @namespace x url("x2"); - test{color: green} - x|test {color: green}""": """@namespace "e2"; -@namespace x "x2"; -test { - color: green - } -x|test { - color: green - }""" -# ur'\1 { \2: \3 }': ur'''\x01 { -# \x02: \x03 -# }''', -# ur''' -# \@ { \@: \@ } -# \1 { \2: \3 } -# \{{\::\;;} -# ''': ur'''\@ { -# \@: \@ -# } -#\1 { -# \2: \3 -# } -#\{ -# {\:: \; -# }''' - } - self.do_equal_p(tests) - - s = cssutils.css.CSSStyleSheet() - s.cssText = u'''@charset "ascii";@import "x";@namespace a "x"; - @media all {/*1*/}@page {margin: 0}a {\n x: 1\n }@unknown;/*comment*/''' - for r in s.cssRules: - self.assertEqual(s, r.parentStyleSheet) - - def test_cssText_HierarchyRequestErr(self): - "CSSStyleSheet.cssText HierarchyRequestErr" - tests = { - # @charset: only one and always 1st - u' @charset "utf-8";': xml.dom.HierarchyRequestErr, - u'@charset "ascii";@charset "ascii";': xml.dom.HierarchyRequestErr, u'/*c*/@charset "ascii";': xml.dom.HierarchyRequestErr, - u'@import "x"; @charset "ascii";': xml.dom.HierarchyRequestErr, - u'@namespace a "x"; @charset "ascii";': xml.dom.HierarchyRequestErr, - u'@media all {} @charset "ascii";': xml.dom.HierarchyRequestErr, - u'@page {} @charset "ascii";': xml.dom.HierarchyRequestErr, - u'a {} @charset "ascii";': xml.dom.HierarchyRequestErr, - - # @import: before @namespace, @media, @page, sr - u'@namespace a "x"; @import "x";': xml.dom.HierarchyRequestErr, - u'@media all {} @import "x";': xml.dom.HierarchyRequestErr, - u'@page {} @import "x";': xml.dom.HierarchyRequestErr, - u'a {} @import "x";': xml.dom.HierarchyRequestErr, - - # @namespace: before @media, @page, sr - u'@media all {} @namespace a "x";': xml.dom.HierarchyRequestErr, - u'@page {} @namespace a "x";': xml.dom.HierarchyRequestErr, - u'a {} @namespace a "x";': xml.dom.HierarchyRequestErr, - } - self.do_raise_r(tests) - self.do_raise_p(tests) - - def test_cssText_SyntaxErr(self): - """CSSStyleSheet.cssText SyntaxErr - - for single {, } or ; - """ - tests = { - u'{': xml.dom.SyntaxErr, - u'}': xml.dom.SyntaxErr, - u';': xml.dom.SyntaxErr, - u'@charset "ascii";{': xml.dom.SyntaxErr, - u'@charset "ascii";}': xml.dom.SyntaxErr, - u'@charset "ascii";;': xml.dom.SyntaxErr, - } - self.do_raise_r(tests) - self.do_raise_p(tests) - - def test_encoding(self): - "CSSStyleSheet.encoding" - self.s.cssText='' - self.assertEqual('utf-8', self.s.encoding) - - self.s.encoding = 'ascii' - self.assertEqual('ascii', self.s.encoding) - self.assertEqual(1, self.s.cssRules.length) - self.assertEqual('ascii', self.s.cssRules[0].encoding) - - self.s.encoding = None - self.assertEqual('utf-8', self.s.encoding) - self.assertEqual(0, self.s.cssRules.length) - - self.s.encoding = 'UTF-8' - self.assertEqual('utf-8', self.s.encoding) - self.assertEqual(1, self.s.cssRules.length) - - self.assertRaises(xml.dom.SyntaxErr, self.s._setEncoding, - 'INVALID ENCODING') - self.assertEqual('utf-8', self.s.encoding) - self.assertEqual(1, self.s.cssRules.length) - - def test_namespaces1(self): - "CSSStyleSheet.namespaces.namespaces" - # tests for namespaces internal methods - s = cssutils.css.CSSStyleSheet() - self.assertEqual(0, len(s.namespaces)) - - css = u'''@namespace "default"; -@namespace ex "example"; -@namespace ex2 "example"; -ex2|x { top: 0 }''' - expcss = u'''@namespace "default"; -@namespace ex2 "example"; -ex2|x { - top: 0 - }''' - s.cssText = css - self.assertEqual(s.cssText, expcss.encode()) - self.assertEqual(s.namespaces.namespaces, - { u'': u'default', u'ex2': u'example'}) - - # __contains__ - self.assertTrue('' in s.namespaces) - self.assertTrue('ex2' in s.namespaces) - self.assertFalse('NOTSET' in s.namespaces) - # __delitem__ - self.assertRaises(xml.dom.NoModificationAllowedErr, - s.namespaces.__delitem__, 'ex2') - s.namespaces['del'] = 'del' - del s.namespaces['del'] - self.assertRaises(xml.dom.NamespaceErr, s.namespaces.__getitem__, 'del') - # __getitem__ - self.assertEquals('default', s.namespaces['']) - self.assertEquals('example', s.namespaces['ex2']) - self.assertRaises(xml.dom.NamespaceErr, s.namespaces.__getitem__, 'UNSET') - # __iter__ - self.assertEquals(['', 'ex2'], list(s.namespaces)) - # __len__ - self.assertEqual(2, len(s.namespaces)) - # __setitem__ - self.assertRaises(xml.dom.NoModificationAllowedErr, - s.namespaces.__setitem__, 'ex2', 'NEWURI') - s.namespaces['n1'] = 'new' - self.assertEqual(s.namespaces.namespaces, - { u'': u'default', u'ex2': u'example', u'n1': 'new'}) - s.namespaces['n'] = 'new' # replaces prefix! - self.assertEqual(s.namespaces.namespaces, - { u'': u'default', u'ex2': u'example', u'n': 'new'}) - # prefixForNamespaceURI - self.assertEquals('', s.namespaces.prefixForNamespaceURI('default')) - self.assertEquals('ex2', s.namespaces.prefixForNamespaceURI('example')) - self.assertRaises(IndexError, - s.namespaces.prefixForNamespaceURI, 'UNSET') - # .keys - self.assertEqual(set(s.namespaces.keys()), set(['', 'ex2', 'n'])) - # .get - self.assertEqual('x', s.namespaces.get('UNKNOWN', 'x')) - self.assertEqual('example', s.namespaces.get('ex2', 'not used defa')) - - def test_namespaces2(self): - "CSSStyleSheet.namespaces" - # tests using CSSStyleSheet.namespaces - - s = cssutils.css.CSSStyleSheet() - css = '@namespace n "new";' - # doubles will be removed - s.insertRule(css + css) - self.assertEqual(s.cssText, css.encode()) - r = cssutils.css.CSSNamespaceRule(prefix='ex2', namespaceURI='example') - s.insertRule(r) - r = cssutils.css.CSSNamespaceRule(namespaceURI='default') - s.insertRule(r) - - expcss = '''@namespace n "new"; -@namespace ex2 "example"; -@namespace "default";''' - self.assertEqual(s.cssText, expcss.encode()) - r.prefix = 'DEFAULT' - expcss = '''@namespace n "new"; -@namespace ex2 "example"; -@namespace DEFAULT "default";''' - self.assertEqual(s.cssText, expcss.encode()) - - # CSSMediaRule - self.assertRaises(xml.dom.NamespaceErr, s.add, '@media all {x|a {left: 0}}') - mcss = '@media all {\n ex2|SEL1 {\n left: 0\n }\n }' - s.add(mcss) - expcss += '\n' + mcss - self.assertEqual(s.cssText, expcss.encode()) - - # CSSStyleRule - self.assertRaises(xml.dom.NamespaceErr, s.add, 'x|a {top: 0}') - scss = 'n|SEL2 {\n top: 0\n }' - s.add(scss) - expcss += '\n' + scss - self.assertEqual(s.cssText, expcss.encode()) - - mr = s.cssRules[3] - sr = s.cssRules[4] - - # SelectorList @media - self.assertRaises(xml.dom.NamespaceErr, - mr.cssRules[0]._setSelectorText, 'x|b') - oldsel, newsel = mr.cssRules[0].selectorText, 'n|SEL3, a' - mr.cssRules[0].selectorText = newsel - expcss = expcss.replace(oldsel, newsel) - self.assertEqual(s.cssText, expcss.encode()) - # SelectorList stylerule - self.assertRaises(xml.dom.NamespaceErr, - sr._setSelectorText, 'x|b') - oldsel, newsel = sr.selectorText, 'ex2|SEL4, a' - sr.selectorText = newsel - expcss = expcss.replace(oldsel, newsel) - self.assertEqual(s.cssText, expcss.encode()) - - # Selector @media - self.assertRaises(xml.dom.NamespaceErr, - mr.cssRules[0].selectorList.append, 'x|b') - oldsel, newsel = mr.cssRules[0].selectorText, 'ex2|SELMR' - mr.cssRules[0].selectorList.append(newsel) - expcss = expcss.replace(oldsel, oldsel + ', ' + newsel) - self.assertEqual(s.cssText, expcss.encode()) - # Selector stylerule - self.assertRaises(xml.dom.NamespaceErr, - sr.selectorList.append, 'x|b') - oldsel, newsel = sr.selectorText, 'ex2|SELSR' - sr.selectorList.append(newsel) - expcss = expcss.replace(oldsel, oldsel + ', ' + newsel) - self.assertEqual(s.cssText, expcss.encode()) - - self.assertEqual(s.cssText, u'''@namespace n "new"; -@namespace ex2 "example"; -@namespace DEFAULT "default"; -@media all { - n|SEL3, a, ex2|SELMR { - left: 0 - } - } -ex2|SEL4, a, ex2|SELSR { - top: 0 - }'''.encode()) - - def test_namespaces3(self): - "CSSStyleSheet.namespaces 3" - # tests setting namespaces with new {} - s = cssutils.css.CSSStyleSheet() - css = u'h|a { top: 0 }' - self.assertRaises(xml.dom.NamespaceErr, s.add, css) - - s.add('@namespace x "html";') - self.assert_(s.namespaces['x'] == 'html') - - r = cssutils.css.CSSStyleRule() - r.cssText = ((css, {'h': 'html'})) - s.add(r) # uses x as set before! h is temporary only - self.assertEqual(s.cssText, '@namespace x "html";\nx|a {\n top: 0\n }'.encode()) - - # prefix is now "x"! - self.assertRaises(xml.dom.NamespaceErr, r.selectorList.append, 'h|b') - self.assertRaises(xml.dom.NamespaceErr, r.selectorList.append, 'y|b') - s.namespaces['y'] = 'html' - r.selectorList.append('y|b') - self.assertEqual(s.cssText, - u'@namespace y "html";\ny|a, y|b {\n top: 0\n }'.encode()) - - self.assertRaises(xml.dom.NoModificationAllowedErr, - s.namespaces.__delitem__, 'y') - self.assertEqual(s.cssText, - u'@namespace y "html";\ny|a, y|b {\n top: 0\n }'.encode()) - - s.cssRules[0].prefix = '' - self.assertEqual(s.cssText, - u'@namespace "html";\na, b {\n top: 0\n }'.encode()) - - # remove need of namespace - s.cssRules[0].prefix = 'x' - s.cssRules[1].selectorText = 'a, b' - self.assertEqual(s.cssText, - u'@namespace x "html";\na, b {\n top: 0\n }'.encode()) - - - def test_namespaces4(self): - "CSSStyleSheet.namespaces 4" - # tests setting namespaces with new {} - s = cssutils.css.CSSStyleSheet() - self.assertEqual({}, s.namespaces.namespaces) - - s.namespaces.namespaces['a'] = 'no setting possible' - self.assertEqual({}, s.namespaces.namespaces) - - s.namespaces[None] = 'default' - self.assertEqual({u'': 'default'}, s.namespaces.namespaces) - - del s.namespaces[''] - self.assertEqual({}, s.namespaces.namespaces) - - s.namespaces[''] = 'default' - self.assertEqual({u'': 'default'}, s.namespaces.namespaces) - - del s.namespaces[None] - self.assertEqual({}, s.namespaces.namespaces) - - s.namespaces['p'] = 'uri' - # cannot use namespaces.namespaces - del s.namespaces.namespaces['p'] - self.assertEqual({u'p': 'uri'}, s.namespaces.namespaces) - - self.assertRaisesMsg(xml.dom.NamespaceErr, u"Prefix undefined not found.", - s.namespaces.__delitem__, 'undefined') - - def test_namespaces5(self): - "CSSStyleSheet.namespaces 5" - # unknown namespace - s = cssutils.parseString('a|a { color: red }') - self.assertEqual(s.cssText, ''.encode()) - - s = cssutils.css.CSSStyleSheet() - self.assertRaisesMsg(xml.dom.NamespaceErr, "Prefix a not found.", - s._setCssText, 'a|a { color: red }') - - def test_deleteRuleIndex(self): - "CSSStyleSheet.deleteRule(index)" - self.s.cssText = u'@charset "ascii"; @import "x"; @x; a {\n x: 1\n }@y;' - self.assertEqual(5, self.s.cssRules.length) - - self.assertRaises(xml.dom.IndexSizeErr, self.s.deleteRule, 5) - - # end -1 - # check parentStyleSheet - r = self.s.cssRules[-1] - self.assertEqual(self.s, r.parentStyleSheet) - self.s.deleteRule(-1) - self.assertEqual(None, r.parentStyleSheet) - - self.assertEqual(4, self.s.cssRules.length) - self.assertEqual( - u'@charset "ascii";\n@import "x";\n@x;\na {\n x: 1\n }'.encode(), self.s.cssText) - # beginning - self.s.deleteRule(0) - self.assertEqual(3, self.s.cssRules.length) - self.assertEqual(u'@import "x";\n@x;\na {\n x: 1\n }'.encode(), self.s.cssText) - # middle - self.s.deleteRule(1) - self.assertEqual(2, self.s.cssRules.length) - self.assertEqual(u'@import "x";\na {\n x: 1\n }'.encode(), self.s.cssText) - # end - self.s.deleteRule(1) - self.assertEqual(1, self.s.cssRules.length) - self.assertEqual(u'@import "x";'.encode(), self.s.cssText) - - def test_deleteRule(self): - "CSSStyleSheet.deleteRule(rule)" - s = cssutils.css.CSSStyleSheet() - s.cssText=''' - @namespace x "http://example.com"; - a { color: red; } - b { color: blue; } - c { color: green; } - ''' - n, s1, s2, s3 = s.cssRules - - r = cssutils.css.CSSStyleRule() - self.assertRaises(xml.dom.IndexSizeErr, s.deleteRule, r) - - self.assertEqual(4, s.cssRules.length) - s.deleteRule(n) - self.assertEqual(3, s.cssRules.length) - self.assertEqual(s.cssText, 'a {\n color: red\n }\nb {\n color: blue\n }\nc {\n color: green\n }'.encode()) - self.assertRaises(xml.dom.IndexSizeErr, s.deleteRule, n) - s.deleteRule(s2) - self.assertEqual(2, s.cssRules.length) - self.assertEqual(s.cssText, 'a {\n color: red\n }\nc {\n color: green\n }'.encode()) - self.assertRaises(xml.dom.IndexSizeErr, s.deleteRule, s2) - - def _gets(self): - # complete - self.cr = cssutils.css.CSSCharsetRule('ascii') - self.c = cssutils.css.CSSComment(u'/*c*/') - self.ur = cssutils.css.CSSUnknownRule('@x;') - self.ir = cssutils.css.CSSImportRule('x') - self.nr = cssutils.css.CSSNamespaceRule('uri', 'p') - self.mr = cssutils.css.CSSMediaRule() - self.mr.cssText = u'@media all { @m; }' - self.pr = cssutils.css.CSSPageRule() - self.pr.style = u'margin: 0;' - self.sr = cssutils.css.CSSStyleRule() - self.sr.cssText = 'a {\n x: 1\n }' - - s = cssutils.css.CSSStyleSheet() - s.insertRule(self.cr) # 0 - s.insertRule(self.ir) # 1 - s.insertRule(self.nr) # 2 - s.insertRule(self.mr) # 3 - s.insertRule(self.sr) # 4 - s.insertRule(self.mr) # 5 - s.insertRule(self.pr) # 6 - s.insertRule(self.sr) # 7 - self.assertEqual(u'@charset "ascii";\n@import url(x);\n@namespace p "uri";\n@media all {\n @m;\n }\na {\n x: 1\n }\n@media all {\n @m;\n }\n@page {\n margin: 0\n }\na {\n x: 1\n }'.encode(), s.cssText) - return s, s.cssRules.length - - def test_add(self): - "CSSStyleSheet.add()" - full = cssutils.css.CSSStyleSheet() - sheet = cssutils.css.CSSStyleSheet() - css = ['@charset "ascii";', - '@import "x";', - '@namespace p "u";', - '@page {\n left: 0\n }', - '@font-face {\n src: local(x)\n }', - '@media all {\n a {\n color: red\n }\n }', - 'a {\n color: green\n }', - '/*comment*/', - '@x;' - ] - - fullcss = u'\n'.join(css) - full.cssText = fullcss - self.assertEqual(full.cssText, fullcss.encode()) - for i, line in enumerate(css): - # sheet without same ruletype - before = css[:i] - after = css[i+1:] - sheet.cssText = u''.join(before + after) - - index = sheet.add(line) - if i < 3: - # specific insertion point - self.assertEqual(fullcss.encode(), sheet.cssText) - self.assertEqual(i, index) - else: - # end of sheet - expected = before - expected.extend(after) - expected.append(line) - self.assertEqual(u'\n'.join(expected).encode(), sheet.cssText) - self.assertEqual(len(expected)-1, index) # no same rule present - - # sheet with the same ruletype - if i == 1: line = '@import "x2";' - if i == 2: line = '@namespace p2 "u2";' - - full.cssText = fullcss - index = full.add(line) - if i < 1: - self.assertEqual(fullcss.encode(), sheet.cssText) - self.assertEqual(i, index) # no same rule present - else: - if i < 3: - # in order - expected = css[:i+1] # including same rule - expected.append(line) - expected.extend(css[i+1:]) - expectedindex = i+1 - else: - # just appended as no order needed - expected = css[:] - expected.append(line) - expectedindex = len(expected) - 1 - - self.assertEqual(u'\n'.join(expected).encode(), full.cssText) - self.assertEqual(expectedindex, index) # no same rule present - - def test_addimport(self): - p = cssutils.CSSParser(fetcher=lambda url: (None, '/**/')) - - cssrulessheet = p.parseString('@import "example.css";') - imports = ( - '@import "example.css";', # string - cssutils.css.CSSImportRule(href="example.css"), # CSSRule - cssrulessheet.cssRules # CSSRuleList - ) - for imp in imports: - sheet = p.parseString('', href='http://example.com') - sheet.add(imp) - added = sheet.cssRules[0] - self.assertEqual(sheet, added.parentStyleSheet) - self.assertEqual(u'example.css', added.href) - self.assertEqual(u'utf-8', added.styleSheet.encoding) - self.assertEqual(u'/**/'.encode(), added.styleSheet.cssText) - - cssrulessheet = p.parseString('@import "example.css";') - imports = ( - ('@import "example.css";', 'ascii'), # string - (cssutils.css.CSSImportRule(href="example.css"), 'ascii'), # CSSRule - # got encoding from old parent already - (cssrulessheet.cssRules, 'utf-8') # CSSRuleList - ) - for imp, enc in imports: - sheet = p.parseString('', href='http://example.com', encoding='ascii') - sheet.add(imp) - added = sheet.cssRules[1] - self.assertEqual(sheet, added.parentStyleSheet) - self.assertEqual(u'example.css', added.href) - self.assertEqual(enc, added.styleSheet.encoding) - if enc == 'ascii': - self.assertEqual(u'@charset "ascii";\n/**/'.encode(), added.styleSheet.cssText) - else: - self.assertEqual(u'/**/'.encode(), added.styleSheet.cssText) - - # if styleSheet is already there encoding is not set new - impsheet = p.parseString('@import "example.css";') - imp = impsheet.cssRules[0] - sheet = p.parseString('', href='http://example.com', encoding='ascii') - sheet.add(imp) - added = sheet.cssRules[1] - self.assertEqual(sheet, added.parentStyleSheet) - self.assertEqual(u'example.css', added.href) - self.assertEqual(u'utf-8', added.styleSheet.encoding) - self.assertEqual(u'/**/'.encode(), added.styleSheet.cssText) - - def test_insertRule(self): - "CSSStyleSheet.insertRule()" - s, L = self._gets() - - # INVALID index - self.assertRaises(xml.dom.IndexSizeErr, - s.insertRule, self.sr, -1) - self.assertRaises(xml.dom.IndexSizeErr, - s.insertRule, self.sr, s.cssRules.length + 1) - # check if rule is really not in - self.assertEqual(L, s.cssRules.length) - - # insert string - s.insertRule('a {}') - self.assertEqual(L+1, s.cssRules.length) - # insert rule - s.insertRule(self.sr) - self.assertEqual(L+2, s.cssRules.length) - # insert rulelist - s2, L2 = self._gets() - rulelist = s2.cssRules - del rulelist[:-2] - s.insertRule(rulelist) - self.assertEqual(L+2 + 2, s.cssRules.length) - - def _insertRule(self, rules, notbefore, notafter, anywhere, - checkdoubles=True): - """ - helper - test if any rule in rules cannot be inserted before rules in before - or after rules in after but before and after rules in anywhere - """ - for rule in rules: - for r in notbefore: - s = cssutils.css.CSSStyleSheet() - s.insertRule(r) - self.assertRaises(xml.dom.HierarchyRequestErr, - s.insertRule, rule, 0) - s = cssutils.css.CSSStyleSheet() - s.add(r) - self.assertRaises(xml.dom.HierarchyRequestErr, - s.insertRule, rule, 0) - for r in notafter: - s = cssutils.css.CSSStyleSheet() - s.insertRule(r) - self.assertRaises(xml.dom.HierarchyRequestErr, - s.insertRule, rule, 1) - s = cssutils.css.CSSStyleSheet() - s.add(r) - s.add(rule) # never raises - self.assertEqual(s, r.parentStyleSheet) - - for r in anywhere: - s = cssutils.css.CSSStyleSheet() - s.insertRule(r) - s.insertRule(rule, 0) # before - s.insertRule(rule) # after - if checkdoubles: - self.assertEqual(s.cssRules.length, 3) - self.assertEqual(s, r.parentStyleSheet) - - def test_insertRule_charset(self): - "CSSStyleSheet.insertRule(@charset)" - s, L = self._gets() - notbefore = (self.cr,) - notafter = (self.cr, self.ir, self.nr, self.mr, self.pr, self.sr, - self.c, self.ur) - anywhere = () - self._insertRule((self.cr,), - notbefore, notafter, anywhere) - - def test_insertRule_import(self): - "CSSStyleSheet.insertRule(@import)" - s, L = self._gets() - notbefore = (self.cr,) - notafter = (self.nr, self.pr, self.mr, self.sr) - anywhere = (self.c, self.ur, self.ir) - self._insertRule((self.ir,), - notbefore, notafter, anywhere) - - def test_insertRule_namespace(self): - "CSSStyleSheet.insertRule(@namespace)" - s, L = self._gets() - notbefore = (self.cr, self.ir) - notafter = (self.pr, self.mr, self.sr) - anywhere = (self.c, self.ur, self.nr) - self._insertRule((self.nr,), notbefore, notafter, anywhere, - checkdoubles=False) - - def test_insertRule_media_page_style(self): - "CSSStyleSheet.insertRule(@media, @page, stylerule)" - s, L = self._gets() - notbefore = (self.cr, self.ir, self.nr) - notafter = () - anywhere = (self.c, self.ur, self.mr, self.pr, self.sr) - self._insertRule((self.pr, self.mr, self.sr), - notbefore, notafter, anywhere) - - def test_insertRule_unknownandcomment(self): - "CSSStyleSheet.insertRule(@ unknown, comment)" - s, L = self._gets() - notbefore = (self.cr,) - notafter = () - anywhere = (self.c, self.ur, self.ir, self.nr, self.mr, self.pr, - self.sr) - self._insertRule((self.ur,), - notbefore, notafter, anywhere) - - def test_HTMLComments(self): - "CSSStyleSheet CDO CDC" - css = u'''body { color: red } - -body { color: blue } -body { color: pink } - -body { color: green } -''' - exp = u'''body { - color: red - } -body { - color: pink - }''' - sheet = cssutils.parseString(css) - self.assertEqual(sheet.cssText, exp.encode()) - - def test_incomplete(self): - "CSSStyleRule (incomplete)" - tests = { - u'@import "a': u'@import "a";', # no } - u'a { x: 1': u'a {\n x: 1\n }', # no } - u'a { font-family: "arial sans': # no " - u'a {\n font-family: "arial sans"\n }', - } - self.do_equal_p(tests) # parse - - def test_NoModificationAllowedErr(self): - "CSSStyleSheet NoModificationAllowedErr" - css = cssutils.css.CSSStyleSheet(readonly=True) - - self.assertEqual(True, css._readonly) # internal... - - self.assertRaises(xml.dom.NoModificationAllowedErr, - css._setCssText, u'@x;') - self.assertRaises(xml.dom.NoModificationAllowedErr, - css.insertRule, self.rule) - self.assertRaises(xml.dom.NoModificationAllowedErr, - css.insertRule, self.rule, 0) - self.assertRaises(xml.dom.NoModificationAllowedErr, - css.deleteRule, 0) - - def test_reprANDstr(self): - "CSSStyleSheet.__repr__(), .__str__()" - href = 'file:foo.css' - title = 'title-of-css' - - s = cssutils.css.CSSStyleSheet(href=href, title=title) - - self.assert_(href in str(s)) - self.assert_(title in str(s)) - - s2 = eval(repr(s)) - self.assert_(isinstance(s2, s.__class__)) - self.assert_(href == s2.href) - self.assert_(title == s2.title) - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_cssunknownrule.py cssutils-0.9.10/src/tests/test_cssunknownrule.py --- cssutils-0.9.10~b1/src/tests/test_cssunknownrule.py 2011-12-24 23:32:34.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_cssunknownrule.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,151 +0,0 @@ -"""testcases for cssutils.css.CSSUnkownRule""" - -import xml.dom -import test_cssrule -import cssutils - -class CSSUnknownRuleTestCase(test_cssrule.CSSRuleTestCase): - - def setUp(self): - super(CSSUnknownRuleTestCase, self).setUp() - self.r = cssutils.css.CSSUnknownRule() - self.rRO = cssutils.css.CSSUnknownRule(readonly=True) - self.r_type = cssutils.css.CSSUnknownRule.UNKNOWN_RULE - self.r_typeString = 'UNKNOWN_RULE' - - def tearDown(self): - cssutils.ser.prefs.useDefaults() - - def test_init(self): - "CSSUnknownRule.type and init" - super(CSSUnknownRuleTestCase, self).test_init() - - self.assertFalse(self.r.wellformed) - - # only name - r = cssutils.css.CSSUnknownRule(cssText=u'@init;') - self.assertEqual(u'@init', r.atkeyword) - self.assertEqual(u'@init;', r.cssText) - self.assertTrue(r.wellformed) - - # @-... not allowed? - r = cssutils.css.CSSUnknownRule(cssText=u'@-init;') - self.assertEqual(u'@-init;', r.cssText) - self.assertEqual(u'@-init', r.atkeyword) - self.assertTrue(r.wellformed) - - r = cssutils.css.CSSUnknownRule(cssText=u'@_w-h-a-012;') - self.assertEqual(u'@_w-h-a-012;', r.cssText) - self.assertEqual(u'@_w-h-a-012', r.atkeyword) - self.assertTrue(r.wellformed) - - # name and content - r = cssutils.css.CSSUnknownRule(cssText=u'@init xxx;') - self.assertEqual(u'@init', r.atkeyword) - self.assertEqual(u'@init xxx;', r.cssText) - self.assertTrue(r.wellformed) - - # name and block - r = cssutils.css.CSSUnknownRule(cssText=u'@init { xxx }') - self.assertEqual(u'@init', r.atkeyword) - self.assertEqual(u'@init {\n xxx\n }', r.cssText) - self.assertTrue(r.wellformed) - - # name and content and block - r = cssutils.css.CSSUnknownRule(cssText=u'@init xxx { yyy }') - self.assertEqual(u'@init', r.atkeyword) - self.assertEqual(u'@init xxx {\n yyy\n }', r.cssText) - self.assertTrue(r.wellformed) - - def test_cssText(self): - "CSSUnknownRule.cssText" - tests = { - # not normal rules! - u'@font-facex{}': u'@font-facex {\n }', - u'@importurl(x.css);': u'@importurl (x . css);', - u'@mediaAll{}': u'@mediaall {\n }', - u'@namespacep"x";': u'@namespacep "x";', - u'@pageX{}': u'@pagex {\n }', - u'@xbottom { content: counter(page) }': u'@xbottom {\n content: counter(page)\n }', - u'@xbottom { content: "x" counter(page) "y"}': u'@xbottom {\n content: "x" counter(page) "y"\n }' - } - self.do_equal_p(tests) - - # expects the same atkeyword for self.r so do a new one each test - oldr = self.r - for t, e in tests.items(): - self.r = cssutils.css.CSSUnknownRule() - self.do_equal_r({t:e}) - self.r = oldr - - tests = { - '@x;': None, - '@x {}': u'@x {\n }', - '@x{ \n \t \f\r}': u'@x {\n }', - '@x {\n [()]([ {\n }]) {\n }\n }': None, - '@x {\n @b;\n }': None, - '''@x { - @b { - x: 1x; - y: 2y; - } - }''': None, - '@x "string" url(x);': None, - - # comments - '@x/*1*//*2*/"str"/*3*//*4*/url("x");': - '@x /*1*/ /*2*/ "str" /*3*/ /*4*/ url(x);', - # WS - '@x"string"url("x");': '@x "string" url(x);', - '@x\n\r\t\f "string"\n\r\t\f url(\n\r\t\f "x"\n\r\t\f )\n\r\t\f ;': - '@x "string" url(x);', - } - self.do_equal_p(tests) - self.do_equal_r(tests) - - tests = { - u'@;': xml.dom.InvalidModificationErr, - u'@{}': xml.dom.InvalidModificationErr, - u'@ ;': xml.dom.InvalidModificationErr, - u'@ {};': xml.dom.InvalidModificationErr, - - u'@x ;{}': xml.dom.SyntaxErr, - u'@x ;;': xml.dom.SyntaxErr, - u'@x } ': xml.dom.SyntaxErr, - u'@x } ;': xml.dom.SyntaxErr, - u'@x { ': xml.dom.SyntaxErr, - u'@x { ;': xml.dom.SyntaxErr, - u'@x ': xml.dom.SyntaxErr, - u'@x (;': xml.dom.SyntaxErr, - u'@x );': xml.dom.SyntaxErr, - u'@x [;': xml.dom.SyntaxErr, - u'@x ];': xml.dom.SyntaxErr, - u'@x {[(]()}': xml.dom.SyntaxErr, - # trailing - u'@x{}{}': xml.dom.SyntaxErr, - u'@x{};': xml.dom.SyntaxErr, - u'@x{}1': xml.dom.SyntaxErr, - u'@x{} ': xml.dom.SyntaxErr, - u'@x{}/**/': xml.dom.SyntaxErr, - u'@x;1': xml.dom.SyntaxErr, - u'@x; ': xml.dom.SyntaxErr, - u'@x;/**/': xml.dom.SyntaxErr, - - } - self.do_raise_r(tests) - - def test_InvalidModificationErr(self): - "CSSUnknownRule.cssText InvalidModificationErr" - self._test_InvalidModificationErr(u'@unknown') - - def test_reprANDstr(self): - "CSSUnknownRule.__repr__(), .__str__()" - s = cssutils.css.CSSUnknownRule(cssText='@x;') - - s2 = eval(repr(s)) - self.assert_(isinstance(s2, s.__class__)) - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_cssutils.py cssutils-0.9.10/src/tests/test_cssutils.py --- cssutils-0.9.10~b1/src/tests/test_cssutils.py 2012-04-28 14:55:42.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_cssutils.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,426 +0,0 @@ -# -*- coding: utf-8 -*- -"""Testcases for cssutils.css.CSSCharsetRule""" -from __future__ import with_statement - -import basetest -import codecs -import cssutils -import os -import sys -import tempfile -import xml.dom - -try: - import mock -except ImportError: - mock = None - print "install mock library to run all tests" - - -class CSSutilsTestCase(basetest.BaseTestCase): - - def setUp(self): - cssutils.ser.prefs.useDefaults() - - def tearDown(self): - cssutils.ser.prefs.useDefaults() - - exp = u'''@import "import/import2.css"; -.import { - /* ./import.css */ - background-image: url(images/example.gif) - }''' - - def test_VERSION(self): - self.assertEqual('0.9.10b1', cssutils.VERSION) - - def test_parseString(self): - "cssutils.parseString()" - s = cssutils.parseString(self.exp, - media='handheld, screen', - title='from string') - self.assert_(isinstance(s, cssutils.css.CSSStyleSheet)) - self.assertEqual(None, s.href) - self.assertEqual(self.exp.encode(), s.cssText) - self.assertEqual(u'utf-8', s.encoding) - self.assertEqual(u'handheld, screen', s.media.mediaText) - self.assertEqual(u'from string', s.title) - self.assertEqual(self.exp.encode(), s.cssText) - - ir = s.cssRules[0] - self.assertEqual('import/import2.css', ir.href) - irs = ir.styleSheet - self.assertEqual(cssutils.css.CSSStyleSheet, type(irs)) - - href = os.path.join(os.path.dirname(__file__), - '..', '..', 'sheets', 'import.css') - href = cssutils.helper.path2url(href) - s = cssutils.parseString(self.exp, - href=href) - self.assertEqual(href, s.href) - - ir = s.cssRules[0] - self.assertEqual('import/import2.css', ir.href) - irs = ir.styleSheet - self.assert_(isinstance(irs, cssutils.css.CSSStyleSheet)) - self.assertEqual(irs.cssText, '@import "../import3.css";\n@import "import-impossible.css" print;\n.import2 {\n /* sheets/import2.css */\n background: url(http://example.com/images/example.gif);\n background: url(//example.com/images/example.gif);\n background: url(/images/example.gif);\n background: url(images2/example.gif);\n background: url(./images2/example.gif);\n background: url(../images/example.gif);\n background: url(./../images/example.gif)\n }'.encode()) - - tests = { - 'a {color: red}': u'a {\n color: red\n }', - 'a {color: rgb(1,2,3)}': u'a {\n color: rgb(1, 2, 3)\n }' - } - self.do_equal_p(tests) - - def test_parseFile(self): - "cssutils.parseFile()" - # name if used with open, href used for @import resolving - name = os.path.join(os.path.dirname(__file__), - '..', '..', 'sheets', 'import.css') - href = cssutils.helper.path2url(name) - - s = cssutils.parseFile(name, href=href, media='screen', title='from file') - self.assert_(isinstance(s, cssutils.css.CSSStyleSheet)) - if sys.platform.startswith('java'): - # on Jython only file: - self.assert_(s.href.startswith('file:')) - else: - # normally file:/// on win and file:/ on unix - self.assert_(s.href.startswith('file:/')) - self.assert_(s.href.endswith('/sheets/import.css')) - self.assertEqual(u'utf-8', s.encoding) - self.assertEqual(u'screen', s.media.mediaText) - self.assertEqual(u'from file', s.title) - self.assertEqual(self.exp.encode(), s.cssText) - - ir = s.cssRules[0] - self.assertEqual('import/import2.css', ir.href) - irs = ir.styleSheet - self.assert_(isinstance(irs, cssutils.css.CSSStyleSheet)) - self.assertEqual(irs.cssText, '@import "../import3.css";\n@import "import-impossible.css" print;\n.import2 {\n /* sheets/import2.css */\n background: url(http://example.com/images/example.gif);\n background: url(//example.com/images/example.gif);\n background: url(/images/example.gif);\n background: url(images2/example.gif);\n background: url(./images2/example.gif);\n background: url(../images/example.gif);\n background: url(./../images/example.gif)\n }'.encode()) - - # name is used for open and setting of href automatically - # test needs to be relative to this test file! - os.chdir(os.path.dirname(__file__)) - name = os.path.join('..', '..', 'sheets', 'import.css') - - s = cssutils.parseFile(name, media='screen', title='from file') - self.assert_(isinstance(s, cssutils.css.CSSStyleSheet)) - if sys.platform.startswith('java'): - # on Jython only file: - self.assert_(s.href.startswith('file:')) - else: - # normally file:/// on win and file:/ on unix - self.assert_(s.href.startswith('file:/')) - self.assert_(s.href.endswith('/sheets/import.css')) - self.assertEqual(u'utf-8', s.encoding) - self.assertEqual(u'screen', s.media.mediaText) - self.assertEqual(u'from file', s.title) - self.assertEqual(self.exp.encode(), s.cssText) - - ir = s.cssRules[0] - self.assertEqual('import/import2.css', ir.href) - irs = ir.styleSheet - self.assert_(isinstance(irs, cssutils.css.CSSStyleSheet)) - self.assertEqual(irs.cssText, '@import "../import3.css";\n@import "import-impossible.css" print;\n.import2 {\n /* sheets/import2.css */\n background: url(http://example.com/images/example.gif);\n background: url(//example.com/images/example.gif);\n background: url(/images/example.gif);\n background: url(images2/example.gif);\n background: url(./images2/example.gif);\n background: url(../images/example.gif);\n background: url(./../images/example.gif)\n }'.encode()) - - # next test - css = u'a:after { content: "羊蹄€\u2020" }' - - fd, name = tempfile.mkstemp('_cssutilstest.css') - t = os.fdopen(fd, 'wb') - t.write(css.encode('utf-8')) - t.close() - - self.assertRaises(UnicodeDecodeError, cssutils.parseFile, name, 'ascii') - - # ??? - s = cssutils.parseFile(name, encoding='iso-8859-1') - self.assertEqual(cssutils.css.CSSStyleSheet, type(s)) - self.assertEqual(s.cssRules[1].selectorText, 'a:after') - - s = cssutils.parseFile(name, encoding='utf-8') - self.assertEqual(cssutils.css.CSSStyleSheet, type(s)) - self.assertEqual(s.cssRules[1].selectorText, 'a:after') - - css = u'@charset "iso-8859-1"; a:after { content: "ä" }' - t = codecs.open(name, 'w', 'iso-8859-1') - t.write(css) - t.close() - - self.assertRaises( - UnicodeDecodeError, cssutils.parseFile, name, 'ascii') - - s = cssutils.parseFile(name, encoding='iso-8859-1') - self.assertEqual(cssutils.css.CSSStyleSheet, type(s)) - self.assertEqual(s.cssRules[1].selectorText, 'a:after') - - self.assertRaises( - UnicodeDecodeError, cssutils.parseFile, name, 'utf-8') - - # clean up - try: - os.remove(name) - except OSError, e: - pass - - def test_parseUrl(self): - "cssutils.parseUrl()" - href = os.path.join(os.path.dirname(__file__), - '..', '..', 'sheets', 'import.css') - #href = u'file:' + urllib.pathname2url(href) - href = cssutils.helper.path2url(href) - #href = 'http://seewhatever.de/sheets/import.css' - s = cssutils.parseUrl(href, - media='tv, print', - title='from url') - self.assert_(isinstance(s, cssutils.css.CSSStyleSheet)) - self.assertEqual(href, s.href) - self.assertEqual(self.exp.encode(), s.cssText) - self.assertEqual(u'utf-8', s.encoding) - self.assertEqual(u'tv, print', s.media.mediaText) - self.assertEqual('from url', s.title) - - sr = s.cssRules[1] - img = sr.style.getProperty('background-image').propertyValue[0].value - self.assertEqual(img, 'images/example.gif') - - ir = s.cssRules[0] - self.assertEqual(u'import/import2.css', ir.href) - irs = ir.styleSheet - self.assertEqual(irs.cssText, '@import "../import3.css";\n@import "import-impossible.css" print;\n.import2 {\n /* sheets/import2.css */\n background: url(http://example.com/images/example.gif);\n background: url(//example.com/images/example.gif);\n background: url(/images/example.gif);\n background: url(images2/example.gif);\n background: url(./images2/example.gif);\n background: url(../images/example.gif);\n background: url(./../images/example.gif)\n }'.encode()) - - ir2 = irs.cssRules[0] - self.assertEqual(u'../import3.css', ir2.href) - irs2 = ir2.styleSheet - self.assertEqual(irs2.cssText, '/* import3 */\n.import3 {\n /* from ./import/../import3.css */\n background: url(images/example3.gif);\n background: url(./images/example3.gif);\n background: url(import/images2/example2.gif);\n background: url(./import/images2/example2.gif);\n background: url(import/images2/../../images/example3.gif)\n }'.encode()) - - def test_setCSSSerializer(self): - "cssutils.setSerializer() and cssutils.ser" - s = cssutils.parseString('a { left: 0 }') - exp4 = '''a { - left: 0 - }''' - exp1 = '''a { - left: 0 - }''' - self.assertEqual(exp4.encode(), s.cssText) - newser = cssutils.CSSSerializer(cssutils.serialize.Preferences(indent=' ')) - cssutils.setSerializer(newser) - self.assertEqual(exp1.encode(), s.cssText) - newser = cssutils.CSSSerializer(cssutils.serialize.Preferences(indent=' ')) - cssutils.ser = newser - self.assertEqual(exp4.encode(), s.cssText) - - def test_parseStyle(self): - "cssutils.parseStyle()" - s = cssutils.parseStyle('x:0; y:red') - self.assertEqual(type(s), cssutils.css.CSSStyleDeclaration) - self.assertEqual(s.cssText, u'x: 0;\ny: red') - - s = cssutils.parseStyle('@import "x";') - self.assertEqual(type(s), cssutils.css.CSSStyleDeclaration) - self.assertEqual(s.cssText, u'') - - tests = [ - (u'content: "ä"', 'iso-8859-1'), - (u'content: "€"', 'utf-8') - ] - for v, e in tests: - s = cssutils.parseStyle(v.encode(e), encoding=e) - self.assertEqual(s.cssText, v) - - self.assertRaises(UnicodeDecodeError, cssutils.parseStyle, - u'content: "ä"'.encode('utf-8'), 'ascii') - - - def test_getUrls(self): - "cssutils.getUrls()" - cssutils.ser.prefs.keepAllProperties = True - - css=''' - @import "im1"; - @import url(im2); - @import url( im3 ); - @import url( "im4" ); - @import url( 'im5' ); - a { - background-image: url(a) !important; - background-\image: url(b); - background: url(c) no-repeat !important; - /* issue #46 */ - src: local("xx"), - url("f.woff") format("woff"), - url("f.otf") format("opentype"), - url("f.svg#f") format("svg"); - }''' - urls = set(cssutils.getUrls(cssutils.parseString(css))) - self.assertEqual(urls, set(["im1", "im2", "im3", "im4", "im5", - "a", "b", "c", - u'f.woff', u'f.svg#f', u'f.otf'])) - cssutils.ser.prefs.keepAllProperties = False - - def test_replaceUrls(self): - "cssutils.replaceUrls()" - cssutils.ser.prefs.keepAllProperties = True - - css=''' - @import "im1"; - @import url(im2); - a { - background-image: url(c) !important; - background-\image: url(b); - background: url(a) no-repeat !important; - }''' - s = cssutils.parseString(css) - cssutils.replaceUrls(s, lambda old: "NEW" + old) - self.assertEqual(u'@import "NEWim1";', s.cssRules[0].cssText) - self.assertEqual(u'NEWim2', s.cssRules[1].href) - self.assertEqual(u'''background-image: url(NEWc) !important; -background-\\image: url(NEWb); -background: url(NEWa) no-repeat !important''', s.cssRules[2].style.cssText) - - cssutils.ser.prefs.keepAllProperties = False - - # CSSStyleDeclaration - style = cssutils.parseStyle(u'''color: red; - background-image: - url(1.png), - url('2.png')''') - cssutils.replaceUrls(style, lambda url: 'prefix/'+url) - self.assertEqual(style.cssText, u'''color: red; -background-image: url(prefix/1.png), url(prefix/2.png)''') - - - def test_resolveImports(self): - "cssutils.resolveImports(sheet)" - if mock: - self._tempSer() - cssutils.ser.prefs.useMinified() - - a = u'@charset "iso-8859-1";@import"b.css";\xe4{color:green}'.encode('iso-8859-1') - b = u'@charset "ascii";\\E4 {color:red}'.encode('ascii') - - # normal - m = mock.Mock() - with mock.patch('cssutils.util._defaultFetcher', m): - m.return_value = (None, b) - s = cssutils.parseString(a) - - # py3 TODO - self.assertEqual(a, s.cssText) - self.assertEqual(b, s.cssRules[1].styleSheet.cssText) - - c = cssutils.resolveImports(s) - - # py3 TODO - self.assertEqual(u'\xc3\xa4{color:red}\xc3\xa4{color:green}'.encode('iso-8859-1'), - c.cssText) - - c.encoding = 'ascii' - self.assertEqual(ur'@charset "ascii";\E4 {color:red}\E4 {color:green}'.encode(), - c.cssText) - - # b cannot be found - m = mock.Mock() - with mock.patch('cssutils.util._defaultFetcher', m): - m.return_value = (None, None) - s = cssutils.parseString(a) - - # py3 TODO - self.assertEqual(a, s.cssText) - self.assertEqual(cssutils.css.CSSStyleSheet, - type(s.cssRules[1].styleSheet)) - c = cssutils.resolveImports(s) - # py3 TODO - self.assertEqual(u'@import"b.css";\xc3\xa4{color:green}'.encode('iso-8859-1'), - c.cssText) - - # @import with media - a = u'@import"b.css";@import"b.css" print, tv ;@import"b.css" all;' - b = u'a {color: red}' - m = mock.Mock() - with mock.patch('cssutils.util._defaultFetcher', m): - m.return_value = (None, b) - s = cssutils.parseString(a) - - c = cssutils.resolveImports(s) - - self.assertEqual('a{color:red}@media print,tv{a{color:red}}a{color:red}'.encode(), - c.cssText) - - # cannot resolve with media => keep original - a = u'@import"b.css"print;' - b = u'@namespace "http://example.com";' - m = mock.Mock() - with mock.patch('cssutils.util._defaultFetcher', m): - m.return_value = (None, b) - s = cssutils.parseString(a) - c = cssutils.resolveImports(s) - self.assertEqual(a.encode(), c.cssText) - - # urls are adjusted too, layout: - # a.css - # c.css - # img/img.gif - # b/ - # b.css - # subimg/subimg.gif - a = u''' - @import"b/b.css"; - a { - x: url(/img/abs.gif); - y: url(img/img.gif); - z: url(b/subimg/subimg.gif); - }''' - def fetcher(url): - c = { - 'b.css': u''' - @import"../c.css"; - b { - x: url(/img/abs.gif); - y: url(../img/img.gif); - z: url(subimg/subimg.gif); - }''', - 'c.css': u''' - c { - x: url(/img/abs.gif); - y: url(./img/img.gif); - z: url(./b/subimg/subimg.gif); - }''' - } - return 'utf-8', c[os.path.split(url)[1]] - - @mock.patch.object(cssutils.util, '_defaultFetcher', - new=fetcher) - def do(): - s = cssutils.parseString(a) - r = cssutils.resolveImports(s) - return s, r - - s, r = do() - - cssutils.ser.prefs.useDefaults() - cssutils.ser.prefs.keepComments = False - self.assertEqual(u'''c { - x: url(/img/abs.gif); - y: url(img/img.gif); - z: url(b/subimg/subimg.gif) - } -b { - x: url(/img/abs.gif); - y: url(img/img.gif); - z: url(b/subimg/subimg.gif) - } -a { - x: url(/img/abs.gif); - y: url(img/img.gif); - z: url(b/subimg/subimg.gif) - }'''.encode(), r.cssText) - - cssutils.ser.prefs.useDefaults() - else: - self.assertEqual(False, u'Mock needed for this test') - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_cssutilsimport.py cssutils-0.9.10/src/tests/test_cssutilsimport.py --- cssutils-0.9.10~b1/src/tests/test_cssutilsimport.py 2011-07-26 18:22:54.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_cssutilsimport.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -"""Testcase for cssutils imports""" - -before = len(locals()) # to check is only exp amount is imported -from cssutils import * -after = len(locals()) # to check is only exp amount is imported - -import unittest - -class CSSutilsImportTestCase(unittest.TestCase): - - def test_import_all(self): - "from cssutils import *" - import cssutils - - act = globals() - exp = {'CSSParser': CSSParser, - 'CSSSerializer': CSSSerializer, - 'css': cssutils.css, - 'stylesheets': cssutils.stylesheets, - } - exptotal = before + len(exp) + 1 - # imports before + * + "after" - self.assert_(after == exptotal, 'too many imported') - - found = 0 - for e in exp: - self.assert_(e in act, '%s not found' %e) - self.assert_(act[e] == exp[e], '%s not the same' %e) - found += 1 - self.assert_(found == len(exp)) - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_cssvalue.py cssutils-0.9.10/src/tests/test_cssvalue.py --- cssutils-0.9.10~b1/src/tests/test_cssvalue.py 2011-07-26 18:22:54.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_cssvalue.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,819 +0,0 @@ -"""Testcases for cssutils.css.CSSValue and CSSPrimitiveValue.""" - -# -## from decimal import Decimal # maybe for later tests? -#import xml.dom -#import basetest -#import cssutils -#import types -# -#class CSSValueTestCase(basetest.BaseTestCase): -# -# def setUp(self): -# self.r = cssutils.css.CSSValue() # needed for tests -# -# def test_init(self): -# "CSSValue.__init__()" -# v = cssutils.css.CSSValue() -# self.assert_(u'' == v.cssText) -# self.assert_(None is v.cssValueType) -# self.assert_(None == v.cssValueTypeString) -# -# def test_escapes(self): -# "CSSValue Escapes" -# v = cssutils.css.CSSValue() -# v.cssText = u'1px' -# self.assert_(v.CSS_PRIMITIVE_VALUE == v.cssValueType) -# self.assert_(v.CSS_PX == v.primitiveType) -# self.assert_(u'1px' == v.cssText) -# -# v.cssText = u'1PX' -# self.assert_(v.CSS_PRIMITIVE_VALUE == v.cssValueType) -# self.assert_(v.CSS_PX == v.primitiveType) -# self.assert_(u'1px' == v.cssText) -# -# v.cssText = u'1p\\x' -# self.assert_(v.CSS_PRIMITIVE_VALUE == v.cssValueType) -# self.assert_(v.CSS_PX == v.primitiveType) -# self.assert_(u'1px' == v.cssText) -# -# def test_cssText(self): -# "CSSValue.cssText" -# v = cssutils.css.CSSValue() -# v.cssText = u'1px' -# self.assert_(v.CSS_PRIMITIVE_VALUE == v.cssValueType) -# self.assert_(v.CSS_PX == v.primitiveType) -# self.assert_(u'1px' == v.cssText) -# -# v = cssutils.css.CSSValue() -# v.cssText = u'1px' -# self.assert_(v.CSS_PRIMITIVE_VALUE == v.cssValueType) -# self.assert_(v.CSS_PX == v.primitiveType) -# self.assert_(u'1px' == v.cssText) -# -# v = cssutils.css.CSSValue() -# v.cssText = u'a ,b, c ,"d or d", "e, " ' -# self.assertEqual(v.CSS_PRIMITIVE_VALUE, v.cssValueType) -# self.assertEqual(v.CSS_STRING, v.primitiveType) -# self.assertEqual(u'a, b, c, "d or d", "e, "', v.cssText) -# -# v.cssText = u' 1 px ' -# self.assert_(v.CSS_VALUE_LIST == v.cssValueType) -# self.assert_('1 px' == v.cssText) -# -# v.cssText = u' normal 1px a, b, "c" end ' -# self.assert_(v.CSS_VALUE_LIST == v.cssValueType) -# self.assertEqual('normal 1px a, b, "c" end', v.cssText) -# -# for i, x in enumerate(v): -# self.assertEqual(x.CSS_PRIMITIVE_VALUE, x.cssValueType) -# if x == 0: -# self.assertEqual(x.CSS_IDENT, x.primitiveType) -# self.assertEqual(u'normal', x.cssText) -# elif x == 1: -# self.assertEqual(x.CSS_PX, x.primitiveType) -# self.assertEqual(u'1px', x.cssText) -# if x == 2: -# self.assertEqual(x.CSS_STRING, x.primitiveType) -# self.assertEqual(u'a, b, "c"', x.cssText) -# if x == 3: -# self.assertEqual(x.CSS_IDENT, x.primitiveType) -# self.assertEqual(u'end', x.cssText) -# -# -# v = cssutils.css.CSSValue() -# v.cssText = u' 1 px ' -# self.assert_(v.CSS_VALUE_LIST == v.cssValueType) -# self.assert_(u'1 px' == v.cssText) -# -# v.cssText = u'expression(document.body.clientWidth > 972 ? "1014px": "100%" )' -# self.assert_(v.CSS_PRIMITIVE_VALUE == v.cssValueType) -# self.assert_(v.CSS_UNKNOWN == v.primitiveType) -# self.assertEqual(u'expression(document.body.clientWidth > 972?"1014px": "100%")', -# v.cssText) -# -# def test_cssText2(self): -# "CSSValue.cssText 2" -# tests = { -# # mix -# u'a()1,-1,+1,1%,-1%,1px,-1px,"a",a,url(a),#aabb44': -# u'a() 1, -1, 1, 1%, -1%, 1px, -1px, "a", a, url(a), #ab4', -# -# # S or COMMENT -# u'red': u'red', -# u'red ': u'red', -# u' red ': u'red', -# u'/**/red': u'/**/ red', -# u'red/**/': u'red /**/', -# u'/**/red/**/': u'/**/ red /**/', -# u'/**/ red': u'/**/ red', -# u'red /**/': u'red /**/', -# u'/**/ red /**/': u'/**/ red /**/', -# u'red-': u'red-', -# -# # num / dimension -# u'.0': u'0', -# u'0': u'0', -# u'0.0': u'0', -# u'00': u'0', -# u'0%': u'0%', -# u'0px': u'0', -# u'-.0': u'0', -# u'-0': u'0', -# u'-0.0': u'0', -# u'-00': u'0', -# u'-0%': u'0%', -# u'-0px': u'0', -# u'+.0': u'0', -# u'+0': u'0', -# u'+0.0': u'0', -# u'+00': u'0', -# u'+0%': u'0%', -# u'+0px': u'0', -# u'1': u'1', -# u'1.0': u'1', -# u'1px': u'1px', -# u'1%': u'1%', -# u'1px1': u'1px1', -# u'+1': u'1', -# u'-1': u'-1', -# u'+1.0': u'1', -# u'-1.0': u'-1', -# -# # string, escaped nl is removed during tokenizing -# u'"x"': u'"x"', -# u"'x'": u'"x"', -# #ur''' "1\'2" ''': u'''"1'2"''', #??? -# #ur"'x\"'": ur'"x\""', #??? -# ur'''"x\ -#y"''': u'''"xy"''', -# -# # hash and rgb/a -# u'#112234': u'#112234', -# u'#112233': u'#123', -# u'rgb(1,2,3)': u'rgb(1, 2, 3)', -# u'rgb( 1 , 2 , 3 )': u'rgb(1, 2, 3)', -# u'rgb(-1,+2,0)': u'rgb(-1, 2, 0)', -# u'rgba(1,2,3,4)': u'rgba(1, 2, 3, 4)', -# u'rgba( 1 , 2 , 3 , 4 )': u'rgba(1, 2, 3, 4)', -# u'rgba(-1,+2,0, 0)': u'rgba(-1, 2, 0, 0)', -# -# # FUNCTION -# u'f(1,2)': u'f(1, 2)', -# u'f( 1 , 2 )': u'f(1, 2)', -# u'f(-1,+2)': u'f(-1, 2)', -# u'f( -1 , +2 )': u'f(-1, 2)', -# u'fun( -1 , +2 )': u'fun(-1, 2)', -# u'local( x )': u'local(x)', -# u'test(1px, #111, y, 1, 1%, "1", y(), var(x))': -# u'test(1px, #111, y, 1, 1%, "1", y(), var(x))', -# u'test(-1px, #111, y, -1, -1%, "1", -y())': -# u'test(-1px, #111, y, -1, -1%, "1", -y())', -# u'url(y) format( "x" , "y" )': u'url(y) format("x", "y")', -# u'f(1 2,3 4)': u'f(1 2, 3 4)', -# -# # IE expression -# ur'Expression()': u'Expression()', -# ur'expression(-1 < +2)': u'expression(-1< + 2)', -# ur'expression(document.width == "1")': u'expression(document.width=="1")', -# u'alpha(opacity=80)': u'alpha(opacity=80)', -# u'alpha( opacity = 80 , x=2 )': u'alpha(opacity=80, x=2)', -# -# # unicode-range -# 'u+f': 'u+f', -# 'U+ABCdef': 'u+abcdef', -# -# # url -# 'url(a)': 'url(a)', -# 'uRl(a)': 'url(a)', -# 'u\\rl(a)': 'url(a)', -# 'url("a")': 'url(a)', -# 'url( "a" )': 'url(a)', -# 'url(a)': 'url(a)', -# 'url(";")': 'url(";")', -# 'url(",")': 'url(",")', -# 'url(")")': 'url(")")', -# '''url("'")''': '''url("'")''', -# '''url('"')''': '''url("\\"")''', -# '''url("'")''': '''url("'")''', -# -# # operator -# '1': '1', -# '1 2': '1 2', -# '1 2': '1 2', -# '1,2': '1, 2', -# '1, 2': '1, 2', -# '1 ,2': '1, 2', -# '1 , 2': '1, 2', -# '1/2': '1/2', -# '1/ 2': '1/2', -# '1 /2': '1/2', -# '1 / 2': '1/2', -# # comment -# '1/**/2': '1 /**/ 2', -# '1 /**/2': '1 /**/ 2', -# '1/**/ 2': '1 /**/ 2', -# '1 /**/ 2': '1 /**/ 2', -# '1 /*a*/ /*b*/ 2': '1 /*a*/ /*b*/ 2', -# # , before -# '1,/**/2': '1, /**/ 2', -# '1 ,/**/2': '1, /**/ 2', -# '1, /**/2': '1, /**/ 2', -# '1 , /**/2': '1, /**/ 2', -# # , after -# '1/**/,2': '1 /**/, 2', -# '1/**/ ,2': '1 /**/, 2', -# '1/**/, 2': '1 /**/, 2', -# '1/**/ , 2': '1 /**/, 2', -# # all -# '1/*a*/ ,/*b*/ 2': '1 /*a*/, /*b*/ 2', -# '1 /*a*/, /*b*/2': '1 /*a*/, /*b*/ 2', -# '1 /*a*/ , /*b*/ 2': '1 /*a*/, /*b*/ 2', -# -# # list -# 'a b1,b2 b2,b3,b4': 'a b1, b2 b2, b3, b4', -# 'a b1 , b2 b2 , b3 , b4': 'a b1, b2 b2, b3, b4', -# 'u+1 , u+2-5': 'u+1, u+2-5', -# u'local( x ), url(y) format( "x" , "y" )': -# u'local(x), url(y) format("x", "y")', -# # FUNCTION -# u'attr( href )': u'attr(href)', -# # PrinceXML extende FUNC syntax with nested FUNC -# u'target-counter(attr(href),page)': u'target-counter(attr(href), page)' -# } -# -# self.do_equal_r(tests) -# -# tests = { -# u'a+': xml.dom.SyntaxErr, -# u'-': xml.dom.SyntaxErr, -# u'+': xml.dom.SyntaxErr, -# u'-%': xml.dom.SyntaxErr, -# u'+a': xml.dom.SyntaxErr, -# u'--1px': xml.dom.SyntaxErr, -# u'++1px': xml.dom.SyntaxErr, -# u'#': xml.dom.SyntaxErr, -# u'#00': xml.dom.SyntaxErr, -# u'#0000': xml.dom.SyntaxErr, -# u'#00000': xml.dom.SyntaxErr, -# u'#0000000': xml.dom.SyntaxErr, -# u'-#0': xml.dom.SyntaxErr, -# # operator -# u',': xml.dom.SyntaxErr, -# u'1,,2': xml.dom.SyntaxErr, -# u'1,/**/,2': xml.dom.SyntaxErr, -# u'1 , /**/ , 2': xml.dom.SyntaxErr, -# u'1,': xml.dom.SyntaxErr, -# u'1, ': xml.dom.SyntaxErr, -# u'1 ,': xml.dom.SyntaxErr, -# u'1 , ': xml.dom.SyntaxErr, -# u'1 , ': xml.dom.SyntaxErr, -# u'1//2': xml.dom.SyntaxErr, -# # URL -# u'url(x))': xml.dom.SyntaxErr, -# # string -# u'"': xml.dom.SyntaxErr, -# u"'": xml.dom.SyntaxErr, -# # function -# u'f(-)': xml.dom.SyntaxErr, -# u'f(x))': xml.dom.SyntaxErr -# } -# self.do_raise_r(tests) -# -# def test_incomplete(self): -# "CSSValue (incomplete)" -# tests = { -# u'url("a': u'url(a)', -# u'url(a': u'url(a)' -# } -# for v, exp in tests.items(): -# s = cssutils.parseString('a { background: %s' % v) -# v = s.cssRules[0].style.background -# self.assertEqual(v, exp) -# -# def test_cssValueType(self): -# "CSSValue.cssValueType .cssValueTypeString" -# tests = [ -# ([u'inherit', u'INhe\\rit'], 'CSS_INHERIT', cssutils.css.CSSValue), -# (['1', '1%', '1em', '1ex', '1px', '1cm', '1mm', '1in', '1pt', '1pc', -# '1deg', '1rad', '1grad', '1ms', '1s', '1hz', '1khz', '1other', -# '"string"', "'string'", 'url(x)', 'red', -# 'attr(a)', 'counter(x)', 'rect(1px, 2px, 3px, 4px)', -# 'rgb(0, 0, 0)', '#000', '#123456', 'rgba(0, 0, 0, 0)', -# 'hsl(0, 0, 0)', 'hsla(0, 0, 0, 0)', -# ], -# 'CSS_PRIMITIVE_VALUE', cssutils.css.CSSPrimitiveValue), -# ([u'1px 1px', 'red blue green x'], 'CSS_VALUE_LIST', cssutils.css.CSSValueList), -# # what is a custom value? -# #([], 'CSS_CUSTOM', cssutils.css.CSSValue) -# ] -# for values, name, cls in tests: -# for value in values: -# v = cssutils.css.CSSValue(cssText=value) -# if value == "'string'": -# # will be changed to " always -# value = '"string"' -# self.assertEqual(value, v.cssText) -# self.assertEqual(name, v.cssValueTypeString) -# self.assertEqual(getattr(v, name), v.cssValueType) -# self.assertEqual(cls, type(v)) -# -# def test_readonly(self): -# "(CSSValue._readonly)" -# v = cssutils.css.CSSValue(cssText='inherit') -# self.assert_(False is v._readonly) -# -# v = cssutils.css.CSSValue(cssText='inherit', readonly=True) -# self.assert_(True is v._readonly) -# self.assert_(u'inherit', v.cssText) -# self.assertRaises(xml.dom.NoModificationAllowedErr, v._setCssText, u'x') -# self.assert_(u'inherit', v.cssText) -# -# def test_reprANDstr(self): -# "CSSValue.__repr__(), .__str__()" -# cssText='inherit' -# -# s = cssutils.css.CSSValue(cssText=cssText) -# -# self.assert_(cssText in str(s)) -# -# s2 = eval(repr(s)) -# self.assert_(isinstance(s2, s.__class__)) -# self.assert_(cssText == s2.cssText) -# -# -#class CSSPrimitiveValueTestCase(basetest.BaseTestCase): -# -# def test_init(self): -# "CSSPrimitiveValue.__init__()" -# v = cssutils.css.CSSPrimitiveValue(u'1') -# self.assert_(u'1' == v.cssText) -# -# self.assert_(v.CSS_PRIMITIVE_VALUE == v.cssValueType) -# self.assert_("CSS_PRIMITIVE_VALUE" == v.cssValueTypeString) -# -# self.assert_(v.CSS_NUMBER == v.primitiveType) -# self.assert_("CSS_NUMBER" == v.primitiveTypeString) -# -# # DUMMY to be able to test empty constructor call -# #self.assertRaises(xml.dom.SyntaxErr, v.__init__, None) -# -# self.assertRaises(xml.dom.InvalidAccessErr, v.getCounterValue) -# self.assertRaises(xml.dom.InvalidAccessErr, v.getRGBColorValue) -# self.assertRaises(xml.dom.InvalidAccessErr, v.getRectValue) -# self.assertRaises(xml.dom.InvalidAccessErr, v.getStringValue) -# -# def test_CSS_UNKNOWN(self): -# "CSSPrimitiveValue.CSS_UNKNOWN" -# v = cssutils.css.CSSPrimitiveValue(u'expression(false)') -# self.assert_(v.CSS_UNKNOWN == v.primitiveType) -# self.assert_('CSS_UNKNOWN' == v.primitiveTypeString) -# -# def test_CSS_NUMBER_AND_OTHER_DIMENSIONS(self): -# "CSSPrimitiveValue.CSS_NUMBER .. CSS_DIMENSION" -# defs = [ -# ('', 'CSS_NUMBER'), -# ('%', 'CSS_PERCENTAGE'), -# ('em', 'CSS_EMS'), -# ('ex', 'CSS_EXS'), -# ('px', 'CSS_PX'), -# ('cm', 'CSS_CM'), -# ('mm', 'CSS_MM'), -# ('in', 'CSS_IN'), -# ('pt', 'CSS_PT'), -# ('pc', 'CSS_PC'), -# ('deg', 'CSS_DEG'), -# ('rad', 'CSS_RAD'), -# ('grad', 'CSS_GRAD'), -# ('ms', 'CSS_MS'), -# ('s', 'CSS_S'), -# ('hz', 'CSS_HZ'), -# ('khz', 'CSS_KHZ'), -# ('other_dimension', 'CSS_DIMENSION') -# ] -# for dim, name in defs: -# for n in (0, 1, 1.1, -1, -1.1, -0): -# v = cssutils.css.CSSPrimitiveValue('%i%s' % (n, dim)) -# self.assertEqual(name, v.primitiveTypeString) -# self.assertEqual(getattr(v, name), v.primitiveType) -# -# def test_CSS_STRING_AND_OTHER(self): -# "CSSPrimitiveValue.CSS_STRING .. CSS_RGBCOLOR" -# defs = [ -# (('""', "''", '"some thing"', "' A\\ND '", -# # comma separated lists are STRINGS FOR NOW! -# 'a, b', -# '"a", "b"', -# ), 'CSS_STRING'), -# (('url(a)', 'url("a b")', "url(' ')"), 'CSS_URI'), -# (('some', 'or_anth-er'), 'CSS_IDENT'), -# (('attr(a)', 'attr(b)'), 'CSS_ATTR'), -# (('counter(1)', 'counter(2)'), 'CSS_COUNTER'), -# (('rect(1,2,3,4)',), 'CSS_RECT'), -# (('rgb(1,2,3)', 'rgb(10%, 20%, 30%)', '#123', '#123456'), -# 'CSS_RGBCOLOR'), -# (('rgba(1,2,3,4)','rgba(10%, 20%, 30%, 40%)', ), -# 'CSS_RGBACOLOR'), -# (('U+0', 'u+ffffff', 'u+000000-f', -# 'u+0-f, U+ee-ff'), 'CSS_UNICODE_RANGE') -# ] -# -# for examples, name in defs: -# for x in examples: -# v = cssutils.css.CSSPrimitiveValue(x) -# self.assertEqual(getattr(v, name), v.primitiveType) -# self.assertEqual(name, v.primitiveTypeString) -# -# def test_getFloat(self): -# "CSSPrimitiveValue.getFloatValue()" -# # NOT TESTED are float values as it seems difficult to -# # compare these. Maybe use decimal.Decimal? -# -# v = cssutils.css.CSSPrimitiveValue(u'1px') -# tests = { -# '0': (v.CSS_NUMBER, 0), -# '-1.1': (v.CSS_NUMBER, -1.1), -# '1%': (v.CSS_PERCENTAGE, 1), -# '-1%': (v.CSS_PERCENTAGE, -1), -# '1em': (v.CSS_EMS, 1), -# '-1.1em': (v.CSS_EMS, -1.1), -# '1ex': (v.CSS_EXS, 1), -# '1px': (v.CSS_PX, 1), -# -# '1cm': (v.CSS_CM, 1), -# '1cm': (v.CSS_MM, 10), -# '254cm': (v.CSS_IN, 100), -# '1mm': (v.CSS_MM, 1), -# '10mm': (v.CSS_CM, 1), -# '254mm': (v.CSS_IN, 10), -# '1in': (v.CSS_IN, 1), -# '100in': (v.CSS_CM, 254), # ROUNDED!!! -# '10in': (v.CSS_MM, 254), # ROUNDED!!! -# -# '1pt': (v.CSS_PT, 1), -# '1pc': (v.CSS_PC, 1), -# -# '1deg': (v.CSS_DEG, 1), -# '1rad': (v.CSS_RAD, 1), -# '1grad': (v.CSS_GRAD, 1), -# -# '1ms': (v.CSS_MS, 1), -# '1000ms': (v.CSS_S, 1), -# '1s': (v.CSS_S, 1), -# '1s': (v.CSS_MS, 1000), -# -# '1hz': (v.CSS_HZ, 1), -# '1000hz': (v.CSS_KHZ, 1), -# '1khz': (v.CSS_KHZ, 1), -# '1khz': (v.CSS_HZ, 1000), -# -# '1DIMENSION': (v.CSS_DIMENSION, 1), -# } -# for cssText in tests: -# v.cssText = cssText -# unitType, exp = tests[cssText] -# val = v.getFloatValue(unitType) -# if unitType in (v.CSS_IN, v.CSS_CM): -# val = round(val) -# self.assertEqual(val , exp) -# -# def test_setFloat(self): -# "CSSPrimitiveValue.setFloatValue()" -# V = cssutils.css.CSSPrimitiveValue -# -# tests = { -# # unitType, value -# (V.CSS_NUMBER, 1): [ -# # unitType, setvalue, -# # getvalue or expected exception, msg or cssText -# (V.CSS_NUMBER, 0, 0, '0'), -# (V.CSS_NUMBER, 0.1, 0.1, '0.1'), -# (V.CSS_NUMBER, -0, 0, '0'), -# (V.CSS_NUMBER, 2, 2, '2'), -# (V.CSS_NUMBER, 2.0, 2, '2'), -# (V.CSS_NUMBER, 2.1, 2.1, '2.1'), -# (V.CSS_NUMBER, -2.1, -2.1, '-2.1'), -# # setting with string does work -# (V.CSS_NUMBER, '1', 1, '1'), -# (V.CSS_NUMBER, '1.1', 1.1, '1.1'), -# (V.CSS_PX, 1, xml.dom.InvalidAccessErr, None), -# (V.CSS_DEG, 1, xml.dom.InvalidAccessErr, None), -# (V.CSS_RAD, 1, xml.dom.InvalidAccessErr, None), -# (V.CSS_GRAD, 1, xml.dom.InvalidAccessErr, None), -# (V.CSS_S, 1, xml.dom.InvalidAccessErr, None), -# (V.CSS_MS, 1, xml.dom.InvalidAccessErr, None), -# (V.CSS_KHZ, 1, xml.dom.InvalidAccessErr, None), -# (V.CSS_HZ, 1, xml.dom.InvalidAccessErr, None), -# (V.CSS_DIMENSION, 1, xml.dom.InvalidAccessErr, None), -# (V.CSS_MM, 2, xml.dom.InvalidAccessErr, None), -# -# (V.CSS_NUMBER, 'x', xml.dom.InvalidAccessErr, -# "CSSPrimitiveValue: floatValue 'x' is not a float"), -# (V.CSS_NUMBER, '1x', xml.dom.InvalidAccessErr, -# "CSSPrimitiveValue: floatValue '1x' is not a float"), -# -# (V.CSS_STRING, 'x', xml.dom.InvalidAccessErr, -# "CSSPrimitiveValue: unitType 'CSS_STRING' is not a float type"), -# (V.CSS_URI, 'x', xml.dom.InvalidAccessErr, -# "CSSPrimitiveValue: unitType 'CSS_URI' is not a float type"), -# (V.CSS_ATTR, 'x', xml.dom.InvalidAccessErr, -# "CSSPrimitiveValue: unitType 'CSS_ATTR' is not a float type"), -# (V.CSS_IDENT, 'x', xml.dom.InvalidAccessErr, -# "CSSPrimitiveValue: unitType 'CSS_IDENT' is not a float type"), -# (V.CSS_RGBCOLOR, 'x', xml.dom.InvalidAccessErr, -# "CSSPrimitiveValue: unitType 'CSS_RGBCOLOR' is not a float type"), -# (V.CSS_RGBACOLOR, 'x', xml.dom.InvalidAccessErr, -# "CSSPrimitiveValue: unitType 'CSS_RGBACOLOR' is not a float type"), -# (V.CSS_RECT, 'x', xml.dom.InvalidAccessErr, -# "CSSPrimitiveValue: unitType 'CSS_RECT' is not a float type"), -# (V.CSS_COUNTER, 'x', xml.dom.InvalidAccessErr, -# "CSSPrimitiveValue: unitType 'CSS_COUNTER' is not a float type"), -# (V.CSS_EMS, 1, xml.dom.InvalidAccessErr, -# "CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_NUMBER' to 'CSS_EMS'"), -# (V.CSS_EXS, 1, xml.dom.InvalidAccessErr, -# "CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_NUMBER' to 'CSS_EXS'") -# ], -# (V.CSS_MM, '1mm'): [ -# (V.CSS_MM, 2, 2, '2mm'), -# (V.CSS_MM, 0, 0, '0mm'), -# (V.CSS_MM, 0.1, 0.1, '0.1mm'), -# (V.CSS_MM, -0, -0, '0mm'), -# (V.CSS_MM, 3.0, 3, '3mm'), -# (V.CSS_MM, 3.1, 3.1, '3.1mm'), -# (V.CSS_MM, -3.1, -3.1, '-3.1mm'), -# (V.CSS_CM, 1, 10, '10mm'), -# (V.CSS_IN, 10, 254, '254mm'), -# (V.CSS_PT, 1, 1828.8, '1828.8mm'), -# (V.CSS_PX, 1, xml.dom.InvalidAccessErr, None), -# (V.CSS_NUMBER, 2, xml.dom.InvalidAccessErr, None) -# ], -# (V.CSS_PT, '1pt'): [ -# (V.CSS_PT, 2, 2, '2pt'), -# (V.CSS_PC, 12, 1, '1pt'), -# (V.CSS_NUMBER, 1, xml.dom.InvalidAccessErr, None), -# (V.CSS_DEG, 1, xml.dom.InvalidAccessErr, None), -# (V.CSS_PX, 1, xml.dom.InvalidAccessErr, None) -# ], -# (V.CSS_KHZ, '1khz'): [ -# (V.CSS_HZ, 2000, 2, '2khz'), -# (V.CSS_NUMBER, 1, xml.dom.InvalidAccessErr, None), -# (V.CSS_DEG, 1, xml.dom.InvalidAccessErr, None), -# (V.CSS_PX, 1, xml.dom.InvalidAccessErr, None) -# ] -# } -# for test in tests: -# initialType, initialValue = test -# pv = cssutils.css.CSSPrimitiveValue(initialValue) -# for setType, setValue, exp, cssText in tests[test]: -# if type(exp) == types.TypeType or\ -# type(exp) == types.ClassType: # 2.4 compatibility -# if cssText: -# self.assertRaisesMsg( -# exp, cssText, pv.setFloatValue, setType, setValue) -# else: -# self.assertRaises( -# exp, pv.setFloatValue, setType, setValue) -# else: -# pv.setFloatValue(setType, setValue) -# self.assertEqual(pv._value[0], cssText) -# if cssText == '0mm': -# cssText = '0' -# self.assertEqual(pv.cssText, cssText) -# self.assertEqual(pv.getFloatValue(initialType), exp) -# -# def test_getString(self): -# "CSSPrimitiveValue.getStringValue()" -# v = cssutils.css.CSSPrimitiveValue(u'1px') -# self.assert_(v.primitiveType == v.CSS_PX) -# self.assertRaises(xml.dom.InvalidAccessErr, -# v.getStringValue) -# -# pv = cssutils.css.CSSPrimitiveValue -# tests = { -# pv.CSS_STRING: ("'red'", 'red'), -# pv.CSS_STRING: ('"red"', 'red'), -# pv.CSS_URI: ('url(http://example.com)', None), -# pv.CSS_URI: ("url('http://example.com')", -# u"http://example.com"), -# pv.CSS_URI: ('url("http://example.com")', -# u'http://example.com'), -# pv.CSS_URI: ('url("http://example.com?)")', -# u'http://example.com?)'), -# pv.CSS_IDENT: ('red', None), -# pv.CSS_ATTR: ('attr(att-name)', -# u'att-name'), # the name of the attrr -# } -# for t in tests: -# val, exp = tests[t] -# if not exp: -# exp = val -# -# v = cssutils.css.CSSPrimitiveValue(val) -# self.assertEqual(v.primitiveType, t) -# self.assertEqual(v.getStringValue(), exp) -# -# def test_setString(self): -# "CSSPrimitiveValue.setStringValue()" -# # CSS_STRING -# v = cssutils.css.CSSPrimitiveValue(u'"a"') -# self.assert_(v.CSS_STRING == v.primitiveType) -# v.setStringValue(v.CSS_STRING, 'b') -# self.assert_(('b', 'STRING') == v._value) -# self.assertEqual('b', v.getStringValue()) -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_STRING' to 'CSS_URI'", -# v.setStringValue, *(v.CSS_URI, 'x')) -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_STRING' to 'CSS_IDENT'", -# v.setStringValue, *(v.CSS_IDENT, 'x')) -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_STRING' to 'CSS_ATTR'", -# v.setStringValue, *(v.CSS_ATTR, 'x')) -# -# # CSS_IDENT -# v = cssutils.css.CSSPrimitiveValue('new') -# v.setStringValue(v.CSS_IDENT, 'ident') -# self.assert_(v.CSS_IDENT == v.primitiveType) -# self.assert_(('ident', 'IDENT') == v._value) -# self.assert_('ident' == v.getStringValue()) -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_IDENT' to 'CSS_URI'", -# v.setStringValue, *(v.CSS_URI, 'x')) -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_IDENT' to 'CSS_STRING'", -# v.setStringValue, *(v.CSS_STRING, '"x"')) -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_IDENT' to 'CSS_ATTR'", -# v.setStringValue, *(v.CSS_ATTR, 'x')) -# -# # CSS_URI -# v = cssutils.css.CSSPrimitiveValue('url(old)') -# v.setStringValue(v.CSS_URI, '(') -# self.assertEqual((u'(', 'URI'), v._value) -# self.assertEqual(u'(', v.getStringValue()) -# -# v.setStringValue(v.CSS_URI, ')') -# self.assertEqual((u')', 'URI'), v._value) -# self.assertEqual(u')', v.getStringValue()) -# -# v.setStringValue(v.CSS_URI, '"') -# self.assertEqual(ur'"', v.getStringValue()) -# self.assertEqual((ur'"', 'URI'), v._value) -# -# v.setStringValue(v.CSS_URI, "''") -# self.assertEqual(ur"''", v.getStringValue()) -# self.assertEqual((ur"''", 'URI'), v._value) -# -# v.setStringValue(v.CSS_URI, ',') -# self.assertEqual(ur',', v.getStringValue()) -# self.assertEqual((ur',', 'URI'), v._value) -# -# v.setStringValue(v.CSS_URI, ' ') -# self.assertEqual((u' ', 'URI'), v._value) -# self.assertEqual(u' ', v.getStringValue()) -# -# v.setStringValue(v.CSS_URI, 'a)') -# self.assertEqual((u'a)', 'URI'), v._value) -# self.assertEqual(u'a)', v.getStringValue()) -# -# v.setStringValue(v.CSS_URI, 'a') -# self.assert_(v.CSS_URI == v.primitiveType) -# self.assertEqual((u'a', 'URI'), v._value) -# self.assertEqual(u'a', v.getStringValue()) -# -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_URI' to 'CSS_IDENT'", -# v.setStringValue, *(v.CSS_IDENT, 'x')) -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_URI' to 'CSS_STRING'", -# v.setStringValue, *(v.CSS_STRING, '"x"')) -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_URI' to 'CSS_ATTR'", -# v.setStringValue, *(v.CSS_ATTR, 'x')) -# -# # CSS_ATTR -# v = cssutils.css.CSSPrimitiveValue('attr(old)') -# v.setStringValue(v.CSS_ATTR, 'a') -# self.assert_(v.CSS_ATTR == v.primitiveType) -# self.assert_('a' == v.getStringValue()) -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_ATTR' to 'CSS_IDENT'", -# v.setStringValue, *(v.CSS_IDENT, 'x')) -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_ATTR' to 'CSS_STRING'", -# v.setStringValue, *(v.CSS_STRING, '"x"')) -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_ATTR' to 'CSS_URI'", -# v.setStringValue, *(v.CSS_URI, 'x')) -# -# # TypeError as 'x' is no valid type -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: stringType 'x' (UNKNOWN TYPE) is not a string type", -# v.setStringValue, *('x', 'brown')) -# # IndexError as 111 is no valid type -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: stringType 111 (UNKNOWN TYPE) is not a string type", -# v.setStringValue, *(111, 'brown')) -# # CSS_PX is no string type -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: stringType CSS_PX is not a string type", -# v.setStringValue, *(v.CSS_PX, 'brown')) -# -# def test_typeRGBColor(self): -# "RGBColor" -# v = cssutils.css.CSSPrimitiveValue('RGB(1, 5, 10)') -# self.assertEqual(v.CSS_RGBCOLOR, v.primitiveType) -# self.assertEqual(u'rgb(1, 5, 10)', v.cssText) -# -# v = cssutils.css.CSSPrimitiveValue('rgb(1, 5, 10)') -# self.assertEqual(v.CSS_RGBCOLOR, v.primitiveType) -# self.assertEqual(u'rgb(1, 5, 10)', v.cssText) -# -# v = cssutils.css.CSSPrimitiveValue('rgb(1%, 5%, 10%)') -# self.assertEqual(v.CSS_RGBCOLOR, v.primitiveType) -# self.assertEqual(u'rgb(1%, 5%, 10%)', v.cssText) -# -# v = cssutils.css.CSSPrimitiveValue(' rgb( 1 ,5, 10 )') -# self.assertEqual(v.CSS_RGBCOLOR, v.primitiveType) -# v = cssutils.css.CSSPrimitiveValue('rgb(1,5,10)') -# self.assertEqual(v.CSS_RGBCOLOR, v.primitiveType) -# v = cssutils.css.CSSPrimitiveValue('rgb(1%, .5%, 10.1%)') -# self.assertEqual(v.CSS_RGBCOLOR, v.primitiveType) -# -# def test_reprANDstr(self): -# "CSSPrimitiveValue.__repr__(), .__str__()" -# v='111' -# -# s = cssutils.css.CSSPrimitiveValue(v) -# -# self.assert_(v in str(s)) -# self.assert_('CSS_NUMBER' in str(s)) -# -# s2 = eval(repr(s)) -# self.assert_(isinstance(s2, s.__class__)) -# self.assert_(v == s2.cssText) -# -# -#class CSSValueListTestCase(basetest.BaseTestCase): -# -# def test_init(self): -# "CSSValueList.__init__()" -# v = cssutils.css.CSSValue(cssText=u'red blue') -# self.assert_(v.CSS_VALUE_LIST == v.cssValueType) -# self.assertEqual('red blue', v.cssText) -# -# self.assert_(2 == v.length) -# -# item = v.item(0) -# item.setStringValue(item.CSS_IDENT, 'green') -# self.assertEqual('green blue', v.cssText) -# -# def test_numbers(self): -# "CSSValueList.cssText" -# tests = { -# u'0 0px -0px +0px': (u'0 0 0 0', 4), -# u'1 2 3 4': (None, 4), -# u'-1 -2 -3 -4': (None, 4), -# u'-1 2': (None, 2), -# u'-1px red "x"': (None, 3), -# u'a, b c': (None, 2), -# u'1px1 2% 3': (u'1px1 2% 3', 3), -# u'f(+1pX, -2, 5%) 1': (u'f(1px, -2, 5%) 1', 2), -# u'0 f()0': (u'0 f() 0', 3), -# u'f()0': (u'f() 0', 2), -# u'f()1%': (u'f() 1%', 2), -# u'f()1px': (u'f() 1px', 2), -# u'f()"str"': (u'f() "str"', 2), -# u'f()ident': (u'f() ident', 2), -# u'f()#123': (u'f() #123', 2), -# u'f()url()': (u'f() url()', 2), -# u'f()f()': (u'f() f()', 2), -# u'url(x.gif)0 0': (u'url(x.gif) 0 0', 3), -# u'url(x.gif)no-repeat': (u'url(x.gif) no-repeat', 2) -# } -# for test in tests: -# exp, num = tests[test] -# if not exp: -# exp = test -# v = cssutils.css.CSSValue(cssText=test) -# self.assert_(v.CSS_VALUE_LIST == v.cssValueType) -# self.assertEqual(num, v.length) -# self.assertEqual(exp, v.cssText) -# -# def test_reprANDstr(self): -# "CSSValueList.__repr__(), .__str__()" -# v='1px 2px' -# -# s = cssutils.css.CSSValue(v) -# self.assert_(isinstance(s, cssutils.css.CSSValueList)) -# -# self.assert_('length=2' in str(s)) -# self.assert_(v in str(s)) -# -# # not "eval()"able! -# #s2 = eval(repr(s)) -# -# -#if __name__ == '__main__': -# import unittest -# unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_cssvariablesdeclaration.py cssutils-0.9.10/src/tests/test_cssvariablesdeclaration.py --- cssutils-0.9.10~b1/src/tests/test_cssvariablesdeclaration.py 2012-04-28 14:46:40.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_cssvariablesdeclaration.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,350 +0,0 @@ -"""Testcases for cssutils.css.cssvariablesdelaration.CSSVariablesDeclaration.""" -__version__ = '$Id: test_cssstyledeclaration.py 1869 2009-10-17 19:37:40Z cthedot $' - -import xml.dom -import basetest -import cssutils - -class CSSVariablesDeclarationTestCase(basetest.BaseTestCase): - - def setUp(self): - self.r = cssutils.css.CSSVariablesDeclaration() - cssutils.ser.prefs.useDefaults() - - def tearDown(self): - cssutils.ser.prefs.useDefaults() - - def test_init(self): - "CSSVariablesDeclaration.__init__()" - v = cssutils.css.CSSVariablesDeclaration() - self.assertEqual(u'', v.cssText) - self.assertEqual(0, v.length) - self.assertEqual(None, v.parentRule) - - v = cssutils.css.CSSVariablesDeclaration(cssText='x: 0') - self.assertEqual(u'x: 0', v.cssText) - self.assertEqual('0', v.getVariableValue('x')) - - rule = cssutils.css.CSSVariablesRule() - v = cssutils.css.CSSVariablesDeclaration(cssText='x: 0', - parentRule=rule) - self.assertEqual(rule, v.parentRule) - - def test__contains__(self): - "CSSVariablesDeclaration.__contains__(name)" - v = cssutils.css.CSSVariablesDeclaration(cssText='x: 0; y: 2') - for test in ('x', 'y'): - self.assert_(test in v) - self.assert_(test.upper() in v) - - self.assert_('z' not in v) - - def test_items(self): - "CSSVariablesDeclaration[variableName]" - v = cssutils.css.CSSVariablesDeclaration() - - value = '0' - v['X'] = value - self.assertEqual(value, v['X']) - self.assertEqual(value, v.getVariableValue('X')) - self.assertEqual(value, v['x']) - self.assertEqual(value, v.getVariableValue('x')) - - self.assertEqual(u'', v['y']) - self.assertEqual(u'', v.getVariableValue('y')) - - v['z'] = '1' - self.assertEqual(2, v.length) - - items = [] - # unsorted! - self.assertEquals(sorted(v), ['x', 'z']) - - del v['z'] - self.assertEqual(1, v.length) - self.assertEqual(1, v.length) - - self.assertEqual(u'0', v.removeVariable('x')) - self.assertEqual(u'', v.removeVariable('z')) - self.assertEqual(0, v.length) - - v.cssText = 'x:0; y:1' - keys = [] - # unsorted! - for i in range(0, v.length): - keys.append(v.item(i)) - self.assertEqual(sorted(keys), [u'x', u'y']) - - def test_keys(self): - "CSSVariablesDeclaration.keys()" - v = cssutils.css.CSSVariablesDeclaration(cssText='x: 0; Y: 2') - self.assertEqual(['x', 'y'], sorted(v.keys())) - - def test_cssText(self): - "CSSVariablesDeclaration.cssText" - # empty - tests = { - u'': u'', - u' ': u'', - u' \t \n ': u'', - u'x: 1': None, - u'x: "a"': None, - u'x: rgb(1, 2, 3)': None, - u'x: 1px 2px 3px': None, - - u'x:1': u'x: 1', - u'x:1;': u'x: 1', - - u'x : 1 ': u'x: 1', - u'x : 1 ; ': u'x: 1', - - u'x:1;y:2': u'x: 1;\ny: 2', - u'x:1;y:2;': u'x: 1;\ny: 2', - u'x : 1 ; y : 2 ': u'x: 1;\ny: 2', - u'x : 1 ; y : 2 ; ': u'x: 1;\ny: 2', - - u'/*x*/': u'/*x*/', - u'x555: 5': None, - u'xxx:1;yyy:2': u'xxx: 1;\nyyy: 2', - u'xxx : 1; yyy : 2': u'xxx: 1;\nyyy: 2', - u'x:1;x:2;X:2': u'x: 2', - u'same:1;SAME:2;': u'same: 2', - u'/**/x/**/:/**/1/**/;/**/y/**/:/**/2/**/': - u'/**/ \n /**/ \n /**/ \n x: 1 /**/;\n/**/ \n /**/ \n /**/ \n y: 2 /**/' - } - self.do_equal_r(tests) - - # TODO: Fix? -# def test_cssText2(self): -# "CSSVariablesDeclaration.cssText" -# # exception -# tests = { -# u'top': xml.dom.SyntaxErr, -# u'top:': xml.dom.SyntaxErr, -# u'top : ': xml.dom.SyntaxErr, -# u'top:;': xml.dom.SyntaxErr, -# u'top 0': xml.dom.SyntaxErr, -# u'top 0;': xml.dom.SyntaxErr, -# -# u':': xml.dom.SyntaxErr, -# u':0': xml.dom.SyntaxErr, -# u':0;': xml.dom.SyntaxErr, -# u':;': xml.dom.SyntaxErr, -# u': ;': xml.dom.SyntaxErr, -# -# u'0': xml.dom.SyntaxErr, -# u'0;': xml.dom.SyntaxErr, -# -# u';': xml.dom.SyntaxErr, -# } -# self.do_raise_r(tests) - - def test_xVariable(self): - "CSSVariablesDeclaration.xVariable()" - v = cssutils.css.CSSVariablesDeclaration() - # unset - self.assertEqual(u'', v.getVariableValue('x')) - # set - v.setVariable('x', '0') - self.assertEqual(u'0', v.getVariableValue('x')) - self.assertEqual(u'0', v.getVariableValue('X')) - self.assertEqual(u'x: 0', v.cssText) - v.setVariable('X', '0') - self.assertEqual(u'0', v.getVariableValue('x')) - self.assertEqual(u'0', v.getVariableValue('X')) - self.assertEqual(u'x: 0', v.cssText) - # remove - self.assertEqual(u'0', v.removeVariable('x')) - self.assertEqual(u'', v.removeVariable('x')) - self.assertEqual(u'', v.getVariableValue('x')) - self.assertEqual(u'', v.cssText) - - - def test_imports(self): - "CSSVariables imports" - def fetcher(url): - url = url.replace('\\', '/') - url = url[url.rfind('/')+1:] - return (None, { - '3.css': ''' - @variables { - over3-2-1-0: 3; - over3-2-1: 3; - over3-2: 3; - over3-2-0: 3; - over3-1: 3; - over3-1-0: 3; - over3-0: 3; - local3: 3; - } - - ''', - '2.css': ''' - @variables { - over3-2-1-0: 2; - over3-2-1: 2; - over3-2-0: 2; - over3-2: 2; - over2-1: 2; - over2-1-0: 2; - over2-0: 2; - local2: 2; - } - - ''', - '1.css': ''' - @import "3.css"; - @import "2.css"; - @variables { - over3-2-1-0: 1; - over3-2-1: 1; - over3-1: 1; - over3-1-0: 1; - over2-1: 1; - over2-1-0: 1; - over1-0: 1; - local1: 1; - } - - ''' - }[url]) - - css = ''' - @import "1.css"; - @variables { - over3-2-1-0: 0; - over3-2-0: 0; - over3-1-0: 0; - over2-1-0: 0; - over3-0: 0; - over2-0: 0; - over1-0: 0; - local0: 0; - } - a { - local0: var(local0); - local1: var(local1); - local2: var(local2); - local3: var(local3); - over1-0: var(over1-0); - over2-0: var(over2-0); - over3-0: var(over3-0); - over2-1: var(over2-1); - over3-1: var(over3-1); - over3-2: var(over3-2); - over2-1-0: var(over2-1-0); - over3-2-0: var(over3-2-0); - over3-2-1: var(over3-2-1); - over3-2-1-0: var(over3-2-1-0); - } - ''' - p = cssutils.CSSParser(fetcher=fetcher) - s = p.parseString(css) - - # only these in rule of this sheet - self.assertEqual(s.cssRules[1].variables.length, 8) - # but all vars in s available! - self.assertEqual(s.variables.length, 15) - self.assertEqual([u'local0', u'local1', u'local2', u'local3', - u'over1-0', u'over2-0', u'over2-1', u'over2-1-0', - u'over3-0', u'over3-1', u'over3-1-0', u'over3-2', - u'over3-2-0', u'over3-2-1', u'over3-2-1-0'], - sorted(s.variables.keys())) - - - # test with variables rule - cssutils.ser.prefs.resolveVariables = False - self.assertEqual(s.cssText, '''@import "1.css"; -@variables { - over3-2-1-0: 0; - over3-2-0: 0; - over3-1-0: 0; - over2-1-0: 0; - over3-0: 0; - over2-0: 0; - over1-0: 0; - local0: 0 - } -a { - local0: var(local0); - local1: var(local1); - local2: var(local2); - local3: var(local3); - over1-0: var(over1-0); - over2-0: var(over2-0); - over3-0: var(over3-0); - over2-1: var(over2-1); - over3-1: var(over3-1); - over3-2: var(over3-2); - over2-1-0: var(over2-1-0); - over3-2-0: var(over3-2-0); - over3-2-1: var(over3-2-1); - over3-2-1-0: var(over3-2-1-0) - }'''.encode()) - - # test with resolved vars - cssutils.ser.prefs.resolveVariables = True - self.assertEqual(s.cssText, '''@import "1.css"; -a { - local0: 0; - local1: 1; - local2: 2; - local3: 3; - over1-0: 0; - over2-0: 0; - over3-0: 0; - over2-1: 1; - over3-1: 1; - over3-2: 2; - over2-1-0: 0; - over3-2-0: 0; - over3-2-1: 1; - over3-2-1-0: 0 - }'''.encode()) - - - s = cssutils.resolveImports(s) - self.assertEqual(s.cssText, '''/* START @import "1.css" */ -/* START @import "3.css" */ -/* START @import "2.css" */ -a { - local0: 0; - local1: 1; - local2: 2; - local3: 3; - over1-0: 0; - over2-0: 0; - over3-0: 0; - over2-1: 1; - over3-1: 1; - over3-2: 2; - over2-1-0: 0; - over3-2-0: 0; - over3-2-1: 1; - over3-2-1-0: 0 - }'''.encode()) - - def test_parentRule(self): - "CSSVariablesDeclaration.parentRule" - s = cssutils.parseString(u'@variables { a:1}') - r = s.cssRules[0] - d = r.variables - self.assertEqual(r, d.parentRule) - - d2 = cssutils.css.CSSVariablesDeclaration('b: 2') - r.variables = d2 - self.assertEqual(r, d2.parentRule) - - def test_reprANDstr(self): - "CSSVariablesDeclaration.__repr__(), .__str__()" - s = cssutils.css.CSSVariablesDeclaration(cssText='a:1;b:2') - - self.assert_("2" in str(s)) # length - - s2 = eval(repr(s)) - self.assert_(isinstance(s2, s.__class__)) - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_cssvariablesrule.py cssutils-0.9.10/src/tests/test_cssvariablesrule.py --- cssutils-0.9.10~b1/src/tests/test_cssvariablesrule.py 2011-07-24 18:24:06.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_cssvariablesrule.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,155 +0,0 @@ -"""Testcases for cssutils.css.CSSPageRule""" -__version__ = '$Id: test_csspagerule.py 1869 2009-10-17 19:37:40Z cthedot $' - -import xml.dom -import test_cssrule -import cssutils - -class CSSVariablesRuleTestCase(test_cssrule.CSSRuleTestCase): - - def setUp(self): - super(CSSVariablesRuleTestCase, self).setUp() - self.r = cssutils.css.CSSVariablesRule() - self.rRO = cssutils.css.CSSVariablesRule(readonly=True) - self.r_type = cssutils.css.CSSPageRule.VARIABLES_RULE - self.r_typeString = 'VARIABLES_RULE' - - cssutils.ser.prefs.resolveVariables = False - - def test_init(self): - "CSSVariablesRule.__init__()" - super(CSSVariablesRuleTestCase, self).test_init() - - r = cssutils.css.CSSVariablesRule() - self.assertEqual(cssutils.css.CSSVariablesDeclaration, - type(r.variables)) - self.assertEqual(r, r.variables.parentRule) - - # until any variables - self.assertEqual(u'', r.cssText) - - # only possible to set @... similar name - self.assertRaises(xml.dom.InvalidModificationErr, - self.r._setAtkeyword, 'x') - - def test_InvalidModificationErr(self): - "CSSVariablesRule.cssText InvalidModificationErr" - self._test_InvalidModificationErr(u'@variables') - tests = { - u'@var {}': xml.dom.InvalidModificationErr, - } - self.do_raise_r(tests) - - def test_incomplete(self): - "CSSVariablesRule (incomplete)" - tests = { - u'@variables { ': - u'', # no } and no content - u'@variables { x: red': - u'@variables {\n x: red\n }', # no } - } - self.do_equal_p(tests) # parse - - def test_cssText(self): - "CSSVariablesRule" - EXP = u'@variables {\n margin: 0\n }' - tests = { - u'@variables {}': u'', - u'@variables {margin:0;}': EXP, - u'@variables {margin:0}': EXP, - u'@VaRIables { margin : 0 ; }': EXP, - u'@\\VaRIables { margin : 0 }': EXP, - - u'@variables {a:1;b:2}': - u'@variables {\n a: 1;\n b: 2\n }', - - # comments - u'@variables /*1*/ {margin:0;}': - u'@variables /*1*/ {\n margin: 0\n }', - u'@variables/*1*/{margin:0;}': - u'@variables /*1*/ {\n margin: 0\n }', - } - self.do_equal_r(tests) - self.do_equal_p(tests) - - def test_media(self): - "CSSVariablesRule.media" - r = cssutils.css.CSSVariablesRule() - self.assertRaises(AttributeError, r.__getattribute__, 'media') - self.assertRaises(AttributeError, r.__setattr__, 'media', '?') - - def test_variables(self): - "CSSVariablesRule.variables" - r = cssutils.css.CSSVariablesRule( - variables=cssutils.css.CSSVariablesDeclaration('x: 1')) - self.assertEqual(r, r.variables.parentRule) - - # cssText - r = cssutils.css.CSSVariablesRule() - r.cssText = u'@variables { x: 1 }' - vars1 = r.variables - self.assertEqual(r, r.variables.parentRule) - self.assertEqual(vars1, r.variables) - self.assertEqual(r.variables.cssText, u'x: 1') - self.assertEqual(r.cssText, u'@variables {\n x: 1\n }') - - r.cssText = u'@variables {y:2}' - self.assertEqual(r, r.variables.parentRule) - self.failIfEqual(vars1, r.variables) - self.assertEqual(r.variables.cssText, u'y: 2') - self.assertEqual(r.cssText, u'@variables {\n y: 2\n }') - - vars2 = r.variables - - # fail - try: - r.cssText = u'@variables {$:1}' - except xml.dom.DOMException, e: - pass - - self.assertEqual(vars2, r.variables) - self.assertEqual(r.variables.cssText, u'y: 2') - self.assertEqual(r.cssText, u'@variables {\n y: 2\n }') - - # var decl - vars3 = cssutils.css.CSSVariablesDeclaration('z: 3') - r.variables = vars3 - - self.assertEqual(r, r.variables.parentRule) - self.assertEqual(vars3, r.variables) - self.assertEqual(r.variables.cssText, u'z: 3') - self.assertEqual(r.cssText, u'@variables {\n z: 3\n }') - - # string - r.variables = 'a: x' - self.failIfEqual(vars3, r.variables) - self.assertEqual(r, r.variables.parentRule) - self.assertEqual(r.variables.cssText, u'a: x') - self.assertEqual(r.cssText, u'@variables {\n a: x\n }') - vars4 = r.variables - - # string fail - try: - r.variables = '$: x' - except xml.dom.DOMException, e: - pass - self.assertEqual(vars4, r.variables) - self.assertEqual(r, r.variables.parentRule) - self.assertEqual(r.variables.cssText, u'a: x') - self.assertEqual(r.cssText, u'@variables {\n a: x\n }') - - - def test_reprANDstr(self): - "CSSVariablesRule.__repr__(), .__str__()" - r = cssutils.css.CSSVariablesRule() - r.cssText = '@variables { xxx: 1 }' - self.assert_('xxx' in str(r)) - - r2 = eval(repr(r)) - self.assert_(isinstance(r2, r.__class__)) - self.assert_(r.cssText == r2.cssText) - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_domimplementation.py cssutils-0.9.10/src/tests/test_domimplementation.py --- cssutils-0.9.10~b1/src/tests/test_domimplementation.py 2011-07-26 18:22:54.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_domimplementation.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ -"""Testcases for cssutils.css.DOMImplementation""" - -import xml.dom -import unittest -import cssutils - -class DOMImplementationTestCase(unittest.TestCase): - - def setUp(self): - self.domimpl = xml.dom.getDOMImplementation() - - def test_createCSSStyleSheet(self): - "DOMImplementationCSS.createCSSStyleSheet()" - title, media = 'Test Title', cssutils.stylesheets.MediaList('all') - sheet = self.domimpl.createCSSStyleSheet(title, media) - self.assertEqual(True, isinstance(sheet, cssutils.css.CSSStyleSheet)) - self.assertEqual(title, sheet.title) - self.assertEqual(media, sheet.media) - - def test_createDocument(self): - "DOMImplementationCSS.createDocument()" - self.assertRaises(NotImplementedError, self.domimpl.createDocument) - self.assertRaises(NotImplementedError, self.domimpl.createDocument) - - def test_createDocumentType(self): - "DOMImplementationCSS.createDocumentType()" - self.assertRaises(NotImplementedError, self.domimpl.createDocumentType) - - def test_hasFeature(self): - "DOMImplementationCSS.hasFeature()" - tests = [ - ('css', '1.0'), - ('css', '2.0'), - ('stylesheets', '1.0'), - ('stylesheets', '2.0') - ] - for name, version in tests: - self.assertEqual(True, self.domimpl.hasFeature(name, version)) - - -if __name__ == '__main__': - unittest.main() \ No newline at end of file diff -Nru cssutils-0.9.10~b1/src/tests/test_encutils/__init__.py cssutils-0.9.10/src/tests/test_encutils/__init__.py --- cssutils-0.9.10~b1/src/tests/test_encutils/__init__.py 2011-07-26 18:19:56.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_encutils/__init__.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,408 +0,0 @@ -# -*- coding: utf-8 -*- -""" -tests for encutils.py -""" -import httplib -from StringIO import StringIO -import sys -import unittest - -PY2x = sys.version_info < (3,0) - -try: - import cssutils.encutils as encutils -except ImportError: - import encutils - -# helper log -log = encutils.buildlog(stream=StringIO()) - -class AutoEncodingTestCase(unittest.TestCase): - - def _fakeRes(self, content): - "build a fake HTTP response" - class FakeRes: - def __init__(self, content): - if PY2x: - fp = StringIO(content) - self._info = httplib.HTTPMessage(fp) - else: - self._info = httplib.HTTPMessage() - # Adjust to testdata. - l = content.split(':') - if len(l) > 1: - # Get the type by just - # using the data at the end. - t = l[-1].strip() - self._info.set_type(t) - - def info(self): - return self._info - - def read(self): - return content - - return FakeRes(content) - - def test_getTextTypeByMediaType(self): - "encutils._getTextTypeByMediaType" - tests = { - 'application/xml': encutils._XML_APPLICATION_TYPE, - 'application/xml-dtd': encutils._XML_APPLICATION_TYPE, - 'application/xml-external-parsed-entity': encutils._XML_APPLICATION_TYPE, - 'application/xhtml+xml': encutils._XML_APPLICATION_TYPE, - 'text/xml': encutils._XML_TEXT_TYPE, - 'text/xml-external-parsed-entity': encutils._XML_TEXT_TYPE, - 'text/xhtml+xml': encutils._XML_TEXT_TYPE, - 'text/html': encutils._HTML_TEXT_TYPE, - 'text/css': encutils._TEXT_UTF8, - 'text/plain': encutils._TEXT_TYPE, - 'x/x': encutils._OTHER_TYPE, - 'ANYTHING': encutils._OTHER_TYPE - } - for test, exp in tests.items(): - self.assertEqual( - exp, encutils._getTextTypeByMediaType(test, log=log)) - - def test_getTextType(self): - "encutils._getTextType" - tests = { - u'\x00\x00\xFE\xFF""": - (None, None), - """""": - (None, None), - - """""": - ('text/html', None), - - """""": - ('text/html', None), - """""": - ('text/html', 'ascii'), - - """""": - ('text/html', 'ascii'), - """""": - ('text/html', 'iso-8859-1'), - """""": - ('text/html', 'ascii'), - - """""": - ('text/html', 'ascii'), - """""": - ('text/html', 'ascii'), - """""": - ('text/html', 'ascii'), - - """""": - ('text/html', 'ascii'), - """""": - ('text/html', 'ascii'), - """""": - ('text/html', 'ascii'), - """""": - ('text/html', 'ascii'), - - """""": - ('text/html', 'ascii'), - """""": - ('text/html', 'ascii'), - """raises exception: """: - (None, None), - """ - """: - ('text/html', 'ascii'), - """ - """: - (None, None), - """ - - """: - ('text/html', None) - } - for test, exp in tests.items(): - self.assertEqual(exp, encutils.getMetaInfo(test, log=log)) - - def test_detectXMLEncoding(self): - "encutils.detectXMLEncoding" - tests = { - # BOM - ('utf_32_be'): u'\x00\x00\xFE\xFFanything', - ('utf_32_le'): u'\xFF\xFE\x00\x00anything', - ('utf_16_be'): u'\xFE\xFFanything', - ('utf_16_le'): u'\xFF\xFEanything', - ('utf-8'): u'\xef\xbb\xbfanything', - # encoding= - ('ascii'): '', - ('ascii'): "", - ('iso-8859-1'): "", - # default - ('utf-8'): '', - ('utf-8'): '' - } - for exp, test in tests.items(): - self.assertEqual(exp, encutils.detectXMLEncoding(test, log=log)) - - def test_tryEncodings(self): - "encutils.tryEncodings" - try: - import chardet - tests = [ - ('ascii', u'abc'.encode('ascii')), - ('windows-1252', u'€'.encode('windows-1252')), - ('ascii', u'1'.encode('utf-8')) - ] - except ImportError: - tests = [ - ('ascii', u'abc'.encode('ascii')), - ('windows-1252', u'€'.encode('windows-1252')), - ('iso-8859-1', u'äöüß'.encode('iso-8859-1')), - ('iso-8859-1', u'äöüß'.encode('windows-1252')), - #('utf-8', u'\u1111'.encode('utf-8')) - ] - for exp, test in tests: - self.assertEqual(exp, encutils.tryEncodings(test)) - - - def test_getEncodingInfo(self): - "encutils.getEncodingInfo" - # (expectedencoding, expectedmismatch): (httpheader, filecontent) - tests = [ - - # --- application/xhtml+xml --- - - # header default and XML default - (('utf-8', False), ( - '''Content-Type: application/xhtml+xml''', - ''' - - - ''')), - # XML default - (('utf-8', False), ( - None, - ''' - - - ''')), - # meta is ignored! - (('utf-8', False), ( - '''Content-Type: application/xhtml+xml''', - ''' - - - ''')), - - # header enc and XML default - (('iso-h', True), ( - '''Content-Type: application/xhtml+xml;charset=iso-H''', - ''' - - - ''')), - - # mismatch header and XML explicit, header wins - (('iso-h', True), ( - '''Content-Type: application/xhtml+xml;charset=iso-H''', - ''' - ''')), - - # header == XML, meta ignored! - (('iso-h', False), ( - '''Content-Type: application/xhtml+xml;charset=iso-H''', - ''' - - - ''')), - - # XML only, meta ignored! - (('iso-x', False), ( - '''Content-Type: application/xhtml+xml''', - ''' - - - ''')), - - - # no text or not enough text: - (('iso-h', False), ('Content-Type: application/xml;charset=iso-h', - '1')), - (('utf-8', False), ('Content-Type: application/xml', - None)), - ((None, False), ('Content-Type: application/xml', - '1')), - - - # --- text/xml --- - - # default enc - (('ascii', False), ( - '''Content-Type: text/xml''', - ''' - - - ''')), - # default as XML ignored and meta completely ignored - (('ascii', False), ( - '''Content-Type: text/xml''', - ''' - - - ''')), - (('ascii', False), ('Content-Type: text/xml', - '1')), - (('ascii', False), ('Content-Type: text/xml', - None)), - - # header enc - (('iso-h', False), ( - '''Content-Type: text/xml;charset=iso-H''', - ''' - - - ''')), - - # header only, XML and meta ignored! - (('iso-h', False), ( - '''Content-Type: text/xml;charset=iso-H''', - ''' - ''')), - (('iso-h', False), ( - '''Content-Type: text/xml;charset=iso-H''', - ''' - - - ''')), - - - # --- text/html --- - - # default enc - (('iso-8859-1', False), ('Content-Type: text/html;', - '''''')), - (('iso-8859-1', False), ('Content-Type: text/html;', - None)), - - # header enc - (('iso-h', False), ('Content-Type: text/html;charset=iso-H', - '''''')), - # meta enc - (('iso-m', False), ('Content-Type: text/html', - '''''')), - - # mismatch header and meta, header wins - (('iso-h', True), ('Content-Type: text/html;charset=iso-H', - '''''')), - - # no header: - ((None, False), (None, - '''''')), - # no encoding at all - ((None, False), (None, - '''''')), - - - ((None, False), (None, - '''text''')), - - - # --- no header --- - - ((None, False), (None, '')), - (('iso-8859-1', False), ('''NoContentType''', - '''OnlyText''')), - (('iso-8859-1', False), ('Content-Type: text/html;', - None)), - (('iso-8859-1', False), ('Content-Type: text/html;', - '1')), - - # XML - (('utf-8', False), (None, - '''''')), - # meta ignored - (('utf-8', False), (None, - ''' - ''')), - - (('utf-8', False), ('Content-Type: text/css;', - '1')), - (('iso-h', False), ('Content-Type: text/css;charset=iso-h', - '1')), - # only header is used by encutils - (('utf-8', False), ('Content-Type: text/css', - '@charset "ascii";')), - - ] - for exp, test in tests: - header, text = test - if header: - res = encutils.getEncodingInfo(self._fakeRes(header), text) - else: - res = encutils.getEncodingInfo(text=text) - - res = (res.encoding, res.mismatch) - self.assertEqual(exp, res) - - -if __name__ == '__main__': - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_errorhandler.py cssutils-0.9.10/src/tests/test_errorhandler.py --- cssutils-0.9.10~b1/src/tests/test_errorhandler.py 2012-03-24 22:35:56.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_errorhandler.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,150 +0,0 @@ -"""Tests for parsing which does not raise Exceptions normally""" -__version__ = '$Id: test_parse.py 1281 2008-06-04 21:12:29Z cthedot $' - -import logging -import StringIO -import sys -import xml.dom -import basetest -import cssutils - -class ErrorHandlerTestCase(basetest.BaseTestCase): - - def setUp(self): - "replace default log and ignore its output" - self._oldlog = cssutils.log._log - self._saved = cssutils.log.raiseExceptions - - cssutils.log.raiseExceptions = False - cssutils.log.setLog(logging.getLogger('IGNORED-CSSUTILS-TEST')) - - def tearDown(self): - "reset default log" - cssutils.log.setLog(self._oldlog) - # for tests only - cssutils.log.setLevel(logging.FATAL) - cssutils.log.raiseExceptions = self._saved - - def _setHandler(self): - "sets new handler and returns StringIO instance to getvalue" - s = StringIO.StringIO() - h = logging.StreamHandler(s) - h.setFormatter(logging.Formatter('%(levelname)s %(message)s')) - # remove if present already - cssutils.log.removeHandler(h) - cssutils.log.addHandler(h) - return s - - def test_calls(self): - "cssutils.log.*" - s = self._setHandler() - cssutils.log.setLevel(logging.DEBUG) - cssutils.log.debug('msg', neverraise=True) - self.assertEqual(s.getvalue(), u'DEBUG msg\n') - - s = self._setHandler() - cssutils.log.setLevel(logging.INFO) - cssutils.log.info('msg', neverraise=True) - self.assertEqual(s.getvalue(), u'INFO msg\n') - - s = self._setHandler() - cssutils.log.setLevel(logging.WARNING) - cssutils.log.warn('msg', neverraise=True) - self.assertEqual(s.getvalue(), u'WARNING msg\n') - - s = self._setHandler() - cssutils.log.setLevel(logging.ERROR) - cssutils.log.error('msg', neverraise=True) - self.assertEqual(s.getvalue(), u'ERROR msg\n') - - s = self._setHandler() - cssutils.log.setLevel(logging.FATAL) - cssutils.log.fatal('msg', neverraise=True) - self.assertEqual(s.getvalue(), u'CRITICAL msg\n') - - s = self._setHandler() - cssutils.log.setLevel(logging.CRITICAL) - cssutils.log.critical('msg', neverraise=True) - self.assertEqual(s.getvalue(), u'CRITICAL msg\n') - - s = self._setHandler() - cssutils.log.setLevel(logging.CRITICAL) - cssutils.log.error('msg', neverraise=True) - self.assertEqual(s.getvalue(), u'') - - def test_linecol(self): - "cssutils.log line col" - o = cssutils.log.raiseExceptions - cssutils.log.raiseExceptions = True - - s = cssutils.css.CSSStyleSheet() - try: - s.cssText = '@import x;' - except xml.dom.DOMException, e: - self.assertEqual(str(e), 'CSSImportRule: Unexpected ident. [1:9: x]') - self.assertEqual(e.line, 1) - self.assertEqual(e.col, 9) - if sys.platform.startswith('java'): - self.assertEqual(e.msg, u'CSSImportRule: Unexpected ident. [1:9: x]') - else: - self.assertEqual(e.args, (u'CSSImportRule: Unexpected ident. [1:9: x]',)) - - cssutils.log.raiseExceptions = o - - def test_handlers(self): - "cssutils.log" - s = self._setHandler() - - cssutils.log.setLevel(logging.FATAL) - self.assertEqual(cssutils.log.getEffectiveLevel(), logging.FATAL) - - cssutils.parseString('a { color: 1 }') - self.assertEqual(s.getvalue(), u'') - - cssutils.log.setLevel(logging.DEBUG) - cssutils.parseString('a { color: 1 }') - # TODO: Fix? -# self.assertEqual(s.getvalue(), -# u'ERROR Property: Invalid value for "CSS Color Module Level 3/CSS Level 2.1" property: 1 [1:5: color]\n') - self.assertEqual(s.getvalue(), - u'ERROR Property: Invalid value for "CSS Level 2.1" property: 1 [1:5: color]\n') - - s = self._setHandler() - - cssutils.log.setLevel(logging.ERROR) - cssutils.parseUrl('http://example.com') - self.assertEqual(s.getvalue()[:38], - u'ERROR Expected "text/css" mime type') - - def test_parsevalidation(self): - style = 'color: 1' - t = 'a { %s }' % style - - cssutils.log.setLevel(logging.DEBUG) - - # sheet - s = self._setHandler() - cssutils.parseString(t) - self.assertNotEqual(len(s.getvalue()), 0) - - s = self._setHandler() - cssutils.parseString(t, validate=False) - self.assertEqual(s.getvalue(), '') - - # style - s = self._setHandler() - cssutils.parseStyle(style) - self.assertNotEqual(len(s.getvalue()), 0) - - s = self._setHandler() - cssutils.parseStyle(style, validate=True) - self.assertNotEqual(len(s.getvalue()), 0) - - s = self._setHandler() - cssutils.parseStyle(style, validate=False) - self.assertEqual(s.getvalue(), '') - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_helper.py cssutils-0.9.10/src/tests/test_helper.py --- cssutils-0.9.10~b1/src/tests/test_helper.py 2011-07-24 18:24:06.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_helper.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,89 +0,0 @@ -# -*- coding: utf-8 -*- -"""Testcases for cssutils.helper""" -__version__ = '$Id: test_util.py 1437 2008-08-18 20:30:38Z cthedot $' - -import basetest -from cssutils.helper import * - -class HelperTestCase(basetest.BaseTestCase): - - def test_normalize(self): - "helper._normalize()" - tests = {u'abcdefg ABCDEFG äöü߀ AÖÜ': ur'abcdefg abcdefg äöü߀ aöü', - ur'\ga\Ga\\\ ': ur'gaga\ ', - ur'0123456789': ur'0123456789', - ur'"\x"': ur'"x"', - # unicode escape seqs should have been done by - # the tokenizer... - } - for test, exp in tests.items(): - self.assertEqual(normalize(test), exp) - # static too - self.assertEqual(normalize(test), exp) - -# def test_normalnumber(self): -# "helper.normalnumber()" -# tests = { -# '0': '0', -# '00': '0', -# '0.0': '0', -# '00.0': '0', -# '1': '1', -# '01': '1', -# '00.1': '0.1', -# '0.00001': '0.00001', -# '-0': '0', -# '-00': '0', -# '-0.0': '0', -# '-00.0': '0', -# '-1': '-1', -# '-01': '-1', -# '-00.1': '-0.1', -# '-0.00001': '-0.00001', -# } -# for test, exp in tests.items(): -# self.assertEqual(exp, normalnumber(test)) - - def test_string(self): - "helper.string()" - self.assertEqual(u'"x"', string(u'x')) - self.assertEqual(u'"1 2ä€"', string(u'1 2ä€')) - self.assertEqual(ur'''"'"''', string(u"'")) - self.assertEqual(ur'"\""', string(u'"')) - # \n = 0xa, \r = 0xd, \f = 0xc - self.assertEqual(ur'"\a "', string(''' -''')) - self.assertEqual(ur'"\c "', string('\f')) - self.assertEqual(ur'"\d "', string('\r')) - self.assertEqual(ur'"\d \a "', string('\r\n')) - - def test_stringvalue(self): - "helper.stringvalue()" - self.assertEqual(u'x', stringvalue(u'"x"')) - self.assertEqual(u'"', stringvalue(u'"\\""')) - self.assertEqual(ur'x', stringvalue(ur"\x ")) - - # escapes should have been done by tokenizer - # so this shoule not happen at all: - self.assertEqual(ur'a', stringvalue(ur"\a ")) - - def test_uri(self): - "helper.uri()" - self.assertEqual(u'url(x)', uri('x')) - self.assertEqual(u'url("(")', uri('(')) - self.assertEqual(u'url(")")', uri(')')) - self.assertEqual(u'url(" ")', uri(' ')) - self.assertEqual(u'url(";")', uri(';')) - self.assertEqual(u'url(",")', uri(',')) - self.assertEqual(u'url("x)x")', uri('x)x')) - - def test_urivalue(self): - "helper.urivalue()" - self.assertEqual(u'x', urivalue('url(x)')) - self.assertEqual(u'x', urivalue('url("x")')) - self.assertEqual(u')', urivalue('url(")")')) - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_marginrule.py cssutils-0.9.10/src/tests/test_marginrule.py --- cssutils-0.9.10~b1/src/tests/test_marginrule.py 2011-12-25 18:21:42.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_marginrule.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,97 +0,0 @@ -"""Testcases for cssutils.css.CSSPageRule""" - -import xml.dom -import test_cssrule -import cssutils - -class MarginRuleTestCase(test_cssrule.CSSRuleTestCase): - - def setUp(self): - super(MarginRuleTestCase, self).setUp() - - cssutils.ser.prefs.useDefaults() - self.r = cssutils.css.MarginRule() - self.rRO = cssutils.css.MarginRule(readonly=True) - self.r_type = cssutils.css.MarginRule.MARGIN_RULE - self.r_typeString = 'MARGIN_RULE' - - def tearDown(self): - cssutils.ser.prefs.useDefaults() - - def test_init(self): - "MarginRule.__init__()" - - r = cssutils.css.MarginRule() - self.assertEqual(r.margin, None) - self.assertEqual(r.atkeyword, None) - self.assertEqual(r._keyword, None) - self.assertEqual(r.style.cssText, u'') - self.assertEqual(r.cssText, u'') - - r = cssutils.css.MarginRule(margin=u'@TOP-left') - self.assertEqual(r.margin, u'@top-left') - self.assertEqual(r.atkeyword, u'@top-left') - self.assertEqual(r._keyword, u'@TOP-left') - self.assertEqual(r.style.cssText, u'') - self.assertEqual(r.cssText, u'') - - self.assertRaises(xml.dom.InvalidModificationErr, cssutils.css.MarginRule, u'@x') - - def test_InvalidModificationErr(self): - "MarginRule.cssText InvalidModificationErr" - # TODO: !!! -# self._test_InvalidModificationErr(u'@top-left') -# tests = { -# u'@x {}': xml.dom.InvalidModificationErr, -# } -# self.do_raise_r(tests) - - def test_incomplete(self): - "MarginRule (incomplete)" - # must be inside @page as not valid outside - tests = { - u'@page { @top-left { ': u'', # no } and no content - u'@page { @top-left { /*1*/ ': u'', # no } and no content - u'@page { @top-left { color: red': - u'@page {\n @top-left {\n color: red\n }\n }' - } - self.do_equal_p(tests) # parse - - def test_cssText(self): - tests = { - u'@top-left {}': u'', - u'@top-left { /**/ }': u'', - u'@top-left { color: red }': u'@top-left {\n color: red\n }', - u'@top-left{color:red;}': u'@top-left {\n color: red\n }', - u'@top-left{color:red}': u'@top-left {\n color: red\n }', - u'@top-left { color: red; left: 0 }': u'@top-left {\n color: red;\n left: 0\n }' - } - self.do_equal_r(tests) - - # TODO - tests.update({ - # false selector -# u'@top-left { color:': xml.dom.SyntaxErr, # no } -# u'@top-left { color': xml.dom.SyntaxErr, # no } -# u'@top-left {': xml.dom.SyntaxErr, # no } -# u'@top-left': xml.dom.SyntaxErr, # no } -# u'@top-left;': xml.dom.SyntaxErr, # no } - }) -# self.do_raise_r(tests) # set cssText - - - def test_reprANDstr(self): - "MarginRule.__repr__(), .__str__()" - margin = u'@top-left' - - s = cssutils.css.MarginRule(margin=margin, style=u'left: 0') - - self.assert_(margin in str(s)) - - s2 = eval(repr(s)) - self.assert_(isinstance(s2, s.__class__)) - self.assert_(margin == s2.margin) - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_medialist.py cssutils-0.9.10/src/tests/test_medialist.py --- cssutils-0.9.10~b1/src/tests/test_medialist.py 2011-07-26 18:22:54.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_medialist.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,196 +0,0 @@ -# -*- coding: iso-8859-1 -*- -"""Testcases for cssutils.stylesheets.MediaList""" - -import xml.dom -import basetest -import cssutils.stylesheets - -class MediaListTestCase(basetest.BaseTestCase): - - def setUp(self): - super(MediaListTestCase, self).setUp() - self.r = cssutils.stylesheets.MediaList() - - def test_set(self): - "MediaList.mediaText 1" - ml = cssutils.stylesheets.MediaList() - - self.assertEqual(0, ml.length) - self.assertEqual(u'all', ml.mediaText) - - ml.mediaText = u' print , screen ' - self.assertEqual(2, ml.length) - self.assertEqual(u'print, screen', ml.mediaText) - - self.assertRaisesMsg(xml.dom.InvalidModificationErr, - basetest.msg3x('''MediaList: Ignoring new medium cssutils.stylesheets.MediaQuery(mediaText=u'tv') as already specified "all" (set ``mediaText`` instead).'''), - ml._setMediaText, u' print , all , tv ') - - self.assertEqual(u'all', ml.mediaText) - self.assertEqual(1, ml.length) - - self.assertRaises(xml.dom.InvalidCharacterErr, - ml.appendMedium, u'test') - - def test_appendMedium(self): - "MediaList.appendMedium() 1" - ml = cssutils.stylesheets.MediaList() - - ml.appendMedium(u'print') - self.assertEqual(1, ml.length) - self.assertEqual(u'print', ml.mediaText) - - ml.appendMedium(u'screen') - self.assertEqual(2, ml.length) - self.assertEqual(u'print, screen', ml.mediaText) - - # automatic del and append! - ml.appendMedium(u'print') - self.assertEqual(2, ml.length) - self.assertEqual(u'screen, print', ml.mediaText) - - # automatic del and append! - ml.appendMedium(u'SCREEN') - self.assertEqual(2, ml.length) - self.assertEqual(u'print, SCREEN', ml.mediaText) - - # append invalid MediaQuery - mq = cssutils.stylesheets.MediaQuery() - ml.appendMedium(mq) - self.assertEqual(2, ml.length) - self.assertEqual(u'print, SCREEN', ml.mediaText) - - # append() - mq = cssutils.stylesheets.MediaQuery('tv') - ml.append(mq) - self.assertEqual(3, ml.length) - self.assertEqual(u'print, SCREEN, tv', ml.mediaText) - - # __setitem__ - self.assertRaises(IndexError, ml.__setitem__, 10, 'all') - ml[0] = 'handheld' - self.assertEqual(3, ml.length) - self.assertEqual(u'handheld, SCREEN, tv', ml.mediaText) - - def test_appendAll(self): - "MediaList.append() 2" - ml = cssutils.stylesheets.MediaList() - ml.appendMedium(u'print') - ml.appendMedium(u'tv') - self.assertEqual(2, ml.length) - self.assertEqual(u'print, tv', ml.mediaText) - - ml.appendMedium(u'all') - self.assertEqual(1, ml.length) - self.assertEqual(u'all', ml.mediaText) - - self.assertRaisesMsg(xml.dom.InvalidModificationErr, - basetest.msg3x('''MediaList: Ignoring new medium cssutils.stylesheets.MediaQuery(mediaText=u'tv') as already specified "all" (set ``mediaText`` instead).'''), - ml.appendMedium, 'tv') - self.assertEqual(1, ml.length) - self.assertEqual(u'all', ml.mediaText) - - self.assertRaises(xml.dom.InvalidCharacterErr, ml.appendMedium, u'test') - - def test_append2All(self): - "MediaList all" - ml = cssutils.stylesheets.MediaList() - ml.appendMedium(u'all') - self.assertRaisesMsg(xml.dom.InvalidModificationErr, - basetest.msg3x('''MediaList: Ignoring new medium cssutils.stylesheets.MediaQuery(mediaText=u'print') as already specified "all" (set ``mediaText`` instead).'''), - ml.appendMedium, 'print') - - sheet = cssutils.parseString('@media all, print { /**/ }') - self.assertEqual(u'@media all {\n /**/\n }'.encode(), sheet.cssText) - - def test_delete(self): - "MediaList.deleteMedium()" - ml = cssutils.stylesheets.MediaList() - - self.assertRaises(xml.dom.NotFoundErr, ml.deleteMedium, u'all') - self.assertRaises(xml.dom.NotFoundErr, ml.deleteMedium, u'test') - - ml.appendMedium(u'print') - ml.deleteMedium(u'print') - ml.appendMedium(u'tV') - ml.deleteMedium(u'Tv') - self.assertEqual(0, ml.length) - self.assertEqual(u'all', ml.mediaText) - - def test_item(self): - "MediaList.item()" - ml = cssutils.stylesheets.MediaList() - ml.appendMedium(u'print') - ml.appendMedium(u'screen') - - self.assertEqual(u'print', ml.item(0)) - self.assertEqual(u'screen', ml.item(1)) - self.assertEqual(None, ml.item(2)) - - def test_handheld(self): - "MediaList handheld" - ml = cssutils.stylesheets.MediaList() - - ml.mediaText = u' handheld , all ' - self.assertEqual(2, ml.length) - self.assertEqual(u'all, handheld', ml.mediaText) - - self.assertRaisesMsg(xml.dom.InvalidModificationErr, - basetest.msg3x('''MediaList: Ignoring new medium cssutils.stylesheets.MediaQuery(mediaText=u'tv') as already specified "all" (set ``mediaText`` instead).'''), - ml._setMediaText, u' handheld , all , tv ') - - def test_mediaText(self): - "MediaList.mediaText 2" - tests = { - u'': u'all', - u'ALL': u'ALL', - u'Tv': u'Tv', - u'all': None, - u'all, handheld': None, - u'tv': None, - u'tv, handheld, print': None, - u'tv and (color), handheld and (width: 1px) and (color)': None, - } - self.do_equal_r(tests, att='mediaText') - - tests = { - u'UNKNOWN': xml.dom.InvalidCharacterErr, - u'a,b': xml.dom.InvalidCharacterErr, - u'a and (color)': xml.dom.InvalidCharacterErr, - u'not': xml.dom.SyntaxErr, # known but need media - u'only': xml.dom.SyntaxErr, # known but need media - u'not tv,': xml.dom.SyntaxErr, # known but need media - u'all;': xml.dom.SyntaxErr, - u'all, and(color)': xml.dom.SyntaxErr, - u'all,': xml.dom.SyntaxErr, - u'all, ': xml.dom.SyntaxErr, - u'all ,': xml.dom.SyntaxErr, - u'all, /*1*/': xml.dom.SyntaxErr, - u'all and (color),': xml.dom.SyntaxErr, - u'all tv, print': xml.dom.SyntaxErr, - } - self.do_raise_r(tests, att='_setMediaText') - - def test_comments(self): - "MediaList.mediaText comments" - tests = { - u'/*1*/ tv /*2*/, /*3*/ handheld /*4*/, print': None, - } - self.do_equal_r(tests, att='mediaText') - - def test_reprANDstr(self): - "MediaList.__repr__(), .__str__()" - mediaText='tv, print' - - s = cssutils.stylesheets.MediaList(mediaText=mediaText) - - self.assert_(mediaText in str(s)) - - s2 = eval(repr(s)) - self.assert_(isinstance(s2, s.__class__)) - self.assert_(mediaText == s2.mediaText) - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_mediaquery.py cssutils-0.9.10/src/tests/test_mediaquery.py --- cssutils-0.9.10~b1/src/tests/test_mediaquery.py 2011-07-26 18:22:54.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_mediaquery.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,102 +0,0 @@ -# -*- coding: iso-8859-1 -*- -"""Testcases for cssutils.stylesheets.MediaList""" - -import xml.dom -import basetest -import cssutils.stylesheets - -class MediaQueryTestCase(basetest.BaseTestCase): - - def setUp(self): - super(MediaQueryTestCase, self).setUp() - self.r = cssutils.stylesheets.MediaQuery() - - def test_mediaText(self): - "MediaQuery.mediaText" - tests = { - u'all': None, - u'braille': None, - u'embossed': None, - u'handheld': None, - u'print': None, - u'projection': None, - u'screen': None, - u'speech': None, - u'tty': None, - u'tv': None, - u'ALL': None, - u'a\\ll': None, - u'not tv': None, - u'n\\ot t\\v': None, - u'only tv': None, - u'\\only \\tv': None, - u'PRINT': None, - u'NOT PRINT': None, - u'ONLY PRINT': None, - u'tv and (color)': None, - u'not tv and (color)': None, - u'only tv and (color)': None, - } - self.do_equal_r(tests, att='mediaText') - - tests = { - u'': xml.dom.SyntaxErr, - u'two values': xml.dom.SyntaxErr, - u'or even three': xml.dom.SyntaxErr, - u'print and(color)': xml.dom.SyntaxErr, # a function - u'aural': xml.dom.InvalidCharacterErr, # a dimension - u'3d': xml.dom.InvalidCharacterErr, # a dimension - } - self.do_raise_r(tests, att='_setMediaText') - - def test_mediaType(self): - "MediaQuery.mediaType" - mq = cssutils.stylesheets.MediaQuery() - - self.assertEqual(u'', mq.mediaText) - - for mt in cssutils.stylesheets.MediaQuery.MEDIA_TYPES: - mq.mediaType = mt - self.assertEqual(mq.mediaType, mt) - mq.mediaType = mt.upper() - self.assertEqual(mq.mediaType, mt.upper()) - - mt = u'3D-UNKOwn-MEDIAtype0123' - #mq.mediaType = mt - self.assertRaises(xml.dom.InvalidCharacterErr, mq._setMediaType, mt) - - def test_comments(self): - "MediaQuery.mediaText comments" - tests = { - u'all': None, - u'print': None, - u'not print': None, - u'only print': None, - u'print and (color)': None, - u'print and (color) and (width)': None, - u'print and (color: 2)': None, - u'print and (min-width: 100px)': None, - u'print and (min-width: 100px) and (color: red)': None, - u'not print and (min-width: 100px)': None, - u'only print and (min-width: 100px)': None, - u'/*1*/ tv /*2*/': None, - u'/*0*/ only /*1*/ tv /*2*/': None, - u'/*0* /not /*1*/ tv /*2*/': None, - u'/*x*/ only /*x*/ print /*x*/ and /*x*/ (/*x*/min-width/*x*/: /*x*/ 100px /*x*/)': None, - u'print and/*1*/(color)': u'print and /*1*/ (color)' - } - self.do_equal_r(tests, att='mediaText') - - def test_reprANDstr(self): - "MediaQuery.__repr__(), .__str__()" - mediaText='tv and (color)' - s = cssutils.stylesheets.MediaQuery(mediaText=mediaText) - self.assert_(mediaText in str(s)) - s2 = eval(repr(s)) - self.assertEqual(mediaText, s2.mediaText) - self.assert_(isinstance(s2, s.__class__)) - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_parse.py cssutils-0.9.10/src/tests/test_parse.py --- cssutils-0.9.10~b1/src/tests/test_parse.py 2011-12-24 12:26:36.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_parse.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,496 +0,0 @@ -# -*- coding: utf-8 -*- -"""Tests for parsing which does not raise Exceptions normally""" -from __future__ import with_statement - - -import sys -import xml.dom -import basetest -import cssutils -import urllib2 - -try: - import mock -except ImportError: - mock = None - print "install mock library to run all tests" - - -class CSSParserTestCase(basetest.BaseTestCase): - - def _make_fetcher(self, encoding, content): - "make an URL fetcher with specified data" - def fetcher(url): - return encoding, content - return fetcher - - def setUp(self): - self._saved = cssutils.log.raiseExceptions - - def tearDown(self): - cssutils.log.raiseExceptions = self._saved - - def test_init(self): - "CSSParser.__init__()" - self.assertEqual(True, cssutils.log.raiseExceptions) - - # also the default: - cssutils.log.raiseExceptions = True - - # default non raising parser - p = cssutils.CSSParser() - s = p.parseString('$') - self.assertEqual(s.cssText, u''.encode()) - - # explicit raiseExceptions=False - p = cssutils.CSSParser(raiseExceptions=False) - s = p.parseString('$') - self.assertEqual(s.cssText, u''.encode()) - - # working with sheet does raise though! - self.assertRaises(xml.dom.DOMException, s.__setattr__, u'cssText', u'$') - - # ---- - - # raiseExceptions=True - p = cssutils.CSSParser(raiseExceptions=True) - self.assertRaises(xml.dom.SyntaxErr, p.parseString, u'$') - - # working with a sheet does raise too - s = cssutils.css.CSSStyleSheet() - self.assertRaises(xml.dom.DOMException, s.__setattr__, u'cssText', u'$') - - # RESET cssutils.log.raiseExceptions - cssutils.log.raiseExceptions = False - s = cssutils.css.CSSStyleSheet() - # does not raise! - s.__setattr__(u'cssText', u'$') - self.assertEqual(s.cssText, ''.encode()) - - def test_parseComments(self): - "cssutils.CSSParser(parseComments=False)" - css = u'/*1*/ a { color: /*2*/ red; }' - - p = cssutils.CSSParser(parseComments=False) - self.assertEqual(p.parseString(css).cssText, - u'a {\n color: red\n }'.encode()) - p = cssutils.CSSParser(parseComments=True) - self.assertEqual(p.parseString(css).cssText, - u'/*1*/\na {\n color: /*2*/ red\n }'.encode()) - -# def test_parseFile(self): -# "CSSParser.parseFile()" -# # see test_cssutils - - def test_parseUrl(self): - "CSSParser.parseUrl()" - if mock: - # parseUrl(self, href, encoding=None, media=None, title=None): - parser = cssutils.CSSParser() - m = mock.Mock() - with mock.patch('cssutils.util._defaultFetcher', m): - m.return_value = (None, '') - sheet = parser.parseUrl('http://example.com', - media='tv,print', - title='test') - - self.assertEqual(sheet.href, u'http://example.com') - self.assertEqual(sheet.encoding, u'utf-8') - self.assertEqual(sheet.media.mediaText, u'tv, print') - self.assertEqual(sheet.title, u'test') - - # URL and content tests - tests = { - # (url, content): isSheet, encoding, cssText - ('', None): (False, None, None), - ('1', None): (False, None, None), - ('mailto:a@bb.cd', None): (False, None, None), - ('http://cthedot.de/test.css', None): (False, None, None), - ('http://cthedot.de/test.css', ''): (True, u'utf-8', u''), - ('http://cthedot.de/test.css', 'a'): (True, u'utf-8', u''), - ('http://cthedot.de/test.css', 'a {color: red}'): (True, u'utf-8', - u'a {\n color: red\n }'), - ('http://cthedot.de/test.css', 'a {color: red}'): (True, u'utf-8', - u'a {\n color: red\n }'), - ('http://cthedot.de/test.css', '@charset "ascii";a {color: red}'): (True, u'ascii', - u'@charset "ascii";\na {\n color: red\n }'), - } - override = 'iso-8859-1' - overrideprefix = u'@charset "iso-8859-1";' - httpencoding = None - - for (url, content), (isSheet, expencoding, cssText) in tests.items(): - parser.setFetcher(self._make_fetcher(httpencoding, content)) - sheet1 = parser.parseUrl(url) - sheet2 = parser.parseUrl(url, encoding=override) - if isSheet: - self.assertEqual(sheet1.encoding, expencoding) - self.assertEqual(sheet1.cssText, cssText.encode()) - self.assertEqual(sheet2.encoding, override) - if sheet1.cssText and cssText.startswith('@charset'): - self.assertEqual(sheet2.cssText, (cssText.replace('ascii', override).encode())) - elif sheet1.cssText: - self.assertEqual(sheet2.cssText, (overrideprefix + '\n' + cssText).encode()) - else: - self.assertEqual(sheet2.cssText, (overrideprefix + cssText).encode()) - else: - self.assertEqual(sheet1, None) - self.assertEqual(sheet2, None) - - parser.setFetcher(None) - - self.assertRaises(ValueError, parser.parseUrl, '../not-valid-in-urllib') - self.assertRaises(urllib2.HTTPError, parser.parseUrl, 'http://cthedot.de/not-present.css') - - else: - self.assertEqual(False, u'Mock needed for this test') - - def test_parseString(self): - "CSSParser.parseString()" - tests = { - # (byte) string, encoding: encoding, cssText - ('/*a*/', None): (u'utf-8', u'/*a*/'.encode('utf-8')), - ('/*a*/', 'ascii'): (u'ascii', u'@charset "ascii";\n/*a*/'.encode('ascii')), - - # org - #('/*\xc3\xa4*/', None): (u'utf-8', u'/*\xc3\xa4*/'.encode('utf-8')), - #('/*\xc3\xa4*/', 'utf-8'): (u'utf-8', u'@charset "utf-8";\n/*\xc3\xa4*/'.encode('utf-8')), - # new for 2.x and 3.x - (u'/*\xe4*/'.encode('utf-8'), None): (u'utf-8', u'/*\xe4*/'.encode('utf-8')), - (u'/*\xe4*/'.encode('utf-8'), 'utf-8'): (u'utf-8', u'@charset "utf-8";\n/*\xe4*/'.encode('utf-8')), - - ('@charset "ascii";/*a*/', None): (u'ascii', u'@charset "ascii";\n/*a*/'.encode('ascii')), - ('@charset "utf-8";/*a*/', None): (u'utf-8', u'@charset "utf-8";\n/*a*/'.encode('utf-8')), - ('@charset "iso-8859-1";/*a*/', None): (u'iso-8859-1', u'@charset "iso-8859-1";\n/*a*/'.encode('iso-8859-1')), - - # unicode string, no encoding: encoding, cssText - (u'/*€*/', None): ( - u'utf-8', u'/*€*/'.encode('utf-8')), - (u'@charset "iso-8859-1";/*ä*/', None): ( - u'iso-8859-1', u'@charset "iso-8859-1";\n/*ä*/'.encode('iso-8859-1')), - (u'@charset "utf-8";/*€*/', None): ( - u'utf-8', u'@charset "utf-8";\n/*€*/'.encode('utf-8')), - (u'@charset "utf-16";/**/', None): ( - u'utf-16', u'@charset "utf-16";\n/**/'.encode('utf-16')), - # unicode string, encoding utf-8: encoding, cssText - (u'/*€*/', 'utf-8'): ('utf-8', - u'@charset "utf-8";\n/*€*/'.encode('utf-8')), - (u'@charset "iso-8859-1";/*ä*/', 'utf-8'): ( - u'utf-8', u'@charset "utf-8";\n/*ä*/'.encode('utf-8')), - (u'@charset "utf-8";/*€*/', 'utf-8'): ( - u'utf-8', u'@charset "utf-8";\n/*€*/'.encode('utf-8')), - (u'@charset "utf-16";/**/', 'utf-8'): ( - u'utf-8', u'@charset "utf-8";\n/**/'.encode('utf-8')), - # probably not what is wanted but does not raise: - (u'/*€*/', 'ascii'): ( - u'ascii', u'@charset "ascii";\n/*\\20AC */'.encode('utf-8')), - (u'/*€*/', 'iso-8859-1'): ( - u'iso-8859-1', u'@charset "iso-8859-1";\n/*\\20AC */'.encode('utf-8')), - } - for test in tests: - css, encoding = test - sheet = cssutils.parseString(css, encoding=encoding) - encoding, cssText = tests[test] - self.assertEqual(encoding, sheet.encoding) - self.assertEqual(cssText, sheet.cssText) - - tests = [ - # encoded css, overiding encoding - (u'/*€*/'.encode('utf-16'), 'utf-8'), - (u'/*ä*/'.encode('iso-8859-1'), 'ascii'), - (u'/*€*/'.encode('utf-8'), 'ascii'), - (u'a'.encode('ascii'), 'utf-16'), - ] - for test in tests: - #self.assertEqual(None, cssutils.parseString(css, encoding=encoding)) - self.assertRaises(UnicodeDecodeError, cssutils.parseString, test[0], test[1]) - - def test_validate(self): - """CSSParser(validate)""" - style = 'color: red' - t = 'a { %s }' % style - - # helper - s = cssutils.parseString(t) - self.assertEqual(s.validating, True) - s = cssutils.parseString(t, validate=False) - self.assertEqual(s.validating, False) - s = cssutils.parseString(t, validate=True) - self.assertEqual(s.validating, True) - - d = cssutils.parseStyle(style) - self.assertEqual(d.validating, True) - d = cssutils.parseStyle(style, validate=True) - self.assertEqual(d.validating, True) - d = cssutils.parseStyle(style, validate=False) - self.assertEqual(d.validating, False) - - # parser - p = cssutils.CSSParser() - s = p.parseString(t) - self.assertEqual(s.validating, True) - s = p.parseString(t, validate=False) - self.assertEqual(s.validating, False) - s = p.parseString(t, validate=True) - self.assertEqual(s.validating, True) - d = p.parseStyle(style) - self.assertEqual(d.validating, True) - - p = cssutils.CSSParser(validate=True) - s = p.parseString(t) - self.assertEqual(s.validating, True) - s = p.parseString(t, validate=False) - self.assertEqual(s.validating, False) - s = p.parseString(t, validate=True) - self.assertEqual(s.validating, True) - d = p.parseStyle(style) - self.assertEqual(d.validating, True) - - p = cssutils.CSSParser(validate=False) - s = p.parseString(t) - self.assertEqual(s.validating, False) - s = p.parseString(t, validate=False) - self.assertEqual(s.validating, False) - s = p.parseString(t, validate=True) - self.assertEqual(s.validating, True) - d = p.parseStyle(style) - self.assertEqual(d.validating, False) - - # url - p = cssutils.CSSParser(validate=False) - p.setFetcher(self._make_fetcher('utf-8', t)) - u = 'url' - s = p.parseUrl(u) - self.assertEqual(s.validating, False) - s = p.parseUrl(u, validate=False) - self.assertEqual(s.validating, False) - s = p.parseUrl(u, validate=True) - self.assertEqual(s.validating, True) - - # check if it raises see log test - - - def test_fetcher(self): - """CSSParser.fetcher - - order: - 0. explicity given encoding OVERRIDE (cssutils only) - - 1. An HTTP "charset" parameter in a "Content-Type" field (or similar parameters in other protocols) - 2. BOM and/or @charset (see below) - 3. or other metadata from the linking mechanism (if any) - 4. charset of referring style sheet or document (if any) - 5. Assume UTF-8 - """ - tests = { - # css, encoding, (mimetype, encoding, importcss): - # encoding, importIndex, importEncoding, importText - - # 0/0 override/override => ASCII/ASCII - (u'@charset "utf-16"; @import "x";', 'ASCII', ('iso-8859-1', - u'@charset "latin1";/*t*/')): ( - 'ascii', 1, 'ascii', u'@charset "ascii";\n/*t*/'.encode()), - # 1/1 not tested her but same as next - # 2/1 @charset/HTTP => UTF-16/ISO-8859-1 - (u'@charset "UTF-16"; @import "x";', None, ('ISO-8859-1', - u'@charset "latin1";/*t*/')): ( - 'utf-16', 1, 'iso-8859-1', u'@charset "iso-8859-1";\n/*t*/'.encode('iso-8859-1')), - # 2/2 @charset/@charset => UTF-16/ISO-8859-1 - (u'@charset "UTF-16"; @import "x";', None, - (None, u'@charset "ISO-8859-1";/*t*/')): ( - 'utf-16', 1, 'iso-8859-1', u'@charset "iso-8859-1";\n/*t*/'.encode('iso-8859-1')), - # 2/4 @charset/referrer => ASCII/ASCII - ('@charset "ASCII"; @import "x";', None, (None, u'/*t*/')): ( - 'ascii', 1, 'ascii', u'@charset "ascii";\n/*t*/'.encode()), - # 5/5 default/default or referrer - ('@import "x";', None, (None, u'/*t*/')): ( - 'utf-8', 0, 'utf-8', u'/*t*/'.encode()), - # 0/0 override/override+unicode - ('@charset "utf-16"; @import "x";', 'ASCII', ( - None, u'@charset "latin1";/*\u0287*/')): ( - 'ascii', 1, 'ascii', u'@charset "ascii";\n/*\\287 */'.encode()), - # 2/1 @charset/HTTP+unicode - ('@charset "ascii"; @import "x";', None, ('iso-8859-1', u'/*\u0287*/')): ( - 'ascii', 1, 'iso-8859-1', u'@charset "iso-8859-1";\n/*\\287 */'.encode()), - # 2/4 @charset/referrer+unicode - ('@charset "ascii"; @import "x";', None, (None, u'/*\u0287*/')): ( - 'ascii', 1, 'ascii', u'@charset "ascii";\n/*\\287 */'.encode()), - # 5/1 default/HTTP+unicode - ('@import "x";', None, ('ascii', u'/*\u0287*/')): ( - 'utf-8', 0, 'ascii', u'@charset "ascii";\n/*\\287 */'.encode()), - # 5/5 default+unicode/default+unicode - ('@import "x";', None, (None, u'/*\u0287*/')): ( - 'utf-8', 0, 'utf-8', u'/*\u0287*/'.encode('utf-8')) - } - parser = cssutils.CSSParser() - for test in tests: - css, encoding, fetchdata = test - sheetencoding, importIndex, importEncoding, importText = tests[test] - - # use setFetcher - parser.setFetcher(self._make_fetcher(*fetchdata)) - # use init - parser2 = cssutils.CSSParser(fetcher=self._make_fetcher(*fetchdata)) - - sheet = parser.parseString(css, encoding=encoding) - sheet2 = parser2.parseString(css, encoding=encoding) - - # sheet - self.assertEqual(sheet.encoding, sheetencoding) - self.assertEqual(sheet2.encoding, sheetencoding) - # imported sheet - self.assertEqual(sheet.cssRules[importIndex].styleSheet.encoding, - importEncoding) - self.assertEqual(sheet2.cssRules[importIndex].styleSheet.encoding, - importEncoding) - self.assertEqual(sheet.cssRules[importIndex].styleSheet.cssText, - importText) - self.assertEqual(sheet2.cssRules[importIndex].styleSheet.cssText, - importText) - - def test_roundtrip(self): - "cssutils encodings" - css1 = ur'''@charset "utf-8"; -/* ä */''' - s = cssutils.parseString(css1) - css2 = unicode(s.cssText, 'utf-8') - self.assertEqual(css1, css2) - - s = cssutils.parseString(css2) - s.cssRules[0].encoding='ascii' - css3 = ur'''@charset "ascii"; -/* \E4 */''' - self.assertEqual(css3, unicode(s.cssText, 'utf-8')) - - def test_escapes(self): - "cssutils escapes" - css = ur'\43\x { \43\x: \43\x !import\41nt }' - sheet = cssutils.parseString(css) - self.assertEqual(sheet.cssText, ur'''C\x { - c\x: C\x !important - }'''.encode()) - - css = ur'\ x{\ x :\ x ;y:1} ' - sheet = cssutils.parseString(css) - self.assertEqual(sheet.cssText, ur'''\ x { - \ x: \ x; - y: 1 - }'''.encode()) - - def test_invalidstring(self): - "cssutils.parseString(INVALID_STRING)" - validfromhere = '@namespace "x";' - csss = ( - u'''@charset "ascii - ;''' + validfromhere, - u'''@charset 'ascii - ;''' + validfromhere, - u'''@namespace "y - ;''' + validfromhere, - u'''@import "y - ;''' + validfromhere, - u'''@import url('a - );''' + validfromhere, - u'''@unknown "y - ;''' + validfromhere) - for css in csss: - s = cssutils.parseString(css) - self.assertEqual(validfromhere.encode(), s.cssText) - - csss = (u'''a { font-family: "Courier - ; }''', - ur'''a { content: "\"; } - ''', - ur'''a { content: "\\\"; } - ''' - ) - for css in csss: - self.assertEqual(u''.encode(), cssutils.parseString(css).cssText) - - def test_invalid(self): - "cssutils.parseString(INVALID_CSS)" - tests = { - u'a {color: blue}} a{color: red} a{color: green}': - u'''a { - color: blue - } -a { - color: green - }''', - u'p @here {color: red} p {color: green}': u'p {\n color: green\n }' - } - - for css in tests: - exp = tests[css] - if exp == None: - exp = css - s = cssutils.parseString(css) - self.assertEqual(exp.encode(), s.cssText) - - def test_nesting(self): - "cssutils.parseString nesting" - # examples from csslist 27.11.2007 - tests = { - '@1; div{color:green}': u'div {\n color: green\n }', - '@1 []; div{color:green}': u'div {\n color: green\n }', - '@1 [{}]; div { color:green; }': u'div {\n color: green\n }', - '@media all { @ } div{color:green}': - u'div {\n color: green\n }', - # should this be u''? - '@1 { [ } div{color:green}': u'', - # red was eaten: - '@1 { [ } ] div{color:red}div{color:green}': u'div {\n color: green\n }', - } - for css, exp in tests.items(): - self.assertEqual(exp.encode(), cssutils.parseString(css).cssText) - - def test_specialcases(self): - "cssutils.parseString(special_case)" - tests = { - u''' - a[title="a not s\ -o very long title"] {/*...*/}''': u'''a[title="a not so very long title"] { - /*...*/ - }''' - } - for css in tests: - exp = tests[css] - if exp == None: - exp = css - s = cssutils.parseString(css) - self.assertEqual(exp.encode(), s.cssText) - - def test_iehack(self): - "IEhack: $property (not since 0.9.5b3)" - # $color is not color! - css = 'a { color: green; $color: red; }' - s = cssutils.parseString(css) - - p1 = s.cssRules[0].style.getProperty('color') - self.assertEqual('color', p1.name) - self.assertEqual('color', p1.literalname) - self.assertEqual('', s.cssRules[0].style.getPropertyValue('$color')) - - p2 = s.cssRules[0].style.getProperty('$color') - self.assertEqual(None, p2) - - self.assertEqual('green', s.cssRules[0].style.getPropertyValue('color')) - self.assertEqual('green', s.cssRules[0].style.color) - - def test_attributes(self): - "cssutils.parseString(href, media)" - s = cssutils.parseString("a{}", href="file:foo.css", media="screen, projection, tv") - self.assertEqual(s.href, "file:foo.css") - self.assertEqual(s.media.mediaText, "screen, projection, tv") - - s = cssutils.parseString("a{}", href="file:foo.css", media=["screen", "projection", "tv"]) - self.assertEqual(s.media.mediaText, "screen, projection, tv") - - def tearDown(self): - # needs to be reenabled here for other tests - cssutils.log.raiseExceptions = True - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_prodparser.py cssutils-0.9.10/src/tests/test_prodparser.py --- cssutils-0.9.10~b1/src/tests/test_prodparser.py 2011-07-24 18:24:06.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_prodparser.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,397 +0,0 @@ -"""Testcases for cssutils.css.CSSCharsetRule""" -__version__ = '$Id: test_csscharsetrule.py 1356 2008-07-13 17:29:09Z cthedot $' - -import sys -import xml.dom -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.maxint - 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, u'Extra token')], - [(t1, p1), (t2, u'Extra token')] - ), - (p2, ): ([(t2, p2)], - [(t2, p2), (t2, u'Extra token')], - [(t2, p2), (t1, u'Extra token')], - [(t1, 'Missing token for production p2')] - ), - (p1, p2): ([(t1, p1), (t2, p2)], - [(t1, p1), (t1, u'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, u'Extra token')], - ), - (p1, ): ([(t1, p1)], - [(t2, 'Extra token')], - [(t1, p1), (t1, p1)], - [(t1, p1), (t2, 'Extra token')], - [(t1, p1), (t1, p1), (t1, u'Extra token')], - [(t1, p1), (t1, p1), (t2, u'Extra token')] - ), - # as p2 NOT optional - (p2, ): ([(t2, p2)], - [(t1, 'Missing token for production p2')], - [(t2, p2), (t2, p2)], - [(t2, p2), (t1, u'No matching production for token')], - [(t2, p2), (t2, p2), (t2, u'Extra token')], - [(t2, p2), (t2, p2), (t1, u'Extra token')] - ), - (p1, p2): ([(t1, p1), (t1, u'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, u'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, u'No match in Choice(p1, p2)', ch.nextProd, t0) - self.assertEqual(p1, ch.nextProd(t1)) - self.assertRaisesMsg(Exhausted, u'Extra token', ch.nextProd, t1) - - ch = Choice(p1, p2) - self.assertEqual(p2, ch.nextProd(t2)) - self.assertRaisesMsg(Exhausted, u'Extra token', ch.nextProd, t2) - - ch = Choice(p2, p1) - self.assertRaisesMsg(ParseError, 'No match in Choice(p2, p1)', ch.nextProd, t0) - self.assertEqual(p1, ch.nextProd(t1)) - self.assertRaisesMsg(Exhausted, u'Extra token', ch.nextProd, t1) - - ch = Choice(p2, p1) - self.assertEqual(p2, ch.nextProd(t2)) - self.assertRaisesMsg(Exhausted, u'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, u'No match in Choice(Sequence(p1, p1), Sequence(p2, p2))', ch.nextProd, t0) - self.assertEqual(s1, ch.nextProd(t1)) - self.assertRaisesMsg(Exhausted, u'Extra token', ch.nextProd, t1) - - ch = Choice(s1, s2) - self.assertEqual(s2, ch.nextProd(t2)) - self.assertRaisesMsg(Exhausted, u'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(';', u';'), - PreDef.char(':', u':') - ) - - 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(): - 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, u'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(): - 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, u'T: %s' % exp, - ProdParser().parse, text, 'T', prods) - - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_profiles.py cssutils-0.9.10/src/tests/test_profiles.py --- cssutils-0.9.10~b1/src/tests/test_profiles.py 2012-04-28 14:43:34.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_profiles.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,542 +0,0 @@ -"""Testcases for cssutils.css.CSSValue and CSSPrimitiveValue.""" -__version__ = '$Id: test_cssvalue.py 1443 2008-08-31 13:54:39Z cthedot $' - -import sys -import basetest -import cssutils - -CSS2 = (cssutils.profile.CSS_LEVEL_2,) -C3BUI = (cssutils.profile.CSS3_BASIC_USER_INTERFACE,) -C3BB = (cssutils.profile.CSS3_BACKGROUNDS_AND_BORDERS,) -CM3 = (cssutils.profile.CSS3_COLOR,) -FM3 = (cssutils.profile.CSS3_FONTS,) -C3PM = (cssutils.profile.CSS3_PAGED_MEDIA,) -C3T = (cssutils.profile.CSS3_TEXT,) -FM3FF = (cssutils.profile.CSS3_FONT_FACE,) -CSS2_CM3 = (CM3[0], CSS2[0]) -CSS2_FM3 = (FM3[0], CSS2[0]) - - -class ProfilesTestCase(basetest.BaseTestCase): - M1 = { - 'testvalue': 'x' - } - P1 = { - '-test-tokenmacro': '({num}{w}){1,2}', - '-test-macro': '{ident}|{percentage}', - '-test-custommacro': '{testvalue}', - # custom validation function - '-test-funcval': lambda(v): int(v) > 0 - } - - def test_knownNames(self): - "Profiles.knownNames" - p = cssutils.profiles.Profiles() - p.removeProfile(all=True) - p.addProfile('test', self.P1, self.M1) - self.assertEqual(p.knownNames, self.P1.keys()) - p.removeProfile(all=True) - self.assertEqual(p.knownNames, []) - - def test_profiles(self): - "Profiles.profiles" - p = cssutils.profiles.Profiles() - p.removeProfile(all=True) - p.addProfile('test', self.P1, self.M1) - self.assertEqual(p.profiles, ['test']) - p.removeProfile(all=True) - self.assertEqual(p.profiles, []) - - def test_validate2(self): - "Profiles.validate()" - #save - saved = cssutils.profile - - # test - p = cssutils.profiles.Profiles() - cssutils.profile = p - - pvs = [('color', 'red'), - ('color', 'rgba(0,0,0,0)'), - ('color', 'XXX') - ] - - def check(*results): - for i, pv in enumerate(pvs): - self.assertEqual(p.validate(*pv), results[i]) - - check(True, True, False) - - p.removeProfile(p.CSS3_COLOR) - check(True, False, False) - - cssutils.profile.addProfile('test', {}, {'color': 'XXX'}) - check(False, False, True) - - p.removeProfile(all=True) - check(False, False, False) - - # TODO: validateWithProfile - - # restore - cssutils.profile = saved - - def test_addProfile(self): - "Profiles.addProfile with custom validation function" - # unknown profile - self.assertRaises(cssutils.profiles.NoSuchProfileException, - lambda: list(cssutils.profile.propertiesByProfile('NOTSET')) ) - - # new profile - cssutils.profile.addProfile('test', self.P1, self.M1) - - props = self.P1.keys() - props.sort() - self.assertEqual(props, list(cssutils.profile.propertiesByProfile('test'))) - - cssutils.log.raiseExceptions = False - tests = { - ('-test-tokenmacro', '1'): True, - ('-test-tokenmacro', '1 -2'): True, - ('-test-tokenmacro', '1 2 3'): False, - ('-test-tokenmacro', 'a'): False, - ('-test-macro', 'a'): True, - ('-test-macro', '0.1%'): True, - ('-test-custommacro', 'x'): True, - ('-test-custommacro', '1'): False, - ('-test-custommacro', 'y'): False, - ('-test-funcval', '1'): True, - ('-test-funcval', '-1'): False, - ('-test-funcval', 'x'): False - } - for test, v in tests.items(): - self.assertEqual(v, cssutils.profile.validate(*test)) - - self.assertEqual((v, v, ['test']), - cssutils.profile.validateWithProfile(*test)) - - cssutils.log.raiseExceptions = True - - # raises: - expmsg = u"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 = u"invalid literal for int(): x" - elif sys.platform.startswith('java'): - expmsg = u"invalid literal for int() with base 10: x" - - self.assertRaisesMsg(Exception, expmsg, - cssutils.profile.validate, u'-test-funcval', u'x') - - def test_removeProfile(self): - "Profiles.removeProfile()" - p = cssutils.profiles.Profiles() - self.assertEqual(9, len(p.profiles)) - p.removeProfile(p.CSS_LEVEL_2) - self.assertEqual(8, len(p.profiles)) - p.removeProfile(all=True) - self.assertEqual(0, len(p.profiles)) - - # TODO: FIX -# def test_validateWithProfile(self): -# "Profiles.validate(), Profiles.validateWithProfile()" -# p = cssutils.profiles.Profiles() -# tests = { -# ('color', 'red', None): (True, True, [p.CSS_LEVEL_2]), -# ('color', 'red', p.CSS_LEVEL_2): (True, True,[p.CSS_LEVEL_2]), -# ('color', 'red', p.CSS3_COLOR): (True, False, [p.CSS_LEVEL_2]), -# ('color', 'rgba(0,0,0,0)', None): (True, True, [p.CSS3_COLOR]), -# ('color', 'rgba(0,0,0,0)', p.CSS_LEVEL_2): (True, False, [p.CSS3_COLOR]), -# ('color', 'rgba(0,0,0,0)', p.CSS3_COLOR): (True, True, [p.CSS3_COLOR]), -# ('color', '1px', None): (False, False, [p.CSS3_COLOR, p.CSS_LEVEL_2]), -# ('color', '1px', p.CSS_LEVEL_2): (False, False, [p.CSS3_COLOR, p.CSS_LEVEL_2]), -# ('color', '1px', p.CSS3_COLOR): (False, False, [p.CSS3_COLOR, p.CSS_LEVEL_2]), -# ('color', 'aliceblue', None): (True, True, [p.CSS_LEVEL_2]), -# -# ('opacity', '1', None): (True, True, [p.CSS3_COLOR]), -# ('opacity', '1', p.CSS_LEVEL_2): (True, False, [p.CSS3_COLOR]), -# ('opacity', '1', p.CSS3_COLOR): (True, True, [p.CSS3_COLOR]), -# ('opacity', '1px', None): (False, False, [p.CSS3_COLOR]), -# ('opacity', '1px', p.CSS_LEVEL_2): (False, False, [p.CSS3_COLOR]), -# ('opacity', '1px', p.CSS3_COLOR): (False, False, [p.CSS3_COLOR]), -# -# ('-x', '1', None): (False, False, []), -# ('-x', '1', p.CSS_LEVEL_2): (False, False, []), -# ('-x', '1', p.CSS3_COLOR): (False, False, []), -# } -# for test, r in tests.items(): -# self.assertEqual(p.validate(test[0], test[1]), r[0]) -# self.assertEqual(p.validateWithProfile(*test), r) - - def test_propertiesByProfile(self): - "Profiles.propertiesByProfile" - self.assertEqual(['opacity'], #'color', - list(cssutils.profile.propertiesByProfile( - cssutils.profile.CSS3_COLOR))) - - def test_csscolorlevel3(self): - "CSS Color Module Level 3" - # (propname, propvalue): (valid, validprofile) - namedcolors = '''transparent, orange, - aqua, black, blue, fuchsia, gray, green, lime, maroon, - navy, olive, purple, red, silver, teal, white, yellow''' - for color in namedcolors.split(','): - color = color.strip() - self.assertEqual(True, cssutils.profile.validate('color', color)) - - self.assertEqual((True, True, list(CSS2)), - cssutils.profile.validateWithProfile('color', color)) - - # CSS2 only: - uicolor = 'ActiveBorder|ActiveCaption|AppWorkspace|Background|ButtonFace|ButtonHighlight|ButtonShadow|ButtonText|CaptionText|GrayText|Highlight|HighlightText|InactiveBorder|InactiveCaption|InactiveCaptionText|InfoBackground|InfoText|Menu|MenuText|Scrollbar|ThreeDDarkShadow|ThreeDFace|ThreeDHighlight|ThreeDLightShadow|ThreeDShadow|Window|WindowFrame|WindowText' - for color in uicolor.split('|'): - self.assertEqual(False, cssutils.profile.validate('color', color)) - - # TODO: Fix - #self.assertEqual((True, True, list(CSS2)), - # cssutils.profile.validateWithProfile('color', color)) - - def test_validate(self): - "Profiles.validate()" - tests = { - # name, values: valid, matching, profile - - # background-position - ('background-position', ('inherit', - '0', - '1%', - '1px', - '0 0', - '1% 1%', - '1px 1px', - '1px 1%', - 'top', 'bottom', - 'left', 'right', - 'center center', - 'center', - 'top left', 'top center', 'top right', - 'bottom left', 'bottom center', 'bottom right', - 'center left', 'center center', 'center right', - '0 center', 'center 0', - '0 top', '10% bottom', - 'left 0', 'right 10%', - '1% center', 'center 1%' - )): (True, True, CSS2), - ('background-position', ('0 left', - 'top 0' - )): (False, False, CSS2), - - - ('border-top-right-radius', ('1px', - '1%', - '1% -1px', - '1% 0', - )): (True, True, C3BB), - ('border-top-right-radius', ('1px 2px 2px', - '/ 1px', - 'black')): (False, False, C3BB), - - ('border-radius', ('1px', - '1%', - '0', - '1px 1px', - '1px/ 1px', - '1px /1px', - '1px / 1px', - '1px 1px 1px 1px', - '1px 1px 1px 1px / 1px 1px 1px 1px', - )): (True, True, C3BB), - ('border-radius', ('1px /', - '/ 1px', - '1px / 1px / 1px', - '1px 1px 1px 1px 1px', - '1px / 1px 1px 1px 1px 1px', - 'black')): (False, False, C3BB), - - ('border', ('1px', - 'solid', - 'red', - '1px solid red', - '1px red solid', - 'red 1px solid', - 'red solid 1px', - 'solid 1px red', - 'solid red 1px', - )): (True, True, C3BB), - ('border', ('1px 1px', - 'red red 1px', - )): (False, False, C3BB), - - ('box-shadow', ('none', - '1px 1px', - '1px 1px 1px', - '1px 1px 1px 1px', - '1px 1px 1px 1px red', - 'inset 1px 1px', - 'inset 1px 1px 1px 1px black')): (True, True, C3BB), - ('box-shadow', ('1px', - '1px 1px 1px 1px 1px', - 'x 1px 1px', - 'inset', - '1px black', - 'black')): (False, False, C3BB), - - # color - ('color', ('x', - '#', - '#0', - '#00', - '#0000', - '#00000', - '#0000000', - '#00j', - '#j00000', - 'rgb(0.0,1,1)', - 'rgb(0)', - 'rgb(0, 1)', - 'rgb(0, 1, 1, 1)', - 'rgb(0, 1, 0%)', - 'rgba(0)', - 'rgba(0, 1, 1.0, 1)', - 'rgba(0, 1)', - 'rgba(0, 1, 1, 1, 1)', - 'rgba(100%, 0%, 0%, 1%)', - 'rgba(100%, 0%, 0, 1)', - 'hsl(1.5,1%,1%)', - 'hsl(1,1,1%)', - 'hsl(1,1%,1)', - 'hsla(1.5,1%,1%, 1)', - 'hsla(1,1,1%, 1)', - 'hsla(1,1%,1, 1)', - 'hsla(1,1%,1%, 1%)' - )): (False,False, CSS2_CM3), - ('color', ('inherit', - 'black', - '#000', - '#000000', - 'rgb(0,1,1)', - 'rgb( 0 , 1 , 1 )', - 'rgb(-10,555,1)', - 'rgb(100%, 1.5%, 0%)', - 'rgb(150%, -20%, 0%)', - )): (True, True, CSS2), - ('color', ('currentcolor', - 'aliceblue', - 'rgba(1,1,1,1)', - 'rgba( 1 , 1 , 1 , 1 )', - 'rgba(100%, 0%, 0%, 1)', - 'hsl(1,1%,1%)', - 'hsl( 1 , 1% , 1% )', - 'hsl(-1000,555.5%,-61.5%)', - 'hsla(1,1%,1%,1)', - 'hsla( 1, 1% , 1% , 1 )', - 'hsla(-1000,555.5%,-61.5%, 0.5)' - )): (True, True, CM3), - # TODO?: - #('color', 'rgb(/**/ 0 /**/ , /**/ 1 /**/ , /**/ 1 /**/ )'): (True, True, CSS2), - - # content - ('content', ('none', - 'normal', - '""', - "'x'", - )): (True, True, CSS2), - - ('cursor', ('url(1), auto', - 'url(1) 2 3, help', - 'wait', - 'inherit', - 'none')): (True, True, C3BUI), - ('cursor', ('url(1), auto, wait', - 'url(1) 2, help', - '1')): (False, False, C3BUI), - - # FONTS - ('font-family', ('serif, x', - )): (True, True, CSS2), #CSS2_FM3), - - ('font-family', ('inherit', - 'a, b', - 'a,b,c', - 'a, "b", c', - '"a", b, "c"', - '"a", "b", "c"', - '"x y"', - 'serif', - '"serif"', # valid but CSS2: font with name serif, CSS3: same as `serif` - 'a b', # should use quotes but valid - 'a, b b, d', - )): (True, True, CSS2), - - ('font-weight', ('normal', 'bold', 'bolder', 'lighter', 'inherit', - '100', '200', '300', '400', '500', '600', '700', '800', '900' - )): (True, True, CSS2), - - ('font-stretch', ('normal', 'wider', 'narrower', 'ultra-condensed', - 'extra-condensed', 'condensed', 'semi-condensed', - 'semi-expanded', 'expanded', 'extra-expanded', - 'ultra-expanded', 'inherit' - )): (True, True, FM3), - - ('font-style', ('normal', 'italic', 'oblique', 'inherit' - )): (True, True, CSS2), - - ('font-variant', ('normal', 'small-caps', 'inherit' - )): (True, True, CSS2), - ('font-size', ('-1em', - )): (False, False, CSS2), - ('font-size', ('xx-small', 'x-small', 'small', 'medium', 'large', - 'x-large', 'xx-large', 'larger', 'smaller', - '1em', '1%', 'inherit' - )): (True, True, CSS2), - - ('font-size-adjust', ('1.0', - 'none', 'inherit' - )): (True, True, FM3), - - ('font', ('italic small-caps bold 1px/3 a, "b", serif', - '12pt/14pt sans-serif', - '80% sans-serif', - 'x-large/110% "new century schoolbook", serif', - 'bold italic large Palatino, serif', - 'normal small-caps 120%/120% fantasy', - 'oblique 12pt "Helvetica Nue", serif', - 'caption', 'icon', 'menu', 'message-box', 'small-caption', - 'status-bar', 'inherit' - )): (True, True, CSS2), - - ('nav-index', ('1', 'auto', 'inherit')): (True, True, C3BUI), - ('nav-index', ('x', '1 2', '1px')): (False, False, C3BUI), - - ('opacity', ('inherit', - '0', '0.0', '0.42342', '1', '1.0', - # should be clipped but valid - '-0', '-0.1', '-10', '2' - )): (True, True, CM3), - ('opacity', ('a', '#000', '+1')): (False, False, CM3), - - ('outline', ('red dotted 1px', - 'dotted 1px red', - '1px red dotted', - 'red', '1px', 'dotted', - 'red 1px', '1px dotted', 'red dotted', - 'inherit' - )): (True, True, C3BUI), - ('outline', ('red #fff', 'solid dotted', 'Url(x)', '1px 1px' - )): (False, False, C3BUI), - ('outline-color', ('red', '#fff', 'inherit' - )): (True, True, C3BUI), - ('outline-color', ('0', '1em' - )): (False, False, C3BUI), - ('outline-offset', ('0', '1em', 'inherit' - )): (True, True, C3BUI), - ('outline-offset', ('1%', 'red' - )): (False, False, C3BUI), - ('outline-style', ('auto', 'dotted', 'inherit' - )): (True, True, C3BUI), - ('outline-style', ('0', '1em', 'red' - )): (False, False, C3BUI), - ('outline-width', ('0', '1em', 'inherit' - )): (True, True, C3BUI), - ('outline-width', ('auto', 'red', 'dotted' - )): (False, False, C3BUI), - - ('resize', ('none', - 'both', - 'horizontal', - 'vertical', - 'inherit')): (True, True, C3BUI), - ('resize', ('1', - 'auto', - '1px', - '2%')): (False, False, C3BUI), - - ('size', ('1cm', - '1mm 20cm', - 'auto', - 'landscape letter', - 'a4 portrait', - 'landscape', - 'a5', - #'inherit' - )): (True, True, C3PM), - ('size', ( - 'portrait landscape', - 'a5 letter', - '2%')): (False, False, C3PM), - - ('src', ('url( a )', - 'local( x )', - 'local("x")', - 'local( "x" )', - 'url(../fonts/LateefRegAAT.ttf) format( "truetype-aat" )', - 'url(a) format( "123x" , "a" )', - 'url(a) format( "123x" , "a" ), url(a) format( "123x" , "a" )', - 'local(HiraKakuPro-W3), local(Meiryo), local(IPAPGothic)', - 'local(Gentium), url(/fonts/Gentium.ttf)', - 'local("Gentium"), url("/fonts/Gentium.ttf")', - 'local(Futura-Medium), url(fonts.svg#MyGeometricModern) format("svg")', - )): (True, True, FM3FF), - - - ('text-shadow', ('none', - '1px 1px', - '1px 1px 1px', - '1px 1px 1px 1px', - '1px 1px 1px 1px red', - 'inset 1px 1px', - 'inset 1px 1px 1px 1px black')): (True, True, C3T), - ('text-shadow', ('1px', - '1px 1px 1px 1px 1px', - 'x 1px 1px', - 'inset', - '1px black', - 'black')): (False, False, C3T), - - ('unicode-range', ('u+1', 'U+111111-ffffff', - 'u+123456 , U+1-f' - )): (True, True, FM3FF), - - } - # TODO!!! - for (name, values), (valid, matching, profile) in tests.items(): - for value in values: - self.assertEqual(valid, cssutils.profile.validate(name, value)) - - -# if (valid, matching, list(profile)) != cssutils.profile.validateWithProfile(name, value): -# print -# print '###############', name, value -# print (valid, matching, list(profile)), cssutils.profile.validateWithProfile(name, value) - - # TODO: fix -# self.assertEqual((valid, matching, list(profile)), -# cssutils.profile.validateWithProfile(name, value)) - - # TODO: fix -# def test_validateByProfile(self): -# "Profiles.validateByProfile()" -# # testing for valid values overwritten in a profile -# tests = { -# (FM3FF, 'font-family', ('y', '"y"' # => name should be "y"!!! -# )): (True, True, FM3FF), -# (FM3FF, 'font-family', ('"y", "a"', 'a, b', 'a a' -# )): (True, False, CSS2), -# (FM3FF, 'font-stretch', ('normal', 'wider', 'narrower', 'inherit' -# )): (True, False, FM3), -# (FM3FF, 'font-style', ('inherit', -# )): (True, False, CSS2), -# (FM3FF, 'font-weight', ('bolder', 'lighter', 'inherit', -# )): (True, False, CSS2), -# } -# for (profiles, name, values), (v, m, p) in tests.items(): -# for value in values: -# self.assertEqual((v, m, list(p)), -# cssutils.profile.validateWithProfile(name, -# value, -# profiles)) - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_properties.py cssutils-0.9.10/src/tests/test_properties.py --- cssutils-0.9.10~b1/src/tests/test_properties.py 2012-03-24 22:34:48.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_properties.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,209 +0,0 @@ -"""Testcases for cssutils.css.property._Property.""" -__version__ = '$Id: test_property.py 1529 2008-11-30 15:12:01Z cthedot $' - -import copy -import xml.dom -import basetest -import cssutils -from cssutils.css.property import Property - -debug = False - -class PropertiesTestCase(basetest.BaseTestCase): - - def setUp(self): - "init test values" - V = { - '0': ('0', '-0'),#, '+0'), - 'NUMBER': ('0', '-0', '100.1', '-100.1'),#, '+0', '+100.1'), - 'PERCENTAGE': ('0%', '-0%', '100.1%', '-100.1%'),#, '+0%', '+100.1%'), - - 'EM': '1.2em', - 'EX': '1.2ex', - 'PX': '1.2px', - 'CM': '1.2cm', - 'MM': '1.2mm', - 'IN': '1.2in', - 'PT': '1.2pt', - 'PC': '1.2pc', - - 'ANGLES': ('1deg', '1rad', '1grad'), - 'TIMES': ('1s', '1ms'), - 'FREQUENCIES': ('1hz', '1khz'), - 'DIMENSION': ('1dimension', '1_dimension', '1dimension2'), - 'STRING': ('"string"', "'STRING'"), - 'URI': ('url(x)', 'URL("x")', "url(')')"), - 'IDENT': ('ident', 'IDENT', '_IDENT', '_2', 'i-2'), - #'AUTO': 'auto', # explicit in list as an IDENT too - #'INHERIT': 'inherit', # explicit in list as an IDENT too - 'ATTR': ('attr(x)'), - 'RECT': ('rect(1,2,3,4)'), - #? - 'CLIP': ('rect(1,2,3,4)'), - 'FUNCTION': (), - - 'HEX3': '#123', - 'HEX6': '#123abc', - 'RGB': 'rgb(1,2,3)', - 'RGB100': 'rgb(1%,2%,100%)', - 'RGBA': 'rgba(1,2,3, 1)', - 'RGBA100': 'rgba(1%,2%,100%, 0)', - 'HSL': 'hsl(1,2%,3%)', - 'HSLA': 'hsla(1,2%,3%, 1.0)' - } - def expanded(*keys): - r = [] - for k in keys: - if isinstance(V[k], basestring): - r.append(V[k]) - else: - r.extend(list(V[k])) - return r - - # before adding combined - self.V = V - self.ALL = list(self._valuesofkeys(V.keys())) - - # combined values, only keys of V may be used! - self.V['LENGTHS'] = expanded('0', 'EM', 'EX', 'PX', 'CM', 'MM', 'IN', 'PT', 'PC') - self.V['COLORS'] = expanded('HEX3', 'HEX6', 'RGB', 'RGB100') - self.V['COLORS3'] = expanded('RGBA', 'RGBA100', 'HSL', 'HSLA') - - def _allvalues(self): - "Return list of **all** possible values as simple list" - return copy.copy(self.ALL) - - def _valuesofkeys(self, keys): - "Generate all distinct values in given keys of self.V" - done = [] - for key in keys: - if isinstance(key, list): - # not a key but a list of values, return directly - for v in key: - yield v - else: - v = self.V[key] - if isinstance(v, basestring): - # single value - if v not in done: - done.append(v) - yield v - else: - # a list of values - for value in v: - if value not in done: - done.append(value) - yield value - - def _check(self, name, keys): - """ - Check each value in values if for property name p.name==exp. - """ - notvalid = self._allvalues() - - for value in self._valuesofkeys(keys): - if name == debug: - print '+True?', Property(name, value).valid, value - self.assertEqual(True, Property(name, value).valid) - if value in notvalid: - notvalid.remove(value) - for value in notvalid: - if name == debug: - print '-False?', Property(name, value).valid, value - self.assertEqual(False, Property(name, value).valid) - - def test_properties(self): - "properties" - tests = { - # propname: key or [list of values] - 'color': ('COLORS', 'COLORS3', ['inherit', 'red']), - - 'fit': (['fill', 'hidden', 'meet', 'slice'],), - 'fit-position': ('LENGTHS', 'PERCENTAGE', - ['auto', - 'top left', - '0% 50%', - '1cm 5em', - 'bottom']), - 'font-family': ('STRING', 'IDENT', ['a, b', - '"a", "b"', - 'a, "b"', - '"a", b', - r'a\{b', - r'a\ b', - 'a b' - 'a b, c d , e' - ]), - #'src': ('STRING',), - - 'font-weight': (['normal', 'bold', 'bolder', 'lighter', 'inherit', - '100', '200', '300', '400', '500', '600', '700', - '800', '900'],), - 'font-stretch': (['normal', 'wider', 'narrower', 'ultra-condensed', - 'extra-condensed', 'condensed', 'semi-condensed', - 'semi-expanded', 'expanded', 'extra-expanded', - 'ultra-expanded', 'inherit'],), - 'font-style': (['normal', 'italic', 'oblique', 'inherit'],), - 'font-variant': (['normal', 'small-caps', 'inherit'],), - 'font-size': ('LENGTHS', 'PERCENTAGE', ['xx-small', 'x-small', - 'small', 'medium', 'large', - 'x-large', 'xx-large', - 'larger', 'smaller', - '1em', '1%', 'inherit']), - 'font-size-adjust': ('NUMBER', ['none', 'inherit']), -# 'font': (['italic small-caps bold 1px/3 a, "b", serif', -# 'caption', 'icon', 'menu', 'message-box', 'small-caption', -# 'status-bar', 'inherit'],), - - 'image-orientation': ('0', 'ANGLES', ['auto']), - 'left': ('LENGTHS', 'PERCENTAGE', ['inherit', 'auto']), - 'opacity': ('NUMBER', ['inherit']), - - 'orphans': ('0', ['1', '99999', 'inherit']), - 'page': ('IDENT',), - 'page-break-inside': (['auto', 'inherit', 'avoid'],), - 'size': ('LENGTHS', ['auto', - '1em 1em', - 'a4 portrait', - 'b4 landscape', - 'A5 PORTRAIT']), - - 'widows': ('0', ['1', '99999', 'inherit']) - } - for name, keys in tests.items(): - # keep track of valid keys - self._check(name, keys) - - def test_validate(self): - "Property.validate() and Property.valid" - tests = { - # (default L2, no default, no profile, L2, Color L3) - 'red': (True, True, True, True, True), - 'rgba(1,2,3,1)': (False, True, True, False, True), - '1': (False, False, False, False, False) - } - for v, rs in tests.items(): - p = Property('color', v) - - # TODO: Fix -# cssutils.profile.defaultProfiles = \ -# cssutils.profile.CSS_LEVEL_2 -# self.assertEqual(rs[0], p.valid) - - cssutils.profile.defaultProfiles = None - self.assertEqual(rs[1], p.valid) - - self.assertEqual(rs[2], p.validate()) -# self.assertEqual(rs[3], p.validate( -# profiles=cssutils.profile.CSS_LEVEL_2)) -# self.assertEqual(rs[4], p.validate( -# cssutils.profile.CSS3_COLOR)) - - -if __name__ == '__main__': - debug = 'font-family' - import logging - import unittest - cssutils.log.setLevel(logging.FATAL) - #debug = True - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_property.py cssutils-0.9.10/src/tests/test_property.py --- cssutils-0.9.10~b1/src/tests/test_property.py 2011-07-26 18:22:54.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_property.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,268 +0,0 @@ -"""Testcases for cssutils.css.property._Property.""" - -import xml.dom -import basetest -import cssutils - -class PropertyTestCase(basetest.BaseTestCase): - - def setUp(self): - self.r = cssutils.css.property.Property('top', '1px')#, 'important') - - def test_init(self): - "Property.__init__()" - p = cssutils.css.property.Property('top', '1px') - self.assertEqual('top: 1px', p.cssText) - self.assertEqual('top', p.literalname) - self.assertEqual('top', p.name) - self.assertEqual('1px', p.value) - self.assertEqual('1px', p.cssValue.cssText) - self.assertEqual(u'', p.priority) - self.assertEqual(True, p.valid) - self.assertEqual(True, p.wellformed) - - self.assertEqual([u'top'], p.seqs[0]) - self.assertEqual(type(cssutils.css.PropertyValue(cssText="2px")), type(p.seqs[1])) - self.assertEqual([], p.seqs[2]) - - self.assertEqual(True, p.valid) - - # Prop of MediaQuery - p = cssutils.css.property.Property('top', _mediaQuery=True) - self.assertEqual('top', p.cssText) - self.assertEqual('top', p.literalname) - self.assertEqual('top', p.name) - self.assertEqual('', p.value) - self.assertEqual('', p.cssValue.cssText) - self.assertEqual(u'', p.priority) - self.assertEqual(False, p.valid) - p.cssValue.cssText = '1px' - self.assertEqual('top: 1px', p.cssText) - p.cssValue = '' - self.assertEqual('top', p.cssText) - - self.assertRaises(xml.dom.SyntaxErr, cssutils.css.property.Property, 'top', '') - self.assertRaises(xml.dom.SyntaxErr, cssutils.css.property.Property, 'top') - p = cssutils.css.property.Property('top', '0') - self.assertEqual('0', p.value) - self.assertEqual(True, p.wellformed) - self.assertRaises(xml.dom.SyntaxErr, p._setValue, '') - self.assertEqual('0', p.value) - self.assertEqual(True, p.wellformed) - -# self.assertEqual(True, p.valid) - -# def test_valid(self): -# "Property.valid" -# # context property must be set -# tests = [ -# ('color', r'INHe\rIT', True), -# ('color', '1', False), -# ('color', 'red', True), -# ('left', '1', False), -# ('left', '1px', True), -# ('font', 'normal 1em/1.5 serif', True), -# ('background', 'url(x.gif) 1 0', False) -# ] -# for n, v, exp in tests: -# v = cssutils.css.CSSValue(cssText=v) -# self.assert_(v.wellformed, True) - - def test_cssText(self): - "Property.cssText" - p = cssutils.css.property.Property() - - tests = { - u'a: 1': None, - u'a: 1px 2px': None, - u'a: 1 !important': None, - u'a: 1 !IMPORTANT': u'a: 1 !important', - u'a: 1 !impor\\tant': u'a: 1 !important', - # TODO: important with unicode escapes! - u'font: normal 1em/1.5 serif': None, - u'font: normal 1em/serif': None - } - self.do_equal_r(tests) - - tests = { - u'': (xml.dom.SyntaxErr, - u'Property: No property name found: '), - u':': (xml.dom.SyntaxErr, - u'Property: No property name found: : [1:1: :]'), - u'a': (xml.dom.SyntaxErr, - u'Property: No ":" after name found: a [1:1: a]'), - u'a !': (xml.dom.SyntaxErr, - u'Property: No ":" after name found: a ! [1:3: !]'), - u'a:': (xml.dom.SyntaxErr, - u'Property: No property value found: a: [1:2: :]'), - u'/**/a': (xml.dom.SyntaxErr, - u'Property: No ":" after name found: /**/a [1:5: a]'), - # somehow 'a: ' fails?!? - u'a111: ': (xml.dom.SyntaxErr, - u"PropertyValue: Unknown syntax or no value: "), - u'a: 1!': (xml.dom.SyntaxErr, - u'Property: Invalid priority: !'), - u'a: 1!importantX': (xml.dom.SyntaxErr, - u"Property: No CSS priority value: importantx"), - u'a:!important': (xml.dom.SyntaxErr, - u"PropertyValue: Unknown syntax or no value: "), - - # TODO? -# u'a: 1;': (xml.dom.SyntaxErr, -# u'''CSSValue: No match: ('CHAR', u';', 1, 5)''') - } - for test in tests: - ecp, msg = tests[test] - self.assertRaisesMsg(ecp, msg, p._setCssText, test) - - def test_name(self): - "Property.name" - p = cssutils.css.property.Property('top', '1px') - p.name = 'left' - self.assertEqual('left', p.name) - - tests = { - u'top': None, - u' top': u'top', - u'top ': u'top', - u' top ': u'top', - u'/*x*/ top ': u'top', - u' top /*x*/': u'top', - u'/*x*/top/*x*/': u'top', - u'\\x': u'x', - u'a\\010': u'a\x10', - u'a\\01': u'a\x01' - } - self.do_equal_r(tests, att='name') - - tests = { - u'': xml.dom.SyntaxErr, - u' ': xml.dom.SyntaxErr, - u'"\n': xml.dom.SyntaxErr, - u'/*x*/': xml.dom.SyntaxErr, - u':': xml.dom.SyntaxErr, - u';': xml.dom.SyntaxErr, - u'top:': xml.dom.SyntaxErr, - u'top;': xml.dom.SyntaxErr, - } - self.do_raise_r(tests, att='_setName') - - p = cssutils.css.property.Property(r'c\olor', 'red') - self.assertEqual(r'c\olor', p.literalname) - self.assertEqual('color', p.name) - - def test_literalname(self): - "Property.literalname" - p = cssutils.css.property.Property(r'c\olor', 'red') - self.assertEqual(r'c\olor', p.literalname) - self.assertRaisesMsg(AttributeError, "can't set attribute", p.__setattr__, - 'literalname', 'color') - - def test_validate(self): - "Property.valid" - p = cssutils.css.property.Property('left', '1px', '') - - self.assertEqual(p.valid, True) - - p.name = 'color' - self.assertEqual(p.valid, False) - - p.name = 'top' - self.assertEqual(p.valid, True) - - p.value = 'red' - self.assertEqual(p.valid, False) - - def test_cssValue(self): - "Property.cssValue" - pass - #TODO - - def test_priority(self): - "Property.priority" - p = cssutils.css.property.Property('top', '1px', 'important') - - for prio in (None, u''): - p.priority = prio - self.assertEqual(u'', p.priority) - self.assertEqual(u'', p.literalpriority) - - for prio in (u'!important', - u'! important', - u'!/* x */ important', - u'!/* x */ important /**/', - u'important', - u'IMPORTANT', - ur'im\portant' - ): - p.priority = prio - self.assertEqual(u'important', p.priority) - if prio.startswith('!'): - prio = prio[1:].strip() - if u'/*' in prio: - check = 'important' - else: - check = prio - self.assertEqual(check, p.literalpriority) - - tests = { - u' ': xml.dom.SyntaxErr, - u'"\n': xml.dom.SyntaxErr, - #u'important': xml.dom.SyntaxErr, - u';': xml.dom.SyntaxErr, - u'!important !important': xml.dom.SyntaxErr - } - self.do_raise_r(tests, att='_setPriority') - - def test_value(self): - "Property.value" - p = cssutils.css.property.Property('top', u'1px') - self.assertEqual('1px', p.value) - p.value = '2px' - self.assertEqual('2px', p.value) - - tests = { - u'1px': None, - u' 2px': u'2px', - u'3px ': u'3px', - u' 4px ': u'4px', - u'5px 1px': u'5px 1px', - } - self.do_equal_r(tests, att='value') - - tests = { - # no value - None: xml.dom.SyntaxErr, - u'': xml.dom.SyntaxErr, - u' ': xml.dom.SyntaxErr, - u'"\n': xml.dom.SyntaxErr, - u'/*x*/': xml.dom.SyntaxErr, - # not allowed: - u':': xml.dom.SyntaxErr, - u';': xml.dom.SyntaxErr, - u'!important': xml.dom.SyntaxErr, - } - self.do_raise_r(tests, att='_setValue') - - def test_reprANDstr(self): - "Property.__repr__(), .__str__()" - name="color" - value="red" - priority="important" - - s = cssutils.css.property.Property(name=name, value=value, priority=priority) - - self.assert_(name in str(s)) - self.assert_(value in str(s)) - self.assert_(priority in str(s)) - - s2 = eval(repr(s)) - self.assert_(isinstance(s2, s.__class__)) - self.assert_(name == s2.name) - self.assert_(value == s2.value) - self.assert_(priority == s2.priority) - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_scripts_csscombine.py cssutils-0.9.10/src/tests/test_scripts_csscombine.py --- cssutils-0.9.10~b1/src/tests/test_scripts_csscombine.py 2011-07-26 18:22:54.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_scripts_csscombine.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,74 +0,0 @@ -"""Testcases for cssutils.scripts.csscombine""" - -from cssutils.script import csscombine -import basetest -import cssutils -import os - -class CSSCombine(basetest.BaseTestCase): - - C = '@namespace s2"uri";s2|sheet-1{top:1px}s2|sheet-2{top:2px}proxy{top:3px}' - - def setUp(self): - self._saved = cssutils.log.raiseExceptions - - def tearDown(self): - cssutils.log.raiseExceptions = self._saved - - def test_combine(self): - "scripts.csscombine()" - - # path, SHOULD be keyword argument! - csspath = os.path.join(os.path.dirname(__file__), '..', '..', - 'sheets', 'csscombine-proxy.css') - combined = csscombine(csspath) - self.assertEqual(combined, self.C.encode()) - combined = csscombine(path=csspath, targetencoding='ascii') - self.assertEqual(combined, ('@charset "ascii";' + self.C).encode()) - - # url - cssurl = cssutils.helper.path2url(csspath) - combined = csscombine(url=cssurl) - self.assertEqual(combined, self.C.encode()) - combined = csscombine(url=cssurl, targetencoding='ascii') - self.assertEqual(combined, ('@charset "ascii";' + self.C).encode()) - - # cssText - # TODO: really need binary or can handle str too? - cssText=open(csspath, mode="rb").read() - combined = csscombine(cssText=cssText, href=cssurl) - self.assertEqual(combined, self.C.encode()) - combined = csscombine(cssText=cssText, href=cssurl, - targetencoding='ascii') - self.assertEqual(combined, ('@charset "ascii";' + self.C).encode()) - - def test_combine_resolveVariables(self): - "scripts.csscombine(minify=..., resolveVariables=...)" - # no actual imports but checking if minify and resolveVariables work - cssText = ''' - @variables { - c: #0f0; - } - a { - color: var(c); - } - ''' - # default minify - self.assertEqual(csscombine(cssText=cssText, - resolveVariables=False), - '@variables{c:#0f0}a{color:var(c)}'.encode()) - self.assertEqual(csscombine(cssText=cssText), - 'a{color:#0f0}'.encode()) - - # no minify - self.assertEqual(csscombine(cssText=cssText, - minify=False, - resolveVariables=False), - '@variables {\n c: #0f0\n }\na {\n color: var(c)\n }'.encode()) - self.assertEqual(csscombine(cssText=cssText, minify=False), - 'a {\n color: #0f0\n }'.encode()) - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_selector.py cssutils-0.9.10/src/tests/test_selector.py --- cssutils-0.9.10~b1/src/tests/test_selector.py 2011-07-26 18:22:54.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_selector.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,495 +0,0 @@ -"""Testcases for cssutils.css.selector.Selector. - -what should happen here? - - star 7 hack:: - x* - does not validate but works in IE>5 and FF, does it??? - -""" -import xml.dom -import basetest -import cssutils - -class SelectorTestCase(basetest.BaseTestCase): - - def setUp(self): - self.r = cssutils.css.Selector('*') - - def test_init(self): - "Selector.__init__()" - s = cssutils.css.Selector('*') - self.assertEqual((None, '*'), s.element) - self.assertEqual({}, s._namespaces.namespaces) - self.assertEqual(None, s.parent) - self.assertEqual('*', s.selectorText) - self.assertEqual((0,0,0,0), s.specificity) - self.assertEqual(True, s.wellformed) - - s = cssutils.css.Selector(('p|b', {'p': 'URI'}) ) - self.assertEqual(('URI', 'b'), s.element) - self.assertEqual({'p': 'URI'}, s._namespaces.namespaces) - self.assertEqual(None, s.parent) - self.assertEqual('p|b', s.selectorText) - self.assertEqual((0,0,0,1), s.specificity) - self.assertEqual(True, s.wellformed) - - self.assertRaisesEx(xml.dom.NamespaceErr, cssutils.css.Selector, 'p|b') - - def test_element(self): - "Selector.element (TODO: RESOLVE)" - tests = { - '*': (None, '*'), - 'x': (None, 'x'), - '\\x': (None, '\\x'), - '|x': (u'', 'x'), - '*|x': (cssutils._ANYNS, 'x'), - 'ex|x': (u'example', 'x'), - 'a x': (None, 'x'), - 'a+x': (None, 'x'), - 'a>x': (None, 'x'), - 'a~x': (None, 'x'), - 'a+b~c x': (None, 'x'), - 'x[href]': (None, 'x'), - 'x[href="123"]': (None, 'x'), - 'x:hover': (None, 'x'), - 'x:first-letter': (None, 'x'), # TODO: Really? - 'x::first-line': (None, 'x'), # TODO: Really? - 'x:not(href)': (None, 'x'), # TODO: Really? - - '#id': None, - '.c': None, - 'x#id': (None, 'x'), - 'x.c': (None, 'x') - } - for test, ele in tests.items(): - s = cssutils.css.Selector((test,{'ex': 'example'})) - self.assertEqual(ele, s.element) - - def test_namespaces(self): - "Selector.namespaces" - namespaces = [ - {'p': 'other'}, # no default - {'': 'default', 'p': 'other'}, # with default - {'': 'default', 'p': 'default' } # same default - ] - tests = { - # selector: with default, no default, same default - '*': ('*', '*', '*'), - 'x': ('x', 'x', 'x'), - '|*': ('|*', '|*', '|*'), - '|x': ('|x', '|x', '|x'), - '*|*': ('*|*', '*|*', '*|*'), - '*|x': ('*|x', '*|x', '*|x'), - 'p|*': ('p|*', 'p|*', '*'), - 'p|x': ('p|x', 'p|x', 'x'), - 'x[a][|a][*|a][p|a]': ('x[a][a][*|a][p|a]', - 'x[a][a][*|a][p|a]', - 'x[a][a][*|a][a]') - } - for sel, exp in tests.items(): - for i, result in enumerate(exp): - s = cssutils.css.Selector((sel, namespaces[i])) - self.assertEqual(result, s.selectorText) - - # add to CSSStyleSheet - sheet = cssutils.css.CSSStyleSheet() - sheet.cssText = '@namespace p "u"; a { color: green }' - - r = sheet.cssRules[1] - - self.assertEqual(r.selectorText, u'a') - - # add default namespace - sheet.namespaces[''] = 'a'; - self.assertEqual(r.selectorText, u'|a') - - del sheet.namespaces['']; - self.assertEqual(r.selectorText, u'a') - -# r.selectorList.append('a') -# self.assertEqual(r.selectorText, u'|a, a') -# r.selectorList.append('*|a') -# self.assertEqual(r.selectorText, u'|a, a, *|a') - - def test_default_namespace(self): - "Selector.namespaces default" - css = '''@namespace "default"; - a[att] { color:green; } - ''' - sheet = cssutils.css.CSSStyleSheet() - sheet.cssText = css - self.assertEqual(sheet.cssText, - u'@namespace "default";\na[att] {\n color: green\n }'.encode()) - # use a prefix for default namespace, does not goes for atts! - sheet.namespaces['p'] = 'default' - self.assertEqual(sheet.cssText, - u'@namespace p "default";\np|a[att] {\n color: green\n }'.encode()) - - def test_parent(self): - "Selector.parent" - sl = cssutils.css.SelectorList('a, b') - for sel in sl: - self.assertEqual(sl, sel.parent) - - newsel = cssutils.css.Selector('x') - sl.append(newsel) - self.assertEqual(sl, newsel.parent) - - newsel = cssutils.css.Selector('y') - sl.appendSelector(newsel) - self.assertEqual(sl, newsel.parent) - - def test_selectorText(self): - "Selector.selectorText" - tests = { - # combinators - u'a+b>c~e f': u'a + b > c ~ e f', - u'a + b > c ~ e f': u'a + b > c ~ e f', - u'a+b': u'a + b', - u'a + b': 'a + b', - u'a\n +\t b': 'a + b', - u'a~b': u'a ~ b', - u'a b': None, - u'a b': 'a b', - u'a\nb': 'a b', - u'a\tb': 'a b', - u'a #b': 'a #b', - u'a .b': 'a .b', - u'a * b': None, - # > - u'a>b': u'a > b', - u'a> b': 'a > b', - u'a >b': 'a > b', - u'a > b': 'a > b', - # + - u'a+b': u'a + b', - u'a+ b': 'a + b', - u'a +b': 'a + b', - u'a + b': 'a + b', - # ~ - u'a~b': u'a ~ b', - u'a~ b': 'a ~ b', - u'a ~b': 'a ~ b', - u'a ~ b': 'a ~ b', - - # type selector - u'a': None, - u'h1-a_x__--': None, - u'a-a': None, - u'a_a': None, - u'-a': None, - u'_': None, - u'-_': None, - ur'-\72': u'-r', - #ur'\25': u'%', # TODO: should be escaped! - u'.a a': None, - u'a1': None, - u'a1-1': None, - u'.a1-1': None, - - # universal - u'*': None, - u'*/*x*/': None, - u'* /*x*/': None, - u'*:hover': None, - u'* :hover': None, - u'*:lang(fr)': None, - u'* :lang(fr)': None, - u'*::first-line': None, - u'* ::first-line': None, - u'*[lang=fr]': None, - u'[lang=fr]': None, - - # HASH - u'''#a''': None, - u'''#a1''': None, - u'''#1a''': None, # valid to grammar but not for HTML - u'''#1''': None, # valid to grammar but not for HTML - u'''a#b''': None, - u'''a #b''': None, - u'''a#b.c''': None, - u'''a.c#b''': None, - u'''a #b.c''': None, - u'''a .c#b''': None, - - # class - u'ab': 'ab', - u'a.b': None, - u'a.b.c': None, - u'.a1._1': None, - - # attrib - u'''[x]''': None, - u'''*[x]''': None, - u'''a[x]''': None, - u'''a[ x]''': 'a[x]', - u'''a[x ]''': 'a[x]', - u'''a [x]''': 'a [x]', - u'''* [x]''': None, # is really * *[x] - - u'''a[x="1"]''': None, - u'''a[x ="1"]''': 'a[x="1"]', - u'''a[x= "1"]''': 'a[x="1"]', - u'''a[x = "1"]''': 'a[x="1"]', - u'''a[ x = "1"]''': 'a[x="1"]', - u'''a[x = "1" ]''': 'a[x="1"]', - u'''a[ x = "1" ]''': 'a[x="1"]', - u'''a [ x = "1" ]''': 'a [x="1"]', - - u'''a[x~=a1]''': None, - u'''a[x ~=a1]''': 'a[x~=a1]', - u'''a[x~= a1]''': 'a[x~=a1]', - u'''a[x ~= a1]''': 'a[x~=a1]', - u'''a[ x ~= a1]''': 'a[x~=a1]', - u'''a[x ~= a1 ]''': 'a[x~=a1]', - u'''a[ x ~= a1 ]''': 'a[x~=a1]', - u'''a [ x ~= a1 ]''': 'a [x~=a1]', # same as next! - u'''a *[ x ~= a1 ]''': 'a *[x~=a1]', - - u'''a[x|=en]''': None, - u'''a[x|= en]''': 'a[x|=en]', - u'''a[x |=en]''': 'a[x|=en]', - u'''a[x |= en]''': 'a[x|=en]', - u'''a[ x |= en]''': 'a[x|=en]', - u'''a[x |= en ]''': 'a[x|=en]', - u'''a[ x |= en]''': 'a[x|=en]', - u'''a [ x |= en]''': 'a [x|=en]', - # CSS3 - u'''a[x^=en]''': None, - u'''a[x$=en]''': None, - u'''a[x*=en]''': None, - - u'''a[/*1*/x/*2*/]''': None, - u'''a[/*1*/x/*2*/=/*3*/a/*4*/]''': None, - u'''a[/*1*/x/*2*/~=/*3*/a/*4*/]''': None, - u'''a[/*1*/x/*2*/|=/*3*/a/*4*/]''': None, - - # pseudo-elements - u'a x:first-line': None, - u'a x:first-letter': None, - u'a x:before': None, - u'a x:after': None, - u'a x::selection': None, - u'a:hover+b:hover>c:hover~e:hover f:hover': - u'a:hover + b:hover > c:hover ~ e:hover f:hover', - u'a:hover + b:hover > c:hover ~ e:hover f:hover': - u'a:hover + b:hover > c:hover ~ e:hover f:hover', - u'a::selection+b::selection>c::selection~e::selection f::selection': - u'a::selection + b::selection > c::selection ~ e::selection f::selection', - u'a::selection + b::selection > c::selection ~ e::selection f::selection': - u'a::selection + b::selection > c::selection ~ e::selection f::selection', - - u'x:lang(de) y': None, - u'x:nth-child(odd) y': None, - # functional pseudo - u'x:func(a + b-2px22.3"s"i)': None, - u'x:func(1 + 1)': None, - u'x:func(1+1)': u'x:func(1 + 1)', - u'x:func(1 + 1)': u'x:func(1 + 1)', - u'x:func(1-1)': u'x:func(1-1)', - u'x:func(1 - 1)': u'x:func(1 -1)', - u'x:func(a-1)': u'x:func(a-1)', - u'x:func(a -1px)': u'x:func(a -1px)', - u'x:func(1px)': None, - u'x:func(23.4)': None, - u'x:func("s")': None, - u'x:func(i)': None, - - # negation - u':not(y)': None, - u':not( y \t\n)': u':not(y)', - u'*:not(y)': None, - u'x:not(y)': None, - u'.x:not(y)': None, - u':not(*)': None, - u':not(#a)': None, - u':not(.a)': None, - u':not([a])': None, - u':not(:first-letter)': None, - u':not(::first-letter)': None, - - # escapes - ur'\74\72 td': 'trtd', - ur'\74\72 td': 'tr td', - ur'\74\000072 td': 'trtd', - ur'\74\000072 td': 'tr td', - - # comments - u'a/**/ b': None, - u'a /**/b': None, - u'a /**/ b': None, - u'a /**/ b': u'a /**/ b', - u'a /**/ b': u'a /**/ b', - - # namespaces - u'|e': None, - u'*|e': None, - u'*|*': None, - (u'p|*', (('p', 'uri'),)): u'p|*', - (u'p|e', (('p', 'uri'),)): u'p|e', - (u'-a_x12|e', (('-a_x12', 'uri'),)): u'-a_x12|e', - (u'*|b[p|a]', (('p', 'uri'),)): '*|b[p|a]', - - # case - u'elemenT.clasS#iD[atT="valuE"]:noT(x)::firsT-linE': - u'elemenT.clasS#iD[atT="valuE"]:not(x)::first-line' - } - # do not parse as not complete - self.do_equal_r(tests, att='selectorText') - - tests = { - u'x|a': xml.dom.NamespaceErr, - (u'p|*', (('x', 'uri'),)): xml.dom.NamespaceErr, - - u'': xml.dom.SyntaxErr, - u'1': xml.dom.SyntaxErr, - u'-1': xml.dom.SyntaxErr, - u'a*b': xml.dom.SyntaxErr, - u'a *b': xml.dom.SyntaxErr, - u'a* b': xml.dom.SyntaxErr, - u'a/**/b': xml.dom.SyntaxErr, - - u'#': xml.dom.SyntaxErr, - u'|': xml.dom.SyntaxErr, - - u':': xml.dom.SyntaxErr, - u'::': xml.dom.SyntaxErr, - u': a': xml.dom.SyntaxErr, - u':: a': xml.dom.SyntaxErr, - u':a()': xml.dom.SyntaxErr, # no value - u'::a()': xml.dom.SyntaxErr, # no value - u':::a': xml.dom.SyntaxErr, - u':1': xml.dom.SyntaxErr, - - u'#.x': xml.dom.SyntaxErr, - u'.': xml.dom.SyntaxErr, - u'.1': xml.dom.SyntaxErr, - u'.a.1': xml.dom.SyntaxErr, - - u'[a': xml.dom.SyntaxErr, - u'a]': xml.dom.SyntaxErr, - u'[a b]': xml.dom.SyntaxErr, - u'[=b]': xml.dom.SyntaxErr, - u'[a=]': xml.dom.SyntaxErr, - u'[a|=]': xml.dom.SyntaxErr, - u'[a~=]': xml.dom.SyntaxErr, - u'[a=1]': xml.dom.SyntaxErr, - - u'a +': xml.dom.SyntaxErr, - u'a >': xml.dom.SyntaxErr, - u'a ++ b': xml.dom.SyntaxErr, - u'a + > b': xml.dom.SyntaxErr, - - # functional pseudo - u'*:lang(': xml.dom.SyntaxErr, - u'*:lang()': xml.dom.SyntaxErr, # no arg - - # negation - u'not(x)': xml.dom.SyntaxErr, # no valid function - u':not()': xml.dom.SyntaxErr, # no arg - u':not(x': xml.dom.SyntaxErr, # no ) - u':not(-': xml.dom.SyntaxErr, # not allowed - u':not(+': xml.dom.SyntaxErr, # not allowed - - # only one selector! - u',': xml.dom.InvalidModificationErr, - u',a': xml.dom.InvalidModificationErr, - u'a,': xml.dom.InvalidModificationErr, - - # @ - u'p @here': xml.dom.SyntaxErr, # not allowed - - } - # only set as not complete - self.do_raise_r(tests, att='_setSelectorText') - - def test_specificity(self): - "Selector.specificity" - selector = cssutils.css.Selector() - - # readonly - def _set(): selector.specificity = 1 - self.assertRaisesMsg(AttributeError, "can't set attribute", _set) - - tests = { - u'*': (0,0,0,0), - u'li': (0,0,0,1), - u'li:first-line': (0,0,0,2), - u'ul li': (0,0,0,2), - u'ul ol+li': (0,0,0,3), - u'h1 + *[rel=up]': (0,0,1,1), - u'ul ol li.red': (0,0,1,3), - u'li.red.level': (0,0,2,1), - u'#x34y': (0,1,0,0), - - u'UL OL LI.red': (0,0,1,3), - u'LI.red.level': (0,0,2,1), - u'#s12:not(FOO)': (0,1,0,1), - u'button:not([DISABLED])': (0,0,1,1), #? - u'*:not(FOO)': (0,0,0,1), - - # elements - u'a+b': (0,0,0,2), - u'a>b': (0,0,0,2), - u'a b': (0,0,0,2), - u'* a': (0,0,0,1), - u'a *': (0,0,0,1), - u'a * b': (0,0,0,2), - - u'a:hover': (0,0,0,1), - - u'a:first-line': (0,0,0,2), - u'a:first-letter': (0,0,0,2), - u'a:before': (0,0,0,2), - u'a:after': (0,0,0,2), - - # classes and attributes - u'.a': (0,0,1,0), - u'*.a': (0,0,1,0), - u'a.a': (0,0,1,1), - u'.a.a': (0,0,2,0), # IE<7 False (0,0,1,0) - u'a.a.a': (0,0,2,1), - u'.a.b': (0,0,2,0), - u'a.a.b': (0,0,2,1), - u'.a .a': (0,0,2,0), - u'*[x]': (0,0,1,0), - u'*[x]': (0,0,1,0), - u'*[x]': (0,0,1,0), - u'*[x=a]': (0,0,1,0), - u'*[x~=a]': (0,0,1,0), - u'*[x|=a]': (0,0,1,0), - u'*[x^=a]': (0,0,1,0), - u'*[x*=a]': (0,0,1,0), - u'*[x$=a]': (0,0,1,0), - u'*[x][y]': (0,0,2,0), - - # ids - u'#a': (0,1,0,0), - u'*#a': (0,1,0,0), - u'x#a': (0,1,0,1), - u'.x#a': (0,1,1,0), - u'a.x#a': (0,1,1,1), - u'#a#a': (0,2,0,0), # e.g. html:id + xml:id - u'#a#b': (0,2,0,0), - u'#a #b': (0,2,0,0), - } - for text in tests: - selector.selectorText = text - self.assertEqual(tests[text], selector.specificity) - - def test_reprANDstr(self): - "Selector.__repr__(), .__str__()" - sel=u'a + b' - - s = cssutils.css.Selector(selectorText=sel) - - self.assert_(sel in str(s)) - - s2 = eval(repr(s)) - self.assert_(isinstance(s2, s.__class__)) - self.assert_(sel == s2.selectorText) - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_selectorlist.py cssutils-0.9.10/src/tests/test_selectorlist.py --- cssutils-0.9.10~b1/src/tests/test_selectorlist.py 2011-07-26 18:22:54.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_selectorlist.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,147 +0,0 @@ -"""Testcases for cssutils.css.selectorlist.SelectorList.""" - -import xml.dom -import basetest -import cssutils -from cssutils.css.selectorlist import SelectorList - -class SelectorListTestCase(basetest.BaseTestCase): - - def setUp(self): - self.r = SelectorList() - - def test_init(self): - "SelectorList.__init__() and .length" - s = SelectorList() - self.assertEqual(0, s.length) - - s = SelectorList('a, b') - self.assertEqual(2, s.length) - self.assertEqual(u'a, b', s.selectorText) - - s = SelectorList(selectorText='a') - self.assertEqual(1, s.length) - self.assertEqual(u'a', s.selectorText) - - s = SelectorList(selectorText=('p|a', {'p': 'uri'})) # n-dict - self.assertEqual(1, s.length) - self.assertEqual(u'p|a', s.selectorText) - - s = SelectorList(selectorText=('p|a', (('p', 'uri'),))) # n-tuples - self.assertEqual(1, s.length) - self.assertEqual(u'p|a', s.selectorText) - - def test_parentRule(self): - "Selector.parentRule" - def check(style): - self.assertEqual(style, style.selectorList.parentRule) - for sel in style.selectorList: - self.assertEqual(style.selectorList, sel.parent) - - style = cssutils.css.CSSStyleRule('a, b') - check(style) - - # add new selector - style.selectorList.append(cssutils.css.Selector('x')) - check(style) - - # replace selectorList - style.selectorList = cssutils.css.SelectorList('x') - check(style) - - # replace selectorText - style.selectorText = ('x, y') - check(style) - - def test_appendSelector(self): - "SelectorList.appendSelector() and .length" - s = SelectorList() - s.appendSelector('a') - self.assertEqual(1, s.length) - - self.assertRaises(xml.dom.InvalidModificationErr, - s.appendSelector, 'b,') - self.assertEqual(1, s.length) - - self.assertEqual(u'a', s.selectorText) - - s.append('b') - self.assertEqual(2, s.length) - self.assertEqual(u'a, b', s.selectorText) - - s.append('a') - self.assertEqual(2, s.length) - self.assertEqual(u'b, a', s.selectorText) - - # __setitem__ - self.assertRaises(IndexError, s.__setitem__, 4, 'x') - s[1] = 'c' - self.assertEqual(2, s.length) - self.assertEqual(u'b, c', s.selectorText) - # TODO: remove duplicates? -# s[0] = 'c' -# self.assertEqual(1, s.length) -# self.assertEqual(u'c', s.selectorText) - - s = SelectorList() - s.appendSelector(('p|a', {'p': 'uri', 'x': 'xxx'})) - self.assertEqual(u'p|a', s.selectorText) - # x gets lost as not used - self.assertRaises(xml.dom.NamespaceErr, s.append, 'x|a') - # not set at all - self.assertRaises(xml.dom.NamespaceErr, s.append, 'y|a') - # but p is retained - s.append('p|b') - self.assertEqual(u'p|a, p|b', s.selectorText) - - def test_selectorText(self): - "SelectorList.selectorText" - s = SelectorList() - s.selectorText = u'a, b' - self.assertEqual(u'a, b', s.selectorText) - self.assertRaises(xml.dom.SyntaxErr, s._setSelectorText, u',') - # not changed as invalid! - self.assertEqual(u'a, b', s.selectorText) - - tests = { - u'*': None, - u'/*1*/*': None, - u'/*1*/*, a': None, - u'a, b': None, - u'a ,b': u'a, b', - u'a , b': u'a, b', - u'a, b, c': u'a, b, c', - u'#a, x#a, .b, x.b': u'#a, x#a, .b, x.b', - (u'[p|a], p|*', (('p', 'uri'),)): u'[p|a], p|*', - } - # do not parse as not complete - self.do_equal_r(tests, att='selectorText') - - tests = { - u'x|*': xml.dom.NamespaceErr, - u'': xml.dom.SyntaxErr, - u' ': xml.dom.SyntaxErr, - u',': xml.dom.SyntaxErr, - u'a,': xml.dom.SyntaxErr, - u',a': xml.dom.SyntaxErr, - u'/* 1 */,a': xml.dom.SyntaxErr, - } - # only set as not complete - self.do_raise_r(tests, att='_setSelectorText') - - def test_reprANDstr(self): - "SelectorList.__repr__(), .__str__()" - sel=(u'a, p|b', { 'p': 'uri'}) - - s = cssutils.css.SelectorList(selectorText=sel) - - self.assert_(sel[0] in str(s)) - - s2 = eval(repr(s)) - self.assert_(isinstance(s2, s.__class__)) - self.assertEqual(sel[0], s2.selectorText) - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_serialize.py cssutils-0.9.10/src/tests/test_serialize.py --- cssutils-0.9.10~b1/src/tests/test_serialize.py 2011-12-24 23:47:48.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_serialize.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,740 +0,0 @@ -# -*- coding: utf-8 -*- -"""Testcases for cssutils.CSSSerializer""" - -import basetest -import cssutils -import sys - - -class PreferencesTestCase(basetest.BaseTestCase): - """ - testcases for cssutils.serialize.Preferences - """ - def setUp(self): - cssutils.ser.prefs.useDefaults() - - def tearDown(self): - cssutils.ser.prefs.useDefaults() - -# def testkeepUnkownAtRules(self): -# "Preferences.keepUnkownAtRules" -# # py >=2.6 only -# # v = sys.version_info; if v[0]*10+v[1] >= 26: -# from warnings import catch_warnings -# with catch_warnings(record=True) as log: -# x = cssutils.ser.prefs.keepUnkownAtRules -# -# if log: -# # unpack the only member of log -# warning, = log -# self.assertEqual(warning.category, DeprecationWarning) - - def test_resolveVariables(self): - "Preferences.resolveVariables" - self.assertEqual(cssutils.ser.prefs.resolveVariables, True) - - cssutils.ser.prefs.resolveVariables = False - - vars = u''' - @variables { - c1: red; - c2: #0f0; - px: 1px 2px; - } - ''' - tests = { - u'''a {\n color: var(c1)\n }''': - u'''a {\n color: red\n }''', - u'''a {\n color: var(c1)\n; color: var( c2 ) }''': - u'''a {\n color: red;\n color: #0f0\n }''', - u'''a {\n margin: var(px)\n }''': - u'''a {\n margin: 1px 2px\n }''', - u'''@media all { - a { - margin: var(px) var(px); - color: var(c1); - left: var(unknown) - } - }''': - u'''@media all {\n a {\n margin: 1px 2px 1px 2px;\n color: red;\n left: var(unknown)\n }\n }''', - } - cssutils.ser.prefs.resolveVariables = True - - for test, exp in tests.items(): - s = cssutils.parseString(vars + test) - self.assertEqual(exp.encode(), s.cssText) - - cssutils.ser.prefs.resolveVariables = True - - - def test_useDefaults(self): - "Preferences.useDefaults()" - cssutils.ser.prefs.useMinified() - cssutils.ser.prefs.useDefaults() - self.assertEqual(cssutils.ser.prefs.defaultAtKeyword, True) - self.assertEqual(cssutils.ser.prefs.defaultPropertyName, True) - self.assertEqual(cssutils.ser.prefs.defaultPropertyPriority, True) - self.assertEqual(cssutils.ser.prefs.importHrefFormat, None) - self.assertEqual(cssutils.ser.prefs.indent, 4 * u' ') - self.assertEqual(cssutils.ser.prefs.indentClosingBrace, True) - self.assertEqual(cssutils.ser.prefs.keepAllProperties, True) - self.assertEqual(cssutils.ser.prefs.keepComments, True) - self.assertEqual(cssutils.ser.prefs.keepEmptyRules, False) - self.assertEqual(cssutils.ser.prefs.keepUnknownAtRules, True) - self.assertEqual(cssutils.ser.prefs.keepUsedNamespaceRulesOnly, False) - self.assertEqual(cssutils.ser.prefs.lineNumbers, False) - self.assertEqual(cssutils.ser.prefs.lineSeparator, u'\n') - self.assertEqual(cssutils.ser.prefs.listItemSpacer, u' ') - self.assertEqual(cssutils.ser.prefs.omitLastSemicolon, True) - self.assertEqual(cssutils.ser.prefs.omitLeadingZero, False) - self.assertEqual(cssutils.ser.prefs.paranthesisSpacer, u' ') - self.assertEqual(cssutils.ser.prefs.propertyNameSpacer, u' ') - self.assertEqual(cssutils.ser.prefs.selectorCombinatorSpacer, u' ') - self.assertEqual(cssutils.ser.prefs.spacer, u' ') - self.assertEqual(cssutils.ser.prefs.validOnly, False) - css = u''' - /*1*/ - @import url(x) tv , print; - @namespace prefix "uri"; - @namespace unused "unused"; - @media all {} - @media all { - a {} - } - @media all { - a { color: red; } - } - @page { left: 0; } - a {} - prefix|x, a + b > c ~ d , b { top : 1px ; - font-family : arial ,'some' - } - ''' - parsedcss = u'''/*1*/ -@import url(x) tv, print; -@namespace prefix "uri"; -@namespace unused "unused"; -@media all { - a { - color: red - } - } -@page { - left: 0 - } -prefix|x, a + b > c ~ d, b { - top: 1px; - font-family: arial, "some" - }''' - s = cssutils.parseString(css) - self.assertEqual(s.cssText, parsedcss.encode()) - - tests = { - u'0.1 .1 0.1px .1px 0.1% .1% +0.1 +.1 +0.1px +.1px +0.1% +.1% -0.1 -.1 -0.1px -.1px -0.1% -.1%': - u'0.1 0.1 0.1px 0.1px 0.1% 0.1% +0.1 +0.1 +0.1px +0.1px +0.1% +0.1% -0.1 -0.1 -0.1px -0.1px -0.1% -0.1%' - } - cssutils.ser.prefs.useDefaults() - for test, exp in tests.items(): - s = cssutils.parseString(u'a{x:%s}' % test) - self.assertEqual((u'a {\n x: %s\n }' % exp).encode(), s.cssText) - - - def test_useMinified(self): - "Preferences.useMinified()" - cssutils.ser.prefs.useDefaults() - cssutils.ser.prefs.useMinified() - self.assertEqual(cssutils.ser.prefs.defaultAtKeyword, True) - self.assertEqual(cssutils.ser.prefs.defaultPropertyName, True) - self.assertEqual(cssutils.ser.prefs.importHrefFormat, 'string') - self.assertEqual(cssutils.ser.prefs.indent, u'') - self.assertEqual(cssutils.ser.prefs.keepAllProperties, True) - self.assertEqual(cssutils.ser.prefs.keepComments, False) - self.assertEqual(cssutils.ser.prefs.keepEmptyRules, False) - self.assertEqual(cssutils.ser.prefs.keepUnknownAtRules, False) - self.assertEqual(cssutils.ser.prefs.keepUsedNamespaceRulesOnly, True) - self.assertEqual(cssutils.ser.prefs.lineNumbers, False) - self.assertEqual(cssutils.ser.prefs.lineSeparator, u'') - self.assertEqual(cssutils.ser.prefs.listItemSpacer, u'') - self.assertEqual(cssutils.ser.prefs.omitLastSemicolon, True) - self.assertEqual(cssutils.ser.prefs.omitLeadingZero, True) - self.assertEqual(cssutils.ser.prefs.paranthesisSpacer, u'') - self.assertEqual(cssutils.ser.prefs.propertyNameSpacer, u'') - self.assertEqual(cssutils.ser.prefs.selectorCombinatorSpacer, u'') - self.assertEqual(cssutils.ser.prefs.spacer, u'') - self.assertEqual(cssutils.ser.prefs.validOnly, False) - - css = u''' - /*1*/ - @import url(x) tv , print; - @namespace prefix "uri"; - @namespace unused "unused"; - @media all {} - @media all { - a {} - } - @media all "name" { - a { color: red; } - } - @page:left { - left: 0 - } - a {} - prefix|x, a + b > c ~ d , b { top : 1px ; - font-family : arial , 'some' - } - @x x; - ''' - s = cssutils.parseString(css) - cssutils.ser.prefs.keepUnknownAtRules = True - self.assertEqual(s.cssText, - u'''@import"x"tv,print;@namespace prefix"uri";@media all"name"{a{color:red}}@page :left{left:0}prefix|x,a+b>c~d,b{top:1px;font-family:arial,"some"}@x x;'''.encode() - ) - cssutils.ser.prefs.keepUnknownAtRules = False - self.assertEqual(s.cssText, - u'''@import"x"tv,print;@namespace prefix"uri";@media all"name"{a{color:red}}@page :left{left:0}prefix|x,a+b>c~d,b{top:1px;font-family:arial,"some"}'''.encode() - ) - # Values - valuetests = { - u' a a1 a-1 a-1a ': 'a a1 a-1 a-1a', - u'a b 1 c 1em d -1em e': u'a b 1 c 1em d -1em e', - u' 1em / 5 ': u'1em/5', - u'1em/5': u'1em/5', - u'a 0 a .0 a 0.0 a -0 a -.0 a -0.0 a +0 a +.0 a +0.0': - u'a 0 a 0 a 0 a 0 a 0 a 0 a 0 a 0 a 0', - u'a 0px a .0px a 0.0px a -0px a -.0px a -0.0px a +0px a +.0px a +0.0px ': - u'a 0 a 0 a 0 a 0 a 0 a 0 a 0 a 0 a 0', - u'a 1 a .1 a 1.0 a 0.1 a -1 a -.1 a -1.0 a -0.1 a +1 a +.1 a +1.0': - u'a 1 a .1 a 1 a .1 a -1 a -.1 a -1 a -.1 a +1 a +.1 a +1', - u' url(x) f()': 'url(x) f()', - u'#112233': '#123', - u'#112234': '#112234', - u'#123': '#123', - u'#123 url() f()': '#123 url() f()', - u'1 +2 +3 -4': u'1 +2 +3 -4', # ? - u'0.1 .1 0.1px .1px 0.1% .1% +0.1 +.1 +0.1px +.1px +0.1% +.1% -0.1 -.1 -0.1px -.1px -0.1% -.1%': - u'.1 .1 .1px .1px .1% .1% +.1 +.1 +.1px +.1px +.1% +.1% -.1 -.1 -.1px -.1px -.1% -.1%' - } - for test, exp in valuetests.items(): - s = cssutils.parseString(u'a{x:%s}' % test) - self.assertEqual((u'a{x:%s}' % exp).encode(), s.cssText) - - - - def test_defaultAtKeyword(self): - "Preferences.defaultAtKeyword" - s = cssutils.parseString(u'@im\\port "x";') - self.assertEqual(u'@import "x";'.encode(), s.cssText) - cssutils.ser.prefs.defaultAtKeyword = True - self.assertEqual(u'@import "x";'.encode(), s.cssText) - cssutils.ser.prefs.defaultAtKeyword = False - self.assertEqual(u'@im\\port "x";'.encode(), s.cssText) - - def test_defaultPropertyName(self): - "Preferences.defaultPropertyName" - cssutils.ser.prefs.keepAllProperties = False - - # does not actually work as once the name is set it is used also - # if used with a backslash in it later... - - s = cssutils.parseString(ur'a { c\olor: green; }') - self.assertEqual(u'a {\n color: green\n }'.encode(), s.cssText) - cssutils.ser.prefs.defaultPropertyName = True - self.assertEqual(u'a {\n color: green\n }'.encode(), s.cssText) - cssutils.ser.prefs.defaultPropertyName = False - self.assertEqual(u'a {\n c\\olor: green\n }'.encode(), s.cssText) - - s = cssutils.parseString(u'a { color: red; c\olor: green; }') - self.assertEqual(u'a {\n c\\olor: green\n }'.encode(), s.cssText) - cssutils.ser.prefs.defaultPropertyName = False - self.assertEqual(u'a {\n c\\olor: green\n }'.encode(), s.cssText) - cssutils.ser.prefs.defaultPropertyName = True - self.assertEqual(u'a {\n color: green\n }'.encode(), s.cssText) - - def test_defaultPropertyPriority(self): - "Preferences.defaultPropertyPriority" - css = u'a {\n color: green !IM\\portant\n }' - s = cssutils.parseString(css) - self.assertEqual(s.cssText, u'a {\n color: green !important\n }'.encode()) - cssutils.ser.prefs.defaultPropertyPriority = False - self.assertEqual(s.cssText, css.encode()) - - def test_importHrefFormat(self): - "Preferences.importHrefFormat" - r0 = cssutils.css.CSSImportRule() - r0.cssText=u'@import url("not");' - r1 = cssutils.css.CSSImportRule() - r1.cssText=u'@import "str";' - self.assertEqual(u'@import url(not);', r0.cssText) - self.assertEqual(u'@import "str";', r1.cssText) - - cssutils.ser.prefs.importHrefFormat = 'string' - self.assertEqual(u'@import "not";', r0.cssText) - self.assertEqual(u'@import "str";', r1.cssText) - - cssutils.ser.prefs.importHrefFormat = 'uri' - self.assertEqual(u'@import url(not);', r0.cssText) - self.assertEqual(u'@import url(str);', r1.cssText) - - cssutils.ser.prefs.importHrefFormat = 'not defined' - self.assertEqual(u'@import url(not);', r0.cssText) - self.assertEqual(u'@import "str";', r1.cssText) - - def test_indent(self): - "Preferences.ident" - s = cssutils.parseString(u'a { left: 0 }') - exp4 = u'''a { - left: 0 - }''' - exp1 = u'''a { - left: 0 - }''' - cssutils.ser.prefs.indent = ' ' - self.assertEqual(exp1.encode(), s.cssText) - cssutils.ser.prefs.indent = 4* ' ' - self.assertEqual(exp4.encode(), s.cssText) - - def test_indentClosingBrace(self): - "Preferences.indentClosingBrace" - s = cssutils.parseString(u'@media all {a {left: 0}} b { top: 0 }') - expT = u'''@media all { - a { - left: 0 - } - } -b { - top: 0 - }''' - expF = u'''@media all { - a { - left: 0 - } -} -b { - top: 0 -}''' - cssutils.ser.prefs.useDefaults() - self.assertEqual(expT.encode(), s.cssText) - cssutils.ser.prefs.indentClosingBrace = False - self.assertEqual(expF.encode(), s.cssText) - - def test_keepAllProperties(self): - "Preferences.keepAllProperties" - css = '''a { - color: pink; - color: red; - c\olor: blue; - c\olor: green; - }''' - s = cssutils.parseString(css) - # keep only last - cssutils.ser.prefs.keepAllProperties = False - self.assertEqual(u'a {\n color: green\n }'.encode(), s.cssText) - # keep all - cssutils.ser.prefs.keepAllProperties = True - self.assertEqual(u'a {\n color: pink;\n color: red;\n c\olor: blue;\n c\olor: green\n }'.encode(), s.cssText) - - def test_keepComments(self): - "Preferences.keepComments" - s = cssutils.parseString('/*1*/ a { /*2*/ }') - cssutils.ser.prefs.keepComments = False - self.assertEqual(''.encode(), s.cssText) - cssutils.ser.prefs.keepEmptyRules = True - self.assertEqual('a {}'.encode(), s.cssText) - - def test_keepEmptyRules(self): - "Preferences.keepEmptyRules" - # CSSStyleRule - css = u'''a {} -a { - /*1*/ - } -a { - color: red - }''' - s = cssutils.parseString(css) - cssutils.ser.prefs.useDefaults() - cssutils.ser.prefs.keepEmptyRules = True - self.assertEqual(css.encode(), s.cssText) - cssutils.ser.prefs.keepEmptyRules = False - self.assertEqual(u'a {\n /*1*/\n }\na {\n color: red\n }'.encode(), - s.cssText) - cssutils.ser.prefs.keepComments = False - self.assertEqual(u'a {\n color: red\n }'.encode(), s.cssText) - - # CSSMediaRule - css = u'''@media tv { - } -@media all { - /*1*/ - } -@media print { - a {} - } -@media print { - a { - /*1*/ - } - } -@media all { - a { - color: red - } - }''' - s = cssutils.parseString(css) - cssutils.ser.prefs.useDefaults() - cssutils.ser.prefs.keepEmptyRules = True - # self.assertEqual(css, s.cssText) - cssutils.ser.prefs.keepEmptyRules = False - self.assertEqual('''@media all { - /*1*/ - } -@media print { - a { - /*1*/ - } - } -@media all { - a { - color: red - } - }'''.encode(), s.cssText) - cssutils.ser.prefs.keepComments = False - self.assertEqual('''@media all { - a { - color: red - } - }'''.encode(), s.cssText) - - def test_keepUnknownAtRules(self): - "Preferences.keepUnknownAtRules" - tests = { - u'''@three-dee { - @background-lighting { - azimuth: 30deg; - elevation: 190deg; - } - h1 { color: red } - } - h1 { color: blue }''': (u'''@three-dee { - @background-lighting { - azimuth: 30deg; - elevation: 190deg; - } h1 { - color: red - } - } -h1 { - color: blue - }''', u'''h1 { - color: blue - }''') - } - for test in tests: - s = cssutils.parseString(test) - expwith, expwithout = tests[test] - cssutils.ser.prefs.keepUnknownAtRules = True - self.assertEqual(s.cssText, expwith.encode()) - cssutils.ser.prefs.keepUnknownAtRules = False - self.assertEqual(s.cssText, expwithout.encode()) - - def test_keepUsedNamespaceRulesOnly(self): - "Preferences.keepUsedNamespaceRulesOnly" - tests = { - # default == prefix => both are combined - '@namespace p "u"; @namespace "u"; p|a, a {top: 0}': - ('@namespace "u";\na, a {\n top: 0\n }', - '@namespace "u";\na, a {\n top: 0\n }'), - '@namespace "u"; @namespace p "u"; p|a, a {top: 0}': - ('@namespace p "u";\np|a, p|a {\n top: 0\n }', - '@namespace p "u";\np|a, p|a {\n top: 0\n }'), - # default and prefix - '@namespace p "u"; @namespace "d"; p|a, a {top: 0}': - ('@namespace p "u";\n@namespace "d";\np|a, a {\n top: 0\n }', - '@namespace p "u";\n@namespace "d";\np|a, a {\n top: 0\n }'), - # prefix only - '@namespace p "u"; @namespace "d"; p|a {top: 0}': - ('@namespace p "u";\n@namespace "d";\np|a {\n top: 0\n }', - '@namespace p "u";\np|a {\n top: 0\n }'), - # default only - '@namespace p "u"; @namespace "d"; a {top: 0}': - ('@namespace p "u";\n@namespace "d";\na {\n top: 0\n }', - '@namespace "d";\na {\n top: 0\n }'), - # prefix-ns only - '@namespace p "u"; @namespace d "d"; p|a {top: 0}': - ('@namespace p "u";\n@namespace d "d";\np|a {\n top: 0\n }', - '@namespace p "u";\np|a {\n top: 0\n }'), - } - for test in tests: - s = cssutils.parseString(test) - expwith, expwithout = tests[test] - cssutils.ser.prefs.keepUsedNamespaceRulesOnly = False - self.assertEqual(s.cssText, expwith.encode()) - cssutils.ser.prefs.keepUsedNamespaceRulesOnly = True - self.assertEqual(s.cssText, expwithout.encode()) - - def test_lineNumbers(self): - "Preferences.lineNumbers" - - s = cssutils.parseString('a {top: 1; left: 2}') - exp0 = '''a { - top: 1; - left: 2 - }''' - exp1 = '''1: a { -2: top: 1; -3: left: 2 -4: }''' - self.assertEqual(False, cssutils.ser.prefs.lineNumbers) - self.assertEqual(exp0.encode(), s.cssText) - cssutils.ser.prefs.lineNumbers = True - self.assertEqual(True, cssutils.ser.prefs.lineNumbers) - self.assertEqual(exp1.encode(), s.cssText) - - def test_lineSeparator(self): - "Preferences.lineSeparator" - s = cssutils.parseString('a { x:1;y:2}') - self.assertEqual('a {\n x: 1;\n y: 2\n }'.encode(), s.cssText) - # cannot be indented as no split possible - cssutils.ser.prefs.lineSeparator = u'' - self.assertEqual('a {x: 1;y: 2 }'.encode(), s.cssText) - # no valid css but should work - cssutils.ser.prefs.lineSeparator = u'XXX' - self.assertEqual('a {XXX x: 1;XXX y: 2XXX }'.encode(), s.cssText) - - def test_listItemSpacer(self): - "Preferences.listItemSpacer" - cssutils.ser.prefs.keepEmptyRules = True - - css = ''' - @import "x" print, tv; -a, b {}''' - s = cssutils.parseString(css) - self.assertEqual(u'@import "x" print, tv;\na, b {}'.encode(), s.cssText) - cssutils.ser.prefs.listItemSpacer = u'' - self.assertEqual(u'@import "x" print,tv;\na,b {}'.encode(), s.cssText) - - def test_omitLastSemicolon(self): - "Preferences.omitLastSemicolon" - css = 'a { x: 1; y: 2 }' - s = cssutils.parseString(css) - self.assertEqual(u'a {\n x: 1;\n y: 2\n }'.encode(), s.cssText) - cssutils.ser.prefs.omitLastSemicolon = False - self.assertEqual(u'a {\n x: 1;\n y: 2;\n }'.encode(), s.cssText) - - def test_normalizedVarNames(self): - "Preferences.normalizedVarNames" - cssutils.ser.prefs.resolveVariables = False - - css = '@variables { A: 1 }' - s = cssutils.parseString(css) - self.assertEqual(u'@variables {\n a: 1\n }'.encode(), s.cssText) - cssutils.ser.prefs.normalizedVarNames = False - self.assertEqual(u'@variables {\n A: 1\n }'.encode(), s.cssText) - - cssutils.ser.prefs.resolveVariables = True - - def test_paranthesisSpacer(self): - "Preferences.paranthesisSpacer" - css = 'a { x: 1; y: 2 }' - s = cssutils.parseString(css) - self.assertEqual(u'a {\n x: 1;\n y: 2\n }'.encode(), s.cssText) - cssutils.ser.prefs.paranthesisSpacer = u'' - self.assertEqual(u'a{\n x: 1;\n y: 2\n }'.encode(), s.cssText) - - def test_propertyNameSpacer(self): - "Preferences.propertyNameSpacer" - css = 'a { x: 1; y: 2 }' - s = cssutils.parseString(css) - self.assertEqual(u'a {\n x: 1;\n y: 2\n }'.encode(), s.cssText) - cssutils.ser.prefs.propertyNameSpacer = u'' - self.assertEqual(u'a {\n x:1;\n y:2\n }'.encode(), s.cssText) - - def test_selectorCombinatorSpacer(self): - "Preferences.selectorCombinatorSpacer" - s = cssutils.css.Selector(selectorText='a+b>c~d e') - self.assertEqual(u'a + b > c ~ d e', s.selectorText) - cssutils.ser.prefs.selectorCombinatorSpacer = u'' - self.assertEqual(u'a+b>c~d e', s.selectorText) - - def test_spacer(self): - cssutils.ser.prefs.spacer = u'' - tests = { - u'@font-face {a:1}': u'@font-face {\n a: 1\n }', - u'@import url( a );': u'@import url(a);', - u'@media all{a{color:red}}': u'@media all {\n a {\n color: red\n }\n }', - u'@namespace "a";': u'@namespace"a";', - u'@namespace a "a";': u'@namespace a"a";', - u'@page :left { a :1 }': u'@page :left {\n a: 1\n }', - u'@x x;': u'@x x;', - u'@import"x"a': u'@import"x"a;' # ? - } - for css, exp in tests.items(): - self.assertEqual(exp.encode(), cssutils.parseString(css).cssText) - - def test_validOnly(self): - "Preferences.validOnly" - # Property - p = cssutils.css.Property('color', '1px') - self.assertEqual(p.cssText, 'color: 1px') - p.value = '1px' - cssutils.ser.prefs.validOnly = True - self.assertEqual(p.cssText, '') - cssutils.ser.prefs.validOnly = False - self.assertEqual(p.cssText, 'color: 1px') - - # CSSStyleDeclaration has no actual property valid - # but is empty if containing invalid Properties only - s = cssutils.css.CSSStyleDeclaration() - s.cssText = u'left: x;top: x' - self.assertEqual(s.cssText, u'left: x;\ntop: x') - cssutils.ser.prefs.validOnly = True - self.assertEqual(s.cssText, u'') - - cssutils.ser.prefs.useDefaults() - cssutils.ser.prefs.keepComments = False - cssutils.ser.prefs.validOnly = True - tests = { - u'h1 { color: red; rotation: 70minutes }': 'h1 {\n color: red;\n }', - u'''img { float: left } /* correct CSS 2.1 */ -img { float: left here } /* "here" is not a value of 'float' */ -img { background: "red" } /* keywords cannot be quoted */ -img { border-width: 3 } /* a unit must be specified for length values */''': 'img {\n float: left\n }' - - } - self.do_equal_p(tests, raising=False) - - -class CSSSerializerTestCase(basetest.BaseTestCase): - """ - testcases for cssutils.CSSSerializer - """ - def setUp(self): - cssutils.ser.prefs.useDefaults() - - def tearDown(self): - cssutils.ser.prefs.useDefaults() - - def test_canonical(self): - tests = { - u'''1''': u'''1''', - # => remove + - u'''+1''': u'''+1''', - # 0 => remove unit - u'''0''': u'''0''', - u'''+0''': u'''0''', - u'''-0''': u'''0''', - u'''0.0''': u'''0''', - u'''00.0''': u'''0''', - u'''00.0px''': u'''0''', - u'''00.0pc''': u'''0''', - u'''00.0em''': u'''0''', - u'''00.0ex''': u'''0''', - u'''00.0cm''': u'''0''', - u'''00.0mm''': u'''0''', - u'''00.0in''': u'''0''', - # 0 => keep unit - u'''00.0%''': u'''0%''', - u'''00.0ms''': u'''0ms''', - u'''00.0s''': u'''0s''', - u'''00.0khz''': u'''0khz''', - u'''00.0hz''': u'''0hz''', - u'''00.0khz''': u'''0khz''', - u'''00.0deg''': u'''0deg''', - u'''00.0rad''': u'''0rad''', - u'''00.0grad''': u'''0grad''', - u'''00.0xx''': u'''0xx''', - # 11. - u'''a, 'b"', serif''': ur'''a, "b\"", serif''', - # SHOULD: \[ => [ but keep! - ur"""url('h)i') '\[\]'""": ur'''url("h)i") "\[\]"''', - u'''rgb(18, 52, 86)''': u'''rgb(18, 52, 86)''', - u'''#123456''': u'''#123456''', - # SHOULD => #112233 - u'''#112233''': u'''#123''', - # SHOULD => #000000 -# u'rgba(000001, 0, 0, 1)': u'#000' - } - for test, exp in tests.items(): - v = cssutils.css.PropertyValue(test) - self.assertEqual(exp, v.cssText) - - - def test_CSSStyleSheet(self): - "CSSSerializer.do_CSSStyleSheet" - css = u'/* κουρος */' - sheet = cssutils.parseString(css) - self.assertEqual(css, unicode(sheet.cssText, 'utf-8')) - - css = u'@charset "utf-8";\n/* κουρος */' - sheet = cssutils.parseString(css) - self.assertEqual(css, unicode(sheet.cssText, 'utf-8')) - sheet.cssRules[0].encoding = 'ascii' - self.assertEqual('@charset "ascii";\n/* \\3BA \\3BF \\3C5 \\3C1 \\3BF \\3C2 */'.encode(), - sheet.cssText) - - def test_Property(self): - "CSSSerializer.do_Property" - - name="color" - value="red" - priority="!important" - - s = cssutils.css.property.Property( - name=name, value=value, priority=priority) - self.assertEqual(u'color: red !important', - cssutils.ser.do_Property(s)) - - s = cssutils.css.property.Property( - name=name, value=value) - self.assertEqual(u'color: red', - cssutils.ser.do_Property(s)) - - def test_escapestring(self): - "CSSSerializer._escapestring" - #'"\a\22\27"' - css = ur'''@import url("ABC\a"); -@import "ABC\a"; -@import 'ABC\a'; -a[href='"\a\22\27"'] { - a: "\a\d\c"; - b: "\a \d \c "; - c: "\""; - d: "\22"; - e: '\''; - f: "\\"; - g: "2\\ 1\ 2\\"; - content: '\27'; - }''' -# exp = ur'''@import url("ABC\a "); -#@import "ABC\a"; -#@import "ABC\a"; -#a[href="\"\a\22\27\""] { -# a: "\a\d\c"; -# b: "\a \d \c "; -# c: "\""; -# d: "\22"; -# e: "'"; -# f: "\\"; -# g: "2\\ 1\ 2\\"; -# content: "\27" -# }''' - exp = ur'''@import url("ABC\a "); -@import "ABC\a "; -@import "ABC\a "; -a[href="\"\a \"'\""] { - a: "\a \d \c "; - b: "\a \d \c "; - c: "\""; - d: "\""; - e: "'"; - f: "\\"; - g: "2\\ 1\ 2\\"; - content: "'" - }''' - sheet = cssutils.parseString(css) - self.assertEqual(sheet.cssText, exp.encode()) - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_settings.py cssutils-0.9.10/src/tests/test_settings.py --- cssutils-0.9.10~b1/src/tests/test_settings.py 2011-12-24 23:18:44.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_settings.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -"""Testcases for cssutils.settings""" -__version__ = '$Id: test_csscharsetrule.py 1356 2008-07-13 17:29:09Z cthedot $' - -import test_cssrule -import cssutils -import cssutils.settings - -class Settings(test_cssrule.CSSRuleTestCase): - - def test_set(self): - "settings.set()" - cssutils.ser.prefs.useMinified() - text = u'a {filter: progid:DXImageTransform.Microsoft.BasicImage( rotation = 90 )}' - - self.assertEqual(cssutils.parseString(text).cssText, ''.encode()) - - cssutils.settings.set('DXImageTransform.Microsoft', True) - self.assertEqual(cssutils.parseString(text).cssText, - 'a{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=90)}'.encode()) - - cssutils.ser.prefs.useDefaults() - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_stylesheet.py cssutils-0.9.10/src/tests/test_stylesheet.py --- cssutils-0.9.10~b1/src/tests/test_stylesheet.py 2011-07-24 18:24:06.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_stylesheet.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -"""Testcases for cssutils.stylesheets.StyleSheet""" -__version__ = '$Id: test_csspagerule.py 1869 2009-10-17 19:37:40Z cthedot $' - -import xml.dom -import basetest -import cssutils - -class StyleSheetTestCase(basetest.BaseTestCase): - - def test_init(self): - "StyleSheet.__init__()" - s = cssutils.stylesheets.StyleSheet() - - self.assertEqual(s.type, 'text/css') - self.assertEqual(s.href, None) - self.assertEqual(s.media, None) - self.assertEqual(s.title, u'') - self.assertEqual(s.ownerNode, None) - self.assertEqual(s.parentStyleSheet, None) - self.assertEqual(s.alternate, False) - self.assertEqual(s.disabled, False) - - - s = cssutils.stylesheets.StyleSheet(type='unknown', - href='test.css', - media=None, - title=u'title', - ownerNode=None, - parentStyleSheet=None, - alternate=True, - disabled=True) - - self.assertEqual(s.type, 'unknown') - self.assertEqual(s.href, 'test.css') - self.assertEqual(s.media, None) - self.assertEqual(s.title, u'title') - self.assertEqual(s.ownerNode, None) - self.assertEqual(s.parentStyleSheet, None) - self.assertEqual(s.alternate, True) - self.assertEqual(s.disabled, True) - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_tokenize2.py cssutils-0.9.10/src/tests/test_tokenize2.py --- cssutils-0.9.10~b1/src/tests/test_tokenize2.py 2012-01-31 19:08:30.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_tokenize2.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,858 +0,0 @@ -# -*- coding: utf-8 -*- -"""Testcases for new cssutils.tokenize.Tokenizer - -TODO: old tests as new ones are **not complete**! -""" - -import sys -import xml.dom -import basetest -from cssutils.tokenize2 import * - -class TokenizerTestCase(basetest.BaseTestCase): - - testsall = { - # IDENT - u'äöü߀': [('IDENT', u'äöü߀', 1, 1)], - u' a ': [('S', u' ', 1, 1), - ('IDENT', u'a', 1, 2), - ('S', u' ', 1, 3)], - u'_a': [('IDENT', u'_a', 1, 1)], - u'-a': [('IDENT', u'-a', 1, 1)], - u'aA-_\200\377': [('IDENT', u'aA-_\200\377', 1, 1)], - u'a1': [('IDENT', u'a1', 1, 1)], - # escapes must end with S or max 6 digits: - u'\\44 b': [('IDENT', u'Db', 1, 1)], - u'\\44 b': [('IDENT', u'D', 1, 1), - ('S', u' ', 1, 5), - ('IDENT', u'b', 1, 6)], - u'\\44\nb': [('IDENT', u'Db', 1, 1)], - u'\\44\rb': [('IDENT', u'Db', 1, 1)], - u'\\44\fb': [('IDENT', u'Db', 1, 1)], - u'\\44\n*': [('IDENT', u'D', 1, 1), - ('CHAR', u'*', 2, 1)], - u'\\44 a': [('IDENT', u'D', 1, 1), - ('S', u' ', 1, 5), - ('IDENT', u'a', 1, 6)], - # TODO: - # Note that this means that a "real" space after the escape sequence - # must itself either be escaped or doubled: - u'\\44\ x': [('IDENT', u'D\\ x', 1, 1)], - u'\\44 ': [('IDENT', u'D', 1, 1), - ('S', u' ', 1, 5)], - - ur'\44': [('IDENT', u'D', 1, 1)], - ur'\\': [('IDENT', ur'\\', 1, 1)], - ur'\{': [('IDENT', ur'\{', 1, 1)], - ur'\"': [('IDENT', ur'\"', 1, 1)], - ur'\(': [('IDENT', ur'\(', 1, 1)], - ur'\1 \22 \333 \4444 \55555 \666666 \777777 7 \7777777': - [( - ('IDENT', u'\x01"\u0333\u4444\U00055555\\666666 \\777777 7', 1, 1) - if sys.maxunicode > 0x10000 else - ('IDENT', u'\x01"\u0333\u4444\\55555 \\666666 \\777777 7', 1, 1) - ), - ('S', ' ', 1, 43), - ('IDENT', '\\7777777', 1, 44) - ], - - - u'\\1 b': [('IDENT', u'\x01b', 1, 1)], - u'\\44 b': [('IDENT', u'Db', 1, 1)], - u'\\123 b': [('IDENT', u'\u0123b', 1, 1)], - u'\\1234 b': [('IDENT', u'\u1234b', 1, 1)], - u'\\12345 b': - [( - ('IDENT', u'\U00012345b', 1, 1) - if sys.maxunicode > 0x10000 else - ('IDENT', u'\\12345 b', 1, 1) - )], - u'\\123456 b': [('IDENT', u'\\123456 b', 1, 1)], - u'\\1234567 b': [('IDENT', u'\\1234567', 1, 1), - ('S', u' ', 1, 9), - ('IDENT', u'b', 1, 10)], - u'\\{\\}\\(\\)\\[\\]\\#\\@\\.\\,': - [('IDENT', u'\\{\\}\\(\\)\\[\\]\\#\\@\\.\\,', 1, 1)], - - # STRING - u' "" ': [('S', u' ', 1, 1), - ('STRING', u'""', 1, 2), - ('S', u' ', 1, 4)], - u' "\'" ': [('S', u' ', 1, 1), - ('STRING', u'"\'"', 1, 2), - ('S', u' ', 1, 5)], - u" '' ": [('S', u' ', 1, 1), - ('STRING', u"''", 1, 2), - ('S', u' ', 1, 4)], - u" '' ": [('S', u' ', 1, 1), - ('STRING', u"''", 1, 2), - ('S', u' ', 1, 4)], - # until 0.9.5.x - #u"'\\\n'": [('STRING', u"'\\\n'", 1, 1)], - #u"'\\\n\\\n\\\n'": [('STRING', u"'\\\n\\\n\\\n'", 1, 1)], - #u"'\\\f'": [('STRING', u"'\\\f'", 1, 1)], - #u"'\\\r'": [('STRING', u"'\\\r'", 1, 1)], - #u"'\\\r\n'": [('STRING', u"'\\\r\n'", 1, 1)], - #u"'1\\\n2'": [('STRING', u"'1\\\n2'", 1, 1)], - # from 0.9.6a0 escaped nl is removed from string - u"'\\\n'": [('STRING', u"''", 1, 1)], - u"'\\\n\\\n\\\n'": [('STRING', u"''", 1, 1)], - u"'\\\f'": [('STRING', u"''", 1, 1)], - u"'\\\r'": [('STRING', u"''", 1, 1)], - u"'1\\\n2'": [('STRING', u"'12'", 1, 1)], - u"'1\\\r\n2'": [('STRING', u"'12'", 1, 1)], - #ur'"\0020|\0020"': [('STRING', u'"\\0020|\\0020"', 1, 1)], - ur'"\61|\0061"': [('STRING', u'"a|a"', 1, 1)], - - # HASH - u' #a ': [('S', u' ', 1, 1), - ('HASH', u'#a', 1, 2), - ('S', u' ', 1, 4)], - - u'#ccc': [('HASH', u'#ccc', 1, 1)], - u'#111': [('HASH', u'#111', 1, 1)], - u'#a1a1a1': [('HASH', u'#a1a1a1', 1, 1)], - u'#1a1a1a': [('HASH', u'#1a1a1a', 1, 1)], - - # NUMBER, for plus see CSS3 - u' 0 ': [('S', u' ', 1, 1), - ('NUMBER', u'0', 1, 2), - ('S', u' ', 1, 3)], - u' 0.1 ': [('S', u' ', 1, 1), - ('NUMBER', u'0.1', 1, 2), - ('S', u' ', 1, 5)], - u' .0 ': [('S', u' ', 1, 1), - ('NUMBER', u'.0', 1, 2), - ('S', u' ', 1, 4)], - - u' -0 ': [('S', u' ', 1, 1), - ('CHAR', u'-', 1, 2), - ('NUMBER', u'0', 1, 3), - ('S', u' ', 1, 4)], - - # PERCENTAGE - u' 0% ': [('S', u' ', 1, 1), - ('PERCENTAGE', u'0%', 1, 2), - ('S', u' ', 1, 4)], - u' .5% ': [('S', u' ', 1, 1), - ('PERCENTAGE', u'.5%', 1, 2), - ('S', u' ', 1, 5)], - - # URI - u' url() ': [('S', u' ', 1, 1), - ('URI', u'url()', 1, 2), - ('S', u' ', 1, 7)], - u' url(a) ': [('S', u' ', 1, 1), - ('URI', u'url(a)', 1, 2), - ('S', u' ', 1, 8)], - u' url("a") ': [('S', u' ', 1, 1), - ('URI', u'url("a")', 1, 2), - ('S', u' ', 1, 10)], - u' url( a ) ': [('S', u' ', 1, 1), - ('URI', u'url( a )', 1, 2), - ('S', u' ', 1, 10)], - - # UNICODE-RANGE - - # CDO - u' "': [('STRING', u'""', 1, 7)], - - # CDC - u' --> ': [('S', u' ', 1, 1), - ('CDC', u'-->', 1, 2), - ('S', u' ', 1, 5)], - - # S - u' ': [('S', u' ', 1, 1)], - u' ': [('S', u' ', 1, 1)], - u'\r': [('S', u'\r', 1, 1)], - u'\n': [('S', u'\n', 1, 1)], - u'\r\n': [('S', u'\r\n', 1, 1)], - u'\f': [('S', u'\f', 1, 1)], - u'\r': [('S', u'\r', 1, 1)], - u'\t': [('S', u'\t', 1, 1)], - u'\r\n\r\n\f\t ': [('S', u'\r\n\r\n\f\t ', 1, 1)], - - # COMMENT, for incomplete see later - u'/*x*/ ': [('COMMENT', u'/*x*/', 1, 1), - ('S', u' ', 1, 6)], - - # FUNCTION - u' x( ': [('S', u' ', 1, 1), - ('FUNCTION', u'x(', 1, 2), - ('S', u' ', 1, 4)], - - # INCLUDES - u' ~= ': [('S', u' ', 1, 1), - ('INCLUDES', u'~=', 1, 2), - ('S', u' ', 1, 4)], - u'~==': [('INCLUDES', u'~=', 1, 1), ('CHAR', u'=', 1, 3)], - - # DASHMATCH - u' |= ': [('S', u' ', 1, 1), - ('DASHMATCH', u'|=', 1, 2), - ('S', u' ', 1, 4)], - u'|==': [('DASHMATCH', u'|=', 1, 1), ('CHAR', u'=', 1, 3)], - - # CHAR - u' @ ': [('S', u' ', 1, 1), - ('CHAR', u'@', 1, 2), - ('S', u' ', 1, 3)], - - # --- overwritten for CSS 2.1 --- - # LBRACE - u' { ': [('S', u' ', 1, 1), - ('CHAR', u'{', 1, 2), - ('S', u' ', 1, 3)], - # PLUS - u' + ': [('S', u' ', 1, 1), - ('CHAR', u'+', 1, 2), - ('S', u' ', 1, 3)], - # GREATER - u' > ': [('S', u' ', 1, 1), - ('CHAR', u'>', 1, 2), - ('S', u' ', 1, 3)], - # COMMA - u' , ': [('S', u' ', 1, 1), - ('CHAR', u',', 1, 2), - ('S', u' ', 1, 3)], - # class - u' . ': [('S', u' ', 1, 1), - ('CHAR', u'.', 1, 2), - ('S', u' ', 1, 3)], - } - - tests3 = { - # UNICODE-RANGE - u' u+0 ': [('S', u' ', 1, 1), - ('UNICODE-RANGE', u'u+0', 1, 2), - ('S', u' ', 1, 5)], - u' u+01 ': [('S', u' ', 1, 1), - ('UNICODE-RANGE', u'u+01', 1, 2), - ('S', u' ', 1, 6)], - u' u+012 ': [('S', u' ', 1, 1), - ('UNICODE-RANGE', u'u+012', 1, 2), - ('S', u' ', 1, 7)], - u' u+0123 ': [('S', u' ', 1, 1), - ('UNICODE-RANGE', u'u+0123', 1, 2), - ('S', u' ', 1, 8)], - u' u+01234 ': [('S', u' ', 1, 1), - ('UNICODE-RANGE', u'u+01234', 1, 2), - ('S', u' ', 1, 9)], - u' u+012345 ': [('S', u' ', 1, 1), - ('UNICODE-RANGE', u'u+012345', 1, 2), - ('S', u' ', 1, 10)], - u' u+0123456 ': [('S', u' ', 1, 1), - ('UNICODE-RANGE', u'u+012345', 1, 2), - ('NUMBER', u'6', 1, 10), - ('S', u' ', 1, 11)], - u' U+123456 ': [('S', u' ', 1, 1), - ('UNICODE-RANGE', u'U+123456', 1, 2), - ('S', u' ', 1, 10)], - u' \\55+abcdef ': [('S', u' ', 1, 1), - ('UNICODE-RANGE', u'U+abcdef', 1, 2), - ('S', u' ', 1, 12)], - u' \\75+abcdef ': [('S', u' ', 1, 1), - ('UNICODE-RANGE', u'u+abcdef', 1, 2), - ('S', u' ', 1, 12)], - u' u+0-1 ': [('S', u' ', 1, 1), - ('UNICODE-RANGE', u'u+0-1', 1, 2), - ('S', u' ', 1, 7)], - u' u+0-1, u+123456-abcdef ': [('S', u' ', 1, 1), - ('UNICODE-RANGE', u'u+0-1', 1, 2), - ('CHAR', u',', 1, 7), - ('S', u' ', 1, 8), - ('UNICODE-RANGE', u'u+123456-abcdef', 1, 9), - ('S', u' ', 1, 24)], - - # specials - u'c\\olor': [('IDENT', u'c\\olor', 1, 1)], - u'-1': [('CHAR', u'-', 1, 1), ('NUMBER', u'1', 1, 2)], - u'-1px': [('CHAR', u'-', 1, 1), ('DIMENSION', u'1px', 1, 2)], - - # ATKEYWORD - u' @x ': [('S', u' ', 1, 1), - ('ATKEYWORD', u'@x', 1, 2), - ('S', u' ', 1, 4)], - u'@X': [('ATKEYWORD', u'@X', 1, 1)], - u'@\\x': [('ATKEYWORD', u'@\\x', 1, 1)], - # - - u'@1x': [('CHAR', u'@', 1, 1), - ('DIMENSION', u'1x', 1, 2)], - - # DIMENSION - u' 0px ': [('S', u' ', 1, 1), - ('DIMENSION', u'0px', 1, 2), - ('S', u' ', 1, 5)], - u' 1s ': [('S', u' ', 1, 1), - ('DIMENSION', u'1s', 1, 2), - ('S', u' ', 1, 4)], - u'0.2EM': [('DIMENSION', u'0.2EM', 1, 1)], - u'1p\\x': [('DIMENSION', u'1p\\x', 1, 1)], - u'1PX': [('DIMENSION', u'1PX', 1, 1)], - - # NUMBER - u' - 0 ': [('S', u' ', 1, 1), - ('CHAR', u'-', 1, 2), - ('S', u' ', 1, 3), - ('NUMBER', u'0', 1, 4), - ('S', u' ', 1, 5)], - u' + 0 ': [('S', u' ', 1, 1), - ('CHAR', u'+', 1, 2), - ('S', u' ', 1, 3), - ('NUMBER', u'0', 1, 4), - ('S', u' ', 1, 5)], - - # PREFIXMATCH - u' ^= ': [('S', u' ', 1, 1), - ('PREFIXMATCH', u'^=', 1, 2), - ('S', u' ', 1, 4)], - u'^==': [('PREFIXMATCH', u'^=', 1, 1), ('CHAR', u'=', 1, 3)], - - # SUFFIXMATCH - u' $= ': [('S', u' ', 1, 1), - ('SUFFIXMATCH', u'$=', 1, 2), - ('S', u' ', 1, 4)], - u'$==': [('SUFFIXMATCH', u'$=', 1, 1), ('CHAR', u'=', 1, 3)], - - # SUBSTRINGMATCH - u' *= ': [('S', u' ', 1, 1), - ('SUBSTRINGMATCH', u'*=', 1, 2), - ('S', u' ', 1, 4)], - u'*==': [('SUBSTRINGMATCH', u'*=', 1, 1), ('CHAR', u'=', 1, 3)], - - # BOM only at start -# u'\xFEFF ': [('BOM', u'\xfeFF', 1, 1), -# ('S', u' ', 1, 1)], -# u' \xFEFF ': [('S', u' ', 1, 1), -# ('IDENT', u'\xfeFF', 1, 2), -# ('S', u' ', 1, 5)], - u'\xfe\xff ': [('BOM', u'\xfe\xff', 1, 1), - ('S', u' ', 1, 1)], - u' \xfe\xff ': [('S', u' ', 1, 1), - ('IDENT', u'\xfe\xff', 1, 2), - ('S', u' ', 1, 4)], - u'\xef\xbb\xbf ': [('BOM', u'\xef\xbb\xbf', 1, 1), - ('S', u' ', 1, 1)], - u' \xef\xbb\xbf ': [('S', u' ', 1, 1), - ('IDENT', u'\xef\xbb\xbf', 1, 2), - ('S', u' ', 1, 5)], } - - tests2 = { - # escapes work not for a-f! - # IMPORT_SYM - u' @import ': [('S', u' ', 1, 1), - ('IMPORT_SYM', u'@import', 1, 2), - ('S', u' ', 1, 9)], - u'@IMPORT': [('IMPORT_SYM', u'@IMPORT', 1, 1)], - u'@\\49\r\nMPORT': [('IMPORT_SYM', u'@\\49\r\nMPORT', 1, 1)], - ur'@\i\m\p\o\r\t': [('IMPORT_SYM', ur'@\i\m\p\o\r\t', 1, 1)], - ur'@\I\M\P\O\R\T': [('IMPORT_SYM', ur'@\I\M\P\O\R\T', 1, 1)], - ur'@\49 \04d\0050\0004f\000052\54': [('IMPORT_SYM', - ur'@\49 \04d\0050\0004f\000052\54', - 1, 1)], - ur'@\69 \06d\0070\0006f\000072\74': [('IMPORT_SYM', - ur'@\69 \06d\0070\0006f\000072\74', - 1, 1)], - - # PAGE_SYM - u' @page ': [('S', u' ', 1, 1), - ('PAGE_SYM', u'@page', 1, 2), - ('S', u' ', 1, 7)], - u'@PAGE': [('PAGE_SYM', u'@PAGE', 1, 1)], - ur'@\pa\ge': [('PAGE_SYM', ur'@\pa\ge', 1, 1)], - ur'@\PA\GE': [('PAGE_SYM', ur'@\PA\GE', 1, 1)], - ur'@\50\41\47\45': [('PAGE_SYM', ur'@\50\41\47\45', 1, 1)], - ur'@\70\61\67\65': [('PAGE_SYM', ur'@\70\61\67\65', 1, 1)], - - # MEDIA_SYM - u' @media ': [('S', u' ', 1, 1), - ('MEDIA_SYM', u'@media', 1, 2), - ('S', u' ', 1, 8)], - u'@MEDIA': [('MEDIA_SYM', u'@MEDIA', 1, 1)], - ur'@\med\ia': [('MEDIA_SYM', ur'@\med\ia', 1, 1)], - ur'@\MED\IA': [('MEDIA_SYM', ur'@\MED\IA', 1, 1)], - u'@\\4d\n\\45\r\\44\t\\49\r\nA': [('MEDIA_SYM', u'@\\4d\n\\45\r\\44\t\\49\r\nA', 1, 1)], - u'@\\4d\n\\45\r\\44\t\\49\r\\41\f': [('MEDIA_SYM', - u'@\\4d\n\\45\r\\44\t\\49\r\\41\f', - 1, 1)], - u'@\\6d\n\\65\r\\64\t\\69\r\\61\f': [('MEDIA_SYM', - u'@\\6d\n\\65\r\\64\t\\69\r\\61\f', - 1, 1)], - - # FONT_FACE_SYM - u' @font-face ': [('S', u' ', 1, 1), - ('FONT_FACE_SYM', u'@font-face', 1, 2), - ('S', u' ', 1, 12)], - u'@FONT-FACE': [('FONT_FACE_SYM', u'@FONT-FACE', 1, 1)], - ur'@f\o\n\t\-face': [('FONT_FACE_SYM', ur'@f\o\n\t\-face', 1, 1)], - ur'@F\O\N\T\-FACE': [('FONT_FACE_SYM', ur'@F\O\N\T\-FACE', 1, 1)], - # TODO: "-" as hex! - ur'@\46\4f\4e\54\-\46\41\43\45': [('FONT_FACE_SYM', - ur'@\46\4f\4e\54\-\46\41\43\45', 1, 1)], - ur'@\66\6f\6e\74\-\66\61\63\65': [('FONT_FACE_SYM', - ur'@\66\6f\6e\74\-\66\61\63\65', 1, 1)], - - # CHARSET_SYM only if "@charset "! - u'@charset ': [('CHARSET_SYM', u'@charset ', 1, 1), - ('S', u' ', 1, 10)], - u' @charset ': [('S', u' ', 1, 1), - ('CHARSET_SYM', u'@charset ', 1, 2), # not at start - ('S', u' ', 1, 11)], - u'@charset': [('ATKEYWORD', u'@charset', 1, 1)], # no ending S - u'@CHARSET ': [('ATKEYWORD', u'@CHARSET', 1, 1),# uppercase - ('S', u' ', 1, 9)], - u'@cha\\rset ': [('ATKEYWORD', u'@cha\\rset', 1, 1), # not literal - ('S', u' ', 1, 10)], - - # NAMESPACE_SYM - u' @namespace ': [('S', u' ', 1, 1), - ('NAMESPACE_SYM', u'@namespace', 1, 2), - ('S', u' ', 1, 12)], - ur'@NAMESPACE': [('NAMESPACE_SYM', ur'@NAMESPACE', 1, 1)], - ur'@\na\me\s\pace': [('NAMESPACE_SYM', ur'@\na\me\s\pace', 1, 1)], - ur'@\NA\ME\S\PACE': [('NAMESPACE_SYM', ur'@\NA\ME\S\PACE', 1, 1)], - ur'@\4e\41\4d\45\53\50\41\43\45': [('NAMESPACE_SYM', - ur'@\4e\41\4d\45\53\50\41\43\45', 1, 1)], - ur'@\6e\61\6d\65\73\70\61\63\65': [('NAMESPACE_SYM', - ur'@\6e\61\6d\65\73\70\61\63\65', 1, 1)], - - # ATKEYWORD - u' @unknown ': [('S', u' ', 1, 1), - ('ATKEYWORD', u'@unknown', 1, 2), - ('S', u' ', 1, 10)], - - # STRING - # strings with linebreak in it - u' "\\na"\na': [('S', u' ', 1, 1), - ('STRING', u'"\\na"', 1, 2), - ('S', u'\n', 1, 7), - ('IDENT', u'a', 2, 1)], - u" '\\na'\na": [('S', u' ', 1, 1), - ('STRING', u"'\\na'", 1, 2), - ('S', u'\n', 1, 7), - ('IDENT', u'a', 2, 1)], - u' "\\r\\n\\t\\n\\ra"a': [('S', u' ', 1, 1), - ('STRING', u'"\\r\\n\\t\\n\\ra"', 1, 2), - ('IDENT', u'a', 1, 15)], - - # IMPORTANT_SYM is not IDENT!!! - u' !important ': [('S', u' ', 1, 1), - ('CHAR', u'!', 1, 2), - ('IDENT', u'important', 1, 3), - ('S', u' ', 1, 12)], - u'! /*1*/ important ': [ - ('CHAR', u'!', 1, 1), - ('S', u' ', 1, 2), - ('COMMENT', u'/*1*/', 1, 3), - ('S', u' ', 1, 8), - ('IDENT', u'important', 1, 9), - ('S', u' ', 1, 18)], - u'! important': [('CHAR', u'!', 1, 1), - ('S', u' ', 1, 2), - ('IDENT', u'important', 1, 3)], - u'!\n\timportant': [('CHAR', u'!', 1, 1), - ('S', u'\n\t', 1, 2), - ('IDENT', u'important', 2, 2)], - u'!IMPORTANT': [('CHAR', u'!', 1, 1), - ('IDENT', u'IMPORTANT', 1, 2)], - ur'!\i\m\p\o\r\ta\n\t': [('CHAR', u'!', 1, 1), - ('IDENT', - ur'\i\m\p\o\r\ta\n\t', 1, 2)], - ur'!\I\M\P\O\R\Ta\N\T': [('CHAR', u'!', 1, 1), - ('IDENT', - ur'\I\M\P\O\R\Ta\N\T', 1, 2)], - ur'!\49\4d\50\4f\52\54\41\4e\54': [('CHAR', u'!', 1, 1), - ('IDENT', - ur'IMPORTANT', - 1, 2)], - ur'!\69\6d\70\6f\72\74\61\6e\74': [('CHAR', u'!', 1, 1), - ('IDENT', - ur'important', - 1, 2)], - } - - # overwriting tests in testsall - tests2only = { - # LBRACE - u' { ': [('S', u' ', 1, 1), - ('LBRACE', u'{', 1, 2), - ('S', u' ', 1, 3)], - # PLUS - u' + ': [('S', u' ', 1, 1), - ('PLUS', u'+', 1, 2), - ('S', u' ', 1, 3)], - # GREATER - u' > ': [('S', u' ', 1, 1), - ('GREATER', u'>', 1, 2), - ('S', u' ', 1, 3)], - # COMMA - u' , ': [('S', u' ', 1, 1), - ('COMMA', u',', 1, 2), - ('S', u' ', 1, 3)], - # class - u' . ': [('S', u' ', 1, 1), - ('CLASS', u'.', 1, 2), - ('S', u' ', 1, 3)], - } - - testsfullsheet = { - # escape ends with explicit space but \r\n as single space - u'\\65\r\nb': [('IDENT', u'eb', 1, 1)], - - # STRING - ur'"\""': [('STRING', ur'"\""', 1, 1)], - ur'"\" "': [('STRING', ur'"\" "', 1, 1)], - u"""'\\''""": [('STRING', u"""'\\''""", 1, 1)], - u'''"\\""''': [('STRING', u'''"\\""''', 1, 1)], - u' "\na': [('S', u' ', 1, 1), - ('INVALID', u'"', 1, 2), - ('S', u'\n', 1, 3), - ('IDENT', u'a', 2, 1)], - - # strings with linebreak in it - u' "\\na\na': [('S', u' ', 1, 1), - ('INVALID', u'"\\na', 1, 2), - ('S', u'\n', 1, 6), - ('IDENT', u'a', 2, 1)], - u' "\\r\\n\\t\\n\\ra\na': [('S', u' ', 1, 1), - ('INVALID', u'"\\r\\n\\t\\n\\ra', 1, 2), - ('S', u'\n', 1, 14), - ('IDENT', u'a', 2, 1)], - # URI - u'ur\\l(a)': [('URI', u'ur\\l(a)', 1, 1)], - u'url(a)': [('URI', u'url(a)', 1, 1)], - u'\\55r\\4c(a)': [('URI', u'UrL(a)', 1, 1)], - u'\\75r\\6c(a)': [('URI', u'url(a)', 1, 1)], - u' url())': [('S', u' ', 1, 1), - ('URI', u'url()', 1, 2), - ('CHAR', u')', 1, 7)], - u'url("x"))': [('URI', u'url("x")', 1, 1), - ('CHAR', u')', 1, 9)], - u"url('x'))": [('URI', u"url('x')", 1, 1), - ('CHAR', u')', 1, 9)], - } - - # tests if fullsheet=False is set on tokenizer - testsfullsheetfalse = { - # COMMENT incomplete - u'/*': [('CHAR', u'/', 1, 1), - ('CHAR', u'*', 1, 2)], - - # INVALID incomplete - u' " ': [('S', u' ', 1, 1), - ('INVALID', u'" ', 1, 2)], - u" 'abc\"with quote\" in it": [('S', u' ', 1, 1), - ('INVALID', u"'abc\"with quote\" in it", 1, 2)], - - # URI incomplete - u'url(a': [('FUNCTION', u'url(', 1, 1), - ('IDENT', u'a', 1, 5)], - u'url("a': [('FUNCTION', u'url(', 1, 1), - ('INVALID', u'"a', 1, 5)], - u"url('a": [('FUNCTION', u'url(', 1, 1), - ('INVALID', u"'a", 1, 5)], - u"UR\\l('a": [('FUNCTION', u'UR\\l(', 1, 1), - ('INVALID', u"'a", 1, 6)], - } - - # tests if fullsheet=True is set on tokenizer - testsfullsheettrue = { - # COMMENT incomplete - u'/*': [('COMMENT', u'/**/', 1, 1)], - -# # INVALID incomplete => STRING - u' " ': [('S', u' ', 1, 1), - ('STRING', u'" "', 1, 2)], - u" 'abc\"with quote\" in it": [('S', u' ', 1, 1), - ('STRING', u"'abc\"with quote\" in it'", 1, 2)], - - # URI incomplete FUNC => URI - u'url(a': [('URI', u'url(a)', 1, 1)], - u'url( a': [('URI', u'url( a)', 1, 1)], - u'url("a': [('URI', u'url("a")', 1, 1)], - u'url( "a ': [('URI', u'url( "a ")', 1, 1)], - u"url('a": [('URI', u"url('a')", 1, 1)], - u'url("a"': [('URI', u'url("a")', 1, 1)], - u"url('a'": [('URI', u"url('a')", 1, 1)], - } - - def setUp(self): - #log = cssutils.errorhandler.ErrorHandler() - self.tokenizer = Tokenizer() - -# NOT USED -# def test_push(self): -# "Tokenizer.push()" -# r = [] -# def do(): -# T = Tokenizer() -# x = False -# for t in T.tokenize('1 x 2 3'): -# if not x and t[1] == 'x': -# T.push(t) -# x = True -# r.append(t[1]) -# return ''.join(r) -# -# # push reinserts token into token stream, so x is doubled -# self.assertEqual('1 xx 2 3', do()) - -# def test_linenumbers(self): -# "Tokenizer line + col" -# pass - - def test_tokenize(self): - "cssutils Tokenizer().tokenize()" - import cssutils.cssproductions - tokenizer = Tokenizer(cssutils.cssproductions.MACROS, - cssutils.cssproductions.PRODUCTIONS) - tests = {} - tests.update(self.testsall) - tests.update(self.tests2) - tests.update(self.tests3) - tests.update(self.testsfullsheet) - tests.update(self.testsfullsheetfalse) - for css in tests: - # check token format - tokens = tokenizer.tokenize(css) - for i, actual in enumerate(tokens): - expected = tests[css][i] - self.assertEqual(expected, actual) - - # check if all same number of tokens - tokens = list(tokenizer.tokenize(css)) - self.assertEqual(len(tokens), len(tests[css])) - - def test_tokenizefullsheet(self): - "cssutils Tokenizer().tokenize(fullsheet=True)" - import cssutils.cssproductions - tokenizer = Tokenizer(cssutils.cssproductions.MACROS, - cssutils.cssproductions.PRODUCTIONS) - tests = {} - tests.update(self.testsall) - tests.update(self.tests2) - tests.update(self.tests3) - tests.update(self.testsfullsheet) - tests.update(self.testsfullsheettrue) - for css in tests: - # check token format - tokens = tokenizer.tokenize(css, fullsheet=True) - for i, actual in enumerate(tokens): - try: - expected = tests[css][i] - except IndexError: - # EOF is added - self.assertEqual(actual[0], 'EOF') - else: - self.assertEqual(expected, actual) - - # check if all same number of tokens - tokens = list(tokenizer.tokenize(css, fullsheet=True)) - # EOF is added so -1 - self.assertEqual(len(tokens) - 1, len(tests[css])) - - - # -------------- - - def __old(self): - - testsOLD = { - u'x x1 -x .-x #_x -': [(1, 1, tt.IDENT, u'x'), - (1, 2, 'S', u' '), - (1, 3, tt.IDENT, u'x1'), - (1, 5, 'S', u' '), - (1, 6, tt.IDENT, u'-x'), - (1, 8, 'S', u' '), - (1, 9, tt.CLASS, u'.'), - (1, 10, tt.IDENT, u'-x'), - (1, 12, 'S', u' '), - (1, 13, tt.HASH, u'#_x'), - (1, 16, 'S', u' '), - (1, 17, 'DELIM', u'-')], - - # num - u'1 1.1 -1 -1.1 .1 -.1 1.': [(1, 1, tt.NUMBER, u'1'), - (1, 2, 'S', u' '), (1, 3, tt.NUMBER, u'1.1'), - (1, 6, 'S', u' '), (1, 7, tt.NUMBER, u'-1'), - (1, 9, 'S', u' '), (1, 10, tt.NUMBER, u'-1.1'), - (1, 14, 'S', u' '), (1, 15, tt.NUMBER, u'0.1'), - (1, 17, 'S', u' '), (1, 18, tt.NUMBER, u'-0.1'), - (1, 21, 'S', u' '), - (1, 22, tt.NUMBER, u'1'), (1, 23, tt.CLASS, u'.') - ], - # CSS3 pseudo - u'::': [(1, 1, tt.PSEUDO_ELEMENT, u'::')], - - # SPECIALS - u'*+>~{},': [(1, 1, tt.UNIVERSAL, u'*'), - (1, 2, tt.PLUS, u'+'), - (1, 3, tt.GREATER, u'>'), - (1, 4, tt.TILDE, u'~'), - (1, 5, tt.LBRACE, u'{'), - (1, 6, tt.RBRACE, u'}'), - (1, 7, tt.COMMA, u',')], - - # DELIM - u'!%:&$|': [(1, 1, 'DELIM', u'!'), - (1, 2, 'DELIM', u'%'), - (1, 3, 'DELIM', u':'), - (1, 4, 'DELIM', u'&'), - (1, 5, 'DELIM', u'$'), - (1, 6, 'DELIM', u'|')], - - - # DIMENSION - u'5em': [(1, 1, tt.DIMENSION, u'5em')], - u' 5em': [(1, 1, 'S', u' '), (1, 2, tt.DIMENSION, u'5em')], - u'5em ': [(1, 1, tt.DIMENSION, u'5em'), (1, 4, 'S', u' ')], - - u'-5em': [(1, 1, tt.DIMENSION, u'-5em')], - u' -5em': [(1, 1, 'S', u' '), (1, 2, tt.DIMENSION, u'-5em')], - u'-5em ': [(1, 1, tt.DIMENSION, u'-5em'), (1, 5, 'S', u' ')], - - u'.5em': [(1, 1, tt.DIMENSION, u'0.5em')], - u' .5em': [(1, 1, 'S', u' '), (1, 2, tt.DIMENSION, u'0.5em')], - u'.5em ': [(1, 1, tt.DIMENSION, u'0.5em'), (1, 5, 'S', u' ')], - - u'-.5em': [(1, 1, tt.DIMENSION, u'-0.5em')], - u' -.5em': [(1, 1, 'S', u' '), (1, 2, tt.DIMENSION, u'-0.5em')], - u'-.5em ': [(1, 1, tt.DIMENSION, u'-0.5em'), (1, 6, 'S', u' ')], - - u'5em5_-': [(1, 1, tt.DIMENSION, u'5em5_-')], - - u'a a5 a5a 5 5a 5a5': [(1, 1, tt.IDENT, u'a'), - (1, 2, 'S', u' '), - (1, 3, tt.IDENT, u'a5'), - (1, 5, 'S', u' '), - (1, 6, tt.IDENT, u'a5a'), - (1, 9, 'S', u' '), - (1, 10, tt.NUMBER, u'5'), - (1, 11, 'S', u' '), - (1, 12, tt.DIMENSION, u'5a'), - (1, 14, 'S', u' '), - (1, 15, tt.DIMENSION, u'5a5')], - - # URI - u'url()': [(1, 1, tt.URI, u'url()')], - u'url();': [(1, 1, tt.URI, u'url()'), (1, 6, tt.SEMICOLON, ';')], - u'url("x")': [(1, 1, tt.URI, u'url("x")')], - u'url( "x")': [(1, 1, tt.URI, u'url("x")')], - u'url("x" )': [(1, 1, tt.URI, u'url("x")')], - u'url( "x" )': [(1, 1, tt.URI, u'url("x")')], - u' url("x")': [ - (1, 1, 'S', u' '), - (1, 2, tt.URI, u'url("x")')], - u'url("x") ': [ - (1, 1, tt.URI, u'url("x")'), - (1, 9, 'S', u' '), - ], - u'url(ab)': [(1, 1, tt.URI, u'url(ab)')], - u'url($#/ab)': [(1, 1, tt.URI, u'url($#/ab)')], - u'url(\1233/a/b)': [(1, 1, tt.URI, u'url(\1233/a/b)')], - # not URI - u'url("1""2")': [ - (1, 1, tt.FUNCTION, u'url('), - (1, 5, tt.STRING, u'"1"'), - (1, 8, tt.STRING, u'"2"'), - (1, 11, tt.RPARANTHESIS, u')'), - ], - u'url(a"2")': [ - (1, 1, tt.FUNCTION, u'url('), - (1, 5, tt.IDENT, u'a'), - (1, 6, tt.STRING, u'"2"'), - (1, 9, tt.RPARANTHESIS, u')'), - ], - u'url(a b)': [ - (1, 1, tt.FUNCTION, u'url('), - (1, 5, tt.IDENT, u'a'), - (1, 6, 'S', u' '), - (1, 7, tt.IDENT, u'b'), - (1, 8, tt.RPARANTHESIS, u')'), - ], - - # FUNCTION - u' counter("x")': [ - (1,1, 'S', u' '), - (1, 2, tt.FUNCTION, u'counter('), - (1, 10, tt.STRING, u'"x"'), - (1, 13, tt.RPARANTHESIS, u')')], - # HASH - u'# #a #_a #-a #1': [ - (1, 1, 'DELIM', u'#'), - (1, 2, 'S', u' '), - (1, 3, tt.HASH, u'#a'), - (1, 5, 'S', u' '), - (1, 6, tt.HASH, u'#_a'), - (1, 9, 'S', u' '), - (1, 10, tt.HASH, u'#-a'), - (1, 13, 'S', u' '), - (1, 14, tt.HASH, u'#1') - ], - u'#1a1 ': [ - (1, 1, tt.HASH, u'#1a1'), - (1, 5, 'S', u' '), - ], - u'#1a1\n': [ - (1, 1, tt.HASH, u'#1a1'), - (1, 5, 'S', u'\n'), - ], - u'#1a1{': [ - (1, 1, tt.HASH, u'#1a1'), - (1, 5, tt.LBRACE, u'{'), - ], - u'#1a1 {': [ - (1, 1, tt.HASH, u'#1a1'), - (1, 5, 'S', u' '), - (1, 6, tt.LBRACE, u'{'), - ], - u'#1a1\n{': [ - (1, 1, tt.HASH, u'#1a1'), - (1, 5, 'S', u'\n'), - (2, 1, tt.LBRACE, u'{'), - ], - u'#1a1\n {': [ - (1, 1, tt.HASH, u'#1a1'), - (1, 5, 'S', u'\n '), - (2, 2, tt.LBRACE, u'{'), - ], - u'#1a1 \n{': [ - (1, 1, tt.HASH, u'#1a1'), - (1, 5, 'S', u' \n'), - (2, 1, tt.LBRACE, u'{'), - ], - # STRINGS with NL - u'"x\n': [(1,1, tt.INVALID, u'"x\n')], - u'"x\r': [(1,1, tt.INVALID, u'"x\r')], - u'"x\f': [(1,1, tt.INVALID, u'"x\f')], - u'"x\n ': [ - (1,1, tt.INVALID, u'"x\n'), - (2,1, 'S', u' ') - ] - - } - - tests = { - u'/*a': xml.dom.SyntaxErr, - u'"a': xml.dom.SyntaxErr, - u"'a": xml.dom.SyntaxErr, - u"\\0 a": xml.dom.SyntaxErr, - u"\\00": xml.dom.SyntaxErr, - u"\\000": xml.dom.SyntaxErr, - u"\\0000": xml.dom.SyntaxErr, - u"\\00000": xml.dom.SyntaxErr, - u"\\000000": xml.dom.SyntaxErr, - u"\\0000001": xml.dom.SyntaxErr - } -# self.tokenizer.log.raiseExceptions = True #!! -# for css, exception in tests.items(): -# self.assertRaises(exception, self.tokenizer.tokenize, css) - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_util.py cssutils-0.9.10/src/tests/test_util.py --- cssutils-0.9.10~b1/src/tests/test_util.py 2011-07-26 18:22:54.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_util.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,422 +0,0 @@ -# -*- coding: utf-8 -*- -"""Testcases for cssutils.util""" -from __future__ import with_statement - -import cgi -from email import message_from_string, message_from_file -import StringIO -import sys -import urllib2 -import xml.dom - -try: - import mock -except ImportError: - mock = None - print "install mock library to run all tests" - -import basetest -import encutils - -from cssutils.util import Base, ListSeq, _readUrl, _defaultFetcher - -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 = {u'abcdefg ABCDEFG äöü߀ AÖÜ': u'abcdefg abcdefg äöü߀ aöü', - ur'\ga\Ga\\\ ': ur'gaga\ ', - ur'0123456789': u'0123456789', - # unicode escape seqs should have been done by - # the tokenizer... - } - for test, exp in 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', u'a[{1}]({2}) { } NOT', u'a[{1}]({2}) { }', False), - ('default', u'a[{1}]({2}) { } NOT', u'a[{1}]func({2}) { }', True), - ('blockstartonly', u'a[{1}]({2}) { NOT', u'a[{1}]({2}) {', False), - ('blockstartonly', u'a[{1}]({2}) { NOT', u'a[{1}]func({2}) {', True), - ('propertynameendonly', u'a[(2)1] { }2 : a;', u'a[(2)1] { }2 :', False), - ('propertynameendonly', u'a[(2)1] { }2 : a;', u'a[func(2)1] { }2 :', True), - ('propertyvalueendonly', u'a{;{;}[;](;)}[;{;}[;](;)](;{;}[;](;)) 1; NOT', - u'a{;{;}[;](;)}[;{;}[;](;)](;{;}[;](;)) 1;', False), - ('propertyvalueendonly', u'a{;{;}[;](;)}[;{;}[;](;)](;{;}[;](;)) 1; NOT', - u'a{;{;}[;]func(;)}[;{;}[;]func(;)]func(;{;}[;]func(;)) 1;', True), - ('funcendonly', u'a{[1]}([3])[{[1]}[2]([3])]) NOT', - u'a{[1]}([3])[{[1]}[2]([3])])', False), - ('funcendonly', u'a{[1]}([3])[{[1]}[2]([3])]) NOT', - u'a{[1]}func([3])[{[1]}[2]func([3])])', True), - ('selectorattendonly', u'[a[()]{()}([()]{()}())] NOT', - u'[a[()]{()}([()]{()}())]', False), - ('selectorattendonly', u'[a[()]{()}([()]{()}())] NOT', - u'[a[func()]{func()}func([func()]{func()}func())]', True), - # issue 50 - ('withstarttoken [', u'a];x', u'[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 u'(' == t[1]: - tokens[i] = ('FUNCTION', u'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 = u''.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, u''), - (None, u'€'.encode('utf-8')): ('utf-8', 5, u'€'), - ('utf-8', u'€'.encode('utf-8')): ('utf-8', 1, u'€'), - ('ISO-8859-1', u'ä'.encode('iso-8859-1')): ('ISO-8859-1', 1, u'ä'), - ('ASCII', u'a'.encode('ascii')): ('ASCII', 1, u'a') - } - - for r, exp in tests.items(): - self.assertEquals(_readUrl(url, fetcher=make_fetcher(r)), exp) - - tests = { - # (overrideEncoding, parentEncoding, (httpencoding, content)): - # readUrl returns - - # ===== 0. OVERRIDE WINS ===== - # override + parent + http - ('latin1', 'ascii', ('utf-16', u''.encode())): ('latin1', 0, u''), - ('latin1', 'ascii', ('utf-16', u'123'.encode())): ('latin1', 0, u'123'), - ('latin1', 'ascii', ('utf-16', u'ä'.encode('iso-8859-1'))): - ('latin1', 0, u'ä'), - ('latin1', 'ascii', ('utf-16', u'a'.encode('ascii'))): - ('latin1',0, u'a'), - # + @charset - ('latin1', 'ascii', ('utf-16', u'@charset "ascii";'.encode())): - ('latin1', 0, u'@charset "latin1";'), - ('latin1', 'ascii', ('utf-16', u'@charset "utf-8";ä'.encode('latin1'))): - ('latin1', 0, u'@charset "latin1";ä'), - ('latin1', 'ascii', ('utf-16', u'@charset "utf-8";ä'.encode('utf-8'))): - ('latin1', 0, u'@charset "latin1";\xc3\xa4'), # read as latin1! - - # override only - ('latin1', None, None): (None, None, None), - ('latin1', None, (None, u''.encode())): ('latin1', 0, u''), - ('latin1', None, (None, u'123'.encode())): ('latin1', 0, u'123'), - ('latin1', None, (None, u'ä'.encode('iso-8859-1'))): - ('latin1', 0, u'ä'), - ('latin1', None, (None, u'a'.encode('ascii'))): - ('latin1', 0, u'a'), - # + @charset - ('latin1', None, (None, u'@charset "ascii";'.encode())): - ('latin1', 0, u'@charset "latin1";'), - ('latin1', None, (None, u'@charset "utf-8";ä'.encode('latin1'))): - ('latin1', 0, u'@charset "latin1";ä'), - ('latin1', None, (None, u'@charset "utf-8";ä'.encode('utf-8'))): - ('latin1', 0, u'@charset "latin1";\xc3\xa4'), # read as latin1! - - # override + parent - ('latin1', 'ascii', None): (None, None, None), - ('latin1', 'ascii', (None, u''.encode())): ('latin1', 0, u''), - ('latin1', 'ascii', (None, u'123'.encode())): ('latin1', 0, u'123'), - ('latin1', 'ascii', (None, u'ä'.encode('iso-8859-1'))): - ('latin1', 0, u'ä'), - ('latin1', 'ascii', (None, u'a'.encode('ascii'))): - ('latin1', 0, u'a'), - # + @charset - ('latin1', 'ascii', (None, u'@charset "ascii";'.encode())): - ('latin1', 0, u'@charset "latin1";'), - ('latin1', 'ascii', (None, u'@charset "utf-8";ä'.encode('latin1'))): - ('latin1', 0, u'@charset "latin1";ä'), - ('latin1', 'ascii', (None, u'@charset "utf-8";ä'.encode('utf-8'))): - ('latin1', 0, u'@charset "latin1";\xc3\xa4'), # read as latin1! - - # override + http - ('latin1', None, ('utf-16', u''.encode())): ('latin1', 0, u''), - ('latin1', None, ('utf-16', u'123'.encode())): ('latin1', 0, u'123'), - ('latin1', None, ('utf-16', u'ä'.encode('iso-8859-1'))): - ('latin1', 0, u'ä'), - ('latin1', None, ('utf-16', u'a'.encode('ascii'))): - ('latin1', 0, u'a'), - # + @charset - ('latin1', None, ('utf-16', u'@charset "ascii";'.encode())): - ('latin1', 0, u'@charset "latin1";'), - ('latin1', None, ('utf-16', u'@charset "utf-8";ä'.encode('latin1'))): - ('latin1', 0, u'@charset "latin1";ä'), - ('latin1', None, ('utf-16', u'@charset "utf-8";ä'.encode('utf-8'))): - ('latin1', 0, u'@charset "latin1";\xc3\xa4'), # read as latin1! - - # override ü @charset - ('latin1', None, (None, u'@charset "ascii";'.encode())): - ('latin1', 0, u'@charset "latin1";'), - ('latin1', None, (None, u'@charset "utf-8";ä'.encode('latin1'))): - ('latin1', 0, u'@charset "latin1";ä'), - ('latin1', None, (None, u'@charset "utf-8";ä'.encode('utf-8'))): - ('latin1', 0, u'@charset "latin1";\xc3\xa4'), # read as latin1! - - - # ===== 1. HTTP WINS ===== - (None, 'ascii', ('latin1', u''.encode())): ('latin1', 1, u''), - (None, 'ascii', ('latin1', u'123'.encode())): ('latin1', 1, u'123'), - (None, 'ascii', ('latin1', u'ä'.encode('iso-8859-1'))): - ('latin1', 1, u'ä'), - (None, 'ascii', ('latin1', u'a'.encode('ascii'))): - ('latin1', 1, u'a'), - # + @charset - (None, 'ascii', ('latin1', u'@charset "ascii";'.encode())): - ('latin1', 1, u'@charset "latin1";'), - (None, 'ascii', ('latin1', u'@charset "utf-8";ä'.encode('latin1'))): - ('latin1', 1, u'@charset "latin1";ä'), - (None, 'ascii', ('latin1', u'@charset "utf-8";ä'.encode('utf-8'))): - ('latin1', 1, u'@charset "latin1";\xc3\xa4'), # read as latin1! - - - # ===== 2. @charset WINS ===== - (None, 'ascii', (None, u'@charset "latin1";'.encode())): - ('latin1', 2, u'@charset "latin1";'), - (None, 'ascii', (None, u'@charset "latin1";ä'.encode('latin1'))): - ('latin1', 2, u'@charset "latin1";ä'), - (None, 'ascii', (None, u'@charset "latin1";ä'.encode('utf-8'))): - ('latin1', 2, u'@charset "latin1";\xc3\xa4'), # read as latin1! - - # ===== 2. BOM WINS ===== - (None, 'ascii', (None, u'ä'.encode('utf-8-sig'))): - ('utf-8-sig', 2, u'\xe4'), # read as latin1! - (None, 'ascii', (None, u'@charset "utf-8";ä'.encode('utf-8-sig'))): - ('utf-8-sig', 2, u'@charset "utf-8";\xe4'), # read as latin1! - (None, 'ascii', (None, u'@charset "latin1";ä'.encode('utf-8-sig'))): - ('utf-8-sig', 2, u'@charset "utf-8";\xe4'), # read as latin1! - - - # ===== 4. parentEncoding WINS ===== - (None, 'latin1', (None, u''.encode())): ('latin1', 4, u''), - (None, 'latin1', (None, u'123'.encode())): ('latin1', 4, u'123'), - (None, 'latin1', (None, u'ä'.encode('iso-8859-1'))): - ('latin1', 4, u'ä'), - (None, 'latin1', (None, u'a'.encode('ascii'))): - ('latin1', 4, u'a'), - (None, 'latin1', (None, u'ä'.encode('utf-8'))): - ('latin1', 4, u'\xc3\xa4'), # read as latin1! - - # ===== 5. default WINS which in this case is None! ===== - (None, None, (None, u''.encode())): ('utf-8', 5, u''), - (None, None, (None, u'123'.encode())): ('utf-8', 5, u'123'), - (None, None, (None, u'a'.encode('ascii'))): - ('utf-8', 5, u'a'), - (None, None, (None, u'ä'.encode('utf-8'))): - ('utf-8', 5, u'ä'), # read as utf-8 - (None, None, (None, u'ä'.encode('iso-8859-1'))): # trigger UnicodeDecodeError! - ('utf-8', 5, None), - - - } - for (override, parent, r), exp in tests.items(): - self.assertEquals(_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', u'€'.encode('utf-8')): - (None, u'€'.encode('utf-8')), - ('text/css;charset=utf-8', u'€'.encode('utf-8')): - ('utf-8', u'€'.encode('utf-8')), - ('text/css;charset=ascii', 'a'): - ('ascii', 'a') - } - url = 'http://example.com/test.css' - for (contenttype, content), exp in 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': (urllib2.URLError, ['urlerror']), - # cannot resolve x, IOError - 'http://x': (urllib2.URLError, ['ioerror']), - } - for url, (exception, args) in 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': (urllib2.HTTPError, ['u', 500, 'server error', {}, None]), - 'e3': (urllib2.HTTPError, ['u', 404, 'not found', {}, None]), - } - for url, (exception, args) in 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, u'Mock needed for this test') - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_value.py cssutils-0.9.10/src/tests/test_value.py --- cssutils-0.9.10~b1/src/tests/test_value.py 2012-03-24 19:02:28.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_value.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,1073 +0,0 @@ -"""Testcases for cssutils.css.CSSValue and CSSPrimitiveValue.""" - -# from decimal import Decimal # maybe for later tests? -import xml.dom -import basetest -import cssutils -import types - - -class PropertyValueTestCase(basetest.BaseTestCase): - - def setUp(self): - self.r = cssutils.css.PropertyValue() - - def test_init(self): - "PropertyValue.__init__() .item() .length" - pv = cssutils.css.PropertyValue() - self.assertEqual(u'', pv.cssText) - self.assertEqual(0, pv.length) - self.assertEqual(u'', pv.value) - - cssText = u'0, 0/0 1px var(x) url(x)' - items = [u'0', u'0', u'0', u'1px', u'var(x)', 'url(x)'] - pv = cssutils.css.PropertyValue(cssText) - self.assertEqual(cssText, pv.cssText) - self.assertEqual(6, len(pv)) - self.assertEqual(6, pv.length) - - # __iter__ - for i, x in enumerate(pv): - self.assertEqual(x.cssText, items[i]) - - # cssText - for i, item in enumerate(items): - self.assertEqual(item, pv[i].cssText) - self.assertEqual(item, pv.item(i).cssText) - - def test_cssText(self): - "PropertyValue.cssText" - tests = { - u'0': (None, 1, None), - u'0 0': (None, 2, None), - u'0, 0': (None, 2, None), - u'0,0': (u'0, 0', 2, None), - u'0 , 0': (u'0, 0', 2, None), - u'0/0': (None, 2, None), - u'/**/ 0 /**/': (None, 1, u'0'), - u'0 /**/ 0 /**/ 0': (None, 3, u'0 0 0'), - u'0, /**/ 0, /**/ 0': (None, 3, u'0, 0, 0'), - u'0//**/ 0//**/ 0': (None, 3, u'0/0/0'), - u'/**/ red': (None, 1, u'red'), - u'/**/red': (u'/**/ red', 1, u'red'), - u'red /**/': (None, 1, u'red'), - u'red/**/': (u'red /**/', 1, u'red'), - - u'a()1,-1,+1,1%,-1%,1px,-1px,"a",a,url(a),#aabb44': ( - u'a() 1, -1, +1, 1%, -1%, 1px, -1px, "a", a, url(a), #ab4', - 12, u'a() 1, -1, +1, 1%, -1%, 1px, -1px, "a", a, url(a), #ab4') - } - for (cssText, (c, l, v)) in tests.items(): - if c is None: - c = cssText - if v is None: - v = c - - pv = cssutils.css.PropertyValue(cssText) - self.assertEqual(c, pv.cssText) - self.assertEqual(l, pv.length) - self.assertEqual(v, pv.value) - - tests = { - u'0 0px -0px +0px': (u'0 0 0 0', 4), - u'1 2 3 4': (None, 4), - u'-1 -2 -3 -4': (None, 4), - u'-1 2': (None, 2), - u'-1px red "x"': (None, 3), - u'a, b c': (None, 3), - u'1px1 2% 3': (u'1px1 2% 3', 3), - u'f(+1pX, -2, 5%) 1': (u'f(+1px, -2, 5%) 1', 2), - u'0 f()0': (u'0 f() 0', 3), - u'f()0': (u'f() 0', 2), - u'f()1%': (u'f() 1%', 2), - u'f()1px': (u'f() 1px', 2), - u'f()"str"': (u'f() "str"', 2), - u'f()ident': (u'f() ident', 2), - u'f()#123': (u'f() #123', 2), - u'f()url()': (u'f() url()', 2), - u'f()f()': (u'f() f()', 2), - u'url(x.gif)0 0': (u'url(x.gif) 0 0', 3), - u'url(x.gif)no-repeat': (u'url(x.gif) no-repeat', 2) - } - for (cssText, (c, l)) in tests.items(): - if c is None: - c = cssText - pv = cssutils.css.PropertyValue(cssText) - self.assertEqual(c, pv.cssText) - self.assertEqual(l, pv.length) - - tests = { - # hash and rgb/a - u'#112234': u'#112234', - u'#112233': u'#123', - u'rgb(1,2,3)': u'rgb(1, 2, 3)', - u'rgb( 1 , 2 , 3 )': u'rgb(1, 2, 3)', - u'rgba(1,2,3,4)': u'rgba(1, 2, 3, 4)', - u'rgba( 1 , 2 , 3 , 4 )': u'rgba(1, 2, 3, 4)', - u'rgb(-1,+2,0)': u'rgb(-1, +2, 0)', - u'rgba(-1,+2,0, 0)': u'rgba(-1, +2, 0, 0)', - - # FUNCTION - u'f(1,2)': u'f(1, 2)', - u'f( 1 , 2 )': u'f(1, 2)', - u'f(-1,+2)': u'f(-1, +2)', - u'f( -1 , +2 )': u'f(-1, +2)', - u'fun( -1 , +2 )': u'fun(-1, +2)', - u'local( x )': u'local(x)', - u'test(1px, #111, y, 1, 1%, "1", y(), var(x))': - u'test(1px, #111, y, 1, 1%, "1", y(), var(x))', - u'test(-1px, #111, y, -1, -1%, "1", -y())': - u'test(-1px, #111, y, -1, -1%, "1", -y())', - u'url(y) format( "x" , "y" )': u'url(y) format("x", "y")', - u'f(1 2,3 4)': u'f(1 2, 3 4)', - - # IE expression - ur'Expression()': u'Expression()', - ur'expression(-1 < +2)': u'expression(-1<+2)', - ur'expression(document.width == "1")': u'expression(document.width=="1")', - u'alpha(opacity=80)': u'alpha(opacity=80)', - u'alpha( opacity = 80 , x=2 )': u'alpha(opacity=80, x=2)', - u'expression(eval(document.documentElement.scrollTop))': - u'expression(eval(document.documentElement.scrollTop))', - #TODO -# u'expression((function(ele){ele.style.behavior="none";})(this))': -# u'expression((function(ele){ele.style.behavior="none";})(this))', - - # unicode-range - 'u+f': 'u+f', - 'U+ABCdef': 'u+abcdef', - - # url - 'url(a)': 'url(a)', - 'uRl(a)': 'url(a)', - 'u\\rl(a)': 'url(a)', - 'url("a")': 'url(a)', - 'url( "a" )': 'url(a)', - 'url(a)': 'url(a)', - 'url(";")': 'url(";")', - 'url(",")': 'url(",")', - 'url(")")': 'url(")")', - '''url("'")''': '''url("'")''', - '''url('"')''': '''url("\\"")''', - '''url("'")''': '''url("'")''', - - # operator - '1': '1', - '1 2': '1 2', - '1 2': '1 2', - '1,2': '1, 2', - '1, 2': '1, 2', - '1 ,2': '1, 2', - '1 , 2': '1, 2', - '1/2': '1/2', - '1/ 2': '1/2', - '1 /2': '1/2', - '1 / 2': '1/2', - # comment - '1/**/2': '1 /**/ 2', - '1 /**/2': '1 /**/ 2', - '1/**/ 2': '1 /**/ 2', - '1 /**/ 2': '1 /**/ 2', - '1 /*a*/ /*b*/ 2': '1 /*a*/ /*b*/ 2', - # , before - '1,/**/2': '1, /**/ 2', - '1 ,/**/2': '1, /**/ 2', - '1, /**/2': '1, /**/ 2', - '1 , /**/2': '1, /**/ 2', - # , after - '1/**/,2': '1 /**/, 2', - '1/**/ ,2': '1 /**/, 2', - '1/**/, 2': '1 /**/, 2', - '1/**/ , 2': '1 /**/, 2', - # all - '1/*a*/ ,/*b*/ 2': '1 /*a*/, /*b*/ 2', - '1 /*a*/, /*b*/2': '1 /*a*/, /*b*/ 2', - '1 /*a*/ , /*b*/ 2': '1 /*a*/, /*b*/ 2', - - # list - 'a b1,b2 b2,b3,b4': 'a b1, b2 b2, b3, b4', - 'a b1 , b2 b2 , b3 , b4': 'a b1, b2 b2, b3, b4', - 'u+1 , u+2-5': 'u+1, u+2-5', - u'local( x ), url(y) format( "x" , "y" )': - u'local(x), url(y) format("x", "y")', - # FUNCTION - u'attr( href )': u'attr(href)', - # PrinceXML extende FUNC syntax with nested FUNC - u'target-counter(attr(href),page)': u'target-counter(attr(href), page)' - } - self.do_equal_r(tests) - - tests = { u'a+': xml.dom.SyntaxErr, - u'-': xml.dom.SyntaxErr, - u'+': xml.dom.SyntaxErr, - u'-%': xml.dom.SyntaxErr, - u'+a': xml.dom.SyntaxErr, - u'--1px': xml.dom.SyntaxErr, - u'++1px': xml.dom.SyntaxErr, - u'#': xml.dom.SyntaxErr, - u'#00': xml.dom.SyntaxErr, - u'#0000': xml.dom.SyntaxErr, - u'#00000': xml.dom.SyntaxErr, - u'#0000000': xml.dom.SyntaxErr, - u'-#0': xml.dom.SyntaxErr, - # operator - u',': xml.dom.SyntaxErr, - u'1,,2': xml.dom.SyntaxErr, - u'1,/**/,2': xml.dom.SyntaxErr, - u'1 , /**/ , 2': xml.dom.SyntaxErr, - u'1,': xml.dom.SyntaxErr, - u'1, ': xml.dom.SyntaxErr, - u'1 ,': xml.dom.SyntaxErr, - u'1 , ': xml.dom.SyntaxErr, - u'1 , ': xml.dom.SyntaxErr, - u'1//2': xml.dom.SyntaxErr, - # URL - u'url(x))': xml.dom.SyntaxErr, - # string - u'"': xml.dom.SyntaxErr, - u"'": xml.dom.SyntaxErr, - # function - u'f(-)': xml.dom.SyntaxErr, - u'f(x))': xml.dom.SyntaxErr - } - self.do_raise_r(tests) - - def test_list(self): - "PropertyValue[index]" - # issue #41 - css = """div.one {color: rgb(255, 0, 0);} """ - sheet = cssutils.parseString(css) - pv = sheet.cssRules[0].style.getProperty('color').propertyValue - self.assertEqual(pv.value, 'rgb(255, 0, 0)') - self.assertEqual(pv[0].value, 'rgb(255, 0, 0)') - - # issue #42 - sheet = cssutils.parseString('body { font-family: "A", b, serif }') - pv = sheet.cssRules[0].style.getProperty('font-family').propertyValue - self.assertEqual(3, pv.length) - self.assertEqual(pv[0].value, 'A') - self.assertEqual(pv[1].value, 'b') - self.assertEqual(pv[2].value, 'serif') - - def test_comments(self): - "PropertyValue with comment" - # issue #45 - for t in (u'green', - u'green /* comment */', - u'/* comment */green', - u'/* comment */green/* comment */', - u'/* comment */ green /* comment */', - u'/* comment *//**/ green /* comment *//**/', - ): - sheet = cssutils.parseString('body {color: %s; }' % t) - p = sheet.cssRules[0].style.getProperties()[0] - self.assertEqual(p.valid, True) - for t in (u'gree', - u'gree /* comment */', - u'/* comment */gree', - u'/* comment */gree/* comment */', - u'/* comment */ gree /* comment */', - u'/* comment *//**/ gree /* comment *//**/', - ): - sheet = cssutils.parseString('body {color: %s; }' % t) - p = sheet.cssRules[0].style.getProperties()[0] - self.assertEqual(p.valid, False) - - def test_incomplete(self): - "PropertyValue (incomplete)" - tests = { - u'url("a': u'url(a)', - u'url(a': u'url(a)' - } - for v, exp in tests.items(): - s = cssutils.parseString('a { background: %s' % v) - v = s.cssRules[0].style.background - self.assertEqual(v, exp) - - def test_readonly(self): - "PropertyValue._readonly" - v = cssutils.css.PropertyValue(cssText='inherit') - self.assert_(False is v._readonly) - - v = cssutils.css.PropertyValue(cssText='inherit', readonly=True) - self.assert_(True is v._readonly) - self.assert_(u'inherit', v.cssText) - self.assertRaises(xml.dom.NoModificationAllowedErr, v._setCssText, u'x') - self.assert_(u'inherit', v.cssText) - - def test_reprANDstr(self): - "PropertyValue.__repr__(), .__str__()" - cssText='inherit' - - s = cssutils.css.PropertyValue(cssText=cssText) - - self.assert_(cssText in str(s)) - - s2 = eval(repr(s)) - self.assert_(isinstance(s2, s.__class__)) - self.assert_(cssText == s2.cssText) - - -class ValueTestCase(basetest.BaseTestCase): - - def test_init(self): - "Value.__init__()" - v = cssutils.css.Value() - self.assert_(u'' == v.cssText) - self.assert_(u'' == v.value) - self.assert_(None is v.type) - - def test_cssText(self): - "Value.cssText" - # HASH IDENT STRING UNICODE-RANGE - tests = { - u'#123': (u'#123', u'#123', u'HASH'), - u'#123456': (u'#123456', u'#123456', u'HASH'), - u'#112233': (u'#123', u'#112233', u'HASH'), - u' #112233 ': (u'#123', u'#112233', u'HASH'), - - u'red': (u'red', u'red', u'IDENT'), - u' red ': (u'red', u'red', u'IDENT'), - u'red ': (u'red', u'red', u'IDENT'), - u' red': (u'red', u'red', u'IDENT'), - u'red-': (u'red-', u'red-', u'IDENT'), - u'-red': (u'-red', u'-red', u'IDENT'), - - u'"red"': (u'"red"', u'red', u'STRING'), - u"'red'": (u'"red"', u'red', u'STRING'), - u' "red" ': (u'"red"', u'red', u'STRING'), - ur'"red\""': (ur'"red\""', ur'red"', u'STRING'), - ur"'x\"'": (ur'"x\\""', ur'x\"', 'STRING'), #??? - u'''"x\ -y"''': (u'"xy"', u'xy', u'STRING'), - } - for (p, (r, n, t)) in tests.items(): - v = cssutils.css.Value(p) - self.assertEqual(r, v.cssText) - self.assertEqual(t, v.type) - self.assertEqual(n, v.value) - - -class ColorValueTestCase(basetest.BaseTestCase): - - def test_init(self): - "ColorValue.__init__()" - v = cssutils.css.ColorValue() - self.assertEqual(v.COLOR_VALUE, v.type) - self.assert_(u'' == v.cssText) - self.assert_(u'' == v.value) - self.assertEqual(u'transparent', v.name) - self.assertEqual(None, v.colorType) - - def test_cssText(self): - "ColorValue.cssText" - tests = { - # HASH - u'#123': (u'#123',), - u'#112233': (u'#123',), - # rgb - u'rgb(1,2,3)': (u'rgb(1, 2, 3)',), - u'rgb(1%,2%,3%)': (u'rgb(1%, 2%, 3%)',), - u'rgb(-1,-1,-1)': (u'rgb(-1, -1, -1)',), - u'rgb(-1%,-2%,-3%)': (u'rgb(-1%, -2%, -3%)',), - # rgba - u'rgba(1,2,3, 0)': (u'rgba(1, 2, 3, 0)',), - # hsl - u'hsl(1,2%,3%)': (u'hsl(1, 2%, 3%)',), - u'hsla(1,2%,3%, 1.0)': (u'hsla(1, 2%, 3%, 1)',), - - } - for (p, (r, )) in tests.items(): - v = cssutils.css.ColorValue(p) - self.assertEqual(v.COLOR_VALUE, v.type) - self.assertEqual(r, v.cssText) - self.assertEqual(r, v.value) - - v = cssutils.css.ColorValue() - v.cssText = p - self.assertEqual(v.COLOR_VALUE, v.type) - self.assertEqual(r, v.cssText) - self.assertEqual(r, v.value) - - tests = { - u'1': xml.dom.SyntaxErr, - u'a': xml.dom.SyntaxErr, - - u'#12': xml.dom.SyntaxErr, - u'#1234': xml.dom.SyntaxErr, - u'#1234567': xml.dom.SyntaxErr, - u'#12345678': xml.dom.SyntaxErr, - - u'rgb(1,1%,1%)': xml.dom.SyntaxErr, - u'rgb(1%,1,1)': xml.dom.SyntaxErr, - u'rgb(-1,-1%,-1%)': xml.dom.SyntaxErr, - u'rgb(-1%,-1,-1)': xml.dom.SyntaxErr, - - u'rgb(1,1,1, 0)': xml.dom.SyntaxErr, - u'rgb(1%,1%,1%, 0)': xml.dom.SyntaxErr, - u'rgba(1,1,1)': xml.dom.SyntaxErr, - u'rgba(1%,1%,1%)': xml.dom.SyntaxErr, - u'rgba(1,1,1, 0%)': xml.dom.SyntaxErr, - u'rgba(1%,1%,1%, 0%)': xml.dom.SyntaxErr, - - u'hsl(1,2%,3%, 1)': xml.dom.SyntaxErr, - u'hsla(1,2%,3%)': xml.dom.SyntaxErr, - - u'hsl(1,2,3)': xml.dom.SyntaxErr, - u'hsl(1%,2,3)': xml.dom.SyntaxErr, - u'hsl(1%,2,3%)': xml.dom.SyntaxErr, - u'hsl(1%,2%,3)': xml.dom.SyntaxErr, - - u'hsla(1,2%,3%, 0%)': xml.dom.SyntaxErr, - u'hsla(1,2,3, 0.0)': xml.dom.SyntaxErr, - u'hsla(1%,2,3, 0.0)': xml.dom.SyntaxErr, - u'hsla(1%,2,3%, 0.0)': xml.dom.SyntaxErr, - u'hsla(1%,2%,3, 0.0)': xml.dom.SyntaxErr, - } - self.r = cssutils.css.ColorValue() - self.do_raise_r(tests) - - def test_rgb(self): - "ColorValue.red .green .blue" - tests = { - (u'#0A0AD2', 'rgb(10, 10, 210)' ): (10, 10, 210, 1.0), - # TODO: Fix rounding? - (u'hsl(240, 91%, 43%)', ): (10, 10, 209, 1.0), - (u'#ff8800', u'#f80', - 'rgb(255, 136, 0)', 'rgba(255, 136, 0, 1.0)'): (255, 136, 0, 1.0), - (u'red', u'#ff0000', u'#f00', - u'hsl(0, 100%, 50%)', u'hsla(0, 100%, 50%, 1.0)'): - (255, 0, 0, 1.0), - (u'lime', u'#00ff00', u'#0f0', u'hsl(120, 100%, 50%)'): - (0, 255, 0, 1.0), - (u'rgba(255, 127, 0, .1)', u'rgba(100%, 50%, 0%, .1)'): - (255, 127, 0, 0.1), - (u'transparent', u'rgba(0, 0, 0, 0)'): (0, 0, 0, 0), - (u'aqua',): (0, 255, 255, 1.0) - } - for colors, rgba in tests.items(): - for color in colors: - c = cssutils.css.ColorValue(color); - self.assertEquals(c.red, rgba[0]) - self.assertEquals(c.green, rgba[1]) - self.assertEquals(c.blue, rgba[2]) - self.assertEquals(c.alpha, rgba[3]) - - -class URIValueTestCase(basetest.BaseTestCase): - - def test_init(self): - "URIValue.__init__()" - v = cssutils.css.URIValue() - self.assert_(u'url()' == v.cssText) - self.assert_(u'' == v.value) - self.assert_(u'' == v.uri) - self.assert_(v.URI is v.type) - - v.uri = '1' - self.assert_(u'1' == v.value) - self.assert_(u'1' == v.uri) - self.assertEqual(u'url(1)', v.cssText) - - v.value = '2' - self.assert_(u'2' == v.value) - self.assert_(u'2' == v.uri) - self.assertEqual(u'url(2)', v.cssText) - - def test_absoluteUri(self): - "URIValue.absoluteUri" - s = cssutils.parseString('a { background-image: url(x.gif)}', href="/path/to/x.css") - v = s.cssRules[0].style.getProperty('background-image').propertyValue[0] - self.assertEqual(u'x.gif', v.uri) - self.assertEqual(u'/path/to/x.gif', v.absoluteUri) - - v = cssutils.css.URIValue(u'url(x.gif)') - self.assertEqual(u'x.gif', v.uri) - self.assertEqual(u'x.gif', v.absoluteUri) - - def test_cssText(self): - "URIValue.cssText" - tests = { - u'url()': (u'url()', u'', u'URI'), - # comments are part of the url! - u'url(/**/)': (u'url(/**/)', u'/**/', u'URI'), - u'url(/**/1)': (u'url(/**/1)', u'/**/1', u'URI'), - u'url(1/**/)': (u'url(1/**/)', u'1/**/', u'URI'), - u'url(/**/1/**/)': (u'url(/**/1/**/)', u'/**/1/**/', u'URI'), - u'url(some.gif)': (u'url(some.gif)', u'some.gif', u'URI'), - u' url(some.gif) ': (u'url(some.gif)', u'some.gif', u'URI'), - u'url( some.gif )': (u'url(some.gif)', u'some.gif', u'URI'), - } - for (p, (r, n, t)) in tests.items(): - v = cssutils.css.URIValue(p) - self.assertEqual(r, v.cssText) - self.assertEqual(t, v.type) - self.assertEqual(n, v.value) - self.assertEqual(n, v.uri) - - v = cssutils.css.URIValue() - v.cssText = p - self.assertEqual(r, v.cssText) - self.assertEqual(t, v.type) - self.assertEqual(n, v.value) - self.assertEqual(n, v.uri) - - tests = { - u'a()': xml.dom.SyntaxErr, - u'1': xml.dom.SyntaxErr, - u'url(': xml.dom.SyntaxErr, - u'url("': xml.dom.SyntaxErr, - u'url(\'': xml.dom.SyntaxErr, - } - self.r = cssutils.css.URIValue() - self.do_raise_r(tests) - -class DimensionValueTestCase(basetest.BaseTestCase): - - def test_init(self): - "DimensionValue.__init__()" - v = cssutils.css.DimensionValue() - self.assert_(u'' == v.cssText) - self.assert_(u'' == v.value) - self.assert_(None is v.type) - self.assert_(None is v.dimension) - - def test_cssText(self): - "DimensionValue.cssText" - # NUMBER DIMENSION PERCENTAGE - tests = { - - u'0': (u'0', 0, None, u'NUMBER'), - u'00': (u'0', 0, None, u'NUMBER'), - u'.0': (u'0', 0, None, u'NUMBER'), - u'0.0': (u'0', 0, None, u'NUMBER'), - u'+0': (u'0', 0, None, u'NUMBER'), - u'+00': (u'0', 0, None, u'NUMBER'), - u'+.0': (u'0', 0, None, u'NUMBER'), - u'+0.0': (u'0', 0, None, u'NUMBER'), - u'-0': (u'0', 0, None, u'NUMBER'), - u'-00': (u'0', 0, None, u'NUMBER'), - u'-.0': (u'0', 0, None, u'NUMBER'), - u'-0.0': (u'0', 0, None, u'NUMBER'), - - u'1': (u'1', 1, None, u'NUMBER'), - u'1.0': (u'1', 1.0, None, u'NUMBER'), - u'1.1': (u'1.1', 1.1, None, u'NUMBER'), - u'+1': (u'+1', 1, None, u'NUMBER'), - u'+1.0': (u'+1', 1.0, None, u'NUMBER'), - u'+1.1': (u'+1.1', 1.1, None, u'NUMBER'), - u'-1': (u'-1', -1, None, u'NUMBER'), - u'-1.0': (u'-1', -1, None, u'NUMBER'), - u'-1.1': (u'-1.1', -1.1, None, u'NUMBER'), - - u'0px': (u'0', 0, u'px', u'DIMENSION'), - u'1px': (u'1px', 1, u'px', u'DIMENSION'), - u'1.0px': (u'1px', 1.0, u'px', u'DIMENSION'), - u'1.1px': (u'1.1px', 1.1, u'px', u'DIMENSION'), - u'-1px': (u'-1px', -1, u'px', u'DIMENSION'), - u'-1.1px': (u'-1.1px', -1.1, u'px', u'DIMENSION'), - u'+1px': (u'+1px', 1, u'px', u'DIMENSION'), - - u'1px1': (u'1px1', 1, u'px1', u'DIMENSION'), - - u'0%': (u'0%', 0, u'%', u'PERCENTAGE'), - u'1%': (u'1%', 1, u'%', u'PERCENTAGE'), - u'1.1%': (u'1.1%', 1.1, u'%', u'PERCENTAGE'), - u'-1%': (u'-1%', -1, u'%', u'PERCENTAGE'), - u'-1.1%': (u'-1.1%', -1.1, u'%', u'PERCENTAGE'), - u'+1%': (u'+1%', 1, u'%', u'PERCENTAGE'), - } - for (p, (r, n, d, t)) in tests.items(): - v = cssutils.css.DimensionValue(p) - self.assertEqual(r, v.cssText) - self.assertEqual(t, v.type) - self.assertEqual(n, v.value) - self.assertEqual(d, v.dimension) - - -class CSSFunctionTestCase(basetest.BaseTestCase): - - def test_init(self): - "CSSFunction.__init__()" - v = cssutils.css.CSSFunction() - self.assertEqual(u'', v.cssText) - self.assertEqual(u'FUNCTION', v.type) - self.assertEqual(v.value, u'') - - def test_cssText(self): - "CSSFunction.cssText" - tests = { - u'x(x)': (u'x(x)', None), - u'X( X )': (u'x(X)', None), - u'x(1,2)': (u'x(1, 2)', None), - u'x(1/**/)': (u'x(1 /**/)', u'x(1)'), - u'x(/**/1)': (u'x(/**/ 1)', u'x(1)'), - u'x(/**/1/**/)': (u'x(/**/ 1 /**/)', u'x(1)'), - u'x(/**/1,x/**/)': (u'x(/**/ 1, x /**/)', u'x(1, x)'), - u'x(1,2)': (u'x(1, 2)', None), - } - for (f, (cssText, value)) in tests.items(): - if value is None: - value = cssText - v = cssutils.css.CSSFunction(f) - self.assertEqual(cssText, v.cssText) - self.assertEqual('FUNCTION', v.type) - self.assertEqual(value, v.value) - - -class CSSVariableTestCase(basetest.BaseTestCase): - - def test_init(self): - "CSSVariable.__init__()" - v = cssutils.css.CSSVariable() - self.assertEqual(u'', v.cssText) - self.assertEqual(u'VARIABLE', v.type) - self.assert_(None is v.name) - self.assert_(None is v.value) - - def test_cssText(self): - "CSSVariable.cssText" - tests = { - u'var(x)': (u'var(x)', 'x'), - u'VAR( X )': (u'var(X)', 'X') - } - for (var, (cssText, name)) in tests.items(): - v = cssutils.css.CSSVariable(var) - self.assertEqual(cssText, v.cssText) - self.assertEqual('VARIABLE', v.type) - self.assertEqual(name, v.name) - # not resolved so it is None - self.assertEqual(None, v.value) - - - -# def test_cssValueType(self): -# "CSSValue.cssValueType .cssValueTypeString" -# tests = [ -# ([u'inherit', u'INhe\\rit'], 'CSS_INHERIT', cssutils.css.CSSValue), -# (['1', '1%', '1em', '1ex', '1px', '1cm', '1mm', '1in', '1pt', '1pc', -# '1deg', '1rad', '1grad', '1ms', '1s', '1hz', '1khz', '1other', -# '"string"', "'string'", 'url(x)', 'red', -# 'attr(a)', 'counter(x)', 'rect(1px, 2px, 3px, 4px)', -# 'rgb(0, 0, 0)', '#000', '#123456', 'rgba(0, 0, 0, 0)', -# 'hsl(0, 0, 0)', 'hsla(0, 0, 0, 0)', -# ], -# 'CSS_PRIMITIVE_VALUE', cssutils.css.CSSPrimitiveValue), -# ([u'1px 1px', 'red blue green x'], 'CSS_VALUE_LIST', cssutils.css.CSSValueList), -# # what is a custom value? -# #([], 'CSS_CUSTOM', cssutils.css.CSSValue) -# ] -# for values, name, cls in tests: -# for value in values: -# v = cssutils.css.CSSValue(cssText=value) -# if value == "'string'": -# # will be changed to " always -# value = '"string"' -# self.assertEqual(value, v.cssText) -# self.assertEqual(name, v.cssValueTypeString) -# self.assertEqual(getattr(v, name), v.cssValueType) -# self.assertEqual(cls, type(v)) - - -#class CSSPrimitiveValueTestCase(basetest.BaseTestCase): -# -# def test_init(self): -# "CSSPrimitiveValue.__init__()" -# v = cssutils.css.CSSPrimitiveValue(u'1') -# self.assert_(u'1' == v.cssText) -# -# self.assert_(v.CSS_PRIMITIVE_VALUE == v.cssValueType) -# self.assert_("CSS_PRIMITIVE_VALUE" == v.cssValueTypeString) -# -# self.assert_(v.CSS_NUMBER == v.primitiveType) -# self.assert_("CSS_NUMBER" == v.primitiveTypeString) -# -# # DUMMY to be able to test empty constructor call -# #self.assertRaises(xml.dom.SyntaxErr, v.__init__, None) -# -# self.assertRaises(xml.dom.InvalidAccessErr, v.getCounterValue) -# self.assertRaises(xml.dom.InvalidAccessErr, v.getRGBColorValue) -# self.assertRaises(xml.dom.InvalidAccessErr, v.getRectValue) -# self.assertRaises(xml.dom.InvalidAccessErr, v.getStringValue) -# -# def test_CSS_UNKNOWN(self): -# "CSSPrimitiveValue.CSS_UNKNOWN" -# v = cssutils.css.CSSPrimitiveValue(u'expression(false)') -# self.assert_(v.CSS_UNKNOWN == v.primitiveType) -# self.assert_('CSS_UNKNOWN' == v.primitiveTypeString) -# -# def test_CSS_NUMBER_AND_OTHER_DIMENSIONS(self): -# "CSSPrimitiveValue.CSS_NUMBER .. CSS_DIMENSION" -# defs = [ -# ('', 'CSS_NUMBER'), -# ('%', 'CSS_PERCENTAGE'), -# ('em', 'CSS_EMS'), -# ('ex', 'CSS_EXS'), -# ('px', 'CSS_PX'), -# ('cm', 'CSS_CM'), -# ('mm', 'CSS_MM'), -# ('in', 'CSS_IN'), -# ('pt', 'CSS_PT'), -# ('pc', 'CSS_PC'), -# ('deg', 'CSS_DEG'), -# ('rad', 'CSS_RAD'), -# ('grad', 'CSS_GRAD'), -# ('ms', 'CSS_MS'), -# ('s', 'CSS_S'), -# ('hz', 'CSS_HZ'), -# ('khz', 'CSS_KHZ'), -# ('other_dimension', 'CSS_DIMENSION') -# ] -# for dim, name in defs: -# for n in (0, 1, 1.1, -1, -1.1, -0): -# v = cssutils.css.CSSPrimitiveValue('%i%s' % (n, dim)) -# self.assertEqual(name, v.primitiveTypeString) -# self.assertEqual(getattr(v, name), v.primitiveType) -# -# def test_CSS_STRING_AND_OTHER(self): -# "CSSPrimitiveValue.CSS_STRING .. CSS_RGBCOLOR" -# defs = [ -# (('""', "''", '"some thing"', "' A\\ND '", -# # comma separated lists are STRINGS FOR NOW! -# 'a, b', -# '"a", "b"', -# ), 'CSS_STRING'), -# (('url(a)', 'url("a b")', "url(' ')"), 'CSS_URI'), -# (('some', 'or_anth-er'), 'CSS_IDENT'), -# (('attr(a)', 'attr(b)'), 'CSS_ATTR'), -# (('counter(1)', 'counter(2)'), 'CSS_COUNTER'), -# (('rect(1,2,3,4)',), 'CSS_RECT'), -# (('rgb(1,2,3)', 'rgb(10%, 20%, 30%)', '#123', '#123456'), -# 'CSS_RGBCOLOR'), -# (('rgba(1,2,3,4)','rgba(10%, 20%, 30%, 40%)', ), -# 'CSS_RGBACOLOR'), -# (('U+0', 'u+ffffff', 'u+000000-f', -# 'u+0-f, U+ee-ff'), 'CSS_UNICODE_RANGE') -# ] -# -# for examples, name in defs: -# for x in examples: -# v = cssutils.css.CSSPrimitiveValue(x) -# self.assertEqual(getattr(v, name), v.primitiveType) -# self.assertEqual(name, v.primitiveTypeString) -# -# def test_getFloat(self): -# "CSSPrimitiveValue.getFloatValue()" -# # NOT TESTED are float values as it seems difficult to -# # compare these. Maybe use decimal.Decimal? -# -# v = cssutils.css.CSSPrimitiveValue(u'1px') -# tests = { -# '0': (v.CSS_NUMBER, 0), -# '-1.1': (v.CSS_NUMBER, -1.1), -# '1%': (v.CSS_PERCENTAGE, 1), -# '-1%': (v.CSS_PERCENTAGE, -1), -# '1em': (v.CSS_EMS, 1), -# '-1.1em': (v.CSS_EMS, -1.1), -# '1ex': (v.CSS_EXS, 1), -# '1px': (v.CSS_PX, 1), -# -# '1cm': (v.CSS_CM, 1), -# '1cm': (v.CSS_MM, 10), -# '254cm': (v.CSS_IN, 100), -# '1mm': (v.CSS_MM, 1), -# '10mm': (v.CSS_CM, 1), -# '254mm': (v.CSS_IN, 10), -# '1in': (v.CSS_IN, 1), -# '100in': (v.CSS_CM, 254), # ROUNDED!!! -# '10in': (v.CSS_MM, 254), # ROUNDED!!! -# -# '1pt': (v.CSS_PT, 1), -# '1pc': (v.CSS_PC, 1), -# -# '1deg': (v.CSS_DEG, 1), -# '1rad': (v.CSS_RAD, 1), -# '1grad': (v.CSS_GRAD, 1), -# -# '1ms': (v.CSS_MS, 1), -# '1000ms': (v.CSS_S, 1), -# '1s': (v.CSS_S, 1), -# '1s': (v.CSS_MS, 1000), -# -# '1hz': (v.CSS_HZ, 1), -# '1000hz': (v.CSS_KHZ, 1), -# '1khz': (v.CSS_KHZ, 1), -# '1khz': (v.CSS_HZ, 1000), -# -# '1DIMENSION': (v.CSS_DIMENSION, 1), -# } -# for cssText in tests: -# v.cssText = cssText -# unitType, exp = tests[cssText] -# val = v.getFloatValue(unitType) -# if unitType in (v.CSS_IN, v.CSS_CM): -# val = round(val) -# self.assertEqual(val , exp) -# -# def test_setFloat(self): -# "CSSPrimitiveValue.setFloatValue()" -# V = cssutils.css.CSSPrimitiveValue -# -# tests = { -# # unitType, value -# (V.CSS_NUMBER, 1): [ -# # unitType, setvalue, -# # getvalue or expected exception, msg or cssText -# (V.CSS_NUMBER, 0, 0, '0'), -# (V.CSS_NUMBER, 0.1, 0.1, '0.1'), -# (V.CSS_NUMBER, -0, 0, '0'), -# (V.CSS_NUMBER, 2, 2, '2'), -# (V.CSS_NUMBER, 2.0, 2, '2'), -# (V.CSS_NUMBER, 2.1, 2.1, '2.1'), -# (V.CSS_NUMBER, -2.1, -2.1, '-2.1'), -# # setting with string does work -# (V.CSS_NUMBER, '1', 1, '1'), -# (V.CSS_NUMBER, '1.1', 1.1, '1.1'), -# (V.CSS_PX, 1, xml.dom.InvalidAccessErr, None), -# (V.CSS_DEG, 1, xml.dom.InvalidAccessErr, None), -# (V.CSS_RAD, 1, xml.dom.InvalidAccessErr, None), -# (V.CSS_GRAD, 1, xml.dom.InvalidAccessErr, None), -# (V.CSS_S, 1, xml.dom.InvalidAccessErr, None), -# (V.CSS_MS, 1, xml.dom.InvalidAccessErr, None), -# (V.CSS_KHZ, 1, xml.dom.InvalidAccessErr, None), -# (V.CSS_HZ, 1, xml.dom.InvalidAccessErr, None), -# (V.CSS_DIMENSION, 1, xml.dom.InvalidAccessErr, None), -# (V.CSS_MM, 2, xml.dom.InvalidAccessErr, None), -# -# (V.CSS_NUMBER, 'x', xml.dom.InvalidAccessErr, -# "CSSPrimitiveValue: floatValue 'x' is not a float"), -# (V.CSS_NUMBER, '1x', xml.dom.InvalidAccessErr, -# "CSSPrimitiveValue: floatValue '1x' is not a float"), -# -# (V.CSS_STRING, 'x', xml.dom.InvalidAccessErr, -# "CSSPrimitiveValue: unitType 'CSS_STRING' is not a float type"), -# (V.CSS_URI, 'x', xml.dom.InvalidAccessErr, -# "CSSPrimitiveValue: unitType 'CSS_URI' is not a float type"), -# (V.CSS_ATTR, 'x', xml.dom.InvalidAccessErr, -# "CSSPrimitiveValue: unitType 'CSS_ATTR' is not a float type"), -# (V.CSS_IDENT, 'x', xml.dom.InvalidAccessErr, -# "CSSPrimitiveValue: unitType 'CSS_IDENT' is not a float type"), -# (V.CSS_RGBCOLOR, 'x', xml.dom.InvalidAccessErr, -# "CSSPrimitiveValue: unitType 'CSS_RGBCOLOR' is not a float type"), -# (V.CSS_RGBACOLOR, 'x', xml.dom.InvalidAccessErr, -# "CSSPrimitiveValue: unitType 'CSS_RGBACOLOR' is not a float type"), -# (V.CSS_RECT, 'x', xml.dom.InvalidAccessErr, -# "CSSPrimitiveValue: unitType 'CSS_RECT' is not a float type"), -# (V.CSS_COUNTER, 'x', xml.dom.InvalidAccessErr, -# "CSSPrimitiveValue: unitType 'CSS_COUNTER' is not a float type"), -# (V.CSS_EMS, 1, xml.dom.InvalidAccessErr, -# "CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_NUMBER' to 'CSS_EMS'"), -# (V.CSS_EXS, 1, xml.dom.InvalidAccessErr, -# "CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_NUMBER' to 'CSS_EXS'") -# ], -# (V.CSS_MM, '1mm'): [ -# (V.CSS_MM, 2, 2, '2mm'), -# (V.CSS_MM, 0, 0, '0mm'), -# (V.CSS_MM, 0.1, 0.1, '0.1mm'), -# (V.CSS_MM, -0, -0, '0mm'), -# (V.CSS_MM, 3.0, 3, '3mm'), -# (V.CSS_MM, 3.1, 3.1, '3.1mm'), -# (V.CSS_MM, -3.1, -3.1, '-3.1mm'), -# (V.CSS_CM, 1, 10, '10mm'), -# (V.CSS_IN, 10, 254, '254mm'), -# (V.CSS_PT, 1, 1828.8, '1828.8mm'), -# (V.CSS_PX, 1, xml.dom.InvalidAccessErr, None), -# (V.CSS_NUMBER, 2, xml.dom.InvalidAccessErr, None) -# ], -# (V.CSS_PT, '1pt'): [ -# (V.CSS_PT, 2, 2, '2pt'), -# (V.CSS_PC, 12, 1, '1pt'), -# (V.CSS_NUMBER, 1, xml.dom.InvalidAccessErr, None), -# (V.CSS_DEG, 1, xml.dom.InvalidAccessErr, None), -# (V.CSS_PX, 1, xml.dom.InvalidAccessErr, None) -# ], -# (V.CSS_KHZ, '1khz'): [ -# (V.CSS_HZ, 2000, 2, '2khz'), -# (V.CSS_NUMBER, 1, xml.dom.InvalidAccessErr, None), -# (V.CSS_DEG, 1, xml.dom.InvalidAccessErr, None), -# (V.CSS_PX, 1, xml.dom.InvalidAccessErr, None) -# ] -# } -# for test in tests: -# initialType, initialValue = test -# pv = cssutils.css.CSSPrimitiveValue(initialValue) -# for setType, setValue, exp, cssText in tests[test]: -# if type(exp) == types.TypeType or\ -# type(exp) == types.ClassType: # 2.4 compatibility -# if cssText: -# self.assertRaisesMsg( -# exp, cssText, pv.setFloatValue, setType, setValue) -# else: -# self.assertRaises( -# exp, pv.setFloatValue, setType, setValue) -# else: -# pv.setFloatValue(setType, setValue) -# self.assertEqual(pv._value[0], cssText) -# if cssText == '0mm': -# cssText = '0' -# self.assertEqual(pv.cssText, cssText) -# self.assertEqual(pv.getFloatValue(initialType), exp) -# -# def test_getString(self): -# "CSSPrimitiveValue.getStringValue()" -# v = cssutils.css.CSSPrimitiveValue(u'1px') -# self.assert_(v.primitiveType == v.CSS_PX) -# self.assertRaises(xml.dom.InvalidAccessErr, -# v.getStringValue) -# -# pv = cssutils.css.CSSPrimitiveValue -# tests = { -# pv.CSS_STRING: ("'red'", 'red'), -# pv.CSS_STRING: ('"red"', 'red'), -# pv.CSS_URI: ('url(http://example.com)', None), -# pv.CSS_URI: ("url('http://example.com')", -# u"http://example.com"), -# pv.CSS_URI: ('url("http://example.com")', -# u'http://example.com'), -# pv.CSS_URI: ('url("http://example.com?)")', -# u'http://example.com?)'), -# pv.CSS_IDENT: ('red', None), -# pv.CSS_ATTR: ('attr(att-name)', -# u'att-name'), # the name of the attrr -# } -# for t in tests: -# val, exp = tests[t] -# if not exp: -# exp = val -# -# v = cssutils.css.CSSPrimitiveValue(val) -# self.assertEqual(v.primitiveType, t) -# self.assertEqual(v.getStringValue(), exp) -# -# def test_setString(self): -# "CSSPrimitiveValue.setStringValue()" -# # CSS_STRING -# v = cssutils.css.CSSPrimitiveValue(u'"a"') -# self.assert_(v.CSS_STRING == v.primitiveType) -# v.setStringValue(v.CSS_STRING, 'b') -# self.assert_(('b', 'STRING') == v._value) -# self.assertEqual('b', v.getStringValue()) -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_STRING' to 'CSS_URI'", -# v.setStringValue, *(v.CSS_URI, 'x')) -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_STRING' to 'CSS_IDENT'", -# v.setStringValue, *(v.CSS_IDENT, 'x')) -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_STRING' to 'CSS_ATTR'", -# v.setStringValue, *(v.CSS_ATTR, 'x')) -# -# # CSS_IDENT -# v = cssutils.css.CSSPrimitiveValue('new') -# v.setStringValue(v.CSS_IDENT, 'ident') -# self.assert_(v.CSS_IDENT == v.primitiveType) -# self.assert_(('ident', 'IDENT') == v._value) -# self.assert_('ident' == v.getStringValue()) -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_IDENT' to 'CSS_URI'", -# v.setStringValue, *(v.CSS_URI, 'x')) -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_IDENT' to 'CSS_STRING'", -# v.setStringValue, *(v.CSS_STRING, '"x"')) -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_IDENT' to 'CSS_ATTR'", -# v.setStringValue, *(v.CSS_ATTR, 'x')) -# -# # CSS_URI -# v = cssutils.css.CSSPrimitiveValue('url(old)') -# v.setStringValue(v.CSS_URI, '(') -# self.assertEqual((u'(', 'URI'), v._value) -# self.assertEqual(u'(', v.getStringValue()) -# -# v.setStringValue(v.CSS_URI, ')') -# self.assertEqual((u')', 'URI'), v._value) -# self.assertEqual(u')', v.getStringValue()) -# -# v.setStringValue(v.CSS_URI, '"') -# self.assertEqual(ur'"', v.getStringValue()) -# self.assertEqual((ur'"', 'URI'), v._value) -# -# v.setStringValue(v.CSS_URI, "''") -# self.assertEqual(ur"''", v.getStringValue()) -# self.assertEqual((ur"''", 'URI'), v._value) -# -# v.setStringValue(v.CSS_URI, ',') -# self.assertEqual(ur',', v.getStringValue()) -# self.assertEqual((ur',', 'URI'), v._value) -# -# v.setStringValue(v.CSS_URI, ' ') -# self.assertEqual((u' ', 'URI'), v._value) -# self.assertEqual(u' ', v.getStringValue()) -# -# v.setStringValue(v.CSS_URI, 'a)') -# self.assertEqual((u'a)', 'URI'), v._value) -# self.assertEqual(u'a)', v.getStringValue()) -# -# v.setStringValue(v.CSS_URI, 'a') -# self.assert_(v.CSS_URI == v.primitiveType) -# self.assertEqual((u'a', 'URI'), v._value) -# self.assertEqual(u'a', v.getStringValue()) -# -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_URI' to 'CSS_IDENT'", -# v.setStringValue, *(v.CSS_IDENT, 'x')) -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_URI' to 'CSS_STRING'", -# v.setStringValue, *(v.CSS_STRING, '"x"')) -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_URI' to 'CSS_ATTR'", -# v.setStringValue, *(v.CSS_ATTR, 'x')) -# -# # CSS_ATTR -# v = cssutils.css.CSSPrimitiveValue('attr(old)') -# v.setStringValue(v.CSS_ATTR, 'a') -# self.assert_(v.CSS_ATTR == v.primitiveType) -# self.assert_('a' == v.getStringValue()) -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_ATTR' to 'CSS_IDENT'", -# v.setStringValue, *(v.CSS_IDENT, 'x')) -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_ATTR' to 'CSS_STRING'", -# v.setStringValue, *(v.CSS_STRING, '"x"')) -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: Cannot coerce primitiveType 'CSS_ATTR' to 'CSS_URI'", -# v.setStringValue, *(v.CSS_URI, 'x')) -# -# # TypeError as 'x' is no valid type -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: stringType 'x' (UNKNOWN TYPE) is not a string type", -# v.setStringValue, *('x', 'brown')) -# # IndexError as 111 is no valid type -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: stringType 111 (UNKNOWN TYPE) is not a string type", -# v.setStringValue, *(111, 'brown')) -# # CSS_PX is no string type -# self.assertRaisesMsg(xml.dom.InvalidAccessErr, -# u"CSSPrimitiveValue: stringType CSS_PX is not a string type", -# v.setStringValue, *(v.CSS_PX, 'brown')) -# -# def test_typeRGBColor(self): -# "RGBColor" -# v = cssutils.css.CSSPrimitiveValue('RGB(1, 5, 10)') -# self.assertEqual(v.CSS_RGBCOLOR, v.primitiveType) -# self.assertEqual(u'rgb(1, 5, 10)', v.cssText) -# -# v = cssutils.css.CSSPrimitiveValue('rgb(1, 5, 10)') -# self.assertEqual(v.CSS_RGBCOLOR, v.primitiveType) -# self.assertEqual(u'rgb(1, 5, 10)', v.cssText) -# -# v = cssutils.css.CSSPrimitiveValue('rgb(1%, 5%, 10%)') -# self.assertEqual(v.CSS_RGBCOLOR, v.primitiveType) -# self.assertEqual(u'rgb(1%, 5%, 10%)', v.cssText) -# -# v = cssutils.css.CSSPrimitiveValue(' rgb( 1 ,5, 10 )') -# self.assertEqual(v.CSS_RGBCOLOR, v.primitiveType) -# v = cssutils.css.CSSPrimitiveValue('rgb(1,5,10)') -# self.assertEqual(v.CSS_RGBCOLOR, v.primitiveType) -# v = cssutils.css.CSSPrimitiveValue('rgb(1%, .5%, 10.1%)') -# self.assertEqual(v.CSS_RGBCOLOR, v.primitiveType) - - -if __name__ == '__main__': - import unittest - unittest.main() diff -Nru cssutils-0.9.10~b1/src/tests/test_x.py cssutils-0.9.10/src/tests/test_x.py --- cssutils-0.9.10~b1/src/tests/test_x.py 2011-12-24 23:26:54.000000000 +0000 +++ cssutils-0.9.10/src/tests/test_x.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,54 +0,0 @@ -"""Testcases for cssutils.css.CSSValue and CSSPrimitiveValue.""" -__version__ = '$Id: test_cssvalue.py 1473 2008-09-15 21:15:54Z cthedot $' - -# from decimal import Decimal # maybe for later tests? -import xml.dom -import basetest -import cssutils -import types - -class XTestCase(basetest.BaseTestCase): - - def setUp(self): - cssutils.ser.prefs.useDefaults() - - def tearDown(self): - cssutils.ser.prefs.useDefaults() - - def test_prioriy(self): - "Property.priority" - s = cssutils.parseString(u'a { color: red }') - self.assertEqual(s.cssText, u'a {\n color: red\n }'.encode()) -# self.assertEqual(u'', s.cssRules[0].style.getPropertyPriority('color')) -# -# s = cssutils.parseString('a { color: red !important }') -# self.assertEqual(u'a {\n color: red !important\n }', s.cssText) -# self.assertEqual(u'important', s.cssRules[0].style.getPropertyPriority('color')) -# -# cssutils.log.raiseExceptions = True -# p = cssutils.css.Property(u'color', u'red', u'') -# self.assertEqual(p.priority, u'') -# p = cssutils.css.Property(u'color', u'red', u'!important') -# self.assertEqual(p.priority, u'important') -# self.assertRaisesMsg(xml.dom.SyntaxErr, -# u'', -# cssutils.css.Property, u'color', u'red', u'x') -# -# cssutils.log.raiseExceptions = False -# p = cssutils.css.Property(u'color', u'red', u'!x') -# self.assertEqual(p.priority, u'x') -# p = cssutils.css.Property(u'color', u'red', u'!x') -# self.assertEqual(p.priority, u'x') -# cssutils.log.raiseExceptions = True -# -# -# # invalid but kept! -## #cssutils.log.raiseExceptions = False -## s = cssutils.parseString('a { color: red !x }') -## self.assertEqual(u'a {\n color: red !x\n }', s.cssText) -## self.assertEqual(u'x', s.cssRules[0].style.getPropertyPriority('color')) -# - -if __name__ == '__main__': - import unittest - unittest.main()