Skip to content

Commit 3ef92ae

Browse files
committed
test(schema): cover experimental v2 bindings
1 parent c794422 commit 3ef92ae

2 files changed

Lines changed: 67 additions & 3 deletions

File tree

tests/test_gen_all.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from acp.schema import ReadTextFileRequest
44
from scripts.gen_all import resolve_ref, schema_source_paths
5+
from scripts.gen_meta import generate_meta
56
from scripts.gen_schema import generate_schema
67

78

@@ -13,6 +14,7 @@ def test_generated_field_descriptions_are_introspectable() -> None:
1314

1415
def test_resolve_ref_accepts_schema_release_tags() -> None:
1516
assert resolve_ref("schema-v1.16.0") == "refs/tags/schema-v1.16.0"
17+
assert resolve_ref("schema-v2.0.0-alpha.3") == "refs/tags/schema-v2.0.0-alpha.3"
1618

1719

1820
def test_resolve_ref_keeps_legacy_version_tags() -> None:
@@ -27,6 +29,12 @@ def test_schema_release_tags_prefer_v1_schema_layout() -> None:
2729
)
2830

2931

32+
def test_v2_generation_uses_v2_schema_layout() -> None:
33+
assert schema_source_paths("refs/tags/schema-v2.0.0-alpha.3", 2) == (
34+
("schema/v2/schema.unstable.json", "schema/v2/meta.unstable.json"),
35+
)
36+
37+
3038
def test_legacy_tags_keep_legacy_schema_layout_first() -> None:
3139
assert schema_source_paths("refs/tags/v0.13.6")[0] == (
3240
"schema/schema.unstable.json",
@@ -49,8 +57,16 @@ def test_parse_args_can_skip_format(monkeypatch) -> None:
4957

5058

5159
def test_codegen_check_is_clean_and_read_only() -> None:
52-
output = Path("src/acp/schema.py")
53-
before = output.read_bytes()
60+
outputs = (
61+
Path("src/acp/meta.py"),
62+
Path("src/acp/schema.py"),
63+
Path("src/acp/experimental/v2/meta.py"),
64+
Path("src/acp/experimental/v2/schema.py"),
65+
)
66+
before = {output: output.read_bytes() for output in outputs}
5467

5568
assert generate_schema(check=True)
56-
assert output.read_bytes() == before
69+
assert generate_meta(check=True)
70+
assert generate_schema(check=True, protocol_version=2)
71+
assert generate_meta(check=True, protocol_version=2)
72+
assert {output: output.read_bytes() for output in outputs} == before

tests/test_v2_schema.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import pytest
2+
from pydantic import ValidationError
3+
4+
from acp.experimental.v2 import PROTOCOL_VERSION
5+
from acp.experimental.v2.schema import (
6+
AgentMessageChunk,
7+
OtherSessionUpdate,
8+
TextContentBlock,
9+
UpdateSessionNotification,
10+
)
11+
12+
13+
def test_v2_models_fill_protocol_discriminators() -> None:
14+
update = AgentMessageChunk(
15+
message_id="message-1",
16+
content=TextContentBlock(text="hello"),
17+
)
18+
19+
assert PROTOCOL_VERSION == 2
20+
assert update.model_dump(by_alias=True, exclude_none=True) == {
21+
"sessionUpdate": "agent_message_chunk",
22+
"messageId": "message-1",
23+
"content": {"type": "text", "text": "hello"},
24+
}
25+
26+
27+
def test_v2_open_union_preserves_unknown_updates() -> None:
28+
notification = UpdateSessionNotification.model_validate({
29+
"sessionId": "session-1",
30+
"update": {"sessionUpdate": "_vendor_status", "status": "waiting"},
31+
})
32+
33+
assert isinstance(notification.update, OtherSessionUpdate)
34+
assert notification.model_dump(by_alias=True, exclude_none=True)["update"] == {
35+
"sessionUpdate": "_vendor_status",
36+
"status": "waiting",
37+
}
38+
39+
40+
def test_v2_open_union_rejects_malformed_known_updates() -> None:
41+
with pytest.raises(ValidationError):
42+
UpdateSessionNotification.model_validate({
43+
"sessionId": "session-1",
44+
"update": {
45+
"sessionUpdate": "agent_message_chunk",
46+
"content": {"type": "text", "text": "hello"},
47+
},
48+
})

0 commit comments

Comments
 (0)