From 2688ba0a1753ef7b7e8869e349018d5b120bef35 Mon Sep 17 00:00:00 2001 From: Sagar Date: Sat, 10 Oct 2026 22:56:01 +0530 Subject: [PATCH] Fix LineBuffer payload byte accounting --- spectator/writer/line_buffer.py | 7 +++++-- tests/writer/test_line_buffer.py | 28 +++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/spectator/writer/line_buffer.py b/spectator/writer/line_buffer.py index 35d1599..24cf339 100644 --- a/spectator/writer/line_buffer.py +++ b/spectator/writer/line_buffer.py @@ -2,7 +2,7 @@ class LineBuffer: - """Line buffer for Writers.""" + """Line buffer for Writers, sized in UTF-8 bytes including newline separators.""" def __init__(self, max_size: int) -> None: self._size: int = 0 @@ -14,8 +14,11 @@ def __len__(self) -> int: def append(self, line: str) -> bool: """Return value indicates whether the buffer should be flushed.""" + line_size = len(line.encode("utf-8")) + if self._lines: + self._size += 1 # Newline inserted between lines by flush(). self._lines.append(line) - self._size += len(line) + self._size += line_size return self._size >= self._max_size def flush(self) -> str: diff --git a/tests/writer/test_line_buffer.py b/tests/writer/test_line_buffer.py index 98373c1..32be25d 100644 --- a/tests/writer/test_line_buffer.py +++ b/tests/writer/test_line_buffer.py @@ -14,7 +14,7 @@ def test_all_methods(self): self.assertFalse(should_flush) should_flush = buffer.append("e") - self.assertEqual(5, len(buffer)) + self.assertEqual(6, len(buffer)) self.assertTrue(should_flush) self.assertEqual("abcd\ne", buffer.flush()) @@ -26,3 +26,29 @@ def test_all_methods(self): self.assertEqual("abcdefghij", buffer.flush()) self.assertEqual(0, len(buffer)) + + def test_flush_threshold_includes_newline_separators(self): + buffer = LineBuffer(7) + self.assertFalse(buffer.append("abc")) + self.assertTrue(buffer.append("def")) + self.assertEqual(7, len(buffer)) + self.assertEqual("abc\ndef", buffer.flush()) + + def test_size_matches_utf8_payload(self): + buffer = LineBuffer(6) + self.assertFalse(buffer.append("é")) + self.assertEqual(2, len(buffer)) + self.assertTrue(buffer.append("€")) + self.assertEqual(6, len(buffer)) + payload = buffer.flush() + self.assertEqual(6, len(payload.encode("utf-8"))) + self.assertEqual(0, len(buffer)) + self.assertFalse(buffer.append("abc")) + self.assertEqual(3, len(buffer)) + + def test_empty_lines_include_separators(self): + buffer = LineBuffer(1) + self.assertFalse(buffer.append("")) + self.assertTrue(buffer.append("")) + self.assertEqual(1, len(buffer)) + self.assertEqual("\n", buffer.flush())