main
py 95 lines 2.5 KB
Raw
1 from __future__ import annotations
2
3 import sys
4 from pathlib import Path
5
6 import pytest
7
8 PROJECT_ROOT = Path(__file__).resolve().parents[1]
9 if str(PROJECT_ROOT) not in sys.path:
10 sys.path.insert(0, str(PROJECT_ROOT))
11
12 from helpers.dirty_json import DirtyJson
13
14
15 @pytest.mark.parametrize(
16 ("payload", "expected"),
17 [
18 (
19 '{"tool_name":"x","tool_args":{}}',
20 {"tool_name": "x", "tool_args": {}},
21 ),
22 ("[1, 2, 3]", [1, 2, 3]),
23 ],
24 )
25 def test_completed_true_when_root_is_explicitly_closed(payload, expected) -> None:
26 parser = DirtyJson()
27
28 assert parser.parse(payload) == expected
29 assert parser.completed is True
30
31
32 def test_completed_false_when_root_hits_eof_before_closing() -> None:
33 parser = DirtyJson()
34
35 assert parser.parse('{"tool_name":"x","tool_args":{}') == {
36 "tool_name": "x",
37 "tool_args": {},
38 }
39 assert parser.completed is False
40
41
42 def test_completed_remains_true_after_trailing_content() -> None:
43 parser = DirtyJson()
44
45 assert parser.feed('{"tool_name":"x","tool_args":{}}') == {
46 "tool_name": "x",
47 "tool_args": {},
48 }
49 assert parser.completed is True
50
51 assert parser.feed(" trailing noise") == {
52 "tool_name": "x",
53 "tool_args": {},
54 }
55
56 assert parser.completed is True
57
58
59 def test_value_keeps_unescaped_markdown_quotes_until_structural_delimiter() -> None:
60 payload = (
61 "{\n"
62 ' "tool_name": "response",\n'
63 ' "tool_args": {\n'
64 ' "text": "The rule:\\n\\n> *"'
65 'Create a child AGENTS.md when a folder becomes a boundary."'
66 '*\\n\\nAdding `css/AGENTS.md` that says *"'
67 'this folder contains CSS"'
68 '* is duplication."\n'
69 " }\n"
70 "}"
71 )
72
73 parsed = DirtyJson.parse_string(payload)
74
75 assert parsed["tool_args"] == {
76 "text": (
77 "The rule:\n\n"
78 '> *"Create a child AGENTS.md when a folder becomes a boundary."*\n\n'
79 'Adding `css/AGENTS.md` that says *"this folder contains CSS"* is duplication.'
80 )
81 }
82
83
84 def test_value_keeps_unescaped_quotes_on_single_line() -> None:
85 parsed = DirtyJson.parse_string(
86 '{"text":"He said "hello" before closing","ok":true}'
87 )
88
89 assert parsed == {"text": 'He said "hello" before closing', "ok": True}
90
91
92 def test_value_can_still_end_before_quoted_key_when_comma_is_missing() -> None:
93 parsed = DirtyJson.parse_string('{"first":"one" "second":"two"}')
94
95 assert parsed == {"first": "one", "second": "two"}