Skip to content

Commit 45f4eac

Browse files
committed
fix(demo): inline ternary to fix mypy assignment type error
Also: - chore(pyproject): ignore E501 in tests - test(client): 16 with_raw_response tests (sync + async) - test(opencode): 7 ask_stream unit tests
1 parent 4c262fe commit 45f4eac

5 files changed

Lines changed: 420 additions & 4 deletions

File tree

demo.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@
5151
# 8. Code search
5252
print("\n[8] Searching text...")
5353
found = client.find_text("create_opencode")
54-
n = len(found) if isinstance(found, list) else "?"
55-
print(f" Found: {n}")
54+
print(f" Found: {len(found) if isinstance(found, list) else '?'}")
5655

5756
# 9. Send prompt (no LLM — queue only)
5857
print("\n[9] Sending prompt (no API key)...")
@@ -69,15 +68,23 @@
6968
# 10. Session context messages
7069
print("\n[10] Session messages...")
7170
ctx = client.v2_session_context(sid)
72-
items = ctx.get("data", []) if isinstance(ctx, dict) else ctx if isinstance(ctx, list) else []
71+
items = (
72+
ctx.get("data", [])
73+
if isinstance(ctx, dict)
74+
else ctx
75+
if isinstance(ctx, list)
76+
else []
77+
)
7378
print(f" Messages: {len(items)}")
7479

7580
# 11. Extra capabilities
7681
print("\n[11] Additional:")
7782
path = client.path_get()
7883
print(f" Working directory: {path.worktree}")
7984
cmds = client.command_list()
80-
print(f" Opencode commands: {len(cmds) if isinstance(cmds, list) else '?'}")
85+
print(
86+
f" Opencode commands: {len(cmds) if isinstance(cmds, list) else '?'}"
87+
)
8188
agents = client.app_agents()
8289
print(f" Agents: {len(agents) if isinstance(agents, list) else '?'}")
8390

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ select = ["E", "F", "I", "N", "W", "UP"]
6464

6565
[tool.ruff.lint.per-file-ignores]
6666
"src/opencode/_response_models.py" = ["N815"]
67+
"tests/*" = ["E501"]
6768

6869
[tool.mypy]
6970
python_version = "3.10"

tests/test_async_client.py

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from opencode._response_models import (
88
FileContentResponse,
99
HealthResponse,
10+
RawResponse,
1011
SessionResponse,
1112
V1SessionResponse,
1213
)
@@ -150,3 +151,114 @@ async def test_file_read() -> None:
150151
result = await client.file_read("/path/to/file.py")
151152
assert isinstance(result, FileContentResponse)
152153
assert result.content == "print('hello')"
154+
155+
156+
# ---------------------------------------------------------------------------
157+
# with_raw_response
158+
# ---------------------------------------------------------------------------
159+
160+
161+
@pytest.mark.asyncio
162+
async def test_with_raw_response_parsed_model() -> None:
163+
client = AsyncOpendcodeClient(
164+
base_url="http://localhost:9999",
165+
httpx_client=httpx.AsyncClient(
166+
transport=httpx.MockTransport(lambda _: httpx.Response(200, json={"ok": True}))
167+
),
168+
)
169+
with client.with_raw_response:
170+
raw = await client.health()
171+
assert isinstance(raw, RawResponse)
172+
assert isinstance(raw.parsed, HealthResponse)
173+
assert raw.parsed.ok is True
174+
175+
176+
@pytest.mark.asyncio
177+
async def test_with_raw_response_status_code() -> None:
178+
client = AsyncOpendcodeClient(
179+
base_url="http://localhost:9999",
180+
httpx_client=httpx.AsyncClient(
181+
transport=httpx.MockTransport(lambda _: httpx.Response(201, json={"ok": True}))
182+
),
183+
)
184+
with client.with_raw_response:
185+
raw = await client.health()
186+
assert raw.status_code == 201
187+
188+
189+
@pytest.mark.asyncio
190+
async def test_with_raw_response_headers() -> None:
191+
client = AsyncOpendcodeClient(
192+
base_url="http://localhost:9999",
193+
httpx_client=httpx.AsyncClient(
194+
transport=httpx.MockTransport(
195+
lambda _: httpx.Response(
196+
200, json={"ok": True}, headers={"x-custom": "test-val"}
197+
)
198+
)
199+
),
200+
)
201+
with client.with_raw_response:
202+
raw = await client.health()
203+
assert raw.headers["x-custom"] == "test-val"
204+
205+
206+
@pytest.mark.asyncio
207+
async def test_with_raw_response_204() -> None:
208+
client = AsyncOpendcodeClient(
209+
base_url="http://localhost:9999",
210+
httpx_client=httpx.AsyncClient(
211+
transport=httpx.MockTransport(lambda _: httpx.Response(204))
212+
),
213+
)
214+
with client.with_raw_response:
215+
raw = await client.v2_session_wait("ses_1")
216+
assert isinstance(raw, RawResponse)
217+
assert raw.status_code == 204
218+
assert raw.parsed is None
219+
220+
221+
@pytest.mark.asyncio
222+
async def test_with_raw_response_mode_resets() -> None:
223+
client = AsyncOpendcodeClient(
224+
base_url="http://localhost:9999",
225+
httpx_client=httpx.AsyncClient(
226+
transport=httpx.MockTransport(lambda _: httpx.Response(200, json={"ok": True}))
227+
),
228+
)
229+
with client.with_raw_response:
230+
raw = await client.health()
231+
assert isinstance(raw, RawResponse)
232+
normal = await client.health()
233+
assert isinstance(normal, HealthResponse)
234+
assert not isinstance(normal, RawResponse)
235+
236+
237+
@pytest.mark.asyncio
238+
async def test_with_raw_response_still_raises_error() -> None:
239+
client = AsyncOpendcodeClient(
240+
base_url="http://localhost:9999",
241+
httpx_client=httpx.AsyncClient(
242+
transport=httpx.MockTransport(
243+
lambda _: httpx.Response(500, json={"message": "boom"})
244+
)
245+
),
246+
)
247+
with client.with_raw_response:
248+
with pytest.raises(APIError) as exc:
249+
await client.health()
250+
assert exc.value.status == 500
251+
252+
253+
@pytest.mark.asyncio
254+
async def test_with_raw_response_cast_to_none() -> None:
255+
client = AsyncOpendcodeClient(
256+
base_url="http://localhost:9999",
257+
httpx_client=httpx.AsyncClient(
258+
transport=httpx.MockTransport(lambda _: httpx.Response(200, json={"foo": "bar"}))
259+
),
260+
)
261+
with client.with_raw_response:
262+
raw = await client.global_dispose()
263+
assert isinstance(raw, RawResponse)
264+
assert raw.parsed == {"foo": "bar"}

tests/test_client.py

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from opencode._response_models import (
88
FileContentResponse,
99
HealthResponse,
10+
RawResponse,
1011
SessionResponse,
1112
V1SessionResponse,
1213
)
@@ -123,3 +124,127 @@ def test_file_read() -> None:
123124
result = client.file_read("/path/to/file.py")
124125
assert isinstance(result, FileContentResponse)
125126
assert result.content == "print('hello')"
127+
128+
129+
# ---------------------------------------------------------------------------
130+
# with_raw_response
131+
# ---------------------------------------------------------------------------
132+
133+
134+
def test_with_raw_response_parsed_model() -> None:
135+
client = OpencodeClient(
136+
base_url="http://localhost:9999",
137+
httpx_client=httpx.Client(
138+
transport=httpx.MockTransport(lambda _: httpx.Response(200, json={"ok": True}))
139+
),
140+
)
141+
with client.with_raw_response:
142+
raw = client.health()
143+
assert isinstance(raw, RawResponse)
144+
assert isinstance(raw.parsed, HealthResponse)
145+
assert raw.parsed.ok is True
146+
147+
148+
def test_with_raw_response_status_code() -> None:
149+
client = OpencodeClient(
150+
base_url="http://localhost:9999",
151+
httpx_client=httpx.Client(
152+
transport=httpx.MockTransport(lambda _: httpx.Response(201, json={"ok": True}))
153+
),
154+
)
155+
with client.with_raw_response:
156+
raw = client.health()
157+
assert raw.status_code == 201
158+
159+
160+
def test_with_raw_response_headers() -> None:
161+
client = OpencodeClient(
162+
base_url="http://localhost:9999",
163+
httpx_client=httpx.Client(
164+
transport=httpx.MockTransport(
165+
lambda _: httpx.Response(
166+
200,
167+
json={"ok": True},
168+
headers={"x-custom": "test-val"},
169+
)
170+
)
171+
),
172+
)
173+
with client.with_raw_response:
174+
raw = client.health()
175+
assert raw.headers["x-custom"] == "test-val"
176+
177+
178+
def test_with_raw_response_content() -> None:
179+
client = OpencodeClient(
180+
base_url="http://localhost:9999",
181+
httpx_client=httpx.Client(
182+
transport=httpx.MockTransport(
183+
lambda _: httpx.Response(200, json={"ok": True})
184+
)
185+
),
186+
)
187+
with client.with_raw_response:
188+
raw = client.health()
189+
assert raw.content is not None
190+
assert b"ok" in raw.content
191+
192+
193+
def test_with_raw_response_204() -> None:
194+
client = OpencodeClient(
195+
base_url="http://localhost:9999",
196+
httpx_client=httpx.Client(
197+
transport=httpx.MockTransport(lambda _: httpx.Response(204))
198+
),
199+
)
200+
with client.with_raw_response:
201+
raw = client.v2_session_wait("ses_1")
202+
assert isinstance(raw, RawResponse)
203+
assert raw.status_code == 204
204+
assert raw.parsed is None
205+
206+
207+
def test_with_raw_response_mode_resets() -> None:
208+
client = OpencodeClient(
209+
base_url="http://localhost:9999",
210+
httpx_client=httpx.Client(
211+
transport=httpx.MockTransport(lambda _: httpx.Response(200, json={"ok": True}))
212+
),
213+
)
214+
# Inside context — returns RawResponse
215+
with client.with_raw_response:
216+
raw = client.health()
217+
assert isinstance(raw, RawResponse)
218+
# After context — returns normal model
219+
normal = client.health()
220+
assert isinstance(normal, HealthResponse)
221+
assert not isinstance(normal, RawResponse)
222+
223+
224+
def test_with_raw_response_still_raises_error() -> None:
225+
client = OpencodeClient(
226+
base_url="http://localhost:9999",
227+
httpx_client=httpx.Client(
228+
transport=httpx.MockTransport(
229+
lambda _: httpx.Response(500, json={"message": "boom"})
230+
)
231+
),
232+
)
233+
with client.with_raw_response:
234+
with pytest.raises(APIError) as exc:
235+
client.health()
236+
assert exc.value.status == 500
237+
238+
239+
def test_with_raw_response_cast_to_none() -> None:
240+
"""Methods without cast_to should still return RawResponse with raw parsed data."""
241+
client = OpencodeClient(
242+
base_url="http://localhost:9999",
243+
httpx_client=httpx.Client(
244+
transport=httpx.MockTransport(lambda _: httpx.Response(200, json={"foo": "bar"}))
245+
),
246+
)
247+
with client.with_raw_response:
248+
raw = client.global_dispose()
249+
assert isinstance(raw, RawResponse)
250+
assert raw.parsed == {"foo": "bar"}

0 commit comments

Comments
 (0)