diff --git a/.gitignore b/.gitignore --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *.orig __pycache__ +*.egg-info *.trace build qtcreator-build diff --git a/dev-tools/python/dev-requirements.txt b/dev-tools/python/dev-requirements.txt new file mode 100644 --- /dev/null +++ b/dev-tools/python/dev-requirements.txt @@ -0,0 +1,6 @@ +flake8==3.6.0 +pytest==4.0.2 +PyQt5==5.11.3 +PyQt5-sip==4.19.13 + +-e dev-tools/python/krita-mock diff --git a/dev-tools/python/krita-mock/setup.py b/dev-tools/python/krita-mock/setup.py new file mode 100644 --- /dev/null +++ b/dev-tools/python/krita-mock/setup.py @@ -0,0 +1,8 @@ +from setuptools import setup, find_namespace_packages + +setup( + name="krita", + version="0.1", + packages=find_namespace_packages('src'), + package_dir={'': 'src'}, +) diff --git a/dev-tools/python/krita-mock/src/krita/__init__.py b/dev-tools/python/krita-mock/src/krita/__init__.py new file mode 100644 --- /dev/null +++ b/dev-tools/python/krita-mock/src/krita/__init__.py @@ -0,0 +1,31 @@ +"""This is a mock krita module for Python unit tests. + +This module returns a mock object for any attribute name and thus +prevents any errors surrounding the krita module in unit tests. This +makes it possible to write unit tests for Krita-independent code +units. + +Caveats: + +Will only work with proper imports: + + import krita + krita.Krita.instance() # no-op on a mock object + +Not with wildcard imports: + + from krita import * + Krita.instance() # error + +(Wildcard imports should be avoided anyway.) + +""" + +import builtins +import sys +from unittest.mock import MagicMock + + +sys.modules['krita'] = MagicMock() + +builtins.i18n = lambda s: s diff --git a/plugins/python/CMakeLists.txt b/plugins/python/CMakeLists.txt --- a/plugins/python/CMakeLists.txt +++ b/plugins/python/CMakeLists.txt @@ -57,6 +57,7 @@ PATTERN "*.csv" PATTERN "*.html" PATTERN "__pycache__*" EXCLUDE + PATTERN "tests*" EXCLUDE ) # TODO Is there any way to form a long PATTERN options string # and use it in a single install() call? @@ -68,6 +69,7 @@ FILES_MATCHING PATTERN "${_pattern}" PATTERN "__pycache__*" EXCLUDE + PATTERN "tests*" EXCLUDE ) endforeach() else() diff --git a/plugins/python/plugin_importer/tests/__init__.py b/plugins/python/plugin_importer/tests/__init__.py new file mode 100644 diff --git a/plugins/python/plugin_importer/tests/test_plugin_importer.py b/plugins/python/plugin_importer/tests/test_plugin_importer.py new file mode 100644 --- /dev/null +++ b/plugins/python/plugin_importer/tests/test_plugin_importer.py @@ -0,0 +1,37 @@ +import os +import pytest +from tempfile import TemporaryDirectory +from unittest import TestCase + + +from .. plugin_importer import PluginImporter, PluginReadError + + +class PluginImporterTestCase(TestCase): + + def setUp(self): + self.resources_dir = TemporaryDirectory() + self.plugin_dir = TemporaryDirectory() + + def tearDown(self): + self.resources_dir.cleanup() + self.plugin_dir.cleanup() + + @property + def zip_filename(self): + return os.path.join( + self.resources_dir.name, 'plugin.zip') + + def test_zipfile_doesnt_exist(self): + with pytest.raises(PluginReadError): + PluginImporter(self.zip_filename, + self.resources_dir.name, + lambda x: True) + + def test_zipfile_not_a_zip(self): + with open(self.zip_filename, 'w') as f: + f.write('foo') + with pytest.raises(PluginReadError): + PluginImporter(self.zip_filename, + self.resources_dir.name, + lambda x: True) diff --git a/setup.cfg b/setup.cfg new file mode 100644 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,4 @@ +# Setting for various Python tools (code checks, unit tests etc) + +[flake8] +builtins = i18n,Scripter,Application,Krita