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-02-02 23:53:54 +0100 (Sa, 02 Feb 2008) $'
11 __version__ = '$LastChangedRevision: 975 $'
12
13 import xml.dom
14 import basetest
15 import cssutils
16
18
21
23 "Selector.__init__()"
24 s = cssutils.css.Selector('*')
25 self.assertEqual((None, '*'), s.element)
26 self.assertEqual({}, s._namespaces.namespaces)
27 self.assertEqual(None, s.parentList)
28 self.assertEqual('*', s.selectorText)
29 self.assertEqual((0,0,0,0), s.specificity)
30 self.assertEqual(True, s.wellformed)
31
32 s = cssutils.css.Selector(('p|b', {'p': 'URI'}) )
33 self.assertEqual(('URI', 'b'), s.element)
34 self.assertEqual({'p': 'URI'}, s._namespaces.namespaces)
35 self.assertEqual(None, s.parentList)
36 self.assertEqual('p|b', s.selectorText)
37 self.assertEqual((0,0,0,1), s.specificity)
38 self.assertEqual(True, s.wellformed)
39
40 self.assertRaisesEx(xml.dom.NamespaceErr, cssutils.css.Selector, 'p|b')
41
43 "Selector.element (TODO: RESOLVE)"
44 tests = {
45 '*': (None, '*'),
46 'x': (None, 'x'),
47 '\\x': (None, '\\x'),
48 '|x': (u'', 'x'),
49 '*|x': (cssutils._ANYNS, 'x'),
50 'ex|x': (u'example', 'x'),
51 'a x': (None, 'x'),
52 'a+x': (None, 'x'),
53 'a>x': (None, 'x'),
54 'a~x': (None, 'x'),
55 'a+b~c x': (None, 'x'),
56 'x[href]': (None, 'x'),
57 'x[href="123"]': (None, 'x'),
58 'x:hover': (None, 'x'),
59 'x:first-letter': (None, 'x'),
60 'x::first-line': (None, 'x'),
61 'x:not(href)': (None, 'x'),
62
63 '#id': None,
64 '.c': None,
65 'x#id': (None, 'x'),
66 'x.c': (None, 'x')
67 }
68 for test, ele in tests.items():
69 s = cssutils.css.Selector((test,{'ex': 'example'}))
70 self.assertEqual(ele, s.element)
71
73 "Selector.namespaces"
74 namespaces = [
75 {'p': 'other'},
76 {'': 'default', 'p': 'other'},
77 {'': 'default', 'p': 'default' }
78 ]
79 tests = {
80
81 '*': ('*', '|*', '|*'),
82 'x': ('x', '|x', '|x'),
83 '|*': ('|*', '|*', '|*'),
84 '|x': ('|x', '|x', '|x'),
85 '*|*': ('*', '*', '*'),
86 '*|x': ('x', 'x', 'x'),
87 'p|*': ('p|*', 'p|*', '|*'),
88 'p|x': ('p|x', 'p|x', '|x'),
89 'x[a][|a][*|a][p|a]': ('x[a][|a][a][p|a]',
90 '|x[|a][|a][*|a][p|a]',
91 '|x[|a][|a][*|a][|a]')
92 }
93 for sel, exp in tests.items():
94 for i, result in enumerate(exp):
95 s = cssutils.css.Selector((sel, namespaces[i]))
96 self.assertEqual(result, s.selectorText)
97
98
99 sheet = cssutils.css.CSSStyleSheet()
100 sheet.cssText = '@namespace p "u"; p|x { color: green }'
101
115
117 "Selector.selectorText"
118 tests = {
119
120 u'a+b>c~e f': u'a + b > c ~ e f',
121 u'a+b': u'a + b',
122 u'a + b': 'a + b',
123 u'a\n +\t b': 'a + b',
124 u'a~b': u'a ~ b',
125 u'a b': None,
126 u'a b': 'a b',
127 u'a\nb': 'a b',
128 u'a\tb': 'a b',
129 u'a #b': 'a #b',
130 u'a .b': 'a .b',
131 u'a * b': None,
132
133 u'a>b': u'a > b',
134 u'a> b': 'a > b',
135 u'a >b': 'a > b',
136 u'a > b': 'a > b',
137
138 u'a+b': u'a + b',
139 u'a+ b': 'a + b',
140 u'a +b': 'a + b',
141 u'a + b': 'a + b',
142
143 u'a~b': u'a ~ b',
144 u'a~ b': 'a ~ b',
145 u'a ~b': 'a ~ b',
146 u'a ~ b': 'a ~ b',
147
148
149 u'a': None,
150 u'h1-a_x__--': None,
151 u'a-a': None,
152 u'a_a': None,
153 u'-a': None,
154 u'_': None,
155 u'-_': None,
156 ur'-\72': u'-r',
157
158 u'.a a': None,
159 u'a1': None,
160 u'a1-1': None,
161 u'.a1-1': None,
162
163
164 u'*': None,
165 u'*/*x*/': None,
166 u'* /*x*/': None,
167 u'*:hover': None,
168 u'* :hover': None,
169 u'*:lang(fr)': None,
170 u'* :lang(fr)': None,
171 u'*::first-line': None,
172 u'* ::first-line': None,
173 u'*[lang=fr]': None,
174 u'[lang=fr]': None,
175
176
177 u'''#a''': None,
178 u'''#a1''': None,
179 u'''#1a''': None,
180 u'''#1''': None,
181 u'''a#b''': None,
182 u'''a #b''': None,
183 u'''a#b.c''': None,
184 u'''a.c#b''': None,
185 u'''a #b.c''': None,
186 u'''a .c#b''': None,
187
188
189 u'ab': 'ab',
190 u'a.b': None,
191 u'a.b.c': None,
192 u'.a1._1': None,
193
194
195 u'''[x]''': None,
196 u'''*[x]''': None,
197 u'''a[x]''': None,
198 u'''a[ x]''': 'a[x]',
199 u'''a[x ]''': 'a[x]',
200 u'''a [x]''': 'a [x]',
201 u'''* [x]''': None,
202
203 u'''a[x="1"]''': None,
204 u'''a[x ="1"]''': 'a[x="1"]',
205 u'''a[x= "1"]''': 'a[x="1"]',
206 u'''a[x = "1"]''': 'a[x="1"]',
207 u'''a[ x = "1"]''': 'a[x="1"]',
208 u'''a[x = "1" ]''': 'a[x="1"]',
209 u'''a[ x = "1" ]''': 'a[x="1"]',
210 u'''a [ x = "1" ]''': 'a [x="1"]',
211
212 u'''a[x~=a1]''': None,
213 u'''a[x ~=a1]''': 'a[x~=a1]',
214 u'''a[x~= a1]''': 'a[x~=a1]',
215 u'''a[x ~= a1]''': 'a[x~=a1]',
216 u'''a[ x ~= a1]''': 'a[x~=a1]',
217 u'''a[x ~= a1 ]''': 'a[x~=a1]',
218 u'''a[ x ~= a1 ]''': 'a[x~=a1]',
219 u'''a [ x ~= a1 ]''': 'a [x~=a1]',
220 u'''a *[ x ~= a1 ]''': 'a *[x~=a1]',
221
222 u'''a[x|=en]''': None,
223 u'''a[x|= en]''': 'a[x|=en]',
224 u'''a[x |=en]''': 'a[x|=en]',
225 u'''a[x |= en]''': 'a[x|=en]',
226 u'''a[ x |= en]''': 'a[x|=en]',
227 u'''a[x |= en ]''': 'a[x|=en]',
228 u'''a[ x |= en]''': 'a[x|=en]',
229 u'''a [ x |= en]''': 'a [x|=en]',
230
231 u'''a[x^=en]''': None,
232 u'''a[x$=en]''': None,
233 u'''a[x*=en]''': None,
234
235 u'''a[/*1*/x/*2*/]''': None,
236 u'''a[/*1*/x/*2*/=/*3*/a/*4*/]''': None,
237 u'''a[/*1*/x/*2*/~=/*3*/a/*4*/]''': None,
238 u'''a[/*1*/x/*2*/|=/*3*/a/*4*/]''': None,
239
240
241 u'a x:first-line': None,
242 u'a x:first-letter': None,
243 u'a x:before': None,
244 u'a x:after': None,
245 u'a x::selection': None,
246
247 u'x:lang(de) y': None,
248 u'x:nth-child(odd) y': None,
249
250 u'x:func(+-2px22.3"s"i)': None,
251 u'x:func(+)': None,
252 u'x:func(1px)': None,
253 u'x:func(23.4)': None,
254 u'x:func("s")': None,
255 u'x:func(i)': None,
256
257
258 u':not(y)': None,
259 u':not( y \t\n)': u':not(y)',
260 u'*:not(y)': None,
261 u'x:not(y)': None,
262 u'.x:not(y)': None,
263 u':not(*)': None,
264 u':not(#a)': None,
265 u':not(.a)': None,
266 u':not([a])': None,
267 u':not(:first-letter)': None,
268 u':not(::first-letter)': None,
269
270
271 ur'\74\72 td': 'trtd',
272 ur'\74\72 td': 'tr td',
273 ur'\74\000072 td': 'trtd',
274 ur'\74\000072 td': 'tr td',
275
276
277 u'a/**/ b': None,
278 u'a /**/b': None,
279 u'a /**/ b': None,
280 u'a /**/ b': u'a /**/ b',
281 u'a /**/ b': u'a /**/ b',
282
283
284 u'|e': u'|e',
285 u'*|e': 'e',
286 u'*|*': u'*',
287 (u'p|*', (('p', 'uri'),)): u'p|*',
288 (u'p|e', (('p', 'uri'),)): u'p|e',
289 (u'-a_x12|e', (('-a_x12', 'uri'),)): u'-a_x12|e',
290 (u'*|b[p|a]', (('p', 'uri'),)): 'b[p|a]'
291 }
292
293 self.do_equal_r(tests, att='selectorText')
294
295 tests = {
296 u'x|a': xml.dom.NamespaceErr,
297 (u'p|*', (('x', 'uri'),)): xml.dom.NamespaceErr,
298
299 u'': xml.dom.SyntaxErr,
300 u'1': xml.dom.SyntaxErr,
301 u'-1': xml.dom.SyntaxErr,
302 u'a*b': xml.dom.SyntaxErr,
303 u'a *b': xml.dom.SyntaxErr,
304 u'a* b': xml.dom.SyntaxErr,
305 u'a/**/b': xml.dom.SyntaxErr,
306
307 u'#': xml.dom.SyntaxErr,
308 u'|': xml.dom.SyntaxErr,
309
310 u':': xml.dom.SyntaxErr,
311 u'::': xml.dom.SyntaxErr,
312 u': a': xml.dom.SyntaxErr,
313 u':: a': xml.dom.SyntaxErr,
314 u':a()': xml.dom.SyntaxErr,
315 u'::a()': xml.dom.SyntaxErr,
316 u':::a': xml.dom.SyntaxErr,
317 u':1': xml.dom.SyntaxErr,
318
319 u'#.x': xml.dom.SyntaxErr,
320 u'.': xml.dom.SyntaxErr,
321 u'.1': xml.dom.SyntaxErr,
322 u'.a.1': xml.dom.SyntaxErr,
323
324 u'[a': xml.dom.SyntaxErr,
325 u'a]': xml.dom.SyntaxErr,
326 u'[a b]': xml.dom.SyntaxErr,
327 u'[=b]': xml.dom.SyntaxErr,
328 u'[a=]': xml.dom.SyntaxErr,
329 u'[a|=]': xml.dom.SyntaxErr,
330 u'[a~=]': xml.dom.SyntaxErr,
331 u'[a=1]': xml.dom.SyntaxErr,
332
333 u'a +': xml.dom.SyntaxErr,
334 u'a >': xml.dom.SyntaxErr,
335 u'a ++ b': xml.dom.SyntaxErr,
336 u'a + > b': xml.dom.SyntaxErr,
337
338
339 u'*:lang(': xml.dom.SyntaxErr,
340 u'*:lang()': xml.dom.SyntaxErr,
341
342
343 u'not(x)': xml.dom.SyntaxErr,
344 u':not()': xml.dom.SyntaxErr,
345 u':not(x': xml.dom.SyntaxErr,
346 u':not(-': xml.dom.SyntaxErr,
347 u':not(+': xml.dom.SyntaxErr,
348
349
350 u',': xml.dom.InvalidModificationErr,
351 u',a': xml.dom.InvalidModificationErr,
352 u'a,': xml.dom.InvalidModificationErr,
353 }
354
355 self.do_raise_r(tests, att='_setSelectorText')
356
358 "Selector.specificity"
359 selector = cssutils.css.Selector()
360
361
362 def _set(): selector.specificity = 1
363 self.assertRaisesMsg(AttributeError, "can't set attribute", _set)
364
365 tests = {
366 u'*': (0,0,0,0),
367 u'li': (0,0,0,1),
368 u'li:first-line': (0,0,0,2),
369 u'ul li': (0,0,0,2),
370 u'ul ol+li': (0,0,0,3),
371 u'h1 + *[rel=up]': (0,0,1,1),
372 u'ul ol li.red': (0,0,1,3),
373 u'li.red.level': (0,0,2,1),
374 u'#x34y': (0,1,0,0),
375
376 u'UL OL LI.red': (0,0,1,3),
377 u'LI.red.level': (0,0,2,1),
378 u'#s12:not(FOO)': (0,1,0,1),
379 u'button:not([DISABLED])': (0,0,1,1),
380 u'*:not(FOO)': (0,0,0,1),
381
382
383 u'a+b': (0,0,0,2),
384 u'a>b': (0,0,0,2),
385 u'a b': (0,0,0,2),
386 u'* a': (0,0,0,1),
387 u'a *': (0,0,0,1),
388 u'a * b': (0,0,0,2),
389
390 u'a:hover': (0,0,0,1),
391
392 u'a:first-line': (0,0,0,2),
393 u'a:first-letter': (0,0,0,2),
394 u'a:before': (0,0,0,2),
395 u'a:after': (0,0,0,2),
396
397
398 u'.a': (0,0,1,0),
399 u'*.a': (0,0,1,0),
400 u'a.a': (0,0,1,1),
401 u'.a.a': (0,0,2,0),
402 u'a.a.a': (0,0,2,1),
403 u'.a.b': (0,0,2,0),
404 u'a.a.b': (0,0,2,1),
405 u'.a .a': (0,0,2,0),
406 u'*[x]': (0,0,1,0),
407 u'*[x]': (0,0,1,0),
408 u'*[x]': (0,0,1,0),
409 u'*[x=a]': (0,0,1,0),
410 u'*[x~=a]': (0,0,1,0),
411 u'*[x|=a]': (0,0,1,0),
412 u'*[x^=a]': (0,0,1,0),
413 u'*[x*=a]': (0,0,1,0),
414 u'*[x$=a]': (0,0,1,0),
415 u'*[x][y]': (0,0,2,0),
416
417
418 u'#a': (0,1,0,0),
419 u'*#a': (0,1,0,0),
420 u'x#a': (0,1,0,1),
421 u'.x#a': (0,1,1,0),
422 u'a.x#a': (0,1,1,1),
423 u'#a#a': (0,2,0,0),
424 u'#a#b': (0,2,0,0),
425 u'#a #b': (0,2,0,0),
426 }
427 for text in tests:
428 selector.selectorText = text
429 self.assertEqual(tests[text], selector.specificity)
430
432 "Selector.__repr__(), .__str__()"
433 sel=u'a + b'
434
435 s = cssutils.css.Selector(selectorText=sel)
436
437 self.assert_(sel in str(s))
438
439 s2 = eval(repr(s))
440 self.assert_(isinstance(s2, s.__class__))
441 self.assert_(sel == s2.selectorText)
442
443
444 if __name__ == '__main__':
445 import unittest
446 unittest.main()
447