@@ -16,146 +16,146 @@ def create_mock_event_source(data_chunks: list[bytes]) -> EventSource:
1616 event_source = MagicMock (spec = EventSource )
1717 response = AsyncMock ()
1818 event_source .response = response
19-
19+
2020 async def mock_aiter_bytes () -> AsyncIterator [bytes ]:
2121 for chunk in data_chunks :
2222 yield chunk
23-
23+
2424 response .aiter_bytes = mock_aiter_bytes
2525 return event_source
2626
2727
2828async def test_compliant_aiter_sse_handles_unicode_line_separators ():
2929 """Test that compliant_aiter_sse correctly handles U+2028 and U+2029 characters."""
30-
30+
3131 # Simulate SSE data with U+2028 in JSON content
3232 # The server sends: event: message\ndata: {"text":"Hello\u2028World"}\n\n
3333 test_data = [
34- b' event: message\n ' ,
34+ b" event: message\n " ,
3535 b'data: {"text":"Hello' ,
36- b' \xe2 \x80 \xa8 ' , # UTF-8 encoding of U+2028
36+ b" \xe2 \x80 \xa8 " , # UTF-8 encoding of U+2028
3737 b'World"}\n ' ,
38- b' \n ' ,
38+ b" \n " ,
3939 ]
40-
40+
4141 event_source = create_mock_event_source (test_data )
42-
42+
4343 # Collect events
4444 events = [event async for event in compliant_aiter_sse (event_source )]
45-
45+
4646 # Should receive one message event
4747 assert len (events ) == 1
4848 assert events [0 ].event == "message"
4949 # The U+2028 should be preserved in the data
50- assert ' \u2028 ' in events [0 ].data
50+ assert " \u2028 " in events [0 ].data
5151 assert events [0 ].data == '{"text":"Hello\u2028 World"}'
5252
5353
5454async def test_compliant_aiter_sse_handles_paragraph_separator ():
5555 """Test that compliant_aiter_sse correctly handles U+2029 (PARAGRAPH SEPARATOR)."""
56-
56+
5757 # Simulate SSE data with U+2029
5858 test_data = [
59- b' event: test\n data: Line1' ,
60- b' \xe2 \x80 \xa9 ' , # UTF-8 encoding of U+2029
61- b' Line2\n \n ' ,
59+ b" event: test\n data: Line1" ,
60+ b" \xe2 \x80 \xa9 " , # UTF-8 encoding of U+2029
61+ b" Line2\n \n " ,
6262 ]
63-
63+
6464 event_source = create_mock_event_source (test_data )
65-
65+
6666 events = [event async for event in compliant_aiter_sse (event_source )]
67-
67+
6868 assert len (events ) == 1
6969 assert events [0 ].event == "test"
7070 # U+2029 should be preserved, not treated as a newline
71- assert ' \u2029 ' in events [0 ].data
72- assert events [0 ].data == ' Line1\u2029 Line2'
71+ assert " \u2029 " in events [0 ].data
72+ assert events [0 ].data == " Line1\u2029 Line2"
7373
7474
7575async def test_compliant_aiter_sse_handles_crlf ():
7676 """Test that compliant_aiter_sse correctly handles \\ r\\ n line endings."""
77-
77+
7878 # Simulate SSE data with CRLF line endings
7979 test_data = [
80- b' event: message\r \n ' ,
81- b' data: test data\r \n ' ,
82- b' \r \n ' ,
80+ b" event: message\r \n " ,
81+ b" data: test data\r \n " ,
82+ b" \r \n " ,
8383 ]
84-
84+
8585 event_source = create_mock_event_source (test_data )
86-
86+
8787 events = [event async for event in compliant_aiter_sse (event_source )]
88-
88+
8989 assert len (events ) == 1
9090 assert events [0 ].event == "message"
9191 assert events [0 ].data == "test data"
9292
9393
9494async def test_compliant_aiter_sse_handles_split_utf8 ():
9595 """Test that compliant_aiter_sse handles UTF-8 characters split across chunks."""
96-
96+
9797 # Split a UTF-8 emoji (🎉 = \xf0\x9f\x8e\x89) across chunks
9898 test_data = [
99- b' event: message\n ' ,
100- b' data: Party ' ,
101- b' \xf0 \x9f ' , # First half of emoji
102- b' \x8e \x89 ' , # Second half of emoji
103- b' time!\n \n ' ,
99+ b" event: message\n " ,
100+ b" data: Party " ,
101+ b" \xf0 \x9f " , # First half of emoji
102+ b" \x8e \x89 " , # Second half of emoji
103+ b" time!\n \n " ,
104104 ]
105-
105+
106106 event_source = create_mock_event_source (test_data )
107-
107+
108108 events = [event async for event in compliant_aiter_sse (event_source )]
109-
109+
110110 assert len (events ) == 1
111111 assert events [0 ].event == "message"
112112 assert events [0 ].data == "Party 🎉 time!"
113113
114114
115115async def test_compliant_aiter_sse_handles_multiple_events ():
116116 """Test that compliant_aiter_sse correctly handles multiple SSE events."""
117-
117+
118118 # Multiple events with problematic Unicode
119119 test_data = [
120- b' event: first\n data: Hello\xe2 \x80 \xa8 World\n \n ' ,
121- b' event: second\n data: Test\xe2 \x80 \xa9 Data\n \n ' ,
122- b' data: No event name\n \n ' ,
120+ b" event: first\n data: Hello\xe2 \x80 \xa8 World\n \n " ,
121+ b" event: second\n data: Test\xe2 \x80 \xa9 Data\n \n " ,
122+ b" data: No event name\n \n " ,
123123 ]
124-
124+
125125 event_source = create_mock_event_source (test_data )
126-
126+
127127 events = [event async for event in compliant_aiter_sse (event_source )]
128-
128+
129129 assert len (events ) == 3
130-
130+
131131 assert events [0 ].event == "first"
132- assert ' \u2028 ' in events [0 ].data
133-
132+ assert " \u2028 " in events [0 ].data
133+
134134 assert events [1 ].event == "second"
135- assert ' \u2029 ' in events [1 ].data
136-
135+ assert " \u2029 " in events [1 ].data
136+
137137 # Default event type is "message"
138138 assert events [2 ].event == "message"
139139 assert events [2 ].data == "No event name"
140140
141141
142142async def test_compliant_aiter_sse_handles_split_crlf ():
143143 """Test that \r at end of chunk followed by \n in next chunk is treated as one newline."""
144-
144+
145145 # Test case where \r is at the end of one chunk and \n starts the next
146146 # This should be treated as a single CRLF line ending, not two separate newlines
147147 test_data = [
148- b' event: test\r ' , # \r at end of chunk
149- b' \n data: line1\r ' , # \n at start of next chunk, then another \r at end
150- b' \n data: line2\n \n ' , # \n at start, completing the CRLF
148+ b" event: test\r " , # \r at end of chunk
149+ b" \n data: line1\r " , # \n at start of next chunk, then another \r at end
150+ b" \n data: line2\n \n " , # \n at start, completing the CRLF
151151 ]
152-
152+
153153 event_source = create_mock_event_source (test_data )
154-
154+
155155 events = [event async for event in compliant_aiter_sse (event_source )]
156-
156+
157157 # Should get exactly one event with both data lines
158158 assert len (events ) == 1
159159 assert events [0 ].event == "test"
160160 # The SSE decoder concatenates multiple data fields with \n
161- assert events [0 ].data == "line1\n line2"
161+ assert events [0 ].data == "line1\n line2"
0 commit comments