196 lines
6.9 KiB
Python
196 lines
6.9 KiB
Python
# coding=utf-8
|
|
|
|
import os, sys
|
|
|
|
import pytest
|
|
from image_extract import ExtractImage
|
|
from inkex.tester import ComparisonMixin, InkscapeExtensionTestMixin, TestCase
|
|
from inkex.tester.mock import Capture, MockCommandMixin
|
|
import inkex
|
|
|
|
|
|
class ExtractImageBasicTest(ComparisonMixin, InkscapeExtensionTestMixin, TestCase):
|
|
"""Comparison tests of ExtractImage"""
|
|
|
|
stderr_protect = False
|
|
effect_class = ExtractImage
|
|
compare_file = "svg/images.svg"
|
|
compare_file_extension = "png"
|
|
comparisons = [
|
|
("--selectedonly=False",),
|
|
("--selectedonly=True", "--id=embeded_image01"),
|
|
]
|
|
|
|
def test_all_comparisons(self):
|
|
"""Images are extracted to a file directory"""
|
|
for args in self.comparisons:
|
|
args += (f"--filepath={self.tempdir}/",)
|
|
self.assertCompare(self.compare_file, None, args, "embeded_image01.png")
|
|
|
|
|
|
class ExtractImageComponentTests(TestCase, MockCommandMixin):
|
|
"""Test some functions of ExtractImage"""
|
|
|
|
mocks = [(sys, "exit", lambda status: None)] # type:ignore
|
|
|
|
def test_extract_multiple(self):
|
|
"""test extraction in a multi-image file"""
|
|
args = [
|
|
self.data_file("svg", "images_multiple.svg"),
|
|
f"--directory={self.tempdir}/",
|
|
f"--output={self.tempdir}/out.svg",
|
|
"--selectedonly=True",
|
|
"--id=embedded_image01",
|
|
"--id=embedded_image02",
|
|
"--basename=image.jpg", # test that bad file extensions are corrected
|
|
"--linkextracted=false",
|
|
]
|
|
|
|
ext = ExtractImage()
|
|
|
|
def run_test(outexists):
|
|
with Capture("stderr") as stderr:
|
|
ext.run(args)
|
|
# There should be two images saved to the tempdir
|
|
self.assertListEqual(
|
|
sorted(os.listdir(self.tempdir)),
|
|
["image_1.png", "image_2.png"] + (["out.svg"] if outexists else []),
|
|
)
|
|
self.assertEqual(len(stderr.getvalue().split("extracted")), 3)
|
|
self.assertEqual(ext.errcount, 0)
|
|
|
|
# the out file only exists if it was changed, in this case, no change should
|
|
# be made
|
|
run_test(False)
|
|
for file in os.scandir(self.tempdir):
|
|
os.remove(file.path)
|
|
# We can do the same test again, because of linkextracted=False, the file is
|
|
# unchaged when running it on the output file.
|
|
args[-1] = "--linkextracted=true"
|
|
run_test(True)
|
|
|
|
# Now save all images again from the temp file, two images will raise an error
|
|
# because they are already embedded
|
|
|
|
# we also test that that relative target directories are interpreted relative to
|
|
# the input file stored in DOCUMENT_PATH (and not the actual input file name)
|
|
|
|
args[0] = f"{self.tempdir}/out.svg"
|
|
args[3] = "--selectedonly=False"
|
|
os.environ["DOCUMENT_PATH"] = os.path.abspath("images_multiple.svg")
|
|
args[1] = "--directory=" + os.path.relpath(self.tempdir, "images_multiple.svg")
|
|
|
|
with Capture("stderr") as stderr:
|
|
ext.run(args)
|
|
# There should be three images saved to the tempdir
|
|
self.assertListEqual(
|
|
sorted(os.listdir(self.tempdir)),
|
|
["image_1.png", "image_2.png", "image_3.png", "out.svg"],
|
|
)
|
|
self.assertEqual(len(stderr.getvalue().split("extracted")), 2)
|
|
self.assertEqual(len(stderr.getvalue().split("Unable")), 4)
|
|
self.assertEqual(ext.errcount, 3)
|
|
|
|
def test_extract_single_contextmenu(self):
|
|
"""test extraction in a multi-image file, called from the extensions menu,
|
|
but with only one selected image"""
|
|
args = [
|
|
self.data_file("svg", "images_multiple.svg"),
|
|
f"--directory={self.tempdir}/",
|
|
"--selectedonly=True",
|
|
"--id=embedded_image01",
|
|
"--basename=image",
|
|
]
|
|
ext = ExtractImage()
|
|
|
|
with Capture("stderr") as stderr:
|
|
ext.run(args)
|
|
|
|
self.assertListEqual(sorted(os.listdir(self.tempdir)), ["image.png"])
|
|
|
|
self.assertEqual(len(stderr.getvalue().split("extracted")), 2)
|
|
self.assertEqual(ext.errcount, 0)
|
|
|
|
@pytest.mark.skipif(sys.platform == "win32", reason="all directories writeable")
|
|
def test_extract_badpath(self):
|
|
"""Test writing to an unwriteable directory"""
|
|
|
|
args = [
|
|
self.data_file("svg", "images_multiple.svg"),
|
|
"--directory=/proc",
|
|
"--id=embedded_image01",
|
|
"--basename=image",
|
|
]
|
|
with Capture("stderr") as stderr:
|
|
ext = ExtractImage()
|
|
ext.run(args)
|
|
|
|
self.assertIn("Unable to write to", stderr.getvalue())
|
|
self.assertEqual(ext.errcount, 1)
|
|
|
|
args = [
|
|
self.data_file("svg", "images_multiple.svg"),
|
|
"--directory=/proc/test",
|
|
"--id=embedded_image01",
|
|
"--basename=image",
|
|
]
|
|
ext = ExtractImage()
|
|
|
|
with Capture("stderr") as stderr:
|
|
# The extension aborts
|
|
ext.run(args)
|
|
self.assertIn("Unable to create", stderr.getvalue())
|
|
|
|
def test_extract_badfilename(self):
|
|
"""Test writing to an unwriteable directory"""
|
|
|
|
if sys.platform == "win32":
|
|
filename = "<"
|
|
else:
|
|
filename = "a\x00" # null bytes are invalid
|
|
args = [
|
|
self.data_file("svg", "images_multiple.svg"),
|
|
"--directory=" + self.tempdir,
|
|
"--id=embedded_image01",
|
|
"--basename=" + filename,
|
|
]
|
|
with Capture("stderr") as stderr:
|
|
ext = ExtractImage()
|
|
|
|
if sys.version_info > (3, 8, 0) or filename == "<":
|
|
ext.run(args)
|
|
|
|
self.assertIn("Unable to write to", stderr.getvalue())
|
|
self.assertEqual(ext.errcount, 1)
|
|
else:
|
|
with self.assertRaises(ValueError) as __:
|
|
ext.run(args)
|
|
|
|
def test_extract_bad_data(self):
|
|
"""Extract bad data"""
|
|
|
|
svg = inkex.load_svg(self.data_file("svg", "images_multiple.svg")).getroot()
|
|
|
|
svg.getElementById("embedded_image01").set("xlink:href", "data:svg+xml;base64,")
|
|
svg.getElementById("embedded_image02").set(
|
|
"xlink:href", "data:image/abc;base32,"
|
|
)
|
|
|
|
temppath = os.path.join(self.tempdir, "temp.svg")
|
|
|
|
with open(temppath, "wb") as f:
|
|
f.write(svg.tostring())
|
|
args = [
|
|
self.data_file("svg", temppath),
|
|
"--directory=" + self.tempdir,
|
|
"--id=embedded_image01",
|
|
"--id=embedded_image02",
|
|
"--basename=badimage",
|
|
]
|
|
ext = ExtractImage()
|
|
with Capture("stderr") as stderr:
|
|
ext.run(args)
|
|
|
|
self.assertIn("Invalid image format", stderr.getvalue())
|
|
self.assertIn("encoding", stderr.getvalue())
|
|
self.assertEqual(ext.errcount, 2)
|