summaryrefslogtreecommitdiffstats
path: root/share/extensions/tests/test_inkex_styles.py
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:29:01 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:29:01 +0000
commit35a96bde514a8897f6f0fcc41c5833bf63df2e2a (patch)
tree657d15a03cc46bd099fc2c6546a7a4ad43815d9f /share/extensions/tests/test_inkex_styles.py
parentInitial commit. (diff)
downloadinkscape-upstream.tar.xz
inkscape-upstream.zip
Adding upstream version 1.0.2.upstream/1.0.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'share/extensions/tests/test_inkex_styles.py')
-rw-r--r--share/extensions/tests/test_inkex_styles.py229
1 files changed, 229 insertions, 0 deletions
diff --git a/share/extensions/tests/test_inkex_styles.py b/share/extensions/tests/test_inkex_styles.py
new file mode 100644
index 0000000..224be2c
--- /dev/null
+++ b/share/extensions/tests/test_inkex_styles.py
@@ -0,0 +1,229 @@
+# coding=utf-8
+"""
+Test Inkex style parsing functionality.
+"""
+
+import pytest
+
+from inkex.styles import Style
+from inkex.colors import Color
+from inkex.tester import TestCase
+from inkex.tester.svg import svg_file
+
+class StyleTest(TestCase):
+ """Test path API and calculations"""
+
+ def test_new_style(self):
+ """Create a style from a path string"""
+ stl = Style("border-color: blue; border-width: 4px;")
+ self.assertEqual(str(stl), 'border-color:blue;border-width:4px')
+
+ def test_composite(self):
+ """Test chaining styles together"""
+ stl = Style("border-color: blue;")
+ stl += "border-color: red; border-issues: true;"
+ self.assertEqual(str(stl), 'border-color:red;border-issues:true')
+ st2 = stl + "border-issues: false;"
+ self.assertEqual(str(st2), 'border-color:red;border-issues:false')
+
+ def test_inbuilts(self):
+ """Test inbuild style functions"""
+ stadd = Style("a: 1") + Style("b: 2")
+ self.assertTrue(stadd == Style("b: 2; a: 1"))
+ self.assertFalse(stadd == Style("b: 2"))
+ self.assertFalse(stadd != Style("b: 2; a: 1"))
+ self.assertEqual(stadd - "a: 4", "b: 2")
+ stadd -= "b: 3; c: 4"
+ self.assertEqual(stadd, Style("a: 1"))
+
+ def test_set_property(self):
+ """Set the style attribute directly"""
+ stl = Style()
+ stl['border-pain'] = 'green'
+ self.assertEqual(str(stl), 'border-pain:green')
+
+ def test_color_property(self):
+ """Color special handling"""
+ stl = Style("fill-opacity:0.7;fill:red;")
+ self.assertEqual(stl.get_color('fill').alpha, 0.7)
+ self.assertEqual(str(stl.get_color('fill')), 'rgba(255, 0, 0, 0.7)')
+ stl.set_color('rgba(0, 127, 0, 0.5)', 'stroke')
+ self.assertEqual(str(stl), 'fill-opacity:0.7;fill:red;stroke-opacity:0.5;stroke:#007f00')
+
+ def test_interpolate(self):
+ """Test interpolation method."""
+ stl1 = Style({'stroke-width':'0px', 'fill-opacity':1.0,'fill':Color((200, 0, 0))})
+ stl2 = Style({'stroke-width':'1pc', 'fill-opacity':0.0,'fill':Color((100, 0, 100))})
+ stl3 = stl1.interpolate(stl2, 0.5)
+ assert stl3['fill-opacity'] == pytest.approx(0.5, 1e-3)
+ assert stl3['fill'] == [150, 0, 50]
+ assert stl3['stroke-width'] == '8px'
+
+class AttribFallbackTest(TestCase):
+ """Test the fallback style for handling attribute based styles"""
+ def setUp(self):
+ self.svg = svg_file(self.data_file('svg', 'css.svg'))
+ self.elem = self.svg.getElementById('rect2')
+
+ def test_fallback_read_style(self):
+ """Style comes from style property"""
+ self.elem.style['fill'] = 'green'
+ self.elem.set('fill', 'red')
+ self.assertEqual(self.elem.fallback_style()['fill'], 'green')
+
+ def test_fallback_read_attrib(self):
+ """Style comes from attribute"""
+ self.elem.style.pop('stroke', None)
+ self.assertEqual(self.elem.fallback_style()['stroke'], None)
+ self.elem.set('stroke', 'green')
+ self.assertEqual(self.elem.fallback_style()['stroke'], 'green')
+
+ def test_fallback_read_css(self):
+ """Style from basic css will work"""
+ elem = self.svg.getElementById('rect1')
+ self.assertEqual(elem.fallback_style()['fill'], 'blue')
+
+ def test_fallback_write_style(self):
+ """Styles are set back correctly"""
+ self.elem.style['fill'] = 'green'
+ self.elem.set('fill', 'red')
+ self.elem.fallback_style()['fill'] = 'blue'
+ self.assertEqual(self.elem.style['fill'], 'blue')
+ self.assertEqual(self.elem.get('fill'), None) # Removed
+
+ def test_fallback_write_attrib(self):
+ """Attrib is written back when needed"""
+ self.elem.style.pop('stroke', None)
+ self.elem.set('stroke', 'green')
+ self.elem.fallback_style()['stroke'] = 'blue'
+ self.assertEqual(self.elem.style.get('stroke', None), None) # Still empty
+ self.assertEqual(self.elem.get('stroke'), 'blue')
+
+ def test_fallback_write_move(self):
+ """Style is moved when required"""
+ self.elem.style.pop('stroke', None)
+ self.elem.set('stroke', 'green')
+ self.elem.fallback_style(move=True)['stroke'] = 'blue'
+ self.assertEqual(self.elem.style['stroke'], 'blue')
+ self.assertEqual(self.elem.get('stroke'), None) # Moved
+
+ def test_fallback_write_css(self):
+ """Style can be set into the stylesheet style"""
+ elem = self.svg.getElementById('rect1')
+ elem.fallback_style()['fill'] = 'green'
+ self.assertIn('#rect1 {\n fill:green;\n}', self.svg.getElementById('style1').text)
+ elem.fallback_style()['fill'] = 'red'
+ self.assertIn('#rect1 {\n fill:red;\n}', self.svg.getElementById('style1').text)
+
+ def test_no_attr(self):
+ """Given name doesn't exist anywhere"""
+ self.elem.style = 'fill:red'
+ style = self.elem.fallback_style()
+ self.assertEqual(style.get('fill'), 'red')
+ self.assertEqual(style.get('jump'), None)
+
+class StyleSheetTest(TestCase):
+ """Test parsing style sheets"""
+ def setUp(self):
+ super(StyleSheetTest, self).setUp()
+ self.svg = svg_file(self.data_file('svg', 'css.svg'))
+ self.css = self.svg.stylesheet
+
+ def test_classes(self):
+ """Test element class manipulation"""
+ rect = self.svg.getElementById('rect2')
+ self.assertEqual(rect.get('class'), 'two')
+ self.assertEqual(rect.classes, ['two'])
+ rect.classes[0] = 'twa'
+ self.assertEqual(rect.get('class'), 'twa')
+ rect.classes.append('tri')
+ rect.classes.append('four')
+ self.assertEqual(rect.get('class'), 'twa tri four')
+ rect.classes.remove('twa')
+ self.assertEqual(rect.get('class'), 'tri four')
+ rect.classes.toggle('toggle')
+ self.assertEqual(rect.get('class'), 'tri four toggle')
+ rect.classes.toggle('toggle')
+ self.assertEqual(rect.get('class'), 'tri four')
+
+ def test_creation(self):
+ """Stylesheet is created when needed"""
+ self.svg = svg_file(self.data_file('svg', 'empty.svg'))
+ self.assertEqual(len(self.svg.stylesheets), 0)
+ self.assertEqual(len(self.svg.stylesheet), 0)
+ self.assertEqual(len(self.svg.stylesheets), 1)
+ self.svg.stylesheet.append('.cls1 { fill: blue; }')
+ self.assertIn(b'style><![CDATA[\n.cls1 {\n fill:blue;\n}\n]]><', self.svg.tostring())
+
+ def test_parsing(self):
+ """SVG parsing provides access to stylesheets"""
+ sheets = self.svg.stylesheets
+ self.assertEqual(len(sheets), 3)
+ self.assertEqual(len(sheets[0]), 7)
+ self.assertEqual(len(sheets[1]), 0)
+ self.assertEqual(len(sheets[2]), 2)
+
+ def test_string(self):
+ """Rendered to a string"""
+ sheets = self.svg.stylesheets
+ self.assertEqual(str(sheets[0][0]), '#layer1 {\n stroke:yellow;\n}')
+ self.assertEqual(str(sheets[2][1]), '.rule {}')
+
+ def test_lookup_by_id(self):
+ """ID CSS lookup"""
+ self.assertEqual(self.css[0].to_xpath(), "//*[@id='layer1']")
+ elem = self.svg.getElement(self.css[0].to_xpath())
+ self.assertEqual(elem.get('id'), 'layer1')
+
+ def test_lookup_by_element(self):
+ """Element name CSS lookup"""
+ self.assertEqual(self.css[1].to_xpath(), "//svg:circle")
+ elems = list(self.svg.xpath(self.css[1].to_xpath()))
+ self.assertEqual(len(elems), 2)
+ self.assertEqual(elems[0].get('id'), 'circle1')
+ self.assertEqual(elems[1].get('id'), 'circle2')
+
+ def test_lookup_by_class(self):
+ """Class name CSS lookup"""
+ self.assertEqual(self.css[2].to_xpath(),\
+ "//*[contains(concat(' ', normalize-space(@class), ' '), ' two ')]")
+ elem = self.svg.getElement(self.css[2].to_xpath())
+ self.assertEqual(elem.get('id'), 'rect2')
+
+ def test_lookup_and(self):
+ """Multiple CSS lookups"""
+ self.assertEqual(self.css[3].to_xpath(), "//*[@id='rect3']"\
+ "[contains(concat(' ', normalize-space(@class), ' '), ' three ')]")
+ elem = self.svg.getElement(self.css[3].to_xpath())
+ self.assertEqual(elem.get('id'), 'rect3')
+
+ def test_lookup_or(self):
+ """SVG rules can look up the right elements"""
+ self.assertEqual(self.css[6].to_xpath(), "//*[@id='circle1']|//*[@id='circle2']|"\
+ "//*[contains(concat(' ', normalize-space(@class), ' '), ' two ')]")
+ elems = self.svg.xpath(self.css[6].to_xpath())
+ self.assertEqual(len(elems), 3)
+ self.assertEqual(elems[0].get('id'), 'rect2')
+ self.assertEqual(elems[1].get('id'), 'circle1')
+ self.assertEqual(elems[2].get('id'), 'circle2')
+
+ def test_applied_styles(self):
+ """Are styles applied to the svg elements correctly"""
+ self.assertEqual(
+ str(self.svg.getElementById('rect1').cascaded_style()),
+ 'fill:blue')
+ self.assertEqual(
+ str(self.svg.getElementById('rect2').cascaded_style()),
+ 'fill:green;font:Homie')
+ self.assertEqual(
+ str(self.svg.getElementById('rect3').cascaded_style()),
+ 'fill:cyan')
+ self.assertEqual(
+ str(self.svg.getElementById('rect4').cascaded_style()),
+ 'fill:grey;stroke:red')
+ self.assertEqual(
+ str(self.svg.getElementById('circle1').cascaded_style()),
+ 'fill:red;font:Homie')
+ self.assertEqual(
+ str(self.svg.getElementById('circle2').cascaded_style()),
+ 'fill:red;font:Homie')