Skip to content

Commit

Permalink
Changes:
Browse files Browse the repository at this point in the history
- add extensions tests
- validate deprecation works
  • Loading branch information
devkral committed Nov 8, 2024
1 parent 5cf4d33 commit bb97e2c
Show file tree
Hide file tree
Showing 2 changed files with 197 additions and 38 deletions.
172 changes: 172 additions & 0 deletions tests/pluggables/test_extensions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
from typing import Optional

import pytest
from loguru import logger
from pydantic import BaseModel

from esmerald import Esmerald, Extension, Pluggable
from esmerald.exceptions import ImproperlyConfigured
from esmerald.types import DictAny


class MyNewPluggable: ...


class PluggableNoPlug(Extension): # pragma: no cover
def __init__(self, app: "Esmerald"):
super().__init__(app)
self.app = app


def test_raises_improperly_configured_for_subclass(test_client_factory):
with pytest.raises(ImproperlyConfigured) as raised:
Esmerald(routes=[], extensions={"test": MyNewPluggable})

assert raised.value.detail == (
"An extension must subclass from Extension, implement the ExtensionProtocol "
"as instance or being wrapped in a Pluggable."
)


def test_raises_improperly_configured_for_key_of_pluggables(test_client_factory):
with pytest.raises(ImproperlyConfigured) as raised:
Esmerald(routes=[], extensions={1: MyNewPluggable})

assert raised.value.detail == "Extension names should be in string format."


def test_raises_error_for_missing_extend(test_client_factory):
with pytest.raises(Exception): # noqa
Esmerald(
routes=[],
extensions={"test": Pluggable(PluggableNoPlug)},
)


class Config(BaseModel):
name: Optional[str]


class MyExtension(Extension):
def __init__(self, app: "Esmerald", config: Config):
super().__init__(app)
self.config = config

def extend(self, config: Config) -> None:
logger.info(f"Started extension with config name {config.name}")


def test_generates_pluggable():
app = Esmerald(
routes=[], extensions={"test": Pluggable(MyExtension, config=Config(name="my pluggable"))}
)

assert "test" in app.extensions


def test_generates_many_pluggables():
class LoggingExtension(Extension):
def __init__(self, app: "Esmerald", name):
super().__init__(app)
self.app = app
self.name = name

def extend(self, name) -> None:
logger.info(f"Started logging extension with name {name}")

class DatabaseExtension(Extension):
def __init__(self, app: "Esmerald", database):
super().__init__(app)
self.app = app
self.database = database

def extend(self, database) -> None:
logger.info(f"Started extension with database {database}")

app = Esmerald(
routes=[],
extensions={
"test": Pluggable(MyExtension, config=Config(name="my pluggable")),
"logging": Pluggable(LoggingExtension, name="my logging"),
"database": Pluggable(DatabaseExtension, database="my db"),
},
)

assert len(app.extensions.keys()) == 3


def test_start_extension_directly(test_client_factory):
class CustomExtension(Extension):
def __init__(self, app: Optional["Esmerald"] = None, **kwargs: DictAny):
super().__init__(app, **kwargs)

def extend(self, **kwargs) -> None:
app = kwargs.get("app")
config = kwargs.get("config")
logger.success(f"Started standalone plugging with the name: {config.name}")
app.extensions["custom"] = self

app = Esmerald(routes=[])
config = Config(name="standalone")
extension = CustomExtension()
extension.extend(app=app, config=config)

assert "custom" in app.extensions
assert isinstance(app.extensions["custom"], Extension)


def test_add_extension_manual(test_client_factory):
class CustomExtension(Extension):
def __init__(self, app: Optional["Esmerald"] = None, **kwargs: DictAny):
super().__init__(app, **kwargs)
self.app = app

def extend(self, config) -> None:
logger.success(f"Started plugging with the name: {config.name}")

self.app.add_extension("manual", self)

app = Esmerald(routes=[])
config = Config(name="manual")
extension = CustomExtension(app=app)
extension.extend(config=config)

assert "manual" in app.extensions
assert isinstance(app.extensions["manual"], Extension)


def test_add_standalone_extension(test_client_factory):
class CustomExtension:
def __init__(self, app: Optional["Esmerald"] = None, **kwargs: DictAny):
self.app = app
self.kwargs = kwargs

def extend(self, config) -> None:
logger.success(f"Started standalone plugging with the name: {config.name}")

self.app.add_extension("manual", self)

app = Esmerald(routes=[])
config = Config(name="manual")
extension = CustomExtension(app=app)
extension.extend(config=config)

assert "manual" in app.extensions
assert not isinstance(app.extensions["manual"], Extension)


def test_add_pluggable(test_client_factory):
class CustomExtension(Extension):
def __init__(self, app: Optional["Esmerald"] = None, **kwargs: DictAny):
super().__init__(app, **kwargs)
self.app = app

def extend(self, config) -> None:
logger.success(f"Started standalone plugging with the name: {config.name}")

app = Esmerald(routes=[])
config = Config(name="manual")
app.add_extension("manual", Pluggable(CustomExtension, config=config))

assert "manual" in app.extensions
assert isinstance(app.extensions["manual"], Extension)
63 changes: 25 additions & 38 deletions tests/pluggables/test_pluggables.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ def __init__(self, app: "Esmerald"):


def test_raises_improperly_configured_for_subclass(test_client_factory):
with pytest.raises(ImproperlyConfigured) as raised:
Esmerald(routes=[], extensions={"test": MyNewPluggable})
with pytest.warns(DeprecationWarning):
with pytest.raises(ImproperlyConfigured) as raised:
Esmerald(routes=[], pluggables={"test": MyNewPluggable})

assert raised.value.detail == (
"An extension must subclass from Extension, implement the ExtensionProtocol "
Expand All @@ -29,18 +30,20 @@ def test_raises_improperly_configured_for_subclass(test_client_factory):


def test_raises_improperly_configured_for_key_of_pluggables(test_client_factory):
with pytest.raises(ImproperlyConfigured) as raised:
Esmerald(routes=[], extensions={1: MyNewPluggable})
with pytest.warns(DeprecationWarning):
with pytest.raises(ImproperlyConfigured) as raised:
Esmerald(routes=[], pluggables={1: MyNewPluggable})

assert raised.value.detail == "Extension names should be in string format."


def test_raises_error_for_missing_extend(test_client_factory):
with pytest.raises(Exception): # noqa
Esmerald(
routes=[],
extensions={"test": Pluggable(PluggableNoPlug)},
)
with pytest.warns(DeprecationWarning):
with pytest.raises(Exception): # noqa
Esmerald(
routes=[],
pluggables={"test": Pluggable(PluggableNoPlug)},
)


class Config(BaseModel):
Expand All @@ -57,11 +60,14 @@ def extend(self, config: Config) -> None:


def test_generates_pluggable():
app = Esmerald(
routes=[], extensions={"test": Pluggable(MyExtension, config=Config(name="my pluggable"))}
)
with pytest.warns(DeprecationWarning):
app = Esmerald(
routes=[],
pluggables={"test": Pluggable(MyExtension, config=Config(name="my pluggable"))},
)

assert "test" in app.extensions
with pytest.warns(DeprecationWarning):
assert "test" in app.pluggables


def test_generates_many_pluggables():
Expand Down Expand Up @@ -91,31 +97,11 @@ def extend(self, database) -> None:
"database": Pluggable(DatabaseExtension, database="my db"),
},
)

assert len(app.extensions.keys()) == 3
with pytest.warns(DeprecationWarning):
assert len(app.pluggables.keys()) == 3


def test_start_extension_directly(test_client_factory):
class CustomExtension(Extension):
def __init__(self, app: Optional["Esmerald"] = None, **kwargs: DictAny):
super().__init__(app, **kwargs)

def extend(self, **kwargs) -> None:
app = kwargs.get("app")
config = kwargs.get("config")
logger.success(f"Started standalone plugging with the name: {config.name}")
app.extensions["custom"] = self

app = Esmerald(routes=[])
config = Config(name="standalone")
extension = CustomExtension()
extension.extend(app=app, config=config)

assert "custom" in app.extensions
assert isinstance(app.extensions["custom"], Extension)


def test_add_extension_(test_client_factory):
def test_add_pluggable(test_client_factory):
class CustomExtension(Extension):
def __init__(self, app: Optional["Esmerald"] = None, **kwargs: DictAny):
super().__init__(app, **kwargs)
Expand Down Expand Up @@ -155,7 +141,7 @@ def extend(self, config) -> None:
assert not isinstance(app.extensions["manual"], Extension)


def test_add_pluggable(test_client_factory):
def test_add_pluggable_manual(test_client_factory):
class CustomExtension(Extension):
def __init__(self, app: Optional["Esmerald"] = None, **kwargs: DictAny):
super().__init__(app, **kwargs)
Expand All @@ -166,7 +152,8 @@ def extend(self, config) -> None:

app = Esmerald(routes=[])
config = Config(name="manual")
app.add_extension("manual", Pluggable(CustomExtension, config=config))
with pytest.warns(DeprecationWarning):
app.add_pluggable("manual", Pluggable(CustomExtension, config=config))

assert "manual" in app.extensions
assert isinstance(app.extensions["manual"], Extension)

0 comments on commit bb97e2c

Please sign in to comment.