diff --git a/.coveragerc b/.coveragerc index 42c9476a4f0ae7db13a7c422f694e53be1073e08..33dd30c84ddd2e96a947121ac5aae698581cb32c 100644 --- a/.coveragerc +++ b/.coveragerc @@ -14,3 +14,10 @@ exclude_lines = pragma: no cover if __name__ == .__main__.: +[paths] +source = + ./ + C:\GitLab-Runner\builds\*\extensions + C:\GitLab-Runner\builds\*\*\extensions + C:\builds\*\extensions + /builds/*/extensions diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 674ebf97bde34c592a6d09995f97a9b22a5fc236..801d1ad4a5494e7667f6bba29631460627b11d7a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -21,13 +21,18 @@ variables: - .coverage-* - htmlcov +.shared-windows-runners: + tags: + - shared-windows + - windows + - windows-1809 test:python37: extends: .tests script: - source /root/pyenv-init - pyenv shell 3.7.2 - - tox -e py37-normal + - tox -e py37-normal-linux test:python38: @@ -35,21 +40,34 @@ test:python38: script: - source /root/pyenv-init - pyenv shell 3.8.0 - - tox -e py38-normal + - tox -e py38-normal-linux test:python39: extends: .tests script: - source /root/pyenv-init - pyenv shell 3.9.0 - - tox -e py39-normal + - tox -e py39-normal-linux + +test:python38-windows: + stage: test + extends: + - .shared-windows-runners + - .tests + script: + - choco install python --version 3.8.3 -y -f --no-progress + - $env:PATH += ";C:\\PYTHON38\\;C:\\PYTHON38\\Scripts" + - refreshenv + - "python -m pip install --upgrade setuptools" + - "python -m pip install --upgrade tox" + - "tox -e py38-normal-win" test:python310: extends: .tests script: - source /root/pyenv-init - pyenv shell 3.10.0 - - tox -e py310-normal + - tox -e py310-normal-linux test:coverage: stage: coverage @@ -57,6 +75,7 @@ test:coverage: - source /root/pyenv-init - pyenv shell 3.7.2 - pip install coverage + - ls -la | grep coverage - coverage3 combine .coverage-* - coverage3 report -m --precision=2 - coverage3 html --ignore-errors --title="Coverage for Inkscape Extensions (${CI_COMMIT_REF_NAME} branch)" @@ -72,6 +91,7 @@ test:coverage: - test:python38 - test:python39 - test:python310 + - test:python38-windows when: always coverage: '/TOTAL.+?(\d+.\d+%)/' artifacts: diff --git a/inkex/command.py b/inkex/command.py index f1fe260719a46cd0154152397d396c235bbad3ea..d2ff95876973ce7529247b6733be8886f71501ab 100644 --- a/inkex/command.py +++ b/inkex/command.py @@ -164,6 +164,9 @@ def to_args(prog, *positionals, **arguments): args += [to_arg(pos, oldie) for pos in positionals if pos is not None] # Filter out empty non-arguments return [arg for arg in args if arg is not None] +def to_args_sorted(prog, *positionals, **arguments): + """same as to_args, but keyword arguments are sorted beforehand""" + return to_args(prog, *positionals, **dict(sorted(arguments.items()))) def _call(program, *args, **kwargs): stdin = kwargs.pop('stdin', None) diff --git a/inkex/tester/filters.py b/inkex/tester/filters.py index c6703716dfeee76a69d4e9c40fa5efa706dedebb..1680350e13ee9e91830ed308892d37cf352fc8b6 100644 --- a/inkex/tester/filters.py +++ b/inkex/tester/filters.py @@ -60,7 +60,7 @@ class CompareNumericFuzzy(Compare): @staticmethod def filter(contents): func = lambda m: b'%.3f' % (float(m.group(0))) - contents = re.sub(br'\d+\.\d+', func, contents) + contents = re.sub(br'\d+\.\d+(e[+-]\d+)?', func, contents) contents = re.sub(br'(\d\.\d+?)0+\b', br'\1', contents) contents = re.sub(br'(\d)\.0+(?=\D|\b)', br'\1', contents) return contents @@ -138,3 +138,7 @@ class CompareReplacement(Compare): for _from, _to in self.deltas: contents = contents.replace(to_bytes(_from), to_bytes(_to)) return contents + +class WindowsTextCompat(CompareReplacement): + def __init__(self): + super().__init__(('\r\n', '\n')) \ No newline at end of file diff --git a/inkex/tester/mock.py b/inkex/tester/mock.py index c6507fe4e60bf6fb1e599b9274cb2e504ecac366..1655fad4450094b08c76e0c7e43612414c8de97b 100644 --- a/inkex/tester/mock.py +++ b/inkex/tester/mock.py @@ -174,12 +174,18 @@ class MockCommandMixin(MockMixin): def clean_paths(self, data, files): """Clean a string of any files or tempdirs""" + def replace(indata, replaced, replacement): + if isinstance(indata, str): + indata = indata.replace(replaced, replacement) + else: + indata = [i.replace(replaced, replacement) for i in indata] + return indata try: for fdir in self.recorded_tempdirs: - data = data.replace(fdir, '.') - files = [fname.replace(fdir, '.') for fname in files] + data = replace(data, fdir, '.') + files = replace(files, fdir, '.') for fname in files: - data = data.replace(fname, os.path.basename(fname)) + data = replace(data, fname, os.path.basename(fname)) except (UnicodeDecodeError, TypeError): pass return data @@ -205,7 +211,6 @@ class MockCommandMixin(MockMixin): if self and program and arglst: return os.environ.get('NO_MOCK_COMMANDS') return False - def mock_call(self, program, *args, **kwargs): """ Replacement for the inkex.command.call() function, instead of calling @@ -224,18 +229,20 @@ class MockCommandMixin(MockMixin): # may be modified to strip out filename directories (which change) inputs, outputs = self.add_call_files(msg, args, kwargs) - arglst = inkex.command.to_args(program, *args, **kwargs)[1:] - arglst.sort() + arglst = inkex.command.to_args_sorted(program, *args, **kwargs)[1:] + arglst = self.clean_paths(arglst, inputs + outputs) argstr = ' '.join(arglst) - argstr = self.clean_paths(argstr, inputs + outputs) msg['Arguments'] = argstr.strip() if stdin is not None: # The stdin is counted as the msg body - cleanin = self.clean_paths(stdin, inputs + outputs) + cleanin = self.clean_paths(stdin, inputs + outputs)\ + .replace("\r\n", "\n").replace(".\\", "./") msg.attach(MIMEText(cleanin, 'plain', 'utf-8')) keystr = msg.as_string() + # On Windows, output is separated by CRLF + keystr = keystr.replace('\r\n', '\n') # There is a difference between python2 and python3 output keystr = keystr.replace('\n\n', '\n') keystr = keystr.replace('\n ', ' ') @@ -273,7 +280,7 @@ class MockCommandMixin(MockMixin): self.save_key(program, key, keystr, 'bad-key') raise IOError(f"Problem loading call: {program}/{key} use the environment variable "\ "NO_MOCK_COMMANDS=1 to call out to the external program and generate "\ - "the mock call file.") + f"the mock call file for call {program} {argstr}.") def add_call_files(self, msg, args, kwargs): """ @@ -316,6 +323,12 @@ class MockCommandMixin(MockMixin): value = self.clean_paths(fhl.read().decode('utf8'), []) else: value = fhl.read() + try: + value = value.decode() + except UnicodeDecodeError: # do not attempt to process binary files further + pass + if isinstance(value, str): + value = value.replace('\r\n', '\n').replace(".\\", "./") part = MIMEApplication(value, Name=fname) # After the file is closed part['Content-Disposition'] = 'attachment' diff --git a/inkex/tester/xmldiff.py b/inkex/tester/xmldiff.py index a3197cfabd7eb03f23d65ea2e66d1cf608fab084..27d672663bfe1b18f45d72934e237f93cb128af4 100644 --- a/inkex/tester/xmldiff.py +++ b/inkex/tester/xmldiff.py @@ -41,7 +41,12 @@ class DeltaLogger(list): return [attr] + Path(val).to_arrays() return (attr, val) return val - self.append((_prep(value_a), _prep(value_b))) + # Only append a difference if the preprocessed values are different. + # This solves the issue that -0 != 0 in path data. + pa = _prep(value_a) + pb = _prep(value_b) + if pa != pb: + self.append((pa, pb)) def append_text(self, text_a, text_b): """Record a text difference""" diff --git a/tar_layers.py b/tar_layers.py index 09a1dfbd9b9264d88646dba90d2ac46c9d918822..a9ede3d619df050c9f0a5d8ea42dbdc663a7e47a 100755 --- a/tar_layers.py +++ b/tar_layers.py @@ -63,7 +63,10 @@ class TarLayers(inkex.OutputExtension): # Switch stdout to binary on Windows. if sys.platform == "win32": import msvcrt - msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) + try: + msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) + except io.UnsupportedOperation: + pass # The .fileno() function is not available during pytest runs template = self.make_template() diff --git a/tests/data/cmd/fig2dev/c15e8c5e5e50d45b2579ac22522b007e.msg b/tests/data/cmd/fig2dev/5d879c5bf2edd4bc478d8bef487538b9.msg similarity index 100% rename from tests/data/cmd/fig2dev/c15e8c5e5e50d45b2579ac22522b007e.msg rename to tests/data/cmd/fig2dev/5d879c5bf2edd4bc478d8bef487538b9.msg diff --git a/tests/data/cmd/gimp/6c0e5d2fbe380e26e310ebfc206d81ea.msg b/tests/data/cmd/gimp/a8418e80d6e849cc2e91b1baecbfada4.msg similarity index 100% rename from tests/data/cmd/gimp/6c0e5d2fbe380e26e310ebfc206d81ea.msg rename to tests/data/cmd/gimp/a8418e80d6e849cc2e91b1baecbfada4.msg diff --git a/tests/data/cmd/gimp/9de0e6f5cf782a299a1c062b5412dd63.msg b/tests/data/cmd/gimp/ba387a2bf0dfa5d22b061bfbe6fae05b.msg similarity index 100% rename from tests/data/cmd/gimp/9de0e6f5cf782a299a1c062b5412dd63.msg rename to tests/data/cmd/gimp/ba387a2bf0dfa5d22b061bfbe6fae05b.msg diff --git a/tests/data/cmd/gswin64c/7379fbc5c4f64c97c911b3e2695fdb8d.msg b/tests/data/cmd/gswin64c/c6b57b05e3a139d2172cab6307ebb2e4.msg similarity index 96% rename from tests/data/cmd/gswin64c/7379fbc5c4f64c97c911b3e2695fdb8d.msg rename to tests/data/cmd/gswin64c/c6b57b05e3a139d2172cab6307ebb2e4.msg index ed7676c87f314c54b8d9a5d1efc8aae258c01fdc..740011b7e2b82c1abe79ff727239cb596a2bf136 100644 --- a/tests/data/cmd/gswin64c/7379fbc5c4f64c97c911b3e2695fdb8d.msg +++ b/tests/data/cmd/gswin64c/c6b57b05e3a139d2172cab6307ebb2e4.msg @@ -1,7 +1,7 @@ Content-Type: multipart/mixed; boundary="--CALLDATA--//--CALLDATA--" MIME-Version: 1.0 Program: gswin64c -Arguments: -P- -dBATCH -dCompatibilityLevel#1.4 -dNOPAUSE -dSAFER -q -sDEVICE#pdfwrite -sOutputFile#.\output.pdf test.eps +Arguments: -q -P- -dSAFER -dNOPAUSE -dBATCH -sDEVICE#pdfwrite -dCompatibilityLevel#1.4 -sOutputFile#.\output.pdf test.eps ----CALLDATA--//--CALLDATA-- Content-Type: application/octet-stream; Name="output.pdf" diff --git a/tests/data/cmd/gswin64c/685cf0650d5e5573b3bc5bbeafbc2a7a.msg b/tests/data/cmd/gswin64c/f016f18bc5ee9c06cbf8bd0e05d54648.msg similarity index 96% rename from tests/data/cmd/gswin64c/685cf0650d5e5573b3bc5bbeafbc2a7a.msg rename to tests/data/cmd/gswin64c/f016f18bc5ee9c06cbf8bd0e05d54648.msg index 20063c0ea9822ac1e1f186248cd2ec0b77e92e51..78ab4eefc643824bb2fa5dab9d256e4f11b28bd3 100644 --- a/tests/data/cmd/gswin64c/685cf0650d5e5573b3bc5bbeafbc2a7a.msg +++ b/tests/data/cmd/gswin64c/f016f18bc5ee9c06cbf8bd0e05d54648.msg @@ -1,7 +1,7 @@ Content-Type: multipart/mixed; boundary="--CALLDATA--//--CALLDATA--" MIME-Version: 1.0 Program: gswin64c -Arguments: -P- -dBATCH -dCompatibilityLevel#1.4 -dNOPAUSE -dSAFER -q -sDEVICE#pdfwrite -sOutputFile#.\output.pdf test.ps +Arguments: -q -P- -dSAFER -dNOPAUSE -dBATCH -sDEVICE#pdfwrite -dCompatibilityLevel#1.4 -sOutputFile#.\output.pdf test.ps ----CALLDATA--//--CALLDATA-- Content-Type: application/octet-stream; Name="output.pdf" diff --git a/tests/data/cmd/inkscape/f863b882b18ffd8659b3c20cdd549266.msg b/tests/data/cmd/inkscape/1c734cd0171b9097039996e1bd63ed6f.msg similarity index 100% rename from tests/data/cmd/inkscape/f863b882b18ffd8659b3c20cdd549266.msg rename to tests/data/cmd/inkscape/1c734cd0171b9097039996e1bd63ed6f.msg diff --git a/tests/data/cmd/inkscape/818d4c30d07def36e80e32df12023124.msg b/tests/data/cmd/inkscape/21e5197995b5aa619151b61ebee79f23.msg similarity index 100% rename from tests/data/cmd/inkscape/818d4c30d07def36e80e32df12023124.msg rename to tests/data/cmd/inkscape/21e5197995b5aa619151b61ebee79f23.msg diff --git a/tests/data/cmd/inkscape/581055ce0e3ef5df0c1ab22982a51513.msg b/tests/data/cmd/inkscape/7f8bea1476711ae5f57b9d30111ec50b.msg similarity index 100% rename from tests/data/cmd/inkscape/581055ce0e3ef5df0c1ab22982a51513.msg rename to tests/data/cmd/inkscape/7f8bea1476711ae5f57b9d30111ec50b.msg diff --git a/tests/data/cmd/inkscape/c23825a5b83e906138ca8bff105b8b29.msg b/tests/data/cmd/inkscape/bf3e6cfcbb81940d4f7d667750681b0c.msg similarity index 100% rename from tests/data/cmd/inkscape/c23825a5b83e906138ca8bff105b8b29.msg rename to tests/data/cmd/inkscape/bf3e6cfcbb81940d4f7d667750681b0c.msg diff --git a/tests/data/cmd/scribus/b8a765f070200c63d022a696ac129e35.msg b/tests/data/cmd/scribus/cbaa8e934937d1d6b0355b525b5351e5.msg similarity index 100% rename from tests/data/cmd/scribus/b8a765f070200c63d022a696ac129e35.msg rename to tests/data/cmd/scribus/cbaa8e934937d1d6b0355b525b5351e5.msg diff --git a/tests/data/cmd/scribus/a5ed3ec8aa6d61652cb04fa27f921943.msg b/tests/data/cmd/scribus/e1f8033066a1e79d574f64111d5b92af.msg similarity index 100% rename from tests/data/cmd/scribus/a5ed3ec8aa6d61652cb04fa27f921943.msg rename to tests/data/cmd/scribus/e1f8033066a1e79d574f64111d5b92af.msg diff --git a/tests/test_color_list.py b/tests/test_color_list.py index 6f38e6ddf47a6c1b7a667ed5742c6d47bf20bfc9..c05f6469a7570031e7d45dcddd66d95ec61118d9 100644 --- a/tests/test_color_list.py +++ b/tests/test_color_list.py @@ -1,9 +1,11 @@ # coding=utf-8 from color_list import ListColours from .test_inkex_extensions import ColorEffectTest +from inkex.tester.filters import WindowsTextCompat class ColorListTest(ColorEffectTest): effect_class = ListColours effect_name = 'test_color_list' stderr_output = True + compare_filters = [WindowsTextCompat()] color_tests = [] diff --git a/tests/test_docinfo.py b/tests/test_docinfo.py index 1390d5b77cc46eac95924b63c215e2da795c1e7a..324b4b90f7ec151b360603b424f2ab5097d3c167 100644 --- a/tests/test_docinfo.py +++ b/tests/test_docinfo.py @@ -1,9 +1,11 @@ # coding=utf-8 from docinfo import DocInfo from inkex.tester import ComparisonMixin, TestCase +from inkex.tester.filters import WindowsTextCompat class TestDocInfo(ComparisonMixin, TestCase): compare_file = 'svg/guides.svg' effect_class = DocInfo stderr_output = True comparisons = [()] + compare_filters = [WindowsTextCompat()] \ No newline at end of file diff --git a/tests/test_dxf12_outlines.py b/tests/test_dxf12_outlines.py index e1bb05013865171e3c419d9a4f0205ecffd90b32..6bf8198334aadef31258326cd533e25ee9889836 100644 --- a/tests/test_dxf12_outlines.py +++ b/tests/test_dxf12_outlines.py @@ -1,10 +1,11 @@ # coding=utf-8 from dxf12_outlines import DxfTwelve from inkex.tester import ComparisonMixin, TestCase - +from inkex.tester.filters import WindowsTextCompat class TestDXF12OutlinesBasic(ComparisonMixin, TestCase): compare_file = ["svg/shapes.svg", "svg/preserved-transforms.svg", "svg/dxf_nested_transforms.svg"] comparisons = [()] - effect_class = DxfTwelve \ No newline at end of file + effect_class = DxfTwelve + compare_filters = [WindowsTextCompat()] \ No newline at end of file diff --git a/tests/test_dxf_outlines.py b/tests/test_dxf_outlines.py index 76a235097e45c41ee1248219fb2ef8a341eecca1..f830d23cd1673caf57283a46153933db5b1658c5 100644 --- a/tests/test_dxf_outlines.py +++ b/tests/test_dxf_outlines.py @@ -1,7 +1,7 @@ # coding=utf-8 from dxf_outlines import DxfOutlines from inkex.tester import ComparisonMixin, InkscapeExtensionTestMixin, TestCase - +from inkex.tester.filters import WindowsTextCompat class DFXOutlineBasicTest(ComparisonMixin, InkscapeExtensionTestMixin, TestCase): effect_class = DxfOutlines @@ -11,3 +11,4 @@ class DFXOutlineBasicTest(ComparisonMixin, InkscapeExtensionTestMixin, TestCase) ('--POLY=true',), ('--ROBO=true',), ] + compare_filters = [WindowsTextCompat()] diff --git a/tests/test_export_gimp_palette.py b/tests/test_export_gimp_palette.py index c322b313a98083fa879d9a7f1f86d7c8db3c1331..9f0c977219e88cbe517812e387ca30b0ec604dbe 100644 --- a/tests/test_export_gimp_palette.py +++ b/tests/test_export_gimp_palette.py @@ -1,7 +1,9 @@ # coding=utf-8 from export_gimp_palette import ExportGimpPalette from inkex.tester import ComparisonMixin, TestCase +from inkex.tester.filters import WindowsTextCompat class TestExportGplBasic(ComparisonMixin, TestCase): effect_class = ExportGimpPalette compare_file = 'svg/colors.svg' + compare_filters = [WindowsTextCompat()] \ No newline at end of file diff --git a/tests/test_ink2canvas_svg.py b/tests/test_ink2canvas_svg.py index d3e3270c7ea955c4879d6a65c06f9a9e9a5b3b69..3401db417dc0c4ff07eabc095b703e88b38f1d59 100644 --- a/tests/test_ink2canvas_svg.py +++ b/tests/test_ink2canvas_svg.py @@ -3,6 +3,7 @@ from ink2canvas import Html5Canvas from inkex.tester import ComparisonMixin, TestCase from inkex.tester.filters import CompareOrderIndependentLines +from inkex.tester.filters import WindowsTextCompat class Ink2CanvasBasicTest(ComparisonMixin, TestCase): effect_class = Html5Canvas @@ -21,4 +22,5 @@ class Ink2CanvasTestTextPath(ComparisonMixin, TestCase): class Ink2CanvasTestClosedPath(ComparisonMixin, TestCase): effect_class = Html5Canvas compare_file = 'svg/multiple_closed_subpaths.svg' - comparisons = [("--id=path31",)] \ No newline at end of file + comparisons = [("--id=path31",)] + compare_filters = [WindowsTextCompat()] \ No newline at end of file diff --git a/tests/test_inkex_base.py b/tests/test_inkex_base.py index 01fe619bd2d16ce700d79b7eadf6c01f80b9f3f3..44cacd33c63eacecea8154c915a2470bcf974e03 100644 --- a/tests/test_inkex_base.py +++ b/tests/test_inkex_base.py @@ -99,7 +99,7 @@ class InkscapeExtensionTest(TestCase): ext = ModExtension() os.environ['DOCUMENT_PATH'] = self.empty_svg self.assertEqual(ext.svg_path(), os.path.join(self.datadir(), 'svg')) - self.assertEqual(ext.absolute_href('/foo'), '/foo') + self.assertIn(ext.absolute_href('/foo'), ['/foo', "C:\\foo"]) self.assertEqual(ext.absolute_href('./foo'), os.path.join(self.datadir(), 'svg', 'foo')) self.assertEqual(ext.absolute_href('~/foo'), os.path.realpath(os.path.expanduser('~/foo'))) diff --git a/tests/test_inkex_command.py b/tests/test_inkex_command.py index dd60357ace1adb56c2054bcb31d8052e04bb80db..ed271a8f86b5199349a616350e48c410f16b79a4 100644 --- a/tests/test_inkex_command.py +++ b/tests/test_inkex_command.py @@ -2,12 +2,14 @@ """ Test Inkex command launching functionality. """ - +import pytest +import sys from inkex.tester import BaseCase from inkex.command import which, write_svg, to_arg, to_args, call, inkscape, inkscape_command, take_snapshot class CommandTest(BaseCase): """Test command API""" + @pytest.mark.skipif(sys.platform=="win32", reason="gunzip doesn't exist on windows") def test_binary_call(self): """Calls should allow binary stdin""" # https://gitlab.com/inkscape/extensions/-/commit/2e504f2a3f6bb627f17b267c5623a71005d7234d#note_164780678 diff --git a/tests/test_inkex_deprecated.py b/tests/test_inkex_deprecated.py index b569a7684975178f948e0886493810acbc3dcc23..546f158a1b7c9671133b59a45376a7b260dfd721 100644 --- a/tests/test_inkex_deprecated.py +++ b/tests/test_inkex_deprecated.py @@ -1,7 +1,7 @@ # coding=utf-8 """Test base inkex module functionality""" from __future__ import absolute_import, print_function, unicode_literals - +from pathlib import Path import warnings from inkex.deprecated import _deprecated @@ -32,5 +32,5 @@ class DeprecatedTests(TestCase): def test_traceback(self): """Traceback is possible for deprecation warnings""" warn = self.assertDeprecated(_deprecated, False, "BAR", stack=0, level=2) - self.assertIn("inkex/deprecated.py", str(warn.message)) + self.assertIn(str(Path("inkex") / "deprecated"), str(warn.message)) self.assertIn("test_inkex_deprecated.py", str(warn.message)) diff --git a/tests/test_jessyink_summary.py b/tests/test_jessyink_summary.py index 45c3a526648d39172add9dd14a61f702c07ef085..4a881dfa86a8643c928f4331c63bbc5ea0cf48f7 100644 --- a/tests/test_jessyink_summary.py +++ b/tests/test_jessyink_summary.py @@ -1,8 +1,10 @@ # coding=utf-8 from jessyink_summary import Summary from inkex.tester import ComparisonMixin, TestCase +from inkex.tester.filters import WindowsTextCompat class JessyInkSummaryTest(ComparisonMixin, TestCase): stderr_output = True effect_class = Summary comparisons = [()] + compare_filters = [WindowsTextCompat()] diff --git a/tests/test_plotter.py b/tests/test_plotter.py index 2d05ba365701bcf572bb066e5f229958579ffd12..d24a707268e7ab356a0cee106f7abf632bc2f2bf 100644 --- a/tests/test_plotter.py +++ b/tests/test_plotter.py @@ -1,8 +1,11 @@ """Test Plotter extension""" +import pytest +import sys from plotter import Plot from inkex.tester import ComparisonMixin, TestCase from inkex.tester.filters import CompareReplacement +@pytest.mark.skipif(sys.platform == "win32", reason="termios not available on Windows") class TestPlotter(ComparisonMixin, TestCase): """Test the plotter extension""" stderr_output = True diff --git a/tests/test_polyhedron_3d.py b/tests/test_polyhedron_3d.py index 4c26ace05cdd1aaf1720c4b95a4906a89bb6c7cb..5fa315ec47d65777a2703c435b129fd7e3cc4fd3 100644 --- a/tests/test_polyhedron_3d.py +++ b/tests/test_polyhedron_3d.py @@ -1,6 +1,7 @@ # coding=utf-8 from polyhedron_3d import Poly3D from inkex.tester import ComparisonMixin, TestCase +from inkex.tester.filters import CompareNumericFuzzy class Poly3DBasicTest(ComparisonMixin, TestCase): effect_class = Poly3D @@ -15,4 +16,5 @@ class Poly3DBasicTest(ComparisonMixin, TestCase): ('--show=edg', '--obj=methane', '--cw_wound=True'), ('--show=fce', '--obj=from_file', '--spec_file=great_stel_dodec.obj', '--cw_wound=True'), ] + compare_filters = [CompareNumericFuzzy()] compare_file = 'svg/empty.svg' diff --git a/tests/test_replace_font.py b/tests/test_replace_font.py index cbd68c4b8ba5b5aa0e7c20cd466400506ebb9b08..ea1ed5c81c555589d3fedf483055424f9655a7e3 100644 --- a/tests/test_replace_font.py +++ b/tests/test_replace_font.py @@ -2,6 +2,7 @@ from replace_font import ReplaceFont from inkex.tester import ComparisonMixin, InkscapeExtensionTestMixin, TestCase from inkex.tester.filters import CompareOrderIndependentStyle +from inkex.tester.filters import WindowsTextCompat class TestReplaceFontBasic(ComparisonMixin, InkscapeExtensionTestMixin, TestCase): effect_class = ReplaceFont @@ -16,3 +17,4 @@ class TestFontList(ComparisonMixin, TestCase): effect_class = ReplaceFont comparisons = [('--action=list_only',),] stderr_output = True + compare_filters = [WindowsTextCompat()] diff --git a/tests/test_text_extract.py b/tests/test_text_extract.py index 11ddec47ce0c77bd202c56de385fcbb2733992d0..63f6e582fa0c4464013d2fae342141b43e7d5ac1 100644 --- a/tests/test_text_extract.py +++ b/tests/test_text_extract.py @@ -1,6 +1,7 @@ # coding=utf-8 from inkex.tester import ComparisonMixin, TestCase from text_extract import Extract +from inkex.tester.filters import WindowsTextCompat class TestExtractBasic(ComparisonMixin, TestCase): effect_class = Extract @@ -11,3 +12,4 @@ class TestExtractBasic(ComparisonMixin, TestCase): ('--direction=lr', '--xanchor=center_x', '--yanchor=center_y'), ('--direction=rl', '--xanchor=center_x', '--yanchor=center_y'), ] + compare_filters = [WindowsTextCompat()] diff --git a/tox.ini b/tox.ini index 3e7a040b2251213b15ea553214cbc58bff7d3ed8..e570084e2a80ce7f7392e62bb2e9d22f460f9ca3 100644 --- a/tox.ini +++ b/tox.ini @@ -1,9 +1,15 @@ [tox] -envlist = py{36,37,38,39,310}-normal +envlist = py{36,37,38,39,310}-normal-{linux,win} [testenv] -setenv = COVERAGE_FILE=.coverage-{env:TOX_ENV_NAME} +platform = + linux: linux + win: win32 + +setenv = + COVERAGE_FILE=.coverage-{env:TOX_ENV_NAME} + win: COVERAGE_FILE=.coverage-{env:TOX_ENV_NAME}-win commands = pytest --ignore=other --cov=. --cov-report html --cov-report term {posargs} @@ -12,4 +18,11 @@ deps = -rtests/dev_requirements.txt [pytest] -addopts = --ignore=other --cov=. --cov-report=xml +addopts = --ignore=other + +[coverage3:paths] +source = + C:\GitLab-Runner\builds\*\extensions + C:\GitLab-Runner\builds\*\*\extensions + C:\builds\*\extensions + /builds/*/extensions diff --git a/webslicer_export.py b/webslicer_export.py index 1c718d8619f91d75c3ccff632550cfb5ed76f170..578cf26df71a0214becdbf9d423f1d1956199ed9 100755 --- a/webslicer_export.py +++ b/webslicer_export.py @@ -16,6 +16,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # +import subprocess import os import sys import tempfile @@ -61,21 +62,17 @@ class Export(WebSlicerMixin, inkex.OutputExtension): return None def get_cmd_output(self, cmd): - # This solution comes from Andrew Reedick - # http://mail.python.org/pipermail/python-win32/2008-January/006606.html - # This method replaces the commands.getstatusoutput() usage, with the - # hope to correct the windows exporting bug: - # https://bugs.launchpad.net/inkscape/+bug/563722 - if sys.platform != "win32": - cmd = '{ ' + cmd + '; }' - pipe = os.popen(cmd + ' 2>&1', 'r') - text = pipe.read() - sts = pipe.close() + try: + pipe = subprocess.Popen(cmd) + except FileNotFoundError: + return 1, "" + stdout, _ = pipe.communicate() + sts = pipe.returncode if sts is None: sts = 0 - if text[-1:] == '\n': - text = text[:-1] - return sts, text + if stdout is not None and stdout[-1:] == '\n': + stdout = stdout[:-1] + return sts, stdout _html_ids = []