diff --git a/.gitignore b/.gitignore deleted file mode 100644 index bee8a64..0000000 --- a/.gitignore +++ /dev/null @@ -1 +0,0 @@ -__pycache__ diff --git a/tests/test_pager.py b/tests/test_pager.py deleted file mode 100644 index 18be310..0000000 --- a/tests/test_pager.py +++ /dev/null @@ -1,74 +0,0 @@ -"""Unit tests for pagination helpers in ``depicts.pager``. - -Covers page counting, slicing, page iteration, URL building, and Jinja init. -""" - -from __future__ import annotations - -from depicts.pager import Pagination, init_pager, url_for_other_page -from flask import Flask - - -def _make_app() -> Flask: - """Create a minimal Flask app with a paging route.""" - app = Flask(__name__) - - @app.get("/items/") - def items(category_id: int) -> str: # noqa: ARG001 - used via request - # Return a URL for a different page while preserving args. - return url_for_other_page(5) - - return app - - -def test_pagination_basic_properties() -> None: - """Compute total pages and prev/next boundaries.""" - p = Pagination(page=1, per_page=10, total_count=95) - assert p.pages == 10 - assert p.has_prev is False - assert p.has_next is True - - p2 = Pagination(page=10, per_page=10, total_count=95) - assert p2.pages == 10 - assert p2.has_prev is True - assert p2.has_next is False - - -def test_pagination_slice() -> None: - """Return the correct slice for a page window.""" - items = list(range(25)) - p = Pagination(page=2, per_page=10, total_count=len(items)) - assert p.slice(items) == list(range(10, 20)) - - -def test_iter_pages_first_middle_last() -> None: - """Iterate pages with ellipses represented by ``None`` when skipping.""" - p = Pagination(page=1, per_page=10, total_count=100) - pages = list(p.iter_pages()) - # First page shows early pages, ellipsis, then tail pages - assert pages == [1, 2, 3, 4, 5, 6, None, 9, 10] - - mid = Pagination(page=5, per_page=10, total_count=100) - # In the middle, defaults show all pages without gaps - assert list(mid.iter_pages()) == list(range(1, 11)) - - last = Pagination(page=10, per_page=10, total_count=100) - # Near the end, elide the early middle (3), keep a window around current - assert list(last.iter_pages()) == [1, 2, None, 4, 5, 6, 7, 8, 9, 10] - - -def test_url_for_other_page_preserves_args_and_view_args() -> None: - """Build a URL for another page preserving args.""" - app = _make_app() - with app.test_client() as client: - resp = client.get("/items/42?q=abc&page=3") - assert resp.status_code == 200 - # The route returns the URL generated for page=5 - assert resp.get_data(as_text=True) == "/items/42?q=abc&page=5" - - -def test_init_pager_registers_jinja_helper() -> None: - """Register the helper in the Jinja environment globals.""" - app = Flask(__name__) - init_pager(app) - assert app.jinja_env.globals["url_for_other_page"] is url_for_other_page diff --git a/tests/test_utils.py b/tests/test_utils.py deleted file mode 100644 index 2ec7136..0000000 --- a/tests/test_utils.py +++ /dev/null @@ -1,109 +0,0 @@ -"""Unit tests for the helpers in ``depicts.utils``. - -These tests cover common paths and a few edge cases to ensure -stable behavior across refactors. -""" - -from depicts import utils -from flask import Flask -import pytest - - -def test_ordinal() -> None: - """Convert integers to the expected English ordinals.""" - assert utils.ordinal(1) == "1st" - assert utils.ordinal(2) == "2nd" - assert utils.ordinal(3) == "3rd" - assert utils.ordinal(4) == "4th" - - -def test_chunk_basic() -> None: - """Chunk an iterable into fixed-size tuples with a remainder.""" - data = list(range(10)) - chunks = list(utils.chunk(data, 3)) - assert chunks == [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9,)] - - -def test_drop_start_success_and_failure() -> None: - """Drop a matching prefix and assert on missing prefix.""" - assert utils.drop_start("Category:Painting", "Category:") == "Painting" - with pytest.raises(AssertionError): - utils.drop_start("Painting", "Category:") - - -def test_drop_category_ns() -> None: - """Remove the "Category:" namespace from a string.""" - assert utils.drop_category_ns("Category:Portraits") == "Portraits" - - -def test_parse_sitelink() -> None: - """Decode sitelink by removing prefix, unquoting, and de-underscoring.""" - start = "https://en.wikipedia.org/wiki/" - s = "https://en.wikipedia.org/wiki/Hello_World%21" - assert utils.parse_sitelink(s, start) == "Hello World!" - - -def test_word_contains_letter() -> None: - """Detect whether a token contains at least one letter.""" - assert utils.word_contains_letter("abc123") is True - assert utils.word_contains_letter("12345") is False - assert utils.word_contains_letter("!!!") is False - - -def test_also_singular_main_plural_and_singular() -> None: - """Return both plural and singular when appropriate.""" - # plural should include both plural and singular - assert set(utils.also_singular_main("Dogs")) == {"Dogs", "Dog"} - # singular should return as-is - assert utils.also_singular_main("Dog") == ["Dog"] - - -def test_also_singular_gender_and_skip_names() -> None: - """Add gender-derived forms and honor the skip list.""" - # Adds gender-derived singulars - names = utils.also_singular("Women") - assert "Women" in names - assert "woman" in names - # Skips configured names - assert utils.also_singular("National Gallery") == [] - - -def test_wiki_url_capitalization_and_ns() -> None: - """Build proper MediaWiki URLs with capitalization and namespace.""" - # lowercase first letter should be capitalized, spaces become underscores - url = utils.wiki_url("example page", site="enwiki") - expected = "https://en.wikipedia.org/wiki/Example_page" - assert url == expected - # namespace prefix when provided - url_cat = utils.wiki_url("Portraits", site="commons", ns="Category") - expected_cat = "https://commons.wikimedia.org/wiki/Category:Portraits" - assert url_cat == expected_cat - - -def test_get_int_arg_present_and_missing() -> None: - """Parse integer query args and ignore missing/non-integer values.""" - app = Flask(__name__) - with app.test_request_context("/?page=10&foo=bar"): - assert utils.get_int_arg("page") == 10 - assert utils.get_int_arg("foo") is None - assert utils.get_int_arg("missing") is None - - -def test_format_time_precisions() -> None: - """Format time strings for multiple precision levels.""" - # Full date - assert utils.format_time("+1965-04-23T00:00:00Z", 11) == "23 April 1965" - # Month precision - assert utils.format_time("+1965-04-00T00:00:00Z", 10) == "April 1965" - # Year precision - assert utils.format_time("+1965-00-00T00:00:00Z", 9) == "1965" - # Decade precision - assert utils.format_time("+1960-00-00T00:00:00Z", 8) == "1960s" - # Century precision - assert utils.format_time("+1965-00-00T00:00:00Z", 7) == "20th century" - # Millennium precision - assert utils.format_time("+2001-00-00T00:00:00Z", 6) == "3rd millennium" - # Unparseable falls back to input - assert utils.format_time("not-a-date", 9) == "not-a-date" - # BC year with unknown month/day should still return year for precision 9 - assert utils.format_time("-0123-00-00T00:00:00Z", 9) == "-123"