diff --git a/.gitignore b/.gitignore index 1c6827be..104190c6 100644 --- a/.gitignore +++ b/.gitignore @@ -135,3 +135,6 @@ dmypy.json # IDE .idea/ PythonImportHelper-v2-Completion.json + +# cpl unittest stuff +unittests/test_*_playground diff --git a/cpl-workspace.json b/cpl-workspace.json index 00e7534a..0ccfebed 100644 --- a/cpl-workspace.json +++ b/cpl-workspace.json @@ -6,7 +6,12 @@ "cpl-cli": "src/cpl_cli/cpl-cli.json", "cpl-query": "src/cpl_query/cpl-query.json", "set-version": "tools/set_version/set-version.json", - "set-pip-urls": "tools/set_pip_urls/set-pip-urls.json" + "set-pip-urls": "tools/set_pip_urls/set-pip-urls.json", + "unittests": "unittests/unittests/unittests.json", + "unittests_cli": "unittests/unittests_cli/unittests_cli.json", + "unittests_core": "unittests/unittests_core/unittests_core.json", + "unittests_query": "unittests/unittests_query/unittests_query.json", + "unittests_shared": "unittests/unittests_shared/unittests_shared.json" }, "Scripts": { "hello-world": "echo 'Hello World'", @@ -22,6 +27,8 @@ "docs-open": "xdg-open $PWD/docs/build/html/index.html &", "do": "cpl docs-open", + "test": "cpl run unittests", + "pre-build-all": "cpl sv $ARGS; cpl spu $ARGS;", "build-all": "cpl build-cli; cpl build-core; cpl build-query; cpl build-set-pip-urls; cpl build-set-version", "ba": "cpl build-all $ARGS", @@ -76,7 +83,13 @@ "dd": "cpl deploy-dev $ARGS", "deploy-dev-cli": "cpl publish-cli; cpl upload-dev-cli", "deploy-dev-core": "cpl publish-core; cpl upload-dev-core", - "deploy-dev-query": "cpl publish-query; cpl upload-dev-query" + "deploy-dev-query": "cpl publish-query; cpl upload-dev-query", + + "dev-install": "cpl di-core; cpl di-cli; cpl di-query;", + "di": "cpl dev-install", + "di-core": "pip install cpl-query --pre --upgrade --extra-index-url https://pip-dev.sh-edraft.de", + "di-cli": "pip install cpl-query --pre --upgrade --extra-index-url https://pip-dev.sh-edraft.de", + "di-query": "pip install cpl-query --pre --upgrade --extra-index-url https://pip-dev.sh-edraft.de" } } } \ No newline at end of file diff --git a/src/cpl_cli/__init__.py b/src/cpl_cli/__init__.py index 05e52eb0..51dbf5a5 100644 --- a/src/cpl_cli/__init__.py +++ b/src/cpl_cli/__init__.py @@ -15,7 +15,7 @@ __title__ = 'cpl_cli' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev10' from collections import namedtuple @@ -27,4 +27,4 @@ from .main import main from .startup import Startup VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev10') diff --git a/src/cpl_cli/_templates/__init__.py b/src/cpl_cli/_templates/__init__.py index 2f05b3a2..25bbfbe6 100644 --- a/src/cpl_cli/_templates/__init__.py +++ b/src/cpl_cli/_templates/__init__.py @@ -15,11 +15,11 @@ __title__ = 'cpl_cli._templates' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev10' from collections import namedtuple # imports: VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev10') diff --git a/src/cpl_cli/_templates/build/__init__.py b/src/cpl_cli/_templates/build/__init__.py index 4d15c7c4..3e4b72ef 100644 --- a/src/cpl_cli/_templates/build/__init__.py +++ b/src/cpl_cli/_templates/build/__init__.py @@ -15,11 +15,11 @@ __title__ = 'cpl_cli._templates.build' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev10' from collections import namedtuple # imports: VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev10') diff --git a/src/cpl_cli/_templates/generate/__init__.py b/src/cpl_cli/_templates/generate/__init__.py index f623a461..b284b1eb 100644 --- a/src/cpl_cli/_templates/generate/__init__.py +++ b/src/cpl_cli/_templates/generate/__init__.py @@ -15,11 +15,11 @@ __title__ = 'cpl_cli._templates.generate' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev10' from collections import namedtuple # imports: VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev10') diff --git a/src/cpl_cli/_templates/generate/test_case_template.py b/src/cpl_cli/_templates/generate/test_case_template.py new file mode 100644 index 00000000..7fa9a4a7 --- /dev/null +++ b/src/cpl_cli/_templates/generate/test_case_template.py @@ -0,0 +1,41 @@ +import textwrap +from string import Template + +from cpl_core.utils.string import String +from cpl_cli._templates.template_file_abc import TemplateFileABC + + +class TestCaseTemplate(TemplateFileABC): + + def __init__(self, name: str, schematic: str, schematic_upper: str, path: str): + TemplateFileABC.__init__(self) + + self._name = f'{String.convert_to_snake_case(name)}_{schematic}.py' + self._class_name = f'{String.first_to_upper(name)}{schematic_upper}' + self._path = path + self._value = textwrap.dedent("""\ + import unittest + + + class $Name(unittest.TestCase): + + def setUp(self): + pass + + def test_equal(self): + pass + """) + + @property + def name(self) -> str: + return self._name + + @property + def path(self) -> str: + return self._path + + @property + def value(self) -> str: + return Template(self._value).substitute( + Name=self._class_name + ) diff --git a/src/cpl_cli/_templates/new/__init__.py b/src/cpl_cli/_templates/new/__init__.py index 87792c02..1d55e913 100644 --- a/src/cpl_cli/_templates/new/__init__.py +++ b/src/cpl_cli/_templates/new/__init__.py @@ -15,11 +15,11 @@ __title__ = 'cpl_cli._templates.new' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev10' from collections import namedtuple # imports: VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev10') diff --git a/src/cpl_cli/_templates/new/console/__init__.py b/src/cpl_cli/_templates/new/console/__init__.py index d88df923..2844a979 100644 --- a/src/cpl_cli/_templates/new/console/__init__.py +++ b/src/cpl_cli/_templates/new/console/__init__.py @@ -15,11 +15,11 @@ __title__ = 'cpl_cli._templates.new.console' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev10' from collections import namedtuple # imports: VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev10') diff --git a/src/cpl_cli/_templates/new/console/source/__init__.py b/src/cpl_cli/_templates/new/console/source/__init__.py index 7d9d4f31..9d5993a1 100644 --- a/src/cpl_cli/_templates/new/console/source/__init__.py +++ b/src/cpl_cli/_templates/new/console/source/__init__.py @@ -15,11 +15,11 @@ __title__ = 'cpl_cli._templates.new.console.source' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev10' from collections import namedtuple # imports: VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev10') diff --git a/src/cpl_cli/_templates/new/console/source/name/__init__.py b/src/cpl_cli/_templates/new/console/source/name/__init__.py index bcf07bec..73b5e446 100644 --- a/src/cpl_cli/_templates/new/console/source/name/__init__.py +++ b/src/cpl_cli/_templates/new/console/source/name/__init__.py @@ -15,11 +15,11 @@ __title__ = 'cpl_cli._templates.new.console.source.name' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev10' from collections import namedtuple # imports: VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev10') diff --git a/src/cpl_cli/_templates/new/console/source/tests/__init__.py b/src/cpl_cli/_templates/new/console/source/tests/__init__.py index e6f97f7d..12090cae 100644 --- a/src/cpl_cli/_templates/new/console/source/tests/__init__.py +++ b/src/cpl_cli/_templates/new/console/source/tests/__init__.py @@ -15,11 +15,11 @@ __title__ = 'cpl_cli._templates.new.console.source.tests' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev10' from collections import namedtuple # imports: VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev10') diff --git a/src/cpl_cli/_templates/new/library/__init__.py b/src/cpl_cli/_templates/new/library/__init__.py index 983bda70..528a3ed3 100644 --- a/src/cpl_cli/_templates/new/library/__init__.py +++ b/src/cpl_cli/_templates/new/library/__init__.py @@ -15,11 +15,11 @@ __title__ = 'cpl_cli._templates.new.library' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev10' from collections import namedtuple # imports: VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev10') diff --git a/src/cpl_cli/_templates/new/library/source/__init__.py b/src/cpl_cli/_templates/new/library/source/__init__.py index 05c73fef..d8b99a19 100644 --- a/src/cpl_cli/_templates/new/library/source/__init__.py +++ b/src/cpl_cli/_templates/new/library/source/__init__.py @@ -15,11 +15,11 @@ __title__ = 'cpl_cli._templates.new.library.source' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev10' from collections import namedtuple # imports: VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev10') diff --git a/src/cpl_cli/_templates/new/library/source/name/__init__.py b/src/cpl_cli/_templates/new/library/source/name/__init__.py index cff20c14..2cb90ed0 100644 --- a/src/cpl_cli/_templates/new/library/source/name/__init__.py +++ b/src/cpl_cli/_templates/new/library/source/name/__init__.py @@ -15,11 +15,11 @@ __title__ = 'cpl_cli._templates.new.library.source.name' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev10' from collections import namedtuple # imports: VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev10') diff --git a/src/cpl_cli/_templates/new/library/source/tests/__init__.py b/src/cpl_cli/_templates/new/library/source/tests/__init__.py index b5b21f5f..e7b146b9 100644 --- a/src/cpl_cli/_templates/new/library/source/tests/__init__.py +++ b/src/cpl_cli/_templates/new/library/source/tests/__init__.py @@ -15,11 +15,11 @@ __title__ = 'cpl_cli._templates.new.library.source.tests' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev10' from collections import namedtuple # imports: VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev10') diff --git a/src/cpl_cli/_templates/new/unittest/__init__.py b/src/cpl_cli/_templates/new/unittest/__init__.py new file mode 100644 index 00000000..70895e74 --- /dev/null +++ b/src/cpl_cli/_templates/new/unittest/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +""" +cpl-cli sh-edraft Common Python library CLI +~~~~~~~~~~~~~~~~~~~ + +sh-edraft Common Python library Command Line Interface + +:copyright: (c) 2020 - 2022 sh-edraft.de +:license: MIT, see LICENSE for more details. + +""" + +__title__ = 'cpl_cli._templates.new.unittest' +__author__ = 'Sven Heidemann' +__license__ = 'MIT' +__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' +__version__ = '2022.6.17.dev10' + +from collections import namedtuple + +# imports: + +VersionInfo = namedtuple('VersionInfo', 'major minor micro') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev10') diff --git a/src/cpl_cli/_templates/new/unittest/license.py b/src/cpl_cli/_templates/new/unittest/license.py new file mode 100644 index 00000000..fb586904 --- /dev/null +++ b/src/cpl_cli/_templates/new/unittest/license.py @@ -0,0 +1,23 @@ +from cpl_cli._templates.template_file_abc import TemplateFileABC + + +class LicenseTemplate(TemplateFileABC): + + def __init__(self): + TemplateFileABC.__init__(self) + + self._name = 'LICENSE' + self._path = '' + self._value = """""" + + @property + def name(self) -> str: + return self._name + + @property + def path(self) -> str: + return self._path + + @property + def value(self) -> str: + return self._value diff --git a/src/cpl_cli/_templates/new/unittest/readme_py.py b/src/cpl_cli/_templates/new/unittest/readme_py.py new file mode 100644 index 00000000..a40286a8 --- /dev/null +++ b/src/cpl_cli/_templates/new/unittest/readme_py.py @@ -0,0 +1,23 @@ +from cpl_cli._templates.template_file_abc import TemplateFileABC + + +class ReadmeTemplate(TemplateFileABC): + + def __init__(self): + TemplateFileABC.__init__(self) + + self._name = 'README.md' + self._path = '' + self._value = """""" + + @property + def name(self) -> str: + return self._name + + @property + def path(self) -> str: + return self._path + + @property + def value(self) -> str: + return self._value diff --git a/src/cpl_cli/_templates/new/unittest/source/__init__.py b/src/cpl_cli/_templates/new/unittest/source/__init__.py new file mode 100644 index 00000000..85a5acfd --- /dev/null +++ b/src/cpl_cli/_templates/new/unittest/source/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +""" +cpl-cli sh-edraft Common Python library CLI +~~~~~~~~~~~~~~~~~~~ + +sh-edraft Common Python library Command Line Interface + +:copyright: (c) 2020 - 2022 sh-edraft.de +:license: MIT, see LICENSE for more details. + +""" + +__title__ = 'cpl_cli._templates.new.unittest.source' +__author__ = 'Sven Heidemann' +__license__ = 'MIT' +__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' +__version__ = '2022.6.17.dev10' + +from collections import namedtuple + +# imports: + +VersionInfo = namedtuple('VersionInfo', 'major minor micro') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev10') diff --git a/src/cpl_cli/_templates/new/unittest/source/name/__init__.py b/src/cpl_cli/_templates/new/unittest/source/name/__init__.py new file mode 100644 index 00000000..ba02fcf1 --- /dev/null +++ b/src/cpl_cli/_templates/new/unittest/source/name/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +""" +cpl-cli sh-edraft Common Python library CLI +~~~~~~~~~~~~~~~~~~~ + +sh-edraft Common Python library Command Line Interface + +:copyright: (c) 2020 - 2022 sh-edraft.de +:license: MIT, see LICENSE for more details. + +""" + +__title__ = 'cpl_cli._templates.new.unittest.source.name' +__author__ = 'Sven Heidemann' +__license__ = 'MIT' +__copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' +__version__ = '2022.6.17.dev10' + +from collections import namedtuple + +# imports: + +VersionInfo = namedtuple('VersionInfo', 'major minor micro') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev10') diff --git a/src/cpl_cli/_templates/new/unittest/source/name/application.py b/src/cpl_cli/_templates/new/unittest/source/name/application.py new file mode 100644 index 00000000..6c40e867 --- /dev/null +++ b/src/cpl_cli/_templates/new/unittest/source/name/application.py @@ -0,0 +1,74 @@ +import textwrap + +from cpl_cli._templates.template_file_abc import TemplateFileABC + + +class ApplicationTemplate(TemplateFileABC): + + def __init__(self, name: str, path: str, use_async: bool): + TemplateFileABC.__init__(self) + + self._name = 'application.py' + self._path = path + self._use_async = use_async + + if self._use_async: + self._value = textwrap.dedent("""\ + import unittest + from unittest import TestSuite + + from cpl_core.application import ApplicationABC + from cpl_core.configuration import ConfigurationABC + from cpl_core.dependency_injection import ServiceProviderABC + from unittests.test_case import TestCase + + + class Application(ApplicationABC): + + def __init__(self, config: ConfigurationABC, services: ServiceProviderABC): + ApplicationABC.__init__(self, config, services) + self._suite: TestSuite = unittest.TestSuite() + + async def configure(self): + self._suite.addTest(TestCase('test_equal')) + + async def main(self): + runner = unittest.TextTestRunner() + runner.run(self._suite) + """) + else: + self._value = textwrap.dedent("""\ + import unittest + from unittest import TestSuite + + from cpl_core.application import ApplicationABC + from cpl_core.configuration import ConfigurationABC + from cpl_core.dependency_injection import ServiceProviderABC + from unittests.test_case import TestCase + + + class Application(ApplicationABC): + + def __init__(self, config: ConfigurationABC, services: ServiceProviderABC): + ApplicationABC.__init__(self, config, services) + self._suite: TestSuite = unittest.TestSuite() + + def configure(self): + self._suite.addTest(TestCase('test_equal')) + + def main(self): + runner = unittest.TextTestRunner() + runner.run(self._suite) + """) + + @property + def name(self) -> str: + return self._name + + @property + def path(self) -> str: + return self._path + + @property + def value(self) -> str: + return self._value diff --git a/src/cpl_cli/_templates/new/unittest/source/name/init.py b/src/cpl_cli/_templates/new/unittest/source/name/init.py new file mode 100644 index 00000000..b3cbdecb --- /dev/null +++ b/src/cpl_cli/_templates/new/unittest/source/name/init.py @@ -0,0 +1,27 @@ +import textwrap + +from cpl_cli._templates.template_file_abc import TemplateFileABC + + +class MainInitTemplate(TemplateFileABC): + + def __init__(self, name: str, path: str): + TemplateFileABC.__init__(self) + + self._name = '__init__.py' + self._path = path + self._value = textwrap.dedent("""\ + # imports: + """) + + @property + def name(self) -> str: + return self._name + + @property + def path(self) -> str: + return self._path + + @property + def value(self) -> str: + return self._value diff --git a/src/cpl_cli/_templates/new/unittest/source/name/main.py b/src/cpl_cli/_templates/new/unittest/source/name/main.py new file mode 100644 index 00000000..81f0a251 --- /dev/null +++ b/src/cpl_cli/_templates/new/unittest/source/name/main.py @@ -0,0 +1,63 @@ +import textwrap + +from cpl_core.utils.string import String +from cpl_cli._templates.template_file_abc import TemplateFileABC + + +class MainWithApplicationBaseTemplate(TemplateFileABC): + + def __init__(self, name: str, path: str, use_async: bool): + TemplateFileABC.__init__(self) + + name = String.convert_to_snake_case(name) + self._name = 'main.py' + self._path = path + + import_pkg = f'{name}.' + + if use_async: + self._value = textwrap.dedent(f"""\ + import asyncio + + from cpl_core.application import ApplicationBuilder + + from {import_pkg}application import Application + + + async def main(): + app_builder = ApplicationBuilder(Application) + app: Application = await app_builder.build_async() + await app.run_async() + + + if __name__ == '__main__': + ml = asyncio.get_event_loop() + ml.run_until_complete(main()) + """) + else: + self._value = textwrap.dedent(f"""\ + from cpl_core.application import ApplicationBuilder + + from {import_pkg}application import Application + + + def main(): + app_builder = ApplicationBuilder(Application) + app_builder.build().run() + + + if __name__ == '__main__': + main() + """) + + @property + def name(self) -> str: + return self._name + + @property + def path(self) -> str: + return self._path + + @property + def value(self) -> str: + return self._value diff --git a/src/cpl_cli/_templates/new/unittest/source/name/test_case.py b/src/cpl_cli/_templates/new/unittest/source/name/test_case.py new file mode 100644 index 00000000..096518bd --- /dev/null +++ b/src/cpl_cli/_templates/new/unittest/source/name/test_case.py @@ -0,0 +1,52 @@ +import textwrap + +from cpl_cli._templates.template_file_abc import TemplateFileABC + + +class TestCaseTemplate(TemplateFileABC): + + def __init__(self, name: str, path: str, use_async: bool): + TemplateFileABC.__init__(self) + + self._name = 'test_case.py' + self._path = path + self._use_async = use_async + + if self._use_async: + self._value = textwrap.dedent("""\ + import unittest + + + class TestCase(unittest.TestCase): + + async def setUp(self) -> None: + pass + + async def test_equal(self): + self.assertEqual(True, True) + """) + else: + self._value = textwrap.dedent("""\ + import unittest + + + class TestCase(unittest.TestCase): + + def setUp(self) -> None: + pass + + def test_equal(self): + self.assertEqual(True, True) + """) + + @property + def name(self) -> str: + return self._name + + @property + def path(self) -> str: + return self._path + + @property + def value(self) -> str: + return self._value diff --git a/src/cpl_cli/_templates/publish/__init__.py b/src/cpl_cli/_templates/publish/__init__.py index 2b81167c..4c6c7c23 100644 --- a/src/cpl_cli/_templates/publish/__init__.py +++ b/src/cpl_cli/_templates/publish/__init__.py @@ -15,11 +15,11 @@ __title__ = 'cpl_cli._templates.publish' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev10' from collections import namedtuple # imports: VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev10') diff --git a/src/cpl_cli/cli.py b/src/cpl_cli/cli.py index 499a5939..d70a777a 100644 --- a/src/cpl_cli/cli.py +++ b/src/cpl_cli/cli.py @@ -29,6 +29,7 @@ class CLI(ApplicationABC): try: result = self._configuration.parse_console_arguments(self._services) if result: + Console.write_line() return if len(self._configuration.additional_arguments) == 0: @@ -37,6 +38,7 @@ class CLI(ApplicationABC): unexpected_arguments = ', '.join(self._configuration.additional_arguments) Error.error(f'Unexpected argument(s): {unexpected_arguments}') + Console.write_line() except KeyboardInterrupt: Console.write_line() sys.exit() diff --git a/src/cpl_cli/command/__init__.py b/src/cpl_cli/command/__init__.py index 57edb0da..64d2b8a1 100644 --- a/src/cpl_cli/command/__init__.py +++ b/src/cpl_cli/command/__init__.py @@ -15,7 +15,7 @@ __title__ = 'cpl_cli.command' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev10' from collections import namedtuple @@ -28,4 +28,4 @@ from .publish_service import PublishService from .version_service import VersionService VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev10') diff --git a/src/cpl_cli/command/generate_service.py b/src/cpl_cli/command/generate_service.py index 6c9861a8..4fb25a04 100644 --- a/src/cpl_cli/command/generate_service.py +++ b/src/cpl_cli/command/generate_service.py @@ -2,21 +2,22 @@ import os import sys import textwrap -from cpl_cli._templates.generate.pipe_template import PipeTemplate -from cpl_cli._templates.generate.validator_template import ValidatorTemplate -from cpl_core.configuration.configuration_abc import ConfigurationABC -from cpl_core.console.foreground_color_enum import ForegroundColorEnum -from cpl_core.console.console import Console -from cpl_core.utils.string import String -from cpl_cli.command_abc import CommandABC -from cpl_cli._templates.generate.init_template import InitTemplate from cpl_cli._templates.generate.abc_template import ABCTemplate from cpl_cli._templates.generate.class_template import ClassTemplate from cpl_cli._templates.generate.configmodel_template import ConfigModelTemplate from cpl_cli._templates.generate.enum_template import EnumTemplate +from cpl_cli._templates.generate.init_template import InitTemplate +from cpl_cli._templates.generate.pipe_template import PipeTemplate from cpl_cli._templates.generate.service_template import ServiceTemplate +from cpl_cli._templates.generate.test_case_template import TestCaseTemplate from cpl_cli._templates.generate.thread_template import ThreadTemplate +from cpl_cli._templates.generate.validator_template import ValidatorTemplate from cpl_cli._templates.template_file_abc import TemplateFileABC +from cpl_cli.command_abc import CommandABC +from cpl_core.configuration.configuration_abc import ConfigurationABC +from cpl_core.console.console import Console +from cpl_core.console.foreground_color_enum import ForegroundColorEnum +from cpl_core.utils.string import String class GenerateService(CommandABC): @@ -53,6 +54,10 @@ class GenerateService(CommandABC): "Upper": "Settings", "Template": ConfigModelTemplate }, + "test_case": { + "Upper": "TestCase", + "Template": TestCaseTemplate + }, "thread": { "Upper": "Thread", "Template": ThreadTemplate @@ -83,6 +88,7 @@ class GenerateService(CommandABC): pipe service settings + test_case thread validator """) @@ -103,6 +109,7 @@ class GenerateService(CommandABC): 'pipe (p|P)', 'service (s|S)', 'settings (st|ST)', + 'test-case (tc|TC)', 'thread (t|T)', 'validator (v|V)' ] diff --git a/src/cpl_cli/command/install_service.py b/src/cpl_cli/command/install_service.py index 688632a3..d4342988 100644 --- a/src/cpl_cli/command/install_service.py +++ b/src/cpl_cli/command/install_service.py @@ -42,7 +42,7 @@ class InstallService(CommandABC): self._is_simulation = False self._is_virtual = False - self._project_file = f'{self._config.get_configuration("ProjectName")}.json' + self._project_file = f'{self._project_settings.name}.json' @property def help_message(self) -> str: diff --git a/src/cpl_cli/command/new_service.py b/src/cpl_cli/command/new_service.py index 916abec3..73f50ced 100644 --- a/src/cpl_cli/command/new_service.py +++ b/src/cpl_cli/command/new_service.py @@ -6,6 +6,7 @@ from typing import Optional from packaging import version import cpl_core +from cpl_cli.source_creator.unittest_builder import UnittestBuilder from cpl_core.configuration.configuration_abc import ConfigurationABC from cpl_core.console.foreground_color_enum import ForegroundColorEnum @@ -43,7 +44,9 @@ class NewService(CommandABC): self._project_json = {} self._name: str = '' + self._rel_path: str = '' self._schematic: ProjectTypeEnum = ProjectTypeEnum.console + self._use_nothing: bool = False self._use_application_api: bool = False self._use_startup: bool = False self._use_service_providing: bool = False @@ -81,9 +84,10 @@ class NewService(CommandABC): for name in schematics: Console.write(f'\n\t{name} ') - def _create_project_settings(self, name: str): + def _create_project_settings(self): + self._rel_path = os.path.dirname(self._name) self._project_dict = { - ProjectSettingsNameEnum.name.value: name, + ProjectSettingsNameEnum.name.value: os.path.basename(self._name), ProjectSettingsNameEnum.version.value: { VersionSettingsNameEnum.major.value: '0', VersionSettingsNameEnum.minor.value: '0', @@ -111,15 +115,11 @@ class NewService(CommandABC): self._project.from_dict(self._project_dict) def _create_build_settings(self): - main = f'{String.convert_to_snake_case(self._project.name)}.main' - if self._schematic == ProjectTypeEnum.library.value: - main = f'{String.convert_to_snake_case(self._project.name)}.main' - self._build_dict = { BuildSettingsNameEnum.project_type.value: self._schematic, BuildSettingsNameEnum.source_path.value: '', BuildSettingsNameEnum.output_path.value: '../../dist', - BuildSettingsNameEnum.main.value: main, + BuildSettingsNameEnum.main.value: f'{String.convert_to_snake_case(self._project.name)}.main', BuildSettingsNameEnum.entry_point.value: self._project.name, BuildSettingsNameEnum.include_package_data.value: False, BuildSettingsNameEnum.included.value: [], @@ -149,40 +149,38 @@ class NewService(CommandABC): :return: """ if self._workspace is None: - project_path = os.path.join(self._env.working_directory, self._project.name) + project_path = os.path.join(self._env.working_directory, self._rel_path, self._project.name) else: - project_path = os.path.join( - self._env.working_directory, - 'src', - String.convert_to_snake_case(self._project.name) - ) + project_path = os.path.join(self._env.working_directory, 'src', self._rel_path, String.convert_to_snake_case(self._project.name)) if os.path.isdir(project_path) and len(os.listdir(project_path)) > 0: + Console.write_line(project_path) Console.error('Project path is not empty\n') return None return project_path - def _get_project_information(self): + def _get_project_information(self, is_unittest=False): """ Gets project information's from user :return: """ - result = Console.read('Do you want to use application base? (y/n) ') - if result.lower() == 'y': - self._use_application_api = True + if self._use_application_api or self._use_startup or self._use_service_providing or self._use_async or self._use_nothing: + Console.set_foreground_color(ForegroundColorEnum.default) + Console.write_line('Skipping question due to given flags') + return - result = Console.read('Do you want to use startup? (y/n) ') - if result.lower() == 'y': - self._use_startup = True - else: - result = Console.read('Do you want to use service providing? (y/n) ') - if result.lower() == 'y': - self._use_service_providing = True - - result = Console.read('Do you want to use async? (y/n) ') - if result.lower() == 'y': - self._use_async = True + if not is_unittest: + self._use_application_api = Console.read('Do you want to use application base? (y/n) ').lower() == 'y' + + if not is_unittest and self._use_application_api: + self._use_startup = Console.read('Do you want to use startup? (y/n) ').lower() == 'y' + + if not is_unittest and not self._use_application_api: + self._use_service_providing = Console.read('Do you want to use service providing? (y/n) ').lower() == 'y' + + if not self._use_async: + self._use_async = Console.read('Do you want to use async? (y/n) ').lower() == 'y' Console.set_foreground_color(ForegroundColorEnum.default) @@ -192,7 +190,7 @@ class NewService(CommandABC): :param args: :return: """ - self._create_project_settings(self._name) + self._create_project_settings() self._create_build_settings() self._create_project_json() path = self._get_project_path() @@ -200,6 +198,9 @@ class NewService(CommandABC): return self._get_project_information() + project_name = self._project.name + if self._rel_path != '': + project_name = f'{self._rel_path}/{project_name}' try: ConsoleBuilder.build( path, @@ -207,7 +208,36 @@ class NewService(CommandABC): self._use_startup, self._use_service_providing, self._use_async, - self._project.name, + project_name, + self._project_json, + self._workspace + ) + except Exception as e: + Console.error('Could not create project', str(e)) + + def _unittest(self, args: list[str]): + """ + Generates new unittest project + :param args: + :return: + """ + self._create_project_settings() + self._create_build_settings() + self._create_project_json() + path = self._get_project_path() + if path is None: + return + + self._get_project_information(is_unittest=True) + project_name = self._project.name + if self._rel_path != '': + project_name = f'{self._rel_path}/{project_name}' + try: + UnittestBuilder.build( + path, + self._use_application_api, + self._use_async, + project_name, self._project_json, self._workspace ) @@ -220,7 +250,7 @@ class NewService(CommandABC): :param args: :return: """ - self._create_project_settings(self._name) + self._create_project_settings() self._create_build_settings() self._create_project_json() path = self._get_project_path() @@ -228,6 +258,9 @@ class NewService(CommandABC): return self._get_project_information() + project_name = self._project.name + if self._rel_path != '': + project_name = f'{self._rel_path}/{project_name}' try: LibraryBuilder.build( path, @@ -235,7 +268,7 @@ class NewService(CommandABC): self._use_startup, self._use_service_providing, self._use_async, - self._project.name, + project_name, self._project_json, self._workspace ) @@ -248,18 +281,52 @@ class NewService(CommandABC): :param args: :return: """ + if 'nothing' in args: + self._use_nothing = True + self._use_async = False + self._use_application_api = False + self._use_startup = False + self._use_service_providing = False + if 'async' in args: + args.remove('async') + if 'application-base' in args: + args.remove('application-base') + if 'startup' in args: + args.remove('startup') + if 'service-providing' in args: + args.remove('service-providing') + + if 'async' in args: + self._use_async = True + args.remove('async') + if 'application-base' in args: + self._use_application_api = True + args.remove('application-base') + if 'startup' in args: + self._use_startup = True + args.remove('startup') + if 'service-providing' in args: + self._use_service_providing = True + args.remove('service-providing') + console = self._config.get_configuration(ProjectTypeEnum.console.value) library = self._config.get_configuration(ProjectTypeEnum.library.value) - if console is not None and library is None: + unittest = self._config.get_configuration(ProjectTypeEnum.unittest.value) + if console is not None and library is None and unittest is None: self._name = console self._schematic = ProjectTypeEnum.console.value self._console(args) - elif console is None and library is not None: + elif console is None and library is not None and unittest is None: self._name = library self._schematic = ProjectTypeEnum.library.value self._library(args) + elif console is None and library is None and unittest is not None: + self._name = unittest + self._schematic = ProjectTypeEnum.unittest.value + self._unittest(args) + else: self._help('Usage: cpl new [options]') return diff --git a/src/cpl_cli/command/remove_service.py b/src/cpl_cli/command/remove_service.py index 42462219..87db8b7a 100644 --- a/src/cpl_cli/command/remove_service.py +++ b/src/cpl_cli/command/remove_service.py @@ -3,12 +3,14 @@ import shutil import json import textwrap +from cpl_cli.configuration.settings_helper import SettingsHelper + from cpl_core.configuration.configuration_abc import ConfigurationABC from cpl_core.console.console import Console from cpl_core.console.foreground_color_enum import ForegroundColorEnum from cpl_core.environment.application_environment_abc import ApplicationEnvironmentABC from cpl_cli.command_abc import CommandABC -from cpl_cli.configuration import WorkspaceSettings, WorkspaceSettingsNameEnum +from cpl_cli.configuration import WorkspaceSettings, WorkspaceSettingsNameEnum, BuildSettingsNameEnum, ProjectSettings, BuildSettings class RemoveService(CommandABC): @@ -68,6 +70,50 @@ class RemoveService(CommandABC): self._create_file(path, ws_dict) + def _get_project_settings(self, project: str) -> dict: + with open(os.path.join(os.getcwd(), self._workspace.projects[project]), 'r', encoding='utf-8') as cfg: + # load json + project_json = json.load(cfg) + cfg.close() + + return project_json + + def _write_project_settings(self, project: str, project_settings: dict, build_settings: dict): + with open(os.path.join(os.getcwd(), self._workspace.projects[project]), 'w', encoding='utf-8') as file: + file.write(json.dumps({ + ProjectSettings.__name__: project_settings, + BuildSettings.__name__: build_settings + }, indent=2)) + file.close() + + def _find_deps_in_projects(self, project_name: str, rel_path: str): + for project in self._workspace.projects: + if project == project_name: + continue + + project_settings = self._get_project_settings(project) + if BuildSettings.__name__ not in project_settings or BuildSettingsNameEnum.project_references.value not in project_settings[BuildSettings.__name__]: + continue + + ref_to_delete = '' + for ref in project_settings[BuildSettings.__name__][BuildSettingsNameEnum.project_references.value]: + if os.path.basename(ref) == f'{project_name}.json': + ref_to_delete = ref + + if ref_to_delete not in project_settings[BuildSettings.__name__][BuildSettingsNameEnum.project_references.value]: + continue + + project_settings[BuildSettings.__name__][BuildSettingsNameEnum.project_references.value].remove(ref_to_delete) + Console.spinner( + f'Removing {project_name} from {project}', + self._write_project_settings, + project, + project_settings[ProjectSettings.__name__], + project_settings[BuildSettings.__name__], + text_foreground_color=ForegroundColorEnum.green, + spinner_foreground_color=ForegroundColorEnum.cyan + ) + def execute(self, args: list[str]): """ Entry point of command @@ -88,15 +134,17 @@ class RemoveService(CommandABC): Console.error(f'Project {project_name} is the default project.') return - src_path = os.path.abspath(os.path.dirname(self._workspace.projects[project_name])) + src_path = os.path.dirname(self._workspace.projects[project_name]) Console.spinner( f'Removing {src_path}', self._remove_sources, - src_path, + os.path.abspath(src_path), text_foreground_color=ForegroundColorEnum.green, spinner_foreground_color=ForegroundColorEnum.cyan ) + self._find_deps_in_projects(project_name, src_path) + del self._workspace.projects[project_name] path = 'cpl-workspace.json' Console.spinner( diff --git a/src/cpl_cli/command/uninstall_service.py b/src/cpl_cli/command/uninstall_service.py index c5c132c4..f2b88d5f 100644 --- a/src/cpl_cli/command/uninstall_service.py +++ b/src/cpl_cli/command/uninstall_service.py @@ -35,6 +35,7 @@ class UninstallService(CommandABC): self._is_simulating = False self._is_virtual = False + self._project_file = f'{self._project_settings.name}.json' @property def help_message(self) -> str: @@ -59,8 +60,7 @@ class UninstallService(CommandABC): Console.error(f'Expected package') Console.error(f'Usage: cpl uninstall ') return - - + if '--virtual' in args: self._is_virtual = True args.remove('--virtual') @@ -110,7 +110,7 @@ class UninstallService(CommandABC): ProjectSettings.__name__: SettingsHelper.get_project_settings_dict(self._project_settings), BuildSettings.__name__: SettingsHelper.get_build_settings_dict(self._build_settings) } - with open(os.path.join(self._env.working_directory, f'{self._config.get_configuration("ProjectName")}.json'), 'w') as project_file: + with open(os.path.join(self._env.working_directory, self._project_file), 'w') as project_file: project_file.write(json.dumps(config, indent=2)) project_file.close() diff --git a/src/cpl_cli/command/update_service.py b/src/cpl_cli/command/update_service.py index 5d082109..3b1895f5 100644 --- a/src/cpl_cli/command/update_service.py +++ b/src/cpl_cli/command/update_service.py @@ -40,6 +40,8 @@ class UpdateService(CommandABC): self._cli_settings = cli_settings self._is_simulation = False + self._project_file = f'{self._project_settings.name}.json' + @property def help_message(self) -> str: return textwrap.dedent("""\ @@ -81,7 +83,7 @@ class UpdateService(CommandABC): new_package = Pip.get_package(name) if new_package is None: Console.error(f'Update for package {package} failed') - return + continue self._project_json_update_dependency(package, new_package) @@ -151,8 +153,7 @@ class UpdateService(CommandABC): BuildSettings.__name__: SettingsHelper.get_build_settings_dict(self._build_settings) } - with open(os.path.join(self._env.working_directory, f'{self._config.get_configuration("ProjectName")}.json'), - 'w') as project: + with open(os.path.join(self._env.working_directory, self._project_file), 'w') as project: project.write(json.dumps(config, indent=2)) project.close() diff --git a/src/cpl_cli/command/version_service.py b/src/cpl_cli/command/version_service.py index 5e93660f..7b74b007 100644 --- a/src/cpl_cli/command/version_service.py +++ b/src/cpl_cli/command/version_service.py @@ -5,7 +5,6 @@ import pkg_resources import textwrap import cpl_cli -import cpl_core from cpl_core.console.console import Console from cpl_core.console.foreground_color_enum import ForegroundColorEnum from cpl_cli.command_abc import CommandABC diff --git a/src/cpl_cli/configuration/__init__.py b/src/cpl_cli/configuration/__init__.py index 1661d5d3..3ef7fcfd 100644 --- a/src/cpl_cli/configuration/__init__.py +++ b/src/cpl_cli/configuration/__init__.py @@ -15,7 +15,7 @@ __title__ = 'cpl_cli.configuration' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev10' from collections import namedtuple @@ -30,4 +30,4 @@ from .workspace_settings import WorkspaceSettings from .workspace_settings_name_enum import WorkspaceSettingsNameEnum VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev10') diff --git a/src/cpl_cli/configuration/project_type_enum.py b/src/cpl_cli/configuration/project_type_enum.py index 9471c59c..235e59c2 100644 --- a/src/cpl_cli/configuration/project_type_enum.py +++ b/src/cpl_cli/configuration/project_type_enum.py @@ -5,3 +5,4 @@ class ProjectTypeEnum(Enum): console = 'console' library = 'library' + unittest = 'unittest' diff --git a/src/cpl_cli/cpl-cli.json b/src/cpl_cli/cpl-cli.json index c82b9c2d..1f2c75d9 100644 --- a/src/cpl_cli/cpl-cli.json +++ b/src/cpl_cli/cpl-cli.json @@ -4,7 +4,7 @@ "Version": { "Major": "2022", "Minor": "6", - "Micro": "16.dev2" + "Micro": "17.dev10" }, "Author": "Sven Heidemann", "AuthorEmail": "sven.heidemann@sh-edraft.de", @@ -16,7 +16,7 @@ "LicenseName": "MIT", "LicenseDescription": "MIT, see LICENSE for more details.", "Dependencies": [ - "cpl-core>=2022.6.16.dev2" + "cpl-core>=2022.6.17.dev8" ], "PythonVersion": ">=3.10", "PythonPath": {}, diff --git a/src/cpl_cli/live_server/__init__.py b/src/cpl_cli/live_server/__init__.py index 15e8c430..b059e535 100644 --- a/src/cpl_cli/live_server/__init__.py +++ b/src/cpl_cli/live_server/__init__.py @@ -15,11 +15,11 @@ __title__ = 'cpl_cli.live_server' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev10' from collections import namedtuple # imports: VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev10') diff --git a/src/cpl_cli/main.py b/src/cpl_cli/main.py index 5ccac3ed..4b6959d9 100644 --- a/src/cpl_cli/main.py +++ b/src/cpl_cli/main.py @@ -41,12 +41,12 @@ def main(): if __name__ == '__main__': main() -# (( -# ( `) -# ; / , -# / \/ -# / | -# / ~/ -# / ) ) ~ edraft -# ___// | / -# `--' \_~-, +# (( +# ( `) +# ; / , +# / \/ +# / | +# / ~/ +# / ) ) ~ edraft +# ___// | / +# `--' \_~-, diff --git a/src/cpl_cli/publish/__init__.py b/src/cpl_cli/publish/__init__.py index 5e21f69d..cb7586fa 100644 --- a/src/cpl_cli/publish/__init__.py +++ b/src/cpl_cli/publish/__init__.py @@ -15,7 +15,7 @@ __title__ = 'cpl_cli.publish' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev10' from collections import namedtuple @@ -24,4 +24,4 @@ from .publisher_abc import PublisherABC from .publisher_service import PublisherService VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev10') diff --git a/src/cpl_cli/publish/publisher_service.py b/src/cpl_cli/publish/publisher_service.py index dc85215c..64988545 100644 --- a/src/cpl_cli/publish/publisher_service.py +++ b/src/cpl_cli/publish/publisher_service.py @@ -426,7 +426,7 @@ class PublisherService(PublisherABC): :return: """ self._env.set_working_directory(os.path.join(self._env.working_directory, '../')) - self.exclude(f'*/{self._config.get_configuration("ProjectName")}.json') + self.exclude(f'*/{self._project_settings.name}.json') self._output_path = os.path.abspath(os.path.join(self._output_path, self._project_settings.name, 'build')) Console.spinner('Reading source files:', self._read_sources, text_foreground_color=ForegroundColorEnum.green, @@ -449,7 +449,7 @@ class PublisherService(PublisherABC): :return: """ self._env.set_working_directory(os.path.join(self._env.working_directory, '../')) - self.exclude(f'*/{self._config.get_configuration("ProjectName")}.json') + self.exclude(f'*/{self._project_settings.name}.json') self._output_path = os.path.abspath(os.path.join(self._output_path, self._project_settings.name, 'publish')) Console.write_line('Build:') diff --git a/src/cpl_cli/source_creator/__init__.py b/src/cpl_cli/source_creator/__init__.py index c4195351..fbcf7624 100644 --- a/src/cpl_cli/source_creator/__init__.py +++ b/src/cpl_cli/source_creator/__init__.py @@ -15,11 +15,11 @@ __title__ = 'cpl_cli.source_creator' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev10' from collections import namedtuple # imports: VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev10') diff --git a/src/cpl_cli/source_creator/unittest_builder.py b/src/cpl_cli/source_creator/unittest_builder.py new file mode 100644 index 00000000..805c6363 --- /dev/null +++ b/src/cpl_cli/source_creator/unittest_builder.py @@ -0,0 +1,164 @@ +import json +import os +from typing import Optional + +from cpl_cli._templates.new.unittest.license import LicenseTemplate +from cpl_cli._templates.new.unittest.readme_py import ReadmeTemplate +from cpl_cli._templates.new.unittest.source.name.application import ApplicationTemplate +from cpl_cli._templates.new.unittest.source.name.init import MainInitTemplate +from cpl_cli._templates.new.unittest.source.name.main import MainWithApplicationBaseTemplate +from cpl_cli._templates.new.unittest.source.name.test_case import TestCaseTemplate +from cpl_cli._templates.template_file_abc import TemplateFileABC +from cpl_cli.configuration.workspace_settings import WorkspaceSettings +from cpl_cli.configuration.workspace_settings_name_enum import WorkspaceSettingsNameEnum +from cpl_cli.source_creator.template_builder import TemplateBuilder +from cpl_core.console.console import Console +from cpl_core.console.foreground_color_enum import ForegroundColorEnum +from cpl_core.utils.string import String + + +class UnittestBuilder: + + def __init__(self): + pass + + @staticmethod + def _create_file(file_name: str, content: dict): + if not os.path.isabs(file_name): + file_name = os.path.abspath(file_name) + + path = os.path.dirname(file_name) + if not os.path.isdir(path): + os.makedirs(path) + + with open(file_name, 'w') as project_json: + project_json.write(json.dumps(content, indent=2)) + project_json.close() + + @classmethod + def _create_workspace(cls, path: str, project_name, projects: dict, scripts: dict): + ws_dict = { + WorkspaceSettings.__name__: { + WorkspaceSettingsNameEnum.default_project.value: project_name, + WorkspaceSettingsNameEnum.projects.value: projects, + WorkspaceSettingsNameEnum.scripts.value: scripts + } + } + + Console.spinner( + f'Creating {path}', + cls._create_file, + path, + ws_dict, + text_foreground_color=ForegroundColorEnum.green, + spinner_foreground_color=ForegroundColorEnum.cyan + ) + + @classmethod + def build(cls, project_path: str, use_application_api: bool, + use_async: bool, project_name: str, project_settings: dict, workspace: Optional[WorkspaceSettings]): + """ + Builds the console project files + :param project_path: + :param use_application_api: + :param use_async: + :param project_name: + :param project_settings: + :param workspace: + :return: + """ + pj_name = project_name + if '/' in pj_name: + pj_name = pj_name.split('/')[len(pj_name.split('/')) - 1] + + project_name_snake = String.convert_to_snake_case(pj_name) + + if workspace is None: + templates: list[TemplateFileABC] = [ + LicenseTemplate(), + ReadmeTemplate(), + MainInitTemplate(project_name, os.path.join('src/', project_name_snake)) + ] + else: + project_path = os.path.join( + os.path.dirname(project_path), + project_name_snake + ) + + templates: list[TemplateFileABC] = [ + MainInitTemplate('', '') + ] + + if not os.path.isdir(project_path): + os.makedirs(project_path) + + py_src_rel_path = '' + src_name = project_name_snake + if workspace is None: + py_src_rel_path = f'src/{src_name}' + + templates.append(ApplicationTemplate(src_name, py_src_rel_path, use_async)) + templates.append(MainWithApplicationBaseTemplate(src_name, py_src_rel_path, use_async)) + templates.append(TestCaseTemplate(src_name, py_src_rel_path, use_async)) + + src_rel_path = '' + if '/' in project_name: + old_pj_name = project_name + parts = project_name.split('/') + project_name = parts[len(parts) - 1] + src_rel_path = old_pj_name.split(project_name)[0] + + proj_name = project_name + if src_rel_path.endswith('/'): + src_rel_path = src_rel_path[:len(src_rel_path) - 1] + + if src_rel_path != '': + proj_name = f'{src_rel_path}/{project_name}' + if workspace is not None: + proj_name = project_name_snake + + if src_rel_path != '': + project_file_path = f'{src_rel_path}/{project_name_snake}/{project_name}.json' + else: + project_file_path = f'{project_name_snake}/{project_name}.json' + + if workspace is None: + src_path = f'src/{project_name_snake}' + workspace_file_path = f'{proj_name}/cpl-workspace.json' + project_file_rel_path = f'{src_path}/{project_name}.json' + project_file_path = f'{proj_name}/{src_path}/{project_name}.json' + cls._create_workspace( + workspace_file_path, + project_name, + { + project_name: project_file_rel_path + }, + {} + ) + + else: + workspace.projects[project_name] = f'src/{project_file_path}' + cls._create_workspace('cpl-workspace.json', workspace.default_project, workspace.projects, workspace.scripts) + + Console.spinner( + f'Creating {project_file_path}', + cls._create_file, + project_file_path if workspace is None else f'src/{project_file_path}', + project_settings, + text_foreground_color=ForegroundColorEnum.green, + spinner_foreground_color=ForegroundColorEnum.cyan + ) + + for template in templates: + divider = '' + if template.path != '' and not template.path.endswith('/'): + divider = '/' + + Console.spinner( + f'Creating {proj_name}/{template.path}{divider}{template.name}', + TemplateBuilder.build, + project_path, + template, + text_foreground_color=ForegroundColorEnum.green, + spinner_foreground_color=ForegroundColorEnum.cyan + ) diff --git a/src/cpl_cli/startup.py b/src/cpl_cli/startup.py index 25aebea5..48d2f0bd 100644 --- a/src/cpl_cli/startup.py +++ b/src/cpl_cli/startup.py @@ -1,5 +1,7 @@ import os +from cpl_core.console import Console + from cpl_cli.error import Error from cpl_cli.live_server.live_server_service import LiveServerService from cpl_cli.publish.publisher_abc import PublisherABC @@ -22,6 +24,11 @@ class Startup(StartupABC): configuration.add_environment_variables('PYTHON_') configuration.add_environment_variables('CPL_') + + is_unittest = configuration.get_configuration('IS_UNITTEST') + if is_unittest == 'YES': + Console.disable() + configuration.add_json_file('appsettings.json', path=environment.runtime_directory, optional=False, output=False) return configuration diff --git a/src/cpl_cli/startup_argument_extension.py b/src/cpl_cli/startup_argument_extension.py index eaa1d899..01f89e2c 100644 --- a/src/cpl_cli/startup_argument_extension.py +++ b/src/cpl_cli/startup_argument_extension.py @@ -77,6 +77,7 @@ class StartupArgumentExtension(StartupExtensionABC): .add_console_argument(ArgumentTypeEnum.Variable, '', 'pipe', ['p', 'P'], ' ') \ .add_console_argument(ArgumentTypeEnum.Variable, '', 'service', ['s', 'S'], ' ') \ .add_console_argument(ArgumentTypeEnum.Variable, '', 'settings', ['st', 'ST'], ' ') \ + .add_console_argument(ArgumentTypeEnum.Variable, '', 'test_case', ['tc', 'TC'], ' ') \ .add_console_argument(ArgumentTypeEnum.Variable, '', 'thread', ['t', 'T'], ' ') \ .add_console_argument(ArgumentTypeEnum.Variable, '', 'validator', ['v', 'V'], ' ') config.create_console_argument(ArgumentTypeEnum.Executable, '', 'install', ['i', 'I'], InstallService, True, validators=[ProjectValidator]) \ @@ -84,7 +85,13 @@ class StartupArgumentExtension(StartupExtensionABC): .add_console_argument(ArgumentTypeEnum.Flag, '--', 'simulate', ['s', 'S']) config.create_console_argument(ArgumentTypeEnum.Executable, '', 'new', ['n', 'N'], NewService, True) \ .add_console_argument(ArgumentTypeEnum.Variable, '', 'console', ['c', 'C'], ' ') \ - .add_console_argument(ArgumentTypeEnum.Variable, '', 'library', ['l', 'L'], ' ') + .add_console_argument(ArgumentTypeEnum.Variable, '', 'library', ['l', 'L'], ' ') \ + .add_console_argument(ArgumentTypeEnum.Variable, '', 'unittest', ['ut', 'UT'], ' ') \ + .add_console_argument(ArgumentTypeEnum.Flag, '--', 'async', ['a', 'A']) \ + .add_console_argument(ArgumentTypeEnum.Flag, '--', 'application-base', ['ab', 'AB']) \ + .add_console_argument(ArgumentTypeEnum.Flag, '--', 'startup', ['s', 'S']) \ + .add_console_argument(ArgumentTypeEnum.Flag, '--', 'service-providing', ['sp', 'SP']) \ + .add_console_argument(ArgumentTypeEnum.Flag, '--', 'nothing', ['n', 'N']) config.create_console_argument(ArgumentTypeEnum.Executable, '', 'publish', ['p', 'P'], PublishService, True, validators=[ProjectValidator]) config.create_console_argument(ArgumentTypeEnum.Executable, '', 'remove', ['r', 'R'], RemoveService, True, validators=[WorkspaceValidator]) \ .add_console_argument(ArgumentTypeEnum.Flag, '--', 'simulate', ['s', 'S']) diff --git a/src/cpl_cli/validators/__init__.py b/src/cpl_cli/validators/__init__.py index 8d8bd93f..0b420956 100644 --- a/src/cpl_cli/validators/__init__.py +++ b/src/cpl_cli/validators/__init__.py @@ -15,11 +15,11 @@ __title__ = 'cpl_cli.validators' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev10' from collections import namedtuple # imports: VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev10') diff --git a/src/cpl_core/__init__.py b/src/cpl_core/__init__.py index 808bef50..e985e960 100644 --- a/src/cpl_core/__init__.py +++ b/src/cpl_core/__init__.py @@ -15,11 +15,11 @@ __title__ = 'cpl_core' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev8' from collections import namedtuple # imports: VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev8') diff --git a/src/cpl_core/application/__init__.py b/src/cpl_core/application/__init__.py index 068828c5..d8ad0d85 100644 --- a/src/cpl_core/application/__init__.py +++ b/src/cpl_core/application/__init__.py @@ -15,7 +15,7 @@ __title__ = 'cpl_core.application' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev8' from collections import namedtuple @@ -28,4 +28,4 @@ from .startup_abc import StartupABC from .startup_extension_abc import StartupExtensionABC VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev8') diff --git a/src/cpl_core/configuration/__init__.py b/src/cpl_core/configuration/__init__.py index 6942e603..8a802ae6 100644 --- a/src/cpl_core/configuration/__init__.py +++ b/src/cpl_core/configuration/__init__.py @@ -15,7 +15,7 @@ __title__ = 'cpl_core.configuration' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev8' from collections import namedtuple @@ -34,4 +34,4 @@ from .validator_abc import ValidatorABC from .variable_argument import VariableArgument VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev8') diff --git a/src/cpl_core/configuration/configuration.py b/src/cpl_core/configuration/configuration.py index 9b344ace..28f40355 100644 --- a/src/cpl_core/configuration/configuration.py +++ b/src/cpl_core/configuration/configuration.py @@ -190,8 +190,7 @@ class Configuration(ConfigurationABC): # executable if isinstance(arg, ExecutableArgument): - if arg_str.startswith(arg.token) \ - and arg_str_without_token == arg.name or arg_str_without_token in arg.aliases: + if arg_str.startswith(arg.token) and arg_str_without_token == arg.name or arg_str_without_token in arg.aliases: executables.append(arg) self._handled_args.append(arg_str) self._parse_arguments(executables, arg_list[i + 1:], arg.console_arguments) @@ -202,8 +201,7 @@ class Configuration(ConfigurationABC): if arg.value_token in arg_str_without_value: arg_str_without_value = arg_str_without_token.split(arg.value_token)[0] - if arg_str.startswith(arg.token) \ - and arg_str_without_value == arg.name or arg_str_without_value in arg.aliases: + if arg_str.startswith(arg.token) and arg_str_without_value == arg.name or arg_str_without_value in arg.aliases: if arg.value_token != ' ': value = arg_str_without_token.split(arg.value_token)[1] else: @@ -215,8 +213,9 @@ class Configuration(ConfigurationABC): # flags elif isinstance(arg, FlagArgument): - if arg_str.startswith(arg.token) \ - and arg_str_without_token == arg.name or arg_str_without_token in arg.aliases: + if arg_str.startswith(arg.token) and arg_str_without_token == arg.name or arg_str_without_token in arg.aliases: + if arg_str in self._additional_arguments: + self._additional_arguments.remove(arg_str) self._additional_arguments.append(arg.name) self._handled_args.append(arg_str) self._parse_arguments(executables, arg_list[i + 1:], arg.console_arguments) diff --git a/src/cpl_core/console/__init__.py b/src/cpl_core/console/__init__.py index 563b63f7..5b16b63e 100644 --- a/src/cpl_core/console/__init__.py +++ b/src/cpl_core/console/__init__.py @@ -15,7 +15,7 @@ __title__ = 'cpl_core.console' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev8' from collections import namedtuple @@ -27,4 +27,4 @@ from .foreground_color_enum import ForegroundColorEnum from .spinner_thread import SpinnerThread VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev8') diff --git a/src/cpl_core/console/console.py b/src/cpl_core/console/console.py index f7a06291..43f9e044 100644 --- a/src/cpl_core/console/console.py +++ b/src/cpl_core/console/console.py @@ -456,17 +456,21 @@ class Console: cls.write_line(message) cls.set_hold_back(True) - spinner = SpinnerThread(len(message), spinner_foreground_color, spinner_background_color) - spinner.start() + spinner = None + if not cls._disabled: + spinner = SpinnerThread(len(message), spinner_foreground_color, spinner_background_color) + spinner.start() return_value = None try: return_value = call(*args, **kwargs) except KeyboardInterrupt: - spinner.exit() + if spinner is not None: + spinner.exit() cls.close() - spinner.stop_spinning() + if spinner is not None: + spinner.stop_spinning() cls.set_hold_back(False) cls.set_foreground_color(ForegroundColorEnum.default) diff --git a/src/cpl_core/cpl-core.json b/src/cpl_core/cpl-core.json index 572e5760..37028396 100644 --- a/src/cpl_core/cpl-core.json +++ b/src/cpl_core/cpl-core.json @@ -4,7 +4,7 @@ "Version": { "Major": "2022", "Minor": "6", - "Micro": "16.dev2" + "Micro": "17.dev8" }, "Author": "Sven Heidemann", "AuthorEmail": "sven.heidemann@sh-edraft.de", diff --git a/src/cpl_core/database/__init__.py b/src/cpl_core/database/__init__.py index 0a98c239..dfbe4285 100644 --- a/src/cpl_core/database/__init__.py +++ b/src/cpl_core/database/__init__.py @@ -15,7 +15,7 @@ __title__ = 'cpl_core.database' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev8' from collections import namedtuple @@ -25,4 +25,4 @@ from .database_settings import DatabaseSettings from .table_abc import TableABC VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev8') diff --git a/src/cpl_core/database/connection/__init__.py b/src/cpl_core/database/connection/__init__.py index fdce501a..a0e4504c 100644 --- a/src/cpl_core/database/connection/__init__.py +++ b/src/cpl_core/database/connection/__init__.py @@ -15,7 +15,7 @@ __title__ = 'cpl_core.database.connection' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev8' from collections import namedtuple @@ -24,4 +24,4 @@ from .database_connection import DatabaseConnection from .database_connection_abc import DatabaseConnectionABC VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev8') diff --git a/src/cpl_core/database/context/__init__.py b/src/cpl_core/database/context/__init__.py index 1be8611e..825fbd5f 100644 --- a/src/cpl_core/database/context/__init__.py +++ b/src/cpl_core/database/context/__init__.py @@ -15,7 +15,7 @@ __title__ = 'cpl_core.database.context' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev8' from collections import namedtuple @@ -24,4 +24,4 @@ from .database_context import DatabaseContext from .database_context_abc import DatabaseContextABC VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev8') diff --git a/src/cpl_core/dependency_injection/__init__.py b/src/cpl_core/dependency_injection/__init__.py index 4685b513..2251a9bf 100644 --- a/src/cpl_core/dependency_injection/__init__.py +++ b/src/cpl_core/dependency_injection/__init__.py @@ -15,7 +15,7 @@ __title__ = 'cpl_core.dependency_injection' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev8' from collections import namedtuple @@ -30,4 +30,4 @@ from .service_provider import ServiceProvider from .service_provider_abc import ServiceProviderABC VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev8') diff --git a/src/cpl_core/environment/__init__.py b/src/cpl_core/environment/__init__.py index 327a383e..0deabdb2 100644 --- a/src/cpl_core/environment/__init__.py +++ b/src/cpl_core/environment/__init__.py @@ -15,7 +15,7 @@ __title__ = 'cpl_core.environment' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev8' from collections import namedtuple @@ -25,4 +25,4 @@ from .environment_name_enum import EnvironmentNameEnum from .application_environment import ApplicationEnvironment VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev8') diff --git a/src/cpl_core/logging/__init__.py b/src/cpl_core/logging/__init__.py index e25ff2ce..d0e23b68 100644 --- a/src/cpl_core/logging/__init__.py +++ b/src/cpl_core/logging/__init__.py @@ -15,7 +15,7 @@ __title__ = 'cpl_core.logging' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev8' from collections import namedtuple @@ -27,4 +27,4 @@ from .logging_settings import LoggingSettings from .logging_settings_name_enum import LoggingSettingsNameEnum VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev8') diff --git a/src/cpl_core/mailing/__init__.py b/src/cpl_core/mailing/__init__.py index 36170fa8..719c40bb 100644 --- a/src/cpl_core/mailing/__init__.py +++ b/src/cpl_core/mailing/__init__.py @@ -15,7 +15,7 @@ __title__ = 'cpl_core.mailing' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev8' from collections import namedtuple @@ -27,4 +27,4 @@ from .email_client_settings import EMailClientSettings from .email_client_settings_name_enum import EMailClientSettingsNameEnum VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev8') diff --git a/src/cpl_core/pipes/__init__.py b/src/cpl_core/pipes/__init__.py index 11fb1b38..0a2735af 100644 --- a/src/cpl_core/pipes/__init__.py +++ b/src/cpl_core/pipes/__init__.py @@ -15,7 +15,7 @@ __title__ = 'cpl_core.pipes' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev8' from collections import namedtuple @@ -29,4 +29,4 @@ from .to_camel_case_pipe import ToCamelCasePipe from .to_snake_case_pipe import ToSnakeCasePipe VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev8') diff --git a/src/cpl_core/time/__init__.py b/src/cpl_core/time/__init__.py index 7f72b984..b6e833e1 100644 --- a/src/cpl_core/time/__init__.py +++ b/src/cpl_core/time/__init__.py @@ -15,7 +15,7 @@ __title__ = 'cpl_core.time' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev8' from collections import namedtuple @@ -24,4 +24,4 @@ from .time_format_settings import TimeFormatSettings from .time_format_settings_names_enum import TimeFormatSettingsNamesEnum VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev8') diff --git a/src/cpl_core/utils/__init__.py b/src/cpl_core/utils/__init__.py index 99a83653..4f51d293 100644 --- a/src/cpl_core/utils/__init__.py +++ b/src/cpl_core/utils/__init__.py @@ -15,7 +15,7 @@ __title__ = 'cpl_core.utils' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2020 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev8' from collections import namedtuple @@ -25,4 +25,4 @@ from .string import String from .pip import Pip VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev8') diff --git a/src/cpl_query/__init__.py b/src/cpl_query/__init__.py index d1767b45..f4bc40d2 100644 --- a/src/cpl_query/__init__.py +++ b/src/cpl_query/__init__.py @@ -15,11 +15,11 @@ __title__ = 'cpl_query' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev8' from collections import namedtuple # imports: VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev8') diff --git a/src/cpl_query/_query/__init__.py b/src/cpl_query/_query/__init__.py index 77edb5f1..059cab97 100644 --- a/src/cpl_query/_query/__init__.py +++ b/src/cpl_query/_query/__init__.py @@ -15,11 +15,11 @@ __title__ = 'cpl_query._query' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev8' from collections import namedtuple # imports: VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev8') diff --git a/src/cpl_query/cpl-query.json b/src/cpl_query/cpl-query.json index 97472344..355d295b 100644 --- a/src/cpl_query/cpl-query.json +++ b/src/cpl_query/cpl-query.json @@ -4,7 +4,7 @@ "Version": { "Major": "2022", "Minor": "6", - "Micro": "16.dev2" + "Micro": "17.dev8" }, "Author": "Sven Heidemann", "AuthorEmail": "sven.heidemann@sh-edraft.de", @@ -15,9 +15,7 @@ "CopyrightName": "sh-edraft.de", "LicenseName": "MIT", "LicenseDescription": "MIT, see LICENSE for more details.", - "Dependencies": [ - "cpl-core>=2022.6.16.dev2" - ], + "Dependencies": [], "PythonVersion": ">=3.10", "PythonPath": {}, "Classifiers": [] diff --git a/src/cpl_query/extension/__init__.py b/src/cpl_query/extension/__init__.py index de7ba7dd..76f7b2c6 100644 --- a/src/cpl_query/extension/__init__.py +++ b/src/cpl_query/extension/__init__.py @@ -15,7 +15,7 @@ __title__ = 'cpl_query.extension' __author__ = 'Sven Heidemann' __license__ = 'MIT' __copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de' -__version__ = '2022.6.16.dev2' +__version__ = '2022.6.17.dev8' from collections import namedtuple @@ -27,4 +27,4 @@ from .ordered_iterable_abc import OrderedIterableABC from .ordered_iterable import OrderedIterable VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major='2022', minor='6', micro='16.dev2') +version_info = VersionInfo(major='2022', minor='6', micro='17.dev8') diff --git a/src/cpl_query/tests/__init__.py b/src/cpl_query/tests/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/src/cpl_query/tests/tester.py b/src/cpl_query/tests/tester.py deleted file mode 100644 index 084071c3..00000000 --- a/src/cpl_query/tests/tester.py +++ /dev/null @@ -1,25 +0,0 @@ -import unittest - -from cpl_query.tests.iterable_test import IterableTest -from cpl_query.tests.query_test import QueryTest - - -class Tester: - - def __init__(self): - self._suite = unittest.TestSuite() - - def create(self): - loader = unittest.TestLoader() - self._suite.addTests(loader.loadTestsFromTestCase(QueryTest)) - self._suite.addTests(loader.loadTestsFromTestCase(IterableTest)) - - def start(self): - runner = unittest.TextTestRunner() - runner.run(self._suite) - - -if __name__ == '__main__': - tester = Tester() - tester.create() - tester.start() diff --git a/src/tests/__init__.py b/src/tests/__init__.py deleted file mode 100644 index 71ee2167..00000000 --- a/src/tests/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -sh_cpl sh-edraft Common Python library -~~~~~~~~~~~~~~~~~~~ - -sh-edraft Common Python library - -:copyright: (c) 2020 - 2021 sh-edraft.de -:license: MIT, see LICENSE for more details. - -""" - -__title__ = 'sh_cpl.tests' -__author__ = 'Sven Heidemann' -__license__ = 'MIT' -__copyright__ = 'Copyright (c) 2020 - 2021 sh-edraft.de' -__version__ = '2021.4.1' - -from collections import namedtuple - -# imports: - -VersionInfo = namedtuple('VersionInfo', 'major minor micro') -version_info = VersionInfo(major=2021, minor=4, micro=1) diff --git a/tools/set_pip_urls/set-pip-urls.json b/tools/set_pip_urls/set-pip-urls.json index 4a56be00..644962a9 100644 --- a/tools/set_pip_urls/set-pip-urls.json +++ b/tools/set_pip_urls/set-pip-urls.json @@ -16,7 +16,7 @@ "LicenseName": "MIT", "LicenseDescription": "MIT, see LICENSE for more details.", "Dependencies": [ - "cpl-core>=2022.6.16.dev2" + "cpl-core>=2022.6.17.dev8" ], "PythonVersion": ">=3.10.4", "PythonPath": {}, diff --git a/tools/set_version/application.py b/tools/set_version/application.py index 3ad1b23a..f052750e 100644 --- a/tools/set_version/application.py +++ b/tools/set_version/application.py @@ -1,5 +1,8 @@ +import os import traceback +from cpl_core.utils import String + from cpl_cli.configuration.version_settings_name_enum import VersionSettingsNameEnum from cpl_cli.configuration.workspace_settings import WorkspaceSettings from cpl_core.application.application_abc import ApplicationABC @@ -27,10 +30,16 @@ class Application(ApplicationABC): def main(self): Console.write_line('Set versions:') + args = self._configuration.additional_arguments version = {} branch = "" suffix = "" + force = False + if '--force' in args: + args.remove('--force') + force = True + if len(args) > 1: Console.error(f'Unexpected argument(s): {", ".join(args[1:])}') return @@ -53,11 +62,25 @@ class Application(ApplicationABC): Console.error(f'Branch {branch} does not contain valid version') return + diff_paths = [] + for file in self._git_service.get_diff_files(): + if '/' in file: + diff_paths.append(file.split('/')[1]) + else: + diff_paths.append(os.path.basename(os.path.dirname(file))) + try: + skipped = [] for project in self._workspace.projects: + if project not in diff_paths and String.convert_to_snake_case(project) not in diff_paths and not force: + Console.write_line(f'Skipping {project} due to missing changes') + skipped.append(project) + continue + Console.write_line(f'Set dependencies {self._version_pipe.transform(version)} for {project}') - self._version_setter.set_dependencies(self._workspace.projects[project], version) - if not project.startswith('cpl'): + self._version_setter.set_dependencies(self._workspace.projects[project], version, skipped=skipped) + if not project.startswith('cpl') and not project.startswith('unittest'): + Console.write_line(f'Skipping {project}') continue Console.write_line(f'Set version {self._version_pipe.transform(version)} for {project}') diff --git a/tools/set_version/git_service.py b/tools/set_version/git_service.py index 263cde5b..0e43b226 100644 --- a/tools/set_version/git_service.py +++ b/tools/set_version/git_service.py @@ -1,4 +1,4 @@ -import os +from git import Repo, DiffIndex from cpl_core.environment import ApplicationEnvironmentABC @@ -7,12 +7,11 @@ class GitService: def __init__(self, env: ApplicationEnvironmentABC): self._env = env + self._repo = Repo(env.working_directory) def get_active_branch_name(self) -> str: - head_dir = os.path.join(self._env.working_directory, '.git/HEAD') - with open(head_dir, 'r') as f: - content = f.read().splitlines() + branch = self._repo.active_branch + return branch.name - for line in content: - if line[0:4] == "ref:": - return line.partition("refs/heads/")[2] + def get_diff_files(self) -> list[str]: + return [item.a_path for item in self._repo.index.diff(None)] diff --git a/tools/set_version/set-version.json b/tools/set_version/set-version.json index 27374888..5ac3d70b 100644 --- a/tools/set_version/set-version.json +++ b/tools/set_version/set-version.json @@ -16,7 +16,8 @@ "LicenseName": "MIT", "LicenseDescription": "MIT, see LICENSE for more details.", "Dependencies": [ - "cpl-core>=2022.6.16.dev2" + "cpl-core>=2022.6.17.dev8", + "gitpython==3.1.27" ], "PythonVersion": ">=3.10.4", "PythonPath": {}, diff --git a/tools/set_version/startup.py b/tools/set_version/startup.py index 31c8a268..609ef337 100644 --- a/tools/set_version/startup.py +++ b/tools/set_version/startup.py @@ -25,7 +25,7 @@ class Startup(StartupABC): def configure_services(self, services: ServiceCollectionABC, environment: ApplicationEnvironment) -> ServiceProviderABC: services.add_pipes() - services.add_transient(GitService) + services.add_singleton(GitService) services.add_transient(VersionSetterService) return services.build_service_provider() diff --git a/tools/set_version/version_setter_service.py b/tools/set_version/version_setter_service.py index fcc3efaa..0ae94c93 100644 --- a/tools/set_version/version_setter_service.py +++ b/tools/set_version/version_setter_service.py @@ -1,5 +1,8 @@ import json import os +from string import ascii_letters + +from cpl_core.utils import String from cpl_core.console import Console @@ -30,7 +33,7 @@ class VersionSetterService: project_json['ProjectSettings']['Version'] = version self._write_file(file, project_json) - def set_dependencies(self, file: str, version: dict): + def set_dependencies(self, file: str, version: dict, skipped=None): project_json = self._read_file(file) dependencies = project_json['ProjectSettings']['Dependencies'] new_deps = [] @@ -40,6 +43,13 @@ class VersionSetterService: continue dep_version = dependency.split('=')[1] + dep_name = dependency.split('=')[0] + if dep_name[len(dep_name)-1] not in ascii_letters: + dep_name = dep_name[:len(dep_name)-1] + + if skipped is not None and (dep_name in skipped or String.convert_to_snake_case(dep_name) in skipped): + new_deps.append(dependency) + continue new_deps.append(dependency.replace(dep_version, f'{version["Major"]}.{version["Minor"]}.{version["Micro"]}')) project_json['ProjectSettings']['Dependencies'] = new_deps diff --git a/unittests/unittests/__init__.py b/unittests/unittests/__init__.py new file mode 100644 index 00000000..ad5eca30 --- /dev/null +++ b/unittests/unittests/__init__.py @@ -0,0 +1 @@ +# imports: diff --git a/unittests/unittests/application.py b/unittests/unittests/application.py new file mode 100644 index 00000000..9ec49cc6 --- /dev/null +++ b/unittests/unittests/application.py @@ -0,0 +1,21 @@ +import unittest + +from cpl_core.application import ApplicationABC +from cpl_core.configuration import ConfigurationABC +from cpl_core.dependency_injection import ServiceProviderABC +from unittests_cli.cli_test_suite import CLITestSuite +from unittests_query.query_test_suite import QueryTestSuite + + +class Application(ApplicationABC): + + def __init__(self, config: ConfigurationABC, services: ServiceProviderABC): + ApplicationABC.__init__(self, config, services) + + def configure(self): + pass + + def main(self): + runner = unittest.TextTestRunner() + runner.run(CLITestSuite()) + runner.run(QueryTestSuite()) diff --git a/unittests/unittests/main.py b/unittests/unittests/main.py new file mode 100644 index 00000000..5fae2bbb --- /dev/null +++ b/unittests/unittests/main.py @@ -0,0 +1,11 @@ +from cpl_core.application import ApplicationBuilder +from unittests.application import Application + + +def main(): + app_builder = ApplicationBuilder(Application) + app_builder.build().run() + + +if __name__ == '__main__': + main() diff --git a/unittests/unittests/unittests.json b/unittests/unittests/unittests.json new file mode 100644 index 00000000..1408486c --- /dev/null +++ b/unittests/unittests/unittests.json @@ -0,0 +1,43 @@ +{ + "ProjectSettings": { + "Name": "unittests", + "Version": { + "Major": "2022", + "Minor": "6", + "Micro": "17.dev8" + }, + "Author": "", + "AuthorEmail": "", + "Description": "", + "LongDescription": "", + "URL": "", + "CopyrightDate": "", + "CopyrightName": "", + "LicenseName": "", + "LicenseDescription": "", + "Dependencies": [ + "cpl-core>=2022.6.17.dev8" + ], + "PythonVersion": ">=3.10.4", + "PythonPath": { + "linux": "" + }, + "Classifiers": [] + }, + "BuildSettings": { + "ProjectType": "unittest", + "SourcePath": "", + "OutputPath": "../../dist", + "Main": "unittest.main", + "EntryPoint": "unittest", + "IncludePackageData": false, + "Included": [], + "Excluded": [ + "*/__pycache__", + "*/logs", + "*/tests" + ], + "PackageData": {}, + "ProjectReferences": [] + } +} \ No newline at end of file diff --git a/unittests/unittests_cli/__init__.py b/unittests/unittests_cli/__init__.py new file mode 100644 index 00000000..ad5eca30 --- /dev/null +++ b/unittests/unittests_cli/__init__.py @@ -0,0 +1 @@ +# imports: diff --git a/unittests/unittests_cli/add_test_case.py b/unittests/unittests_cli/add_test_case.py new file mode 100644 index 00000000..27964fbe --- /dev/null +++ b/unittests/unittests_cli/add_test_case.py @@ -0,0 +1,52 @@ +import json +import os +import shutil +import unittest + +from cpl_core.utils import String + +from unittests_cli.constants import PLAYGROUND_PATH +from unittests_shared.cli_commands import CLICommands + + +class AddTestCase(unittest.TestCase): + + def __init__(self, methodName: str): + unittest.TestCase.__init__(self, methodName) + self._source = 'add-test-project' + self._target = 'add-test-library' + self._project_file = f'src/{String.convert_to_snake_case(self._source)}/{self._source}.json' + + def _get_project_settings(self): + with open(os.path.join(os.getcwd(), self._project_file), 'r', encoding='utf-8') as cfg: + # load json + project_json = json.load(cfg) + cfg.close() + + return project_json + + def setUp(self): + os.chdir(os.path.abspath(PLAYGROUND_PATH)) + # create projects + CLICommands.new('console', self._source, '--ab', '--s') + os.chdir(os.path.join(os.getcwd(), self._source)) + CLICommands.new('console', self._target, '--ab', '--s') + + def cleanUp(self): + # remove projects + if not os.path.exists(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source))): + return + + shutil.rmtree(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source))) + + def test_add(self): + CLICommands.add(self._source, self._target) + settings = self._get_project_settings() + self.assertNotEqual(settings, {}) + self.assertIn('ProjectSettings', settings) + self.assertIn('ProjectReferences', settings['BuildSettings']) + self.assertIn('BuildSettings', settings) + self.assertIn( + f'../{String.convert_to_snake_case(self._target)}/{self._target}.json', + settings['BuildSettings']['ProjectReferences'] + ) diff --git a/unittests/unittests_cli/build_test_case.py b/unittests/unittests_cli/build_test_case.py new file mode 100644 index 00000000..e35d5cbd --- /dev/null +++ b/unittests/unittests_cli/build_test_case.py @@ -0,0 +1,88 @@ +import filecmp +import json +import os +import shutil +import unittest + +from cpl_core.utils import String + +from unittests_cli.constants import PLAYGROUND_PATH +from unittests_shared.cli_commands import CLICommands + + +class BuildTestCase(unittest.TestCase): + + def __init__(self, methodName: str): + unittest.TestCase.__init__(self, methodName) + self._source = 'build-test-source' + self._project_file = f'src/{String.convert_to_snake_case(self._source)}/{self._source}.json' + + def _get_project_settings(self): + with open(os.path.join(os.getcwd(), self._project_file), 'r', encoding='utf-8') as cfg: + # load json + project_json = json.load(cfg) + cfg.close() + + return project_json + + def _save_project_settings(self, settings: dict): + with open(os.path.join(os.getcwd(), self._project_file), 'w', encoding='utf-8') as project_file: + project_file.write(json.dumps(settings, indent=2)) + project_file.close() + + def setUp(self): + os.chdir(os.path.abspath(PLAYGROUND_PATH)) + # create projects + CLICommands.new('console', self._source, '--ab', '--s') + os.chdir(os.path.join(os.getcwd(), self._source)) + + def cleanUp(self): + # remove projects + if not os.path.exists(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source))): + return + + shutil.rmtree(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source))) + + def _are_dir_trees_equal(self, dir1, dir2): + """ + found at https://stackoverflow.com/questions/4187564/recursively-compare-two-directories-to-ensure-they-have-the-same-files-and-subdi + + Compare two directories recursively. Files in each directory are + assumed to be equal if their names and contents are equal. + + @param dir1: First directory path + @param dir2: Second directory path + + @return: True if the directory trees are the same and + there were no errors while accessing the directories or files, + False otherwise. + """ + + dirs_cmp = filecmp.dircmp(dir1, dir2) + if len(dirs_cmp.left_only) > 0 or len(dirs_cmp.right_only) > 0 or len(dirs_cmp.funny_files) > 0: + return False + + (_, mismatch, errors) = filecmp.cmpfiles(dir1, dir2, dirs_cmp.common_files, shallow=False) + + if len(mismatch) > 0 or len(errors) > 0: + return False + + for common_dir in dirs_cmp.common_dirs: + new_dir1 = os.path.join(dir1, common_dir) + new_dir2 = os.path.join(dir2, common_dir) + if not self._are_dir_trees_equal(new_dir1, new_dir2): + return False + + return True + + def test_build(self): + CLICommands.build() + dist_path = './dist' + full_dist_path = f'{dist_path}/{self._source}/build/{String.convert_to_snake_case(self._source)}' + self.assertTrue(os.path.exists(dist_path)) + self.assertTrue(os.path.exists(full_dist_path)) + self.assertFalse(self._are_dir_trees_equal(f'./src/{String.convert_to_snake_case(self._source)}', full_dist_path)) + with open(f'{full_dist_path}/{self._source}.json', 'w') as file: + file.write(json.dumps(self._get_project_settings(), indent=2)) + file.close() + self.assertTrue(self._are_dir_trees_equal(f'./src/{String.convert_to_snake_case(self._source)}', full_dist_path)) diff --git a/unittests/unittests_cli/cli_test_suite.py b/unittests/unittests_cli/cli_test_suite.py new file mode 100644 index 00000000..f26f3f3a --- /dev/null +++ b/unittests/unittests_cli/cli_test_suite.py @@ -0,0 +1,78 @@ +import os +import shutil +import traceback +import unittest +from typing import Optional +from unittest import TestResult + +from unittests_cli.add_test_case import AddTestCase +from unittests_cli.build_test_case import BuildTestCase +from unittests_cli.constants import PLAYGROUND_PATH +from unittests_cli.generate_test_case import GenerateTestCase +from unittests_cli.install_test_case import InstallTestCase +from unittests_cli.new_test_case import NewTestCase +from unittests_cli.publish_test_case import PublishTestCase +from unittests_cli.remove_test_case import RemoveTestCase +from unittests_cli.run_test_case import RunTestCase +from unittests_cli.start_test_case import StartTestCase +from unittests_cli.uninstall_test_case import UninstallTestCase +from unittests_cli.update_test_case import UpdateTestCase +from unittests_cli.version_test_case import VersionTestCase + + +class CLITestSuite(unittest.TestSuite): + + def __init__(self): + unittest.TestSuite.__init__(self) + + loader = unittest.TestLoader() + self._result: Optional[TestResult] = None + self._is_online = True + + active_tests = [ + # nothing needed + VersionTestCase, + GenerateTestCase, + NewTestCase, + # project needed + BuildTestCase, + PublishTestCase, + RunTestCase, + StartTestCase, + # workspace needed + AddTestCase, + RemoveTestCase + ] + + if self._is_online: + active_tests.append(InstallTestCase) + active_tests.append(UninstallTestCase) + active_tests.append(UpdateTestCase) + + for test in active_tests: + self.addTests(loader.loadTestsFromTestCase(test)) + + def _setup(self): + try: + if os.path.exists(PLAYGROUND_PATH): + shutil.rmtree(os.path.abspath(os.path.join(PLAYGROUND_PATH))) + + os.makedirs(PLAYGROUND_PATH) + os.chdir(PLAYGROUND_PATH) + except Exception as e: + print(f'Setup of {__name__} failed: {traceback.format_exc()}') + + def _cleanup(self): + try: + if self._result is not None and (len(self._result.errors) > 0 or len(self._result.failures) > 0): + return + + if os.path.exists(PLAYGROUND_PATH): + shutil.rmtree(os.path.abspath(os.path.join(PLAYGROUND_PATH))) + except Exception as e: + print(f'Cleanup of {__name__} failed: {traceback.format_exc()}') + + def run(self, *args): + self._setup() + self._result = super().run(*args) + self._cleanup() diff --git a/unittests/unittests_cli/constants.py b/unittests/unittests_cli/constants.py new file mode 100644 index 00000000..766d72c0 --- /dev/null +++ b/unittests/unittests_cli/constants.py @@ -0,0 +1,4 @@ +import os + +PLAYGROUND_PATH = os.path.abspath(os.path.join(os.getcwd(), '../test_cli_playground')) +CLI_PATH = os.path.abspath(os.path.join(os.getcwd(), '../../src/cpl_cli/main.py')) diff --git a/unittests/unittests_cli/custom_test_case.py b/unittests/unittests_cli/custom_test_case.py new file mode 100644 index 00000000..db59be7d --- /dev/null +++ b/unittests/unittests_cli/custom_test_case.py @@ -0,0 +1,10 @@ +import unittest + + +class CustomTestCase(unittest.TestCase): + + def setUp(self): + pass + + def test_equal(self): + pass diff --git a/unittests/unittests_cli/generate_test_case.py b/unittests/unittests_cli/generate_test_case.py new file mode 100644 index 00000000..53c03839 --- /dev/null +++ b/unittests/unittests_cli/generate_test_case.py @@ -0,0 +1,41 @@ +import os.path +import unittest + +from unittests_cli.constants import PLAYGROUND_PATH +from unittests_shared.cli_commands import CLICommands + + +class GenerateTestCase(unittest.TestCase): + + def _test_file(self, schematic: str, suffix: str): + CLICommands.generate(schematic, 'GeneratedFile') + file_path = os.path.abspath(os.path.join(PLAYGROUND_PATH, f'generated_file{suffix}.py')) + file_exists = os.path.exists(file_path) + self.assertTrue(file_exists) + + def test_abc(self): + self._test_file('abc', '_abc') + + def test_class(self): + self._test_file('class', '') + + def test_enum(self): + self._test_file('enum', '_enum') + + def test_pipe(self): + self._test_file('pipe', '_pipe') + + def test_service(self): + self._test_file('service', '_service') + + def test_settings(self): + self._test_file('settings', '_settings') + + def test_test_case(self): + self._test_file('test_case', '_test_case') + + def test_thread(self): + self._test_file('thread', '_thread') + + def test_validator(self): + self._test_file('validator', '_validator') diff --git a/unittests/unittests_cli/install_test_case.py b/unittests/unittests_cli/install_test_case.py new file mode 100644 index 00000000..ceefbf4f --- /dev/null +++ b/unittests/unittests_cli/install_test_case.py @@ -0,0 +1,93 @@ +import json +import os +import shutil +import subprocess +import sys +import unittest + +from cpl_core.utils import String +from unittests_cli.constants import PLAYGROUND_PATH +from unittests_shared.cli_commands import CLICommands + + +class InstallTestCase(unittest.TestCase): + + def __init__(self, methodName: str): + unittest.TestCase.__init__(self, methodName) + self._source = 'install-test-source' + self._project_file = f'src/{String.convert_to_snake_case(self._source)}/{self._source}.json' + + def _get_project_settings(self): + with open(os.path.join(os.getcwd(), self._project_file), 'r', encoding='utf-8') as cfg: + # load json + project_json = json.load(cfg) + cfg.close() + + return project_json + + def _save_project_settings(self, settings: dict): + with open(os.path.join(os.getcwd(), self._project_file), 'w', encoding='utf-8') as project_file: + project_file.write(json.dumps(settings, indent=2)) + project_file.close() + + def setUp(self): + os.chdir(os.path.abspath(PLAYGROUND_PATH)) + # create projects + CLICommands.new('console', self._source, '--ab', '--s') + os.chdir(os.path.join(os.getcwd(), self._source)) + + def cleanUp(self): + # remove projects + if not os.path.exists(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source))): + return + + shutil.rmtree(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source))) + + def _get_installed_packages(self) -> dict: + reqs = subprocess.check_output([sys.executable, '-m', 'pip', 'freeze']) + return dict([tuple(r.decode().split('==')) for r in reqs.split()]) + + def test_install_package(self): + version = '1.7.3' + package_name = 'discord.py' + package = f'{package_name}=={version}' + CLICommands.install(package) + settings = self._get_project_settings() + self.assertNotEqual(settings, {}) + self.assertIn('ProjectSettings', settings) + self.assertIn('Dependencies', settings['ProjectSettings']) + self.assertIn( + package, + settings['ProjectSettings']['Dependencies'] + ) + packages = self._get_installed_packages() + self.assertIn(package_name, packages) + self.assertEqual(version, packages[package_name]) + + def _test_install_all(self): + version = '1.7.3' + package_name = 'discord.py' + package = f'{package_name}=={version}' + settings = self._get_project_settings() + self.assertIn('ProjectSettings', settings) + self.assertIn('Dependencies', settings['ProjectSettings']) + self.assertNotIn( + package, + settings['ProjectSettings']['Dependencies'] + ) + settings['ProjectSettings']['Dependencies'].append(package) + self._save_project_settings(settings) + CLICommands.install() + new_settings = self._get_project_settings() + self.assertEqual(settings, new_settings) + self.assertIn('ProjectSettings', new_settings) + self.assertIn('Dependencies', new_settings['ProjectSettings']) + self.assertIn( + package, + new_settings['ProjectSettings']['Dependencies'] + ) + packages = self._get_installed_packages() + self.assertIn(package_name, packages) + self.assertEqual(version, packages[package_name]) + + diff --git a/unittests/unittests_cli/new_test_case.py b/unittests/unittests_cli/new_test_case.py new file mode 100644 index 00000000..4125993d --- /dev/null +++ b/unittests/unittests_cli/new_test_case.py @@ -0,0 +1,106 @@ +import json +import os +import unittest + +from cpl_core.utils import String +from unittests_cli.constants import PLAYGROUND_PATH +from unittests_shared.cli_commands import CLICommands + + +class NewTestCase(unittest.TestCase): + + def setUp(self): + os.chdir(os.path.abspath(PLAYGROUND_PATH)) + + def _test_project(self, project_type: str, name: str, *args): + CLICommands.new(project_type, name, *args) + workspace_path = os.path.abspath(os.path.join(PLAYGROUND_PATH, name)) + self.assertTrue(os.path.exists(workspace_path)) + + project_path = os.path.abspath(os.path.join(PLAYGROUND_PATH, name, 'src', String.convert_to_snake_case(name))) + self.assertTrue(os.path.exists(project_path)) + self.assertTrue(os.path.join(project_path, f'{name}.json')) + self.assertTrue(os.path.join(project_path, f'main.py')) + + if '--ab' in args: + self.assertTrue(os.path.isfile(os.path.join(project_path, f'application.py'))) + else: + self.assertFalse(os.path.isfile(os.path.join(project_path, f'application.py'))) + + # s depends on ab + if '--ab' in args and '--s' in args: + self.assertTrue(os.path.isfile(os.path.join(project_path, f'startup.py'))) + else: + self.assertFalse(os.path.isfile(os.path.join(project_path, f'startup.py'))) + + if project_type == 'unittest': + self.assertTrue(os.path.isfile(os.path.join(project_path, f'test_case.py'))) + else: + self.assertFalse(os.path.isfile(os.path.join(project_path, f'test_case.py'))) + + def _test_sub_project(self, project_type: str, name: str, workspace_name: str, *args): + os.chdir(os.path.abspath(os.path.join(os.getcwd(), workspace_name))) + CLICommands.new(project_type, name, *args) + workspace_path = os.path.abspath(os.path.join(PLAYGROUND_PATH, workspace_name)) + self.assertTrue(os.path.exists(workspace_path)) + + project_path = os.path.abspath(os.path.join(PLAYGROUND_PATH, workspace_name, 'src', String.convert_to_snake_case(name))) + self.assertTrue(os.path.exists(project_path)) + self.assertTrue(os.path.join(project_path, f'{name}.json')) + os.chdir(os.path.abspath(os.path.join(os.getcwd(), '../'))) + + def _test_sub_directory_project(self, project_type: str, directory: str, name: str, workspace_name: str, *args): + os.chdir(os.path.abspath(os.path.join(os.getcwd(), workspace_name))) + CLICommands.new(project_type, f'{directory}/{name}', *args) + workspace_path = os.path.abspath(os.path.join(PLAYGROUND_PATH, workspace_name)) + self.assertTrue(os.path.exists(workspace_path)) + + project_path = os.path.abspath(os.path.join(PLAYGROUND_PATH, workspace_name, f'src/{directory}', String.convert_to_snake_case(name))) + self.assertTrue(os.path.exists(project_path)) + project_file = os.path.join(project_path, f'{name}.json') + self.assertTrue(os.path.exists(project_file)) + with open(project_file, 'r', encoding='utf-8') as cfg: + # load json + project_json = json.load(cfg) + cfg.close() + + project_settings = project_json['ProjectSettings'] + build_settings = project_json['BuildSettings'] + + self.assertEqual(project_settings['Name'], name) + self.assertEqual(build_settings['ProjectType'], 'library') + self.assertEqual(build_settings['OutputPath'], '../../dist') + self.assertEqual(build_settings['Main'], f'{String.convert_to_snake_case(name)}.main') + self.assertEqual(build_settings['EntryPoint'], name) + + os.chdir(os.path.abspath(os.path.join(os.getcwd(), '../'))) + + def test_console(self): + self._test_project('console', 'test-console', '--ab', '--s') + + def test_console_without_s(self): + self._test_project('console', 'test-console-without-s', '--ab') + + def test_console_without_ab(self): + self._test_project('console', 'test-console-without-ab', '--sp') + + def test_console_without_anything(self): + self._test_project('console', 'test-console-without-anything', '--n') + + def test_sub_console(self): + self._test_sub_project('console', 'test-sub-console', 'test-console', '--ab', '--s', '--sp') + + def test_library(self): + self._test_project('library', 'test-library', '--ab', '--s', '--sp') + + def test_sub_library(self): + self._test_sub_project('library', 'test-sub-library', 'test-console', '--ab', '--s', '--sp') + + def test_sub_directory_library(self): + self._test_sub_directory_project('library', 'directory', 'test-sub-library', 'test-console', '--ab', '--s', '--sp') + + def test_unittest(self): + self._test_project('unittest', 'test-unittest', '--ab') + + def test_sub_unittest(self): + self._test_sub_project('unittest', 'test-unittest', 'test-console', '--ab', '--s', '--sp') diff --git a/unittests/unittests_cli/publish_test_case.py b/unittests/unittests_cli/publish_test_case.py new file mode 100644 index 00000000..7c828ced --- /dev/null +++ b/unittests/unittests_cli/publish_test_case.py @@ -0,0 +1,92 @@ +import filecmp +import json +import os +import shutil +import unittest + +from cpl_core.utils import String + +from unittests_cli.constants import PLAYGROUND_PATH +from unittests_shared.cli_commands import CLICommands + + +class PublishTestCase(unittest.TestCase): + + def __init__(self, methodName: str): + unittest.TestCase.__init__(self, methodName) + self._source = 'publish-test-source' + self._project_file = f'src/{String.convert_to_snake_case(self._source)}/{self._source}.json' + + def _get_project_settings(self): + with open(os.path.join(os.getcwd(), self._project_file), 'r', encoding='utf-8') as cfg: + # load json + project_json = json.load(cfg) + cfg.close() + + return project_json + + def _save_project_settings(self, settings: dict): + with open(os.path.join(os.getcwd(), self._project_file), 'w', encoding='utf-8') as project_file: + project_file.write(json.dumps(settings, indent=2)) + project_file.close() + + def setUp(self): + os.chdir(os.path.abspath(PLAYGROUND_PATH)) + # create projects + CLICommands.new('console', self._source, '--ab', '--s') + os.chdir(os.path.join(os.getcwd(), self._source)) + + def cleanUp(self): + # remove projects + if not os.path.exists(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source))): + return + + shutil.rmtree(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source))) + + def _are_dir_trees_equal(self, dir1, dir2): + """ + found at https://stackoverflow.com/questions/4187564/recursively-compare-two-directories-to-ensure-they-have-the-same-files-and-subdi + + Compare two directories recursively. Files in each directory are + assumed to be equal if their names and contents are equal. + + @param dir1: First directory path + @param dir2: Second directory path + + @return: True if the directory trees are the same and + there were no errors while accessing the directories or files, + False otherwise. + """ + + dirs_cmp = filecmp.dircmp(dir1, dir2) + if len(dirs_cmp.left_only) > 0 or len(dirs_cmp.right_only) > 0 or len(dirs_cmp.funny_files) > 0: + return False + + (_, mismatch, errors) = filecmp.cmpfiles(dir1, dir2, dirs_cmp.common_files, shallow=False) + + if len(mismatch) > 0 or len(errors) > 0: + return False + + for common_dir in dirs_cmp.common_dirs: + new_dir1 = os.path.join(dir1, common_dir) + new_dir2 = os.path.join(dir2, common_dir) + if not self._are_dir_trees_equal(new_dir1, new_dir2): + return False + + return True + + def test_publish(self): + CLICommands.publish() + dist_path = './dist' + setup_path = f'{dist_path}/{self._source}/publish/setup' + full_dist_path = f'{dist_path}/{self._source}/publish/build/lib/{String.convert_to_snake_case(self._source)}' + self.assertTrue(os.path.exists(dist_path)) + self.assertTrue(os.path.exists(setup_path)) + self.assertTrue(os.path.exists(os.path.join(setup_path, f'{self._source}-0.0.0.tar.gz'))) + self.assertTrue(os.path.exists(os.path.join(setup_path, f'{String.convert_to_snake_case(self._source)}-0.0.0-py3-none-any.whl'))) + self.assertTrue(os.path.exists(full_dist_path)) + self.assertFalse(self._are_dir_trees_equal(f'./src/{String.convert_to_snake_case(self._source)}', full_dist_path)) + with open(f'{full_dist_path}/{self._source}.json', 'w') as file: + file.write(json.dumps(self._get_project_settings(), indent=2)) + file.close() + self.assertTrue(self._are_dir_trees_equal(f'./src/{String.convert_to_snake_case(self._source)}', full_dist_path)) diff --git a/unittests/unittests_cli/remove_test_case.py b/unittests/unittests_cli/remove_test_case.py new file mode 100644 index 00000000..81aa8ee0 --- /dev/null +++ b/unittests/unittests_cli/remove_test_case.py @@ -0,0 +1,47 @@ +import json +import os +import unittest + +from cpl_core.utils import String +from unittests_cli.constants import PLAYGROUND_PATH +from unittests_shared.cli_commands import CLICommands + + +class RemoveTestCase(unittest.TestCase): + + def __init__(self, methodName: str): + unittest.TestCase.__init__(self, methodName) + self._source = 'add-test-project' + self._target = 'add-test-library' + self._project_file = f'src/{String.convert_to_snake_case(self._source)}/{self._source}.json' + + def _get_project_settings(self): + with open(os.path.join(os.getcwd(), self._project_file), 'r', encoding='utf-8') as cfg: + # load json + project_json = json.load(cfg) + cfg.close() + + return project_json + + def setUp(self): + os.chdir(os.path.abspath(PLAYGROUND_PATH)) + # create projects + CLICommands.new('console', self._source, '--ab', '--s') + os.chdir(os.path.join(os.getcwd(), self._source)) + CLICommands.new('console', self._target, '--ab', '--s') + CLICommands.add(self._source, self._target) + + def test_remove(self): + CLICommands.remove(self._target) + path = os.path.abspath(os.path.join(os.getcwd(), f'../{String.convert_to_snake_case(self._target)}')) + self.assertTrue(os.path.exists(os.getcwd())) + self.assertTrue(os.path.exists(os.path.join(os.getcwd(), self._project_file))) + self.assertFalse(os.path.exists(path)) + settings = self._get_project_settings() + self.assertIn('ProjectSettings', settings) + self.assertIn('ProjectReferences', settings['BuildSettings']) + self.assertIn('BuildSettings', settings) + self.assertNotIn( + f'../{String.convert_to_snake_case(self._target)}/{self._target}.json', + settings['BuildSettings']['ProjectReferences'] + ) diff --git a/unittests/unittests_cli/run_test_case.py b/unittests/unittests_cli/run_test_case.py new file mode 100644 index 00000000..1d86b68d --- /dev/null +++ b/unittests/unittests_cli/run_test_case.py @@ -0,0 +1,91 @@ +import json +import os +import shutil +import subprocess +import sys +import unittest + +import pkg_resources + +from cpl_core.utils import String + +from unittests_cli.constants import PLAYGROUND_PATH +from unittests_shared.cli_commands import CLICommands + + +class RunTestCase(unittest.TestCase): + + def __init__(self, methodName: str): + unittest.TestCase.__init__(self, methodName) + self._source = 'run-test' + self._project_file = f'src/{String.convert_to_snake_case(self._source)}/{self._source}.json' + self._appsettings = f'src/{String.convert_to_snake_case(self._source)}/appsettings.json' + self._application = f'src/{String.convert_to_snake_case(self._source)}/application.py' + self._test_code = f""" + import json + settings = dict() + with open('appsettings.json', 'r', encoding='utf-8') as cfg: + # load json + settings = json.load(cfg) + cfg.close() + + settings['RunTest']['WasStarted'] = 'True' + + with open('appsettings.json', 'w', encoding='utf-8') as project_file: + project_file.write(json.dumps(settings, indent=2)) + project_file.close() + """ + + def _get_appsettings(self): + with open(os.path.join(os.getcwd(), self._appsettings), 'r', encoding='utf-8') as cfg: + # load json + project_json = json.load(cfg) + cfg.close() + + return project_json + + def _save_appsettings(self, settings: dict): + with open(os.path.join(os.getcwd(), self._appsettings), 'w', encoding='utf-8') as project_file: + project_file.write(json.dumps(settings, indent=2)) + project_file.close() + + def setUp(self): + os.chdir(os.path.abspath(PLAYGROUND_PATH)) + # create projects + CLICommands.new('console', self._source, '--ab', '--s') + os.chdir(os.path.join(os.getcwd(), self._source)) + settings = {'RunTest': {'WasStarted': 'False'}} + self._save_appsettings(settings) + with open(os.path.join(os.getcwd(), self._application), 'a', encoding='utf-8') as file: + file.write(f'\t\t{self._test_code}') + file.close() + + def cleanUp(self): + # remove projects + if not os.path.exists(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source))): + return + + shutil.rmtree(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source))) + + def test_run(self): + CLICommands.run() + settings = self._get_appsettings() + self.assertNotEqual(settings, {}) + self.assertIn('RunTest', settings) + self.assertIn('WasStarted', settings['RunTest']) + self.assertEqual( + 'True', + settings['RunTest']['WasStarted'] + ) + + def test_run_by_project(self): + os.chdir(os.path.join(os.getcwd())) + CLICommands.run(self._source) + settings = self._get_appsettings() + self.assertNotEqual(settings, {}) + self.assertIn('RunTest', settings) + self.assertIn('WasStarted', settings['RunTest']) + self.assertEqual( + 'True', + settings['RunTest']['WasStarted'] + ) diff --git a/unittests/unittests_cli/start_test_case.py b/unittests/unittests_cli/start_test_case.py new file mode 100644 index 00000000..f41eb450 --- /dev/null +++ b/unittests/unittests_cli/start_test_case.py @@ -0,0 +1,101 @@ +import json +import os +import shutil +import time +import unittest + +from cpl_core.utils import String +from unittests_cli.constants import PLAYGROUND_PATH +from unittests_cli.threads.start_test_thread import StartTestThread +from unittests_shared.cli_commands import CLICommands + + +class StartTestCase(unittest.TestCase): + + def __init__(self, methodName: str): + unittest.TestCase.__init__(self, methodName) + self._source = 'start-test' + self._project_file = f'src/{String.convert_to_snake_case(self._source)}/{self._source}.json' + self._appsettings = f'src/{String.convert_to_snake_case(self._source)}/appsettings.json' + self._application = f'src/{String.convert_to_snake_case(self._source)}/application.py' + self._test_code = f""" + import json + settings = dict() + with open('appsettings.json', 'r', encoding='utf-8') as cfg: + # load json + settings = json.load(cfg) + cfg.close() + + if settings['RunTest']['WasStarted'] == 'True': + settings['RunTest']['WasRestarted'] = 'True' + + settings['RunTest']['WasStarted'] = 'True' + + with open('appsettings.json', 'w', encoding='utf-8') as project_file: + project_file.write(json.dumps(settings, indent=2)) + project_file.close() + """ + + def _get_appsettings(self): + with open(os.path.join(os.getcwd(), self._appsettings), 'r', encoding='utf-8') as cfg: + # load json + project_json = json.load(cfg) + cfg.close() + + return project_json + + def _save_appsettings(self, settings: dict): + with open(os.path.join(os.getcwd(), self._appsettings), 'w', encoding='utf-8') as project_file: + project_file.write(json.dumps(settings, indent=2)) + project_file.close() + + def setUp(self): + os.chdir(os.path.abspath(PLAYGROUND_PATH)) + # create projects + CLICommands.new('console', self._source, '--ab', '--s') + os.chdir(os.path.join(os.getcwd(), self._source)) + settings = {'RunTest': {'WasStarted': 'False', 'WasRestarted': 'False'}} + self._save_appsettings(settings) + with open(os.path.join(os.getcwd(), self._application), 'a', encoding='utf-8') as file: + file.write(f'\t\t{self._test_code}') + file.close() + + def cleanUp(self): + # remove projects + if not os.path.exists(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source))): + return + + shutil.rmtree(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source))) + + def test_start(self): + thread = StartTestThread() + thread.start() + time.sleep(1) + settings = self._get_appsettings() + self.assertNotEqual(settings, {}) + self.assertIn('RunTest', settings) + self.assertIn('WasStarted', settings['RunTest']) + self.assertEqual( + 'True', + settings['RunTest']['WasStarted'] + ) + + with open(os.path.join(os.getcwd(), self._application), 'a', encoding='utf-8') as file: + file.write(f'# trigger restart (comment generated by unittest)') + file.close() + + time.sleep(1) + + settings = self._get_appsettings() + self.assertNotEqual(settings, {}) + self.assertIn('RunTest', settings) + self.assertIn('WasStarted', settings['RunTest']) + self.assertIn('WasRestarted', settings['RunTest']) + self.assertEqual( + 'True', + settings['RunTest']['WasStarted'] + ) + self.assertEqual( + 'True', + settings['RunTest']['WasRestarted'] + ) diff --git a/unittests/unittests_cli/threads/__init__.py b/unittests/unittests_cli/threads/__init__.py new file mode 100644 index 00000000..425ab6c1 --- /dev/null +++ b/unittests/unittests_cli/threads/__init__.py @@ -0,0 +1 @@ +# imports diff --git a/unittests/unittests_cli/threads/start_test_thread.py b/unittests/unittests_cli/threads/start_test_thread.py new file mode 100644 index 00000000..6c413e6d --- /dev/null +++ b/unittests/unittests_cli/threads/start_test_thread.py @@ -0,0 +1,12 @@ +import threading + +from unittests_shared.cli_commands import CLICommands + + +class StartTestThread(threading.Thread): + + def __init__(self): + threading.Thread.__init__(self, daemon=True) + + def run(self): + CLICommands.start(True) diff --git a/unittests/unittests_cli/uninstall_test_case.py b/unittests/unittests_cli/uninstall_test_case.py new file mode 100644 index 00000000..ac29aaf3 --- /dev/null +++ b/unittests/unittests_cli/uninstall_test_case.py @@ -0,0 +1,60 @@ +import json +import os +import shutil +import subprocess +import sys +import unittest + +from cpl_core.utils import String +from unittests_cli.constants import PLAYGROUND_PATH +from unittests_shared.cli_commands import CLICommands + + +class UninstallTestCase(unittest.TestCase): + + def __init__(self, methodName: str): + unittest.TestCase.__init__(self, methodName) + self._source = 'uninstall-test-source' + self._project_file = f'src/{String.convert_to_snake_case(self._source)}/{self._source}.json' + self._version = '1.7.3' + self._package_name = 'discord.py' + self._package = f'{self._package_name}=={self._version}' + + def _get_project_settings(self): + with open(os.path.join(os.getcwd(), self._project_file), 'r', encoding='utf-8') as cfg: + # load json + project_json = json.load(cfg) + cfg.close() + + return project_json + + def setUp(self): + os.chdir(os.path.abspath(PLAYGROUND_PATH)) + # create projects + CLICommands.new('console', self._source, '--ab', '--s') + os.chdir(os.path.join(os.getcwd(), self._source)) + CLICommands.install(self._package) + + def cleanUp(self): + # remove projects + if not os.path.exists(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source))): + return + + shutil.rmtree(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source))) + + def _get_installed_packages(self) -> dict: + reqs = subprocess.check_output([sys.executable, '-m', 'pip', 'freeze']) + return dict([tuple(r.decode().split('==')) for r in reqs.split()]) + + def test_uninstall(self): + CLICommands.uninstall(self._package) + settings = self._get_project_settings() + self.assertNotEqual(settings, {}) + self.assertIn('ProjectSettings', settings) + self.assertIn('Dependencies', settings['ProjectSettings']) + self.assertNotIn( + self._package, + settings['ProjectSettings']['Dependencies'] + ) + packages = self._get_installed_packages() + self.assertNotIn(self._package_name, packages) diff --git a/unittests/unittests_cli/unittests_cli.json b/unittests/unittests_cli/unittests_cli.json new file mode 100644 index 00000000..eecb81c0 --- /dev/null +++ b/unittests/unittests_cli/unittests_cli.json @@ -0,0 +1,44 @@ +{ + "ProjectSettings": { + "Name": "unittest_cli", + "Version": { + "Major": "2022", + "Minor": "6", + "Micro": "17.dev10" + }, + "Author": "", + "AuthorEmail": "", + "Description": "", + "LongDescription": "", + "URL": "", + "CopyrightDate": "", + "CopyrightName": "", + "LicenseName": "", + "LicenseDescription": "", + "Dependencies": [ + "cpl-core>=2022.6.17.dev8", + "cpl-cli>=2022.6.17.dev10" + ], + "PythonVersion": ">=3.10.4", + "PythonPath": { + "linux": "" + }, + "Classifiers": [] + }, + "BuildSettings": { + "ProjectType": "library", + "SourcePath": "", + "OutputPath": "../../dist", + "Main": "unittest_cli.main", + "EntryPoint": "unittest_cli", + "IncludePackageData": false, + "Included": [], + "Excluded": [ + "*/__pycache__", + "*/logs", + "*/tests" + ], + "PackageData": {}, + "ProjectReferences": [] + } +} \ No newline at end of file diff --git a/unittests/unittests_cli/update_test_case.py b/unittests/unittests_cli/update_test_case.py new file mode 100644 index 00000000..36c6fd4f --- /dev/null +++ b/unittests/unittests_cli/update_test_case.py @@ -0,0 +1,88 @@ +import json +import os +import shutil +import subprocess +import sys +import unittest + +from cpl_core.utils import String +from unittests_cli.constants import PLAYGROUND_PATH +from unittests_shared.cli_commands import CLICommands + + +class UpdateTestCase(unittest.TestCase): + + def __init__(self, methodName: str): + unittest.TestCase.__init__(self, methodName) + self._source = 'install-test-source' + self._project_file = f'src/{String.convert_to_snake_case(self._source)}/{self._source}.json' + + self._old_version = '1.7.1' + self._old_package_name = 'discord.py' + self._old_package = f'{self._old_package_name}=={self._old_version}' + + self._new_version = '1.7.3' + self._new_package_name = 'discord.py' + self._new_package = f'{self._new_package_name}=={self._new_version}' + + def _get_project_settings(self): + with open(os.path.join(os.getcwd(), self._project_file), 'r', encoding='utf-8') as cfg: + # load json + project_json = json.load(cfg) + cfg.close() + + return project_json + + def _save_project_settings(self, settings: dict): + with open(os.path.join(os.getcwd(), self._project_file), 'w', encoding='utf-8') as project_file: + project_file.write(json.dumps(settings, indent=2)) + project_file.close() + + def setUp(self): + CLICommands.uninstall(self._old_package) + CLICommands.uninstall(self._new_package) + os.chdir(os.path.abspath(PLAYGROUND_PATH)) + # create projects + CLICommands.new('console', self._source, '--ab', '--s') + os.chdir(os.path.join(os.getcwd(), self._source)) + CLICommands.install(self._old_package) + + def cleanUp(self): + # remove projects + if not os.path.exists(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source))): + return + + shutil.rmtree(os.path.abspath(os.path.join(PLAYGROUND_PATH, self._source))) + + def _get_installed_packages(self) -> dict: + reqs = subprocess.check_output([sys.executable, '-m', 'pip', 'freeze']) + return dict([tuple(r.decode().split('==')) for r in reqs.split()]) + + def test_install_package(self): + settings = self._get_project_settings() + self.assertNotEqual(settings, {}) + self.assertIn('ProjectSettings', settings) + self.assertIn('Dependencies', settings['ProjectSettings']) + self.assertIn( + self._old_package, + settings['ProjectSettings']['Dependencies'] + ) + packages = self._get_installed_packages() + self.assertIn(self._old_package_name, packages) + self.assertEqual(self._old_version, packages[self._old_package_name]) + + CLICommands.update() + + settings = self._get_project_settings() + self.assertNotEqual(settings, {}) + self.assertIn('ProjectSettings', settings) + self.assertIn('Dependencies', settings['ProjectSettings']) + self.assertIn( + self._new_package, + settings['ProjectSettings']['Dependencies'] + ) + packages = self._get_installed_packages() + self.assertIn(self._new_package_name, packages) + self.assertEqual(self._new_version, packages[self._new_package_name]) + + diff --git a/unittests/unittests_cli/version_test_case.py b/unittests/unittests_cli/version_test_case.py new file mode 100644 index 00000000..73a7053a --- /dev/null +++ b/unittests/unittests_cli/version_test_case.py @@ -0,0 +1,97 @@ +import pkgutil +import platform +import sys +import textwrap +import unittest + +import pkg_resources +from art import text2art +from tabulate import tabulate + +import cpl_cli +from cpl_core.console import ForegroundColorEnum +from termcolor import colored + +from unittests_shared.cli_commands import CLICommands + + +class VersionTestCase(unittest.TestCase): + + def __init__(self, methodName: str): + unittest.TestCase.__init__(self, methodName) + self._block_banner = "" + self._block_version = "" + self._block_package_header = "" + self._block_cpl_packages = "" + self._block_packages = "" + self._name = "CPL CLI" + + def setUp(self): + pass + + def _get_version_output(self, version: str): + index = 0 + + for line in version.split('\n'): + if line == "": + continue + + if index <= 5: + self._block_banner += f'{line}\n' + + if 7 <= index <= 9: + self._block_version += f'{line}\n' + + if 10 <= index <= 15: + self._block_cpl_packages += f'{line}\n' + + if index >= 17: + self._block_packages += f'{line}\n' + + index += 1 + + def test_version(self): + version = CLICommands.version() + self._get_version_output(version) + reference_banner = colored(text2art(self._name), ForegroundColorEnum.yellow.value).split('\n') + reference_banner = "\n".join(reference_banner[:len(reference_banner) - 1]) + '\n' + self.assertEqual(reference_banner, self._block_banner) + + reference_version = [ + colored(f'{colored("Common Python library CLI: ")}{colored(cpl_cli.__version__)}'), + colored(f'{colored("Python: ")}{colored(f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}")}'), + colored(f'OS: {colored(f"{platform.system()} {platform.processor()}")}') + '\n' + ] + self.assertEqual('\n'.join(reference_version), self._block_version) + packages = [] + cpl_packages = [ + 'cpl_core', + 'cpl_cli', + 'cpl_query' + ] + for modname in cpl_packages: + module = pkgutil.find_loader(modname) + if module is None: + break + + module = module.load_module(modname) + if '__version__' in dir(module): + packages.append([f'{modname}', module.__version__]) + + reference_cpl_packages = [ + colored(colored(f'CPL packages:')), + colored(f'{tabulate(packages, headers=["Name", "Version"])}') + '\n' + ] + self.assertEqual('\n'.join(reference_cpl_packages), self._block_cpl_packages) + + packages = [] + dependencies = dict(tuple(str(ws).split()) for ws in pkg_resources.working_set) + for p in dependencies: + packages.append([p, dependencies[p]]) + + reference_packages = [ + colored(colored(f'Python packages:')), + colored(f'{tabulate(packages, headers=["Name", "Version"])}'), + '\x1b[0m\x1b[0m\n\x1b[0m\x1b[0m\n' # fix colored codes + ] + self.assertEqual('\n'.join(reference_packages), self._block_packages) diff --git a/unittests/unittests_core/__init__.py b/unittests/unittests_core/__init__.py new file mode 100644 index 00000000..ad5eca30 --- /dev/null +++ b/unittests/unittests_core/__init__.py @@ -0,0 +1 @@ +# imports: diff --git a/unittests/unittests_core/unittests_core.json b/unittests/unittests_core/unittests_core.json new file mode 100644 index 00000000..0286b34d --- /dev/null +++ b/unittests/unittests_core/unittests_core.json @@ -0,0 +1,43 @@ +{ + "ProjectSettings": { + "Name": "unittest_core", + "Version": { + "Major": "2022", + "Minor": "6", + "Micro": "17.dev8" + }, + "Author": "", + "AuthorEmail": "", + "Description": "", + "LongDescription": "", + "URL": "", + "CopyrightDate": "", + "CopyrightName": "", + "LicenseName": "", + "LicenseDescription": "", + "Dependencies": [ + "cpl-core>=2022.6.17.dev8" + ], + "PythonVersion": ">=3.10.4", + "PythonPath": { + "linux": "" + }, + "Classifiers": [] + }, + "BuildSettings": { + "ProjectType": "library", + "SourcePath": "", + "OutputPath": "../../dist", + "Main": "unittest_core.main", + "EntryPoint": "unittest_core", + "IncludePackageData": false, + "Included": [], + "Excluded": [ + "*/__pycache__", + "*/logs", + "*/tests" + ], + "PackageData": {}, + "ProjectReferences": [] + } +} \ No newline at end of file diff --git a/unittests/unittests_query/__init__.py b/unittests/unittests_query/__init__.py new file mode 100644 index 00000000..ad5eca30 --- /dev/null +++ b/unittests/unittests_query/__init__.py @@ -0,0 +1 @@ +# imports: diff --git a/src/cpl_query/tests/iterable_test.py b/unittests/unittests_query/iterable_test_case.py similarity index 91% rename from src/cpl_query/tests/iterable_test.py rename to unittests/unittests_query/iterable_test_case.py index a8936a88..2523f500 100644 --- a/src/cpl_query/tests/iterable_test.py +++ b/unittests/unittests_query/iterable_test_case.py @@ -3,7 +3,7 @@ import unittest from cpl_query.extension.list import List -class IterableTest(unittest.TestCase): +class IterableTestCase(unittest.TestCase): def setUp(self) -> None: self._list = List(int) diff --git a/src/cpl_query/tests/models.py b/unittests/unittests_query/models.py similarity index 100% rename from src/cpl_query/tests/models.py rename to unittests/unittests_query/models.py diff --git a/src/cpl_query/tests/query_test.py b/unittests/unittests_query/query_test_case.py similarity index 99% rename from src/cpl_query/tests/query_test.py rename to unittests/unittests_query/query_test_case.py index 9f1e48e2..00d4fed8 100644 --- a/src/cpl_query/tests/query_test.py +++ b/unittests/unittests_query/query_test_case.py @@ -5,10 +5,10 @@ from random import randint from cpl_core.utils import String from cpl_query.exceptions import InvalidTypeException, ArgumentNoneException from cpl_query.extension.list import List -from cpl_query.tests.models import User, Address +from unittests_query.models import User, Address -class QueryTest(unittest.TestCase): +class QueryTestCase(unittest.TestCase): def setUp(self) -> None: self._tests = List(User) diff --git a/unittests/unittests_query/query_test_suite.py b/unittests/unittests_query/query_test_suite.py new file mode 100644 index 00000000..35c3fe03 --- /dev/null +++ b/unittests/unittests_query/query_test_suite.py @@ -0,0 +1,17 @@ +import unittest + +from unittests_query.iterable_test_case import IterableTestCase +from unittests_query.query_test_case import QueryTestCase + + +class QueryTestSuite(unittest.TestSuite): + + def __init__(self): + unittest.TestSuite.__init__(self) + + loader = unittest.TestLoader() + self.addTests(loader.loadTestsFromTestCase(QueryTestCase)) + self.addTests(loader.loadTestsFromTestCase(IterableTestCase)) + + def run(self, *args): + super().run(*args) diff --git a/unittests/unittests_query/unittests_query.json b/unittests/unittests_query/unittests_query.json new file mode 100644 index 00000000..bbb2aa8f --- /dev/null +++ b/unittests/unittests_query/unittests_query.json @@ -0,0 +1,44 @@ +{ + "ProjectSettings": { + "Name": "unittest_query", + "Version": { + "Major": "2022", + "Minor": "6", + "Micro": "17.dev8" + }, + "Author": "", + "AuthorEmail": "", + "Description": "", + "LongDescription": "", + "URL": "", + "CopyrightDate": "", + "CopyrightName": "", + "LicenseName": "", + "LicenseDescription": "", + "Dependencies": [ + "cpl-core>=2022.6.17.dev8", + "cpl-query>=2022.6.17.dev8" + ], + "PythonVersion": ">=3.10.4", + "PythonPath": { + "linux": "" + }, + "Classifiers": [] + }, + "BuildSettings": { + "ProjectType": "library", + "SourcePath": "", + "OutputPath": "../../dist", + "Main": "unittest_query.main", + "EntryPoint": "unittest_query", + "IncludePackageData": false, + "Included": [], + "Excluded": [ + "*/__pycache__", + "*/logs", + "*/tests" + ], + "PackageData": {}, + "ProjectReferences": [] + } +} \ No newline at end of file diff --git a/unittests/unittests_shared/__init__.py b/unittests/unittests_shared/__init__.py new file mode 100644 index 00000000..ad5eca30 --- /dev/null +++ b/unittests/unittests_shared/__init__.py @@ -0,0 +1 @@ +# imports: diff --git a/unittests/unittests_shared/cli_commands.py b/unittests/unittests_shared/cli_commands.py new file mode 100644 index 00000000..a458390c --- /dev/null +++ b/unittests/unittests_shared/cli_commands.py @@ -0,0 +1,87 @@ +import os +import subprocess + +from unittests_cli.constants import CLI_PATH + + +class CLICommands: + + @staticmethod + def _run(cmd: str, *args, output=False): + env_vars = os.environ + env_vars['CPL_IS_UNITTEST'] = 'NO' if output else 'YES' + + command = ['python', CLI_PATH, cmd] + for arg in args: + command.append(arg) + + if output: + subprocess.run(command, env=env_vars) + else: + subprocess.run(command, env=env_vars, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, stdin=subprocess.DEVNULL) + + @staticmethod + def _run_with_output(cmd: str, *args) -> str: + env_vars = os.environ + env_vars['CPL_IS_UNITTEST'] = 'NO' + + command = ['python', CLI_PATH, cmd] + for arg in args: + command.append(arg) + + return subprocess.run(command, env=env_vars, check=True, capture_output=True, text=True).stdout + + @classmethod + def add(cls, source: str, target: str, output=False): + cls._run('add', source, target, output=output) + + @classmethod + def build(cls, output=False): + cls._run('build', output=output) + + @classmethod + def generate(cls, schematic: str, name: str, output=False): + cls._run('generate', schematic, name, output=output) + + @classmethod + def install(cls, package: str = None, output=False): + if package is None: + cls._run('install', output=output) + return + + cls._run('install', package, output=output) + + @classmethod + def new(cls, project_type: str, name: str, *args, output=False): + cls._run('new', project_type, name, *args, output=output) + + @classmethod + def publish(cls, output=False): + cls._run('publish', output=output) + + @classmethod + def remove(cls, project: str, output=False): + cls._run('remove', project, output=output) + + @classmethod + def run(cls, project: str = None, output=False): + if project is None: + cls._run('run', output=output) + return + cls._run('run', project, output=output) + + @classmethod + def start(cls, output=False): + cls._run('start', output=output) + + @classmethod + def uninstall(cls, package: str, output=False): + cls._run('uninstall', package, output=output) + + @classmethod + def update(cls, output=False): + cls._run('update', output=output) + + @classmethod + def version(cls) -> str: + return cls._run_with_output('version') diff --git a/unittests/unittests_shared/unittests_shared.json b/unittests/unittests_shared/unittests_shared.json new file mode 100644 index 00000000..89c58db2 --- /dev/null +++ b/unittests/unittests_shared/unittests_shared.json @@ -0,0 +1,43 @@ +{ + "ProjectSettings": { + "Name": "unittest_shared", + "Version": { + "Major": "2022", + "Minor": "6", + "Micro": "17.dev8" + }, + "Author": "", + "AuthorEmail": "", + "Description": "", + "LongDescription": "", + "URL": "", + "CopyrightDate": "", + "CopyrightName": "", + "LicenseName": "", + "LicenseDescription": "", + "Dependencies": [ + "cpl-core>=2022.6.17.dev8" + ], + "PythonVersion": ">=3.10.4", + "PythonPath": { + "linux": "" + }, + "Classifiers": [] + }, + "BuildSettings": { + "ProjectType": "library", + "SourcePath": "", + "OutputPath": "../../dist", + "Main": "unittest_shared.main", + "EntryPoint": "unittest_shared", + "IncludePackageData": false, + "Included": [], + "Excluded": [ + "*/__pycache__", + "*/logs", + "*/tests" + ], + "PackageData": {}, + "ProjectReferences": [] + } +} \ No newline at end of file