From 1b60debba751336947065a5f7312016b5b0c94a3 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Fri, 7 Apr 2023 13:42:20 +0200 Subject: [PATCH 01/14] Fixed cli schematics & added tests --- .../.cpl/schematic_application_extension.py | 3 ++- .../.cpl/schematic_startup_extension.py | 3 ++- src/cpl_cli/.cpl/schematic_test_case.py | 3 ++- unittests/unittests_core/core_test_suite.py | 24 +++++++++++++++++++ .../unittests_core/test_startup_extension.py | 16 +++++++++++++ unittests/unittests_core/utils/__init__.py | 0 .../utils/credential_manager_test_case.py | 10 ++++++++ .../unittests_core/utils/string_test_case.py | 10 ++++++++ 8 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 unittests/unittests_core/core_test_suite.py create mode 100644 unittests/unittests_core/test_startup_extension.py create mode 100644 unittests/unittests_core/utils/__init__.py create mode 100644 unittests/unittests_core/utils/credential_manager_test_case.py create mode 100644 unittests/unittests_core/utils/string_test_case.py diff --git a/src/cpl_cli/.cpl/schematic_application_extension.py b/src/cpl_cli/.cpl/schematic_application_extension.py index 4cbdb453..bb0a58b7 100644 --- a/src/cpl_cli/.cpl/schematic_application_extension.py +++ b/src/cpl_cli/.cpl/schematic_application_extension.py @@ -1,6 +1,7 @@ import textwrap from cpl_cli.abc.generate_schematic_abc import GenerateSchematicABC +from cpl_core.utils import String class ApplicationExtension(GenerateSchematicABC): @@ -22,7 +23,7 @@ class ApplicationExtension(GenerateSchematicABC): def run(self, config: ConfigurationABC, services: ServiceProviderABC): pass """ - x = self.build_code_str(code, Name=self._class_name) + x = self.build_code_str(code, Name=String.convert_to_camel_case(self._class_name)) return x @classmethod diff --git a/src/cpl_cli/.cpl/schematic_startup_extension.py b/src/cpl_cli/.cpl/schematic_startup_extension.py index 3bb74468..09455e78 100644 --- a/src/cpl_cli/.cpl/schematic_startup_extension.py +++ b/src/cpl_cli/.cpl/schematic_startup_extension.py @@ -1,6 +1,7 @@ import textwrap from cpl_cli.abc.generate_schematic_abc import GenerateSchematicABC +from cpl_core.utils import String class StartupExtension(GenerateSchematicABC): @@ -26,7 +27,7 @@ class StartupExtension(GenerateSchematicABC): def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): pass """ - x = self.build_code_str(code, Name=self._class_name) + x = self.build_code_str(code, Name=String.convert_to_camel_case(self._class_name)) return x @classmethod diff --git a/src/cpl_cli/.cpl/schematic_test_case.py b/src/cpl_cli/.cpl/schematic_test_case.py index a29144d4..cc6395e6 100644 --- a/src/cpl_cli/.cpl/schematic_test_case.py +++ b/src/cpl_cli/.cpl/schematic_test_case.py @@ -1,6 +1,7 @@ import textwrap from cpl_cli.abc.generate_schematic_abc import GenerateSchematicABC +from cpl_core.utils import String class TestCase(GenerateSchematicABC): @@ -20,7 +21,7 @@ class TestCase(GenerateSchematicABC): def test_equal(self): pass """ - return self.build_code_str(code, Name=self._class_name) + return self.build_code_str(code, Name=String.convert_to_camel_case(self._class_name)) @classmethod def register(cls): diff --git a/unittests/unittests_core/core_test_suite.py b/unittests/unittests_core/core_test_suite.py new file mode 100644 index 00000000..1b837049 --- /dev/null +++ b/unittests/unittests_core/core_test_suite.py @@ -0,0 +1,24 @@ +import unittest + +from unittests_core.utils.string_test_case import StringTestCase +from unittests_query.enumerable_query_test_case import EnumerableQueryTestCase +from unittests_query.enumerable_test_case import EnumerableTestCase +from unittests_query.iterable_query_test_case import IterableQueryTestCase +from unittests_query.iterable_test_case import IterableTestCase +from unittests_query.sequence_test_case import SequenceTestCase + + +class QueryTestSuite(unittest.TestSuite): + def __init__(self): + unittest.TestSuite.__init__(self) + + loader = unittest.TestLoader() + self.addTests(loader.loadTestsFromTestCase(StringTestCase)) + + def run(self, *args): + super().run(*args) + + +if __name__ == "__main__": + runner = unittest.TextTestRunner() + runner.run(QueryTestSuite()) diff --git a/unittests/unittests_core/test_startup_extension.py b/unittests/unittests_core/test_startup_extension.py new file mode 100644 index 00000000..7c1939f3 --- /dev/null +++ b/unittests/unittests_core/test_startup_extension.py @@ -0,0 +1,16 @@ +from cpl_core.application.startup_extension_abc import StartupExtensionABC +from cpl_core.configuration.configuration_abc import ConfigurationABC +from cpl_core.dependency_injection.service_collection_abc import ServiceCollectionABC +from cpl_core.environment.application_environment_abc import ApplicationEnvironmentABC + + +class TestStartup_extension(StartupExtensionABC): + + def __init__(self): + pass + + def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC): + pass + + def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): + pass diff --git a/unittests/unittests_core/utils/__init__.py b/unittests/unittests_core/utils/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/unittests/unittests_core/utils/credential_manager_test_case.py b/unittests/unittests_core/utils/credential_manager_test_case.py new file mode 100644 index 00000000..f1991eb4 --- /dev/null +++ b/unittests/unittests_core/utils/credential_manager_test_case.py @@ -0,0 +1,10 @@ +import unittest + + +class CredentialManagerTestCase(unittest.TestCase): + + def setUp(self): + pass + + def test_equal(self): + pass diff --git a/unittests/unittests_core/utils/string_test_case.py b/unittests/unittests_core/utils/string_test_case.py new file mode 100644 index 00000000..1fd4eddb --- /dev/null +++ b/unittests/unittests_core/utils/string_test_case.py @@ -0,0 +1,10 @@ +import unittest + + +class StringTestCase(unittest.TestCase): + + def setUp(self): + pass + + def test_equal(self): + pass -- 2.45.2 From 823d524a816bfffc405337c451056d092e8ffef1 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Fri, 7 Apr 2023 14:03:45 +0200 Subject: [PATCH 02/14] Added core.utils.string tests & fixed some functions --- src/cpl_core/utils/string.py | 10 ++++ .../unittests_core/test_startup_extension.py | 16 ------ .../unittests_core/utils/string_test_case.py | 52 ++++++++++++++++++- 3 files changed, 60 insertions(+), 18 deletions(-) delete mode 100644 unittests/unittests_core/test_startup_extension.py diff --git a/src/cpl_core/utils/string.py b/src/cpl_core/utils/string.py index cfeea681..31c0c483 100644 --- a/src/cpl_core/utils/string.py +++ b/src/cpl_core/utils/string.py @@ -37,9 +37,19 @@ class String: String converted to snake_case """ # convert to train-case to CamelCase + if "_" in chars: + chars = chars.replace("_", "-") + if "-" in chars: chars = "".join(word.title() for word in chars.split("-")) + if " " in chars: + new_chars = "" + for word in chars.split(" "): + new_chars += String.first_to_upper(word) + + chars = new_chars + pattern1 = re.compile(r"(.)([A-Z][a-z]+)") pattern2 = re.compile(r"([a-z0-9])([A-Z])") file_name = re.sub(pattern1, r"\1_\2", chars) diff --git a/unittests/unittests_core/test_startup_extension.py b/unittests/unittests_core/test_startup_extension.py deleted file mode 100644 index 7c1939f3..00000000 --- a/unittests/unittests_core/test_startup_extension.py +++ /dev/null @@ -1,16 +0,0 @@ -from cpl_core.application.startup_extension_abc import StartupExtensionABC -from cpl_core.configuration.configuration_abc import ConfigurationABC -from cpl_core.dependency_injection.service_collection_abc import ServiceCollectionABC -from cpl_core.environment.application_environment_abc import ApplicationEnvironmentABC - - -class TestStartup_extension(StartupExtensionABC): - - def __init__(self): - pass - - def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC): - pass - - def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): - pass diff --git a/unittests/unittests_core/utils/string_test_case.py b/unittests/unittests_core/utils/string_test_case.py index 1fd4eddb..665117e4 100644 --- a/unittests/unittests_core/utils/string_test_case.py +++ b/unittests/unittests_core/utils/string_test_case.py @@ -1,10 +1,58 @@ +import string import unittest +from cpl_core.utils import String + class StringTestCase(unittest.TestCase): def setUp(self): pass - def test_equal(self): - pass + def test_convert_to_camel_case(self): + expected = "HelloWorld" + + self.assertEqual(expected, String.convert_to_camel_case("hello-world")) + self.assertEqual(expected, String.convert_to_camel_case("hello_world")) + self.assertEqual("helloWorld", String.convert_to_camel_case("helloWorld")) + self.assertEqual(expected, String.convert_to_camel_case("Hello_world")) + self.assertEqual(expected, String.convert_to_camel_case("Hello_World")) + self.assertEqual(expected, String.convert_to_camel_case("hello world")) + + def test_convert_to_snake_case(self): + expected = "hello_world" + + self.assertEqual(expected, String.convert_to_snake_case("Hello World")) + self.assertEqual(expected, String.convert_to_snake_case("hello-world")) + self.assertEqual(expected, String.convert_to_snake_case("hello_world")) + self.assertEqual(expected, String.convert_to_snake_case("helloWorld")) + self.assertEqual(expected, String.convert_to_snake_case("Hello_world")) + self.assertEqual(expected, String.convert_to_snake_case("Hello_World")) + self.assertEqual(expected, String.convert_to_snake_case("hello world")) + + def test_first_to_upper(self): + expected = "HelloWorld" + + self.assertEqual(expected, String.first_to_upper("helloWorld")) + self.assertEqual(expected, String.first_to_upper("HelloWorld")) + + def test_first_to_lower(self): + expected = "helloWorld" + + self.assertEqual(expected, String.first_to_lower("helloWorld")) + self.assertEqual(expected, String.first_to_lower("HelloWorld")) + + def test_random_string(self): + expected = "" + + for x in range(0, 100): + rstr = String.random_string(string.ascii_letters, 4) + self.assertNotEqual(expected, rstr) + self.assertEqual(4, len(rstr)) + expected = rstr + + for x in range(0, 100): + rstr = String.random_string(string.ascii_letters, 16) + self.assertNotEqual(expected, rstr) + self.assertEqual(16, len(rstr)) + expected = rstr -- 2.45.2 From 7ff7dbc56b0f4b4d1578bfb48f711fd4d0af5846 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Fri, 7 Apr 2023 14:04:39 +0200 Subject: [PATCH 03/14] Added core test suite --- unittests/unittests/application.py | 2 ++ unittests/unittests_core/core_test_suite.py | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/unittests/unittests/application.py b/unittests/unittests/application.py index 9dfc29d5..932fb34b 100644 --- a/unittests/unittests/application.py +++ b/unittests/unittests/application.py @@ -4,6 +4,7 @@ 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_core.core_test_suite import CoreTestSuite from unittests_query.query_test_suite import QueryTestSuite from unittests_translation.translation_test_suite import TranslationTestSuite @@ -17,6 +18,7 @@ class Application(ApplicationABC): def main(self): runner = unittest.TextTestRunner() + runner.run(CoreTestSuite()) runner.run(CLITestSuite()) runner.run(QueryTestSuite()) runner.run(TranslationTestSuite()) diff --git a/unittests/unittests_core/core_test_suite.py b/unittests/unittests_core/core_test_suite.py index 1b837049..574cbead 100644 --- a/unittests/unittests_core/core_test_suite.py +++ b/unittests/unittests_core/core_test_suite.py @@ -8,7 +8,7 @@ from unittests_query.iterable_test_case import IterableTestCase from unittests_query.sequence_test_case import SequenceTestCase -class QueryTestSuite(unittest.TestSuite): +class CoreTestSuite(unittest.TestSuite): def __init__(self): unittest.TestSuite.__init__(self) @@ -21,4 +21,4 @@ class QueryTestSuite(unittest.TestSuite): if __name__ == "__main__": runner = unittest.TextTestRunner() - runner.run(QueryTestSuite()) + runner.run(CoreTestSuite()) -- 2.45.2 From 9c7008e179c9bf73a451b36fb95fc099faf3efe4 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Fri, 7 Apr 2023 14:08:06 +0200 Subject: [PATCH 04/14] Improved core test suite --- unittests/unittests_core/core_test_suite.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/unittests/unittests_core/core_test_suite.py b/unittests/unittests_core/core_test_suite.py index 574cbead..ce89f776 100644 --- a/unittests/unittests_core/core_test_suite.py +++ b/unittests/unittests_core/core_test_suite.py @@ -1,11 +1,6 @@ import unittest from unittests_core.utils.string_test_case import StringTestCase -from unittests_query.enumerable_query_test_case import EnumerableQueryTestCase -from unittests_query.enumerable_test_case import EnumerableTestCase -from unittests_query.iterable_query_test_case import IterableQueryTestCase -from unittests_query.iterable_test_case import IterableTestCase -from unittests_query.sequence_test_case import SequenceTestCase class CoreTestSuite(unittest.TestSuite): -- 2.45.2 From 3178b59147cdeb9f6ebd3d9e21241e2eb1003b71 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Fri, 7 Apr 2023 14:40:03 +0200 Subject: [PATCH 05/14] Added JSONProcessorTestCase --- unittests/unittests_core/core_test_suite.py | 4 ++ .../utils/credential_manager_test_case.py | 36 ++++++++++++++++-- .../utils/json_processor_test_case.py | 38 +++++++++++++++++++ .../unittests_core/utils/string_test_case.py | 1 - 4 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 unittests/unittests_core/utils/json_processor_test_case.py diff --git a/unittests/unittests_core/core_test_suite.py b/unittests/unittests_core/core_test_suite.py index ce89f776..a50d9b90 100644 --- a/unittests/unittests_core/core_test_suite.py +++ b/unittests/unittests_core/core_test_suite.py @@ -1,5 +1,7 @@ import unittest +from unittests_core.utils.credential_manager_test_case import CredentialManagerTestCase +from unittests_core.utils.json_processor_test_case import JSONProcessorTestCase from unittests_core.utils.string_test_case import StringTestCase @@ -8,6 +10,8 @@ class CoreTestSuite(unittest.TestSuite): unittest.TestSuite.__init__(self) loader = unittest.TestLoader() + self.addTests(loader.loadTestsFromTestCase(CredentialManagerTestCase)) + self.addTests(loader.loadTestsFromTestCase(JSONProcessorTestCase)) self.addTests(loader.loadTestsFromTestCase(StringTestCase)) def run(self, *args): diff --git a/unittests/unittests_core/utils/credential_manager_test_case.py b/unittests/unittests_core/utils/credential_manager_test_case.py index f1991eb4..c602dfa1 100644 --- a/unittests/unittests_core/utils/credential_manager_test_case.py +++ b/unittests/unittests_core/utils/credential_manager_test_case.py @@ -1,10 +1,40 @@ import unittest +from cpl_core.utils import CredentialManager + class CredentialManagerTestCase(unittest.TestCase): - def setUp(self): pass - def test_equal(self): - pass + def test_encrypt(self): + self.assertEqual("ZkVjSkplQUx4aW1zWHlPbA==", CredentialManager.encrypt("fEcJJeALximsXyOl")) + self.assertEqual("QmtVd1l4dW5Sck9jRmVTQQ==", CredentialManager.encrypt("BkUwYxunRrOcFeSA")) + self.assertEqual("c2FtaHF1VkNSdmZpSGxDcQ==", CredentialManager.encrypt("samhquVCRvfiHlCq")) + self.assertEqual("S05aWHBPYW9DbkRSV01rWQ==", CredentialManager.encrypt("KNZXpOaoCnDRWMkY")) + self.assertEqual("QmtUV0Zsb3h1Y254UkJWeg==", CredentialManager.encrypt("BkTWFloxucnxRBVz")) + self.assertEqual("VFdNTkRuYXB1b1dndXNKdw==", CredentialManager.encrypt("TWMNDnapuoWgusJw")) + self.assertEqual("WVRiQXVSZXRMblpicWNrcQ==", CredentialManager.encrypt("YTbAuRetLnZbqckq")) + self.assertEqual("bmN4aExackxhYUVVdnV2VA==", CredentialManager.encrypt("ncxhLZrLaaEUvuvT")) + self.assertEqual("dmpNT0J5U0lLQmFrc0pIYQ==", CredentialManager.encrypt("vjMOBySIKBaksJHa")) + self.assertEqual("ZHd6WHFzSlFvQlhRbGtVZw==", CredentialManager.encrypt("dwzXqsJQoBXQlkUg")) + self.assertEqual("Q0lmUUhOREtiUmxnY2VCbQ==", CredentialManager.encrypt("CIfQHNDKbRlgceBm")) + + def test_decrypt(self): + self.assertEqual("fEcJJeALximsXyOl", CredentialManager.decrypt("ZkVjSkplQUx4aW1zWHlPbA==")) + self.assertEqual("BkUwYxunRrOcFeSA", CredentialManager.decrypt("QmtVd1l4dW5Sck9jRmVTQQ==")) + self.assertEqual("samhquVCRvfiHlCq", CredentialManager.decrypt("c2FtaHF1VkNSdmZpSGxDcQ==")) + self.assertEqual("KNZXpOaoCnDRWMkY", CredentialManager.decrypt("S05aWHBPYW9DbkRSV01rWQ==")) + self.assertEqual("BkTWFloxucnxRBVz", CredentialManager.decrypt("QmtUV0Zsb3h1Y254UkJWeg==")) + self.assertEqual("TWMNDnapuoWgusJw", CredentialManager.decrypt("VFdNTkRuYXB1b1dndXNKdw==")) + self.assertEqual("YTbAuRetLnZbqckq", CredentialManager.decrypt("WVRiQXVSZXRMblpicWNrcQ==")) + self.assertEqual("ncxhLZrLaaEUvuvT", CredentialManager.decrypt("bmN4aExackxhYUVVdnV2VA==")) + self.assertEqual("vjMOBySIKBaksJHa", CredentialManager.decrypt("dmpNT0J5U0lLQmFrc0pIYQ==")) + self.assertEqual("dwzXqsJQoBXQlkUg", CredentialManager.decrypt("ZHd6WHFzSlFvQlhRbGtVZw==")) + self.assertEqual("CIfQHNDKbRlgceBm", CredentialManager.decrypt("Q0lmUUhOREtiUmxnY2VCbQ==")) + + def test_build_string(self): + self.assertEqual( + "TestStringWithCredentialsfEcJJeALximsXyOlHere", + CredentialManager.build_string("TestStringWithCredentials$credentialsHere", "ZkVjSkplQUx4aW1zWHlPbA=="), + ) diff --git a/unittests/unittests_core/utils/json_processor_test_case.py b/unittests/unittests_core/utils/json_processor_test_case.py new file mode 100644 index 00000000..4f969a9d --- /dev/null +++ b/unittests/unittests_core/utils/json_processor_test_case.py @@ -0,0 +1,38 @@ +import unittest + +from cpl_core.utils.json_processor import JSONProcessor + + +class SubTestClass: + def __init__(self, value: str = None): + self.value = value + + +class TestClass: + def __init__(self, i: int = None, s: str = None, d: dict = None, l: list = None, value: SubTestClass = None): + self.i = i + self.s = s + self.d = d + self.l = l + self.value = value + + +class JSONProcessorTestCase(unittest.TestCase): + def setUp(self): + pass + + def test_process(self): + test_dict = { + "i": 10, + "s": "Hello World", + "d": {"test": "Test"}, + "l": range(0, 11), + "value": {"value": "Hello World"}, + } + test: TestClass = JSONProcessor.process(TestClass, test_dict) + + self.assertEqual(test.i, test_dict["i"]) + self.assertEqual(test.s, test_dict["s"]) + self.assertEqual(test.d, test_dict["d"]) + self.assertEqual(test.l, test_dict["l"]) + self.assertEqual(test.value.value, test_dict["value"]["value"]) diff --git a/unittests/unittests_core/utils/string_test_case.py b/unittests/unittests_core/utils/string_test_case.py index 665117e4..7a5173f2 100644 --- a/unittests/unittests_core/utils/string_test_case.py +++ b/unittests/unittests_core/utils/string_test_case.py @@ -5,7 +5,6 @@ from cpl_core.utils import String class StringTestCase(unittest.TestCase): - def setUp(self): pass -- 2.45.2 From 04f610c799578e60f75ab19ba0e27d3134f513e7 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Fri, 7 Apr 2023 14:41:11 +0200 Subject: [PATCH 06/14] Removed obsolete pipes --- src/cpl_core/pipes/__init__.py | 5 ---- .../pipes/first_char_to_lower_pipe.py | 18 ------------- src/cpl_core/pipes/first_to_upper_pipe.py | 18 ------------- src/cpl_core/pipes/to_camel_case_pipe.py | 26 ------------------ src/cpl_core/pipes/to_snake_case_pipe.py | 27 ------------------- 5 files changed, 94 deletions(-) delete mode 100644 src/cpl_core/pipes/first_char_to_lower_pipe.py delete mode 100644 src/cpl_core/pipes/first_to_upper_pipe.py delete mode 100644 src/cpl_core/pipes/to_camel_case_pipe.py delete mode 100644 src/cpl_core/pipes/to_snake_case_pipe.py diff --git a/src/cpl_core/pipes/__init__.py b/src/cpl_core/pipes/__init__.py index 5a25afb1..cc4799a0 100644 --- a/src/cpl_core/pipes/__init__.py +++ b/src/cpl_core/pipes/__init__.py @@ -19,15 +19,10 @@ __version__ = "2023.4.0" from collections import namedtuple - # imports: from .bool_pipe import BoolPipe -from .first_char_to_lower_pipe import FirstCharToLowerPipe -from .first_to_upper_pipe import FirstToUpperPipe from .ip_address_pipe import IPAddressPipe from .pipe_abc import PipeABC -from .to_camel_case_pipe import ToCamelCasePipe -from .to_snake_case_pipe import ToSnakeCasePipe VersionInfo = namedtuple("VersionInfo", "major minor micro") version_info = VersionInfo(major="2023", minor="4", micro="0") diff --git a/src/cpl_core/pipes/first_char_to_lower_pipe.py b/src/cpl_core/pipes/first_char_to_lower_pipe.py deleted file mode 100644 index b9e7630e..00000000 --- a/src/cpl_core/pipes/first_char_to_lower_pipe.py +++ /dev/null @@ -1,18 +0,0 @@ -from cpl_core.pipes.pipe_abc import PipeABC - - -class FirstCharToLowerPipe(PipeABC): - def __init__(self): - pass - - def transform(self, value: any, *args): - r"""Converts first char to lower - - Parameter: - value: :class:`str` - String to convert - - Returns: - String with first char as lower - """ - return f"{value[0].lower()}{value[1:]}" diff --git a/src/cpl_core/pipes/first_to_upper_pipe.py b/src/cpl_core/pipes/first_to_upper_pipe.py deleted file mode 100644 index fbc7cb29..00000000 --- a/src/cpl_core/pipes/first_to_upper_pipe.py +++ /dev/null @@ -1,18 +0,0 @@ -from cpl_core.pipes.pipe_abc import PipeABC - - -class FirstToUpperPipe(PipeABC): - def __init__(self): - pass - - def transform(self, value: str, *args): - r"""Converts first char to upper - - Parameter: - chars: :class:`str` - String to convert - - Returns: - String with first char as upper - """ - return f"{value[0].upper()}{value[1:]}" diff --git a/src/cpl_core/pipes/to_camel_case_pipe.py b/src/cpl_core/pipes/to_camel_case_pipe.py deleted file mode 100644 index 6418b97b..00000000 --- a/src/cpl_core/pipes/to_camel_case_pipe.py +++ /dev/null @@ -1,26 +0,0 @@ -import string - -from cpl_core.pipes import PipeABC - - -class ToCamelCasePipe(PipeABC): - def __init__(self): - pass - - def transform(self, value: str, *args) -> str: - r"""Converts string to camel case - - Parameter: - chars: :class:`str` - String to convert - - Returns: - String converted to CamelCase - """ - converted_name = value - char_set = string.punctuation + " " - for char in char_set: - if char in converted_name: - converted_name = "".join(word.title() for word in converted_name.split(char)) - - return converted_name diff --git a/src/cpl_core/pipes/to_snake_case_pipe.py b/src/cpl_core/pipes/to_snake_case_pipe.py deleted file mode 100644 index e4528ab0..00000000 --- a/src/cpl_core/pipes/to_snake_case_pipe.py +++ /dev/null @@ -1,27 +0,0 @@ -import re - -from cpl_core.pipes import PipeABC - - -class ToSnakeCasePipe(PipeABC): - def __init__(self): - pass - - def transform(self, value: str, *args) -> str: - r"""Converts string to snake case - - Parameter: - chars: :class:`str` - String to convert - - Returns: - String converted to snake_case - """ - # convert to train-case to CamelCase - if "-" in value: - value = "".join(word.title() for word in value.split("-")) - - pattern1 = re.compile(r"(.)([A-Z][a-z]+)") - pattern2 = re.compile(r"([a-z0-9])([A-Z])") - file_name = re.sub(pattern1, r"\1_\2", value) - return re.sub(pattern2, r"\1_\2", file_name).lower() -- 2.45.2 From 75fde0f4449f732a71b51c3faeed598a32ba8f16 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Fri, 7 Apr 2023 14:52:17 +0200 Subject: [PATCH 07/14] Added pipe tests --- src/cpl_core/pipes/ip_address_pipe.py | 2 +- unittests/unittests_core/core_test_suite.py | 19 +++++++++++++++--- unittests/unittests_core/pipes/__init__.py | 1 + .../pipes/bool_pipe_test_case.py | 14 +++++++++++++ .../pipes/ip_address_pipe_test_case.py | 20 +++++++++++++++++++ .../pipes/version_pipe_test_case.py | 16 +++++++++++++++ 6 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 unittests/unittests_core/pipes/__init__.py create mode 100644 unittests/unittests_core/pipes/bool_pipe_test_case.py create mode 100644 unittests/unittests_core/pipes/ip_address_pipe_test_case.py create mode 100644 unittests/unittests_core/pipes/version_pipe_test_case.py diff --git a/src/cpl_core/pipes/ip_address_pipe.py b/src/cpl_core/pipes/ip_address_pipe.py index 00dc43b0..71e5c0b4 100644 --- a/src/cpl_core/pipes/ip_address_pipe.py +++ b/src/cpl_core/pipes/ip_address_pipe.py @@ -13,7 +13,7 @@ class IPAddressPipe(PipeABC): for i in range(0, len(value)): byte = value[i] - if byte > 255: + if byte > 255 or byte < 0: raise Exception("Invalid IP") if i == len(value) - 1: diff --git a/unittests/unittests_core/core_test_suite.py b/unittests/unittests_core/core_test_suite.py index a50d9b90..ede67d9e 100644 --- a/unittests/unittests_core/core_test_suite.py +++ b/unittests/unittests_core/core_test_suite.py @@ -1,5 +1,8 @@ import unittest +from unittests_core.pipes.bool_pipe_test_case import BoolPipeTestCase +from unittests_core.pipes.ip_address_pipe_test_case import IPAddressTestCase +from unittests_core.pipes.version_pipe_test_case import VersionPipeTestCase from unittests_core.utils.credential_manager_test_case import CredentialManagerTestCase from unittests_core.utils.json_processor_test_case import JSONProcessorTestCase from unittests_core.utils.string_test_case import StringTestCase @@ -10,9 +13,19 @@ class CoreTestSuite(unittest.TestSuite): unittest.TestSuite.__init__(self) loader = unittest.TestLoader() - self.addTests(loader.loadTestsFromTestCase(CredentialManagerTestCase)) - self.addTests(loader.loadTestsFromTestCase(JSONProcessorTestCase)) - self.addTests(loader.loadTestsFromTestCase(StringTestCase)) + tests = [ + # pipes + BoolPipeTestCase, + IPAddressTestCase, + VersionPipeTestCase, + # utils + CredentialManagerTestCase, + JSONProcessorTestCase, + StringTestCase, + ] + + for test in tests: + self.addTests(loader.loadTestsFromTestCase(test)) def run(self, *args): super().run(*args) diff --git a/unittests/unittests_core/pipes/__init__.py b/unittests/unittests_core/pipes/__init__.py new file mode 100644 index 00000000..425ab6c1 --- /dev/null +++ b/unittests/unittests_core/pipes/__init__.py @@ -0,0 +1 @@ +# imports diff --git a/unittests/unittests_core/pipes/bool_pipe_test_case.py b/unittests/unittests_core/pipes/bool_pipe_test_case.py new file mode 100644 index 00000000..99af412b --- /dev/null +++ b/unittests/unittests_core/pipes/bool_pipe_test_case.py @@ -0,0 +1,14 @@ +import unittest + +from cpl_core.pipes import BoolPipe + + +class BoolPipeTestCase(unittest.TestCase): + def setUp(self): + pass + + def test_transform(self): + pipe = BoolPipe() + + self.assertEqual("True", pipe.transform(True)) + self.assertEqual("False", pipe.transform(False)) diff --git a/unittests/unittests_core/pipes/ip_address_pipe_test_case.py b/unittests/unittests_core/pipes/ip_address_pipe_test_case.py new file mode 100644 index 00000000..218bdb6a --- /dev/null +++ b/unittests/unittests_core/pipes/ip_address_pipe_test_case.py @@ -0,0 +1,20 @@ +import unittest + +from cpl_core.pipes import IPAddressPipe + + +class IPAddressTestCase(unittest.TestCase): + def setUp(self): + pass + + def test_transform(self): + pipe = IPAddressPipe() + + self.assertEqual("192.168.178.1", pipe.transform([192, 168, 178, 1])) + self.assertEqual("255.255.255.255", pipe.transform([255, 255, 255, 255])) + self.assertEqual("0.0.0.0", pipe.transform([0, 0, 0, 0])) + + self.assertRaises(Exception, lambda: pipe.transform([-192, 168, 178, 1])) + self.assertRaises(Exception, lambda: pipe.transform([256, 168, 178, 1])) + self.assertRaises(Exception, lambda: pipe.transform([256, 168, 178])) + self.assertRaises(Exception, lambda: pipe.transform([256, 168, 178, 1, 1])) diff --git a/unittests/unittests_core/pipes/version_pipe_test_case.py b/unittests/unittests_core/pipes/version_pipe_test_case.py new file mode 100644 index 00000000..2df20d76 --- /dev/null +++ b/unittests/unittests_core/pipes/version_pipe_test_case.py @@ -0,0 +1,16 @@ +import unittest + +from cpl_core.pipes.version_pipe import VersionPipe + + +class VersionPipeTestCase(unittest.TestCase): + def setUp(self): + pass + + def test_transform(self): + pipe = VersionPipe() + + self.assertEqual("1.1.1", pipe.transform({"Major": 1, "Minor": 1, "Micro": 1})) + self.assertEqual("0.1.1", pipe.transform({"Major": 0, "Minor": 1, "Micro": 1})) + self.assertEqual("0.0.1", pipe.transform({"Major": 0, "Minor": 0, "Micro": 1})) + self.assertEqual("0.0.0", pipe.transform({"Major": 0, "Minor": 0, "Micro": 0})) -- 2.45.2 From 0378f8944a59a40c59cbaa5c8d244a39973bdce2 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Sun, 9 Apr 2023 12:05:05 +0200 Subject: [PATCH 08/14] Added AppEnv tests --- .../unittests_core/configuration/__init__.py | 0 .../configuration/environment_test_case.py | 52 +++++++++++++++++++ unittests/unittests_core/core_test_suite.py | 3 ++ .../unittests_core/utils/string_test_case.py | 1 + 4 files changed, 56 insertions(+) create mode 100644 unittests/unittests_core/configuration/__init__.py create mode 100644 unittests/unittests_core/configuration/environment_test_case.py diff --git a/unittests/unittests_core/configuration/__init__.py b/unittests/unittests_core/configuration/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/unittests/unittests_core/configuration/environment_test_case.py b/unittests/unittests_core/configuration/environment_test_case.py new file mode 100644 index 00000000..5c1a4aed --- /dev/null +++ b/unittests/unittests_core/configuration/environment_test_case.py @@ -0,0 +1,52 @@ +import os +import unittest +from _socket import gethostname + +from cpl_core.configuration import Configuration +from cpl_core.environment import ApplicationEnvironment, ApplicationEnvironmentABC +from cpl_core.environment import application_environment + + +class EnvironmentTestCase(unittest.TestCase): + def setUp(self): + self._config = Configuration() + self._env = self._config.environment + + def test_app_env_created(self): + self.assertTrue(isinstance(self._env, ApplicationEnvironment)) + self.assertTrue(issubclass(type(self._env), ApplicationEnvironmentABC)) + + def test_app_env_values_correct_when_default(self): + self.assertEqual(self._env.environment_name, "production") + self.assertEqual(self._env.application_name, "") + self.assertEqual(self._env.customer, "") + self.assertEqual(self._env.host_name, gethostname()) + self.assertEqual(self._env.working_directory, os.getcwd()) + self.assertEqual( + self._env.runtime_directory, + os.path.dirname(os.path.dirname(os.path.abspath(application_environment.__file__))), + ) + + def test_app_env_values_correct_when_read_from_env(self): + os.environ["CPLT_ENVIRONMENT"] = "development" + os.environ["CPLT_NAME"] = "Core Tests" + os.environ["CPLT_CUSTOMER"] = "sh-edraft.de" + + self._config.add_environment_variables("CPLT_") + + self.assertEqual(self._env.environment_name, "development") + self.assertEqual(self._env.application_name, "Core Tests") + self.assertEqual(self._env.customer, "sh-edraft.de") + self.assertEqual(self._env.host_name, gethostname()) + self.assertEqual(self._env.working_directory, os.getcwd()) + self.assertEqual( + self._env.runtime_directory, + os.path.dirname(os.path.dirname(os.path.abspath(application_environment.__file__))), + ) + + def test_app_env_set_dirs(self): + new_cwd = os.path.join(os.getcwd(), "../") + self._env.set_working_directory(new_cwd) + self.assertEqual(self._env.working_directory, new_cwd) + self._env.set_runtime_directory(new_cwd) + self.assertEqual(self._env.runtime_directory, new_cwd) diff --git a/unittests/unittests_core/core_test_suite.py b/unittests/unittests_core/core_test_suite.py index ede67d9e..56304328 100644 --- a/unittests/unittests_core/core_test_suite.py +++ b/unittests/unittests_core/core_test_suite.py @@ -1,5 +1,6 @@ import unittest +from unittests_core.configuration.environment_test_case import EnvironmentTestCase from unittests_core.pipes.bool_pipe_test_case import BoolPipeTestCase from unittests_core.pipes.ip_address_pipe_test_case import IPAddressTestCase from unittests_core.pipes.version_pipe_test_case import VersionPipeTestCase @@ -14,6 +15,8 @@ class CoreTestSuite(unittest.TestSuite): loader = unittest.TestLoader() tests = [ + # config + EnvironmentTestCase, # pipes BoolPipeTestCase, IPAddressTestCase, diff --git a/unittests/unittests_core/utils/string_test_case.py b/unittests/unittests_core/utils/string_test_case.py index 7a5173f2..cc826567 100644 --- a/unittests/unittests_core/utils/string_test_case.py +++ b/unittests/unittests_core/utils/string_test_case.py @@ -12,6 +12,7 @@ class StringTestCase(unittest.TestCase): expected = "HelloWorld" self.assertEqual(expected, String.convert_to_camel_case("hello-world")) + self.assertEqual(expected, String.convert_to_camel_case("hello-World")) self.assertEqual(expected, String.convert_to_camel_case("hello_world")) self.assertEqual("helloWorld", String.convert_to_camel_case("helloWorld")) self.assertEqual(expected, String.convert_to_camel_case("Hello_world")) -- 2.45.2 From 1117735f2e5af1238679500374b95b823c4a62b9 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Sun, 9 Apr 2023 12:31:31 +0200 Subject: [PATCH 09/14] Added configuration tests & improved json parsing by converting into target types --- src/cpl_core/database/database_settings.py | 6 +-- src/cpl_core/utils/json_processor.py | 3 ++ .../configuration/configuration_test_case.py | 37 +++++++++++++++++++ .../configuration/test-settings.json | 25 +++++++++++++ unittests/unittests_core/core_test_suite.py | 2 + .../utils/json_processor_test_case.py | 2 +- 6 files changed, 71 insertions(+), 4 deletions(-) create mode 100644 unittests/unittests_core/configuration/configuration_test_case.py create mode 100644 unittests/unittests_core/configuration/test-settings.json diff --git a/src/cpl_core/database/database_settings.py b/src/cpl_core/database/database_settings.py index 609a3075..c8ee032f 100644 --- a/src/cpl_core/database/database_settings.py +++ b/src/cpl_core/database/database_settings.py @@ -12,11 +12,11 @@ class DatabaseSettings(ConfigurationModelABC): port: int = None, user: str = None, password: str = None, - databse: str = None, + database: str = None, charset: str = None, use_unicode: bool = None, buffered: bool = None, - auth_plugin: bool = None, + auth_plugin: str = None, ): ConfigurationModelABC.__init__(self) @@ -24,7 +24,7 @@ class DatabaseSettings(ConfigurationModelABC): self._port: Optional[int] = port self._user: Optional[str] = user self._password: Optional[str] = password - self._databse: Optional[str] = databse + self._databse: Optional[str] = database self._charset: Optional[str] = charset self._use_unicode: Optional[bool] = use_unicode self._buffered: Optional[bool] = buffered diff --git a/src/cpl_core/utils/json_processor.py b/src/cpl_core/utils/json_processor.py index 3de2e59d..afa3ea23 100644 --- a/src/cpl_core/utils/json_processor.py +++ b/src/cpl_core/utils/json_processor.py @@ -30,6 +30,9 @@ class JSONProcessor: if issubclass(parameter.annotation, enum.Enum): value = parameter.annotation[value] + if type(value) != parameter.annotation: + value = parameter.annotation(value) + args.append(value) elif parameter.default != Parameter.empty: diff --git a/unittests/unittests_core/configuration/configuration_test_case.py b/unittests/unittests_core/configuration/configuration_test_case.py new file mode 100644 index 00000000..5e4f113e --- /dev/null +++ b/unittests/unittests_core/configuration/configuration_test_case.py @@ -0,0 +1,37 @@ +import os +import unittest + +from cpl_core.configuration import Configuration +from cpl_core.database import DatabaseSettings +from cpl_core.mailing import EMailClientSettings + + +class ConfigurationTestCase(unittest.TestCase): + def setUp(self): + self._config = Configuration() + + def test_env_vars(self): + os.environ["CPLT_TESTVAR"] = "Hello World" + os.environ["CPL_NOT_EXISTING"] = "Hello World" + + self._config.add_environment_variables("CPLT_") + + self.assertEqual(self._config.get_configuration("TESTVAR"), "Hello World") + self.assertEqual(self._config.get_configuration("TESTVAR"), "Hello World") + self.assertEqual(self._config.get_configuration("NOT_EXISTING"), None) + + def test_add_json_file(self): + self._config.add_json_file("unittests_core/configuration/test-settings.json") + db = self._config.get_configuration(DatabaseSettings) + self.assertIsNotNone(db) + self.assertEqual("localhost", db.host) + self.assertEqual("local", db.user) + self.assertEqual("bG9jYWw=", db.password) + self.assertEqual("local", db.database) + self.assertEqual(int, type(db.port)) + self.assertEqual(3306, db.port) + self.assertEqual("utf8mb4", db.charset) + self.assertTrue(db.use_unicode) + self.assertTrue(db.buffered) + self.assertEqual("mysql_native_password", db.auth_plugin) + self.assertIsNone(self._config.get_configuration(EMailClientSettings)) diff --git a/unittests/unittests_core/configuration/test-settings.json b/unittests/unittests_core/configuration/test-settings.json new file mode 100644 index 00000000..702de250 --- /dev/null +++ b/unittests/unittests_core/configuration/test-settings.json @@ -0,0 +1,25 @@ +{ + "TimeFormatSettings": { + "DateFormat": "%Y-%m-%d", + "TimeFormat": "%H:%M:%S", + "DateTimeFormat": "%Y-%m-%d %H:%M:%S.%f", + "DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S" + }, + "LoggingSettings": { + "Path": "logs/$date_now/", + "Filename": "bot.log", + "ConsoleLogLevel": "TRACE", + "FileLogLevel": "TRACE" + }, + "DatabaseSettings": { + "Host": "localhost", + "User": "local", + "Password": "bG9jYWw=", + "Database": "local", + "Port": "3306", + "Charset": "utf8mb4", + "UseUnicode": "true", + "Buffered": "true", + "AuthPlugin": "mysql_native_password" + } +} \ No newline at end of file diff --git a/unittests/unittests_core/core_test_suite.py b/unittests/unittests_core/core_test_suite.py index 56304328..39dc4c99 100644 --- a/unittests/unittests_core/core_test_suite.py +++ b/unittests/unittests_core/core_test_suite.py @@ -1,5 +1,6 @@ import unittest +from unittests_core.configuration.configuration_test_case import ConfigurationTestCase from unittests_core.configuration.environment_test_case import EnvironmentTestCase from unittests_core.pipes.bool_pipe_test_case import BoolPipeTestCase from unittests_core.pipes.ip_address_pipe_test_case import IPAddressTestCase @@ -16,6 +17,7 @@ class CoreTestSuite(unittest.TestSuite): loader = unittest.TestLoader() tests = [ # config + ConfigurationTestCase, EnvironmentTestCase, # pipes BoolPipeTestCase, diff --git a/unittests/unittests_core/utils/json_processor_test_case.py b/unittests/unittests_core/utils/json_processor_test_case.py index 4f969a9d..2772c966 100644 --- a/unittests/unittests_core/utils/json_processor_test_case.py +++ b/unittests/unittests_core/utils/json_processor_test_case.py @@ -26,7 +26,7 @@ class JSONProcessorTestCase(unittest.TestCase): "i": 10, "s": "Hello World", "d": {"test": "Test"}, - "l": range(0, 11), + "l": list(range(0, 11)), "value": {"value": "Hello World"}, } test: TestClass = JSONProcessor.process(TestClass, test_dict) -- 2.45.2 From 106975015ea5dc139b9b4b075cb2a062470fabd8 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Sun, 9 Apr 2023 12:51:57 +0200 Subject: [PATCH 10/14] Improved config tests --- src/cpl_core/configuration/configuration.py | 2 +- .../configuration/configuration_abc.py | 2 +- .../configuration/configuration_test_case.py | 33 ++++++++++++++++++- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/cpl_core/configuration/configuration.py b/src/cpl_core/configuration/configuration.py index 7e179274..a8372cac 100644 --- a/src/cpl_core/configuration/configuration.py +++ b/src/cpl_core/configuration/configuration.py @@ -314,7 +314,7 @@ class Configuration(ConfigurationABC): for arg in self._argument_types: call(arg) - def get_configuration(self, search_type: Type[T]) -> Optional[T]: + def get_configuration(self, search_type: T) -> Optional[T]: if type(search_type) is str: if search_type == ConfigurationVariableNameEnum.environment.value: return self._application_environment.environment_name diff --git a/src/cpl_core/configuration/configuration_abc.py b/src/cpl_core/configuration/configuration_abc.py index 2f8d7a4c..815fa361 100644 --- a/src/cpl_core/configuration/configuration_abc.py +++ b/src/cpl_core/configuration/configuration_abc.py @@ -124,7 +124,7 @@ class ConfigurationABC(ABC): pass @abstractmethod - def get_configuration(self, search_type: Type[T]) -> Optional[T]: + def get_configuration(self, search_type: T) -> Optional[T]: r"""Returns value from configuration by given type Parameter: diff --git a/unittests/unittests_core/configuration/configuration_test_case.py b/unittests/unittests_core/configuration/configuration_test_case.py index 5e4f113e..1d59d202 100644 --- a/unittests/unittests_core/configuration/configuration_test_case.py +++ b/unittests/unittests_core/configuration/configuration_test_case.py @@ -1,8 +1,11 @@ import os +import sys import unittest +from unittest.mock import Mock, MagicMock -from cpl_core.configuration import Configuration +from cpl_core.configuration import Configuration, ArgumentTypeEnum from cpl_core.database import DatabaseSettings +from cpl_core.dependency_injection import ServiceProvider, ServiceCollection from cpl_core.mailing import EMailClientSettings @@ -35,3 +38,31 @@ class ConfigurationTestCase(unittest.TestCase): self.assertTrue(db.buffered) self.assertEqual("mysql_native_password", db.auth_plugin) self.assertIsNone(self._config.get_configuration(EMailClientSettings)) + + def test_add_config(self): + self.assertIsNone(self._config.get_configuration("Test")) + self._config.add_configuration("Test", "Hello World") + self.assertIsNotNone(self._config.get_configuration("Test")) + self.assertEqual("Hello World", self._config.get_configuration("Test")) + + def test_console_argument(self): + sc = ServiceCollection(self._config) + self.assertEqual([], sys.argv[1:]) + sys.argv.append("flag") + sys.argv.append("exec") + sys.argv.append("var=test") + self.assertNotEqual([], sys.argv[1:]) + + self._config.create_console_argument(ArgumentTypeEnum.Flag, "", "flag", []) + mocked_exec = Mock() + mocked_exec.run = MagicMock() + sc.add_transient(mocked_exec) + self._config.create_console_argument(ArgumentTypeEnum.Executable, "", "exec", [], Mock) + self._config.create_console_argument(ArgumentTypeEnum.Variable, "", "var", [], "=") + + self.assertIsNone(self._config.get_configuration("var")) + self._config.parse_console_arguments(sc.build_service_provider()) + mocked_exec.run.assert_called() + + self.assertEqual("test", self._config.get_configuration("var")) + self.assertIn("flag", self._config.additional_arguments) -- 2.45.2 From 792429d19d4d58fc53b7cd3185ef5dcaa0b9308d Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Mon, 10 Apr 2023 13:35:11 +0200 Subject: [PATCH 11/14] Added console argument tests --- .../console_arguments_test_case.py | 75 +++++++++++++++++++ unittests/unittests_core/core_test_suite.py | 2 + 2 files changed, 77 insertions(+) create mode 100644 unittests/unittests_core/configuration/console_arguments_test_case.py diff --git a/unittests/unittests_core/configuration/console_arguments_test_case.py b/unittests/unittests_core/configuration/console_arguments_test_case.py new file mode 100644 index 00000000..c5b67925 --- /dev/null +++ b/unittests/unittests_core/configuration/console_arguments_test_case.py @@ -0,0 +1,75 @@ +import sys +import unittest +from unittest.mock import Mock, MagicMock + +from cpl_core.configuration import Configuration, ArgumentTypeEnum +from cpl_core.dependency_injection import ServiceCollection + + +class ConsoleArgumentsTestCase(unittest.TestCase): + def setUp(self): + self._config = Configuration() + + self._config.create_console_argument(ArgumentTypeEnum.Flag, "", "flag", []) + self._config.create_console_argument(ArgumentTypeEnum.Variable, "", "var", [], "=") + + self._config.create_console_argument(ArgumentTypeEnum.Executable, "", "exec", [], Mock).add_console_argument( + ArgumentTypeEnum.Flag, "--", "dev", ["d", "D"] + ).add_console_argument(ArgumentTypeEnum.Flag, "--", "virtual", ["v", "V"]).add_console_argument( + ArgumentTypeEnum.Variable, "", "var1", [], "=" + ) + + self._config.for_each_argument( + lambda a: a.add_console_argument(ArgumentTypeEnum.Flag, "--", "help", ["h", "H"]) + ) + + self._sc = ServiceCollection(self._config) + self._mocked_exec = Mock() + self._mocked_exec.run = MagicMock() + self._sc.add_transient(self._mocked_exec) + + def test_flag(self): + sys.argv.append("flag") + + self._config.parse_console_arguments(self._sc.build_service_provider()) + self.assertIn("flag", self._config.additional_arguments) + + def test_var(self): + sys.argv.append("var=1") + sys.argv.append("var2=1") + + self._config.parse_console_arguments(self._sc.build_service_provider()) + self.assertEqual("1", self._config.get_configuration("var")) + self.assertIsNone(self._config.get_configuration("var1")) + + def test_exec(self): + sys.argv.append("exec") + + self._config.parse_console_arguments(self._sc.build_service_provider()) + self._mocked_exec.run.assert_called() + + def test_exec_with_one_flag(self): + sys.argv.append("exec") + sys.argv.append("--dev") + + self._config.parse_console_arguments(self._sc.build_service_provider()) + self._mocked_exec.run.assert_called() + self.assertIn("dev", self._config.additional_arguments) + + def test_exec_with_one_flag_alias(self): + sys.argv.append("exec") + sys.argv.append("--d") + + self._config.parse_console_arguments(self._sc.build_service_provider()) + self._mocked_exec.run.assert_called() + self.assertIn("dev", self._config.additional_arguments) + + def test_exec_with_two_flags(self): + sys.argv.append("exec") + sys.argv.append("--dev") + sys.argv.append("--virtual") + + self._config.parse_console_arguments(self._sc.build_service_provider()) + self._mocked_exec.run.assert_called() + self.assertIn("dev", self._config.additional_arguments) + self.assertIn("virtual", self._config.additional_arguments) diff --git a/unittests/unittests_core/core_test_suite.py b/unittests/unittests_core/core_test_suite.py index 39dc4c99..b1e0c96b 100644 --- a/unittests/unittests_core/core_test_suite.py +++ b/unittests/unittests_core/core_test_suite.py @@ -1,5 +1,6 @@ import unittest +from unittests_core.configuration.console_arguments_test_case import ConsoleArgumentsTestCase from unittests_core.configuration.configuration_test_case import ConfigurationTestCase from unittests_core.configuration.environment_test_case import EnvironmentTestCase from unittests_core.pipes.bool_pipe_test_case import BoolPipeTestCase @@ -18,6 +19,7 @@ class CoreTestSuite(unittest.TestSuite): tests = [ # config ConfigurationTestCase, + ConsoleArgumentsTestCase, EnvironmentTestCase, # pipes BoolPipeTestCase, -- 2.45.2 From 60fb416b671dd1dae40cea746b8a5d80bb7311bd Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Mon, 10 Apr 2023 14:47:25 +0200 Subject: [PATCH 12/14] Added service_provider_tests --- unittests/unittests_core/core_test_suite.py | 5 ++ unittests/unittests_core/di/__init__.py | 0 .../di/service_collection_test_case.py | 56 ++++++++++++ .../di/service_provider_test_case.py | 85 +++++++++++++++++++ 4 files changed, 146 insertions(+) create mode 100644 unittests/unittests_core/di/__init__.py create mode 100644 unittests/unittests_core/di/service_collection_test_case.py create mode 100644 unittests/unittests_core/di/service_provider_test_case.py diff --git a/unittests/unittests_core/core_test_suite.py b/unittests/unittests_core/core_test_suite.py index b1e0c96b..f3321712 100644 --- a/unittests/unittests_core/core_test_suite.py +++ b/unittests/unittests_core/core_test_suite.py @@ -3,6 +3,8 @@ import unittest from unittests_core.configuration.console_arguments_test_case import ConsoleArgumentsTestCase from unittests_core.configuration.configuration_test_case import ConfigurationTestCase from unittests_core.configuration.environment_test_case import EnvironmentTestCase +from unittests_core.di.service_collection_test_case import ServiceCollectionTestCase +from unittests_core.di.service_provider_test_case import ServiceProviderTestCase from unittests_core.pipes.bool_pipe_test_case import BoolPipeTestCase from unittests_core.pipes.ip_address_pipe_test_case import IPAddressTestCase from unittests_core.pipes.version_pipe_test_case import VersionPipeTestCase @@ -21,6 +23,9 @@ class CoreTestSuite(unittest.TestSuite): ConfigurationTestCase, ConsoleArgumentsTestCase, EnvironmentTestCase, + # di + ServiceCollectionTestCase, + ServiceProviderTestCase, # pipes BoolPipeTestCase, IPAddressTestCase, diff --git a/unittests/unittests_core/di/__init__.py b/unittests/unittests_core/di/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/unittests/unittests_core/di/service_collection_test_case.py b/unittests/unittests_core/di/service_collection_test_case.py new file mode 100644 index 00000000..ba41797f --- /dev/null +++ b/unittests/unittests_core/di/service_collection_test_case.py @@ -0,0 +1,56 @@ +import unittest +from unittest.mock import Mock + +from cpl_core.configuration import Configuration +from cpl_core.dependency_injection import ServiceCollection, ServiceLifetimeEnum, ServiceProviderABC + + +class ServiceCollectionTestCase(unittest.TestCase): + def setUp(self): + self._sc = ServiceCollection(Configuration()) + + def test_add_singleton_type(self): + self._sc.add_singleton(Mock) + + service = self._sc._service_descriptors[0] + self.assertEqual(ServiceLifetimeEnum.singleton, service.lifetime) + self.assertEqual(Mock, service.service_type) + self.assertEqual(Mock, service.base_type) + self.assertIsNone(service.implementation) + + def test_add_singleton_instance(self): + mock = Mock() + self._sc.add_singleton(mock) + + service = self._sc._service_descriptors[0] + self.assertEqual(ServiceLifetimeEnum.singleton, service.lifetime) + self.assertEqual(type(mock), service.service_type) + self.assertEqual(type(mock), service.base_type) + self.assertIsNotNone(service.implementation) + + def test_add_transient_type(self): + self._sc.add_transient(Mock) + + service = self._sc._service_descriptors[0] + self.assertEqual(ServiceLifetimeEnum.transient, service.lifetime) + self.assertEqual(Mock, service.service_type) + self.assertEqual(Mock, service.base_type) + self.assertIsNone(service.implementation) + + def test_add_scoped_type(self): + self._sc.add_scoped(Mock) + + service = self._sc._service_descriptors[0] + self.assertEqual(ServiceLifetimeEnum.scoped, service.lifetime) + self.assertEqual(Mock, service.service_type) + self.assertEqual(Mock, service.base_type) + self.assertIsNone(service.implementation) + + def test_build_service_provider(self): + self._sc.add_singleton(Mock) + service = self._sc._service_descriptors[0] + self.assertIsNone(service.implementation) + sp = self._sc.build_service_provider() + self.assertTrue(isinstance(sp, ServiceProviderABC)) + self.assertTrue(isinstance(sp.get_service(Mock), Mock)) + self.assertIsNotNone(service.implementation) diff --git a/unittests/unittests_core/di/service_provider_test_case.py b/unittests/unittests_core/di/service_provider_test_case.py new file mode 100644 index 00000000..637a8aa8 --- /dev/null +++ b/unittests/unittests_core/di/service_provider_test_case.py @@ -0,0 +1,85 @@ +import unittest + +from cpl_core.configuration import Configuration +from cpl_core.dependency_injection import ServiceCollection, ServiceProviderABC + + +class ServiceCount: + def __init__(self): + self.count = 0 + + +class TestService: + def __init__(self, count: ServiceCount): + count.count += 1 + self.id = count.count + + +class DifferentService: + def __init__(self, count: ServiceCount): + count.count += 1 + self.id = count.count + + +class MoreDifferentService: + def __init__(self, count: ServiceCount): + count.count += 1 + self.id = count.count + + +class ServiceProviderTestCase(unittest.TestCase): + def setUp(self): + self._services = ( + ServiceCollection(Configuration()) + .add_singleton(ServiceCount) + .add_singleton(TestService) + .add_singleton(TestService) + .add_transient(DifferentService) + .add_scoped(MoreDifferentService) + .build_service_provider() + ) + + count = self._services.get_service(ServiceCount) + + def test_get_singleton(self): + x = self._services.get_service(TestService) + self.assertIsNotNone(x) + self.assertEqual(1, x.id) + self.assertEqual(x, self._services.get_service(TestService)) + self.assertEqual(x, self._services.get_service(TestService)) + self.assertEqual(x, self._services.get_service(TestService)) + + def test_get_singletons(self): + x = self._services.get_services(list[TestService]) + self.assertEqual(2, len(x)) + self.assertEqual(1, x[0].id) + self.assertEqual(2, x[1].id) + self.assertNotEqual(x[0], x[1]) + + def test_get_transient(self): + x = self._services.get_service(DifferentService) + self.assertIsNotNone(x) + self.assertEqual(1, x.id) + self.assertNotEqual(x, self._services.get_service(DifferentService)) + self.assertNotEqual(x, self._services.get_service(DifferentService)) + self.assertNotEqual(x, self._services.get_service(DifferentService)) + + def test_scoped(self): + scoped_id = 0 + singleton = self._services.get_service(TestService) + with self._services.create_scope() as scope: + sp: ServiceProviderABC = scope.service_provider + y = sp.get_service(DifferentService) + self.assertIsNotNone(y) + self.assertEqual(2, y.id) + x = sp.get_service(MoreDifferentService) + self.assertIsNotNone(x) + self.assertEqual(3, x.id) + scoped_id = 3 + self.assertEqual(x.id, sp.get_service(MoreDifferentService).id) + self.assertEqual(x.id, sp.get_service(MoreDifferentService).id) + self.assertNotEqual(x, self._services.get_service(MoreDifferentService)) + self.assertEqual(singleton, self._services.get_service(TestService)) + + self.assertIsNone(scope.service_provider) + self.assertNotEqual(scoped_id, self._services.get_service(MoreDifferentService).id) -- 2.45.2 From d189f494189ac9f6b963c5c8f19188571b9b9ad4 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Mon, 10 Apr 2023 14:53:59 +0200 Subject: [PATCH 13/14] Improved service_provider_tests --- .../di/service_provider_test_case.py | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/unittests/unittests_core/di/service_provider_test_case.py b/unittests/unittests_core/di/service_provider_test_case.py index 637a8aa8..b191434d 100644 --- a/unittests/unittests_core/di/service_provider_test_case.py +++ b/unittests/unittests_core/di/service_provider_test_case.py @@ -10,20 +10,23 @@ class ServiceCount: class TestService: - def __init__(self, count: ServiceCount): + def __init__(self, sp: ServiceProviderABC, count: ServiceCount): count.count += 1 + self.sp = sp self.id = count.count class DifferentService: - def __init__(self, count: ServiceCount): + def __init__(self, sp: ServiceProviderABC, count: ServiceCount): count.count += 1 + self.sp = sp self.id = count.count class MoreDifferentService: - def __init__(self, count: ServiceCount): + def __init__(self, sp: ServiceProviderABC, count: ServiceCount): count.count += 1 + self.sp = sp self.id = count.count @@ -67,15 +70,25 @@ class ServiceProviderTestCase(unittest.TestCase): def test_scoped(self): scoped_id = 0 singleton = self._services.get_service(TestService) + transient = self._services.get_service(DifferentService) with self._services.create_scope() as scope: sp: ServiceProviderABC = scope.service_provider + self.assertNotEqual(sp, self._services) y = sp.get_service(DifferentService) self.assertIsNotNone(y) - self.assertEqual(2, y.id) + self.assertEqual(3, y.id) x = sp.get_service(MoreDifferentService) self.assertIsNotNone(x) - self.assertEqual(3, x.id) - scoped_id = 3 + self.assertEqual(4, x.id) + scoped_id = 4 + self.assertEqual(singleton.sp, self._services) + self.assertEqual(transient.sp, self._services) + self.assertEqual(x.sp, sp) + self.assertNotEqual(x.sp, singleton.sp) + transient_in_scope = sp.get_service(DifferentService) + self.assertEqual(transient_in_scope.sp, sp) + self.assertNotEqual(transient.sp, transient_in_scope.sp) + self.assertEqual(x.id, sp.get_service(MoreDifferentService).id) self.assertEqual(x.id, sp.get_service(MoreDifferentService).id) self.assertNotEqual(x, self._services.get_service(MoreDifferentService)) -- 2.45.2 From 69a3bc5e31959bcebc161288f3edf64847ad7aff Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Mon, 10 Apr 2023 15:10:39 +0200 Subject: [PATCH 14/14] Fixed cwd handling --- unittests/unittests_cli/abc/command_test_case.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/unittests/unittests_cli/abc/command_test_case.py b/unittests/unittests_cli/abc/command_test_case.py index 754fa9dc..4bf1cd7b 100644 --- a/unittests/unittests_cli/abc/command_test_case.py +++ b/unittests/unittests_cli/abc/command_test_case.py @@ -8,6 +8,7 @@ from unittests_cli.constants import PLAYGROUND_PATH class CommandTestCase(unittest.TestCase): _skip_tear_down = False + _cwd = os.getcwd() def __init__(self, method_name: str): unittest.TestCase.__init__(self, method_name) @@ -32,6 +33,7 @@ class CommandTestCase(unittest.TestCase): if cls._skip_tear_down: return try: + os.chdir(cls._cwd) if os.path.exists(PLAYGROUND_PATH): shutil.rmtree(os.path.abspath(os.path.join(PLAYGROUND_PATH))) except Exception as e: -- 2.45.2