Skip to content

Commit 1b4ed8a

Browse files
committed
Add safeguard tests for dealing with dataclasses
1 parent 2f64842 commit 1b4ed8a

1 file changed

Lines changed: 243 additions & 0 deletions

File tree

tests/test_dataclasses.py

Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
# SPDX-FileCopyrightText: 2025 Alexandre Gomes Gaigalas <alganet@gmail.com>
2+
#
3+
# SPDX-License-Identifier: ISC
4+
5+
from dataclasses import InitVar, dataclass, field
6+
from typing import Protocol
7+
8+
import apywire
9+
10+
11+
@dataclass
12+
class Config:
13+
host: str
14+
port: int
15+
16+
17+
@dataclass
18+
class App:
19+
config: Config
20+
name: str
21+
22+
23+
@dataclass
24+
class DefaultConfig:
25+
host: str = "localhost"
26+
port: int = 8080
27+
28+
29+
@dataclass
30+
class PostInitConfig:
31+
host: str
32+
port: int
33+
url: str = field(init=False)
34+
35+
def __post_init__(self) -> None:
36+
self.url = f"http://{self.host}:{self.port}"
37+
38+
39+
@dataclass
40+
class InitVarConfig:
41+
host: str
42+
port: int
43+
debug: InitVar[bool] = False
44+
mode: str = field(init=False)
45+
46+
def __post_init__(self, debug: bool) -> None:
47+
self.mode = "debug" if debug else "production"
48+
49+
50+
def test_dataclass_runtime() -> None:
51+
spec: apywire.Spec = {
52+
"tests.test_dataclasses.Config config": {
53+
"host": "localhost",
54+
"port": 8080,
55+
}
56+
}
57+
wired = apywire.Wiring(spec)
58+
config = wired.config()
59+
assert isinstance(config, Config)
60+
assert config.host == "localhost"
61+
assert config.port == 8080
62+
63+
64+
def test_dataclass_compiled() -> None:
65+
spec: apywire.Spec = {
66+
"tests.test_dataclasses.Config config": {
67+
"host": "localhost",
68+
"port": 8080,
69+
}
70+
}
71+
compiler = apywire.WiringCompiler(spec)
72+
code = compiler.compile()
73+
74+
class MockConfig(Protocol):
75+
def config(self) -> Config: ...
76+
77+
execd: dict[str, MockConfig] = {}
78+
exec(code, execd)
79+
80+
wired = execd["compiled"]
81+
config = wired.config()
82+
83+
assert isinstance(config, Config)
84+
assert config.host == "localhost"
85+
assert config.port == 8080
86+
87+
88+
def test_nested_dataclass_runtime() -> None:
89+
spec: apywire.Spec = {
90+
"tests.test_dataclasses.Config config": {
91+
"host": "localhost",
92+
"port": 8080,
93+
},
94+
"tests.test_dataclasses.App app": {
95+
"config": "{config}",
96+
"name": "MyApp",
97+
},
98+
}
99+
wired = apywire.Wiring(spec)
100+
app = wired.app()
101+
assert isinstance(app, App)
102+
assert isinstance(app.config, Config)
103+
assert app.config.host == "localhost"
104+
assert app.name == "MyApp"
105+
106+
107+
def test_nested_dataclass_compiled() -> None:
108+
spec: apywire.Spec = {
109+
"tests.test_dataclasses.Config config": {
110+
"host": "localhost",
111+
"port": 8080,
112+
},
113+
"tests.test_dataclasses.App app": {
114+
"config": "{config}",
115+
"name": "MyApp",
116+
},
117+
}
118+
compiler = apywire.WiringCompiler(spec)
119+
code = compiler.compile()
120+
121+
class MockApp(Protocol):
122+
def app(self) -> App: ...
123+
124+
execd: dict[str, MockApp] = {}
125+
exec(code, execd)
126+
127+
wired = execd["compiled"]
128+
app = wired.app()
129+
130+
assert isinstance(app, App)
131+
assert isinstance(app.config, Config)
132+
assert app.config.host == "localhost"
133+
assert app.name == "MyApp"
134+
135+
136+
def test_dataclass_default_runtime() -> None:
137+
spec: apywire.Spec = {"tests.test_dataclasses.DefaultConfig config": {}}
138+
wired = apywire.Wiring(spec)
139+
config = wired.config()
140+
assert isinstance(config, DefaultConfig)
141+
assert config.host == "localhost"
142+
assert config.port == 8080
143+
144+
145+
def test_dataclass_default_compiled() -> None:
146+
spec: apywire.Spec = {"tests.test_dataclasses.DefaultConfig config": {}}
147+
compiler = apywire.WiringCompiler(spec)
148+
code = compiler.compile()
149+
150+
class MockDefaultConfig(Protocol):
151+
def config(self) -> DefaultConfig: ...
152+
153+
execd: dict[str, MockDefaultConfig] = {}
154+
exec(code, execd)
155+
156+
wired = execd["compiled"]
157+
config = wired.config()
158+
159+
assert isinstance(config, DefaultConfig)
160+
assert config.host == "localhost"
161+
assert config.port == 8080
162+
163+
164+
def test_dataclass_post_init_runtime() -> None:
165+
spec: apywire.Spec = {
166+
"tests.test_dataclasses.PostInitConfig config": {
167+
"host": "localhost",
168+
"port": 8080,
169+
}
170+
}
171+
wired = apywire.Wiring(spec)
172+
config = wired.config()
173+
assert isinstance(config, PostInitConfig)
174+
assert config.host == "localhost"
175+
assert config.port == 8080
176+
assert config.url == "http://localhost:8080"
177+
178+
179+
def test_dataclass_post_init_compiled() -> None:
180+
spec: apywire.Spec = {
181+
"tests.test_dataclasses.PostInitConfig config": {
182+
"host": "localhost",
183+
"port": 8080,
184+
}
185+
}
186+
compiler = apywire.WiringCompiler(spec)
187+
code = compiler.compile()
188+
189+
class MockPostInitConfig(Protocol):
190+
def config(self) -> PostInitConfig: ...
191+
192+
execd: dict[str, MockPostInitConfig] = {}
193+
exec(code, execd)
194+
195+
wired = execd["compiled"]
196+
config = wired.config()
197+
198+
assert isinstance(config, PostInitConfig)
199+
assert config.host == "localhost"
200+
assert config.port == 8080
201+
assert config.url == "http://localhost:8080"
202+
203+
204+
def test_dataclass_init_var_runtime() -> None:
205+
spec: apywire.Spec = {
206+
"tests.test_dataclasses.InitVarConfig config": {
207+
"host": "localhost",
208+
"port": 8080,
209+
"debug": True,
210+
}
211+
}
212+
wired = apywire.Wiring(spec)
213+
config = wired.config()
214+
assert isinstance(config, InitVarConfig)
215+
assert config.host == "localhost"
216+
assert config.port == 8080
217+
assert config.mode == "debug"
218+
219+
220+
def test_dataclass_init_var_compiled() -> None:
221+
spec: apywire.Spec = {
222+
"tests.test_dataclasses.InitVarConfig config": {
223+
"host": "localhost",
224+
"port": 8080,
225+
"debug": True,
226+
}
227+
}
228+
compiler = apywire.WiringCompiler(spec)
229+
code = compiler.compile()
230+
231+
class MockInitVarConfig(Protocol):
232+
def config(self) -> InitVarConfig: ...
233+
234+
execd: dict[str, MockInitVarConfig] = {}
235+
exec(code, execd)
236+
237+
wired = execd["compiled"]
238+
config = wired.config()
239+
240+
assert isinstance(config, InitVarConfig)
241+
assert config.host == "localhost"
242+
assert config.port == 8080
243+
assert config.mode == "debug"

0 commit comments

Comments
 (0)