diff --git a/curtsies/formatstring.py b/curtsies/formatstring.py index e24d69c..97dff0d 100644 --- a/curtsies/formatstring.py +++ b/curtsies/formatstring.py @@ -663,6 +663,8 @@ def width_aware_splitlines(self, columns: int) -> Iterator["FmtStr"]: return self._width_aware_splitlines(columns) def _width_aware_splitlines(self, columns: int) -> Iterator["FmtStr"]: + if not self.chunks: + return splitter = self.chunks[0].splitter() chunks_of_line = [] width_of_line = 0 diff --git a/tests/test_fmtstr.py b/tests/test_fmtstr.py index a568780..0c6f5a0 100644 --- a/tests/test_fmtstr.py +++ b/tests/test_fmtstr.py @@ -469,6 +469,37 @@ def test_width_aware_splitlines(self) -> None: with self.assertRaises(ValueError): s.width_aware_splitlines(1) + def test_width_aware_splitlines_empty(self) -> None: + for s in (FmtStr(), fmtstr(""), fmtstr("\x1b[0m"), fmtstr("\x1b[34m")): + for columns in (2, 80): + with self.subTest(s=repr(s), columns=columns): + self.assertEqual(list(s.width_aware_splitlines(columns)), []) + + def test_width_aware_splitlines_empty_narrow_columns(self) -> None: + for s in (FmtStr(), fmtstr(""), fmtstr("\x1b[0m"), fmtstr("\x1b[34m")): + for columns in (-1, 0, 1): + with self.subTest(s=repr(s), columns=columns): + with self.assertRaises(ValueError): + s.width_aware_splitlines(columns) + + def test_width_aware_splitlines_colorized_log(self) -> None: + log = "\x1b[34mDEBUG \x1b[0mmessage\r\n\x1b[0m" + for columns, expected in ( + (80, [blue("DEBUG ") + "message"]), + (8, [blue("DEBUG ") + "me", fmtstr("ssage")]), + ): + with self.subTest(columns=columns): + lines = [ + wrapped + for line in log.splitlines() + for wrapped in fmtstr(line).width_aware_splitlines(columns) + ] + self.assertEqual(lines, expected) + + def test_width_aware_splitlines_zero_width_text(self) -> None: + s = blue("\u0300") + self.assertEqual(list(s.width_aware_splitlines(2)), [s]) + def test_width_at_offset(self) -> None: self.assertEqual(fmtstr("abEcdef").width_at_offset(0), 0) self.assertEqual(fmtstr("abEcdef").width_at_offset(2), 2)