Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ using a familiar Arrange, Act, Evaluate pattern.
## Example

```python
from pyeval import dataset, Case, EqualsExpected, Contains
from pyeval import dataset, execute, Case, EqualsExpected, Contains


def uppercase_text(text: str) -> str:
Expand Down
32 changes: 32 additions & 0 deletions src/pyeval/_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,41 @@

@dataclass
class ExecutionResult:
"""The result of running a task via :func:`execute`.

Provides direct access to the task's output and the case inputs for use
in assertions or additional evaluations::

result = execute(my_func, case)

assert "expected substring" in result.output

result.evaluate(EqualsExpected())
"""

ctx: EvaluatorContext
failures: list[EvaluatorFailure] = field(default_factory=list)

@property
def output(self) -> Any:
"""The value returned by the task function."""
return self.ctx.output

@property
def inputs(self) -> Any:
"""The inputs passed to the task function, taken from the case."""
return self.ctx.inputs

@property
def expected_output(self) -> Any:
"""The expected output from the case, or ``None`` if not set."""
return self.ctx.expected_output

@property
def duration(self) -> float:
"""How long the task took to run, in seconds."""
return self.ctx.duration

def evaluate(self, evaluator: Evaluator) -> None:
results = _CURRENT_EVAL_RESULTS.get()
if results is None:
Expand Down
38 changes: 38 additions & 0 deletions tests/test_execution_result.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from pydantic_evals import Case

from pyeval import execute


def _identity(x):
return x


def test_output_returns_task_return_value():
case = Case(name="test", inputs="hello")
result = execute(_identity, case)
assert result.output == "hello"


def test_inputs_returns_case_inputs():
case = Case(name="test", inputs="hello")
result = execute(_identity, case)
assert result.inputs == "hello"


def test_expected_output_returns_case_expected_output():
case = Case(name="test", inputs="hello", expected_output="world")
result = execute(_identity, case)
assert result.expected_output == "world"


def test_expected_output_is_none_when_not_set():
case = Case(name="test", inputs="hello")
result = execute(_identity, case)
assert result.expected_output is None


def test_duration_is_a_float():
case = Case(name="test", inputs="hello")
result = execute(_identity, case)
assert isinstance(result.duration, float)
assert result.duration > 0
Loading