File: //usr/local/bin/python37_/lib64/python3.7/site-packages/cssutils/tests/test_cssmediarule.py
"""Testcases for cssutils.css.CSSMediaRule"""
# flake8: noqa
import xml.dom
from . import test_cssrule
import cssutils
import pytest
class TestCSSMediaRule(test_cssrule.TestCSSRule):
def _setup_rule(self):
self.r = cssutils.css.CSSMediaRule()
self.rRO = cssutils.css.CSSMediaRule(readonly=True)
self.r_type = cssutils.css.CSSMediaRule.MEDIA_RULE
self.r_typeString = 'MEDIA_RULE'
# for tests
self.stylerule = cssutils.css.CSSStyleRule()
self.stylerule.cssText = 'a {}'
def test_init(self):
"CSSMediaRule.__init__()"
super().test_init()
r = cssutils.css.CSSMediaRule()
assert isinstance(r.cssRules, cssutils.css.CSSRuleList)
assert [] == r.cssRules
assert '' == r.cssText
assert isinstance(r.media, cssutils.stylesheets.MediaList)
assert 'all' == r.media.mediaText
assert r.name is None
r = cssutils.css.CSSMediaRule(mediaText='print', name='name')
assert isinstance(r.cssRules, cssutils.css.CSSRuleList)
assert [] == r.cssRules
assert '' == r.cssText
assert isinstance(r.media, cssutils.stylesheets.MediaList)
assert 'print' == r.media.mediaText
assert 'name' == r.name
# only possible to set @... similar name
with pytest.raises(xml.dom.InvalidModificationErr):
self.r._setAtkeyword('x')
def test_iter(self):
"CSSMediaRule.__iter__()"
m = cssutils.css.CSSMediaRule()
m.cssText = '''@media all { /*1*/a { left: 0} b{ top:0} }'''
types = [
cssutils.css.CSSRule.COMMENT,
cssutils.css.CSSRule.STYLE_RULE,
cssutils.css.CSSRule.STYLE_RULE,
]
for i, rule in enumerate(m):
assert rule == m.cssRules[i]
assert rule.type == types[i]
assert rule.parentRule == m
def test_refs(self):
"""CSSStylesheet references"""
s = cssutils.parseString('@media all {a {color: red}}')
r = s.cssRules[0]
rules = r.cssRules
assert r.cssRules[0].parentStyleSheet == s
assert rules[0].parentStyleSheet == s
# set cssText
r.cssText = '@media all {a {color: blue}}'
# not anymore: self.assertEqual(rules, r.cssRules)
# set cssRules
r.cssRules = cssutils.parseString(
'''
/**/
@x;
b {}').cssRules'''
).cssRules
# new object
assert rules != r.cssRules
for i, sr in enumerate(r.cssRules):
assert sr.parentStyleSheet == s
assert sr.parentRule == r
def test_cssRules(self):
"CSSMediaRule.cssRules"
r = cssutils.css.CSSMediaRule()
assert [] == r.cssRules
sr = cssutils.css.CSSStyleRule()
r.cssRules.append(sr)
assert [sr] == r.cssRules
ir = cssutils.css.CSSImportRule()
with pytest.raises(xml.dom.HierarchyRequestErr):
r.cssRules.append(ir)
s = cssutils.parseString('@media all { /*1*/a {x:1} }')
m = s.cssRules[0]
assert 2 == m.cssRules.length
del m.cssRules[0]
assert 1 == m.cssRules.length
m.cssRules.append('/*2*/')
assert 2 == m.cssRules.length
m.cssRules.extend(cssutils.parseString('/*3*/x {y:2}').cssRules)
assert 4 == m.cssRules.length
assert (
'@media all {\n a {\n x: 1\n }\n /*2*/\n /*3*/\n x {\n y: 2\n }\n }'
== m.cssText
)
for rule in m.cssRules:
assert rule.parentStyleSheet == s
assert rule.parentRule == m
def test_cssText(self):
"CSSMediaRule.cssText"
style = '''{
a {
color: red
}
}'''
mls = {
' (min-device-pixel-ratio: 1.3), (min-resolution: 1.3dppx) ': None,
' tv ': None,
' only tv ': None,
' not tv ': None,
' only tv and (color) ': None,
' only tv and(color)': ' only tv and (color) ',
' only tv and (color: red) ': None,
' only tv and (color: red) and (width: 100px) ': None,
' only tv and (color: red) and (width: 100px), tv ': None,
' only tv and (color: red) and (width: 100px), tv and (width: 20px) ': None,
' only tv and(color :red)and( width :100px ) ,tv and(width: 20px) ': ' only tv and (color: red) and (width: 100px), tv and (width: 20px) ',
' (color: red) and (width: 100px), (width: 20px) ': None,
' /*1*/ only /*2*/ tv /*3*/ and /*4*/ (/*5*/ width) /*5*/ /*6*/, (color) and (height) ': None,
'(color)and(width),(height)': ' (color) and (width), (height) ',
}
tests = {}
for b, a in list(mls.items()):
if a is None:
a = b
tests['@media{}{}'.format(b, style)] = '@media{}{}'.format(a, style)
self.do_equal_p(tests)
self.do_equal_r(tests)
tests = {
'@media only tv{}': '',
'@media not tv{}': '',
'@media only tv and (color){}': '',
'@media only tv and (color: red){}': '',
'@media only tv and (color: red) and (width: 100px){}': '',
'@media only tv and (color: red) and (width: 100px), tv{}': '',
'@media only tv and (color: red) and (width: 100px), tv and (width: 20px){}': '',
'@media (color: red) and (width: 100px), (width: 20px){}': '',
'@media (width){}': '',
'@media (width:10px){}': '',
'@media (width), (color){}': '',
'@media (width) , (color),(height){}': '',
'@media (width) , (color) and (height){}': '',
'@media (width) and (color){}': '',
'@media all and (width){}': '',
'@media all and (width:10px){}': '',
'@media all and (width), (color){}': '',
'@media all and (width) , (color),(height){}': '',
'@media all and (width) , (color) and (height){}': '',
'@media all and (width) and (color){}': '',
'@media only tv and (width){}': '',
'@media only tv and (width:10px){}': '',
'@media only tv and (width), (color){}': '',
'@media only tv and (width) , (color),(height){}': '',
'@media only tv and (width) , (color) and (height){}': '',
'@media only tv and (width) and (color){}': '',
'@media only tv and (width) "name" {}': '',
'@media only tv and (width:10px) "name" {}': '',
'@media only tv and (width), (color){}': '',
'@media only tv and (width) , (color),(height){}': '',
'@media only tv and (width) , (color) and (height){}': '',
'@media only tv and (width) and (color){}': '',
'@media all "name"{}': '',
'@media all {}': '',
'@media/*x*/all{}': '',
'@media all { a{ x: 1} }': '@media all {\n a {\n x: 1\n }\n }',
'@media all "name" { a{ x: 1} }': '@media all "name" {\n a {\n x: 1\n }\n }',
'@MEDIA all { a{x:1} }': '@media all {\n a {\n x: 1\n }\n }',
'@\\media all { a{x:1} }': '@media all {\n a {\n x: 1\n }\n }',
'@media all {@x some;a{color: red;}b{color: green;}}': '''@media all {
@x some;
a {
color: red
}
b {
color: green
}
}''',
'@media all { @x{}}': '@media all {\n @x {\n }\n }',
'@media all "n" /**/ { @x{}}': '@media all "n" /**/ {\n @x {\n }\n }',
# comments
'@media/*1*//*2*/all/*3*//*4*/{/*5*/a{x:1}}': '@media /*1*/ /*2*/ all /*3*/ /*4*/ {\n /*5*/\n a {\n x: 1\n }\n }',
'@media /*1*/ /*2*/ all /*3*/ /*4*/ { /*5*/ a{ x: 1} }': '@media /*1*/ /*2*/ all /*3*/ /*4*/ {\n /*5*/\n a {\n x: 1\n }\n }',
# WS
'@media\n\t\f all\n\t\f {\n\t\f a{ x: 1}\n\t\f }': '@media all {\n a {\n x: 1\n }\n }',
# @page rule inside @media
'@media all { @page { margin: 0; } }': '@media all {\n @page {\n margin: 0\n }\n }',
# nested media rules
'@media all { @media all { p { color: red; } } }': '@media all {\n @media all {\n p {\n '
'color: red\n }\n }\n }',
}
self.do_equal_p(tests)
self.do_equal_r(tests)
tests = {
'@media {}': xml.dom.SyntaxErr,
'@media;': xml.dom.SyntaxErr,
'@media/*only comment*/{}': xml.dom.SyntaxErr,
'@media all;': xml.dom.SyntaxErr,
'@media all "n";': xml.dom.SyntaxErr,
'@media all; @x{}': xml.dom.SyntaxErr,
'@media { a{ x: 1} }': xml.dom.SyntaxErr,
'@media "name" { a{ x: 1} }': xml.dom.SyntaxErr,
'@media "name" all { a{ x: 1} }': xml.dom.SyntaxErr,
'@media all { @charset "x"; a{}}': xml.dom.HierarchyRequestErr,
'@media all { @import "x"; a{}}': xml.dom.HierarchyRequestErr,
'@media all { , }': xml.dom.SyntaxErr,
'@media all {}EXTRA': xml.dom.SyntaxErr,
'@media ({}': xml.dom.SyntaxErr,
'@media (color{}': xml.dom.SyntaxErr,
'@media (color:{}': xml.dom.SyntaxErr,
'@media (color:red{}': xml.dom.SyntaxErr,
'@media (:red){}': xml.dom.SyntaxErr,
'@media (:){}': xml.dom.SyntaxErr,
'@media color:red){}': xml.dom.SyntaxErr,
}
self.do_raise_p(tests)
self.do_raise_r(tests)
tests = {
# extra stuff
'@media all { x{} } a{}': xml.dom.SyntaxErr,
}
self.do_raise_r(tests)
m = cssutils.css.CSSMediaRule()
m.cssText = '''@media all {@x; /*1*/a{color: red;}}'''
for r in m.cssRules:
assert m == r.parentRule
assert m.parentStyleSheet == r.parentStyleSheet
cssutils.ser.prefs.useDefaults()
def test_media(self):
"CSSMediaRule.media"
# see CSSImportRule.media
# setting not allowed
with pytest.raises(AttributeError):
self.r.__setattr__('media', None)
with pytest.raises(AttributeError):
self.r.__setattr__('media', 0)
# set mediaText instead
self.r.media.mediaText = 'print'
self.r.insertRule(self.stylerule)
assert '' == self.r.cssText
cssutils.ser.prefs.keepEmptyRules = True
assert '@media print {\n a {}\n }' == self.r.cssText
cssutils.ser.prefs.useDefaults()
def test_name(self):
"CSSMediaRule.name"
r = cssutils.css.CSSMediaRule()
r.cssText = '@media all "\\n\\"ame" {a{left: 0}}'
assert '\\n"ame' == r.name
r.name = "n"
assert 'n' == r.name
assert (
'@media all "n" {\n a {\n left: 0\n }\n }' == r.cssText
)
r.name = '"'
assert '"' == r.name
assert (
'@media all "\\"" {\n a {\n left: 0\n }\n }'
== r.cssText
)
r.name = ''
assert r.name is None
assert '@media all {\n a {\n left: 0\n }\n }' == r.cssText
r.name = None
assert r.name is None
assert '@media all {\n a {\n left: 0\n }\n }' == r.cssText
with pytest.raises(xml.dom.SyntaxErr):
r._setName(0)
with pytest.raises(xml.dom.SyntaxErr):
r._setName(123)
def test_deleteRuleIndex(self):
"CSSMediaRule.deleteRule(index)"
# see CSSStyleSheet.deleteRule
m = cssutils.css.CSSMediaRule()
m.cssText = '''@media all {
@a;
/* x */
@b;
@c;
@d;
}'''
assert 5 == m.cssRules.length
with pytest.raises(xml.dom.IndexSizeErr):
m.deleteRule(5)
# end -1
# check parentRule
r = m.cssRules[-1]
assert m == r.parentRule
m.deleteRule(-1)
assert r.parentRule is None
assert 4 == m.cssRules.length
assert (
'@media all {\n @a;\n /* x */\n @b;\n @c;\n }' == m.cssText
)
# beginning
m.deleteRule(0)
assert 3 == m.cssRules.length
assert '@media all {\n /* x */\n @b;\n @c;\n }' == m.cssText
# middle
m.deleteRule(1)
assert 2 == m.cssRules.length
assert '@media all {\n /* x */\n @c;\n }' == m.cssText
# end
m.deleteRule(1)
assert 1 == m.cssRules.length
assert '@media all {\n /* x */\n }' == m.cssText
def test_deleteRule(self):
"CSSMediaRule.deleteRule(rule)"
m = cssutils.css.CSSMediaRule()
m.cssText = '''@media all {
a { color: red; }
b { color: blue; }
c { color: green; }
}'''
s1, s2, s3 = m.cssRules
r = cssutils.css.CSSStyleRule()
with pytest.raises(xml.dom.IndexSizeErr):
m.deleteRule(r)
assert 3 == m.cssRules.length
m.deleteRule(s2)
assert 2 == m.cssRules.length
assert (
m.cssText
== '@media all {\n a {\n color: red\n }\n c {\n color: green\n }\n }'
)
with pytest.raises(xml.dom.IndexSizeErr):
m.deleteRule(s2)
def test_add(self):
"CSSMediaRule.add()"
# see CSSStyleSheet.add
r = cssutils.css.CSSMediaRule()
stylerule1 = cssutils.css.CSSStyleRule()
stylerule2 = cssutils.css.CSSStyleRule()
r.add(stylerule1)
r.add(stylerule2)
assert r.cssRules[0] == stylerule1
assert r.cssRules[1] == stylerule2
def test_insertRule(self):
"CSSMediaRule.insertRule"
# see CSSStyleSheet.insertRule
r = cssutils.css.CSSMediaRule()
charsetrule = cssutils.css.CSSCharsetRule('ascii')
importrule = cssutils.css.CSSImportRule('x')
namespacerule = cssutils.css.CSSNamespaceRule()
unknownrule = cssutils.css.CSSUnknownRule('@x;')
stylerule = cssutils.css.CSSStyleRule('a')
stylerule.cssText = 'a { x: 1}'
comment1 = cssutils.css.CSSComment('/*1*/')
comment2 = cssutils.css.CSSComment('/*2*/')
# hierarchy
with pytest.raises(xml.dom.HierarchyRequestErr):
r.insertRule(charsetrule, 0)
with pytest.raises(xml.dom.HierarchyRequestErr):
r.insertRule(importrule, 0)
with pytest.raises(xml.dom.HierarchyRequestErr):
r.insertRule(namespacerule, 0)
# start insert
r.insertRule(stylerule, 0)
assert r == stylerule.parentRule
assert r.parentStyleSheet == stylerule.parentStyleSheet
# before
r.insertRule(comment1, 0)
assert r == comment1.parentRule
assert r.parentStyleSheet == stylerule.parentStyleSheet
# end explicit
r.insertRule(unknownrule, 2)
assert r == unknownrule.parentRule
assert r.parentStyleSheet == stylerule.parentStyleSheet
# end implicit
r.insertRule(comment2)
assert r == comment2.parentRule
assert r.parentStyleSheet == stylerule.parentStyleSheet
assert (
'@media all {\n /*1*/\n a {\n x: 1\n }\n @x;\n /*2*/\n }'
== r.cssText
)
# index
with pytest.raises(xml.dom.IndexSizeErr):
r.insertRule(stylerule, -1)
with pytest.raises(xml.dom.IndexSizeErr):
r.insertRule(stylerule, r.cssRules.length + 1)
def test_InvalidModificationErr(self):
"CSSMediaRule.cssText InvalidModificationErr"
self._test_InvalidModificationErr('@media')
def test_incomplete(self):
"CSSMediaRule (incomplete)"
tests = {
'@media all { @unknown;': '@media all {\n @unknown;\n }', # no }
'@media all { a {x:"1"}': '@media all {\n a {\n x: "1"\n }\n }', # no }
'@media all { a {x:"1"': '@media all {\n a {\n x: "1"\n }\n }', # no }}
'@media all { a {x:"1': '@media all {\n a {\n x: "1"\n }\n }', # no "}}
}
self.do_equal_p(tests) # parse
def test_reprANDstr(self):
"CSSMediaRule.__repr__(), .__str__()"
mediaText = 'tv, print'
s = cssutils.css.CSSMediaRule(mediaText=mediaText)
assert mediaText in str(s)
s2 = eval(repr(s))
assert isinstance(s2, s.__class__)
assert mediaText == s2.media.mediaText