v0.8.82-beta - "Poort {port} is vrij" stond er letterlijk
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 17m4s
All checks were successful
Deploy server-up (dev) / deploy (push) Successful in 17m4s
- De poortcontrole werd aangesloten op vertaalsleutels die er al waren, en twee
daarvan verwachten een plaatshouder die ik niet meegaf: port_free wil {port},
port_in_use wil {port} en {by}
- Nieuwe test die elke t('sleutel', {...}) in de interface vergelijkt met de
plaatshouders in de Nederlandse tekst, in beide richtingen en ook voor
aanroepen zonder variabelen. Die laatste toevoeging was nodig: de eerste
versie van de test liet juist de fout passeren waar hij voor gemaakt was
- De test kent nu ook de verkorte objectnotatie van JavaScript ({name} betekent
{name: name}); zonder dat meldde hij vier bestaande aanroepen ten onrechte
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q9eqpADJSRs49SoGGr4NAy
This commit is contained in:
parent
d7c4682cc7
commit
b6319e8fdd
4 changed files with 103 additions and 3 deletions
13
CHANGELOG.md
13
CHANGELOG.md
|
|
@ -1,3 +1,16 @@
|
|||
# v0.8.82-beta — "Poort {port} is vrij" stond er letterlijk
|
||||
|
||||
De poortcontrole werd aangesloten op vertaalsleutels die er al waren, en twee
|
||||
daarvan verwachten een plaatshouder die niet werd meegegeven: `port_free` wil
|
||||
`{port}`, `port_in_use` wil `{port}` én `{by}`. In beeld stond dus letterlijk
|
||||
"Poort {port} is vrij".
|
||||
|
||||
Er draait nu een test die elke `t('sleutel', { … })` in de interface naloopt en
|
||||
vergelijkt met de plaatshouders in de Nederlandse tekst — in beide richtingen,
|
||||
en ook voor aanroepen zónder variabelen. Dat laatste was nodig: de eerste versie
|
||||
van die test keek alleen naar aanroepen die wél iets meegaven, en liet de fout
|
||||
waar hij voor gemaakt was gewoon passeren.
|
||||
|
||||
# v0.8.81-beta — Poorten kiezen zonder gokken, en installeren op een telefoon
|
||||
|
||||
**De poortcontrole zat er wel, maar werd nooit gevraagd.** `/api/ports/check`
|
||||
|
|
|
|||
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
|||
0.8.81-beta
|
||||
0.8.82-beta
|
||||
|
|
|
|||
|
|
@ -3282,11 +3282,15 @@ function app() {
|
|||
if (!c.free) {
|
||||
return c.used_by
|
||||
? this.t('port_used_by', { port: c.port, container: c.used_by })
|
||||
: this.t('port_in_use', { port: c.port });
|
||||
// `by` staat in de tekst voor het geval we wél weten waardoor; hier
|
||||
// weten we dat niet, dus leeg. Weglaten zou '{by}' in beeld zetten.
|
||||
: this.t('port_in_use', { port: c.port, by: '' });
|
||||
}
|
||||
// Zonder de hulpcontainer zien we alleen Docker; dan is "vrij" een
|
||||
// aanname en dat hoort de melding te zeggen.
|
||||
return c.host_checked ? this.t('port_free') : this.t('port_free_docker_only');
|
||||
return c.host_checked
|
||||
? this.t('port_free', { port: c.port })
|
||||
: this.t('port_free_docker_only');
|
||||
},
|
||||
// Bij het openen van een stap meteen controleren wat er in de poortvelden
|
||||
// staat, in plaats van te wachten tot iemand iets typt.
|
||||
|
|
|
|||
|
|
@ -128,3 +128,86 @@ def test_auditnamen_bestaan_in_beide_talen():
|
|||
nl, en = _laad("nl"), _laad("en")
|
||||
alleen_nl = sorted(k for k in nl if k.startswith("audit_") and k not in en)
|
||||
assert not alleen_nl, f"ontbreken in en.json: {alleen_nl}"
|
||||
|
||||
|
||||
def _meegegeven(blok: str) -> set[str]:
|
||||
"""De sleutels uit een `{…}` in een t()-aanroep.
|
||||
|
||||
JavaScript kent twee vormen: `{port: c.port}` en de verkorte `{name}`, die
|
||||
hetzelfde betekent als `{name: name}`. Alleen op een dubbele punt zoeken
|
||||
mist die tweede, en dan meldt de test fouten die er niet zijn.
|
||||
"""
|
||||
uit, huidig, diepte = set(), "", 0
|
||||
for teken in blok + ",":
|
||||
if teken in "([{":
|
||||
diepte += 1
|
||||
elif teken in ")]}":
|
||||
diepte -= 1
|
||||
if teken == "," and diepte == 0:
|
||||
deel = huidig.strip()
|
||||
if deel:
|
||||
naam = deel.split(":", 1)[0].strip()
|
||||
if re.fullmatch(r"\w+", naam):
|
||||
uit.add(naam)
|
||||
huidig = ""
|
||||
else:
|
||||
huidig += teken
|
||||
return uit
|
||||
|
||||
|
||||
def _t_aanroepen(html: str):
|
||||
"""Elke `t('sleutel', { … })` met de meegegeven sleutels."""
|
||||
for m in re.finditer(r"\bt\(\s*'([a-z0-9_]+)'\s*,\s*\{([^{}]*)\}", html):
|
||||
yield m.group(1), _meegegeven(m.group(2))
|
||||
|
||||
|
||||
def test_elke_plaatshouder_wordt_ook_meegegeven():
|
||||
"""`t('port_free')` op een tekst met `{port}` erin zet letterlijk "{port}"
|
||||
in beeld.
|
||||
|
||||
Dat is precies wat er gebeurde toen de poortcontrole werd aangesloten op
|
||||
sleutels die er al waren: `port_free` verwacht `{port}`, `port_in_use`
|
||||
verwacht `{port}` én `{by}`, en die werden niet meegegeven.
|
||||
"""
|
||||
nl = _laad("nl")
|
||||
html = (WORTEL / "templates" / "index.html").read_text(encoding="utf-8")
|
||||
aanroepen = list(_t_aanroepen(html))
|
||||
assert aanroepen, "geen t()-aanroepen met variabelen gevonden — vorm veranderd?"
|
||||
|
||||
fouten = []
|
||||
for sleutel, gegeven in aanroepen:
|
||||
tekst = nl.get(sleutel)
|
||||
if tekst is None:
|
||||
continue # andere test dekt onbekende sleutels
|
||||
ontbreekt = set(re.findall(r"\{(\w+)\}", tekst)) - gegeven
|
||||
if ontbreekt:
|
||||
fouten.append(f"{sleutel}: mist {sorted(ontbreekt)}")
|
||||
|
||||
# En het geval dat de eerste versie van deze test miste: een aanroep zónder
|
||||
# variabelen op een tekst die er wél verwacht. Dat was precies de fout —
|
||||
# `t('port_free')` op "Poort {port} is vrij".
|
||||
for m in re.finditer(r"\bt\(\s*'([a-z0-9_]+)'\s*\)", html):
|
||||
sleutel = m.group(1)
|
||||
tekst = nl.get(sleutel)
|
||||
if tekst is None:
|
||||
continue
|
||||
nodig = sorted(set(re.findall(r"\{(\w+)\}", tekst)))
|
||||
if nodig:
|
||||
fouten.append(f"{sleutel}: aangeroepen zonder {nodig}")
|
||||
assert not fouten, fouten
|
||||
|
||||
|
||||
def test_geen_plaatshouder_zonder_tekst():
|
||||
"""Andersom: een sleutel meegeven die niet in de tekst staat is meestal een
|
||||
hernoeming die half is doorgevoerd."""
|
||||
nl = _laad("nl")
|
||||
html = (WORTEL / "templates" / "index.html").read_text(encoding="utf-8")
|
||||
fouten = []
|
||||
for sleutel, gegeven in _t_aanroepen(html):
|
||||
tekst = nl.get(sleutel)
|
||||
if tekst is None:
|
||||
continue
|
||||
over = gegeven - set(re.findall(r"\{(\w+)\}", tekst))
|
||||
if over:
|
||||
fouten.append(f"{sleutel}: geeft {sorted(over)} mee, staat niet in de tekst")
|
||||
assert not fouten, fouten
|
||||
|
|
|
|||
Loading…
Reference in a new issue