File size: 2,942 Bytes
31c8075
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
from datetime import timedelta

import pytest
from pydantic import ValidationError

from arena.models import (
    CodebaseArchive,
    Criteria,
    Run,
    RunEvent,
    RunRequest,
    ValidationCheck,
    ValidationReport,
    utc_now,
)


def test_run_view_exposes_prompt_state_without_rejoin_token() -> None:
    request = RunRequest(
        prompt="Build a small FastAPI app",
        criteria=[Criteria(text="pytest must pass")],
        user_tests=["uv run pytest"],
    )
    run = Run(
        id="run-1",
        prompt=request.prompt,
        criteria=request.criteria,
        user_tests=request.user_tests,
        rejoin_token="r" * 24,
        validation_checks=[
            ValidationCheck(
                id="check-1",
                name="tests",
                command="uv run pytest",
                source="user",
            )
        ],
    )

    view = run.to_view()

    assert view.id == "run-1"
    assert view.prompt == "Build a small FastAPI app"
    assert view.criteria[0].text == "pytest must pass"
    assert view.validation_checks[0].source == "user"
    assert not hasattr(view, "rejoin_token")


def test_run_view_orders_events_by_created_at() -> None:
    later = utc_now() + timedelta(seconds=5)
    earlier = utc_now()
    run = Run(
        id="run-1",
        prompt="Build a CLI",
        rejoin_token="r" * 24,
        events=[
            RunEvent(id="event-2", message="Implemented CLI", created_at=later),
            RunEvent(id="event-1", message="Planned tasks", created_at=earlier),
        ],
    )

    view = run.to_view()

    assert [event.id for event in view.events] == ["event-1", "event-2"]


def test_completed_run_requires_validation_report() -> None:
    with pytest.raises(ValidationError):
        Run(
            id="run-1",
            prompt="Build a CLI",
            rejoin_token="r" * 24,
            status="completed",
        )

    run = Run(
        id="run-1",
        prompt="Build a CLI",
        rejoin_token="r" * 24,
        status="completed",
        validation_report=ValidationReport(run_id="run-1", passed=True, summary="ok"),
        codebase_archive=CodebaseArchive(pointer="local-archive://run-1", file_count=3, size_bytes=1024),
    )

    assert run.validation_report is not None


def test_completed_run_requires_codebase_archive() -> None:
    with pytest.raises(ValidationError):
        Run(
            id="run-1",
            prompt="Build a CLI",
            rejoin_token="r" * 24,
            status="completed",
            validation_report=ValidationReport(run_id="run-1", passed=True, summary="ok"),
        )


def test_run_rejects_validation_report_for_different_run() -> None:
    with pytest.raises(ValidationError):
        Run(
            id="run-1",
            prompt="Build a CLI",
            rejoin_token="r" * 24,
            validation_report=ValidationReport(run_id="run-2", passed=True, summary="ok"),
        )