Skip to content

Commit

Permalink
Add basic GenericApplication
Browse files Browse the repository at this point in the history
  • Loading branch information
tdg5 committed Jan 27, 2024
1 parent c5c9caa commit f0eef2b
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 0 deletions.
28 changes: 28 additions & 0 deletions service_oriented/application/generic_application.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from typing import Dict, Generic, TypeVar

from service_oriented.application.config import BaseConfig
from service_oriented.application.entry_point_spec import EntryPointSpec


C = TypeVar("C", bound=BaseConfig)
E = TypeVar("E", bound=EntryPointSpec)


class GenericApplication(Generic[C]):
def __init__(
self,
config: C,
entry_points: Dict[str, E],
):
self.config: C = config
self.entry_points: Dict[str, E] = entry_points

def run(self) -> None:
entry_point_name = self.config.entry_point
entry_point_spec = self.entry_points.get(entry_point_name)
if entry_point_spec is None:
raise RuntimeError(
f"No mapping found for entry point named '{entry_point_name}'"
)
entry_point = entry_point_spec.build(config=self.config)
entry_point.run()
99 changes: 99 additions & 0 deletions service_oriented_test/application/generic_application_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
from typing import Callable

import pytest

from service_oriented.application.config import BaseConfig
from service_oriented.application.entry_point_spec import EntryPointSpec
from service_oriented.application.generic_application import GenericApplication
from service_oriented_test.test_helpers import (
TEST_DEPLOYMENT_ENVIRONMENT,
TEST_ENTRY_POINT,
)


class Config(
BaseConfig,
env_nested_delimiter="__",
env_prefix="generic_application_test_",
):
pass


class CallbackEntryPoint:
def __init__(
self,
config: Config,
on_run_callback: Callable[[], None],
) -> None:
self.config = config
self.on_run_callback = on_run_callback

def run(self) -> None:
self.on_run_callback()


class Application(GenericApplication[Config]):
pass


def test_application_init() -> None:
config = Config(
deployment_environment=TEST_DEPLOYMENT_ENVIRONMENT,
entry_point=TEST_ENTRY_POINT,
)
entry_points = {
"other": EntryPointSpec(CallbackEntryPoint),
}
application = Application(
config=config,
entry_points=entry_points,
)
assert config == application.config
assert entry_points == application.entry_points


def test_application_run() -> None:
on_run_called = False

def on_run_callback() -> None:
nonlocal on_run_called
on_run_called = True

config = Config(
deployment_environment=TEST_DEPLOYMENT_ENVIRONMENT,
entry_point=TEST_ENTRY_POINT,
)
entry_points = {
TEST_ENTRY_POINT: EntryPointSpec(
CallbackEntryPoint,
on_run_callback=on_run_callback,
),
}
application = Application(
config=config,
entry_points=entry_points,
)

application.run()
assert on_run_called


def test_application_run_raises_for_unknown_entry_point() -> None:
config = Config(
deployment_environment=TEST_DEPLOYMENT_ENVIRONMENT,
entry_point="other",
)
entry_points = {
TEST_ENTRY_POINT: EntryPointSpec(CallbackEntryPoint),
}
application = Application(
config=config,
entry_points=entry_points,
)

with pytest.raises(RuntimeError) as exinfo:
application.run()

assert RuntimeError == exinfo.type
exception_message = str(exinfo.value)
assert "No mapping found for entry point named 'other'" == exception_message
1 change: 1 addition & 0 deletions whitelist.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
dirname
dotenv
exinfo
nonlocal
param
pydantic

0 comments on commit f0eef2b

Please sign in to comment.