Skip to content

Commit 93f8238

Browse files
chore(internal): add jsonl unit tests (#43)
1 parent 1c95dc2 commit 93f8238

File tree

1 file changed

+88
-0
lines changed

1 file changed

+88
-0
lines changed

Diff for: tests/decoders/test_jsonl.py

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
from __future__ import annotations
2+
3+
from typing import Any, Iterator, AsyncIterator
4+
from typing_extensions import TypeVar
5+
6+
import httpx
7+
import pytest
8+
9+
from gitpod._decoders.jsonl import JSONLDecoder, AsyncJSONLDecoder
10+
11+
_T = TypeVar("_T")
12+
13+
14+
@pytest.mark.asyncio
15+
@pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"])
16+
async def test_basic(sync: bool) -> None:
17+
def body() -> Iterator[bytes]:
18+
yield b'{"foo":true}\n'
19+
yield b'{"bar":false}\n'
20+
21+
iterator = make_jsonl_iterator(
22+
content=body(),
23+
sync=sync,
24+
line_type=object,
25+
)
26+
27+
assert await iter_next(iterator) == {"foo": True}
28+
assert await iter_next(iterator) == {"bar": False}
29+
30+
await assert_empty_iter(iterator)
31+
32+
33+
@pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"])
34+
async def test_new_lines_in_json(
35+
sync: bool,
36+
) -> None:
37+
def body() -> Iterator[bytes]:
38+
yield b'{"content":"Hello, world!\\nHow are you doing?"}'
39+
40+
iterator = make_jsonl_iterator(content=body(), sync=sync, line_type=object)
41+
42+
assert await iter_next(iterator) == {"content": "Hello, world!\nHow are you doing?"}
43+
44+
45+
@pytest.mark.parametrize("sync", [True, False], ids=["sync", "async"])
46+
async def test_multi_byte_character_multiple_chunks(
47+
sync: bool,
48+
) -> None:
49+
def body() -> Iterator[bytes]:
50+
yield b'{"content":"'
51+
# bytes taken from the string 'известни' and arbitrarily split
52+
# so that some multi-byte characters span multiple chunks
53+
yield b"\xd0"
54+
yield b"\xb8\xd0\xb7\xd0"
55+
yield b"\xb2\xd0\xb5\xd1\x81\xd1\x82\xd0\xbd\xd0\xb8"
56+
yield b'"}\n'
57+
58+
iterator = make_jsonl_iterator(content=body(), sync=sync, line_type=object)
59+
60+
assert await iter_next(iterator) == {"content": "известни"}
61+
62+
63+
async def to_aiter(iter: Iterator[bytes]) -> AsyncIterator[bytes]:
64+
for chunk in iter:
65+
yield chunk
66+
67+
68+
async def iter_next(iter: Iterator[_T] | AsyncIterator[_T]) -> _T:
69+
if isinstance(iter, AsyncIterator):
70+
return await iter.__anext__()
71+
return next(iter)
72+
73+
74+
async def assert_empty_iter(decoder: JSONLDecoder[Any] | AsyncJSONLDecoder[Any]) -> None:
75+
with pytest.raises((StopAsyncIteration, RuntimeError)):
76+
await iter_next(decoder)
77+
78+
79+
def make_jsonl_iterator(
80+
content: Iterator[bytes],
81+
*,
82+
sync: bool,
83+
line_type: type[_T],
84+
) -> JSONLDecoder[_T] | AsyncJSONLDecoder[_T]:
85+
if sync:
86+
return JSONLDecoder(line_type=line_type, raw_iterator=content, http_response=httpx.Response(200))
87+
88+
return AsyncJSONLDecoder(line_type=line_type, raw_iterator=to_aiter(content), http_response=httpx.Response(200))

0 commit comments

Comments
 (0)