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
18
22
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
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
54 "Selector.selectorText"
55 tests = {
56
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
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
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
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
121 u'''#a''': None,
122 u'''#a1''': None,
123 u'''#1a''': None,
124 u'''#1''': None,
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
133 u'ab': 'ab',
134 u'a.b': None,
135 u'a.b.c': None,
136 u'.a1._1': None,
137
138
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,
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]',
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
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
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
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
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
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
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
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,
247 u'::a()': xml.dom.SyntaxErr,
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
271 u'*:lang(': xml.dom.SyntaxErr,
272 u'*:lang()': xml.dom.SyntaxErr,
273
274
275 u'not(x)': xml.dom.SyntaxErr,
276 u':not()': xml.dom.SyntaxErr,
277 u':not(x': xml.dom.SyntaxErr,
278 u':not(-': xml.dom.SyntaxErr,
279 u':not(+': xml.dom.SyntaxErr,
280
281
282 u',': xml.dom.InvalidModificationErr,
283 u',a': xml.dom.InvalidModificationErr,
284 u'a,': xml.dom.InvalidModificationErr,
285 }
286
287 self.do_raise_r(tests, att='_setSelectorText')
288
290 "Selector.specificity"
291 selector = cssutils.css.Selector()
292
293
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
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
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),
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
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),
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
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