Package cssutils :: Package tests :: Module test_cssstylesheet |
[hide private]
[frames] | no frames]

# Source Code for Module cssutils.tests.test_cssstylesheet

      1  # -*- coding: utf-8 -*-
      2  """
      3  tests for css.CSSStyleSheet
      4  """
      5  __author__ = '$LastChangedBy: cthedot $'
      6  __date__ = '$LastChangedDate: 2007-11-24 23:35:04 +0100 (Sa, 24 Nov 2007) $'
      7  __version__ = '$LastChangedRevision: 684 $'
      8
      9  import xml.dom
     10  import basetest
     11  import cssutils.css
     12
     13 -class CSSStyleSheetTestCase(basetest.BaseTestCase):
     14
     15 -    def setUp(self):
     16          super(CSSStyleSheetTestCase, self).setUp()
     17          self.r = cssutils.css.CSSStyleSheet() # used by basetest
     18          self.s = self.r # used here
     19          self.rule = cssutils.css.CSSStyleRule()
     20
     21 -    def test_init(self):
     22          "CSSStyleSheet.__init__()"
     23          self.assertEqual(False, self.s._readonly)
     24          self.assertEqual([], self.s.cssRules)
     25          self.assertEqual('text/css', self.s.type)
     26          self.assertEqual(False, self.s.disabled)
     27          self.assertEqual(None, self.s.href)
     28          self.assertEqual(None, self.s.media)
     29          self.assertEqual(None, self.s.ownerNode)
     30          self.assertEqual(None, self.s.parentStyleSheet)
     31          self.assertEqual(u'', self.s.title)
     32
     33 -    def test_NoModificationAllowedErr(self):
     34          "CSSStyleSheet NoModificationAllowedErr"
     35          css = cssutils.css.CSSStyleSheet(readonly=True)
     36
     37          self.assertEqual(True, css._readonly) # internal...
     38
     39          self.assertRaises(xml.dom.NoModificationAllowedErr,
     40                            css._setCssText, u'@x;')
     41          self.assertRaises(xml.dom.NoModificationAllowedErr,
     42                            css.insertRule, self.rule)
     43          self.assertRaises(xml.dom.NoModificationAllowedErr,
     44                            css.insertRule, self.rule, 0)
     45          self.assertRaises(xml.dom.NoModificationAllowedErr,
     46                            css.deleteRule, 0)
     47
     48 -    def test_cssText_HierarchyRequestErr(self):
     49          "CSSStyleSheet.cssText HierarchyRequestErr"
     50          tests = {
     51              # @charset: only one and always 1st
     52              u' @charset "utf-8";': xml.dom.HierarchyRequestErr,
     53              u'@charset "ascii";@charset "ascii";': xml.dom.HierarchyRequestErr,            u'/*c*/@charset "ascii";': xml.dom.HierarchyRequestErr,
     54              u'@import "x"; @charset "ascii";': xml.dom.HierarchyRequestErr,
     55              u'@namespace a "x"; @charset "ascii";': xml.dom.HierarchyRequestErr,
     56              u'@media all {} @charset "ascii";': xml.dom.HierarchyRequestErr,
     57              u'@page {} @charset "ascii";': xml.dom.HierarchyRequestErr,
     58              u'a {} @charset "ascii";': xml.dom.HierarchyRequestErr,
     59
     60              # @import: before @namespace, @media, @page, sr
     61              u'@namespace a "x"; @import "x";': xml.dom.HierarchyRequestErr,
     62              u'@media all {} @import "x";': xml.dom.HierarchyRequestErr,
     63              u'@page {} @import "x";': xml.dom.HierarchyRequestErr,
     64              u'a {} @import "x";': xml.dom.HierarchyRequestErr,
     65
     66              # @namespace: before @media, @page, sr
     67              u'@media all {} @namespace a "x";': xml.dom.HierarchyRequestErr,
     68              u'@page {} @namespace a "x";': xml.dom.HierarchyRequestErr,
     69              u'a {} @namespace a "x";': xml.dom.HierarchyRequestErr,
     70              }
     71          self.do_raise_r(tests)
     72          self.do_raise_p(tests)
     73
     74 -    def test_cssText_SyntaxErr(self):
     75          """CSSStyleSheet.cssText SyntaxErr
     76
     77          for single {, } or ;
     78          """
     79          tests = {
     80              u'{': xml.dom.SyntaxErr,
     81              u'}': xml.dom.SyntaxErr,
     82              u';': xml.dom.SyntaxErr,
     83              u'@charset "ascii";{': xml.dom.SyntaxErr,
     84              u'@charset "ascii";}': xml.dom.SyntaxErr,
     85              u'@charset "ascii";;': xml.dom.SyntaxErr,
     86              }
     87          self.do_raise_r(tests)
     88          self.do_raise_p(tests)
     89
     90 -    def test_incomplete(self):
     91          "CSSStyleRule (incomplete)"
     92          tests = {
     93              u'@import "a': u'@import "a";', # no }
     94              u'a { x: 1': u'a {\n    x: 1\n    }', # no }
     95              u'a { font-family: "arial sans': # no "
     96                  u'a {\n    font-family: "arial sans"\n    }',
     97          }
     98          self.do_equal_p(tests) # parse
     99
    100 -    def test_cssText(self):
    101          "CSSStyleSheet.cssText"
    102          tests = {
    103              u'': None,
    104              # @charset
    105              u'@charset "ascii";\n@import "x";': None,
    106              u'@charset "ascii";\n@media all {}': u'@charset "ascii";',
    107              u'@charset "ascii";\n@x;': None,
    108              u'@charset "ascii";\na {\n    x: 1\n    }': None,
    109              # @import
    110              u'@x;\n@import "x";': None,
    111              u'@import "x";\n@import "y";': None,
    112              u'@import "x";\n@media all {}': u'@import "x";',
    113              u'@import "x";\n@x;': None,
    114              u'@import "x";\na {\n    x: 1\n    }': None,
    115              # @namespace
    116              u'@x;\n@namespace a "x";': None,
    117              u'@namespace a "x";\n@namespace b "y";': None,
    118              u'@import "x";\n@namespace a "x";\n@media all {}': u'@import "x";\n@namespace a "x";',
    119              u'@namespace a "x";\n@x;': None,
    120              u'@namespace a "x";\na {\n    x: 1\n    }': None,
    121  #            ur'\1 { \2: \3 }': ur'''\1 {
    122  #    \2: \3
    123  #    }''',
    124  #            ur'''
    125  #            \@ { \@: \@ }
    126  #            \1 { \2: \3 }
    127  #            \{{\::\;;}
    128  #            ''': ur'''\@ {
    129  #    \@: \@
    130  #    }
    131  #\1 {
    132  #    \2: \3
    133  #    }
    134  #\{
    135  #    {\:: \;
    136  #    }'''
    137              }
    138          self.do_equal_r(tests)
    139          self.do_equal_p(tests)
    140
    141          s = cssutils.css.CSSStyleSheet()
    142          s.cssText = u'''@charset "ascii";@import "x";@namespace a "x";
    143          @media all {/*1*/}@page {margin: 0}a {\n    x: 1\n    }@unknown;/*comment*/'''
    144          for r in s.cssRules:
    145              self.assertEqual(s, r.parentStyleSheet)
    146
    147 -    def test_HTMLComments(self):
    148          "CSSStyleSheet CDO CDC"
    149          css = u'''body { color: red }
    150  <!-- comment -->
    151  body { color: blue }
    152  body { color: pink }
    153  <!-- comment -->
    154  body { color: green }
    155  '''
    156          exp = u'''body {
    157      color: red
    158      }
    159  body {
    160      color: pink
    161      }'''
    162          sheet = cssutils.parseString(css)
    163          self.assertEqual(sheet.cssText, exp)
    164
    165 -    def test_encoding(self):
    166          "CSSStyleSheet.encoding"
    167          self.s.cssText=''
    168          self.assertEqual('utf-8', self.s.encoding)
    169
    170          self.s.encoding = 'ascii'
    171          self.assertEqual('ascii', self.s.encoding)
    172          self.assertEqual(1, self.s.cssRules.length)
    173          self.assertEqual('ascii', self.s.cssRules[0].encoding)
    174
    175          self.s.encoding = None
    176          self.assertEqual('utf-8', self.s.encoding)
    177          self.assertEqual(0, self.s.cssRules.length)
    178
    179          self.s.encoding = 'UTF-8'
    180          self.assertEqual('utf-8', self.s.encoding)
    181          self.assertEqual(1, self.s.cssRules.length)
    182
    183          self.assertRaises(xml.dom.SyntaxErr, self.s._setEncoding,
    184                            'INVALID ENCODING')
    185          self.assertEqual('utf-8', self.s.encoding)
    186          self.assertEqual(1, self.s.cssRules.length)
    187
    188 -    def test_deleteRule(self):
    189          "CSSStyleSheet.deleteRule()"
    190          self.s.cssText = u'@charset "ascii"; @import "x"; @x; a {\n    x: 1\n    }@y;'
    191          self.assertEqual(5, self.s.cssRules.length)
    192
    193          self.assertRaises(xml.dom.IndexSizeErr, self.s.deleteRule, 5)
    194
    195          # end -1
    196          # check parentStyleSheet
    197          r = self.s.cssRules[-1]
    198          self.assertEqual(self.s, r.parentStyleSheet)
    199          self.s.deleteRule(-1)
    200          self.assertEqual(None, r.parentStyleSheet)
    201
    202          self.assertEqual(4, self.s.cssRules.length)
    203          self.assertEqual(
    204              u'@charset "ascii";\n@import "x";\n@x;\na {\n    x: 1\n    }', self.s.cssText)
    205          # beginning
    206          self.s.deleteRule(0)
    207          self.assertEqual(3, self.s.cssRules.length)
    208          self.assertEqual(u'@import "x";\n@x;\na {\n    x: 1\n    }', self.s.cssText)
    209          # middle
    210          self.s.deleteRule(1)
    211          self.assertEqual(2, self.s.cssRules.length)
    212          self.assertEqual(u'@import "x";\na {\n    x: 1\n    }', self.s.cssText)
    213          # end
    214          self.s.deleteRule(1)
    215          self.assertEqual(1, self.s.cssRules.length)
    216          self.assertEqual(u'@import "x";', self.s.cssText)
    217
    218 -    def _gets(self):
    219          # complete
    220          self.cr = cssutils.css.CSSCharsetRule('ascii')
    221          self.c = cssutils.css.CSSComment(u'/*c*/')
    222          self.ur = cssutils.css.CSSUnknownRule('@x;')
    223          self.ir = cssutils.css.CSSImportRule('x')
    224          self.nr = cssutils.css.CSSNamespaceRule('uri')
    225          self.mr = cssutils.css.CSSMediaRule()
    226          self.mr.cssText = u'@media all { @m; }'
    227          self.pr = cssutils.css.CSSPageRule()
    228          self.pr.style = u'margin: 0;'
    229          self.sr = cssutils.css.CSSStyleRule()
    230          self.sr.cssText = 'a {\n    x: 1\n    }'
    231
    232          s = cssutils.css.CSSStyleSheet()
    233          s.insertRule(self.cr) # 0
    234          s.insertRule(self.ir) # 1
    235          s.insertRule(self.nr) # 2
    236          s.insertRule(self.mr) # 3
    237          s.insertRule(self.sr) # 4
    238          s.insertRule(self.mr) # 5
    239          s.insertRule(self.pr) # 6
    240          s.insertRule(self.sr) # 7
    241          self.assertEqual(u'@charset "ascii";\n@import url(x);\n@namespace "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    }', s.cssText)
    242          return s, s.cssRules.length
    243
    244 -    def test_insertRule(self):
    245          "CSSStyleSheet.insertRule()"
    246          s, L = self._gets()
    247
    248          # INVALID index
    249          self.assertRaises(xml.dom.IndexSizeErr,
    250                    s.insertRule, self.sr, -1)
    251          self.assertRaises(xml.dom.IndexSizeErr,
    252                    s.insertRule, self.sr, s.cssRules.length + 1)
    253          #   check if rule is really not in
    254          self.assertEqual(L, s.cssRules.length)
    255
    256 -    def _insertRule(self, rules, notbefore, notafter, anywhere):
    257          """
    258          helper
    259          test if any rule in rules cannot be inserted before rules in before
    260          or after rules in after but before and after rules in anywhere
    261          """
    262          for rule in rules:
    263              for r in notbefore:
    264                  s = cssutils.css.CSSStyleSheet()
    265                  s.insertRule(r)
    266                  self.assertRaises(xml.dom.HierarchyRequestErr,
    267                                    s.insertRule, rule, 0)
    268              for r in notafter:
    269                  s = cssutils.css.CSSStyleSheet()
    270                  s.insertRule(r)
    271                  self.assertRaises(xml.dom.HierarchyRequestErr,
    272                                    s.insertRule, rule, 1)
    273              for r in anywhere:
    274                  s = cssutils.css.CSSStyleSheet()
    275                  s.insertRule(r)
    276                  s.insertRule(rule, 0) # before
    277                  s.insertRule(rule) # after
    278                  self.assertEqual(s.cssRules.length, 3)
    279                  self.assertEqual(s, r.parentStyleSheet)
    280
    281 -    def test_insertRule_charset(self):
    282          "CSSStyleSheet.insertRule(@charset)"
    283          s, L = self._gets()
    284          notbefore = (self.cr,)
    285          notafter = (self.cr, self.ir, self.nr, self.mr, self.pr, self.sr,
    286                      self.c, self.ur)
    287          anywhere = ()
    288          self._insertRule((self.cr,),
    289                           notbefore, notafter, anywhere)
    290
    291 -    def test_insertRule_import(self):
    292          "CSSStyleSheet.insertRule(@import)"
    293          s, L = self._gets()
    294          notbefore = (self.cr,)
    295          notafter = (self.nr, self.pr, self.mr, self.sr)
    296          anywhere = (self.c, self.ur, self.ir)
    297          self._insertRule((self.ir,),
    298                           notbefore, notafter, anywhere)
    299
    300 -    def test_insertRule_namespace(self):
    301          "CSSStyleSheet.insertRule(@namespace)"
    302          s, L = self._gets()
    303          notbefore = (self.cr, self.ir)
    304          notafter = (self.pr, self.mr, self.sr)
    305          anywhere = (self.c, self.ur, self.nr)
    306          self._insertRule((self.nr,), notbefore, notafter, anywhere)
    307
    308 -    def test_insertRule_media_page_style(self):
    309          "CSSStyleSheet.insertRule(@media, @page, stylerule)"
    310          s, L = self._gets()
    311          notbefore = (self.cr, self.ir, self.nr)
    312          notafter = ()
    313          anywhere = (self.c, self.ur, self.mr, self.pr, self.sr)
    314          self._insertRule((self.pr, self.mr, self.sr),
    315                           notbefore, notafter, anywhere)
    316
    317 -    def test_insertRule_unknownandcomment(self):
    318          "CSSStyleSheet.insertRule(@ unknown, comment)"
    319          s, L = self._gets()
    320          notbefore = (self.cr,)
    321          notafter = ()
    322          anywhere = (self.c, self.ur, self.ir, self.nr, self.mr, self.pr,
    323                      self.sr)
    324          self._insertRule((self.ur,),
    325                           notbefore, notafter, anywhere)
    326
    327 -    def test_replaceUrls(self):
    328          cssutils.ser.prefs.keepAllProperties = True
    329
    330          css='''
    331          @import "im1";
    332          @import url(im2);
    333          a {
    334              background-image: url(c) !important;
    335              background-\image: url(b);
    336              background: url(a) no-repeat !important;
    337              }'''
    338          s = cssutils.parseString(css)
    339          s.replaceUrls(lambda old: "NEW" + old)
    340          self.assertEqual(u'@import "NEWim1";', s.cssRules[0].cssText)
    341          self.assertEqual(u'NEWim2', s.cssRules[1].href)
    342          self.assertEqual(u'''background-image: url(NEWc) !important;
    343  background-\\image: url(NEWb);
    344  background: url(NEWa) no-repeat !important''', s.cssRules[2].style.cssText)
    345
    346          cssutils.ser.prefs.keepAllProperties = False
    347
    348 -    def test_reprANDstr(self):
    349          "CSSStyleSheet.__repr__(), .__str__()"
    350          href = 'file:foo.css'
    351          title = 'title-of-css'
    352
    353          s = cssutils.css.CSSStyleSheet(href=href, title=title)
    354
    355          self.assert_(href in str(s))
    356          self.assert_(title in str(s))
    357
    358          s2 = eval(repr(s))
    359          self.assert_(isinstance(s2, s.__class__))
    360          self.assert_(href == s2.href)
    361          self.assert_(title == s2.title)
    362
    363
    364  if __name__ == '__main__':
    365      import unittest
    366      unittest.main()
    367