diff --git a/src/flext_tests/_utilities/_matchers/_result.py b/src/flext_tests/_utilities/_matchers/_result.py index a1505d24..7857c1ff 100644 --- a/src/flext_tests/_utilities/_matchers/_result.py +++ b/src/flext_tests/_utilities/_matchers/_result.py @@ -313,9 +313,7 @@ def ok_validate_type[TResult: t.Tests.TestResultValue]( @staticmethod @overload - def ok[TResult: t.Tests.TestResultValue]( - result: core_p.ResultView[TResult], - ) -> TResult: ... + def ok[TResult](result: core_p.ResultView[TResult]) -> TResult: ... @staticmethod @overload @@ -324,12 +322,15 @@ def ok[TResult: t.Tests.TestResultValue]( ) -> TResult | t.Tests.TestobjectSerializable: ... @staticmethod - def ok[TResult: t.Tests.TestResultValue]( + def ok[TResult]( result: core_p.ResultView[TResult], **kwargs: t.Tests.MatcherKwargValue ) -> TResult | t.Tests.TestobjectSerializable: # mro-j47u: matchers observe the protocol and preserve source identity. if not kwargs: return FlextTestsResultUtilitiesMixin.assert_success(result) + structured_result = cast( + "core_p.ResultView[t.Tests.TestResultValue]", result + ) try: params = m.Tests.OkParams.model_validate(kwargs) except c.EXC_BASIC_TYPE as exc: @@ -337,7 +338,7 @@ def ok[TResult: t.Tests.TestResultValue]( raise ValueError(msg) from exc result_value: t.Tests.TestResultValue = ( FlextTestsResultUtilitiesMixin.assert_success( - result, error_msg=params.msg + structured_result, error_msg=params.msg ) ) result_value, extracted_payload = ( diff --git a/tests/unit/_matchers_parts/results.py b/tests/unit/_matchers_parts/results.py index bd5035db..51abcded 100644 --- a/tests/unit/_matchers_parts/results.py +++ b/tests/unit/_matchers_parts/results.py @@ -5,6 +5,7 @@ from typing import assert_type import pytest +from pydantic import BaseModel from flext_core import p as core_p from flext_core import r as core_r @@ -31,6 +32,20 @@ def test_ok_preserves_generic_result_payload(self) -> None: tm.ok(r[t.JsonMapping].ok({"meta": {"id": "x"}}), path="meta.id"), eq="x" ) + def test_ok_preserves_arbitrary_result_payload(self) -> None: + """The no-matcher overload accepts payloads outside the matcher union.""" + + class Payload(BaseModel): + value: str + + payload = Payload(value="typed") + result = core_r[Payload].ok(payload) + + resolved = tm.ok(result) + + assert_type(resolved, Payload) + tm.that(resolved, eq=payload) + def test_assert_result_success_fails(self) -> None: """Test tm.ok() with failed result.""" result: core_p.Result[str] = r[str].fail("error")