|
11 | 11 | from plugboard.component import Component, IOController |
12 | 12 | from plugboard.connector import AsyncioConnector, Connector, ConnectorBuilder |
13 | 13 | from plugboard.events import Event |
| 14 | +from plugboard.events.event import StopEvent |
14 | 15 | from plugboard.schemas import ConnectorSpec |
15 | 16 | from tests.conftest import zmq_connector_cls |
16 | 17 |
|
@@ -272,3 +273,106 @@ class _A(A): |
272 | 273 | assert getattr(a, "in_2", None) == 6 |
273 | 274 |
|
274 | 275 | await a.io.close() |
| 276 | + |
| 277 | + |
| 278 | +class B(Component): |
| 279 | + """B test component.""" |
| 280 | + |
| 281 | + io = IOController(inputs=["a", "b"], input_events=[EventTypeA, EventTypeB]) |
| 282 | + |
| 283 | + def __init__(self: _t.Self, *args: _t.Any, **kwargs: _t.Any) -> None: |
| 284 | + super().__init__(*args, **kwargs) |
| 285 | + self.hist_a: list[int] = [] |
| 286 | + self.hist_b: list[int] = [] |
| 287 | + |
| 288 | + async def step(self) -> None: |
| 289 | + """A test step.""" |
| 290 | + pass |
| 291 | + |
| 292 | + @EventTypeA.handler(populates_fields=["a"]) |
| 293 | + async def event_A_handler(self, evt: EventTypeA) -> None: |
| 294 | + """A test event handler.""" |
| 295 | + self.a = evt.data.x |
| 296 | + self.hist_a.append(self.a) |
| 297 | + |
| 298 | + @EventTypeB.handler(populates_fields=["b"]) |
| 299 | + async def event_B_handler(self, evt: EventTypeB) -> None: |
| 300 | + """A test event handler.""" |
| 301 | + self.b = evt.data.y |
| 302 | + self.hist_b.append(self.b) |
| 303 | + |
| 304 | + |
| 305 | +async def test_component_event_handlers_populates_fields( |
| 306 | + connector_builder: ConnectorBuilder, |
| 307 | +) -> None: |
| 308 | + """Test that event handlers can populate fields for components.""" |
| 309 | + b = B(name="b") |
| 310 | + |
| 311 | + assert b.io.event_field_coverage == { |
| 312 | + EventTypeA.safe_type(): ["a"], |
| 313 | + EventTypeB.safe_type(): ["b"], |
| 314 | + } |
| 315 | + |
| 316 | + assert b.io.dict() == { |
| 317 | + "namespace": "b", |
| 318 | + "inputs": ["a", "b"], |
| 319 | + "outputs": [], |
| 320 | + "input_events": [StopEvent.safe_type(), EventTypeA.safe_type(), EventTypeB.safe_type()], |
| 321 | + "output_events": [StopEvent.safe_type()], |
| 322 | + "event_field_coverage": { |
| 323 | + EventTypeA.safe_type(): ["a"], |
| 324 | + EventTypeB.safe_type(): ["b"], |
| 325 | + }, |
| 326 | + "initial_values": {}, |
| 327 | + } |
| 328 | + |
| 329 | + connectors = connector_builder.build_event_connectors([b]) |
| 330 | + event_connectors_map = {conn.spec.source.entity: conn for conn in connectors} |
| 331 | + |
| 332 | + await b.io.connect(connectors) |
| 333 | + |
| 334 | + assert b.hist_a == [] |
| 335 | + assert b.hist_b == [] |
| 336 | + assert getattr(b, "a", None) is None |
| 337 | + assert getattr(b, "b", None) is None |
| 338 | + |
| 339 | + chan_A = await event_connectors_map[EventTypeA.safe_type()].connect_send() |
| 340 | + chan_B = await event_connectors_map[EventTypeB.safe_type()].connect_send() |
| 341 | + |
| 342 | + evt_A = EventTypeA(data=EventTypeAData(x=2), source="test-driver") |
| 343 | + await chan_A.send(evt_A) |
| 344 | + await b.step() |
| 345 | + |
| 346 | + assert b.hist_a == [2] |
| 347 | + assert b.hist_b == [] |
| 348 | + assert getattr(b, "a", None) == 2 |
| 349 | + assert getattr(b, "b", None) is None |
| 350 | + |
| 351 | + evt_B = EventTypeB(data=EventTypeBData(y=4), source="test-driver") |
| 352 | + await chan_B.send(evt_B) |
| 353 | + await b.step() |
| 354 | + |
| 355 | + assert b.hist_a == [2] |
| 356 | + assert b.hist_b == [4] |
| 357 | + assert getattr(b, "a", None) == 2 |
| 358 | + assert getattr(b, "b", None) == 4 |
| 359 | + |
| 360 | + evt_A = EventTypeA(data=EventTypeAData(x=3), source="test-driver") |
| 361 | + await chan_A.send(evt_A) |
| 362 | + await b.step() |
| 363 | + |
| 364 | + assert b.hist_a == [2, 3] |
| 365 | + assert b.hist_b == [4] |
| 366 | + assert getattr(b, "a", None) == 3 |
| 367 | + assert getattr(b, "b", None) == 4 |
| 368 | + |
| 369 | + evt_B = EventTypeB(data=EventTypeBData(y=5), source="test-driver") |
| 370 | + await chan_B.send(evt_B) |
| 371 | + await b.step() |
| 372 | + |
| 373 | + assert b.hist_a == [2, 3] |
| 374 | + assert b.hist_b == [4, 5] |
| 375 | + assert getattr(b, "a", None) == 3 |
| 376 | + assert getattr(b, "b", None) == 5 |
| 377 | + |
| 378 | + await b.io.close() |
0 commit comments