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-01 22:39:48 +0100 (Do, 01 Nov 2007) $'
      7  __version__ = '$LastChangedRevision: 621 $'
      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_deleteRule(self):
    166          "CSSStyleSheet.deleteRule()"
    167          self.s.cssText = u'@charset "ascii"; @import "x"; @x; a {\n    x: 1\n    }@y;'
    168          self.assertEqual(5, self.s.cssRules.length)
    169
    170          self.assertRaises(xml.dom.IndexSizeErr, self.s.deleteRule, 5)
    171
    172          # end -1
    173          # check parentStyleSheet
    174          r = self.s.cssRules[-1]
    175          self.assertEqual(self.s, r.parentStyleSheet)
    176          self.s.deleteRule(-1)
    177          self.assertEqual(None, r.parentStyleSheet)
    178
    179          self.assertEqual(4, self.s.cssRules.length)
    180          self.assertEqual(
    181              u'@charset "ascii";\n@import "x";\n@x;\na {\n    x: 1\n    }', self.s.cssText)
    182          # beginning
    183          self.s.deleteRule(0)
    184          self.assertEqual(3, self.s.cssRules.length)
    185          self.assertEqual(u'@import "x";\n@x;\na {\n    x: 1\n    }', self.s.cssText)
    186          # middle
    187          self.s.deleteRule(1)
    188          self.assertEqual(2, self.s.cssRules.length)
    189          self.assertEqual(u'@import "x";\na {\n    x: 1\n    }', self.s.cssText)
    190          # end
    191          self.s.deleteRule(1)
    192          self.assertEqual(1, self.s.cssRules.length)
    193          self.assertEqual(u'@import "x";', self.s.cssText)
    194
    195 -    def _gets(self):
    196          # complete
    197          self.cr = cssutils.css.CSSCharsetRule('ascii')
    198          self.c = cssutils.css.CSSComment(u'/*c*/')
    199          self.ur = cssutils.css.CSSUnknownRule('@x;')
    200          self.ir = cssutils.css.CSSImportRule('x')
    201          self.nr = cssutils.css.CSSNamespaceRule('uri')
    202          self.mr = cssutils.css.CSSMediaRule()
    203          self.mr.cssText = u'@media all { @m; }'
    204          self.pr = cssutils.css.CSSPageRule()
    205          self.pr.style = u'margin: 0;'
    206          self.sr = cssutils.css.CSSStyleRule()
    207          self.sr.cssText = 'a {\n    x: 1\n    }'
    208
    209          s = cssutils.css.CSSStyleSheet()
    210          s.insertRule(self.cr) # 0
    211          s.insertRule(self.ir) # 1
    212          s.insertRule(self.nr) # 2
    213          s.insertRule(self.mr) # 3
    214          s.insertRule(self.sr) # 4
    215          s.insertRule(self.mr) # 5
    216          s.insertRule(self.pr) # 6
    217          s.insertRule(self.sr) # 7
    218          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)
    219          return s, s.cssRules.length
    220
    221 -    def test_insertRule(self):
    222          "CSSStyleSheet.insertRule()"
    223          s, L = self._gets()
    224
    225          # INVALID index
    226          self.assertRaises(xml.dom.IndexSizeErr,
    227                    s.insertRule, self.sr, -1)
    228          self.assertRaises(xml.dom.IndexSizeErr,
    229                    s.insertRule, self.sr, s.cssRules.length + 1)
    230          #   check if rule is really not in
    231          self.assertEqual(L, s.cssRules.length)
    232
    233 -    def _insertRule(self, rules, notbefore, notafter, anywhere):
    234          """
    235          helper
    236          test if any rule in rules cannot be inserted before rules in before
    237          or after rules in after but before and after rules in anywhere
    238          """
    239          for rule in rules:
    240              for r in notbefore:
    241                  s = cssutils.css.CSSStyleSheet()
    242                  s.insertRule(r)
    243                  self.assertRaises(xml.dom.HierarchyRequestErr,
    244                                    s.insertRule, rule, 0)
    245              for r in notafter:
    246                  s = cssutils.css.CSSStyleSheet()
    247                  s.insertRule(r)
    248                  self.assertRaises(xml.dom.HierarchyRequestErr,
    249                                    s.insertRule, rule, 1)
    250              for r in anywhere:
    251                  s = cssutils.css.CSSStyleSheet()
    252                  s.insertRule(r)
    253                  s.insertRule(rule, 0) # before
    254                  s.insertRule(rule) # after
    255                  self.assertEqual(s.cssRules.length, 3)
    256                  self.assertEqual(s, r.parentStyleSheet)
    257
    258 -    def test_insertRule_charset(self):
    259          "CSSStyleSheet.insertRule(@charset)"
    260          s, L = self._gets()
    261          notbefore = (self.cr,)
    262          notafter = (self.cr, self.ir, self.nr, self.mr, self.pr, self.sr,
    263                      self.c, self.ur)
    264          anywhere = ()
    265          self._insertRule((self.cr,),
    266                           notbefore, notafter, anywhere)
    267
    268 -    def test_insertRule_import(self):
    269          "CSSStyleSheet.insertRule(@import)"
    270          s, L = self._gets()
    271          notbefore = (self.cr,)
    272          notafter = (self.nr, self.pr, self.mr, self.sr)
    273          anywhere = (self.c, self.ur, self.ir)
    274          self._insertRule((self.ir,),
    275                           notbefore, notafter, anywhere)
    276
    277 -    def test_insertRule_namespace(self):
    278          "CSSStyleSheet.insertRule(@namespace)"
    279          s, L = self._gets()
    280          notbefore = (self.cr, self.ir)
    281          notafter = (self.pr, self.mr, self.sr)
    282          anywhere = (self.c, self.ur, self.nr)
    283          self._insertRule((self.nr,), notbefore, notafter, anywhere)
    284
    285 -    def test_insertRule_media_page_style(self):
    286          "CSSStyleSheet.insertRule(@media, @page, stylerule)"
    287          s, L = self._gets()
    288          notbefore = (self.cr, self.ir, self.nr)
    289          notafter = ()
    290          anywhere = (self.c, self.ur, self.mr, self.pr, self.sr)
    291          self._insertRule((self.pr, self.mr, self.sr),
    292                           notbefore, notafter, anywhere)
    293
    294 -    def test_insertRule_unknownandcomment(self):
    295          "CSSStyleSheet.insertRule(@ unknown, comment)"
    296          s, L = self._gets()
    297          notbefore = (self.cr,)
    298          notafter = ()
    299          anywhere = (self.c, self.ur, self.ir, self.nr, self.mr, self.pr,
    300                      self.sr)
    301          self._insertRule((self.ur,),
    302                           notbefore, notafter, anywhere)
    303
    304 -    def test_replaceUrls(self):
    305          cssutils.ser.prefs.keepAllProperties = True
    306
    307          css='''
    308          @import "im1";
    309          @import url(im2);
    310          a {
    311              background-image: url(c) !important;
    312              background-\image: url(b);
    313              background: url(a) no-repeat !important;
    314              }'''
    315          s = cssutils.parseString(css)
    316          s.replaceUrls(lambda old: "NEW" + old)
    317          self.assertEqual(u'@import "NEWim1";', s.cssRules[0].cssText)
    318          self.assertEqual(u'NEWim2', s.cssRules[1].href)
    319          self.assertEqual(u'''background-image: url(NEWc) !important;
    320  background-\\image: url(NEWb);
    321  background: url(NEWa) no-repeat !important''', s.cssRules[2].style.cssText)
    322
    323          cssutils.ser.prefs.keepAllProperties = False
    324
    325 -    def test_reprANDstr(self):
    326          "CSSStyleSheet.__repr__(), .__str__()"
    327          href = 'file:foo.css'
    328          title = 'title-of-css'
    329
    330          s = cssutils.css.CSSStyleSheet(href=href, title=title)
    331
    332          self.assert_(href in str(s))
    333          self.assert_(title in str(s))
    334
    335          s2 = eval(repr(s))
    336          self.assert_(isinstance(s2, s.__class__))
    337          self.assert_(href == s2.href)
    338          self.assert_(title == s2.title)
    339
    340
    341  if __name__ == '__main__':
    342      import unittest
    343      unittest.main()
    344