| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152 |
- """
- Shared pytest fixtures and import setup for the seq_interp test suite.
- The source modules import themselves as ``seq_interp.src...`` — the name the
- Docker image mounts the tree under (``COPY services/seq-interp /app/seq_interp``).
- Locally the directory is ``seq-interp`` (with a hyphen), which is not a valid
- module name, so we register an in-process alias package ``seq_interp`` that
- points at the service root. This lets tests import the real source unchanged.
- """
- from __future__ import annotations
- import pathlib
- import sys
- import types
- import pytest
- SERVICE_ROOT = pathlib.Path(__file__).resolve().parents[1] # .../services/seq-interp
- if "seq_interp" not in sys.modules:
- _pkg = types.ModuleType("seq_interp")
- _pkg.__path__ = [str(SERVICE_ROOT)]
- sys.modules["seq_interp"] = _pkg
- class FakeSeq:
- """
- Minimal stand-in for a loaded pypulseq sequence, exposing only what
- ``Synchronizer.process`` touches: ``block_events`` and ``block_durations``.
- block_events layout (1-indexed, pypulseq order):
- [ ?, RF, GX, GY, GZ, ADC, EXT ]
- 0 1 2 3 4 5 6
- """
- def __init__(self, specs: list[dict]):
- self.block_events: dict[int, list[int]] = {}
- self.block_durations: dict[int, float] = {}
- for i, spec in enumerate(specs, start=1):
- ev = [0, 0, 0, 0, 0, 0, 0]
- if spec.get("rf"):
- ev[1] = 1
- if spec.get("adc"):
- ev[5] = 1
- self.block_events[i] = ev
- self.block_durations[i] = spec["dur"]
- @pytest.fixture
- def make_seq():
- """Factory: make_seq([{"rf": bool, "adc": bool, "dur": seconds}, ...])."""
- return FakeSeq
|