[UPD] analyse: give every "go further" entry an icon, and guard it

"Show every entry" was the only bare label in menus where every other
line carried one, so it read as an oversight -- and it was. It takes
the 📜 that "Show every table" already uses for the same gesture, and
"List the known packages" gets one too rather than being left as the
last bare line.

The guard reads the labels straight out of the _analyse_follow_up calls
and checks both languages, so the next entry added without an icon
fails here instead of being noticed six months later. A second test
bounds the extraction: were it to stop finding anything, the first
would pass while checking nothing.

--- FR ---

« Tout afficher » était le seul libellé nu dans des menus où toutes les
autres lignes en portaient une : ça se lisait comme un oubli, et c'en
était un. Il prend le 📜 qu'« Afficher toutes les tables » utilise déjà
pour le même geste, et « Lister les packages connus » en reçoit une
plutôt que de rester la dernière ligne nue.

Le garde lit les libellés directement dans les appels à
_analyse_follow_up et vérifie les deux langues : la prochaine entrée
sans icône tombera là, pas dans l'œil de quelqu'un six mois plus tard.
Un second test borne l'extraction — si elle ne trouvait plus rien, le
premier passerait sans rien vérifier.

Assisted-by: Claude Opus 5
This commit is contained in:
Mathieu Benoit 2026-08-21 23:07:54 -04:00
parent 1bc2b50ca8
commit ff987eeae0
2 changed files with 60 additions and 4 deletions

View file

@ -6115,12 +6115,12 @@ TRANSLATIONS = {
"en": "📦 Modules missing from the default package",
},
"Show every entry": {
"fr": "Tout afficher",
"en": "Show every entry",
"fr": "📜 Tout afficher",
"en": "📜 Show every entry",
},
"List the known packages": {
"fr": "Lister les packages connus",
"en": "List the known packages",
"fr": "📚 Lister les packages connus",
"en": "📚 List the known packages",
},
"Already repaired: the group exists.": {
"fr": "Déjà réparé : le groupe existe.",

View file

@ -730,6 +730,62 @@ class TestTheExitCodes(unittest.TestCase):
self.assertEqual(code, 2)
class TestTheFollowUpIcons(unittest.TestCase):
"""Chaque entrée « Aller plus loin » porte une icône, ou aucune.
Une seule entrée nue au milieu d'entrées ornées se lit comme un
oubli — et c'en est un. Le garde vaut mieux qu'une relecture : la
prochaine entrée ajoutée sans icône tombera ici, pas dans l'œil de
quelqu'un six mois plus tard.
"""
RACINE = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
def libelles(self):
"""Les clés passées en `prompt_description` à `_analyse_follow_up`."""
import ast
with io.open(
os.path.join(self.RACINE, "script", "todo", "todo.py"),
encoding="utf-8",
) as handle:
arbre = ast.parse(handle.read())
trouves = []
for node in ast.walk(arbre):
if not (
isinstance(node, ast.Call)
and isinstance(node.func, ast.Attribute)
and node.func.attr == "_analyse_follow_up"
and node.args
):
continue
for element in ast.walk(node.args[0]):
if (
isinstance(element, ast.Call)
and isinstance(element.func, ast.Name)
and element.func.id == "t"
and element.args
and isinstance(element.args[0], ast.Constant)
):
trouves.append(element.args[0].value)
return trouves
def test_there_are_follow_up_entries_to_check(self):
# Sans cette borne, un jour où l'extraction ne trouve plus rien,
# le test suivant passerait en ne vérifiant rien du tout.
self.assertGreater(len(self.libelles()), 5)
def test_every_follow_up_entry_carries_an_icon(self):
for cle in self.libelles():
for langue in ("fr", "en"):
texte = todo_i18n.TRANSLATIONS.get(cle, {}).get(langue, cle)
self.assertGreaterEqual(
ord(texte[0]),
0x1F300,
f"entrée sans icône [{langue}] : {texte!r}",
)
class TestTranslations(unittest.TestCase):
def test_every_key_exists(self):
import ast