gvsig-scripting / org.gvsig.scripting / trunk / org.gvsig.scripting / org.gvsig.scripting.app / org.gvsig.scripting.app.mainplugin / src / main / resources-plugin / scripting / lib / cssutils / tests / test_cssstylesheet.py @ 475
History | View | Annotate | Download (32.7 KB)
1 |
# -*- coding: utf-8 -*-
|
---|---|
2 |
"""Tests for css.CSSStyleSheet"""
|
3 |
|
4 |
import xml.dom |
5 |
import basetest |
6 |
import cssutils.css |
7 |
|
8 |
class CSSStyleSheetTestCase(basetest.BaseTestCase): |
9 |
|
10 |
def setUp(self): |
11 |
super(CSSStyleSheetTestCase, self).setUp() |
12 |
self.r = cssutils.css.CSSStyleSheet() # used by basetest |
13 |
self.s = self.r # used here |
14 |
self.rule = cssutils.css.CSSStyleRule()
|
15 |
|
16 |
def tearDown(self): |
17 |
cssutils.ser.prefs.useDefaults() |
18 |
|
19 |
def test_init(self): |
20 |
"CSSStyleSheet.__init__()"
|
21 |
self.assertEqual('text/css', self.s.type) |
22 |
self.assertEqual(False, self.s._readonly) |
23 |
self.assertEqual([], self.s.cssRules) |
24 |
self.assertEqual(False, self.s.disabled) |
25 |
self.assertEqual(None, self.s.href) |
26 |
self.assertEqual(None, self.s.media) |
27 |
self.assertEqual(None, self.s.ownerNode) |
28 |
self.assertEqual(None, self.s.parentStyleSheet) |
29 |
self.assertEqual(u'', self.s.title) |
30 |
|
31 |
# check that type is readonly
|
32 |
self.assertRaises(AttributeError, self.r.__setattr__, 'href', 'x') |
33 |
self.assertRaises(AttributeError, self.r.__setattr__, 'parentStyleSheet', 'x') |
34 |
self.assertRaises(AttributeError, self.r.__setattr__, 'ownerNode', 'x') |
35 |
self.assertRaises(AttributeError, self.r.__setattr__, 'type', 'x') |
36 |
|
37 |
def test_iter(self): |
38 |
"CSSStyleSheet.__iter__()"
|
39 |
s = cssutils.css.CSSStyleSheet() |
40 |
s.cssText = '''@import "x";@import "y";@namespace "u";'''
|
41 |
types = [cssutils.css.CSSRule.IMPORT_RULE, |
42 |
cssutils.css.CSSRule.IMPORT_RULE, |
43 |
cssutils.css.CSSRule.NAMESPACE_RULE] |
44 |
for i, rule in enumerate(s): |
45 |
self.assertEqual(rule, s.cssRules[i])
|
46 |
self.assertEqual(rule.type, types[i])
|
47 |
|
48 |
def test_refs(self): |
49 |
"""CSSStylesheet references"""
|
50 |
s = cssutils.parseString('a {}')
|
51 |
rules = s.cssRules |
52 |
self.assertEqual(s.cssRules[0].parentStyleSheet, s) |
53 |
self.assertEqual(rules[0].parentStyleSheet, s) |
54 |
|
55 |
# set cssText
|
56 |
s.cssText = 'b{}'
|
57 |
|
58 |
# from 0.9.7b1
|
59 |
self.assertNotEqual(rules, s.cssRules)
|
60 |
|
61 |
# set cssRules
|
62 |
s.cssRules = cssutils.parseString('''
|
63 |
@charset "ascii";
|
64 |
/**/
|
65 |
@import "x";
|
66 |
@namespace "http://example.com/ns0";
|
67 |
@media all {
|
68 |
a { color: green; }
|
69 |
}
|
70 |
@font-face {
|
71 |
font-family: x;
|
72 |
}
|
73 |
@page {
|
74 |
font-family: Arial;
|
75 |
}
|
76 |
@x;
|
77 |
b {}').cssRules''').cssRules
|
78 |
# new object
|
79 |
self.assertNotEqual(rules, s.cssRules)
|
80 |
for i, r in enumerate(s.cssRules): |
81 |
self.assertEqual(r.parentStyleSheet, s)
|
82 |
|
83 |
# namespaces
|
84 |
s = cssutils.parseString('@namespace "http://example.com/ns1"; a {}')
|
85 |
namespaces = s.namespaces |
86 |
self.assertEqual(s.namespaces.items(), [(u'', 'http://example.com/ns1')]) |
87 |
s.cssText = '@namespace x "http://example.com/ns2"; x|a {}'
|
88 |
# not anymore!
|
89 |
self.assertNotEqual(namespaces, s.namespaces)
|
90 |
self.assertEqual(s.namespaces.items(), [(u'x', 'http://example.com/ns2')]) |
91 |
|
92 |
# variables
|
93 |
s = cssutils.parseString(u'@variables { a:1}')
|
94 |
vars1 = s.variables |
95 |
self.assertEqual(vars1[u'a'], u'1') |
96 |
|
97 |
s = cssutils.parseString(u'@variables { a:2}')
|
98 |
vars2 = s.variables |
99 |
self.assertNotEqual(vars1, vars2)
|
100 |
self.assertEqual(vars1[u'a'], u'1') |
101 |
self.assertEqual(vars2[u'a'], u'2') |
102 |
|
103 |
def test_cssRules(self): |
104 |
"CSSStyleSheet.cssRules"
|
105 |
s = cssutils.parseString('/*1*/a {x:1}')
|
106 |
self.assertEqual(2, s.cssRules.length) |
107 |
del s.cssRules[0] |
108 |
self.assertEqual(1, s.cssRules.length) |
109 |
s.cssRules.append('/*2*/')
|
110 |
self.assertEqual(2, s.cssRules.length) |
111 |
s.cssRules.extend(cssutils.parseString('/*3*/x {y:2}').cssRules)
|
112 |
self.assertEqual(4, s.cssRules.length) |
113 |
self.assertEqual(u'a {\n x: 1\n }\n/*2*/\n/*3*/\nx {\n y: 2\n }'.encode(), |
114 |
s.cssText) |
115 |
|
116 |
for r in s.cssRules: |
117 |
self.assertEqual(r.parentStyleSheet, s)
|
118 |
|
119 |
def test_cssText(self): |
120 |
"CSSStyleSheet.cssText"
|
121 |
tests = { |
122 |
'': ''.encode(), |
123 |
# @charset
|
124 |
'@charset "ascii";\n@import "x";':
|
125 |
'@charset "ascii";\n@import "x";'.encode(),
|
126 |
'@charset "ascii";\n@media all {}': '@charset "ascii";'.encode(), |
127 |
'@charset "ascii";\n@x;': '@charset "ascii";\n@x;'.encode(), |
128 |
'@charset "ascii";\na {\n x: 1\n }':
|
129 |
'@charset "ascii";\na {\n x: 1\n }'.encode(),
|
130 |
# @import
|
131 |
'@x;\n@import "x";': '@x;\n@import "x";'.encode(), |
132 |
'@import "x";\n@import "y";': '@import "x";\n@import "y";'.encode(), |
133 |
'@import "x";\n@media all {}': '@import "x";'.encode(), |
134 |
'@import "x";\n@x;': '@import "x";\n@x;'.encode(), |
135 |
'@import "x";\na {\n x: 1\n }':
|
136 |
'@import "x";\na {\n x: 1\n }'.encode(),
|
137 |
# @namespace
|
138 |
'@x;\n@namespace a "x";': '@x;\n@namespace a "x";'.encode(), |
139 |
'@namespace a "x";\n@namespace b "y";':
|
140 |
'@namespace a "x";\n@namespace b "y";'.encode(),
|
141 |
'@import "x";\n@namespace a "x";\n@media all {}':
|
142 |
'@import "x";\n@namespace a "x";'.encode(),
|
143 |
'@namespace a "x";\n@x;': '@namespace a "x";\n@x;'.encode(), |
144 |
'@namespace a "x";\na {\n x: 1\n }':
|
145 |
'@namespace a "x";\na {\n x: 1\n }'.encode(),
|
146 |
"""@namespace url("e1");
|
147 |
@namespace url("e2");
|
148 |
@namespace x url("x1");
|
149 |
@namespace x url("x2");
|
150 |
test{color: green}
|
151 |
x|test {color: green}""": """@namespace "e2"; |
152 |
@namespace x "x2";
|
153 |
test {
|
154 |
color: green
|
155 |
}
|
156 |
x|test {
|
157 |
color: green
|
158 |
}""".encode()
|
159 |
# ur'\1 { \2: \3 }': ur'''\x01 {
|
160 |
# \x02: \x03
|
161 |
# }''',
|
162 |
# ur'''
|
163 |
# \@ { \@: \@ }
|
164 |
# \1 { \2: \3 }
|
165 |
# \{{\::\;;}
|
166 |
# ''': ur'''\@ {
|
167 |
# \@: \@
|
168 |
# }
|
169 |
#\1 {
|
170 |
# \2: \3
|
171 |
# }
|
172 |
#\{
|
173 |
# {\:: \;
|
174 |
# }'''
|
175 |
} |
176 |
self.do_equal_r(tests)
|
177 |
|
178 |
tests = { |
179 |
'': None, |
180 |
# @charset
|
181 |
'@charset "ascii";\n@import "x";': None, |
182 |
'@charset "ascii";\n@media all {}': '@charset "ascii";', |
183 |
'@charset "ascii";\n@x;': None, |
184 |
'@charset "ascii";\na {\n x: 1\n }': None, |
185 |
# @import
|
186 |
'@x;\n@import "x";': None, |
187 |
'@import "x";\n@import "y";': None, |
188 |
'@import "x";\n@media all {}': '@import "x";', |
189 |
'@import "x";\n@x;': None, |
190 |
'@import "x";\na {\n x: 1\n }': None, |
191 |
# @namespace
|
192 |
'@x;\n@namespace a "x";': None, |
193 |
'@namespace a "x";\n@namespace b "y";': None, |
194 |
'@import "x";\n@namespace a "x";\n@media all {}':
|
195 |
'@import "x";\n@namespace a "x";',
|
196 |
'@namespace a "x";\n@x;': None, |
197 |
'@namespace a "x";\na {\n x: 1\n }': None, |
198 |
"""@namespace url("e1");
|
199 |
@namespace url("e2");
|
200 |
@namespace x url("x1");
|
201 |
@namespace x url("x2");
|
202 |
test{color: green}
|
203 |
x|test {color: green}""": """@namespace "e2"; |
204 |
@namespace x "x2";
|
205 |
test {
|
206 |
color: green
|
207 |
}
|
208 |
x|test {
|
209 |
color: green
|
210 |
}"""
|
211 |
# ur'\1 { \2: \3 }': ur'''\x01 {
|
212 |
# \x02: \x03
|
213 |
# }''',
|
214 |
# ur'''
|
215 |
# \@ { \@: \@ }
|
216 |
# \1 { \2: \3 }
|
217 |
# \{{\::\;;}
|
218 |
# ''': ur'''\@ {
|
219 |
# \@: \@
|
220 |
# }
|
221 |
#\1 {
|
222 |
# \2: \3
|
223 |
# }
|
224 |
#\{
|
225 |
# {\:: \;
|
226 |
# }'''
|
227 |
} |
228 |
self.do_equal_p(tests)
|
229 |
|
230 |
s = cssutils.css.CSSStyleSheet() |
231 |
s.cssText = u'''@charset "ascii";@import "x";@namespace a "x";
|
232 |
@media all {/*1*/}@page {margin: 0}a {\n x: 1\n }@unknown;/*comment*/'''
|
233 |
for r in s.cssRules: |
234 |
self.assertEqual(s, r.parentStyleSheet)
|
235 |
|
236 |
def test_cssText_HierarchyRequestErr(self): |
237 |
"CSSStyleSheet.cssText HierarchyRequestErr"
|
238 |
tests = { |
239 |
# @charset: only one and always 1st
|
240 |
u' @charset "utf-8";': xml.dom.HierarchyRequestErr,
|
241 |
u'@charset "ascii";@charset "ascii";': xml.dom.HierarchyRequestErr, u'/*c*/@charset "ascii";': xml.dom.HierarchyRequestErr, |
242 |
u'@import "x"; @charset "ascii";': xml.dom.HierarchyRequestErr,
|
243 |
u'@namespace a "x"; @charset "ascii";': xml.dom.HierarchyRequestErr,
|
244 |
u'@media all {} @charset "ascii";': xml.dom.HierarchyRequestErr,
|
245 |
u'@page {} @charset "ascii";': xml.dom.HierarchyRequestErr,
|
246 |
u'a {} @charset "ascii";': xml.dom.HierarchyRequestErr,
|
247 |
|
248 |
# @import: before @namespace, @media, @page, sr
|
249 |
u'@namespace a "x"; @import "x";': xml.dom.HierarchyRequestErr,
|
250 |
u'@media all {} @import "x";': xml.dom.HierarchyRequestErr,
|
251 |
u'@page {} @import "x";': xml.dom.HierarchyRequestErr,
|
252 |
u'a {} @import "x";': xml.dom.HierarchyRequestErr,
|
253 |
|
254 |
# @namespace: before @media, @page, sr
|
255 |
u'@media all {} @namespace a "x";': xml.dom.HierarchyRequestErr,
|
256 |
u'@page {} @namespace a "x";': xml.dom.HierarchyRequestErr,
|
257 |
u'a {} @namespace a "x";': xml.dom.HierarchyRequestErr,
|
258 |
} |
259 |
self.do_raise_r(tests)
|
260 |
self.do_raise_p(tests)
|
261 |
|
262 |
def test_cssText_SyntaxErr(self): |
263 |
"""CSSStyleSheet.cssText SyntaxErr
|
264 |
|
265 |
for single {, } or ;
|
266 |
"""
|
267 |
tests = { |
268 |
u'{': xml.dom.SyntaxErr,
|
269 |
u'}': xml.dom.SyntaxErr,
|
270 |
u';': xml.dom.SyntaxErr,
|
271 |
u'@charset "ascii";{': xml.dom.SyntaxErr,
|
272 |
u'@charset "ascii";}': xml.dom.SyntaxErr,
|
273 |
u'@charset "ascii";;': xml.dom.SyntaxErr,
|
274 |
} |
275 |
self.do_raise_r(tests)
|
276 |
self.do_raise_p(tests)
|
277 |
|
278 |
def test_encoding(self): |
279 |
"CSSStyleSheet.encoding"
|
280 |
self.s.cssText='' |
281 |
self.assertEqual('utf-8', self.s.encoding) |
282 |
|
283 |
self.s.encoding = 'ascii' |
284 |
self.assertEqual('ascii', self.s.encoding) |
285 |
self.assertEqual(1, self.s.cssRules.length) |
286 |
self.assertEqual('ascii', self.s.cssRules[0].encoding) |
287 |
|
288 |
self.s.encoding = None |
289 |
self.assertEqual('utf-8', self.s.encoding) |
290 |
self.assertEqual(0, self.s.cssRules.length) |
291 |
|
292 |
self.s.encoding = 'UTF-8' |
293 |
self.assertEqual('utf-8', self.s.encoding) |
294 |
self.assertEqual(1, self.s.cssRules.length) |
295 |
|
296 |
self.assertRaises(xml.dom.SyntaxErr, self.s._setEncoding, |
297 |
'INVALID ENCODING')
|
298 |
self.assertEqual('utf-8', self.s.encoding) |
299 |
self.assertEqual(1, self.s.cssRules.length) |
300 |
|
301 |
def test_namespaces1(self): |
302 |
"CSSStyleSheet.namespaces.namespaces"
|
303 |
# tests for namespaces internal methods
|
304 |
s = cssutils.css.CSSStyleSheet() |
305 |
self.assertEqual(0, len(s.namespaces)) |
306 |
|
307 |
css = u'''@namespace "default";
|
308 |
@namespace ex "example";
|
309 |
@namespace ex2 "example";
|
310 |
ex2|x { top: 0 }'''
|
311 |
expcss = u'''@namespace "default";
|
312 |
@namespace ex2 "example";
|
313 |
ex2|x {
|
314 |
top: 0
|
315 |
}'''
|
316 |
s.cssText = css |
317 |
self.assertEqual(s.cssText, expcss.encode())
|
318 |
self.assertEqual(s.namespaces.namespaces,
|
319 |
{ u'': u'default', u'ex2': u'example'}) |
320 |
|
321 |
# __contains__
|
322 |
self.assertTrue('' in s.namespaces) |
323 |
self.assertTrue('ex2' in s.namespaces) |
324 |
self.assertFalse('NOTSET' in s.namespaces) |
325 |
# __delitem__
|
326 |
self.assertRaises(xml.dom.NoModificationAllowedErr,
|
327 |
s.namespaces.__delitem__, 'ex2')
|
328 |
s.namespaces['del'] = 'del' |
329 |
del s.namespaces['del'] |
330 |
self.assertRaises(xml.dom.NamespaceErr, s.namespaces.__getitem__, 'del') |
331 |
# __getitem__
|
332 |
self.assertEqual('default', s.namespaces['']) |
333 |
self.assertEqual('example', s.namespaces['ex2']) |
334 |
self.assertRaises(xml.dom.NamespaceErr, s.namespaces.__getitem__, 'UNSET') |
335 |
# __iter__
|
336 |
self.assertEqual(['', 'ex2'], sorted(list(s.namespaces))) |
337 |
# __len__
|
338 |
self.assertEqual(2, len(s.namespaces)) |
339 |
# __setitem__
|
340 |
self.assertRaises(xml.dom.NoModificationAllowedErr,
|
341 |
s.namespaces.__setitem__, 'ex2', 'NEWURI') |
342 |
s.namespaces['n1'] = 'new' |
343 |
self.assertEqual(s.namespaces.namespaces,
|
344 |
{ u'': u'default', u'ex2': u'example', u'n1': 'new'}) |
345 |
s.namespaces['n'] = 'new' # replaces prefix! |
346 |
self.assertEqual(s.namespaces.namespaces,
|
347 |
{ u'': u'default', u'ex2': u'example', u'n': 'new'}) |
348 |
# prefixForNamespaceURI
|
349 |
self.assertEqual('', s.namespaces.prefixForNamespaceURI('default')) |
350 |
self.assertEqual('ex2', s.namespaces.prefixForNamespaceURI('example')) |
351 |
self.assertRaises(IndexError, |
352 |
s.namespaces.prefixForNamespaceURI, 'UNSET')
|
353 |
# .keys
|
354 |
self.assertEqual(set(s.namespaces.keys()), set(['', 'ex2', 'n'])) |
355 |
# .get
|
356 |
self.assertEqual('x', s.namespaces.get('UNKNOWN', 'x')) |
357 |
self.assertEqual('example', s.namespaces.get('ex2', 'not used defa')) |
358 |
|
359 |
def test_namespaces2(self): |
360 |
"CSSStyleSheet.namespaces"
|
361 |
# tests using CSSStyleSheet.namespaces
|
362 |
|
363 |
s = cssutils.css.CSSStyleSheet() |
364 |
css = '@namespace n "new";'
|
365 |
# doubles will be removed
|
366 |
s.insertRule(css + css) |
367 |
self.assertEqual(s.cssText, css.encode())
|
368 |
r = cssutils.css.CSSNamespaceRule(prefix='ex2', namespaceURI='example') |
369 |
s.insertRule(r) |
370 |
r = cssutils.css.CSSNamespaceRule(namespaceURI='default')
|
371 |
s.insertRule(r) |
372 |
|
373 |
expcss = '''@namespace n "new";
|
374 |
@namespace ex2 "example";
|
375 |
@namespace "default";'''
|
376 |
self.assertEqual(s.cssText, expcss.encode())
|
377 |
r.prefix = 'DEFAULT'
|
378 |
expcss = '''@namespace n "new";
|
379 |
@namespace ex2 "example";
|
380 |
@namespace DEFAULT "default";'''
|
381 |
self.assertEqual(s.cssText, expcss.encode())
|
382 |
|
383 |
# CSSMediaRule
|
384 |
self.assertRaises(xml.dom.NamespaceErr, s.add, '@media all {x|a {left: 0}}') |
385 |
mcss = '@media all {\n ex2|SEL1 {\n left: 0\n }\n }'
|
386 |
s.add(mcss) |
387 |
expcss += '\n' + mcss
|
388 |
self.assertEqual(s.cssText, expcss.encode())
|
389 |
|
390 |
# CSSStyleRule
|
391 |
self.assertRaises(xml.dom.NamespaceErr, s.add, 'x|a {top: 0}') |
392 |
scss = 'n|SEL2 {\n top: 0\n }'
|
393 |
s.add(scss) |
394 |
expcss += '\n' + scss
|
395 |
self.assertEqual(s.cssText, expcss.encode())
|
396 |
|
397 |
mr = s.cssRules[3]
|
398 |
sr = s.cssRules[4]
|
399 |
|
400 |
# SelectorList @media
|
401 |
self.assertRaises(xml.dom.NamespaceErr,
|
402 |
mr.cssRules[0]._setSelectorText, 'x|b') |
403 |
oldsel, newsel = mr.cssRules[0].selectorText, 'n|SEL3, a' |
404 |
mr.cssRules[0].selectorText = newsel
|
405 |
expcss = expcss.replace(oldsel, newsel) |
406 |
self.assertEqual(s.cssText, expcss.encode())
|
407 |
# SelectorList stylerule
|
408 |
self.assertRaises(xml.dom.NamespaceErr,
|
409 |
sr._setSelectorText, 'x|b')
|
410 |
oldsel, newsel = sr.selectorText, 'ex2|SEL4, a'
|
411 |
sr.selectorText = newsel |
412 |
expcss = expcss.replace(oldsel, newsel) |
413 |
self.assertEqual(s.cssText, expcss.encode())
|
414 |
|
415 |
# Selector @media
|
416 |
self.assertRaises(xml.dom.NamespaceErr,
|
417 |
mr.cssRules[0].selectorList.append, 'x|b') |
418 |
oldsel, newsel = mr.cssRules[0].selectorText, 'ex2|SELMR' |
419 |
mr.cssRules[0].selectorList.append(newsel)
|
420 |
expcss = expcss.replace(oldsel, oldsel + ', ' + newsel)
|
421 |
self.assertEqual(s.cssText, expcss.encode())
|
422 |
# Selector stylerule
|
423 |
self.assertRaises(xml.dom.NamespaceErr,
|
424 |
sr.selectorList.append, 'x|b')
|
425 |
oldsel, newsel = sr.selectorText, 'ex2|SELSR'
|
426 |
sr.selectorList.append(newsel) |
427 |
expcss = expcss.replace(oldsel, oldsel + ', ' + newsel)
|
428 |
self.assertEqual(s.cssText, expcss.encode())
|
429 |
|
430 |
self.assertEqual(s.cssText, u'''@namespace n "new"; |
431 |
@namespace ex2 "example";
|
432 |
@namespace DEFAULT "default";
|
433 |
@media all {
|
434 |
n|SEL3, a, ex2|SELMR {
|
435 |
left: 0
|
436 |
}
|
437 |
}
|
438 |
ex2|SEL4, a, ex2|SELSR {
|
439 |
top: 0
|
440 |
}'''.encode())
|
441 |
|
442 |
def test_namespaces3(self): |
443 |
"CSSStyleSheet.namespaces 3"
|
444 |
# tests setting namespaces with new {}
|
445 |
s = cssutils.css.CSSStyleSheet() |
446 |
css = u'h|a { top: 0 }'
|
447 |
self.assertRaises(xml.dom.NamespaceErr, s.add, css)
|
448 |
|
449 |
s.add('@namespace x "html";')
|
450 |
self.assertTrue(s.namespaces['x'] == 'html') |
451 |
|
452 |
r = cssutils.css.CSSStyleRule() |
453 |
r.cssText = ((css, {'h': 'html'})) |
454 |
s.add(r) # uses x as set before! h is temporary only
|
455 |
self.assertEqual(s.cssText, '@namespace x "html";\nx|a {\n top: 0\n }'.encode()) |
456 |
|
457 |
# prefix is now "x"!
|
458 |
self.assertRaises(xml.dom.NamespaceErr, r.selectorList.append, 'h|b') |
459 |
self.assertRaises(xml.dom.NamespaceErr, r.selectorList.append, 'y|b') |
460 |
s.namespaces['y'] = 'html' |
461 |
r.selectorList.append('y|b')
|
462 |
self.assertEqual(s.cssText,
|
463 |
u'@namespace y "html";\ny|a, y|b {\n top: 0\n }'.encode())
|
464 |
|
465 |
self.assertRaises(xml.dom.NoModificationAllowedErr,
|
466 |
s.namespaces.__delitem__, 'y')
|
467 |
self.assertEqual(s.cssText,
|
468 |
u'@namespace y "html";\ny|a, y|b {\n top: 0\n }'.encode())
|
469 |
|
470 |
s.cssRules[0].prefix = '' |
471 |
self.assertEqual(s.cssText,
|
472 |
u'@namespace "html";\na, b {\n top: 0\n }'.encode())
|
473 |
|
474 |
# remove need of namespace
|
475 |
s.cssRules[0].prefix = 'x' |
476 |
s.cssRules[1].selectorText = 'a, b' |
477 |
self.assertEqual(s.cssText,
|
478 |
u'@namespace x "html";\na, b {\n top: 0\n }'.encode())
|
479 |
|
480 |
|
481 |
def test_namespaces4(self): |
482 |
"CSSStyleSheet.namespaces 4"
|
483 |
# tests setting namespaces with new {}
|
484 |
s = cssutils.css.CSSStyleSheet() |
485 |
self.assertEqual({}, s.namespaces.namespaces)
|
486 |
|
487 |
s.namespaces.namespaces['a'] = 'no setting possible' |
488 |
self.assertEqual({}, s.namespaces.namespaces)
|
489 |
|
490 |
s.namespaces[None] = 'default' |
491 |
self.assertEqual({u'': 'default'}, s.namespaces.namespaces) |
492 |
|
493 |
del s.namespaces[''] |
494 |
self.assertEqual({}, s.namespaces.namespaces)
|
495 |
|
496 |
s.namespaces[''] = 'default' |
497 |
self.assertEqual({u'': 'default'}, s.namespaces.namespaces) |
498 |
|
499 |
del s.namespaces[None] |
500 |
self.assertEqual({}, s.namespaces.namespaces)
|
501 |
|
502 |
s.namespaces['p'] = 'uri' |
503 |
# cannot use namespaces.namespaces
|
504 |
del s.namespaces.namespaces['p'] |
505 |
self.assertEqual({u'p': 'uri'}, s.namespaces.namespaces) |
506 |
|
507 |
self.assertRaisesMsg(xml.dom.NamespaceErr, u"Prefix undefined not found.", |
508 |
s.namespaces.__delitem__, 'undefined')
|
509 |
|
510 |
def test_namespaces5(self): |
511 |
"CSSStyleSheet.namespaces 5"
|
512 |
# unknown namespace
|
513 |
s = cssutils.parseString('a|a { color: red }')
|
514 |
self.assertEqual(s.cssText, ''.encode()) |
515 |
|
516 |
s = cssutils.css.CSSStyleSheet() |
517 |
self.assertRaisesMsg(xml.dom.NamespaceErr, "Prefix a not found.", |
518 |
s._setCssText, 'a|a { color: red }')
|
519 |
|
520 |
def test_deleteRuleIndex(self): |
521 |
"CSSStyleSheet.deleteRule(index)"
|
522 |
self.s.cssText = u'@charset "ascii"; @import "x"; @x; a {\n x: 1\n }@y;' |
523 |
self.assertEqual(5, self.s.cssRules.length) |
524 |
|
525 |
self.assertRaises(xml.dom.IndexSizeErr, self.s.deleteRule, 5) |
526 |
|
527 |
# end -1
|
528 |
# check parentStyleSheet
|
529 |
r = self.s.cssRules[-1] |
530 |
self.assertEqual(self.s, r.parentStyleSheet) |
531 |
self.s.deleteRule(-1) |
532 |
self.assertEqual(None, r.parentStyleSheet) |
533 |
|
534 |
self.assertEqual(4, self.s.cssRules.length) |
535 |
self.assertEqual(
|
536 |
u'@charset "ascii";\n@import "x";\n@x;\na {\n x: 1\n }'.encode(), self.s.cssText) |
537 |
# beginning
|
538 |
self.s.deleteRule(0) |
539 |
self.assertEqual(3, self.s.cssRules.length) |
540 |
self.assertEqual(u'@import "x";\n@x;\na {\n x: 1\n }'.encode(), self.s.cssText) |
541 |
# middle
|
542 |
self.s.deleteRule(1) |
543 |
self.assertEqual(2, self.s.cssRules.length) |
544 |
self.assertEqual(u'@import "x";\na {\n x: 1\n }'.encode(), self.s.cssText) |
545 |
# end
|
546 |
self.s.deleteRule(1) |
547 |
self.assertEqual(1, self.s.cssRules.length) |
548 |
self.assertEqual(u'@import "x";'.encode(), self.s.cssText) |
549 |
|
550 |
def test_deleteRule(self): |
551 |
"CSSStyleSheet.deleteRule(rule)"
|
552 |
s = cssutils.css.CSSStyleSheet() |
553 |
s.cssText='''
|
554 |
@namespace x "http://example.com";
|
555 |
a { color: red; }
|
556 |
b { color: blue; }
|
557 |
c { color: green; }
|
558 |
'''
|
559 |
n, s1, s2, s3 = s.cssRules |
560 |
|
561 |
r = cssutils.css.CSSStyleRule() |
562 |
self.assertRaises(xml.dom.IndexSizeErr, s.deleteRule, r)
|
563 |
|
564 |
self.assertEqual(4, s.cssRules.length) |
565 |
s.deleteRule(n) |
566 |
self.assertEqual(3, s.cssRules.length) |
567 |
self.assertEqual(s.cssText, 'a {\n color: red\n }\nb {\n color: blue\n }\nc {\n color: green\n }'.encode()) |
568 |
self.assertRaises(xml.dom.IndexSizeErr, s.deleteRule, n)
|
569 |
s.deleteRule(s2) |
570 |
self.assertEqual(2, s.cssRules.length) |
571 |
self.assertEqual(s.cssText, 'a {\n color: red\n }\nc {\n color: green\n }'.encode()) |
572 |
self.assertRaises(xml.dom.IndexSizeErr, s.deleteRule, s2)
|
573 |
|
574 |
def _gets(self): |
575 |
# complete
|
576 |
self.cr = cssutils.css.CSSCharsetRule('ascii') |
577 |
self.c = cssutils.css.CSSComment(u'/*c*/') |
578 |
self.ur = cssutils.css.CSSUnknownRule('@x;') |
579 |
self.ir = cssutils.css.CSSImportRule('x') |
580 |
self.nr = cssutils.css.CSSNamespaceRule('uri', 'p') |
581 |
self.mr = cssutils.css.CSSMediaRule()
|
582 |
self.mr.cssText = u'@media all { @m; }' |
583 |
self.pr = cssutils.css.CSSPageRule()
|
584 |
self.pr.style = u'margin: 0;' |
585 |
self.sr = cssutils.css.CSSStyleRule()
|
586 |
self.sr.cssText = 'a {\n x: 1\n }' |
587 |
|
588 |
s = cssutils.css.CSSStyleSheet() |
589 |
s.insertRule(self.cr) # 0 |
590 |
s.insertRule(self.ir) # 1 |
591 |
s.insertRule(self.nr) # 2 |
592 |
s.insertRule(self.mr) # 3 |
593 |
s.insertRule(self.sr) # 4 |
594 |
s.insertRule(self.mr) # 5 |
595 |
s.insertRule(self.pr) # 6 |
596 |
s.insertRule(self.sr) # 7 |
597 |
self.assertEqual(u'@charset "ascii";\n@import url(x);\n@namespace p "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 }'.encode(), s.cssText) |
598 |
return s, s.cssRules.length
|
599 |
|
600 |
def test_add(self): |
601 |
"CSSStyleSheet.add()"
|
602 |
full = cssutils.css.CSSStyleSheet() |
603 |
sheet = cssutils.css.CSSStyleSheet() |
604 |
css = ['@charset "ascii";',
|
605 |
'@import "x";',
|
606 |
'@namespace p "u";',
|
607 |
'@page {\n left: 0\n }',
|
608 |
'@font-face {\n src: local(x)\n }',
|
609 |
'@media all {\n a {\n color: red\n }\n }',
|
610 |
'a {\n color: green\n }',
|
611 |
'/*comment*/',
|
612 |
'@x;'
|
613 |
] |
614 |
|
615 |
fullcss = u'\n'.join(css)
|
616 |
full.cssText = fullcss |
617 |
self.assertEqual(full.cssText, fullcss.encode())
|
618 |
for i, line in enumerate(css): |
619 |
# sheet without same ruletype
|
620 |
before = css[:i] |
621 |
after = css[i+1:]
|
622 |
sheet.cssText = u''.join(before + after)
|
623 |
|
624 |
index = sheet.add(line) |
625 |
if i < 3: |
626 |
# specific insertion point
|
627 |
self.assertEqual(fullcss.encode(), sheet.cssText)
|
628 |
self.assertEqual(i, index)
|
629 |
else:
|
630 |
# end of sheet
|
631 |
expected = before |
632 |
expected.extend(after) |
633 |
expected.append(line) |
634 |
self.assertEqual(u'\n'.join(expected).encode(), sheet.cssText) |
635 |
self.assertEqual(len(expected)-1, index) # no same rule present |
636 |
|
637 |
# sheet with the same ruletype
|
638 |
if i == 1: line = '@import "x2";' |
639 |
if i == 2: line = '@namespace p2 "u2";' |
640 |
|
641 |
full.cssText = fullcss |
642 |
index = full.add(line) |
643 |
if i < 1: |
644 |
self.assertEqual(fullcss.encode(), sheet.cssText)
|
645 |
self.assertEqual(i, index) # no same rule present |
646 |
else:
|
647 |
if i < 3: |
648 |
# in order
|
649 |
expected = css[:i+1] # including same rule |
650 |
expected.append(line) |
651 |
expected.extend(css[i+1:])
|
652 |
expectedindex = i+1
|
653 |
else:
|
654 |
# just appended as no order needed
|
655 |
expected = css[:] |
656 |
expected.append(line) |
657 |
expectedindex = len(expected) - 1 |
658 |
|
659 |
self.assertEqual(u'\n'.join(expected).encode(), full.cssText) |
660 |
self.assertEqual(expectedindex, index) # no same rule present |
661 |
|
662 |
def test_addimport(self): |
663 |
p = cssutils.CSSParser(fetcher=lambda url: (None, '/**/')) |
664 |
|
665 |
cssrulessheet = p.parseString('@import "example.css";')
|
666 |
imports = ( |
667 |
'@import "example.css";', # string |
668 |
cssutils.css.CSSImportRule(href="example.css"), # CSSRule |
669 |
cssrulessheet.cssRules # CSSRuleList
|
670 |
) |
671 |
for imp in imports: |
672 |
sheet = p.parseString('', href='http://example.com') |
673 |
sheet.add(imp) |
674 |
added = sheet.cssRules[0]
|
675 |
self.assertEqual(sheet, added.parentStyleSheet)
|
676 |
self.assertEqual(u'example.css', added.href) |
677 |
self.assertEqual(u'utf-8', added.styleSheet.encoding) |
678 |
self.assertEqual(u'/**/'.encode(), added.styleSheet.cssText) |
679 |
|
680 |
cssrulessheet = p.parseString('@import "example.css";')
|
681 |
imports = ( |
682 |
('@import "example.css";', 'ascii'), # string |
683 |
(cssutils.css.CSSImportRule(href="example.css"), 'ascii'), # CSSRule |
684 |
# got encoding from old parent already
|
685 |
(cssrulessheet.cssRules, 'utf-8') # CSSRuleList |
686 |
) |
687 |
for imp, enc in imports: |
688 |
sheet = p.parseString('', href='http://example.com', encoding='ascii') |
689 |
sheet.add(imp) |
690 |
added = sheet.cssRules[1]
|
691 |
self.assertEqual(sheet, added.parentStyleSheet)
|
692 |
self.assertEqual(u'example.css', added.href) |
693 |
self.assertEqual(enc, added.styleSheet.encoding)
|
694 |
if enc == 'ascii': |
695 |
self.assertEqual(u'@charset "ascii";\n/**/'.encode(), added.styleSheet.cssText) |
696 |
else:
|
697 |
self.assertEqual(u'/**/'.encode(), added.styleSheet.cssText) |
698 |
|
699 |
# if styleSheet is already there encoding is not set new
|
700 |
impsheet = p.parseString('@import "example.css";')
|
701 |
imp = impsheet.cssRules[0]
|
702 |
sheet = p.parseString('', href='http://example.com', encoding='ascii') |
703 |
sheet.add(imp) |
704 |
added = sheet.cssRules[1]
|
705 |
self.assertEqual(sheet, added.parentStyleSheet)
|
706 |
self.assertEqual(u'example.css', added.href) |
707 |
self.assertEqual(u'utf-8', added.styleSheet.encoding) |
708 |
self.assertEqual(u'/**/'.encode(), added.styleSheet.cssText) |
709 |
|
710 |
def test_insertRule(self): |
711 |
"CSSStyleSheet.insertRule()"
|
712 |
s, L = self._gets()
|
713 |
|
714 |
# INVALID index
|
715 |
self.assertRaises(xml.dom.IndexSizeErr,
|
716 |
s.insertRule, self.sr, -1) |
717 |
self.assertRaises(xml.dom.IndexSizeErr,
|
718 |
s.insertRule, self.sr, s.cssRules.length + 1) |
719 |
# check if rule is really not in
|
720 |
self.assertEqual(L, s.cssRules.length)
|
721 |
|
722 |
# insert string
|
723 |
s.insertRule('a {}')
|
724 |
self.assertEqual(L+1, s.cssRules.length) |
725 |
# insert rule
|
726 |
s.insertRule(self.sr)
|
727 |
self.assertEqual(L+2, s.cssRules.length) |
728 |
# insert rulelist
|
729 |
s2, L2 = self._gets()
|
730 |
rulelist = s2.cssRules |
731 |
del rulelist[:-2] |
732 |
s.insertRule(rulelist) |
733 |
self.assertEqual(L+2 + 2, s.cssRules.length) |
734 |
|
735 |
def _insertRule(self, rules, notbefore, notafter, anywhere, |
736 |
checkdoubles=True):
|
737 |
"""
|
738 |
helper
|
739 |
test if any rule in rules cannot be inserted before rules in before
|
740 |
or after rules in after but before and after rules in anywhere
|
741 |
"""
|
742 |
for rule in rules: |
743 |
for r in notbefore: |
744 |
s = cssutils.css.CSSStyleSheet() |
745 |
s.insertRule(r) |
746 |
self.assertRaises(xml.dom.HierarchyRequestErr,
|
747 |
s.insertRule, rule, 0)
|
748 |
s = cssutils.css.CSSStyleSheet() |
749 |
s.add(r) |
750 |
self.assertRaises(xml.dom.HierarchyRequestErr,
|
751 |
s.insertRule, rule, 0)
|
752 |
for r in notafter: |
753 |
s = cssutils.css.CSSStyleSheet() |
754 |
s.insertRule(r) |
755 |
self.assertRaises(xml.dom.HierarchyRequestErr,
|
756 |
s.insertRule, rule, 1)
|
757 |
s = cssutils.css.CSSStyleSheet() |
758 |
s.add(r) |
759 |
s.add(rule) # never raises
|
760 |
self.assertEqual(s, r.parentStyleSheet)
|
761 |
|
762 |
for r in anywhere: |
763 |
s = cssutils.css.CSSStyleSheet() |
764 |
s.insertRule(r) |
765 |
s.insertRule(rule, 0) # before |
766 |
s.insertRule(rule) # after
|
767 |
if checkdoubles:
|
768 |
self.assertEqual(s.cssRules.length, 3) |
769 |
self.assertEqual(s, r.parentStyleSheet)
|
770 |
|
771 |
def test_insertRule_charset(self): |
772 |
"CSSStyleSheet.insertRule(@charset)"
|
773 |
s, L = self._gets()
|
774 |
notbefore = (self.cr,)
|
775 |
notafter = (self.cr, self.ir, self.nr, self.mr, self.pr, self.sr, |
776 |
self.c, self.ur) |
777 |
anywhere = () |
778 |
self._insertRule((self.cr,), |
779 |
notbefore, notafter, anywhere) |
780 |
|
781 |
def test_insertRule_import(self): |
782 |
"CSSStyleSheet.insertRule(@import)"
|
783 |
s, L = self._gets()
|
784 |
notbefore = (self.cr,)
|
785 |
notafter = (self.nr, self.pr, self.mr, self.sr) |
786 |
anywhere = (self.c, self.ur, self.ir) |
787 |
self._insertRule((self.ir,), |
788 |
notbefore, notafter, anywhere) |
789 |
|
790 |
def test_insertRule_namespace(self): |
791 |
"CSSStyleSheet.insertRule(@namespace)"
|
792 |
s, L = self._gets()
|
793 |
notbefore = (self.cr, self.ir) |
794 |
notafter = (self.pr, self.mr, self.sr) |
795 |
anywhere = (self.c, self.ur, self.nr) |
796 |
self._insertRule((self.nr,), notbefore, notafter, anywhere, |
797 |
checkdoubles=False)
|
798 |
|
799 |
def test_insertRule_media_page_style(self): |
800 |
"CSSStyleSheet.insertRule(@media, @page, stylerule)"
|
801 |
s, L = self._gets()
|
802 |
notbefore = (self.cr, self.ir, self.nr) |
803 |
notafter = () |
804 |
anywhere = (self.c, self.ur, self.mr, self.pr, self.sr) |
805 |
self._insertRule((self.pr, self.mr, self.sr), |
806 |
notbefore, notafter, anywhere) |
807 |
|
808 |
def test_insertRule_unknownandcomment(self): |
809 |
"CSSStyleSheet.insertRule(@ unknown, comment)"
|
810 |
s, L = self._gets()
|
811 |
notbefore = (self.cr,)
|
812 |
notafter = () |
813 |
anywhere = (self.c, self.ur, self.ir, self.nr, self.mr, self.pr, |
814 |
self.sr)
|
815 |
self._insertRule((self.ur,), |
816 |
notbefore, notafter, anywhere) |
817 |
|
818 |
def test_HTMLComments(self): |
819 |
"CSSStyleSheet CDO CDC"
|
820 |
css = u'''body { color: red }
|
821 |
<!-- comment -->
|
822 |
body { color: blue }
|
823 |
body { color: pink }
|
824 |
<!-- comment -->
|
825 |
body { color: green }
|
826 |
'''
|
827 |
exp = u'''body {
|
828 |
color: red
|
829 |
}
|
830 |
body {
|
831 |
color: pink
|
832 |
}'''
|
833 |
sheet = cssutils.parseString(css) |
834 |
self.assertEqual(sheet.cssText, exp.encode())
|
835 |
|
836 |
def test_incomplete(self): |
837 |
"CSSStyleRule (incomplete)"
|
838 |
tests = { |
839 |
u'@import "a': u'@import "a";', # no } |
840 |
u'a { x: 1': u'a {\n x: 1\n }', # no } |
841 |
u'a { font-family: "arial sans': # no " |
842 |
u'a {\n font-family: "arial sans"\n }',
|
843 |
} |
844 |
self.do_equal_p(tests) # parse |
845 |
|
846 |
def test_NoModificationAllowedErr(self): |
847 |
"CSSStyleSheet NoModificationAllowedErr"
|
848 |
css = cssutils.css.CSSStyleSheet(readonly=True)
|
849 |
|
850 |
self.assertEqual(True, css._readonly) # internal... |
851 |
|
852 |
self.assertRaises(xml.dom.NoModificationAllowedErr,
|
853 |
css._setCssText, u'@x;')
|
854 |
self.assertRaises(xml.dom.NoModificationAllowedErr,
|
855 |
css.insertRule, self.rule)
|
856 |
self.assertRaises(xml.dom.NoModificationAllowedErr,
|
857 |
css.insertRule, self.rule, 0) |
858 |
self.assertRaises(xml.dom.NoModificationAllowedErr,
|
859 |
css.deleteRule, 0)
|
860 |
|
861 |
def test_reprANDstr(self): |
862 |
"CSSStyleSheet.__repr__(), .__str__()"
|
863 |
href = 'file:foo.css'
|
864 |
title = 'title-of-css'
|
865 |
|
866 |
s = cssutils.css.CSSStyleSheet(href=href, title=title) |
867 |
|
868 |
self.assertTrue(href in str(s)) |
869 |
self.assertTrue(title in str(s)) |
870 |
|
871 |
s2 = eval(repr(s)) |
872 |
self.assertTrue(isinstance(s2, s.__class__)) |
873 |
self.assertTrue(href == s2.href)
|
874 |
self.assertTrue(title == s2.title)
|
875 |
|
876 |
|
877 |
if __name__ == '__main__': |
878 |
import unittest |
879 |
unittest.main() |