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: 2008-01-12 21:28:54 +0100 (Sa, 12 Jan 2008) $'
      7  __version__ = '$LastChangedRevision: 831 $'
      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          # insert string
    257          s.insertRule('a {}')
    258          self.assertEqual(L+1, s.cssRules.length)
    259          # insert rule
    260          s.insertRule(self.sr)
    261          self.assertEqual(L+2, s.cssRules.length)
    262          # insert rulelist
    263          s2, L2 = self._gets()
    264          rulelist = s2.cssRules
    265          del rulelist[:-2]
    266          s.insertRule(rulelist)
    267          self.assertEqual(L+2 + 2, s.cssRules.length)
    268
    269 -    def _insertRule(self, rules, notbefore, notafter, anywhere):
    270          """
    271          helper
    272          test if any rule in rules cannot be inserted before rules in before
    273          or after rules in after but before and after rules in anywhere
    274          """
    275          for rule in rules:
    276              for r in notbefore:
    277                  s = cssutils.css.CSSStyleSheet()
    278                  s.insertRule(r)
    279                  self.assertRaises(xml.dom.HierarchyRequestErr,
    280                                    s.insertRule, rule, 0)
    281              for r in notafter:
    282                  s = cssutils.css.CSSStyleSheet()
    283                  s.insertRule(r)
    284                  self.assertRaises(xml.dom.HierarchyRequestErr,
    285                                    s.insertRule, rule, 1)
    286              for r in anywhere:
    287                  s = cssutils.css.CSSStyleSheet()
    288                  s.insertRule(r)
    289                  s.insertRule(rule, 0) # before
    290                  s.insertRule(rule) # after
    291                  self.assertEqual(s.cssRules.length, 3)
    292                  self.assertEqual(s, r.parentStyleSheet)
    293
    294 -    def test_insertRule_charset(self):
    295          "CSSStyleSheet.insertRule(@charset)"
    296          s, L = self._gets()
    297          notbefore = (self.cr,)
    298          notafter = (self.cr, self.ir, self.nr, self.mr, self.pr, self.sr,
    299                      self.c, self.ur)
    300          anywhere = ()
    301          self._insertRule((self.cr,),
    302                           notbefore, notafter, anywhere)
    303
    304 -    def test_insertRule_import(self):
    305          "CSSStyleSheet.insertRule(@import)"
    306          s, L = self._gets()
    307          notbefore = (self.cr,)
    308          notafter = (self.nr, self.pr, self.mr, self.sr)
    309          anywhere = (self.c, self.ur, self.ir)
    310          self._insertRule((self.ir,),
    311                           notbefore, notafter, anywhere)
    312
    313 -    def test_insertRule_namespace(self):
    314          "CSSStyleSheet.insertRule(@namespace)"
    315          s, L = self._gets()
    316          notbefore = (self.cr, self.ir)
    317          notafter = (self.pr, self.mr, self.sr)
    318          anywhere = (self.c, self.ur, self.nr)
    319          self._insertRule((self.nr,), notbefore, notafter, anywhere)
    320
    321 -    def test_insertRule_media_page_style(self):
    322          "CSSStyleSheet.insertRule(@media, @page, stylerule)"
    323          s, L = self._gets()
    324          notbefore = (self.cr, self.ir, self.nr)
    325          notafter = ()
    326          anywhere = (self.c, self.ur, self.mr, self.pr, self.sr)
    327          self._insertRule((self.pr, self.mr, self.sr),
    328                           notbefore, notafter, anywhere)
    329
    330 -    def test_insertRule_unknownandcomment(self):
    331          "CSSStyleSheet.insertRule(@ unknown, comment)"
    332          s, L = self._gets()
    333          notbefore = (self.cr,)
    334          notafter = ()
    335          anywhere = (self.c, self.ur, self.ir, self.nr, self.mr, self.pr,
    336                      self.sr)
    337          self._insertRule((self.ur,),
    338                           notbefore, notafter, anywhere)
    339
    340 -    def test_replaceUrls(self):
    341          "CSSStyleSheet.replaceUrls()"
    342          cssutils.ser.prefs.keepAllProperties = True
    343
    344          css='''
    345          @import "im1";
    346          @import url(im2);
    347          a {
    348              background-image: url(c) !important;
    349              background-\image: url(b);
    350              background: url(a) no-repeat !important;
    351              }'''
    352          s = cssutils.parseString(css)
    353          s.replaceUrls(lambda old: "NEW" + old)
    354          self.assertEqual(u'@import "NEWim1";', s.cssRules[0].cssText)
    355          self.assertEqual(u'NEWim2', s.cssRules[1].href)
    356          self.assertEqual(u'''background-image: url(NEWc) !important;
    357  background-\\image: url(NEWb);
    358  background: url(NEWa) no-repeat !important''', s.cssRules[2].style.cssText)
    359
    360          cssutils.ser.prefs.keepAllProperties = False
    361
    362 -    def test_reprANDstr(self):
    363          "CSSStyleSheet.__repr__(), .__str__()"
    364          href = 'file:foo.css'
    365          title = 'title-of-css'
    366
    367          s = cssutils.css.CSSStyleSheet(href=href, title=title)
    368
    369          self.assert_(href in str(s))
    370          self.assert_(title in str(s))
    371
    372          s2 = eval(repr(s))
    373          self.assert_(isinstance(s2, s.__class__))
    374          self.assert_(href == s2.href)
    375          self.assert_(title == s2.title)
    376
    377
    378  if __name__ == '__main__':
    379      import unittest
    380      unittest.main()
    381