From c1c5cfb41a80950c2486fa595a7b4b6e91c090d2 Mon Sep 17 00:00:00 2001 From: Slipstream Date: Sun, 15 Jun 2025 18:12:10 -0600 Subject: [PATCH] Add Paginator utility and tests (#92) --- disagreement/utils.py | 39 +++++++++++++++++++++++++++++++++++++++ docs/introduction.md | 1 + tests/test_paginator.py | 23 +++++++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 tests/test_paginator.py diff --git a/disagreement/utils.py b/disagreement/utils.py index 3ca9be3..c9a5fe3 100644 --- a/disagreement/utils.py +++ b/disagreement/utils.py @@ -71,3 +71,42 @@ async def message_pager( remaining -= 1 if remaining == 0: return + + +class Paginator: + """Helper to split text into pages under a character limit.""" + + def __init__(self, limit: int = 2000) -> None: + self.limit = limit + self._pages: list[str] = [] + self._current = "" + + def add_line(self, line: str) -> None: + """Add a line of text to the paginator.""" + if len(line) > self.limit: + if self._current: + self._pages.append(self._current) + self._current = "" + for i in range(0, len(line), self.limit): + chunk = line[i : i + self.limit] + if len(chunk) == self.limit: + self._pages.append(chunk) + else: + self._current = chunk + return + + if not self._current: + self._current = line + elif len(self._current) + 1 + len(line) <= self.limit: + self._current += "\n" + line + else: + self._pages.append(self._current) + self._current = line + + @property + def pages(self) -> list[str]: + """Return the accumulated pages.""" + pages = list(self._pages) + if self._current: + pages.append(self._current) + return pages diff --git a/docs/introduction.md b/docs/introduction.md index fa2bbbe..c2748f1 100644 --- a/docs/introduction.md +++ b/docs/introduction.md @@ -14,6 +14,7 @@ A Python library for interacting with the Discord API, with a focus on bot devel - Built-in caching layer - Experimental voice support - Helpful error handling utilities +- Paginator utility for splitting long messages ## Installation diff --git a/tests/test_paginator.py b/tests/test_paginator.py new file mode 100644 index 0000000..aa207b5 --- /dev/null +++ b/tests/test_paginator.py @@ -0,0 +1,23 @@ +from disagreement.utils import Paginator + + +def test_paginator_single_page(): + p = Paginator(limit=10) + p.add_line("hi") + p.add_line("there") + assert p.pages == ["hi\nthere"] + + +def test_paginator_splits_pages(): + p = Paginator(limit=10) + p.add_line("12345") + p.add_line("67890") + assert p.pages == ["12345", "67890"] + p.add_line("xyz") + assert p.pages == ["12345", "67890\nxyz"] + + +def test_paginator_handles_long_line(): + p = Paginator(limit=5) + p.add_line("abcdef") + assert p.pages == ["abcde", "f"]