sea affinity prose: reinsert the (rank icon) parenthetical + pluralize the NC verb (they/yo leave, he/she/it leaves) — TDD
Two user follow-ups to the personalized affinity prose: (1) the corner-rank + suit-icon abbrev rides the card name again (e.g. 'the Queen of Pentacles (Q <i class=fa-crown></i>)'), mirroring SIG_READY — majors render just the numeral, e.g. '(I)'. (2) The NC clause conjugates the subject verb: they + yo are treated as PLURAL -> 'they leave' / 'yo leave behind'; the singular he/she/it keep the 3rd-person 'leaves'. TDD: per-role-clauses test updated to 'they leave'; new yo-pluralizes + he-keeps-leaves cases; a with-abbrev PC case asserting the full rank+icon parenthetical. 51 drama+epic ITs green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -167,17 +167,29 @@ class GameEvent(models.Model):
|
|||||||
# into the gamer's Role-correlated Celtic position, woven into a
|
# into the gamer's Role-correlated Celtic position, woven into a
|
||||||
# role-specific clause. The actor's @handle is prepended by the
|
# role-specific clause. The actor's @handle is prepended by the
|
||||||
# template; pronouns resolve via the actor (subj/poss). "The " is
|
# template; pronouns resolve via the actor (subj/poss). "The " is
|
||||||
# stripped so a levity/gravity qualifier butts the proper name.
|
# stripped so a levity/gravity qualifier butts the proper name; the
|
||||||
|
# corner-rank + suit-icon abbrev rides the card name (mirrors SIG_READY).
|
||||||
card = d.get("card_name", "a card").replace("The ", "", 1)
|
card = d.get("card_name", "a card").replace("The ", "", 1)
|
||||||
|
corner_rank = d.get("corner_rank", "")
|
||||||
|
suit_icon = d.get("suit_icon", "")
|
||||||
|
if corner_rank:
|
||||||
|
icon_html = f' <i class="fa-solid {suit_icon}"></i>' if suit_icon else ""
|
||||||
|
abbrev = f" ({corner_rank}{icon_html})"
|
||||||
|
else:
|
||||||
|
abbrev = ""
|
||||||
|
card_ref = f"the {card}{abbrev}"
|
||||||
subj, _, poss = _actor_pronouns(self.actor)
|
subj, _, poss = _actor_pronouns(self.actor)
|
||||||
|
# they + yo are PLURAL → the plural verb "leave" (not "leaves"); the
|
||||||
|
# singular he/she/it keep the 3rd-person "leaves" (user-spec).
|
||||||
|
leaves = "leave" if subj in ("they", "yo") else "leaves"
|
||||||
clause = {
|
clause = {
|
||||||
"PC": f"the {card} crowns all {poss} loftiest illusions",
|
"PC": f"{card_ref} crowns all {poss} loftiest illusions",
|
||||||
"NC": f"the {card} traces all the narratives {subj} leaves behind",
|
"NC": f"{card_ref} traces all the narratives {subj} {leaves} behind",
|
||||||
"EC": f"the {card} always looms before {poss} calling",
|
"EC": f"{card_ref} always looms before {poss} calling",
|
||||||
"SC": f"the {card} covers all {poss} righteous conduct",
|
"SC": f"{card_ref} covers all {poss} righteous conduct",
|
||||||
"AC": f"the {card} always crosses {poss} sinister connections",
|
"AC": f"{card_ref} always crosses {poss} sinister connections",
|
||||||
"BC": f"the {card} lays all {poss} foundational work",
|
"BC": f"{card_ref} lays all {poss} foundational work",
|
||||||
}.get(d.get("role", ""), f"the {card} marks {poss} affinity")
|
}.get(d.get("role", ""), f"{card_ref} marks {poss} affinity")
|
||||||
return f"draws {poss} Sea of cards, where {clause}."
|
return f"draws {poss} Sea of cards, where {clause}."
|
||||||
if self.verb == self.SEA_RELINQUISHED:
|
if self.verb == self.SEA_RELINQUISHED:
|
||||||
card_name = d.get("card_name", "a card").replace("The ", "", 1)
|
card_name = d.get("card_name", "a card").replace("The ", "", 1)
|
||||||
|
|||||||
@@ -181,21 +181,24 @@ class GameEventModelTest(TestCase):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# ── to_prose — SEA_DRAWN / SEA_RELINQUISHED ──────────────────────────
|
# ── to_prose — SEA_DRAWN / SEA_RELINQUISHED ──────────────────────────
|
||||||
def test_sea_drawn_prose_pc_crown_clause(self):
|
def test_sea_drawn_prose_pc_crown_clause_with_abbrev(self):
|
||||||
event = record(self.room, GameEvent.SEA_DRAWN, actor=self.user,
|
event = record(self.room, GameEvent.SEA_DRAWN, actor=self.user,
|
||||||
role="PC", slot_number=1, card_name="The Magician")
|
role="PC", slot_number=1, card_name="Queen of Pentacles",
|
||||||
# Default pronouns = pluralism → "their"; "The " stripped before "the".
|
corner_rank="Q", suit_icon="fa-crown")
|
||||||
|
# Default pronouns → "their"; the corner-rank + suit-icon abbrev rides the
|
||||||
|
# card name (rendered |safe in the scroll).
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
event.to_prose(),
|
event.to_prose(),
|
||||||
"draws their Sea of cards, where the Magician crowns all "
|
'draws their Sea of cards, where the Queen of Pentacles '
|
||||||
"their loftiest illusions.")
|
'(Q <i class="fa-solid fa-crown"></i>) crowns all their '
|
||||||
|
'loftiest illusions.')
|
||||||
|
|
||||||
def test_sea_drawn_prose_per_role_clauses(self):
|
def test_sea_drawn_prose_per_role_clauses(self):
|
||||||
# Each Role gets its own clause (user-spec 2026-06-09). Default pronouns:
|
# Each Role gets its own clause (user-spec 2026-06-09). Default pronouns:
|
||||||
# subj "they", poss "their".
|
# subj "they" (plural → "leave"), poss "their". No abbrev (no corner_rank).
|
||||||
cases = {
|
cases = {
|
||||||
"PC": "the Maid crowns all their loftiest illusions",
|
"PC": "the Maid crowns all their loftiest illusions",
|
||||||
"NC": "the Maid traces all the narratives they leaves behind",
|
"NC": "the Maid traces all the narratives they leave behind",
|
||||||
"EC": "the Maid always looms before their calling",
|
"EC": "the Maid always looms before their calling",
|
||||||
"SC": "the Maid covers all their righteous conduct",
|
"SC": "the Maid covers all their righteous conduct",
|
||||||
"AC": "the Maid always crosses their sinister connections",
|
"AC": "the Maid always crosses their sinister connections",
|
||||||
@@ -208,6 +211,28 @@ class GameEventModelTest(TestCase):
|
|||||||
event.to_prose(),
|
event.to_prose(),
|
||||||
f"draws their Sea of cards, where {clause}.", f"role={role}")
|
f"draws their Sea of cards, where {clause}.", f"role={role}")
|
||||||
|
|
||||||
|
def test_sea_drawn_nc_clause_pluralizes_yo(self):
|
||||||
|
# yo is treated as PLURAL → "yo leave behind", not "leaves".
|
||||||
|
self.user.pronouns = "bawlmorese"
|
||||||
|
self.user.save(update_fields=["pronouns"])
|
||||||
|
event = record(self.room, GameEvent.SEA_DRAWN, actor=self.user,
|
||||||
|
role="NC", card_name="Maid")
|
||||||
|
self.assertEqual(
|
||||||
|
event.to_prose(),
|
||||||
|
"draws yos Sea of cards, where the Maid traces all the "
|
||||||
|
"narratives yo leave behind.")
|
||||||
|
|
||||||
|
def test_sea_drawn_nc_clause_keeps_leaves_for_singular(self):
|
||||||
|
# A singular subject (he) keeps the 3rd-person "leaves".
|
||||||
|
self.user.pronouns = "misogyny"
|
||||||
|
self.user.save(update_fields=["pronouns"])
|
||||||
|
event = record(self.room, GameEvent.SEA_DRAWN, actor=self.user,
|
||||||
|
role="NC", card_name="Maid")
|
||||||
|
self.assertEqual(
|
||||||
|
event.to_prose(),
|
||||||
|
"draws his Sea of cards, where the Maid traces all the "
|
||||||
|
"narratives he leaves behind.")
|
||||||
|
|
||||||
def test_sea_drawn_prose_uses_actor_pronouns(self):
|
def test_sea_drawn_prose_uses_actor_pronouns(self):
|
||||||
self.user.pronouns = "bawlmorese"
|
self.user.pronouns = "bawlmorese"
|
||||||
self.user.save(update_fields=["pronouns"])
|
self.user.save(update_fields=["pronouns"])
|
||||||
|
|||||||
Reference in New Issue
Block a user