Compare commits
1 Commits
#191_tests
...
2025.10.19
| Author | SHA1 | Date | |
|---|---|---|---|
| 88d5d78583 |
@@ -3,8 +3,7 @@
|
|||||||
"projects": [
|
"projects": [
|
||||||
"src/cli/cpl.project.json",
|
"src/cli/cpl.project.json",
|
||||||
"src/core/cpl.project.json",
|
"src/core/cpl.project.json",
|
||||||
"src/mail/cpl.project.json",
|
"src/mail/cpl.project.json"
|
||||||
"test/cpl.project.json"
|
|
||||||
],
|
],
|
||||||
"defaultProject": "cpl-cli",
|
"defaultProject": "cpl-cli",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -75,3 +75,9 @@ class Application(ApplicationABC):
|
|||||||
test_settings1 = Configuration.get(TestSettings)
|
test_settings1 = Configuration.get(TestSettings)
|
||||||
Console.write_line(test_settings1.value)
|
Console.write_line(test_settings1.value)
|
||||||
# self.test_send_mail()
|
# self.test_send_mail()
|
||||||
|
|
||||||
|
x = 0
|
||||||
|
while x < 500:
|
||||||
|
Console.write_line("Running...")
|
||||||
|
x += 1
|
||||||
|
await asyncio.sleep(5)
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
from application import Application
|
from application import Application
|
||||||
from cpl.application import ApplicationBuilder
|
from cpl.application import ApplicationBuilder
|
||||||
from cpl.core.console import Console
|
|
||||||
from test_extension import TestExtension
|
from test_extension import TestExtension
|
||||||
from startup import Startup
|
from startup import Startup
|
||||||
from test_startup_extension import TestStartupExtension
|
from test_startup_extension import TestStartupExtension
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
Console.write_line("\n\n--- Application Starting ---\n")
|
|
||||||
app_builder = ApplicationBuilder(Application)
|
app_builder = ApplicationBuilder(Application)
|
||||||
app_builder.with_startup(Startup)
|
app_builder.with_startup(Startup)
|
||||||
app_builder.with_extension(TestStartupExtension)
|
app_builder.with_extension(TestStartupExtension)
|
||||||
|
|||||||
@@ -22,6 +22,22 @@ class ApplicationABC(ABC):
|
|||||||
Contains instances of prepared objects
|
Contains instances of prepared objects
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def extend(cls, name: str | Callable, func: Callable[[Self], Self]):
|
||||||
|
r"""Extend the Application with a custom method
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
name: :class:`str`
|
||||||
|
Name of the method
|
||||||
|
func: :class:`Callable[[Self], Self]`
|
||||||
|
Function that takes the Application as a parameter and returns it
|
||||||
|
"""
|
||||||
|
if callable(name):
|
||||||
|
name = name.__name__
|
||||||
|
|
||||||
|
setattr(cls, name, func)
|
||||||
|
return cls
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def __init__(
|
def __init__(
|
||||||
self, services: ServiceProvider, loaded_modules: set[TModule], required_modules: list[str | object] = None
|
self, services: ServiceProvider, loaded_modules: set[TModule], required_modules: list[str | object] = None
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from typing import Callable
|
|||||||
from cpl.core.property import classproperty
|
from cpl.core.property import classproperty
|
||||||
from cpl.dependency.context import get_provider, use_root_provider
|
from cpl.dependency.context import get_provider, use_root_provider
|
||||||
from cpl.dependency.service_collection import ServiceCollection
|
from cpl.dependency.service_collection import ServiceCollection
|
||||||
from cpl.core.service.startup_task import StartupTask
|
from cpl.dependency.hosted.startup_task import StartupTask
|
||||||
|
|
||||||
|
|
||||||
class Host:
|
class Host:
|
||||||
@@ -86,9 +86,10 @@ class Host:
|
|||||||
func(*args, **kwargs)
|
func(*args, **kwargs)
|
||||||
except (KeyboardInterrupt, asyncio.CancelledError):
|
except (KeyboardInterrupt, asyncio.CancelledError):
|
||||||
pass
|
pass
|
||||||
|
finally:
|
||||||
|
await cls._stop_all()
|
||||||
|
|
||||||
cls.get_loop().run_until_complete(runner())
|
cls.get_loop().run_until_complete(runner())
|
||||||
cls.get_loop().run_until_complete(cls.wait_for_all())
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def run(cls, func: Callable, *args, **kwargs):
|
def run(cls, func: Callable, *args, **kwargs):
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
from cpl.core.console import Console
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
Console.write_line("Hello, World!")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
@@ -5,7 +5,6 @@ from pathlib import Path
|
|||||||
import click
|
import click
|
||||||
|
|
||||||
from cpl.cli.cli import cli
|
from cpl.cli.cli import cli
|
||||||
from cpl.cli.model.project import Project
|
|
||||||
from cpl.cli.utils.structure import Structure
|
from cpl.cli.utils.structure import Structure
|
||||||
from cpl.cli.utils.venv import get_venv_python, ensure_venv
|
from cpl.cli.utils.venv import get_venv_python, ensure_venv
|
||||||
from cpl.core.configuration import Configuration
|
from cpl.core.configuration import Configuration
|
||||||
@@ -22,42 +21,35 @@ def run(project: str, args: list[str], dev: bool, verbose: bool):
|
|||||||
if project is not None:
|
if project is not None:
|
||||||
project_path = (Path("./") / project).resolve().absolute()
|
project_path = (Path("./") / project).resolve().absolute()
|
||||||
|
|
||||||
project = Structure.get_project_by_name_or_path(project_path)
|
project = Structure.get_project_by_name_or_path(str(project_path))
|
||||||
is_unittest = project.type == "unittest"
|
if project.main is None:
|
||||||
if not is_unittest and project.main is None:
|
|
||||||
Console.error(f"Project {project.name} has no executable")
|
Console.error(f"Project {project.name} has no executable")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
path = str(Path(project.path).parent.resolve().absolute())
|
||||||
|
executable = project.main
|
||||||
|
if not dev:
|
||||||
|
dist_path = Path(project.path).parent / "dist"
|
||||||
|
|
||||||
|
if Configuration.get("workspace") is not None:
|
||||||
|
dist_path = Path(Configuration.get("workspace").path).parent / "dist"
|
||||||
|
|
||||||
|
dist_path = Path(dist_path).resolve().absolute()
|
||||||
|
if verbose:
|
||||||
|
Console.write_line(f"Creating dist folder at {dist_path}...")
|
||||||
|
|
||||||
|
os.makedirs(dist_path, exist_ok=True)
|
||||||
|
project.do_build(dist_path, verbose)
|
||||||
|
path = dist_path / project.name
|
||||||
|
main = project.main.replace(project.directory, "").lstrip("/\\")
|
||||||
|
|
||||||
|
executable = path / main
|
||||||
|
|
||||||
|
python = str(get_venv_python(ensure_venv()).absolute())
|
||||||
Console.write_line(f"\nStarting project {project.name}...")
|
Console.write_line(f"\nStarting project {project.name}...")
|
||||||
if verbose:
|
if verbose:
|
||||||
Console.write_line(f" with args {args}...")
|
Console.write_line(f" with args {args}...")
|
||||||
|
|
||||||
Console.write_line("\n\n")
|
Console.write_line("\n\n")
|
||||||
|
|
||||||
path = str(Path(project.path).parent.resolve().absolute())
|
subprocess.run([python, executable, *args], cwd=path)
|
||||||
python = str(get_venv_python(ensure_venv()).absolute())
|
|
||||||
if is_unittest:
|
|
||||||
subprocess.run([python, "-m", "pytest", path], cwd=path)
|
|
||||||
return
|
|
||||||
subprocess.run([python, _get_executable(project, dev, verbose), *args], cwd=path)
|
|
||||||
|
|
||||||
|
|
||||||
def _get_executable(project: Project, dev: bool, verbose: bool) -> str:
|
|
||||||
if dev:
|
|
||||||
return project.main
|
|
||||||
|
|
||||||
dist_path = Path(project.path).parent / "dist"
|
|
||||||
|
|
||||||
if Configuration.get("workspace") is not None:
|
|
||||||
dist_path = Path(Configuration.get("workspace").path).parent / "dist"
|
|
||||||
|
|
||||||
dist_path = Path(dist_path).resolve().absolute()
|
|
||||||
if verbose:
|
|
||||||
Console.write_line(f"Creating dist folder at {dist_path}...")
|
|
||||||
|
|
||||||
os.makedirs(dist_path, exist_ok=True)
|
|
||||||
project.do_build(dist_path, verbose)
|
|
||||||
path = dist_path / project.name
|
|
||||||
main = project.main.replace(project.directory, "").lstrip("/\\")
|
|
||||||
|
|
||||||
return str(path / main)
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
PROJECT_TYPES = ["console", "web", "graphql", "library", "service", "unittest"]
|
PROJECT_TYPES = ["console", "web", "graphql", "library", "service"]
|
||||||
PROJECT_TYPES_SHORT = [x[0] for x in PROJECT_TYPES]
|
PROJECT_TYPES_SHORT = [x[0] for x in PROJECT_TYPES]
|
||||||
|
|
||||||
PIP_URL = "https://git.sh-edraft.de/api/packages/sh-edraft.de/pypi/simple/"
|
PIP_URL = "https://git.sh-edraft.de/api/packages/sh-edraft.de/pypi/simple/"
|
||||||
|
|||||||
@@ -11,16 +11,12 @@ T = TypeVar("T", bound="CPLStructureModel")
|
|||||||
|
|
||||||
|
|
||||||
class CPLStructureModel:
|
class CPLStructureModel:
|
||||||
def __init__(self, path: Optional[str] = None, ignore_fields: Optional[List[str]] = None):
|
def __init__(self, path: Optional[str] = None):
|
||||||
self._path = path
|
self.__path = path
|
||||||
|
|
||||||
self._ignore = {"_ignore", "_path"}
|
|
||||||
if ignore_fields is not None:
|
|
||||||
self._ignore.update(ignore_fields)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def path(self) -> Optional[str]:
|
def path(self) -> Optional[str]:
|
||||||
return self._path
|
return self.__path
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_file(cls: Type[T], path: Path | str) -> T:
|
def from_file(cls: Type[T], path: Path | str) -> T:
|
||||||
@@ -72,7 +68,7 @@ class CPLStructureModel:
|
|||||||
def to_json(self) -> Dict[str, Any]:
|
def to_json(self) -> Dict[str, Any]:
|
||||||
result: Dict[str, Any] = {}
|
result: Dict[str, Any] = {}
|
||||||
for key, value in self.__dict__.items():
|
for key, value in self.__dict__.items():
|
||||||
if not key.startswith("_") or key in self._ignore:
|
if not key.startswith("_") or key.startswith("__") or key.endswith("_"):
|
||||||
continue
|
continue
|
||||||
out_key = _self_or_cls_snake_to_camel(key[1:])
|
out_key = _self_or_cls_snake_to_camel(key[1:])
|
||||||
|
|
||||||
@@ -83,13 +79,13 @@ class CPLStructureModel:
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
if not self._path:
|
if not self.__path:
|
||||||
raise ValueError("Cannot save model without a path.")
|
raise ValueError("Cannot save model without a path.")
|
||||||
|
|
||||||
if not Path(self._path).exists():
|
if not Path(self.__path).exists():
|
||||||
os.makedirs(Path(self._path).parent, exist_ok=True)
|
os.makedirs(Path(self.__path).parent, exist_ok=True)
|
||||||
|
|
||||||
with open(self._path, "w", encoding="utf-8") as f:
|
with open(self.__path, "w", encoding="utf-8") as f:
|
||||||
json.dump(self.to_json(), f, indent=2)
|
json.dump(self.to_json(), f, indent=2)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|||||||
@@ -24,24 +24,23 @@ class Workspace(CPLStructureModel):
|
|||||||
default_project: Optional[str],
|
default_project: Optional[str],
|
||||||
scripts: Dict[str, str],
|
scripts: Dict[str, str],
|
||||||
):
|
):
|
||||||
CPLStructureModel.__init__(self, path, ["_actual_projects", "_project_names"])
|
CPLStructureModel.__init__(self, path)
|
||||||
|
|
||||||
self._name = name
|
self._name = name
|
||||||
self._projects = projects
|
self._projects = projects
|
||||||
self._default_project = default_project
|
self._default_project = default_project
|
||||||
|
|
||||||
self._actual_projects = []
|
self.__actual_projects = []
|
||||||
self._project_names = []
|
self.__project_names = []
|
||||||
for project in projects:
|
for project in projects:
|
||||||
p_path = (Path(path).parent / Path(project)).resolve().absolute()
|
if Path(project).is_dir() or not Path(project).exists():
|
||||||
if p_path.is_dir() or not p_path.exists():
|
|
||||||
raise ValueError(f"Project path '{project}' does not exist or is a directory.")
|
raise ValueError(f"Project path '{project}' does not exist or is a directory.")
|
||||||
|
|
||||||
p = Project.from_file(p_path)
|
p = Project.from_file(project)
|
||||||
self._actual_projects.append(p)
|
self.__actual_projects.append(p)
|
||||||
self._project_names.append(p.name)
|
self.__project_names.append(p.name)
|
||||||
|
|
||||||
if default_project is not None and default_project not in self._project_names:
|
if default_project is not None and default_project not in self.__project_names:
|
||||||
raise ValueError(f"Default project '{default_project}' not found in workspace projects.")
|
raise ValueError(f"Default project '{default_project}' not found in workspace projects.")
|
||||||
|
|
||||||
self._scripts = scripts
|
self._scripts = scripts
|
||||||
@@ -64,11 +63,11 @@ class Workspace(CPLStructureModel):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def actual_projects(self) -> List[Project]:
|
def actual_projects(self) -> List[Project]:
|
||||||
return self._actual_projects
|
return self.__actual_projects
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def project_names(self) -> List[str]:
|
def project_names(self) -> List[str]:
|
||||||
return self._project_names
|
return self.__project_names
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def default_project(self) -> Optional[str]:
|
def default_project(self) -> Optional[str]:
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ class Structure:
|
|||||||
pyproject_path.write_text(content)
|
pyproject_path.write_text(content)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_project_by_name_or_path(project: str | Path) -> Project:
|
def get_project_by_name_or_path(project: str) -> Project:
|
||||||
if project is None:
|
if project is None:
|
||||||
raise ValueError("Project name or path must be provided.")
|
raise ValueError("Project name or path must be provided.")
|
||||||
|
|
||||||
@@ -86,10 +86,9 @@ class Structure:
|
|||||||
if workspace is None:
|
if workspace is None:
|
||||||
raise RuntimeError("No workspace found. Please run 'cpl init workspace' first.")
|
raise RuntimeError("No workspace found. Please run 'cpl init workspace' first.")
|
||||||
|
|
||||||
project_name = project.name if isinstance(project, Path) else project
|
|
||||||
for p in workspace.actual_projects:
|
for p in workspace.actual_projects:
|
||||||
if p.name == project_name:
|
if p.name == project:
|
||||||
return Project.from_file((Path(workspace.path).parent / Path(p.path)).resolve())
|
return Project.from_file(Path(p.path))
|
||||||
|
|
||||||
if not path.is_dir() and not path.is_file():
|
if not path.is_dir() and not path.is_file():
|
||||||
raise ValueError(f"Unknown project {project}")
|
raise ValueError(f"Unknown project {project}")
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from abc import ABC, abstractmethod
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from cpl.core.time.cron import Cron
|
from cpl.core.time.cron import Cron
|
||||||
from cpl.core.service import HostedService
|
from cpl.dependency.hosted import HostedService
|
||||||
|
|
||||||
|
|
||||||
class CronjobABC(HostedService, ABC):
|
class CronjobABC(HostedService, ABC):
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
from types import NoneType
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
@@ -7,17 +6,7 @@ class Number:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def is_number(value: Any) -> bool:
|
def is_number(value: Any) -> bool:
|
||||||
"""Check if the value is a number (int or float)."""
|
"""Check if the value is a number (int or float)."""
|
||||||
if isinstance(value, (bool, NoneType)):
|
return isinstance(value, (int, float, complex))
|
||||||
return False
|
|
||||||
|
|
||||||
if isinstance(value, (int, float, complex)):
|
|
||||||
return True
|
|
||||||
|
|
||||||
try:
|
|
||||||
Number.to_number(value)
|
|
||||||
return True
|
|
||||||
except (ValueError, TypeError):
|
|
||||||
return False
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def to_number(value: Any) -> int | float | complex:
|
def to_number(value: Any) -> int | float | complex:
|
||||||
|
|||||||
@@ -18,15 +18,14 @@ class String:
|
|||||||
String converted to CamelCase
|
String converted to CamelCase
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if re.search(r'[_\-\s]', s):
|
parts = re.split(r"[^a-zA-Z0-9]+", s.strip())
|
||||||
words = re.split(r'[_\-\s]+', s)
|
|
||||||
else:
|
|
||||||
words = re.findall(r'[A-Z]?[a-z]+|[A-Z]+(?=[A-Z]|$)', s)
|
|
||||||
|
|
||||||
words = [w.lower() for w in words if w]
|
parts = [p for p in parts if p]
|
||||||
if not words:
|
|
||||||
return ''
|
if not parts:
|
||||||
return words[0] + ''.join(w.capitalize() for w in words[1:])
|
return ""
|
||||||
|
|
||||||
|
return parts[0].lower() + "".join(word.capitalize() for word in parts[1:])
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def to_pascal_case(s: str) -> str:
|
def to_pascal_case(s: str) -> str:
|
||||||
@@ -40,12 +39,14 @@ class String:
|
|||||||
String converted to PascalCase
|
String converted to PascalCase
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if re.search(r'[_\-\s]', s):
|
parts = re.split(r"[^a-zA-Z0-9]+", s.strip())
|
||||||
words = re.split(r'[_\-\s]+', s)
|
|
||||||
else:
|
|
||||||
words = re.findall(r'[A-Z]?[a-z]+|[A-Z]+(?=[A-Z]|$)', s)
|
|
||||||
|
|
||||||
return ''.join(word.capitalize() for word in words if word)
|
parts = [p for p in parts if p]
|
||||||
|
|
||||||
|
if not parts:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
return "".join(word.capitalize() for word in parts)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def to_snake_case(chars: str) -> str:
|
def to_snake_case(chars: str) -> str:
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from cpl.database.model.migration import Migration
|
|||||||
from cpl.database.model.server_type import ServerType, ServerTypes
|
from cpl.database.model.server_type import ServerType, ServerTypes
|
||||||
from cpl.database.schema.executed_migration import ExecutedMigration
|
from cpl.database.schema.executed_migration import ExecutedMigration
|
||||||
from cpl.database.schema.executed_migration_dao import ExecutedMigrationDao
|
from cpl.database.schema.executed_migration_dao import ExecutedMigrationDao
|
||||||
from cpl.core.service import StartupTask
|
from cpl.dependency.hosted import StartupTask
|
||||||
|
|
||||||
|
|
||||||
class MigrationService(StartupTask):
|
class MigrationService(StartupTask):
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from cpl.database.abc.data_seeder_abc import DataSeederABC
|
from cpl.database.abc.data_seeder_abc import DataSeederABC
|
||||||
from cpl.database.logger import DBLogger
|
from cpl.database.logger import DBLogger
|
||||||
from cpl.dependency import ServiceProvider
|
from cpl.dependency import ServiceProvider
|
||||||
from cpl.core.service import StartupTask
|
from cpl.dependency.hosted import StartupTask
|
||||||
|
|
||||||
|
|
||||||
class SeederService(StartupTask):
|
class SeederService(StartupTask):
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from cpl.core.errors import module_dependency_error
|
|||||||
from cpl.core.log.logger_abc import LoggerABC
|
from cpl.core.log.logger_abc import LoggerABC
|
||||||
from cpl.core.typing import T, Service
|
from cpl.core.typing import T, Service
|
||||||
from cpl.core.utils.cache import Cache
|
from cpl.core.utils.cache import Cache
|
||||||
from cpl.core.service.startup_task import StartupTask
|
from cpl.dependency.hosted.startup_task import StartupTask
|
||||||
from cpl.dependency.module.module import Module
|
from cpl.dependency.module.module import Module
|
||||||
from cpl.dependency.service_descriptor import ServiceDescriptor
|
from cpl.dependency.service_descriptor import ServiceDescriptor
|
||||||
from cpl.dependency.service_lifetime import ServiceLifetimeEnum
|
from cpl.dependency.service_lifetime import ServiceLifetimeEnum
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from typing import Type
|
|||||||
|
|
||||||
from cpl.core.configuration import ConfigurationModelABC
|
from cpl.core.configuration import ConfigurationModelABC
|
||||||
from cpl.core.typing import T
|
from cpl.core.typing import T
|
||||||
from cpl.core.service import StartupTask
|
from cpl.dependency.hosted import StartupTask
|
||||||
from cpl.dependency.module.module import Module
|
from cpl.dependency.module.module import Module
|
||||||
|
|
||||||
TModule = Type[Module]
|
TModule = Type[Module]
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
from cpl.core.utils.base64 import Base64
|
|
||||||
|
|
||||||
|
|
||||||
def test_encode():
|
|
||||||
assert Base64.encode("hello world") == "aGVsbG8gd29ybGQ="
|
|
||||||
s = "foobar"
|
|
||||||
assert Base64.encode(s) and isinstance(Base64.encode(s), str)
|
|
||||||
|
|
||||||
|
|
||||||
def test_decode():
|
|
||||||
out = Base64.decode("aGVsbG8gd29ybGQ=")
|
|
||||||
if isinstance(out, bytes):
|
|
||||||
out = out.decode("utf-8")
|
|
||||||
assert out == "hello world"
|
|
||||||
|
|
||||||
orig = "äöü߀"
|
|
||||||
enc = Base64.encode(orig)
|
|
||||||
dec = Base64.decode(enc)
|
|
||||||
if isinstance(dec, bytes):
|
|
||||||
dec = dec.decode("utf-8")
|
|
||||||
assert dec == orig
|
|
||||||
|
|
||||||
|
|
||||||
def test_is_b64():
|
|
||||||
assert Base64.is_b64("Zm9vYmFy") # "foobar"
|
|
||||||
assert Base64.is_b64("Zm8=") # "fo"
|
|
||||||
assert not Base64.is_b64("not_base64??")
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
import pytest
|
|
||||||
from enum import Enum
|
|
||||||
from typing import List
|
|
||||||
from cpl.core.utils.cast import cast
|
|
||||||
|
|
||||||
|
|
||||||
class Color(Enum):
|
|
||||||
RED = "red"
|
|
||||||
GREEN = "green"
|
|
||||||
|
|
||||||
|
|
||||||
class Status(Enum):
|
|
||||||
OK = 200
|
|
||||||
ERROR = 500
|
|
||||||
|
|
||||||
|
|
||||||
def test_cast_none_returns_none():
|
|
||||||
assert cast(None, int) is None
|
|
||||||
|
|
||||||
|
|
||||||
def test_cast_bool_true_values():
|
|
||||||
assert cast("true", bool) is True
|
|
||||||
assert cast("YES", bool) is True
|
|
||||||
assert cast("1", bool) is True
|
|
||||||
assert cast("On", bool) is True
|
|
||||||
|
|
||||||
|
|
||||||
def test_cast_bool_false_values():
|
|
||||||
assert cast("false", bool) is False
|
|
||||||
assert cast("0", bool) is False
|
|
||||||
assert cast("no", bool) is False
|
|
||||||
assert cast("off", bool) is False
|
|
||||||
|
|
||||||
|
|
||||||
def test_cast_list_of_str_with_brackets():
|
|
||||||
assert cast("[a,b,c]", List[str]) == ["a", "b", "c"]
|
|
||||||
|
|
||||||
|
|
||||||
def test_cast_list_of_str_with_delimiter_no_brackets():
|
|
||||||
assert cast("a,b,c", List[str]) == ["a", "b", "c"]
|
|
||||||
|
|
||||||
|
|
||||||
def test_cast_list_of_int_with_brackets():
|
|
||||||
assert cast("[1,2,3]", List[int]) == [1, 2, 3]
|
|
||||||
|
|
||||||
|
|
||||||
def test_cast_list_custom_delimiter():
|
|
||||||
assert cast("1;2;3", List[int], list_delimiter=";") == [1, 2, 3]
|
|
||||||
|
|
||||||
|
|
||||||
def test_cast_list_without_brackets_or_delimiter_errors():
|
|
||||||
with pytest.raises(ValueError):
|
|
||||||
cast("abc", List[str])
|
|
||||||
|
|
||||||
|
|
||||||
def test_cast_enum_by_value_case_insensitive():
|
|
||||||
assert cast("red", Color) is Color.RED
|
|
||||||
assert cast("RED", Color) is Color.RED
|
|
||||||
assert cast("Green", Color) is Color.GREEN
|
|
||||||
|
|
||||||
|
|
||||||
def test_cast_enum_by_name_case_insensitive():
|
|
||||||
assert cast("OK", Status) is Status.OK
|
|
||||||
assert cast("ok", Status) is Status.OK
|
|
||||||
assert cast("ERROR", Status) is Status.ERROR
|
|
||||||
|
|
||||||
|
|
||||||
def test_cast_enum_invalid_raises():
|
|
||||||
with pytest.raises(ValueError) as e:
|
|
||||||
cast("unknown", Color)
|
|
||||||
assert "Cannot cast value 'unknown' to enum 'Color'" in str(e.value)
|
|
||||||
|
|
||||||
|
|
||||||
def test_cast_primitives():
|
|
||||||
assert cast("42", int) == 42
|
|
||||||
assert cast("3.14", float) == 3.14
|
|
||||||
assert cast("abc", str) == "abc"
|
|
||||||
|
|
||||||
|
|
||||||
def test_cast_list_without_subtype_defaults_to_str():
|
|
||||||
assert cast("a,b", list) == ["a", "b"]
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
from cryptography.fernet import Fernet
|
|
||||||
|
|
||||||
from cpl.core.utils.credential_manager import CredentialManager
|
|
||||||
|
|
||||||
|
|
||||||
def test_encrypt_decrypt_roundtrip(tmp_path):
|
|
||||||
secret_path = tmp_path / ".secret"
|
|
||||||
secret_path.write_text(Fernet.generate_key().decode())
|
|
||||||
|
|
||||||
CredentialManager.with_secret(str(secret_path))
|
|
||||||
|
|
||||||
plaintext = "hello-world"
|
|
||||||
token = CredentialManager.encrypt(plaintext)
|
|
||||||
assert isinstance(token, str)
|
|
||||||
assert token != plaintext
|
|
||||||
|
|
||||||
decrypted = CredentialManager.decrypt(token)
|
|
||||||
assert decrypted == plaintext
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
from cpl.core.utils.number import Number
|
|
||||||
|
|
||||||
|
|
||||||
def test_is_number():
|
|
||||||
assert Number.is_number(10) is True
|
|
||||||
assert Number.is_number(3.14) is True
|
|
||||||
assert Number.is_number("42") is True
|
|
||||||
assert Number.is_number("3.14") is True
|
|
||||||
assert Number.is_number("-10") is True
|
|
||||||
assert Number.is_number("+5.5") is True
|
|
||||||
assert Number.is_number("abc") is False
|
|
||||||
assert Number.is_number("") is False
|
|
||||||
assert Number.is_number(None) is False
|
|
||||||
assert Number.is_number(True) is False
|
|
||||||
|
|
||||||
|
|
||||||
def test_to_number():
|
|
||||||
assert Number.to_number("42") == 42
|
|
||||||
assert Number.to_number("3.14") == 3.14
|
|
||||||
assert Number.to_number(10) == 10
|
|
||||||
assert Number.to_number(3.14) == 3.14
|
|
||||||
assert Number.to_number("-7") == -7
|
|
||||||
assert Number.to_number("+8.2") == 8.2
|
|
||||||
|
|
||||||
# Optional: define how errors behave
|
|
||||||
try:
|
|
||||||
Number.to_number("abc")
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
assert False, "Expected ValueError for non-numeric input"
|
|
||||||
|
|
||||||
try:
|
|
||||||
Number.to_number(None)
|
|
||||||
except (TypeError, ValueError):
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
assert False, "Expected exception for None input"
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
import pytest
|
|
||||||
from cpl.core.utils import String
|
|
||||||
|
|
||||||
|
|
||||||
def test_to_camel_case():
|
|
||||||
assert String.to_camel_case("hello world") == "helloWorld"
|
|
||||||
assert String.to_camel_case("hello-world") == "helloWorld"
|
|
||||||
assert String.to_camel_case("hello_world") == "helloWorld"
|
|
||||||
assert String.to_camel_case("HelloWorld") == "helloWorld"
|
|
||||||
assert String.to_camel_case("hello world") == "helloWorld"
|
|
||||||
assert String.to_camel_case("") == ""
|
|
||||||
assert String.to_camel_case(" ") == ""
|
|
||||||
assert String.to_camel_case("123-abc") == "123Abc"
|
|
||||||
|
|
||||||
|
|
||||||
def test_to_pascal_case():
|
|
||||||
assert String.to_pascal_case("hello world") == "HelloWorld"
|
|
||||||
assert String.to_pascal_case("hello-world") == "HelloWorld"
|
|
||||||
assert String.to_pascal_case("hello_world") == "HelloWorld"
|
|
||||||
assert String.to_pascal_case("helloWorld") == "HelloWorld"
|
|
||||||
assert String.to_pascal_case("") == ""
|
|
||||||
assert String.to_pascal_case(" ") == ""
|
|
||||||
assert String.to_pascal_case("123-abc") == "123Abc"
|
|
||||||
|
|
||||||
|
|
||||||
def test_to_snake_case():
|
|
||||||
assert String.to_snake_case("HelloWorld") == "hello_world"
|
|
||||||
assert String.to_snake_case("helloWorld") == "hello_world"
|
|
||||||
assert String.to_snake_case("hello-world") == "hello_world"
|
|
||||||
assert String.to_snake_case("hello_world") == "hello_world"
|
|
||||||
assert String.to_snake_case("hello world") == "hello_world"
|
|
||||||
assert String.to_snake_case("ABC123") == "abc123"
|
|
||||||
|
|
||||||
|
|
||||||
def test_first_to_upper():
|
|
||||||
assert String.first_to_upper("hello") == "Hello"
|
|
||||||
assert String.first_to_upper("Hello") == "Hello"
|
|
||||||
assert String.first_to_upper("") == ""
|
|
||||||
assert String.first_to_upper("a") == "A"
|
|
||||||
assert String.first_to_upper("123abc") == "123abc"
|
|
||||||
|
|
||||||
|
|
||||||
def test_first_to_lower():
|
|
||||||
assert String.first_to_lower("Hello") == "hello"
|
|
||||||
assert String.first_to_lower("hello") == "hello"
|
|
||||||
assert String.first_to_lower("") == ""
|
|
||||||
assert String.first_to_lower("A") == "a"
|
|
||||||
assert String.first_to_lower("123ABC") == "123ABC"
|
|
||||||
|
|
||||||
|
|
||||||
def test_random_length():
|
|
||||||
random_str = String.random(10)
|
|
||||||
assert len(random_str) == 10
|
|
||||||
|
|
||||||
|
|
||||||
def test_random_only_letters():
|
|
||||||
random_str = String.random(20, letters=True, digits=False, special_characters=False)
|
|
||||||
assert all(c.isalpha() for c in random_str)
|
|
||||||
|
|
||||||
|
|
||||||
def test_random_only_digits():
|
|
||||||
random_str = String.random(20, letters=False, digits=True, special_characters=False)
|
|
||||||
assert all(c.isdigit() for c in random_str)
|
|
||||||
|
|
||||||
|
|
||||||
def test_random_letters_and_digits():
|
|
||||||
random_str = String.random(20, letters=True, digits=True, special_characters=False)
|
|
||||||
assert all(c.isalnum() for c in random_str)
|
|
||||||
|
|
||||||
|
|
||||||
def test_random_no_characters():
|
|
||||||
with pytest.raises(Exception):
|
|
||||||
String.random(10, letters=False, digits=False, special_characters=False)
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "test",
|
|
||||||
"version": "0.1.0",
|
|
||||||
"type": "unittest",
|
|
||||||
"license": "",
|
|
||||||
"author": "",
|
|
||||||
"description": "",
|
|
||||||
"homepage": "",
|
|
||||||
"keywords": [],
|
|
||||||
"dependencies": {
|
|
||||||
"cpl-core": "~2024.7.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"cpl-cli": ">2024.7.0",
|
|
||||||
"pytest": "~8.4.2",
|
|
||||||
"pytest-mock": "~3.15.1",
|
|
||||||
"pytest-asyncio": "~1.2.0"
|
|
||||||
},
|
|
||||||
"references": [],
|
|
||||||
"main": null,
|
|
||||||
"directory": "./",
|
|
||||||
"build": {
|
|
||||||
"include": [],
|
|
||||||
"exclude": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
23
unittests/unittests/application.py
Normal file
23
unittests/unittests/application.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import unittest
|
||||||
|
|
||||||
|
from cpl.application import ApplicationABC
|
||||||
|
from cpl.core.configuration import ConfigurationABC
|
||||||
|
from cpl.dependency import ServiceProvider
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
class Application(ApplicationABC):
|
||||||
|
def __init__(self, config: ConfigurationABC, services: ServiceProvider):
|
||||||
|
ApplicationABC.__init__(self, config, services)
|
||||||
|
|
||||||
|
def configure(self): ...
|
||||||
|
|
||||||
|
def main(self):
|
||||||
|
runner = unittest.TextTestRunner()
|
||||||
|
runner.run(CoreTestSuite())
|
||||||
|
runner.run(CLITestSuite())
|
||||||
|
runner.run(QueryTestSuite())
|
||||||
|
runner.run(TranslationTestSuite())
|
||||||
11
unittests/unittests/main.py
Normal file
11
unittests/unittests/main.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
from cpl.application import ApplicationBuilder
|
||||||
|
from unittests.application import Application
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
app_builder = ApplicationBuilder(Application)
|
||||||
|
app_builder.build().run()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
42
unittests/unittests/unittests.json
Normal file
42
unittests/unittests/unittests.json
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"Project": {
|
||||||
|
"Name": "unittests",
|
||||||
|
"Version": {
|
||||||
|
"Major": "2024",
|
||||||
|
"Minor": "7",
|
||||||
|
"Micro": "0"
|
||||||
|
},
|
||||||
|
"Author": "",
|
||||||
|
"AuthorEmail": "",
|
||||||
|
"Description": "",
|
||||||
|
"LongDescription": "",
|
||||||
|
"URL": "",
|
||||||
|
"CopyrightDate": "",
|
||||||
|
"CopyrightName": "",
|
||||||
|
"LicenseName": "",
|
||||||
|
"LicenseDescription": "",
|
||||||
|
"Dependencies": [
|
||||||
|
"cpl-core>=2024.6.2024.07.0"
|
||||||
|
],
|
||||||
|
"PythonVersion": ">=3.10.4",
|
||||||
|
"PythonPath": {},
|
||||||
|
"Classifiers": [],
|
||||||
|
"DevDependencies": []
|
||||||
|
},
|
||||||
|
"Build": {
|
||||||
|
"ProjectType": "unittest",
|
||||||
|
"SourcePath": "",
|
||||||
|
"OutputPath": "../../dist",
|
||||||
|
"Main": "unittest.main",
|
||||||
|
"EntryPoint": "unittest",
|
||||||
|
"IncludePackageData": false,
|
||||||
|
"Included": [],
|
||||||
|
"Excluded": [
|
||||||
|
"*/__pycache__",
|
||||||
|
"*/logs",
|
||||||
|
"*/tests"
|
||||||
|
],
|
||||||
|
"PackageData": {},
|
||||||
|
"ProjectReferences": []
|
||||||
|
}
|
||||||
|
}
|
||||||
0
unittests/unittests_cli/abc/__init__.py
Normal file
0
unittests/unittests_cli/abc/__init__.py
Normal file
40
unittests/unittests_cli/abc/command_test_case.py
Normal file
40
unittests/unittests_cli/abc/command_test_case.py
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import traceback
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
try:
|
||||||
|
if os.path.exists(PLAYGROUND_PATH):
|
||||||
|
shutil.rmtree(os.path.abspath(os.path.join(PLAYGROUND_PATH)))
|
||||||
|
|
||||||
|
if not os.path.exists(PLAYGROUND_PATH):
|
||||||
|
os.makedirs(PLAYGROUND_PATH)
|
||||||
|
os.chdir(PLAYGROUND_PATH)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Setup of {__name__} failed: {traceback.format_exc()}")
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
os.chdir(PLAYGROUND_PATH)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def tearDownClass(cls):
|
||||||
|
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:
|
||||||
|
print(f"Cleanup of {__name__} failed: {traceback.format_exc()}")
|
||||||
42
unittests/unittests_cli/add_test_case.py
Normal file
42
unittests/unittests_cli/add_test_case.py
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
from cpl.core.utils import String
|
||||||
|
from unittests_cli.abc.command_test_case import CommandTestCase
|
||||||
|
from unittests_cli.constants import PLAYGROUND_PATH
|
||||||
|
from unittests_shared.cli_commands import CLICommands
|
||||||
|
|
||||||
|
|
||||||
|
class AddTestCase(CommandTestCase):
|
||||||
|
def __init__(self, method_name: str):
|
||||||
|
CommandTestCase.__init__(self, method_name)
|
||||||
|
self._source = "add-test-project"
|
||||||
|
self._target = "add-test-library"
|
||||||
|
self._project_file = f"src/{String.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(PLAYGROUND_PATH)
|
||||||
|
# create projects
|
||||||
|
CLICommands.new("console", self._source, "--ab", "--s")
|
||||||
|
os.chdir(os.path.join(os.getcwd(), self._source))
|
||||||
|
CLICommands.new("library", self._target, "--ab", "--s")
|
||||||
|
|
||||||
|
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.to_snake_case(self._target)}/{self._target}.json",
|
||||||
|
settings["BuildSettings"]["ProjectReferences"],
|
||||||
|
)
|
||||||
86
unittests/unittests_cli/build_test_case.py
Normal file
86
unittests/unittests_cli/build_test_case.py
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
import filecmp
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
from cpl.core.utils import String
|
||||||
|
from unittests_cli.abc.command_test_case import CommandTestCase
|
||||||
|
from unittests_cli.constants import PLAYGROUND_PATH
|
||||||
|
from unittests_shared.cli_commands import CLICommands
|
||||||
|
|
||||||
|
|
||||||
|
class BuildTestCase(CommandTestCase):
|
||||||
|
def __init__(self, method_name: str):
|
||||||
|
CommandTestCase.__init__(self, method_name)
|
||||||
|
self._source = "build-test-source"
|
||||||
|
self._project_file = f"src/{String.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):
|
||||||
|
if not os.path.exists(PLAYGROUND_PATH):
|
||||||
|
os.makedirs(PLAYGROUND_PATH)
|
||||||
|
|
||||||
|
os.chdir(PLAYGROUND_PATH)
|
||||||
|
# create projects
|
||||||
|
CLICommands.new("console", self._source, "--ab", "--s")
|
||||||
|
os.chdir(os.path.join(os.getcwd(), 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.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.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.to_snake_case(self._source)}", full_dist_path)
|
||||||
|
)
|
||||||
82
unittests/unittests_cli/cli_test_suite.py
Normal file
82
unittests/unittests_cli/cli_test_suite.py
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
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,
|
||||||
|
NewTestCase,
|
||||||
|
GenerateTestCase,
|
||||||
|
# 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()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
runner = unittest.TextTestRunner()
|
||||||
|
runner.run(CLITestSuite())
|
||||||
9
unittests/unittests_cli/constants.py
Normal file
9
unittests/unittests_cli/constants.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
base = ""
|
||||||
|
if not os.getcwd().endswith("unittests"):
|
||||||
|
base = "../"
|
||||||
|
|
||||||
|
PLAYGROUND_PATH = os.path.abspath(os.path.join(os.getcwd(), f"{base}test_cli_playground"))
|
||||||
|
TRANSLATION_PATH = os.path.abspath(os.path.join(os.getcwd(), f"{base}unittests_translation"))
|
||||||
|
CLI_PATH = os.path.abspath(os.path.join(os.getcwd(), f"{base}../src/cpl_cli/main.py"))
|
||||||
7
unittests/unittests_cli/custom_test_case.py
Normal file
7
unittests/unittests_cli/custom_test_case.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
from unittests_cli.abc.command_test_case import CommandTestCase
|
||||||
|
|
||||||
|
|
||||||
|
class CustomTestCase(CommandTestCase):
|
||||||
|
def setUp(self): ...
|
||||||
|
|
||||||
|
def test_equal(self): ...
|
||||||
100
unittests/unittests_cli/generate_test_case.py
Normal file
100
unittests/unittests_cli/generate_test_case.py
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
import os.path
|
||||||
|
|
||||||
|
from cpl.core.utils import String
|
||||||
|
from unittests_cli.abc.command_test_case import CommandTestCase
|
||||||
|
from unittests_cli.constants import PLAYGROUND_PATH
|
||||||
|
from unittests_shared.cli_commands import CLICommands
|
||||||
|
|
||||||
|
|
||||||
|
class GenerateTestCase(CommandTestCase):
|
||||||
|
_project = "test-console"
|
||||||
|
_t_path = "test"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
CommandTestCase.setUpClass()
|
||||||
|
CLICommands.new("console", cls._project, "--ab", "--s", "--venv")
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
os.chdir(PLAYGROUND_PATH)
|
||||||
|
|
||||||
|
def _test_file(self, schematic: str, suffix: str, path=None):
|
||||||
|
file = f'GeneratedFile{"OnReady" if schematic == "event" else ""}'
|
||||||
|
expected_path = f'generated_file{"_on_ready" if schematic == "event" else ""}{suffix}.py'
|
||||||
|
|
||||||
|
if path is not None:
|
||||||
|
file = f"{path}/{file}"
|
||||||
|
expected_path = f"{path}/{expected_path}"
|
||||||
|
|
||||||
|
CLICommands.generate(schematic, file)
|
||||||
|
file_path = os.path.abspath(os.path.join(PLAYGROUND_PATH, expected_path))
|
||||||
|
file_exists = os.path.exists(file_path)
|
||||||
|
self.assertTrue(file_exists)
|
||||||
|
|
||||||
|
def _test_file_with_project(self, schematic: str, suffix: str, path=None, enter=True):
|
||||||
|
file = f'GeneratedFile{"OnReady" if schematic == "event" else ""}'
|
||||||
|
excepted_path = f'generated_file{"_on_ready" if schematic == "event" else ""}{suffix}.py'
|
||||||
|
if path is not None:
|
||||||
|
excepted_path = f'{self._project}/src/{String.to_snake_case(self._project)}/{path}/generated_file_in_project{"_on_ready" if schematic == "event" else ""}{suffix}.py'
|
||||||
|
if enter:
|
||||||
|
os.chdir(path)
|
||||||
|
excepted_path = f'{path}/src/{String.to_snake_case(self._project)}/generated_file_in_project{"_on_ready" if schematic == "event" else ""}{suffix}.py'
|
||||||
|
|
||||||
|
file = f'{path}/GeneratedFileInProject{"OnReady" if schematic == "event" else ""}'
|
||||||
|
|
||||||
|
CLICommands.generate(schematic, file)
|
||||||
|
file_path = os.path.abspath(os.path.join(PLAYGROUND_PATH, excepted_path))
|
||||||
|
self.assertTrue(os.path.exists(file_path))
|
||||||
|
|
||||||
|
def test_abc(self):
|
||||||
|
self._test_file("abc", "_abc")
|
||||||
|
self._test_file("abc", "_abc", path=self._t_path)
|
||||||
|
self._test_file("abc", "_abc", path=f"{self._t_path}/{self._t_path}")
|
||||||
|
self._test_file_with_project("abc", "_abc", path=self._project)
|
||||||
|
os.chdir(f"src/{String.to_snake_case(self._project)}")
|
||||||
|
self._test_file_with_project("abc", "_abc", path="test", enter=False)
|
||||||
|
|
||||||
|
def test_class(self):
|
||||||
|
self._test_file("class", "")
|
||||||
|
self._test_file("class", "", path=self._t_path)
|
||||||
|
self._test_file_with_project("class", "", path=self._project)
|
||||||
|
|
||||||
|
def test_enum(self):
|
||||||
|
self._test_file("enum", "_enum")
|
||||||
|
self._test_file("enum", "_enum", path=self._t_path)
|
||||||
|
self._test_file_with_project("enum", "_enum", path=self._project)
|
||||||
|
os.chdir(f"src/{String.to_snake_case(self._project)}")
|
||||||
|
self._test_file_with_project("enum", "_enum", path="test", enter=False)
|
||||||
|
|
||||||
|
def test_pipe(self):
|
||||||
|
self._test_file("pipe", "_pipe")
|
||||||
|
self._test_file("pipe", "_pipe", path=self._t_path)
|
||||||
|
self._test_file_with_project("pipe", "_pipe", path=self._project)
|
||||||
|
|
||||||
|
def test_service(self):
|
||||||
|
self._test_file("service", "_service")
|
||||||
|
self._test_file_with_project("service", "_service", path=self._project)
|
||||||
|
|
||||||
|
def test_settings(self):
|
||||||
|
self._test_file("settings", "_settings")
|
||||||
|
self._test_file_with_project("settings", "_settings", path=self._project)
|
||||||
|
|
||||||
|
def test_test_case(self):
|
||||||
|
self._test_file("test-case", "_test_case")
|
||||||
|
self._test_file_with_project("test-case", "_test_case", path=self._project)
|
||||||
|
|
||||||
|
def test_thread(self):
|
||||||
|
self._test_file("thread", "_thread")
|
||||||
|
self._test_file_with_project("thread", "_thread", path=self._project)
|
||||||
|
|
||||||
|
def test_validator(self):
|
||||||
|
self._test_file("validator", "_validator")
|
||||||
|
self._test_file_with_project("validator", "_validator", path=self._project)
|
||||||
|
|
||||||
|
def test_discord_command(self):
|
||||||
|
self._test_file("command", "_command")
|
||||||
|
self._test_file_with_project("command", "_command", path=self._project)
|
||||||
|
|
||||||
|
def test_discord_event(self):
|
||||||
|
self._test_file("event", "_event")
|
||||||
|
self._test_file_with_project("event", "_event", path=self._project)
|
||||||
108
unittests/unittests_cli/install_test_case.py
Normal file
108
unittests/unittests_cli/install_test_case.py
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from cpl.core.utils import String
|
||||||
|
from unittests_cli.abc.command_test_case import CommandTestCase
|
||||||
|
from unittests_cli.constants import PLAYGROUND_PATH
|
||||||
|
from unittests_shared.cli_commands import CLICommands
|
||||||
|
|
||||||
|
|
||||||
|
class InstallTestCase(CommandTestCase):
|
||||||
|
def __init__(self, method_name: str):
|
||||||
|
CommandTestCase.__init__(self, method_name)
|
||||||
|
self._source = "install-test-source"
|
||||||
|
self._project_file = f"src/{String.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):
|
||||||
|
if not os.path.exists(PLAYGROUND_PATH):
|
||||||
|
os.makedirs(PLAYGROUND_PATH)
|
||||||
|
|
||||||
|
os.chdir(PLAYGROUND_PATH)
|
||||||
|
# create projects
|
||||||
|
CLICommands.new("console", self._source, "--ab", "--s", "--venv")
|
||||||
|
os.chdir(os.path.join(os.getcwd(), self._source))
|
||||||
|
|
||||||
|
def _get_installed_packages(self) -> dict:
|
||||||
|
reqs = subprocess.check_output([os.path.join(os.getcwd(), "venv/bin/python"), "-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()
|
||||||
|
|
||||||
|
with self.subTest(msg="Project deps"):
|
||||||
|
self.assertNotEqual(settings, {})
|
||||||
|
self.assertIn("ProjectSettings", settings)
|
||||||
|
self.assertIn("Dependencies", settings["ProjectSettings"])
|
||||||
|
self.assertIn(package, settings["ProjectSettings"]["Dependencies"])
|
||||||
|
|
||||||
|
with self.subTest(msg="PIP"):
|
||||||
|
packages = self._get_installed_packages()
|
||||||
|
self.assertIn(package_name, packages)
|
||||||
|
self.assertEqual(version, packages[package_name])
|
||||||
|
|
||||||
|
def test_dev_install_package(self):
|
||||||
|
version = "1.7.3"
|
||||||
|
package_name = "discord.py"
|
||||||
|
package = f"{package_name}=={version}"
|
||||||
|
CLICommands.install(package, is_dev=True)
|
||||||
|
settings = self._get_project_settings()
|
||||||
|
|
||||||
|
with self.subTest(msg="Project deps"):
|
||||||
|
self.assertNotEqual(settings, {})
|
||||||
|
self.assertIn("ProjectSettings", settings)
|
||||||
|
self.assertIn("Dependencies", settings["ProjectSettings"])
|
||||||
|
self.assertIn("DevDependencies", settings["ProjectSettings"])
|
||||||
|
self.assertNotIn(package, settings["ProjectSettings"]["Dependencies"])
|
||||||
|
self.assertIn(package, settings["ProjectSettings"]["DevDependencies"])
|
||||||
|
|
||||||
|
with self.subTest(msg="PIP"):
|
||||||
|
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.assertIn("DevDependencies", settings["ProjectSettings"])
|
||||||
|
self.assertNotIn(package, settings["ProjectSettings"]["Dependencies"])
|
||||||
|
self.assertIn("DevDependencies", settings["ProjectSettings"])
|
||||||
|
self.assertNotIn(package, settings["ProjectSettings"]["Dependencies"])
|
||||||
|
settings["ProjectSettings"]["Dependencies"].append(package)
|
||||||
|
settings["ProjectSettings"]["DevDependencies"].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("DevDependencies", new_settings["ProjectSettings"])
|
||||||
|
self.assertIn(package, new_settings["ProjectSettings"]["Dependencies"])
|
||||||
|
self.assertIn(package, new_settings["ProjectSettings"]["DevDependencies"])
|
||||||
|
packages = self._get_installed_packages()
|
||||||
|
self.assertIn(package_name, packages)
|
||||||
|
self.assertEqual(version, packages[package_name])
|
||||||
191
unittests/unittests_cli/new_test_case.py
Normal file
191
unittests/unittests_cli/new_test_case.py
Normal file
@@ -0,0 +1,191 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from cpl.core.utils import String
|
||||||
|
from unittests_cli.abc.command_test_case import CommandTestCase
|
||||||
|
from unittests_cli.constants import PLAYGROUND_PATH
|
||||||
|
from unittests_shared.cli_commands import CLICommands
|
||||||
|
|
||||||
|
|
||||||
|
class NewTestCase(CommandTestCase):
|
||||||
|
def __init__(self, method_name: str):
|
||||||
|
CommandTestCase.__init__(self, method_name)
|
||||||
|
|
||||||
|
def _test_project(self, project_type: str, name: str, *args, test_venv=False, without_ws=False):
|
||||||
|
CLICommands.new(project_type, name, *args, output=False)
|
||||||
|
workspace_path = os.path.abspath(os.path.join(PLAYGROUND_PATH, name))
|
||||||
|
self.assertTrue(os.path.exists(workspace_path))
|
||||||
|
if test_venv:
|
||||||
|
with self.subTest(msg="Venv exists"):
|
||||||
|
self.assertTrue(os.path.exists(os.path.join(workspace_path, "venv")))
|
||||||
|
self.assertTrue(os.path.exists(os.path.join(workspace_path, "venv/bin")))
|
||||||
|
self.assertTrue(os.path.exists(os.path.join(workspace_path, "venv/bin/python")))
|
||||||
|
self.assertTrue(os.path.islink(os.path.join(workspace_path, "venv/bin/python")))
|
||||||
|
|
||||||
|
base = "src"
|
||||||
|
if "--base" in args and "/" in name:
|
||||||
|
base = name.split("/")[0]
|
||||||
|
name = name.replace(f'{name.split("/")[0]}/', "")
|
||||||
|
|
||||||
|
project_path = os.path.abspath(os.path.join(PLAYGROUND_PATH, name, base, String.to_snake_case(name)))
|
||||||
|
if without_ws:
|
||||||
|
project_path = os.path.abspath(
|
||||||
|
os.path.join(PLAYGROUND_PATH, base, name, "src/", String.to_snake_case(name))
|
||||||
|
)
|
||||||
|
|
||||||
|
with self.subTest(msg="Project json exists"):
|
||||||
|
self.assertTrue(os.path.exists(project_path))
|
||||||
|
self.assertTrue(os.path.exists(os.path.join(project_path, f"{name}.json")))
|
||||||
|
|
||||||
|
if project_type == "library":
|
||||||
|
with self.subTest(msg="Library class1 exists"):
|
||||||
|
self.assertTrue(os.path.exists(os.path.join(project_path, f"class1.py")))
|
||||||
|
return
|
||||||
|
|
||||||
|
with self.subTest(msg="Project main.py exists"):
|
||||||
|
self.assertTrue(os.path.exists(os.path.join(project_path, f"main.py")))
|
||||||
|
|
||||||
|
with self.subTest(msg="Application base"):
|
||||||
|
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
|
||||||
|
with self.subTest(msg="Startup"):
|
||||||
|
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")))
|
||||||
|
|
||||||
|
with self.subTest(msg="Unittest"):
|
||||||
|
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")))
|
||||||
|
|
||||||
|
with self.subTest(msg="Discord"):
|
||||||
|
if project_type == "discord-bot":
|
||||||
|
self.assertTrue(os.path.isfile(os.path.join(project_path, f"events/__init__.py")))
|
||||||
|
self.assertTrue(os.path.isfile(os.path.join(project_path, f"events/on_ready_event.py")))
|
||||||
|
self.assertTrue(os.path.isfile(os.path.join(project_path, f"commands/__init__.py")))
|
||||||
|
self.assertTrue(os.path.isfile(os.path.join(project_path, f"commands/ping_command.py")))
|
||||||
|
else:
|
||||||
|
self.assertFalse(os.path.isfile(os.path.join(project_path, f"events/on_ready_event.py")))
|
||||||
|
self.assertFalse(os.path.isfile(os.path.join(project_path, f"commands/ping_command.py")))
|
||||||
|
|
||||||
|
def _test_sub_project(self, project_type: str, name: str, workspace_name: str, *args, test_venv=False):
|
||||||
|
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))
|
||||||
|
if test_venv:
|
||||||
|
self.assertTrue(os.path.exists(os.path.join(workspace_path, "venv")))
|
||||||
|
self.assertTrue(os.path.exists(os.path.join(workspace_path, "venv/bin")))
|
||||||
|
self.assertTrue(os.path.exists(os.path.join(workspace_path, "venv/bin/python")))
|
||||||
|
self.assertTrue(os.path.islink(os.path.join(workspace_path, "venv/bin/python")))
|
||||||
|
|
||||||
|
base = "src"
|
||||||
|
if "--base" in args and "/" in name:
|
||||||
|
base = name.split("/")[0]
|
||||||
|
name = name.replace(f'{name.split("/")[0]}/', "")
|
||||||
|
|
||||||
|
project_path = os.path.abspath(
|
||||||
|
os.path.join(PLAYGROUND_PATH, workspace_name, base, String.to_snake_case(name))
|
||||||
|
)
|
||||||
|
self.assertTrue(os.path.exists(project_path))
|
||||||
|
self.assertTrue(os.path.join(project_path, f"{name}.json"))
|
||||||
|
|
||||||
|
if project_type == "discord-bot":
|
||||||
|
self.assertTrue(os.path.isfile(os.path.join(project_path, f"events/__init__.py")))
|
||||||
|
self.assertTrue(os.path.isfile(os.path.join(project_path, f"events/on_ready_event.py")))
|
||||||
|
self.assertTrue(os.path.isfile(os.path.join(project_path, f"commands/__init__.py")))
|
||||||
|
self.assertTrue(os.path.isfile(os.path.join(project_path, f"commands/ping_command.py")))
|
||||||
|
else:
|
||||||
|
self.assertFalse(os.path.isfile(os.path.join(project_path, f"events/on_ready_event.py")))
|
||||||
|
self.assertFalse(os.path.isfile(os.path.join(project_path, f"commands/ping_command.py")))
|
||||||
|
|
||||||
|
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.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.to_snake_case(name)}.main")
|
||||||
|
self.assertEqual(build_settings["EntryPoint"], name)
|
||||||
|
|
||||||
|
def test_console(self):
|
||||||
|
self._test_project("console", "test-console", "--ab", "--s", "--venv", test_venv=True)
|
||||||
|
|
||||||
|
def test_console_with_other_base(self):
|
||||||
|
self._test_project(
|
||||||
|
"console", "tools/test-console", "--ab", "--s", "--venv", "--base", test_venv=True, without_ws=True
|
||||||
|
)
|
||||||
|
|
||||||
|
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_console_sub(self):
|
||||||
|
self._test_sub_project(
|
||||||
|
"console", "test-sub-console", "test-console", "--ab", "--s", "--sp", "--venv", test_venv=True
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_console_sub_with_other_base(self):
|
||||||
|
self._test_sub_project(
|
||||||
|
"console",
|
||||||
|
"tools/test-sub-console",
|
||||||
|
"test-console",
|
||||||
|
"--ab",
|
||||||
|
"--s",
|
||||||
|
"--sp",
|
||||||
|
"--venv",
|
||||||
|
"--base",
|
||||||
|
test_venv=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_discord_bot(self):
|
||||||
|
self._test_project("discord-bot", "test-bot", "--ab", "--s", "--venv", test_venv=True)
|
||||||
|
|
||||||
|
def test_discord_bot_sub(self):
|
||||||
|
self._test_sub_project("discord-bot", "test-bot-sub", "test-console", "--ab", "--s", "--venv", test_venv=True)
|
||||||
|
|
||||||
|
def test_library(self):
|
||||||
|
self._test_project("library", "test-library", "--ab", "--s", "--sp")
|
||||||
|
|
||||||
|
def test_library_sub(self):
|
||||||
|
self._test_sub_project("library", "test-sub-library", "test-console", "--ab", "--s", "--sp")
|
||||||
|
|
||||||
|
def test_library_sub_directory(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_unittest_sub(self):
|
||||||
|
self._test_sub_project("unittest", "test-unittest", "test-console", "--ab", "--s", "--sp")
|
||||||
85
unittests/unittests_cli/publish_test_case.py
Normal file
85
unittests/unittests_cli/publish_test_case.py
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
import filecmp
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
from cpl.core.utils import String
|
||||||
|
from unittests_cli.abc.command_test_case import CommandTestCase
|
||||||
|
from unittests_cli.constants import PLAYGROUND_PATH
|
||||||
|
from unittests_shared.cli_commands import CLICommands
|
||||||
|
|
||||||
|
|
||||||
|
class PublishTestCase(CommandTestCase):
|
||||||
|
def __init__(self, method_name: str):
|
||||||
|
CommandTestCase.__init__(self, method_name)
|
||||||
|
self._source = "publish-test-source"
|
||||||
|
self._project_file = f"src/{String.to_snake_case(self._source)}/{self._source}.json"
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
if not os.path.exists(PLAYGROUND_PATH):
|
||||||
|
os.makedirs(PLAYGROUND_PATH)
|
||||||
|
|
||||||
|
os.chdir(PLAYGROUND_PATH)
|
||||||
|
# create projects
|
||||||
|
CLICommands.new("console", self._source, "--ab", "--s")
|
||||||
|
os.chdir(os.path.join(os.getcwd(), 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.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.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.to_snake_case(self._source)}", full_dist_path)
|
||||||
|
)
|
||||||
|
|
||||||
|
shutil.copyfile(os.path.join(os.getcwd(), self._project_file), f"{full_dist_path}/{self._source}.json")
|
||||||
|
shutil.copyfile(
|
||||||
|
os.path.join(os.getcwd(), os.path.dirname(self._project_file), "appsettings.json"),
|
||||||
|
f"{full_dist_path}/appsettings.json",
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertTrue(
|
||||||
|
self._are_dir_trees_equal(f"./src/{String.to_snake_case(self._source)}", full_dist_path)
|
||||||
|
)
|
||||||
50
unittests/unittests_cli/remove_test_case.py
Normal file
50
unittests/unittests_cli/remove_test_case.py
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from cpl.core.utils import String
|
||||||
|
from unittests_cli.abc.command_test_case import CommandTestCase
|
||||||
|
from unittests_cli.constants import PLAYGROUND_PATH
|
||||||
|
from unittests_shared.cli_commands import CLICommands
|
||||||
|
|
||||||
|
|
||||||
|
class RemoveTestCase(CommandTestCase):
|
||||||
|
def __init__(self, method_name: str):
|
||||||
|
CommandTestCase.__init__(self, method_name)
|
||||||
|
self._source = "add-test-project"
|
||||||
|
self._target = "add-test-library"
|
||||||
|
self._project_file = f"src/{String.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):
|
||||||
|
if not os.path.exists(PLAYGROUND_PATH):
|
||||||
|
os.makedirs(PLAYGROUND_PATH)
|
||||||
|
|
||||||
|
os.chdir(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.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.to_snake_case(self._target)}/{self._target}.json",
|
||||||
|
settings["BuildSettings"]["ProjectReferences"],
|
||||||
|
)
|
||||||
117
unittests/unittests_cli/run_test_case.py
Normal file
117
unittests/unittests_cli/run_test_case.py
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from cpl.core.utils import String
|
||||||
|
from unittests_cli.abc.command_test_case import CommandTestCase
|
||||||
|
from unittests_cli.constants import PLAYGROUND_PATH
|
||||||
|
from unittests_shared.cli_commands import CLICommands
|
||||||
|
|
||||||
|
|
||||||
|
class RunTestCase(CommandTestCase):
|
||||||
|
def __init__(self, method_name: str):
|
||||||
|
CommandTestCase.__init__(self, method_name)
|
||||||
|
self._source = "run-test"
|
||||||
|
self._project_file = f"src/{String.to_snake_case(self._source)}/{self._source}.json"
|
||||||
|
self._application = f"src/{String.to_snake_case(self._source)}/application.py"
|
||||||
|
self._test_code = f"""
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
settings = dict()
|
||||||
|
with open('appsettings.json', 'r', encoding='utf-8') as cfg:
|
||||||
|
# load json
|
||||||
|
settings = json.load(cfg)
|
||||||
|
cfg.close()
|
||||||
|
|
||||||
|
settings['RunTest']['WasStarted'] = 'True'
|
||||||
|
settings['RunTest']['Path'] = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
|
||||||
|
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, is_dev=False):
|
||||||
|
appsettings = f"dist/{self._source}/build/{String.to_snake_case(self._source)}/appsettings.json"
|
||||||
|
if is_dev:
|
||||||
|
appsettings = f"src/{String.to_snake_case(self._source)}/appsettings.json"
|
||||||
|
|
||||||
|
with open(os.path.join(os.getcwd(), 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(), f"src/{String.to_snake_case(self._source)}/appsettings.json"),
|
||||||
|
"w",
|
||||||
|
encoding="utf-8",
|
||||||
|
) as project_file:
|
||||||
|
project_file.write(json.dumps(settings, indent=2))
|
||||||
|
project_file.close()
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
os.chdir(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 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"])
|
||||||
|
self.assertNotEqual(
|
||||||
|
os.path.join(os.getcwd(), f"src/{String.to_snake_case(self._source)}"), settings["RunTest"]["Path"]
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
os.path.join(os.getcwd(), f"dist/{self._source}/build/{String.to_snake_case(self._source)}"),
|
||||||
|
settings["RunTest"]["Path"],
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_run_by_project(self):
|
||||||
|
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"])
|
||||||
|
self.assertNotEqual(
|
||||||
|
os.path.join(os.getcwd(), f"src/{String.to_snake_case(self._source)}"), settings["RunTest"]["Path"]
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
os.path.join(os.getcwd(), f"dist/{self._source}/build/{String.to_snake_case(self._source)}"),
|
||||||
|
settings["RunTest"]["Path"],
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_run_dev(self):
|
||||||
|
CLICommands.run(is_dev=True)
|
||||||
|
settings = self._get_appsettings(is_dev=True)
|
||||||
|
self.assertNotEqual(settings, {})
|
||||||
|
self.assertIn("RunTest", settings)
|
||||||
|
self.assertIn("WasStarted", settings["RunTest"])
|
||||||
|
self.assertEqual("True", settings["RunTest"]["WasStarted"])
|
||||||
|
self.assertEqual(
|
||||||
|
os.path.join(os.getcwd(), f"src/{String.to_snake_case(self._source)}"), settings["RunTest"]["Path"]
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_run_dev_by_project(self):
|
||||||
|
CLICommands.run(self._source, is_dev=True)
|
||||||
|
settings = self._get_appsettings(is_dev=True)
|
||||||
|
self.assertNotEqual(settings, {})
|
||||||
|
self.assertIn("RunTest", settings)
|
||||||
|
self.assertIn("WasStarted", settings["RunTest"])
|
||||||
|
self.assertEqual("True", settings["RunTest"]["WasStarted"])
|
||||||
|
self.assertEqual(
|
||||||
|
os.path.join(os.getcwd(), f"src/{String.to_snake_case(self._source)}"), settings["RunTest"]["Path"]
|
||||||
|
)
|
||||||
122
unittests/unittests_cli/start_test_case.py
Normal file
122
unittests/unittests_cli/start_test_case.py
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import time
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from cpl.core.utils import String
|
||||||
|
from unittests_cli.abc.command_test_case import CommandTestCase
|
||||||
|
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(CommandTestCase):
|
||||||
|
def __init__(self, method_name: str):
|
||||||
|
CommandTestCase.__init__(self, method_name)
|
||||||
|
self._source = "start-test"
|
||||||
|
self._project_file = f"src/{String.to_snake_case(self._source)}/{self._source}.json"
|
||||||
|
self._appsettings = f"src/{String.to_snake_case(self._source)}/appsettings.json"
|
||||||
|
self._application = f"src/{String.to_snake_case(self._source)}/application.py"
|
||||||
|
self._test_code = f"""
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
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'
|
||||||
|
settings['RunTest']['Path'] = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
|
||||||
|
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, is_dev=False):
|
||||||
|
appsettings = f"dist/{self._source}/build/{String.to_snake_case(self._source)}/appsettings.json"
|
||||||
|
if is_dev:
|
||||||
|
appsettings = f"src/{String.to_snake_case(self._source)}/appsettings.json"
|
||||||
|
|
||||||
|
with open(os.path.join(os.getcwd(), 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(), f"src/{String.to_snake_case(self._source)}/appsettings.json"),
|
||||||
|
"w",
|
||||||
|
encoding="utf-8",
|
||||||
|
) as project_file:
|
||||||
|
project_file.write(json.dumps(settings, indent=2))
|
||||||
|
project_file.close()
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
if not os.path.exists(PLAYGROUND_PATH):
|
||||||
|
os.makedirs(PLAYGROUND_PATH)
|
||||||
|
|
||||||
|
os.chdir(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 test_start(self):
|
||||||
|
thread = StartTestThread()
|
||||||
|
thread.start()
|
||||||
|
time.sleep(5)
|
||||||
|
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(5)
|
||||||
|
|
||||||
|
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"])
|
||||||
|
|
||||||
|
def test_start_dev(self):
|
||||||
|
thread = StartTestThread(is_dev=True)
|
||||||
|
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(is_dev=True)
|
||||||
|
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"])
|
||||||
0
unittests/unittests_cli/threads/__init__.py
Normal file
0
unittests/unittests_cli/threads/__init__.py
Normal file
12
unittests/unittests_cli/threads/start_test_thread.py
Normal file
12
unittests/unittests_cli/threads/start_test_thread.py
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import threading
|
||||||
|
|
||||||
|
from unittests_shared.cli_commands import CLICommands
|
||||||
|
|
||||||
|
|
||||||
|
class StartTestThread(threading.Thread):
|
||||||
|
def __init__(self, is_dev=False):
|
||||||
|
threading.Thread.__init__(self, daemon=True)
|
||||||
|
self._is_dev = is_dev
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
CLICommands.start(is_dev=self._is_dev, output=True)
|
||||||
67
unittests/unittests_cli/uninstall_test_case.py
Normal file
67
unittests/unittests_cli/uninstall_test_case.py
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from cpl.core.utils import String
|
||||||
|
from unittests_cli.abc.command_test_case import CommandTestCase
|
||||||
|
from unittests_cli.constants import PLAYGROUND_PATH
|
||||||
|
from unittests_shared.cli_commands import CLICommands
|
||||||
|
|
||||||
|
|
||||||
|
class UninstallTestCase(CommandTestCase):
|
||||||
|
def __init__(self, method_name: str):
|
||||||
|
CommandTestCase.__init__(self, method_name)
|
||||||
|
self._source = "uninstall-test-source"
|
||||||
|
self._project_file = f"src/{String.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):
|
||||||
|
if not os.path.exists(PLAYGROUND_PATH):
|
||||||
|
os.makedirs(PLAYGROUND_PATH)
|
||||||
|
|
||||||
|
os.chdir(PLAYGROUND_PATH)
|
||||||
|
# create projects
|
||||||
|
CLICommands.new("console", self._source, "--ab", "--s")
|
||||||
|
os.chdir(os.path.join(os.getcwd(), 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.install(self._package)
|
||||||
|
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"])
|
||||||
|
self.assertNotIn(self._package, settings["ProjectSettings"]["DevDependencies"])
|
||||||
|
packages = self._get_installed_packages()
|
||||||
|
self.assertNotIn(self._package_name, packages)
|
||||||
|
|
||||||
|
def test_dev_uninstall(self):
|
||||||
|
CLICommands.install(self._package, is_dev=True)
|
||||||
|
CLICommands.uninstall(self._package, is_dev=True)
|
||||||
|
settings = self._get_project_settings()
|
||||||
|
self.assertNotEqual(settings, {})
|
||||||
|
self.assertIn("ProjectSettings", settings)
|
||||||
|
self.assertIn("Dependencies", settings["ProjectSettings"])
|
||||||
|
self.assertIn("DevDependencies", settings["ProjectSettings"])
|
||||||
|
self.assertNotIn(self._package, settings["ProjectSettings"]["Dependencies"])
|
||||||
|
self.assertNotIn(self._package, settings["ProjectSettings"]["DevDependencies"])
|
||||||
|
packages = self._get_installed_packages()
|
||||||
|
self.assertNotIn(self._package_name, packages)
|
||||||
43
unittests/unittests_cli/unittests_cli.json
Normal file
43
unittests/unittests_cli/unittests_cli.json
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"Project": {
|
||||||
|
"Name": "unittest_cli",
|
||||||
|
"Version": {
|
||||||
|
"Major": "2024",
|
||||||
|
"Minor": "7",
|
||||||
|
"Micro": "0"
|
||||||
|
},
|
||||||
|
"Author": "",
|
||||||
|
"AuthorEmail": "",
|
||||||
|
"Description": "",
|
||||||
|
"LongDescription": "",
|
||||||
|
"URL": "",
|
||||||
|
"CopyrightDate": "",
|
||||||
|
"CopyrightName": "",
|
||||||
|
"LicenseName": "",
|
||||||
|
"LicenseDescription": "",
|
||||||
|
"Dependencies": [
|
||||||
|
"cpl-core>=2024.6.2024.07.0",
|
||||||
|
"cpl-cli>=2024.6.2024.07.0"
|
||||||
|
],
|
||||||
|
"PythonVersion": ">=3.10.4",
|
||||||
|
"PythonPath": {},
|
||||||
|
"Classifiers": [],
|
||||||
|
"DevDependencies": []
|
||||||
|
},
|
||||||
|
"Build": {
|
||||||
|
"ProjectType": "library",
|
||||||
|
"SourcePath": "",
|
||||||
|
"OutputPath": "../../dist",
|
||||||
|
"Main": "unittest_cli.main",
|
||||||
|
"EntryPoint": "unittest_cli",
|
||||||
|
"IncludePackageData": false,
|
||||||
|
"Included": [],
|
||||||
|
"Excluded": [
|
||||||
|
"*/__pycache__",
|
||||||
|
"*/logs",
|
||||||
|
"*/tests"
|
||||||
|
],
|
||||||
|
"PackageData": {},
|
||||||
|
"ProjectReferences": []
|
||||||
|
}
|
||||||
|
}
|
||||||
74
unittests/unittests_cli/update_test_case.py
Normal file
74
unittests/unittests_cli/update_test_case.py
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from cpl.core.utils import String
|
||||||
|
from unittests_cli.abc.command_test_case import CommandTestCase
|
||||||
|
from unittests_cli.constants import PLAYGROUND_PATH
|
||||||
|
from unittests_shared.cli_commands import CLICommands
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateTestCase(CommandTestCase):
|
||||||
|
def __init__(self, method_name: str):
|
||||||
|
CommandTestCase.__init__(self, method_name)
|
||||||
|
self._source = "install-test-source"
|
||||||
|
self._project_file = f"src/{String.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}"
|
||||||
|
|
||||||
|
# todo: better way to do shit required
|
||||||
|
self._new_version = "2.2.2"
|
||||||
|
self._new_package_name = "discord.py"
|
||||||
|
self._new_package = f"{self._new_package_name}=={self._new_version}"
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
CLICommands.uninstall(self._old_package)
|
||||||
|
CLICommands.uninstall(self._new_package)
|
||||||
|
os.chdir(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 _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 _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])
|
||||||
95
unittests/unittests_cli/version_test_case.py
Normal file
95
unittests/unittests_cli/version_test_case.py
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
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_cli.abc.command_test_case import CommandTestCase
|
||||||
|
from unittests_shared.cli_commands import CLICommands
|
||||||
|
|
||||||
|
|
||||||
|
class VersionTestCase(CommandTestCase):
|
||||||
|
def __init__(self, method_name: str):
|
||||||
|
CommandTestCase.__init__(self, method_name)
|
||||||
|
self._block_banner = ""
|
||||||
|
self._block_version = ""
|
||||||
|
self._block_package_header = ""
|
||||||
|
self._block_cpl_packages = ""
|
||||||
|
self._block_packages = ""
|
||||||
|
self._name = "CPL CLI"
|
||||||
|
|
||||||
|
def setUp(self): ...
|
||||||
|
|
||||||
|
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 <= 16:
|
||||||
|
self._block_cpl_packages += f"{line}\n"
|
||||||
|
|
||||||
|
if index >= 18:
|
||||||
|
self._block_packages += f"{line}\n"
|
||||||
|
|
||||||
|
index += 1
|
||||||
|
|
||||||
|
def test_version(self):
|
||||||
|
packages = []
|
||||||
|
cpl_packages = []
|
||||||
|
dependencies = dict(tuple(str(ws).split()) for ws in pkg_resources.working_set)
|
||||||
|
for p in dependencies:
|
||||||
|
if str(p).startswith("cpl-"):
|
||||||
|
cpl_packages.append([p, dependencies[p]])
|
||||||
|
continue
|
||||||
|
|
||||||
|
packages.append([p, dependencies[p]])
|
||||||
|
|
||||||
|
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"
|
||||||
|
|
||||||
|
with self.subTest(msg="Block banner"):
|
||||||
|
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",
|
||||||
|
]
|
||||||
|
with self.subTest(msg="Block version"):
|
||||||
|
self.assertEqual("\n".join(reference_version), self._block_version)
|
||||||
|
reference_cpl_packages = [
|
||||||
|
colored(colored(f"CPL packages:")),
|
||||||
|
colored(f'{tabulate(cpl_packages, headers=["Name", "Version"])}') + "\n",
|
||||||
|
]
|
||||||
|
with self.subTest(msg="Block cpl packages"):
|
||||||
|
self.assertEqual("\n".join(reference_cpl_packages), self._block_cpl_packages)
|
||||||
|
reference_packages = [
|
||||||
|
colored(colored(f"Python packages:")),
|
||||||
|
colored(f'{tabulate(packages, headers=["Name", "Version"])}'),
|
||||||
|
"\x1b[0m\x1b[0m\n\x1b[0m\x1b[0m\n\x1b[0m\x1b[0m\n", # fix colored codes
|
||||||
|
]
|
||||||
|
|
||||||
|
self.maxDiff = None
|
||||||
|
with self.subTest(msg="Block packages"):
|
||||||
|
ref_packages = "\n".join(reference_packages)
|
||||||
|
self.assertEqual(ref_packages, self._block_packages)
|
||||||
0
unittests/unittests_core/__init__.py
Normal file
0
unittests/unittests_core/__init__.py
Normal file
0
unittests/unittests_core/configuration/__init__.py
Normal file
0
unittests/unittests_core/configuration/__init__.py
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
from unittest.mock import Mock, MagicMock
|
||||||
|
|
||||||
|
from cpl.core.configuration import Configuration, ArgumentTypeEnum
|
||||||
|
from cpl.database import DatabaseSettings
|
||||||
|
from cpl.dependency import ServiceProvider, ServiceCollection
|
||||||
|
from cpl.mail 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))
|
||||||
|
|
||||||
|
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())
|
||||||
|
mocked_exec.run.assert_called()
|
||||||
|
|
||||||
|
self.assertEqual("test", self._config.get_configuration("var"))
|
||||||
|
self.assertIn("flag", self._config.additional_arguments)
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
from unittest.mock import Mock, MagicMock
|
||||||
|
|
||||||
|
from cpl.core.configuration import Configuration, ArgumentTypeEnum
|
||||||
|
from cpl.dependency 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())
|
||||||
|
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())
|
||||||
|
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())
|
||||||
|
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())
|
||||||
|
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())
|
||||||
|
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())
|
||||||
|
self._mocked_exec.run.assert_called()
|
||||||
|
self.assertIn("dev", self._config.additional_arguments)
|
||||||
|
self.assertIn("virtual", self._config.additional_arguments)
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
import os
|
||||||
|
import unittest
|
||||||
|
from _socket import gethostname
|
||||||
|
|
||||||
|
from cpl.core.configuration import Configuration
|
||||||
|
from cpl.core.environment import Environment, EnvironmentABC
|
||||||
|
from cpl.core.environment import 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, Environment))
|
||||||
|
self.assertTrue(issubclass(type(self._env), EnvironmentABC))
|
||||||
|
|
||||||
|
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.cwd, 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.cwd, 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_cwd(new_cwd)
|
||||||
|
self.assertEqual(self._env.cwd, new_cwd)
|
||||||
|
self._env.set_runtime_directory(new_cwd)
|
||||||
|
self.assertEqual(self._env.runtime_directory, new_cwd)
|
||||||
25
unittests/unittests_core/configuration/test-settings.json
Normal file
25
unittests/unittests_core/configuration/test-settings.json
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"TimeFormat": {
|
||||||
|
"DateFormat": "%Y-%m-%d",
|
||||||
|
"TimeFormat": "%H:%M:%S",
|
||||||
|
"DateTimeFormat": "%Y-%m-%d %H:%M:%S.%f",
|
||||||
|
"DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S"
|
||||||
|
},
|
||||||
|
"Logging": {
|
||||||
|
"Path": "logs/$date_now/",
|
||||||
|
"Filename": "bot.log",
|
||||||
|
"ConsoleLevel": "TRACE",
|
||||||
|
"Level": "TRACE"
|
||||||
|
},
|
||||||
|
"Database": {
|
||||||
|
"Host": "localhost",
|
||||||
|
"User": "local",
|
||||||
|
"Password": "bG9jYWw=",
|
||||||
|
"Database": "local",
|
||||||
|
"Port": "3306",
|
||||||
|
"Charset": "utf8mb4",
|
||||||
|
"UseUnicode": "true",
|
||||||
|
"Buffered": "true",
|
||||||
|
"AuthPlugin": "mysql_native_password"
|
||||||
|
}
|
||||||
|
}
|
||||||
48
unittests/unittests_core/core_test_suite.py
Normal file
48
unittests/unittests_core/core_test_suite.py
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
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
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
class CoreTestSuite(unittest.TestSuite):
|
||||||
|
def __init__(self):
|
||||||
|
unittest.TestSuite.__init__(self)
|
||||||
|
|
||||||
|
loader = unittest.TestLoader()
|
||||||
|
tests = [
|
||||||
|
# config
|
||||||
|
ConfigurationTestCase,
|
||||||
|
ConsoleArgumentsTestCase,
|
||||||
|
EnvironmentTestCase,
|
||||||
|
# di
|
||||||
|
ServiceCollectionTestCase,
|
||||||
|
ServiceProviderTestCase,
|
||||||
|
# pipes
|
||||||
|
BoolPipeTestCase,
|
||||||
|
IPAddressTestCase,
|
||||||
|
VersionPipeTestCase,
|
||||||
|
# utils
|
||||||
|
CredentialManagerTestCase,
|
||||||
|
JSONProcessorTestCase,
|
||||||
|
StringTestCase,
|
||||||
|
]
|
||||||
|
|
||||||
|
for test in tests:
|
||||||
|
self.addTests(loader.loadTestsFromTestCase(test))
|
||||||
|
|
||||||
|
def run(self, *args):
|
||||||
|
super().run(*args)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
runner = unittest.TextTestRunner()
|
||||||
|
runner.run(CoreTestSuite())
|
||||||
0
unittests/unittests_core/di/__init__.py
Normal file
0
unittests/unittests_core/di/__init__.py
Normal file
56
unittests/unittests_core/di/service_collection_test_case.py
Normal file
56
unittests/unittests_core/di/service_collection_test_case.py
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import unittest
|
||||||
|
from unittest.mock import Mock
|
||||||
|
|
||||||
|
from cpl.core.configuration import Configuration
|
||||||
|
from cpl.dependency import ServiceCollection, ServiceLifetimeEnum, ServiceProvider
|
||||||
|
|
||||||
|
|
||||||
|
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()
|
||||||
|
self.assertTrue(isinstance(sp, ServiceProvider))
|
||||||
|
self.assertTrue(isinstance(sp.get_service(Mock), Mock))
|
||||||
|
self.assertIsNotNone(service.implementation)
|
||||||
98
unittests/unittests_core/di/service_provider_test_case.py
Normal file
98
unittests/unittests_core/di/service_provider_test_case.py
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
import unittest
|
||||||
|
|
||||||
|
from cpl.core.configuration import Configuration
|
||||||
|
from cpl.dependency import ServiceCollection, ServiceProvider
|
||||||
|
|
||||||
|
|
||||||
|
class ServiceCount:
|
||||||
|
def __init__(self):
|
||||||
|
self.count = 0
|
||||||
|
|
||||||
|
|
||||||
|
class TestService:
|
||||||
|
def __init__(self, sp: ServiceProvider, count: ServiceCount):
|
||||||
|
count.count += 1
|
||||||
|
self.sp = sp
|
||||||
|
self.id = count.count
|
||||||
|
|
||||||
|
|
||||||
|
class DifferentService:
|
||||||
|
def __init__(self, sp: ServiceProvider, count: ServiceCount):
|
||||||
|
count.count += 1
|
||||||
|
self.sp = sp
|
||||||
|
self.id = count.count
|
||||||
|
|
||||||
|
|
||||||
|
class MoreDifferentService:
|
||||||
|
def __init__(self, sp: ServiceProvider, count: ServiceCount):
|
||||||
|
count.count += 1
|
||||||
|
self.sp = sp
|
||||||
|
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()
|
||||||
|
)
|
||||||
|
|
||||||
|
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)
|
||||||
|
transient = self._services.get_service(DifferentService)
|
||||||
|
with self._services.create_scope() as scope:
|
||||||
|
sp: ServiceProvider = scope.service_provider
|
||||||
|
self.assertNotEqual(sp, self._services)
|
||||||
|
y = sp.get_service(DifferentService)
|
||||||
|
self.assertIsNotNone(y)
|
||||||
|
self.assertEqual(3, y.id)
|
||||||
|
x = sp.get_service(MoreDifferentService)
|
||||||
|
self.assertIsNotNone(x)
|
||||||
|
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))
|
||||||
|
self.assertEqual(singleton, self._services.get_service(TestService))
|
||||||
|
|
||||||
|
self.assertIsNone(scope.service_provider)
|
||||||
|
self.assertNotEqual(scoped_id, self._services.get_service(MoreDifferentService).id)
|
||||||
0
unittests/unittests_core/pipes/__init__.py
Normal file
0
unittests/unittests_core/pipes/__init__.py
Normal file
11
unittests/unittests_core/pipes/bool_pipe_test_case.py
Normal file
11
unittests/unittests_core/pipes/bool_pipe_test_case.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import unittest
|
||||||
|
|
||||||
|
from cpl.core.pipes import BoolPipe
|
||||||
|
|
||||||
|
|
||||||
|
class BoolPipeTestCase(unittest.TestCase):
|
||||||
|
def setUp(self): ...
|
||||||
|
|
||||||
|
def test_transform(self):
|
||||||
|
self.assertEqual("true", BoolPipe.to_str(True))
|
||||||
|
self.assertEqual("false", BoolPipe.to_str(False))
|
||||||
17
unittests/unittests_core/pipes/ip_address_pipe_test_case.py
Normal file
17
unittests/unittests_core/pipes/ip_address_pipe_test_case.py
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import unittest
|
||||||
|
|
||||||
|
from cpl.core.pipes import IPAddressPipe
|
||||||
|
|
||||||
|
|
||||||
|
class IPAddressTestCase(unittest.TestCase):
|
||||||
|
def setUp(self): ...
|
||||||
|
|
||||||
|
def test_transform(self):
|
||||||
|
self.assertEqual("192.168.178.1", IPAddressPipe.to_str([192, 168, 178, 1]))
|
||||||
|
self.assertEqual("255.255.255.255", IPAddressPipe.to_str([255, 255, 255, 255]))
|
||||||
|
self.assertEqual("0.0.0.0", IPAddressPipe.to_str([0, 0, 0, 0]))
|
||||||
|
|
||||||
|
self.assertRaises(Exception, lambda: IPAddressPipe.to_str([-192, 168, 178, 1]))
|
||||||
|
self.assertRaises(Exception, lambda: IPAddressPipe.to_str([256, 168, 178, 1]))
|
||||||
|
self.assertRaises(Exception, lambda: IPAddressPipe.to_str([256, 168, 178]))
|
||||||
|
self.assertRaises(Exception, lambda: IPAddressPipe.to_str([256, 168, 178, 1, 1]))
|
||||||
42
unittests/unittests_core/unittests_core.json
Normal file
42
unittests/unittests_core/unittests_core.json
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"Project": {
|
||||||
|
"Name": "unittest_core",
|
||||||
|
"Version": {
|
||||||
|
"Major": "2024",
|
||||||
|
"Minor": "7",
|
||||||
|
"Micro": "0"
|
||||||
|
},
|
||||||
|
"Author": "",
|
||||||
|
"AuthorEmail": "",
|
||||||
|
"Description": "",
|
||||||
|
"LongDescription": "",
|
||||||
|
"URL": "",
|
||||||
|
"CopyrightDate": "",
|
||||||
|
"CopyrightName": "",
|
||||||
|
"LicenseName": "",
|
||||||
|
"LicenseDescription": "",
|
||||||
|
"Dependencies": [
|
||||||
|
"cpl-core>=2024.6.2024.07.0"
|
||||||
|
],
|
||||||
|
"PythonVersion": ">=3.10.4",
|
||||||
|
"PythonPath": {},
|
||||||
|
"Classifiers": [],
|
||||||
|
"DevDependencies": []
|
||||||
|
},
|
||||||
|
"Build": {
|
||||||
|
"ProjectType": "library",
|
||||||
|
"SourcePath": "",
|
||||||
|
"OutputPath": "../../dist",
|
||||||
|
"Main": "unittest_core.main",
|
||||||
|
"EntryPoint": "unittest_core",
|
||||||
|
"IncludePackageData": false,
|
||||||
|
"Included": [],
|
||||||
|
"Excluded": [
|
||||||
|
"*/__pycache__",
|
||||||
|
"*/logs",
|
||||||
|
"*/tests"
|
||||||
|
],
|
||||||
|
"PackageData": {},
|
||||||
|
"ProjectReferences": []
|
||||||
|
}
|
||||||
|
}
|
||||||
0
unittests/unittests_core/utils/__init__.py
Normal file
0
unittests/unittests_core/utils/__init__.py
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import unittest
|
||||||
|
|
||||||
|
from cpl.core.utils import CredentialManager
|
||||||
|
|
||||||
|
|
||||||
|
class CredentialManagerTestCase(unittest.TestCase):
|
||||||
|
def setUp(self): ...
|
||||||
|
|
||||||
|
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=="))
|
||||||
37
unittests/unittests_core/utils/json_processor_test_case.py
Normal file
37
unittests/unittests_core/utils/json_processor_test_case.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
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): ...
|
||||||
|
|
||||||
|
def test_process(self):
|
||||||
|
test_dict = {
|
||||||
|
"i": 10,
|
||||||
|
"s": "Hello World",
|
||||||
|
"d": {"test": "Test"},
|
||||||
|
"l": list(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"])
|
||||||
57
unittests/unittests_core/utils/string_test_case.py
Normal file
57
unittests/unittests_core/utils/string_test_case.py
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import string
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from cpl.core.utils import String
|
||||||
|
|
||||||
|
|
||||||
|
class StringTestCase(unittest.TestCase):
|
||||||
|
def setUp(self): ...
|
||||||
|
|
||||||
|
def test_convert_to_camel_case(self):
|
||||||
|
expected = "HelloWorld"
|
||||||
|
|
||||||
|
self.assertEqual(expected, String.to_camel_case("hello-world"))
|
||||||
|
self.assertEqual(expected, String.to_camel_case("hello-World"))
|
||||||
|
self.assertEqual(expected, String.to_camel_case("hello_world"))
|
||||||
|
self.assertEqual("helloWorld", String.to_camel_case("helloWorld"))
|
||||||
|
self.assertEqual(expected, String.to_camel_case("Hello_world"))
|
||||||
|
self.assertEqual(expected, String.to_camel_case("Hello_World"))
|
||||||
|
self.assertEqual(expected, String.to_camel_case("hello world"))
|
||||||
|
|
||||||
|
def test_convert_to_snake_case(self):
|
||||||
|
expected = "hello_world"
|
||||||
|
|
||||||
|
self.assertEqual(expected, String.to_snake_case("Hello World"))
|
||||||
|
self.assertEqual(expected, String.to_snake_case("hello-world"))
|
||||||
|
self.assertEqual(expected, String.to_snake_case("hello_world"))
|
||||||
|
self.assertEqual(expected, String.to_snake_case("helloWorld"))
|
||||||
|
self.assertEqual(expected, String.to_snake_case("Hello_world"))
|
||||||
|
self.assertEqual(expected, String.to_snake_case("Hello_World"))
|
||||||
|
self.assertEqual(expected, String.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
|
||||||
0
unittests/unittests_query/__init__.py
Normal file
0
unittests/unittests_query/__init__.py
Normal file
346
unittests/unittests_query/enumerable_query_test_case.py
Normal file
346
unittests/unittests_query/enumerable_query_test_case.py
Normal file
@@ -0,0 +1,346 @@
|
|||||||
|
import string
|
||||||
|
import unittest
|
||||||
|
from random import randint
|
||||||
|
|
||||||
|
from cpl.core.utils import String
|
||||||
|
from cpl.query.enumerable.enumerable import Enumerable
|
||||||
|
from cpl.query.exceptions import InvalidTypeException, ArgumentNoneException, IndexOutOfRangeException
|
||||||
|
from unittests_query.models import User, Address
|
||||||
|
|
||||||
|
|
||||||
|
class EnumerableQueryTestCase(unittest.TestCase):
|
||||||
|
def setUp(self) -> None:
|
||||||
|
users = []
|
||||||
|
for i in range(0, 100):
|
||||||
|
users.append(
|
||||||
|
User(
|
||||||
|
String.random_string(string.ascii_letters, 8).lower(),
|
||||||
|
Address(String.random_string(string.ascii_letters, 10).lower(), randint(1, 10)),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self._t_user = User("Test user", Address("teststr.", 15))
|
||||||
|
self._t_user2 = User("Test user", Address("teststr.", 14))
|
||||||
|
|
||||||
|
users.append(self._t_user)
|
||||||
|
users.append(self._t_user2)
|
||||||
|
|
||||||
|
self._tests = Enumerable(User, users)
|
||||||
|
|
||||||
|
def test_any(self):
|
||||||
|
results = []
|
||||||
|
for user in self._tests:
|
||||||
|
if user.address.nr == 10:
|
||||||
|
results.append(user)
|
||||||
|
|
||||||
|
res = self._tests.any(lambda u: u.address.nr == 10)
|
||||||
|
n_res = self._tests.any(lambda u: u.address.nr == 100)
|
||||||
|
|
||||||
|
self.assertTrue(res)
|
||||||
|
self.assertFalse(n_res)
|
||||||
|
|
||||||
|
def test_all(self):
|
||||||
|
results = []
|
||||||
|
for user in self._tests:
|
||||||
|
if user.address.nr == 10:
|
||||||
|
results.append(user)
|
||||||
|
|
||||||
|
res = self._tests.all(lambda u: u.address is not None)
|
||||||
|
n_res = self._tests.all(lambda u: u.address.nr == 100)
|
||||||
|
|
||||||
|
self.assertTrue(res)
|
||||||
|
self.assertFalse(n_res)
|
||||||
|
|
||||||
|
def test_avg(self):
|
||||||
|
avg = 0
|
||||||
|
for user in self._tests:
|
||||||
|
avg += user.address.nr
|
||||||
|
|
||||||
|
avg = avg / len(self._tests)
|
||||||
|
res = self._tests.average(lambda u: u.address.nr)
|
||||||
|
|
||||||
|
self.assertEqual(avg, res)
|
||||||
|
|
||||||
|
def invalid():
|
||||||
|
tests = Enumerable(str, ["hello", "world"])
|
||||||
|
e_res = tests.average()
|
||||||
|
|
||||||
|
self.assertRaises(InvalidTypeException, invalid)
|
||||||
|
|
||||||
|
tests = Enumerable(int, list(range(0, 100)))
|
||||||
|
self.assertEqual(sum(tests) / len(tests), tests.average())
|
||||||
|
|
||||||
|
def wrong2():
|
||||||
|
tests2 = Enumerable(int, values=list(range(0, 100)))
|
||||||
|
e_res = tests2.average(lambda u: u.address.nr)
|
||||||
|
|
||||||
|
self.assertRaises(AttributeError, wrong2)
|
||||||
|
|
||||||
|
def test_contains(self):
|
||||||
|
self.assertTrue(self._tests.contains(self._t_user))
|
||||||
|
self.assertFalse(self._tests.contains(User("Test", None)))
|
||||||
|
|
||||||
|
def test_count(self):
|
||||||
|
self.assertEqual(len(self._tests), self._tests.count())
|
||||||
|
self.assertEqual(1, self._tests.count(lambda u: u == self._t_user))
|
||||||
|
|
||||||
|
def test_distinct(self):
|
||||||
|
res = self._tests.distinct(lambda u: u.address.nr).where(lambda u: u.address.nr == 5)
|
||||||
|
self.assertEqual(1, len(res))
|
||||||
|
|
||||||
|
def test_element_at(self):
|
||||||
|
index = randint(0, len(self._tests) - 1)
|
||||||
|
self.assertEqual(self._tests.element_at(index), self._tests.element_at(index))
|
||||||
|
|
||||||
|
def invalid():
|
||||||
|
result = self._tests.element_at(len(self._tests))
|
||||||
|
|
||||||
|
self.assertRaises(IndexOutOfRangeException, invalid)
|
||||||
|
|
||||||
|
def test_element_at_or_default(self):
|
||||||
|
index = randint(0, len(self._tests) - 1)
|
||||||
|
self.assertEqual(self._tests.element_at(index), self._tests.element_at_or_default(index))
|
||||||
|
self.assertIsNone(self._tests.element_at_or_default(len(self._tests)))
|
||||||
|
|
||||||
|
def test_last(self):
|
||||||
|
results = []
|
||||||
|
for user in self._tests:
|
||||||
|
if user.address.nr == 10:
|
||||||
|
results.append(user)
|
||||||
|
|
||||||
|
res = self._tests.where(lambda u: u.address.nr == 10)
|
||||||
|
s_res = self._tests.where(lambda u: u.address.nr == 10).last()
|
||||||
|
|
||||||
|
self.assertEqual(len(res), len(results))
|
||||||
|
self.assertEqual(res.element_at(len(res) - 1), s_res)
|
||||||
|
|
||||||
|
def test_last_or_default(self):
|
||||||
|
results = []
|
||||||
|
for user in self._tests:
|
||||||
|
if user.address.nr == 10:
|
||||||
|
results.append(user)
|
||||||
|
|
||||||
|
res = self._tests.where(lambda u: u.address.nr == 10)
|
||||||
|
s_res = self._tests.where(lambda u: u.address.nr == 10).last_or_default()
|
||||||
|
sn_res = self._tests.where(lambda u: u.address.nr == 11).last_or_default()
|
||||||
|
|
||||||
|
self.assertEqual(len(res), len(results))
|
||||||
|
self.assertEqual(res.element_at(len(res) - 1), s_res)
|
||||||
|
self.assertIsNone(sn_res)
|
||||||
|
|
||||||
|
def test_first(self):
|
||||||
|
results = []
|
||||||
|
for user in self._tests:
|
||||||
|
if user.address.nr == 10:
|
||||||
|
results.append(user)
|
||||||
|
|
||||||
|
res = self._tests.where(lambda u: u.address.nr == 10)
|
||||||
|
s_res = self._tests.where(lambda u: u.address.nr == 10).first()
|
||||||
|
|
||||||
|
self.assertEqual(len(res), len(results))
|
||||||
|
self.assertEqual(res.element_at(0), s_res)
|
||||||
|
self.assertEqual(res.element_at(0), res.first())
|
||||||
|
self.assertEqual(res.first(), res.first())
|
||||||
|
|
||||||
|
def test_first_or_default(self):
|
||||||
|
results = []
|
||||||
|
for user in self._tests:
|
||||||
|
if user.address.nr == 10:
|
||||||
|
results.append(user)
|
||||||
|
|
||||||
|
res = self._tests.where(lambda u: u.address.nr == 10)
|
||||||
|
s_res = self._tests.where(lambda u: u.address.nr == 10).first_or_default()
|
||||||
|
sn_res = self._tests.where(lambda u: u.address.nr == 11).first_or_default()
|
||||||
|
|
||||||
|
self.assertEqual(len(res), len(results))
|
||||||
|
self.assertEqual(res.element_at(0), s_res)
|
||||||
|
self.assertIsNone(sn_res)
|
||||||
|
|
||||||
|
def test_for_each(self):
|
||||||
|
users = []
|
||||||
|
self._tests.for_each(lambda user: (users.append(user)))
|
||||||
|
|
||||||
|
self.assertEqual(len(users), len(self._tests))
|
||||||
|
|
||||||
|
def test_max(self):
|
||||||
|
res = self._tests.max(lambda u: u.address.nr)
|
||||||
|
self.assertEqual(res, self._t_user.address.nr)
|
||||||
|
|
||||||
|
tests = Enumerable(int, list(range(0, 100)))
|
||||||
|
self.assertEqual(99, tests.max())
|
||||||
|
|
||||||
|
def invalid():
|
||||||
|
tests = Enumerable(str, ["hello", "world"])
|
||||||
|
e_res = tests.average()
|
||||||
|
|
||||||
|
self.assertRaises(InvalidTypeException, invalid)
|
||||||
|
|
||||||
|
def test_min(self):
|
||||||
|
res = self._tests.min(lambda u: u.address.nr)
|
||||||
|
self.assertEqual(1, res)
|
||||||
|
|
||||||
|
tests = Enumerable(int, list(range(0, 100)))
|
||||||
|
self.assertEqual(0, tests.min())
|
||||||
|
|
||||||
|
def invalid():
|
||||||
|
tests = Enumerable(str, ["hello", "world"])
|
||||||
|
e_res = tests.average()
|
||||||
|
|
||||||
|
self.assertRaises(InvalidTypeException, invalid)
|
||||||
|
|
||||||
|
def test_order_by(self):
|
||||||
|
res = self._tests.order_by(lambda user: user.address.street)
|
||||||
|
res2 = self._tests.order_by(lambda user: user.address.nr).to_list()
|
||||||
|
s_res = self._tests.to_list()
|
||||||
|
s_res.sort(key=lambda user: user.address.street)
|
||||||
|
self.assertEqual(res.to_list(), s_res)
|
||||||
|
|
||||||
|
s_res = self._tests.to_list()
|
||||||
|
s_res.sort(key=lambda user: user.address.nr)
|
||||||
|
self.assertEqual(res2, s_res)
|
||||||
|
|
||||||
|
self.assertEqual(self._t_user, res.where(lambda u: u.address.nr == self._t_user.address.nr).single())
|
||||||
|
|
||||||
|
def test_order_by_descending(self):
|
||||||
|
res = self._tests.order_by_descending(lambda user: user.address.street).to_list()
|
||||||
|
res2 = self._tests.order_by_descending(lambda user: user.address.nr).to_list()
|
||||||
|
s_res = self._tests.to_list()
|
||||||
|
s_res.sort(key=lambda user: user.address.street, reverse=True)
|
||||||
|
|
||||||
|
self.assertEqual(res, s_res)
|
||||||
|
s_res = self._tests.to_list()
|
||||||
|
s_res.sort(key=lambda user: user.address.nr, reverse=True)
|
||||||
|
self.assertEqual(res2, s_res)
|
||||||
|
|
||||||
|
def test_then_by(self):
|
||||||
|
res = self._tests.order_by(lambda user: user.address.street).then_by(lambda user: user.address.nr).to_list()
|
||||||
|
|
||||||
|
s_res = self._tests.to_list()
|
||||||
|
s_res.sort(key=lambda user: (user.address.street, user.address.nr))
|
||||||
|
|
||||||
|
self.assertEqual(res, s_res)
|
||||||
|
|
||||||
|
def test_then_by_descending(self):
|
||||||
|
res = (
|
||||||
|
self._tests.order_by_descending(lambda user: user.address.street)
|
||||||
|
.then_by_descending(lambda user: user.address.nr)
|
||||||
|
.to_list()
|
||||||
|
)
|
||||||
|
|
||||||
|
s_res = self._tests.to_list()
|
||||||
|
s_res.sort(key=lambda user: (user.address.street, user.address.nr), reverse=True)
|
||||||
|
|
||||||
|
self.assertEqual(res, s_res)
|
||||||
|
|
||||||
|
def test_reverse(self):
|
||||||
|
res = self._tests.reverse().to_list()
|
||||||
|
l_res = self._tests.to_list()
|
||||||
|
l_res.reverse()
|
||||||
|
|
||||||
|
self.assertEqual(res, l_res)
|
||||||
|
|
||||||
|
def test_select(self):
|
||||||
|
range_list = Enumerable(int, range(0, 100))
|
||||||
|
selected_range = range_list.select(lambda x: x + 1)
|
||||||
|
|
||||||
|
modulo_range = []
|
||||||
|
for x in range(0, 100):
|
||||||
|
if x % 2 == 0:
|
||||||
|
modulo_range.append(x)
|
||||||
|
self.assertEqual(selected_range.to_list(), list(range(1, 101)))
|
||||||
|
self.assertEqual(range_list.where(lambda x: x % 2 == 0).to_list(), modulo_range)
|
||||||
|
|
||||||
|
def test_select_many(self):
|
||||||
|
range_list = Enumerable(int, list(range(0, 100)))
|
||||||
|
selected_range = range_list.select(lambda x: [x, x])
|
||||||
|
|
||||||
|
self.assertEqual(selected_range.to_list(), [[x, x] for x in range(0, 100)])
|
||||||
|
self.assertEqual(
|
||||||
|
selected_range.select_many(lambda x: x).to_list(),
|
||||||
|
[_x for _l in [2 * [x] for x in range(0, 100)] for _x in _l],
|
||||||
|
)
|
||||||
|
|
||||||
|
class TestClass:
|
||||||
|
def __init__(self, i, is_sub=False):
|
||||||
|
self.i = i
|
||||||
|
if is_sub:
|
||||||
|
return
|
||||||
|
self.elements = [TestClass(x, True) for x in range(0, 10)]
|
||||||
|
|
||||||
|
elements = Enumerable(TestClass, [TestClass(i) for i in range(0, 100)])
|
||||||
|
selected_elements = elements.select_many(lambda x: x.elements).select(lambda x: x.i)
|
||||||
|
self.assertEqual(selected_elements.where(lambda x: x == 0).count(), 100)
|
||||||
|
|
||||||
|
def test_single(self):
|
||||||
|
res = self._tests.where(lambda u: u.address.nr == self._t_user.address.nr)
|
||||||
|
s_res = self._tests.where(lambda u: u.address.nr == self._t_user.address.nr).single()
|
||||||
|
|
||||||
|
self.assertEqual(len(res), 1)
|
||||||
|
self.assertEqual(self._t_user, s_res)
|
||||||
|
|
||||||
|
def test_single_or_default(self):
|
||||||
|
res = self._tests.where(lambda u: u.address.nr == self._t_user.address.nr)
|
||||||
|
s_res = self._tests.where(lambda u: u.address.nr == self._t_user.address.nr).single_or_default()
|
||||||
|
sn_res = self._tests.where(lambda u: u.address.nr == self._t_user.address.nr + 1).single_or_default()
|
||||||
|
|
||||||
|
self.assertEqual(len(res), 1)
|
||||||
|
self.assertEqual(self._t_user, s_res)
|
||||||
|
self.assertIsNone(sn_res)
|
||||||
|
|
||||||
|
def test_skip(self):
|
||||||
|
skipped = self._tests.skip(5).to_list()
|
||||||
|
|
||||||
|
self.assertEqual(len(skipped), len(self._tests) - 5)
|
||||||
|
self.assertEqual(skipped, self._tests.to_list()[5:])
|
||||||
|
|
||||||
|
def test_skip_last(self):
|
||||||
|
skipped = self._tests.skip_last(5)
|
||||||
|
|
||||||
|
self.assertEqual(skipped.count(), len(self._tests) - 5)
|
||||||
|
self.assertEqual(skipped.to_list(), self._tests.to_list()[:-5])
|
||||||
|
self.assertEqual(skipped.last(), self._tests.to_list()[:-5][len(self._tests.to_list()[:-5]) - 1])
|
||||||
|
|
||||||
|
def test_sum(self):
|
||||||
|
res = self._tests.sum(lambda u: u.address.nr)
|
||||||
|
|
||||||
|
s_res = 0
|
||||||
|
for user in self._tests:
|
||||||
|
s_res += user.address.nr
|
||||||
|
|
||||||
|
self.assertEqual(s_res, res)
|
||||||
|
|
||||||
|
tests = Enumerable(int, list(range(0, 100)))
|
||||||
|
self.assertEqual(0, tests.min())
|
||||||
|
|
||||||
|
def invalid():
|
||||||
|
tests2 = Enumerable(str, ["hello", "world"])
|
||||||
|
e_res = tests2.average()
|
||||||
|
|
||||||
|
self.assertRaises(InvalidTypeException, invalid)
|
||||||
|
|
||||||
|
def test_take(self):
|
||||||
|
skipped = self._tests.take(5)
|
||||||
|
|
||||||
|
self.assertEqual(skipped.count(), 5)
|
||||||
|
self.assertEqual(skipped.to_list(), self._tests.to_list()[:5])
|
||||||
|
|
||||||
|
def test_take_last(self):
|
||||||
|
skipped = self._tests.take_last(5)
|
||||||
|
|
||||||
|
self.assertEqual(skipped.count(), 5)
|
||||||
|
self.assertEqual(skipped.to_list(), self._tests.to_list()[-5:])
|
||||||
|
self.assertEqual(skipped.last(), self._tests.to_list()[len(self._tests) - 1])
|
||||||
|
|
||||||
|
def test_where(self):
|
||||||
|
results = []
|
||||||
|
for user in self._tests:
|
||||||
|
if user.address.nr == 5:
|
||||||
|
results.append(user)
|
||||||
|
|
||||||
|
res = self._tests.where(lambda u: u.address.nr == 5)
|
||||||
|
self.assertEqual(len(results), len(res))
|
||||||
|
|
||||||
|
def ex():
|
||||||
|
e_res = self._tests.where(None)
|
||||||
|
|
||||||
|
self.assertRaises(ArgumentNoneException, ex)
|
||||||
35
unittests/unittests_query/enumerable_test_case.py
Normal file
35
unittests/unittests_query/enumerable_test_case.py
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import unittest
|
||||||
|
|
||||||
|
from cpl.query.enumerable.enumerable import Enumerable
|
||||||
|
|
||||||
|
|
||||||
|
class EnumerableTestCase(unittest.TestCase):
|
||||||
|
def setUp(self) -> None:
|
||||||
|
self._list = Enumerable(int, list(range(1, 4)))
|
||||||
|
|
||||||
|
def test_append(self):
|
||||||
|
self.assertEqual(self._list.to_list(), [1, 2, 3])
|
||||||
|
self.assertRaises(Exception, lambda v: self._list.add(v), "3")
|
||||||
|
|
||||||
|
def test_default(self):
|
||||||
|
self.assertEqual(Enumerable.empty().to_list(), [])
|
||||||
|
self.assertEqual(Enumerable.range(0, 100).to_list(), list(range(0, 100)))
|
||||||
|
|
||||||
|
# def test_iter(self):
|
||||||
|
# n = 0
|
||||||
|
# elements = Enumerable.range(0, 100)
|
||||||
|
# while n < 100:
|
||||||
|
# self.assertEqual(elements.next(), n)
|
||||||
|
# n += 1
|
||||||
|
|
||||||
|
def test_for(self):
|
||||||
|
n = 0
|
||||||
|
for i in Enumerable.range(0, 100):
|
||||||
|
self.assertEqual(i, n)
|
||||||
|
n += 1
|
||||||
|
|
||||||
|
def test_get(self):
|
||||||
|
self.assertEqual(self._list.element_at(2), [1, 2, 3][2])
|
||||||
|
|
||||||
|
def test_count(self):
|
||||||
|
self.assertEqual(self._list.count(), 3)
|
||||||
382
unittests/unittests_query/iterable_query_test_case.py
Normal file
382
unittests/unittests_query/iterable_query_test_case.py
Normal file
@@ -0,0 +1,382 @@
|
|||||||
|
import string
|
||||||
|
import unittest
|
||||||
|
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.collection import Iterable
|
||||||
|
from unittests_query.models import User, Address
|
||||||
|
|
||||||
|
|
||||||
|
class IterableQueryTestCase(unittest.TestCase):
|
||||||
|
def setUp(self) -> None:
|
||||||
|
self._tests = List(User)
|
||||||
|
self._t_user = User("Test user", Address("teststr.", 15))
|
||||||
|
self._t_user2 = User("Test user", Address("teststr.", 14))
|
||||||
|
|
||||||
|
self._generate_test_data()
|
||||||
|
|
||||||
|
def _generate_test_data(self):
|
||||||
|
for i in range(0, 100):
|
||||||
|
user = User(
|
||||||
|
String.random_string(string.ascii_letters, 8).lower(),
|
||||||
|
Address(String.random_string(string.ascii_letters, 10).lower(), randint(1, 10)),
|
||||||
|
)
|
||||||
|
|
||||||
|
self._tests.append(user)
|
||||||
|
|
||||||
|
self._tests.append(self._t_user)
|
||||||
|
self._tests.append(self._t_user2)
|
||||||
|
|
||||||
|
def test_any(self):
|
||||||
|
results = []
|
||||||
|
for user in self._tests:
|
||||||
|
if user.address.nr == 10:
|
||||||
|
results.append(user)
|
||||||
|
|
||||||
|
res = self._tests.any(lambda u: u.address.nr == 10)
|
||||||
|
n_res = self._tests.any(lambda u: u.address.nr == 100)
|
||||||
|
|
||||||
|
self.assertTrue(res)
|
||||||
|
self.assertFalse(n_res)
|
||||||
|
|
||||||
|
def test_all(self):
|
||||||
|
results = []
|
||||||
|
for user in self._tests:
|
||||||
|
if user.address.nr == 10:
|
||||||
|
results.append(user)
|
||||||
|
|
||||||
|
res = self._tests.all(lambda u: u.address is not None)
|
||||||
|
n_res = self._tests.all(lambda u: u.address.nr == 100)
|
||||||
|
|
||||||
|
self.assertTrue(res)
|
||||||
|
self.assertFalse(n_res)
|
||||||
|
|
||||||
|
def test_avg(self):
|
||||||
|
avg = 0
|
||||||
|
for user in self._tests:
|
||||||
|
avg += user.address.nr
|
||||||
|
|
||||||
|
avg = avg / len(self._tests)
|
||||||
|
res = self._tests.average(lambda u: u.address.nr)
|
||||||
|
|
||||||
|
self.assertEqual(avg, res)
|
||||||
|
|
||||||
|
def invalid():
|
||||||
|
tests = List(str, ["hello", "world"])
|
||||||
|
e_res = tests.average()
|
||||||
|
|
||||||
|
self.assertRaises(InvalidTypeException, invalid)
|
||||||
|
|
||||||
|
tests = List(int, list(range(0, 100)))
|
||||||
|
self.assertEqual(sum(tests) / len(tests), tests.average())
|
||||||
|
|
||||||
|
def wrong2():
|
||||||
|
tests2 = List(int, values=list(range(0, 100)))
|
||||||
|
e_res = tests2.average(lambda u: u.address.nr)
|
||||||
|
|
||||||
|
self.assertRaises(AttributeError, wrong2)
|
||||||
|
|
||||||
|
def test_contains(self):
|
||||||
|
self.assertTrue(self._tests.contains(self._t_user))
|
||||||
|
self.assertFalse(self._tests.contains(User("Test", None)))
|
||||||
|
|
||||||
|
def test_count(self):
|
||||||
|
self.assertEqual(len(self._tests), self._tests.count())
|
||||||
|
self.assertEqual(1, self._tests.count(lambda u: u == self._t_user))
|
||||||
|
|
||||||
|
def test_distinct(self):
|
||||||
|
res = self._tests.select(lambda u: u.address.nr).where(lambda a: a == 5).distinct()
|
||||||
|
self.assertEqual(1, res.count())
|
||||||
|
|
||||||
|
addresses = []
|
||||||
|
for u in self._tests:
|
||||||
|
if u.address.nr in addresses:
|
||||||
|
continue
|
||||||
|
|
||||||
|
addresses.append(u.address.nr)
|
||||||
|
|
||||||
|
res2 = self._tests.distinct(lambda x: x.address.nr).select(lambda x: x.address.nr).to_list()
|
||||||
|
self.assertEqual(addresses, res2)
|
||||||
|
|
||||||
|
def test_element_at(self):
|
||||||
|
index = randint(0, len(self._tests) - 1)
|
||||||
|
self.assertEqual(self._tests[index], self._tests.element_at(index))
|
||||||
|
|
||||||
|
def test_element_at_or_default(self):
|
||||||
|
index = randint(0, len(self._tests) - 1)
|
||||||
|
self.assertEqual(self._tests[index], self._tests.element_at_or_default(index))
|
||||||
|
self.assertIsNone(self._tests.element_at_or_default(len(self._tests)))
|
||||||
|
|
||||||
|
def test_last(self):
|
||||||
|
results = []
|
||||||
|
for user in self._tests:
|
||||||
|
if user.address.nr == 10:
|
||||||
|
results.append(user)
|
||||||
|
|
||||||
|
res = self._tests.where(lambda u: u.address.nr == 10)
|
||||||
|
s_res = self._tests.where(lambda u: u.address.nr == 10).last()
|
||||||
|
|
||||||
|
self.assertEqual(len(res), len(results))
|
||||||
|
self.assertEqual(res[len(res) - 1], s_res)
|
||||||
|
|
||||||
|
def test_last_or_default(self):
|
||||||
|
results = []
|
||||||
|
for user in self._tests:
|
||||||
|
if user.address.nr == 10:
|
||||||
|
results.append(user)
|
||||||
|
|
||||||
|
res = self._tests.where(lambda u: u.address.nr == 10)
|
||||||
|
s_res = self._tests.where(lambda u: u.address.nr == 10).last_or_default()
|
||||||
|
sn_res = self._tests.where(lambda u: u.address.nr == 11).last_or_default()
|
||||||
|
|
||||||
|
self.assertEqual(len(res), len(results))
|
||||||
|
self.assertEqual(res[len(res) - 1], s_res)
|
||||||
|
self.assertIsNone(sn_res)
|
||||||
|
|
||||||
|
def test_first(self):
|
||||||
|
results = []
|
||||||
|
for user in self._tests:
|
||||||
|
if user.address.nr == 10:
|
||||||
|
results.append(user)
|
||||||
|
|
||||||
|
res = self._tests.where(lambda u: u.address.nr == 10)
|
||||||
|
s_res = self._tests.where(lambda u: u.address.nr == 10).first()
|
||||||
|
|
||||||
|
self.assertEqual(len(res), len(results))
|
||||||
|
self.assertEqual(res[0], s_res)
|
||||||
|
self.assertEqual(res[0], res.first())
|
||||||
|
self.assertEqual(res.first(), res.first())
|
||||||
|
|
||||||
|
def test_first_or_default(self):
|
||||||
|
results = []
|
||||||
|
for user in self._tests:
|
||||||
|
if user.address.nr == 10:
|
||||||
|
results.append(user)
|
||||||
|
|
||||||
|
res = self._tests.where(lambda u: u.address.nr == 10)
|
||||||
|
s_res = self._tests.where(lambda u: u.address.nr == 10).first_or_default()
|
||||||
|
sn_res = self._tests.where(lambda u: u.address.nr == 11).first_or_default()
|
||||||
|
|
||||||
|
self.assertEqual(len(res), len(results))
|
||||||
|
self.assertEqual(res[0], s_res)
|
||||||
|
self.assertIsNone(sn_res)
|
||||||
|
|
||||||
|
def test_group_by(self):
|
||||||
|
def by_adr(u):
|
||||||
|
return u.address.nr
|
||||||
|
|
||||||
|
t = self._tests.select(by_adr).group_by()
|
||||||
|
res = self._tests.group_by(by_adr)
|
||||||
|
self.assertTrue(isinstance(res.first_or_default(), Iterable))
|
||||||
|
self.assertNotEqual(self._tests.count(), res.count())
|
||||||
|
self.assertEqual(self._tests.distinct(by_adr).count(), res.count())
|
||||||
|
|
||||||
|
elements = List(int)
|
||||||
|
groups = {}
|
||||||
|
for x in range(0, 1000):
|
||||||
|
v = randint(1, 100)
|
||||||
|
if v not in groups:
|
||||||
|
groups[v] = []
|
||||||
|
|
||||||
|
groups[v].append(v)
|
||||||
|
elements.append(v)
|
||||||
|
|
||||||
|
r1, r2 = list(groups.values()), elements.group_by().select(lambda l: l.to_list()).to_list()
|
||||||
|
self.assertEqual(r1, r2)
|
||||||
|
|
||||||
|
def test_for_each(self):
|
||||||
|
users = []
|
||||||
|
self._tests.for_each(lambda user: (users.append(user)))
|
||||||
|
|
||||||
|
self.assertEqual(len(users), len(self._tests))
|
||||||
|
|
||||||
|
def test_max(self):
|
||||||
|
res = self._tests.max(lambda u: u.address.nr)
|
||||||
|
self.assertEqual(res, self._t_user.address.nr)
|
||||||
|
|
||||||
|
tests = List(int, list(range(0, 100)))
|
||||||
|
self.assertEqual(99, tests.max())
|
||||||
|
|
||||||
|
def invalid():
|
||||||
|
tests = List(str, ["hello", "world"])
|
||||||
|
e_res = tests.average()
|
||||||
|
|
||||||
|
self.assertRaises(InvalidTypeException, invalid)
|
||||||
|
|
||||||
|
def test_min(self):
|
||||||
|
res = self._tests.min(lambda u: u.address.nr)
|
||||||
|
self.assertEqual(1, res)
|
||||||
|
|
||||||
|
tests = List(int, list(range(0, 100)))
|
||||||
|
self.assertEqual(0, tests.min())
|
||||||
|
|
||||||
|
def invalid():
|
||||||
|
tests = List(str, ["hello", "world"])
|
||||||
|
e_res = tests.average()
|
||||||
|
|
||||||
|
self.assertRaises(InvalidTypeException, invalid)
|
||||||
|
|
||||||
|
def test_order_by(self):
|
||||||
|
res = self._tests.order_by(lambda user: user.address.street)
|
||||||
|
res2 = self._tests.order_by(lambda user: user.address.nr).to_list()
|
||||||
|
s_res = self._tests.to_list()
|
||||||
|
s_res.sort(key=lambda user: user.address.street)
|
||||||
|
self.assertEqual(res.to_list(), s_res)
|
||||||
|
|
||||||
|
s_res = self._tests.to_list()
|
||||||
|
s_res.sort(key=lambda user: user.address.nr)
|
||||||
|
self.assertEqual(res2, s_res)
|
||||||
|
|
||||||
|
self.assertEqual(self._t_user, res.where(lambda u: u.address.nr == self._t_user.address.nr).single())
|
||||||
|
|
||||||
|
def test_order_by_descending(self):
|
||||||
|
res = self._tests.order_by_descending(lambda user: user.address.street).to_list()
|
||||||
|
res2 = self._tests.order_by_descending(lambda user: user.address.nr).to_list()
|
||||||
|
s_res = self._tests.to_list()
|
||||||
|
s_res.sort(key=lambda user: user.address.street, reverse=True)
|
||||||
|
|
||||||
|
self.assertEqual(res, s_res)
|
||||||
|
s_res = self._tests.to_list()
|
||||||
|
s_res.sort(key=lambda user: user.address.nr, reverse=True)
|
||||||
|
self.assertEqual(res2, s_res)
|
||||||
|
|
||||||
|
def test_then_by(self):
|
||||||
|
res = self._tests.order_by(lambda user: user.address.street).then_by(lambda user: user.address.nr).to_list()
|
||||||
|
|
||||||
|
s_res = self._tests.to_list()
|
||||||
|
s_res.sort(key=lambda user: (user.address.street, user.address.nr))
|
||||||
|
|
||||||
|
self.assertEqual(res, s_res)
|
||||||
|
|
||||||
|
def test_then_by_descending(self):
|
||||||
|
res = (
|
||||||
|
self._tests.order_by_descending(lambda user: user.address.street)
|
||||||
|
.then_by_descending(lambda user: user.address.nr)
|
||||||
|
.to_list()
|
||||||
|
)
|
||||||
|
|
||||||
|
s_res = self._tests.to_list()
|
||||||
|
s_res.sort(key=lambda user: (user.address.street, user.address.nr), reverse=True)
|
||||||
|
|
||||||
|
self.assertEqual(res, s_res)
|
||||||
|
|
||||||
|
def test_reverse(self):
|
||||||
|
res = self._tests.reverse()
|
||||||
|
l_res = self._tests.to_list()
|
||||||
|
l_res.reverse()
|
||||||
|
|
||||||
|
self.assertEqual(res.to_list(), l_res)
|
||||||
|
|
||||||
|
def test_select(self):
|
||||||
|
def test(_l: List) -> List[int]:
|
||||||
|
return _l.select(lambda user: user.address.nr)
|
||||||
|
|
||||||
|
self.assertEqual(List[User], self._tests.type)
|
||||||
|
self.assertEqual(List[int], test(self._tests).type)
|
||||||
|
|
||||||
|
range_list = List(int, range(0, 100))
|
||||||
|
selected_range = range_list.select(lambda x: x + 1)
|
||||||
|
|
||||||
|
modulo_range = []
|
||||||
|
for x in range(0, 100):
|
||||||
|
if x % 2 == 0:
|
||||||
|
modulo_range.append(x)
|
||||||
|
self.assertEqual(selected_range.to_list(), list(range(1, 101)))
|
||||||
|
self.assertEqual(range_list.where(lambda x: x % 2 == 0).to_list(), modulo_range)
|
||||||
|
|
||||||
|
def test_select_many(self):
|
||||||
|
range_list = List(int, list(range(0, 100)))
|
||||||
|
selected_range = range_list.select(lambda x: [x, x])
|
||||||
|
|
||||||
|
self.assertEqual(selected_range.to_list(), [[x, x] for x in range(0, 100)])
|
||||||
|
self.assertEqual(
|
||||||
|
selected_range.select_many(lambda x: x).to_list(),
|
||||||
|
[_x for _l in [2 * [x] for x in range(0, 100)] for _x in _l],
|
||||||
|
)
|
||||||
|
|
||||||
|
class TestClass:
|
||||||
|
def __init__(self, i, is_sub=False):
|
||||||
|
self.i = i
|
||||||
|
if is_sub:
|
||||||
|
return
|
||||||
|
self.elements = [TestClass(x, True) for x in range(0, 10)]
|
||||||
|
|
||||||
|
elements = List(TestClass, [TestClass(i) for i in range(0, 100)])
|
||||||
|
selected_elements = elements.select_many(lambda x: x.elements).select(lambda x: x.i)
|
||||||
|
self.assertEqual(selected_elements.where(lambda x: x == 0).count(), 100)
|
||||||
|
|
||||||
|
def test_single(self):
|
||||||
|
res = self._tests.where(lambda u: u.address.nr == self._t_user.address.nr)
|
||||||
|
s_res = self._tests.where(lambda u: u.address.nr == self._t_user.address.nr).single()
|
||||||
|
|
||||||
|
self.assertEqual(len(res), 1)
|
||||||
|
self.assertEqual(self._t_user, s_res)
|
||||||
|
|
||||||
|
def test_single_or_default(self):
|
||||||
|
res = self._tests.where(lambda u: u.address.nr == self._t_user.address.nr)
|
||||||
|
s_res = self._tests.where(lambda u: u.address.nr == self._t_user.address.nr).single_or_default()
|
||||||
|
sn_res = self._tests.where(lambda u: u.address.nr == self._t_user.address.nr + 1).single_or_default()
|
||||||
|
|
||||||
|
self.assertEqual(len(res), 1)
|
||||||
|
self.assertEqual(self._t_user, s_res)
|
||||||
|
self.assertIsNone(sn_res)
|
||||||
|
|
||||||
|
def test_skip(self):
|
||||||
|
skipped = self._tests.skip(5).to_list()
|
||||||
|
|
||||||
|
self.assertEqual(len(skipped), len(self._tests) - 5)
|
||||||
|
self.assertEqual(skipped, self._tests[5:])
|
||||||
|
|
||||||
|
def test_skip_last(self):
|
||||||
|
skipped = self._tests.skip_last(5)
|
||||||
|
|
||||||
|
self.assertEqual(skipped.count(), len(self._tests) - 5)
|
||||||
|
self.assertEqual(skipped.to_list(), self._tests[:-5])
|
||||||
|
self.assertEqual(skipped.last(), self._tests[:-5][len(self._tests[:-5]) - 1])
|
||||||
|
|
||||||
|
def test_sum(self) -> List["int"]:
|
||||||
|
res = self._tests.sum(lambda u: u.address.nr)
|
||||||
|
|
||||||
|
s_res = 0
|
||||||
|
for user in self._tests:
|
||||||
|
s_res += user.address.nr
|
||||||
|
|
||||||
|
self.assertEqual(s_res, res)
|
||||||
|
|
||||||
|
tests = List(int, list(range(0, 100)))
|
||||||
|
self.assertEqual(0, tests.min())
|
||||||
|
|
||||||
|
def invalid():
|
||||||
|
tests2 = List(str, ["hello", "world"])
|
||||||
|
e_res = tests2.average()
|
||||||
|
|
||||||
|
self.assertRaises(InvalidTypeException, invalid)
|
||||||
|
|
||||||
|
def test_take(self):
|
||||||
|
skipped = self._tests.take(5)
|
||||||
|
|
||||||
|
self.assertEqual(skipped.count(), 5)
|
||||||
|
self.assertEqual(skipped.to_list(), self._tests[:5])
|
||||||
|
|
||||||
|
def test_take_last(self):
|
||||||
|
skipped = self._tests.take_last(5)
|
||||||
|
|
||||||
|
self.assertEqual(skipped.count(), 5)
|
||||||
|
self.assertEqual(skipped.to_list(), self._tests[-5:])
|
||||||
|
self.assertEqual(skipped.last(), self._tests[len(self._tests) - 1])
|
||||||
|
|
||||||
|
def test_where(self):
|
||||||
|
results = []
|
||||||
|
for user in self._tests:
|
||||||
|
if user.address.nr == 5:
|
||||||
|
results.append(user)
|
||||||
|
|
||||||
|
res = self._tests.where(lambda u: u.address.nr == 5)
|
||||||
|
self.assertEqual(len(results), len(res))
|
||||||
|
|
||||||
|
def ex():
|
||||||
|
e_res = self._tests.where(None)
|
||||||
|
|
||||||
|
self.assertRaises(ArgumentNoneException, ex)
|
||||||
34
unittests/unittests_query/iterable_test_case.py
Normal file
34
unittests/unittests_query/iterable_test_case.py
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import unittest
|
||||||
|
|
||||||
|
from cpl.query.extension.list import List
|
||||||
|
|
||||||
|
|
||||||
|
class IterableTestCase(unittest.TestCase):
|
||||||
|
def setUp(self) -> None:
|
||||||
|
self._list = List(int)
|
||||||
|
|
||||||
|
def _clear(self):
|
||||||
|
self._list.clear()
|
||||||
|
self.assertEqual(self._list, [])
|
||||||
|
|
||||||
|
def test_append(self):
|
||||||
|
self._list.append(1)
|
||||||
|
self._list.append(2)
|
||||||
|
self._list.append(3)
|
||||||
|
|
||||||
|
self.assertEqual(self._list.to_list(), [1, 2, 3])
|
||||||
|
self.assertRaises(Exception, lambda v: self._list.append(v), "3")
|
||||||
|
|
||||||
|
def test_assign(self):
|
||||||
|
self._list.append(1)
|
||||||
|
self._list.append(2)
|
||||||
|
self._list.append(3)
|
||||||
|
self._list[0] = 42
|
||||||
|
self.assertEqual(self._list[0], 42)
|
||||||
|
self._list[0] = 1
|
||||||
|
self._list.append(42)
|
||||||
|
self.assertEqual(self._list[3], 42)
|
||||||
|
del self._list[3]
|
||||||
|
|
||||||
|
self.assertEqual(self._list.to_list(), [1, 2, 3])
|
||||||
|
self.assertRaises(Exception, lambda v: self._list.append(v), "3")
|
||||||
16
unittests/unittests_query/models.py
Normal file
16
unittests/unittests_query/models.py
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
class User:
|
||||||
|
def __init__(self, name, address):
|
||||||
|
self.name = name
|
||||||
|
self.address = address
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<{type(self).__name__} {self.name} {self.address}>"
|
||||||
|
|
||||||
|
|
||||||
|
class Address:
|
||||||
|
def __init__(self, street, nr):
|
||||||
|
self.street = street
|
||||||
|
self.nr = nr
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<{type(self).__name__} {self.street} {self.nr}>"
|
||||||
70
unittests/unittests_query/performance_test_case.py
Normal file
70
unittests/unittests_query/performance_test_case.py
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
import sys
|
||||||
|
import timeit
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from cpl.query.enumerable import Enumerable
|
||||||
|
from cpl.query.collection import Iterable
|
||||||
|
|
||||||
|
VALUES = 10000
|
||||||
|
COUNT = 50
|
||||||
|
|
||||||
|
|
||||||
|
class PerformanceTestCase(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
i = 0
|
||||||
|
self.values = []
|
||||||
|
while i < VALUES:
|
||||||
|
self.values.append(i)
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
def test_range(self):
|
||||||
|
default = timeit.timeit(lambda: list(range(0, VALUES)), number=COUNT)
|
||||||
|
iterable = timeit.timeit(lambda: Iterable.range(0, VALUES), number=COUNT)
|
||||||
|
enumerable = timeit.timeit(lambda: Enumerable.range(0, VALUES), number=COUNT)
|
||||||
|
|
||||||
|
print("Range")
|
||||||
|
print(f"d: {default}s")
|
||||||
|
print(f"i: {iterable}s")
|
||||||
|
print(f"e: {enumerable}s")
|
||||||
|
|
||||||
|
self.assertAlmostEqual(round(default, 3), round(enumerable, 3))
|
||||||
|
self.assertAlmostEqual(round(default, 3), round(iterable, 3))
|
||||||
|
|
||||||
|
def test_where_single(self):
|
||||||
|
default = timeit.timeit(lambda: [x for x in list(range(0, VALUES)) if x == 50], number=COUNT)
|
||||||
|
iterable = timeit.timeit(lambda: Iterable.range(0, VALUES).where(lambda x: x == 50).single(), number=COUNT)
|
||||||
|
enumerable = timeit.timeit(lambda: Enumerable.range(0, VALUES).where(lambda x: x == 50).single(), number=COUNT)
|
||||||
|
|
||||||
|
print("Where single")
|
||||||
|
print(f"d: {default}s")
|
||||||
|
print(f"i: {iterable}s")
|
||||||
|
print(f"e: {enumerable}s")
|
||||||
|
|
||||||
|
self.assertLess(default, enumerable)
|
||||||
|
self.assertLess(default, iterable)
|
||||||
|
|
||||||
|
def test_where_single_complex(self):
|
||||||
|
class TestModel:
|
||||||
|
def __init__(self, v, tm=None):
|
||||||
|
self.value = v
|
||||||
|
self.tm = tm
|
||||||
|
|
||||||
|
values = []
|
||||||
|
for i in range(VALUES):
|
||||||
|
values.append(TestModel(i, TestModel(i + 1)))
|
||||||
|
|
||||||
|
default = timeit.timeit(lambda: [x for x in values if x.tm.value == 50], number=COUNT)
|
||||||
|
iterable = timeit.timeit(
|
||||||
|
lambda: Iterable(TestModel, values).where(lambda x: x.tm.value == 50).single(), number=COUNT
|
||||||
|
)
|
||||||
|
enumerable = timeit.timeit(
|
||||||
|
lambda: Enumerable(TestModel, values).where(lambda x: x.tm.value == 50).single(), number=COUNT
|
||||||
|
)
|
||||||
|
|
||||||
|
print("Complex where single")
|
||||||
|
print(f"d: {default}s")
|
||||||
|
print(f"i: {iterable}s")
|
||||||
|
print(f"e: {enumerable}s")
|
||||||
|
|
||||||
|
self.assertLess(default, enumerable)
|
||||||
|
self.assertLess(default, iterable)
|
||||||
27
unittests/unittests_query/query_test_suite.py
Normal file
27
unittests/unittests_query/query_test_suite.py
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import unittest
|
||||||
|
|
||||||
|
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(SequenceTestCase))
|
||||||
|
self.addTests(loader.loadTestsFromTestCase(EnumerableTestCase))
|
||||||
|
self.addTests(loader.loadTestsFromTestCase(EnumerableQueryTestCase))
|
||||||
|
self.addTests(loader.loadTestsFromTestCase(IterableTestCase))
|
||||||
|
self.addTests(loader.loadTestsFromTestCase(IterableQueryTestCase))
|
||||||
|
|
||||||
|
def run(self, *args):
|
||||||
|
super().run(*args)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
runner = unittest.TextTestRunner()
|
||||||
|
runner.run(QueryTestSuite())
|
||||||
31
unittests/unittests_query/sequence_test_case.py
Normal file
31
unittests/unittests_query/sequence_test_case.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import unittest
|
||||||
|
|
||||||
|
from cpl.query.enumerable import Enumerable
|
||||||
|
from cpl.query.extension.list import List
|
||||||
|
from cpl.query.collection import Iterable
|
||||||
|
|
||||||
|
|
||||||
|
class SequenceTestCase(unittest.TestCase):
|
||||||
|
def test_to_list(self):
|
||||||
|
_list = List().extend(range(0, 100))
|
||||||
|
enumerable = Enumerable.range(0, 100)
|
||||||
|
iterable = Iterable(int, list(range(0, 100)))
|
||||||
|
|
||||||
|
self.assertEqual(enumerable.to_list(), _list.to_list())
|
||||||
|
self.assertEqual(iterable.to_list(), _list.to_list())
|
||||||
|
|
||||||
|
def test_to_enumerable(self):
|
||||||
|
_list = List().extend(range(0, 100))
|
||||||
|
enumerable = Enumerable.range(0, 100)
|
||||||
|
iterable = Iterable(int, list(range(0, 100)))
|
||||||
|
|
||||||
|
self.assertEqual(type(_list.to_enumerable()), type(enumerable))
|
||||||
|
self.assertEqual(type(iterable.to_enumerable()), type(enumerable))
|
||||||
|
|
||||||
|
def test_to_iterable(self):
|
||||||
|
_list = List().extend(range(0, 100))
|
||||||
|
enumerable = Enumerable.range(0, 100)
|
||||||
|
iterable = Iterable(int, list(range(0, 100)))
|
||||||
|
|
||||||
|
self.assertEqual(type(_list.to_iterable()), type(iterable))
|
||||||
|
self.assertEqual(type(enumerable.to_iterable()), type(iterable))
|
||||||
43
unittests/unittests_query/unittests_query.json
Normal file
43
unittests/unittests_query/unittests_query.json
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"Project": {
|
||||||
|
"Name": "unittest_query",
|
||||||
|
"Version": {
|
||||||
|
"Major": "2024",
|
||||||
|
"Minor": "7",
|
||||||
|
"Micro": "0"
|
||||||
|
},
|
||||||
|
"Author": "",
|
||||||
|
"AuthorEmail": "",
|
||||||
|
"Description": "",
|
||||||
|
"LongDescription": "",
|
||||||
|
"URL": "",
|
||||||
|
"CopyrightDate": "",
|
||||||
|
"CopyrightName": "",
|
||||||
|
"LicenseName": "",
|
||||||
|
"LicenseDescription": "",
|
||||||
|
"Dependencies": [
|
||||||
|
"cpl-core>=2024.6.2024.07.0",
|
||||||
|
"cpl-query>=2024.6.2024.07.0"
|
||||||
|
],
|
||||||
|
"PythonVersion": ">=3.10.4",
|
||||||
|
"PythonPath": {},
|
||||||
|
"Classifiers": [],
|
||||||
|
"DevDependencies": []
|
||||||
|
},
|
||||||
|
"Build": {
|
||||||
|
"ProjectType": "library",
|
||||||
|
"SourcePath": "",
|
||||||
|
"OutputPath": "../../dist",
|
||||||
|
"Main": "unittest_query.main",
|
||||||
|
"EntryPoint": "unittest_query",
|
||||||
|
"IncludePackageData": false,
|
||||||
|
"Included": [],
|
||||||
|
"Excluded": [
|
||||||
|
"*/__pycache__",
|
||||||
|
"*/logs",
|
||||||
|
"*/tests"
|
||||||
|
],
|
||||||
|
"PackageData": {},
|
||||||
|
"ProjectReferences": []
|
||||||
|
}
|
||||||
|
}
|
||||||
0
unittests/unittests_shared/__init__.py
Normal file
0
unittests/unittests_shared/__init__.py
Normal file
97
unittests/unittests_shared/cli_commands.py
Normal file
97
unittests/unittests_shared/cli_commands.py
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
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, is_dev=False, output=False):
|
||||||
|
if package is None:
|
||||||
|
cls._run("install", output=output)
|
||||||
|
return
|
||||||
|
|
||||||
|
cls._run("install", package, "--dev" if is_dev else "", 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, is_dev=False, output=False):
|
||||||
|
args = []
|
||||||
|
if is_dev:
|
||||||
|
args.append("--dev")
|
||||||
|
|
||||||
|
if project is None:
|
||||||
|
cls._run("run", *args, output=output)
|
||||||
|
return
|
||||||
|
cls._run("run", project, *args, output=output)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def start(cls, is_dev=False, output=False):
|
||||||
|
args = []
|
||||||
|
if is_dev:
|
||||||
|
args.append("--dev")
|
||||||
|
|
||||||
|
cls._run("start", *args, output=output)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def uninstall(cls, package: str, is_dev=False, output=False):
|
||||||
|
cls._run("uninstall", package, "--dev" if is_dev else "", output=output)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def update(cls, output=False):
|
||||||
|
cls._run("update", output=output)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def version(cls) -> str:
|
||||||
|
return cls._run_with_output("version")
|
||||||
42
unittests/unittests_shared/unittests_shared.json
Normal file
42
unittests/unittests_shared/unittests_shared.json
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"Project": {
|
||||||
|
"Name": "unittest_shared",
|
||||||
|
"Version": {
|
||||||
|
"Major": "2024",
|
||||||
|
"Minor": "7",
|
||||||
|
"Micro": "0"
|
||||||
|
},
|
||||||
|
"Author": "",
|
||||||
|
"AuthorEmail": "",
|
||||||
|
"Description": "",
|
||||||
|
"LongDescription": "",
|
||||||
|
"URL": "",
|
||||||
|
"CopyrightDate": "",
|
||||||
|
"CopyrightName": "",
|
||||||
|
"LicenseName": "",
|
||||||
|
"LicenseDescription": "",
|
||||||
|
"Dependencies": [
|
||||||
|
"cpl-core>=2024.6.2024.07.0"
|
||||||
|
],
|
||||||
|
"PythonVersion": ">=3.10.4",
|
||||||
|
"PythonPath": {},
|
||||||
|
"Classifiers": [],
|
||||||
|
"DevDependencies": []
|
||||||
|
},
|
||||||
|
"Build": {
|
||||||
|
"ProjectType": "library",
|
||||||
|
"SourcePath": "",
|
||||||
|
"OutputPath": "../../dist",
|
||||||
|
"Main": "unittest_shared.main",
|
||||||
|
"EntryPoint": "unittest_shared",
|
||||||
|
"IncludePackageData": false,
|
||||||
|
"Included": [],
|
||||||
|
"Excluded": [
|
||||||
|
"*/__pycache__",
|
||||||
|
"*/logs",
|
||||||
|
"*/tests"
|
||||||
|
],
|
||||||
|
"PackageData": {},
|
||||||
|
"ProjectReferences": []
|
||||||
|
}
|
||||||
|
}
|
||||||
0
unittests/unittests_translation/__init__.py
Normal file
0
unittests/unittests_translation/__init__.py
Normal file
7
unittests/unittests_translation/translation/de.json
Normal file
7
unittests/unittests_translation/translation/de.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"main": {
|
||||||
|
"text": {
|
||||||
|
"hello_world": "Hallo Welt"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7
unittests/unittests_translation/translation/en.json
Normal file
7
unittests/unittests_translation/translation/en.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"main": {
|
||||||
|
"text": {
|
||||||
|
"hello_world": "Hello World"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
58
unittests/unittests_translation/translation_test_case.py
Normal file
58
unittests/unittests_translation/translation_test_case.py
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
import os
|
||||||
|
import unittest
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from cpl.translation import TranslationService, TranslatePipe, TranslationSettings
|
||||||
|
from unittests_cli.constants import TRANSLATION_PATH
|
||||||
|
|
||||||
|
|
||||||
|
class TranslationTestCase(unittest.TestCase):
|
||||||
|
def __init__(self, methodName: str):
|
||||||
|
unittest.TestCase.__init__(self, methodName)
|
||||||
|
self._translation: Optional[TranslationService] = None
|
||||||
|
self._translate: Optional[TranslatePipe] = None
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
os.chdir(os.path.abspath(TRANSLATION_PATH))
|
||||||
|
self._translation = TranslationService()
|
||||||
|
settings = TranslationSettings(["de", "en"], "en")
|
||||||
|
self._translation.load_by_settings(settings)
|
||||||
|
self._translation.set_default_lang("de")
|
||||||
|
self._translate = TranslatePipe(self._translation)
|
||||||
|
|
||||||
|
def cleanUp(self): ...
|
||||||
|
|
||||||
|
def test_service(self):
|
||||||
|
self.assertEqual("Hallo Welt", self._translation.translate("main.text.hello_world"))
|
||||||
|
self._translation.set_lang("en")
|
||||||
|
self.assertEqual("Hello World", self._translation.translate("main.text.hello_world"))
|
||||||
|
with self.assertRaises(KeyError) as ctx:
|
||||||
|
self._translation.translate("main.text.hallo_welt")
|
||||||
|
|
||||||
|
self.assertTrue(type(ctx.exception) == KeyError)
|
||||||
|
self.assertIn("Translation main.text.hallo_welt not found", str(ctx.exception))
|
||||||
|
|
||||||
|
with self.assertRaises(FileNotFoundError) as ctx:
|
||||||
|
self._translation.load("DE")
|
||||||
|
|
||||||
|
self.assertTrue(type(ctx.exception) == FileNotFoundError)
|
||||||
|
|
||||||
|
with self.assertRaises(KeyError) as ctx:
|
||||||
|
self._translation.set_lang("DE")
|
||||||
|
|
||||||
|
self.assertTrue(type(ctx.exception) == KeyError)
|
||||||
|
|
||||||
|
with self.assertRaises(KeyError) as ctx:
|
||||||
|
self._translation.set_default_lang("DE")
|
||||||
|
|
||||||
|
self.assertTrue(type(ctx.exception) == KeyError)
|
||||||
|
|
||||||
|
def test_pipe(self):
|
||||||
|
self.assertEqual("Hallo Welt", self._translate.transform("main.text.hello_world"))
|
||||||
|
self._translation.set_lang("en")
|
||||||
|
self.assertEqual("Hello World", self._translate.transform("main.text.hello_world"))
|
||||||
|
with self.assertRaises(KeyError) as ctx:
|
||||||
|
self._translation.translate("main.text.hallo_welt")
|
||||||
|
|
||||||
|
self.assertTrue(type(ctx.exception) == KeyError)
|
||||||
|
self.assertIn("Translation main.text.hallo_welt not found", str(ctx.exception))
|
||||||
22
unittests/unittests_translation/translation_test_suite.py
Normal file
22
unittests/unittests_translation/translation_test_suite.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import unittest
|
||||||
|
from typing import Optional
|
||||||
|
from unittest import TestResult
|
||||||
|
|
||||||
|
from unittests_translation.translation_test_case import TranslationTestCase
|
||||||
|
|
||||||
|
|
||||||
|
class TranslationTestSuite(unittest.TestSuite):
|
||||||
|
def __init__(self):
|
||||||
|
unittest.TestSuite.__init__(self)
|
||||||
|
|
||||||
|
loader = unittest.TestLoader()
|
||||||
|
self._result: Optional[TestResult] = None
|
||||||
|
self._is_online = True
|
||||||
|
|
||||||
|
active_tests = [TranslationTestCase]
|
||||||
|
|
||||||
|
for test in active_tests:
|
||||||
|
self.addTests(loader.loadTestsFromTestCase(test))
|
||||||
|
|
||||||
|
def run(self, *args):
|
||||||
|
self._result = super().run(*args)
|
||||||
45
unittests/unittests_translation/unittests_translation.json
Normal file
45
unittests/unittests_translation/unittests_translation.json
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
"Project": {
|
||||||
|
"Name": "unittests_translation",
|
||||||
|
"Version": {
|
||||||
|
"Major": "2024",
|
||||||
|
"Minor": "7",
|
||||||
|
"Micro": "0"
|
||||||
|
},
|
||||||
|
"Author": "",
|
||||||
|
"AuthorEmail": "",
|
||||||
|
"Description": "",
|
||||||
|
"LongDescription": "",
|
||||||
|
"URL": "",
|
||||||
|
"CopyrightDate": "",
|
||||||
|
"CopyrightName": "",
|
||||||
|
"LicenseName": "",
|
||||||
|
"LicenseDescription": "",
|
||||||
|
"Dependencies": [
|
||||||
|
"cpl-core>=2024.6.2024.07.0",
|
||||||
|
"cpl-translation>=2024.6.2024.07.0"
|
||||||
|
],
|
||||||
|
"DevDependencies": [
|
||||||
|
"cpl-cli>=2024.6.2024.07.0"
|
||||||
|
],
|
||||||
|
"PythonVersion": ">=3.10.4",
|
||||||
|
"PythonPath": {},
|
||||||
|
"Classifiers": []
|
||||||
|
},
|
||||||
|
"Build": {
|
||||||
|
"ProjectType": "unittest",
|
||||||
|
"SourcePath": "",
|
||||||
|
"OutputPath": "../../dist",
|
||||||
|
"Main": "unittests_translation.main",
|
||||||
|
"EntryPoint": "unittests_translation",
|
||||||
|
"IncludePackageData": false,
|
||||||
|
"Included": [],
|
||||||
|
"Excluded": [
|
||||||
|
"*/__pycache__",
|
||||||
|
"*/logs",
|
||||||
|
"*/tests"
|
||||||
|
],
|
||||||
|
"PackageData": {},
|
||||||
|
"ProjectReferences": []
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user