logic-engine / tests /pipeline_engine /test_protocol.py
ghostdrive1's picture
Upload folder using huggingface_hub
116524e verified
Raw
History Blame Contribute Delete
4.09 kB
"""Unit tests for StepProtocol and SampleResult."""
from __future__ import annotations
import pytest
from pipeline import SampleResult, StepContext, StepProtocol
# ---------------------------------------------------------------------------
# Helper objects
# ---------------------------------------------------------------------------
class ValidStep:
requires = frozenset({"a"})
provides = frozenset({"b"})
def __call__(self, ctx: StepContext) -> StepContext:
return ctx
class ValidStepWithPlainSets:
requires = {"a"} # plain set, not frozenset
provides = {"b"}
def __call__(self, ctx: StepContext) -> StepContext:
return ctx
class MissingRequires:
provides = frozenset({"b"})
def __call__(self, ctx: StepContext) -> StepContext:
return ctx
class MissingProvides:
requires = frozenset({"a"})
def __call__(self, ctx: StepContext) -> StepContext:
return ctx
class MissingCall:
requires = frozenset({"a"})
provides = frozenset({"b"})
class EmptyStep:
"""Valid step with empty requires/provides (e.g. a pure side-effect step)."""
requires = frozenset()
provides = frozenset()
def __call__(self, ctx: StepContext) -> StepContext:
return ctx
# ---------------------------------------------------------------------------
# StepProtocol
# ---------------------------------------------------------------------------
@pytest.mark.unit
class TestStepProtocol:
def test_valid_step_passes_isinstance(self):
assert isinstance(ValidStep(), StepProtocol)
def test_valid_step_with_plain_sets_passes_isinstance(self):
# AbstractSet[str] accepts both set and frozenset
assert isinstance(ValidStepWithPlainSets(), StepProtocol)
def test_empty_requires_provides_is_valid(self):
assert isinstance(EmptyStep(), StepProtocol)
def test_missing_requires_fails_isinstance(self):
assert not isinstance(MissingRequires(), StepProtocol)
def test_missing_provides_fails_isinstance(self):
assert not isinstance(MissingProvides(), StepProtocol)
def test_missing_call_fails_isinstance(self):
assert not isinstance(MissingCall(), StepProtocol)
def test_plain_object_fails_isinstance(self):
assert not isinstance(object(), StepProtocol)
def test_none_fails_isinstance(self):
assert not isinstance(None, StepProtocol)
# ---------------------------------------------------------------------------
# SampleResult
# ---------------------------------------------------------------------------
@pytest.mark.unit
class TestSampleResult:
def test_basic_construction(self):
ctx = StepContext(sample="s")
r = SampleResult(sample="s", output=ctx, error=None, failed_at=None)
assert r.sample == "s"
assert r.output is ctx
assert r.error is None
assert r.failed_at is None
def test_cause_defaults_to_none(self):
r = SampleResult(sample="s", output=None, error=None, failed_at=None)
assert r.cause is None
def test_is_mutable(self):
r = SampleResult(sample="s", output=None, error=None, failed_at=None)
exc = RuntimeError("oops")
r.error = exc
r.failed_at = "SomeStep"
assert r.error is exc
assert r.failed_at == "SomeStep"
def test_failure_result(self):
exc = RuntimeError("boom")
r = SampleResult(sample="x", output=None, error=exc, failed_at="BoomStep")
assert r.output is None
assert r.error is exc
assert r.failed_at == "BoomStep"
def test_branch_failure_has_cause(self):
inner = RuntimeError("inner")
from pipeline import BranchError
outer = BranchError([inner])
r = SampleResult(
sample="x", output=None, error=outer, failed_at="Branch", cause=inner
)
assert r.cause is inner
assert r.failed_at == "Branch"