fix(deck): address PR #759 round-3 review feedback

- Drop "(in-place)" from filter-helper docstrings; callers should
  consume the return value, mutation is an implementation detail.
- Document that deck_get_archived_stacks always returns cards (an
  archived stack without its cards has no audit value); point to
  description_max_length for size control.
- Document that deck_get_cards applies filtering client-side, so it
  is network-equivalent to deck_get_stack(include_cards=True).
- Pin the empty-list contract: a stack with all-archived cards and
  include_archived_cards=False yields cards == [] (loaded but empty),
  not cards is None (explicitly suppressed).
- Add explicit one-character-over-limit truncation test alongside the
  existing exact-boundary test.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Chris Coutinho
2026-05-03 01:09:54 +02:00
co-authored by Claude Opus 4.7
parent b7805c2180
commit a995155bd4
2 changed files with 44 additions and 3 deletions
+31
View File
@@ -122,6 +122,15 @@ def test_truncate_card_descriptions_at_exact_boundary():
assert cards[0].description == "x" * 100
def test_truncate_card_descriptions_one_over_limit():
"""A description one character over the limit triggers truncation."""
cards = [_make_card(1, "x" * 101)]
_truncate_card_descriptions(cards, 100)
assert cards[0].description is not None
assert len(cards[0].description) == 101 # 100 chars + ellipsis
assert cards[0].description.endswith("")
def test_truncate_card_descriptions_shorter_than_limit_no_ellipsis():
"""A description shorter than the limit must not have an ellipsis appended."""
cards = [_make_card(1, "hello")]
@@ -296,6 +305,28 @@ def test_apply_stack_filters_handles_none_cards():
assert result.cards is None
def test_apply_stack_filters_all_archived_yields_empty_list_not_none():
"""A stack whose cards are all archived yields cards == [], not None.
Pin the contract: include_cards=True with all cards filtered out
means "the stack was loaded but had nothing to show", which is
semantically distinct from include_cards=False (cards=None,
"explicitly suppressed"). Callers checking ``stack.cards is None``
can use that to distinguish the two states.
"""
stack = _make_stack(
cards=[_make_card(1, archived=True), _make_card(2, archived=True)]
)
result = _apply_stack_filters(
stack,
include_cards=True,
include_archived_cards=False,
description_max_length=None,
)
assert result.cards == []
assert result.cards is not None
# _apply_card_filters -------------------------------------------------------