Skip to content

Commit bb094cb

Browse files
committed
added test for appfactory and some refactoring
1 parent a8638bb commit bb094cb

File tree

3 files changed

+120
-19
lines changed

3 files changed

+120
-19
lines changed

ellar/core/factory.py

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from ellar.core import Config
1414
from ellar.core.main import App
1515
from ellar.core.modules import ModuleBase
16-
from ellar.core.modules.ref import ModuleTemplateRef, create_module_ref_factor
16+
from ellar.core.modules.ref import create_module_ref_factor
1717
from ellar.di import EllarInjector, ProviderConfig
1818
from ellar.reflect import reflect
1919

@@ -25,7 +25,7 @@
2525
class AppFactory:
2626
@classmethod
2727
def _read_all_module(
28-
cls, module: t.Type[ModuleBase]
28+
cls, module: t.Type[t.Union[ModuleBase, t.Any]]
2929
) -> t.Dict[t.Type, t.Type[ModuleBase]]:
3030
modules = reflect.get_metadata(MODULE_METADATA.MODULES, module) or []
3131
module_dependency = OrderedDict()
@@ -36,11 +36,14 @@ def _read_all_module(
3636

3737
@classmethod
3838
def _build_modules(
39-
cls, app_module: t.Type[ModuleBase], config: Config, injector: EllarInjector
39+
cls,
40+
app_module: t.Type[t.Union[ModuleBase, t.Any]],
41+
config: Config,
42+
injector: EllarInjector,
4043
) -> None:
4144
assert reflect.get_metadata(
4245
MODULE_WATERMARK, app_module
43-
), "Only ApplicationModule is allowed"
46+
), "Only Module is allowed"
4447

4548
module_dependency = [app_module] + list(
4649
cls._read_all_module(app_module).values()
@@ -56,19 +59,10 @@ def _build_modules(
5659
)
5760
injector.add_module(module_ref)
5861

59-
@classmethod
60-
def _run_module_application_ready(
61-
cls,
62-
modules: t.Dict[t.Type[ModuleBase], ModuleTemplateRef],
63-
app: App,
64-
) -> None:
65-
for _, module_ref in modules.items():
66-
module_ref.run_application_ready(app)
67-
6862
@classmethod
6963
def _create_app(
7064
cls,
71-
module: t.Type[ModuleBase],
65+
module: t.Type[t.Union[ModuleBase, t.Any]],
7266
global_guards: t.List[
7367
t.Union[t.Type["GuardCanActivate"], "GuardCanActivate"]
7468
] = None,
@@ -95,9 +89,6 @@ def _create_app(
9589
global_guards=global_guards,
9690
)
9791

98-
cls._run_module_application_ready(
99-
modules=injector.get_templating_modules(), app=app
100-
)
10192
return app
10293

10394
@classmethod
@@ -108,7 +99,7 @@ def create_app(
10899
t.Union["ModuleRouter", "ModuleMount", Mount, Host]
109100
] = tuple(),
110101
providers: t.Sequence[t.Union[t.Type, "ProviderConfig"]] = tuple(),
111-
modules: t.Sequence[t.Type] = (),
102+
modules: t.Sequence[t.Type[t.Union[ModuleBase, t.Any]]] = (),
112103
template_folder: t.Optional[str] = None,
113104
base_directory: t.Optional[str] = None,
114105
static_folder: str = "static",
@@ -131,7 +122,7 @@ def create_app(
131122
app_factory_module = type(f"Module{uuid4().hex[:6]}", (ModuleBase,), {})
132123
module(app_factory_module)
133124
return cls._create_app(
134-
t.cast(t.Type[ModuleBase], app_factory_module),
125+
module=app_factory_module,
135126
config_module=config_module,
136127
global_guards=global_guards,
137128
)

ellar/core/main.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,12 @@ def enable_versioning(
219219
**init_kwargs,
220220
)
221221

222+
def _run_module_application_ready(
223+
self,
224+
) -> None:
225+
for _, module_ref in self.injector.get_templating_modules().items():
226+
module_ref.run_application_ready(self)
227+
222228
def _finalize_app_initialization(self) -> None:
223229
self.injector.container.register_instance(self)
224230
self.injector.container.register_instance(Reflector())
@@ -228,6 +234,7 @@ def _finalize_app_initialization(self) -> None:
228234
IExecutionContext,
229235
ModuleProvider(ExecutionContext, scope={}, receive=None, send=None),
230236
)
237+
self._run_module_application_ready()
231238

232239
def add_exception_handler(
233240
self,
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
from starlette.routing import Host, Mount
2+
3+
from ellar.common import Module
4+
from ellar.core import AppFactory, Config, ModuleBase, TestClient
5+
from ellar.di import EllarInjector
6+
7+
from .sample import (
8+
AppAPIKey,
9+
ApplicationModule,
10+
ClassBaseController,
11+
create_tmp_template_and_static_dir,
12+
router,
13+
sub_domain,
14+
users,
15+
)
16+
17+
18+
@Module(modules=[ApplicationModule])
19+
class AModule:
20+
pass
21+
22+
23+
@Module(modules=(AModule,))
24+
class BModule:
25+
pass
26+
27+
28+
def test_factory__read_all_module():
29+
modules_dict = AppFactory._read_all_module(module=BModule)
30+
assert len(modules_dict) == 2
31+
assert list(modules_dict.values())[0] is AModule
32+
assert list(modules_dict.values())[1] is ApplicationModule
33+
34+
modules_dict = AppFactory._read_all_module(module=AModule)
35+
assert len(modules_dict) == 1
36+
assert list(modules_dict.values())[0] is ApplicationModule
37+
38+
modules_dict = AppFactory._read_all_module(module=ApplicationModule)
39+
assert len(modules_dict) == 0
40+
41+
42+
def test_factory__build_modules():
43+
config = Config()
44+
injector = EllarInjector()
45+
assert len(injector.get_modules()) == 0
46+
47+
AppFactory._build_modules(app_module=BModule, config=config, injector=injector)
48+
module_refs = injector.get_modules()
49+
assert len(module_refs) == 3
50+
51+
modules = [AModule, ApplicationModule, BModule]
52+
for k, v in module_refs.items():
53+
assert k in modules
54+
55+
56+
def test_factory_create_from_app_module():
57+
app = AppFactory.create_from_app_module(
58+
module=BModule,
59+
global_guards=[AppAPIKey],
60+
config_module="tests.test_application.settings",
61+
)
62+
assert app.get_guards() == [AppAPIKey]
63+
assert app.config.config_module == "tests.test_application.settings"
64+
65+
66+
def test_factory_create_app_dynamically_creates_module():
67+
app = AppFactory.create_app()
68+
first_module_ref = next(app.get_module_loaders())
69+
module_instance = first_module_ref.get_module_instance()
70+
assert isinstance(module_instance, ModuleBase)
71+
assert "ellar.core.factory.Module" in str(module_instance.__class__)
72+
73+
74+
def test_factory_create_app_works(tmpdir):
75+
create_tmp_template_and_static_dir(tmpdir)
76+
77+
@Module()
78+
class CModule:
79+
pass
80+
81+
app = AppFactory.create_app(
82+
modules=(CModule,),
83+
global_guards=[AppAPIKey],
84+
config_module="tests.test_application.settings",
85+
controllers=(ClassBaseController,),
86+
routers=[
87+
Host("{subdomain}.example.org", app=sub_domain),
88+
Mount("/users", app=users),
89+
router,
90+
],
91+
template_folder="templates",
92+
static_folder="statics",
93+
base_directory=tmpdir,
94+
)
95+
96+
client = TestClient(app)
97+
res = client.get("/static/example.txt")
98+
assert res.status_code == 200
99+
assert res.text == "<file content>"
100+
101+
template = app.jinja_environment.get_template("example.html")
102+
result = template.render()
103+
assert result == "<html>Hello World<html/>"

0 commit comments

Comments
 (0)