From c7dff4a212abcfb91b9c55b7cb6d3462d3ad04fc Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Mon, 23 Nov 2020 22:22:17 +0100 Subject: [PATCH] Added testing for service provider with unittests. Also fixed small bugs, found while testing. --- src/sh_edraft/logging/base/logger_base.py | 10 +- src/sh_edraft/logging/logger.py | 7 - src/sh_edraft/publish/base/publisher_base.py | 13 +- src/sh_edraft/publish/publisher.py | 6 - src/sh_edraft/service/service_provider.py | 2 +- src/tests/service_provider.py | 20 --- src/tests/service_provider/__init__.py | 0 .../service_provider_create.py | 13 ++ .../service_provider_services.py | 130 ++++++++++++++++++ src/tests/tester.py | 77 ++--------- 10 files changed, 178 insertions(+), 100 deletions(-) delete mode 100644 src/tests/service_provider.py create mode 100644 src/tests/service_provider/__init__.py create mode 100644 src/tests/service_provider/service_provider_create.py create mode 100644 src/tests/service_provider/service_provider_services.py diff --git a/src/sh_edraft/logging/base/logger_base.py b/src/sh_edraft/logging/base/logger_base.py index d9579484..b4030be0 100644 --- a/src/sh_edraft/logging/base/logger_base.py +++ b/src/sh_edraft/logging/base/logger_base.py @@ -1,6 +1,10 @@ from abc import abstractmethod +from typing import Optional -from sh_edraft.service.base import ServiceBase +from sh_edraft.configuration.application_host import ApplicationHost +from sh_edraft.logging.model.log_settings import LoggingSettings +from sh_edraft.service.base.service_base import ServiceBase +from sh_edraft.time.model.time_format_settings import TimeFormatSettings class LoggerBase(ServiceBase): @@ -9,6 +13,10 @@ class LoggerBase(ServiceBase): def __init__(self): ServiceBase.__init__(self) + self._log_settings: Optional[LoggingSettings] = None + self._time_format_settings: Optional[TimeFormatSettings] = None + self._app_host: Optional[ApplicationHost] = None + @abstractmethod def header(self, string: str): pass diff --git a/src/sh_edraft/logging/logger.py b/src/sh_edraft/logging/logger.py index 132369d8..689ca901 100644 --- a/src/sh_edraft/logging/logger.py +++ b/src/sh_edraft/logging/logger.py @@ -4,11 +4,8 @@ import traceback from string import Template from typing import Optional -from sh_edraft.configuration.application_host import ApplicationHost from sh_edraft.logging.base.logger_base import LoggerBase from sh_edraft.logging.model.log_level import LoggingLevel -from sh_edraft.logging.model.log_settings import LoggingSettings -from sh_edraft.time.model.time_format_settings import TimeFormatSettings from sh_edraft.utils.console import Console @@ -17,10 +14,6 @@ class Logger(LoggerBase): def __init__(self): LoggerBase.__init__(self) - self._log_settings: Optional[LoggingSettings] = None - self._time_format_settings: Optional[TimeFormatSettings] = None - self._app_host: Optional[ApplicationHost] = None - self._log: Optional[str] = None self._path: Optional[str] = None self._level: Optional[LoggingLevel] = None diff --git a/src/sh_edraft/publish/base/publisher_base.py b/src/sh_edraft/publish/base/publisher_base.py index 51c3d086..2a2bea92 100644 --- a/src/sh_edraft/publish/base/publisher_base.py +++ b/src/sh_edraft/publish/base/publisher_base.py @@ -1,6 +1,9 @@ from abc import abstractmethod +from typing import Optional -from sh_edraft.service.base import ServiceBase +from sh_edraft.logging.base.logger_base import LoggerBase +from sh_edraft.publish.model.template import Template +from sh_edraft.service.base.service_base import ServiceBase class PublisherBase(ServiceBase): @@ -9,6 +12,14 @@ class PublisherBase(ServiceBase): def __init__(self): ServiceBase.__init__(self) + self._logger: Optional[LoggerBase] = None + self._source_path: Optional[str] = None + self._dist_path: Optional[str] = None + self._settings: Optional[list[Template]] = None + + self._included_files: list[str] = [] + self._excluded_files: list[str] = [] + @property @abstractmethod def source_path(self) -> str: pass diff --git a/src/sh_edraft/publish/publisher.py b/src/sh_edraft/publish/publisher.py index 7fae4fff..1b371ed6 100644 --- a/src/sh_edraft/publish/publisher.py +++ b/src/sh_edraft/publish/publisher.py @@ -1,7 +1,6 @@ import os import shutil from string import Template as stringTemplate -from typing import Optional from sh_edraft.logging.base.logger_base import LoggerBase from sh_edraft.publish.base.publisher_base import PublisherBase @@ -13,11 +12,6 @@ class Publisher(PublisherBase): def __init__(self): super().__init__() - self._logger: Optional[LoggerBase] = None - self._source_path: Optional[str] = None - self._dist_path: Optional[str] = None - self._settings: Optional[list[Template]] = None - self._included_files: list[str] = [] self._excluded_files: list[str] = [] diff --git a/src/sh_edraft/service/service_provider.py b/src/sh_edraft/service/service_provider.py index fdc93c36..60627d42 100644 --- a/src/sh_edraft/service/service_provider.py +++ b/src/sh_edraft/service/service_provider.py @@ -30,7 +30,7 @@ class ServiceProvider(ServiceProviderBase): self._transient_services.append(ProvideState(service, args)) def add_scoped(self, service: Type[ServiceBase], *args): - self._transient_services.append(ProvideState(service, args)) + self._scoped_services.append(ProvideState(service, args)) def add_singleton(self, service: Type[ServiceBase], *args): for known_service in self._singleton_services: diff --git a/src/tests/service_provider.py b/src/tests/service_provider.py deleted file mode 100644 index 676cc604..00000000 --- a/src/tests/service_provider.py +++ /dev/null @@ -1,20 +0,0 @@ -from sh_edraft.logging.base.logger_base import LoggerBase -from sh_edraft.publish import Publisher -from sh_edraft.publish.base import PublisherBase -from sh_edraft.service.base import ServiceProviderBase - - -class ServiceProviderTest: - - @staticmethod - def start(services: ServiceProviderBase): - services.add_transient(Publisher, services.get_service(LoggerBase), '../', '../../dist', []) - - publisher: Publisher = services.get_service(PublisherBase) - - if publisher is None or publisher.source_path != '../' or publisher.dist_path != '../../dist': - raise Exception(f'{__name__}: Invalid value in {Publisher.__name__}') - - services.remove_service(PublisherBase) - if services.get_service(PublisherBase) is not None: - raise Exception(f'{__name__}: Service {Publisher.__name__} was not removed') diff --git a/src/tests/service_provider/__init__.py b/src/tests/service_provider/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/tests/service_provider/service_provider_create.py b/src/tests/service_provider/service_provider_create.py new file mode 100644 index 00000000..870b5d14 --- /dev/null +++ b/src/tests/service_provider/service_provider_create.py @@ -0,0 +1,13 @@ +import unittest + +from sh_edraft.service import ServiceProvider + + +class ServiceProviderCreate(unittest.TestCase): + + def test_create(self): + provider = ServiceProvider() + self.assertIsNotNone(provider) + provider.init(()) + provider.create() + self.assertIsNotNone(provider) diff --git a/src/tests/service_provider/service_provider_services.py b/src/tests/service_provider/service_provider_services.py new file mode 100644 index 00000000..5e65a2ea --- /dev/null +++ b/src/tests/service_provider/service_provider_services.py @@ -0,0 +1,130 @@ +import os +import unittest +from string import Template + +from sh_edraft.configuration import ApplicationHost +from sh_edraft.logging import Logger +from sh_edraft.logging.base import LoggerBase +from sh_edraft.logging.model import LoggingSettings +from sh_edraft.publish import Publisher +from sh_edraft.publish.base import PublisherBase +from sh_edraft.service.base import ServiceBase +from sh_edraft.time.model import TimeFormatSettings + + +class ServiceProviderServices(unittest.TestCase): + + def setUp(self): + self._app_host = ApplicationHost() + self._services = self._app_host.services + self._services.init(()) + self._services.create() + + self._log_settings = LoggingSettings() + self._log_settings.from_dict({ + "Path": "logs/", + "Filename": "log_$start_time.log", + "ConsoleLogLevel": "TRACE", + "FileLogLevel": "TRACE" + }) + + self._time_format_settings = TimeFormatSettings() + self._time_format_settings.from_dict({ + "DateFormat": "%Y-%m-%d", + "TimeFormat": "%H:%M:%S", + "DateTimeFormat": "%Y-%m-%d %H:%M:%S.%f", + "DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S" + }) + + def _check_general_requirements(self): + self.assertIsNotNone(self._services) + + def _check_logger_requirements(self): + self.assertIsNotNone(self._log_settings) + self.assertIsNotNone(self._time_format_settings) + + def test_add_singleton(self): + print(f'{__name__}.test_add_singleton:') + self._check_general_requirements() + self._check_logger_requirements() + + self._services.add_singleton(Logger, self._log_settings, self._time_format_settings, self._app_host) + self.assertGreater(len(self._services._singleton_services), 0) + + found = False + for service in self._services._singleton_services: + if isinstance(service, Logger) and isinstance(service, LoggerBase) and isinstance(service, ServiceBase): + if not found: + found = True + + self.assertTrue(found) + + def test_get_singleton(self): + print(f'{__name__}.test_get_singleton:') + self._check_general_requirements() + self._check_logger_requirements() + + self._services.add_singleton(Logger, self._log_settings, self._time_format_settings, self._app_host) + logger: Logger = self._services.get_service(LoggerBase) + self.assertIsNotNone(logger) + self.assertTrue(isinstance(logger, Logger)) + self.assertTrue(isinstance(logger, LoggerBase)) + self.assertTrue(isinstance(logger, ServiceBase)) + + self.assertEqual(logger._log_settings, self._log_settings) + self.assertEqual(logger._time_format_settings, self._time_format_settings) + self.assertEqual(logger._app_host, self._app_host) + + def test_add_scoped(self): + print(f'{__name__}.test_add_scoped:') + self._check_general_requirements() + self._check_logger_requirements() + + self._services.add_singleton(Logger, self._log_settings, self._time_format_settings, self._app_host) + self._services.add_scoped(Publisher, self._services.get_service(LoggerBase), '../', '../../dist', []) + self.assertGreater(len(self._services._scoped_services), 0) + + def test_get_scoped(self): + print(f'{__name__}.test_get_scoped:') + self._check_general_requirements() + self._check_logger_requirements() + + self._services.add_singleton(Logger, self._log_settings, self._time_format_settings, self._app_host) + self._services.add_scoped(Publisher, self._services.get_service(LoggerBase), '../', '../../dist', []) + publisher: Publisher = self._services.get_service(PublisherBase) + self.assertIsNotNone(publisher) + self.assertTrue(isinstance(publisher, Publisher)) + self.assertTrue(isinstance(publisher, PublisherBase)) + self.assertTrue(isinstance(publisher, ServiceBase)) + + self.assertTrue(isinstance(publisher._logger, Logger)) + self.assertTrue(isinstance(publisher._logger, LoggerBase)) + self.assertTrue(isinstance(publisher._logger, ServiceBase)) + + def test_add_transient(self): + print(f'{__name__}.test_add_transient:') + self._check_general_requirements() + self._check_logger_requirements() + + self._services.add_singleton(Logger, self._log_settings, self._time_format_settings, self._app_host) + self._services.add_transient(Publisher, self._services.get_service(LoggerBase), '../', '../../dist', []) + self.assertGreater(len(self._services._transient_services), 0) + + self.assertTrue(bool(isinstance(service, ServiceBase) for service in self._services._transient_services)) + + def test_get_transient(self): + print(f'{__name__}.test_get_transient:') + self._check_general_requirements() + self._check_logger_requirements() + + self._services.add_singleton(Logger, self._log_settings, self._time_format_settings, self._app_host) + self._services.add_transient(Publisher, self._services.get_service(LoggerBase), '../', '../../dist', []) + publisher: Publisher = self._services.get_service(PublisherBase) + self.assertIsNotNone(publisher) + self.assertTrue(isinstance(publisher, Publisher)) + self.assertTrue(isinstance(publisher, PublisherBase)) + self.assertTrue(isinstance(publisher, ServiceBase)) + + self.assertTrue(isinstance(publisher._logger, Logger)) + self.assertTrue(isinstance(publisher._logger, LoggerBase)) + self.assertTrue(isinstance(publisher._logger, ServiceBase)) diff --git a/src/tests/tester.py b/src/tests/tester.py index e4eb313e..234ad59a 100644 --- a/src/tests/tester.py +++ b/src/tests/tester.py @@ -1,79 +1,28 @@ -import os -import sys -import traceback +import unittest -from termcolor import colored - -from sh_edraft.configuration import ApplicationHost -from tests.logger import LoggerTest -from tests.publisher import PublisherTest -from tests.service_provider import ServiceProviderTest +from tests.service_provider.service_provider_create import ServiceProviderCreate +from tests.service_provider.service_provider_services import ServiceProviderServices class Tester: def __init__(self): - self._app_host = ApplicationHost() + self._suite = unittest.TestSuite() - self._error: bool = False - - @staticmethod - def disable_print(): - sys.stdout = open(os.devnull, 'w') - - @staticmethod - def enable_print(): - sys.stdout = sys.__stdout__ - - def success(self, message: str): - self.enable_print() - print(colored(message, 'green')) - self.disable_print() - - def failed(self, message: str): - self.enable_print() - print(colored(message, 'red')) - self.disable_print() - - def exception(self): - self.enable_print() - print(colored(traceback.format_exc(), 'red')) - self.disable_print() - - def create(self): pass + def create(self): + self._suite.addTest(ServiceProviderCreate('test_create')) + self._suite.addTest(ServiceProviderServices('test_add_singleton')) + self._suite.addTest(ServiceProviderServices('test_get_singleton')) + self._suite.addTest(ServiceProviderServices('test_add_scoped')) + self._suite.addTest(ServiceProviderServices('test_get_scoped')) + self._suite.addTest(ServiceProviderServices('test_add_transient')) + self._suite.addTest(ServiceProviderServices('test_get_transient')) def start(self): - if not self._error: - try: - LoggerTest.start(self._app_host) - self.success(f'{LoggerTest.__name__} test succeeded.') - except Exception as e: - self._error = True - self.failed(f'{LoggerTest.__name__} test failed!\n{e}') - self.exception() - - if not self._error: - try: - ServiceProviderTest.start(self._app_host.services) - self.success(f'{ServiceProviderTest.__name__} test succeeded.') - except Exception as e: - self._error = True - self.failed(f'{ServiceProviderTest.__name__} test failed!\n{e}') - self.exception() - - if not self._error: - try: - PublisherTest.start(self._app_host.services) - self.success(f'{PublisherTest.__name__} test succeeded.') - except Exception as e: - self._error = True - self.failed(f'{PublisherTest.__name__} test failed!\n{e}') - self.exception() + unittest.main() if __name__ == '__main__': tester = Tester() tester.create() - tester.disable_print() tester.start() - tester.enable_print()