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

Source Code for Module cssutils.tests.test_selector

  1  """Testcases for cssutils.css.selector.Selector. 
  2   
  3  what should happen here? 
  4      - star 7 hack:: 
  5          x* 
  6          does not validate but works in IE>5 and FF, does it??? 
  7   
  8  """ 
  9  __author__ = '$LastChangedBy: cthedot $' 
 10  __date__ = '$LastChangedDate: 2008-01-06 01:15:23 +0100 (So, 06 Jan 2008) $' 
 11  __version__ = '$LastChangedRevision: 822 $' 
 12   
 13  import xml.dom 
 14  import basetest 
 15  import cssutils 
 16   
17 -class SelectorTestCase(basetest.BaseTestCase):
18
19 - def setUp(self):
20 self.r = cssutils.css.Selector('*', namespaces={'p': 'URI', 21 '-a_x12': 'URI2'})
22
23 - def test_init(self):
24 "Selector.__init__()" 25 s = cssutils.css.Selector('*') 26 self.assertEqual(('', '*'), s.element) 27 self.assertEqual({}, s.namespaces) 28 self.assertEqual(None, s.parentRule) 29 self.assertEqual(set(), s.prefixes) 30 self.assertEqual('*', s.selectorText) 31 self.assertEqual((0,0,0,0), s.specificity) 32 self.assertEqual(True, s.wellformed) 33 34 self.assertRaisesEx(xml.dom.NamespaceErr, cssutils.css.Selector, 'p|b') 35 36 s = cssutils.css.Selector('p|b', namespaces={'p': 'URI'} ) 37 self.assertEqual(('URI', 'b'), s.element) 38 self.assertEqual({'p': 'URI'}, s.namespaces) 39 self.assertEqual(None, s.parentRule) 40 self.assertEqual(set('p'), s.prefixes) 41 self.assertEqual('p|b', s.selectorText) 42 self.assertEqual((0,0,0,1), s.specificity) 43 self.assertEqual(True, s.wellformed)
44
45 - def test_prefixes(self):
46 "Selector.prefixes" 47 sel=u'p|x1 p|x2 |y *|z [p2|x] [p|x="1"]' 48 s = cssutils.css.Selector(selectorText=sel, namespaces={'p': 'URI', 49 'p2': 'URI2'}) 50 self.assertEqual(set([u'p2', u'p']), s.prefixes) 51 self.assertEqual({'p': 'URI', 'p2': 'URI2'}, s.namespaces)
52
53 - def test_selectorText(self):
54 "Selector.selectorText" 55 tests = { 56 # combinators 57 u'a+b>c~e f': None, 58 u'a+b': None, 59 u'a + b': 'a+b', 60 u'a\n +\t b': 'a+b', 61 u'a~b': None, 62 u'a b': None, 63 u'a b': 'a b', 64 u'a\nb': 'a b', 65 u'a\tb': 'a b', 66 u'a #b': 'a #b', 67 u'a .b': 'a .b', 68 u'a * b': None, 69 # > 70 u'a>b': None, 71 u'a> b': 'a>b', 72 u'a >b': 'a>b', 73 u'a > b': 'a>b', 74 # + 75 u'a+b': None, 76 u'a+ b': 'a+b', 77 u'a +b': 'a+b', 78 u'a + b': 'a+b', 79 # ~ 80 u'a~b': None, 81 u'a~ b': 'a~b', 82 u'a ~b': 'a~b', 83 u'a ~ b': 'a~b', 84 85 # type selector 86 u'a': None, 87 u'h1-a_x__--': None, 88 u'a-a': None, 89 u'a_a': None, 90 u'-a': None, 91 u'_': None, 92 u'-_': None, 93 ur'-\72': u'-r', 94 #ur'\25': u'%', # TODO: should be escaped! 95 u'.a a': None, 96 u'a1': None, 97 u'a1-1': None, 98 u'.a1-1': None, 99 u'|e': u'e', 100 u'*|e': None, 101 u'*|*': None, 102 u'p|*': None, 103 u'p|e': None, 104 u'-a_x12|e': None, 105 u'*|b[p|a]': None, 106 107 # universal 108 u'*': None, 109 u'*/*x*/': None, 110 u'* /*x*/': None, 111 u'*:hover': None, 112 u'* :hover': None, 113 u'*:lang(fr)': None, 114 u'* :lang(fr)': None, 115 u'*::first-line': None, 116 u'* ::first-line': None, 117 u'*[lang=fr]': None, 118 u'[lang=fr]': None, 119 120 # HASH 121 u'''#a''': None, 122 u'''#a1''': None, 123 u'''#1a''': None, # valid to grammar but not for HTML 124 u'''#1''': None, # valid to grammar but not for HTML 125 u'''a#b''': None, 126 u'''a #b''': None, 127 u'''a#b.c''': None, 128 u'''a.c#b''': None, 129 u'''a #b.c''': None, 130 u'''a .c#b''': None, 131 132 # class 133 u'ab': 'ab', 134 u'a.b': None, 135 u'a.b.c': None, 136 u'.a1._1': None, 137 138 # attrib 139 u'''[x]''': None, 140 u'''*[x]''': None, 141 u'''a[x]''': None, 142 u'''a[ x]''': 'a[x]', 143 u'''a[x ]''': 'a[x]', 144 u'''a [x]''': 'a [x]', 145 u'''* [x]''': None, # is really * *[x] 146 147 u'''a[x="1"]''': None, 148 u'''a[x ="1"]''': 'a[x="1"]', 149 u'''a[x= "1"]''': 'a[x="1"]', 150 u'''a[x = "1"]''': 'a[x="1"]', 151 u'''a[ x = "1"]''': 'a[x="1"]', 152 u'''a[x = "1" ]''': 'a[x="1"]', 153 u'''a[ x = "1" ]''': 'a[x="1"]', 154 u'''a [ x = "1" ]''': 'a [x="1"]', 155 156 u'''a[x~=a1]''': None, 157 u'''a[x ~=a1]''': 'a[x~=a1]', 158 u'''a[x~= a1]''': 'a[x~=a1]', 159 u'''a[x ~= a1]''': 'a[x~=a1]', 160 u'''a[ x ~= a1]''': 'a[x~=a1]', 161 u'''a[x ~= a1 ]''': 'a[x~=a1]', 162 u'''a[ x ~= a1 ]''': 'a[x~=a1]', 163 u'''a [ x ~= a1 ]''': 'a [x~=a1]', # same as next! 164 u'''a *[ x ~= a1 ]''': 'a *[x~=a1]', 165 166 u'''a[x|=en]''': None, 167 u'''a[x|= en]''': 'a[x|=en]', 168 u'''a[x |=en]''': 'a[x|=en]', 169 u'''a[x |= en]''': 'a[x|=en]', 170 u'''a[ x |= en]''': 'a[x|=en]', 171 u'''a[x |= en ]''': 'a[x|=en]', 172 u'''a[ x |= en]''': 'a[x|=en]', 173 u'''a [ x |= en]''': 'a [x|=en]', 174 # CSS3 175 u'''a[x^=en]''': None, 176 u'''a[x$=en]''': None, 177 u'''a[x*=en]''': None, 178 179 u'''a[/*1*/x/*2*/]''': None, 180 u'''a[/*1*/x/*2*/=/*3*/a/*4*/]''': None, 181 u'''a[/*1*/x/*2*/~=/*3*/a/*4*/]''': None, 182 u'''a[/*1*/x/*2*/|=/*3*/a/*4*/]''': None, 183 184 # pseudo-elements 185 u'a x:first-line': None, 186 u'a x:first-letter': None, 187 u'a x:before': None, 188 u'a x:after': None, 189 u'a x::selection': None, 190 191 u'x:lang(de) y': None, 192 u'x:nth-child(odd) y': None, 193 # functional pseudo 194 u'x:func(+-2px22.3"s"i)': None, 195 u'x:func(+)': None, 196 u'x:func(1px)': None, 197 u'x:func(23.4)': None, 198 u'x:func("s")': None, 199 u'x:func(i)': None, 200 201 # negation 202 u':not(y)': None, 203 u':not( y \t\n)': u':not(y)', 204 u'*:not(y)': None, 205 u'x:not(y)': None, 206 u'.x:not(y)': None, 207 u':not(*)': None, 208 u':not(#a)': None, 209 u':not(.a)': None, 210 u':not([a])': None, 211 u':not(:first-letter)': None, 212 u':not(::first-letter)': None, 213 214 # escapes 215 ur'\74\72 td': 'trtd', 216 ur'\74\72 td': 'tr td', 217 ur'\74\000072 td': 'trtd', 218 ur'\74\000072 td': 'tr td', 219 220 # comments 221 u'a/**/ b': None, 222 u'a /**/b': None, 223 u'a /**/ b': None, 224 u'a /**/ b': u'a /**/ b', 225 u'a /**/ b': u'a /**/ b' 226 } 227 # do not parse as not complete 228 self.do_equal_r(tests, att='selectorText') 229 230 tests = { 231 u'': xml.dom.SyntaxErr, 232 u'1': xml.dom.SyntaxErr, 233 u'-1': xml.dom.SyntaxErr, 234 u'a*b': xml.dom.SyntaxErr, 235 u'a *b': xml.dom.SyntaxErr, 236 u'a* b': xml.dom.SyntaxErr, 237 u'a/**/b': xml.dom.SyntaxErr, 238 239 u'#': xml.dom.SyntaxErr, 240 u'|': xml.dom.SyntaxErr, 241 242 u':': xml.dom.SyntaxErr, 243 u'::': xml.dom.SyntaxErr, 244 u': a': xml.dom.SyntaxErr, 245 u':: a': xml.dom.SyntaxErr, 246 u':a()': xml.dom.SyntaxErr, # no value 247 u'::a()': xml.dom.SyntaxErr, # no value 248 u':::a': xml.dom.SyntaxErr, 249 u':1': xml.dom.SyntaxErr, 250 251 u'#.x': xml.dom.SyntaxErr, 252 u'.': xml.dom.SyntaxErr, 253 u'.1': xml.dom.SyntaxErr, 254 u'.a.1': xml.dom.SyntaxErr, 255 256 u'[a': xml.dom.SyntaxErr, 257 u'a]': xml.dom.SyntaxErr, 258 u'[a b]': xml.dom.SyntaxErr, 259 u'[=b]': xml.dom.SyntaxErr, 260 u'[a=]': xml.dom.SyntaxErr, 261 u'[a|=]': xml.dom.SyntaxErr, 262 u'[a~=]': xml.dom.SyntaxErr, 263 u'[a=1]': xml.dom.SyntaxErr, 264 265 u'a +': xml.dom.SyntaxErr, 266 u'a >': xml.dom.SyntaxErr, 267 u'a ++ b': xml.dom.SyntaxErr, 268 u'a + > b': xml.dom.SyntaxErr, 269 270 # functional pseudo 271 u'*:lang(': xml.dom.SyntaxErr, 272 u'*:lang()': xml.dom.SyntaxErr, # no arg 273 274 # negation 275 u'not(x)': xml.dom.SyntaxErr, # no valid function 276 u':not()': xml.dom.SyntaxErr, # no arg 277 u':not(x': xml.dom.SyntaxErr, # no ) 278 u':not(-': xml.dom.SyntaxErr, # not allowed 279 u':not(+': xml.dom.SyntaxErr, # not allowed 280 281 # only one selector! 282 u',': xml.dom.InvalidModificationErr, 283 u',a': xml.dom.InvalidModificationErr, 284 u'a,': xml.dom.InvalidModificationErr, 285 } 286 # only set as not complete 287 self.do_raise_r(tests, att='_setSelectorText')
288
289 - def test_specificity(self):
290 "Selector.specificity" 291 selector = cssutils.css.Selector() 292 293 # readonly 294 def _set(): selector.specificity = 1 295 self.assertRaisesMsg(AttributeError, "can't set attribute", _set) 296 297 tests = { 298 u'*': (0,0,0,0), 299 u'li': (0,0,0,1), 300 u'li:first-line': (0,0,0,2), 301 u'ul li': (0,0,0,2), 302 u'ul ol+li': (0,0,0,3), 303 u'h1 + *[rel=up]': (0,0,1,1), 304 u'ul ol li.red': (0,0,1,3), 305 u'li.red.level': (0,0,2,1), 306 u'#x34y': (0,1,0,0), 307 308 u'UL OL LI.red': (0,0,1,3), 309 u'LI.red.level': (0,0,2,1), 310 u'#s12:not(FOO)': (0,1,0,1), 311 u'button:not([DISABLED])': (0,0,1,1), #? 312 u'*:not(FOO)': (0,0,0,1), 313 314 # elements 315 u'a+b': (0,0,0,2), 316 u'a>b': (0,0,0,2), 317 u'a b': (0,0,0,2), 318 u'* a': (0,0,0,1), 319 u'a *': (0,0,0,1), 320 u'a * b': (0,0,0,2), 321 322 u'a:hover': (0,0,0,1), 323 324 u'a:first-line': (0,0,0,2), 325 u'a:first-letter': (0,0,0,2), 326 u'a:before': (0,0,0,2), 327 u'a:after': (0,0,0,2), 328 329 # classes and attributes 330 u'.a': (0,0,1,0), 331 u'*.a': (0,0,1,0), 332 u'a.a': (0,0,1,1), 333 u'.a.a': (0,0,2,0), # IE<7 False (0,0,1,0) 334 u'a.a.a': (0,0,2,1), 335 u'.a.b': (0,0,2,0), 336 u'a.a.b': (0,0,2,1), 337 u'.a .a': (0,0,2,0), 338 u'*[x]': (0,0,1,0), 339 u'*[x]': (0,0,1,0), 340 u'*[x]': (0,0,1,0), 341 u'*[x=a]': (0,0,1,0), 342 u'*[x~=a]': (0,0,1,0), 343 u'*[x|=a]': (0,0,1,0), 344 u'*[x^=a]': (0,0,1,0), 345 u'*[x*=a]': (0,0,1,0), 346 u'*[x$=a]': (0,0,1,0), 347 u'*[x][y]': (0,0,2,0), 348 349 # ids 350 u'#a': (0,1,0,0), 351 u'*#a': (0,1,0,0), 352 u'x#a': (0,1,0,1), 353 u'.x#a': (0,1,1,0), 354 u'a.x#a': (0,1,1,1), 355 u'#a#a': (0,2,0,0), # e.g. html:id + xml:id 356 u'#a#b': (0,2,0,0), 357 u'#a #b': (0,2,0,0), 358 } 359 for text in tests: 360 selector.selectorText = text 361 self.assertEqual(tests[text], selector.specificity)
362
363 - def test_reprANDstr(self):
364 "Selector.__repr__(), .__str__()" 365 sel=u'a+b' 366 367 s = cssutils.css.Selector(selectorText=sel) 368 369 self.assert_(sel in str(s)) 370 371 s2 = eval(repr(s)) 372 self.assert_(isinstance(s2, s.__class__)) 373 self.assert_(sel == s2.selectorText)
374 375 376 if __name__ == '__main__': 377 import unittest 378 unittest.main() 379