Fix review findings R1–R3 on Regular grounding and name folding
R1: Migration 0010 now writes revision 0 into every ground_dinner job payload that has none. Jobs queued before the upgrade carry only dinner_id, so the boot cleanup, which matches a pending dinner to its job by revision, failed those dinners as interrupted while their jobs were still queued. The migration runs before the job runner starts. A new test migrates a database to 0009, adds a pending Regular with a legacy queued job, upgrades and boots, and checks the dinner stays pending and is then grounded. R2: Archiving a dinner, or renaming a pending one, now cancels the grounding of any ground_dinner job running for it at an older revision, so no further search, page fetch, photo download or model call is made. The job is registered before it reads the dinner, so an archive or rename committed after that read always finds it. A stopped job succeeds and reports the dinner's current grounding status. The archive and rename tests now check that the job ends while its search is still held, with no page fetched and no model call for the stale name. R3: gen_folds.py writes web/src/dinners/letterFolds.json from the same table as folds_table.go, and names.ts folds through it instead of a hand-copied subset. names.ts also lowercases letter by letter, as Go's strings.ToLower does, rather than by context. TestLetterFoldsMatchPWA fails when the two tables differ. The shared cases add "Ƈhili", "Ꞔarbanzo Stew" and "ΜΟΥΣΑΚΑΣ" (final sigma). Maestro task 5037ff86-181d-448e-927b-c2fd2258a25d. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// TestSharedDedupeCases runs testdata/dedupe_cases.json, which the PWA's
|
||||
@@ -40,6 +41,30 @@ func TestSharedDedupeCases(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestLetterFoldsMatchPWA checks that the PWA's letter-fold table, which
|
||||
// gen_folds.py writes beside folds_table.go, is letterFolds exactly; run
|
||||
// go generate when it fails.
|
||||
func TestLetterFoldsMatchPWA(t *testing.T) {
|
||||
raw, err := os.ReadFile("../../../web/src/dinners/letterFolds.json")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var pwa map[string]string
|
||||
if err := json.Unmarshal(raw, &pwa); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for r, want := range letterFolds {
|
||||
if got, ok := pwa[string(r)]; !ok || got != want {
|
||||
t.Errorf("PWA folds %U to %q (present %v), want %q", r, got, ok, want)
|
||||
}
|
||||
}
|
||||
for k := range pwa {
|
||||
if utf8.RuneCountInString(k) != 1 || letterFolds[[]rune(k)[0]] == "" {
|
||||
t.Errorf("PWA folds %q, which letterFolds does not", k)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNormalize(t *testing.T) {
|
||||
tests := []struct {
|
||||
name, want string
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate folds_table.go, the letter-fold table used by harness.Normalize.
|
||||
"""Generate folds_table.go, the letter-fold table used by harness.Normalize,
|
||||
and its copy web/src/dinners/letterFolds.json, used by the PWA's
|
||||
normalizeName (web/src/dinners/names.ts). TestLetterFoldsMatchPWA fails when
|
||||
the two differ.
|
||||
|
||||
Run from this directory with `go generate ./internal/ai/harness` (or
|
||||
`python3 gen_folds.py`; gofmt must be on PATH). It uses only the Python
|
||||
@@ -28,11 +31,14 @@ Hangul syllables are left out: their decomposition is into conjoining jamo,
|
||||
not combining marks.
|
||||
"""
|
||||
|
||||
import json
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import unicodedata
|
||||
|
||||
PWA_TABLE = "../../../web/src/dinners/letterFolds.json"
|
||||
|
||||
EXTRA = {
|
||||
"ß": "ss", "ẞ": "ss", "æ": "ae", "Æ": "ae", "œ": "oe", "Œ": "oe",
|
||||
"þ": "th", "Þ": "th", "ð": "d", "Ð": "d", "ı": "i", "ʼn": "n",
|
||||
@@ -110,6 +116,9 @@ def main():
|
||||
with open("folds_table.go", "w", encoding="utf-8") as f:
|
||||
f.write("\n".join(out) + "\n")
|
||||
subprocess.run(["gofmt", "-w", "folds_table.go"], check=True)
|
||||
with open(PWA_TABLE, "w", encoding="ascii") as f:
|
||||
json.dump({chr(cp): folded for cp, folded in entries}, f, indent=2)
|
||||
f.write("\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
+17
@@ -67,6 +67,18 @@
|
||||
{
|
||||
"name": "7-layer dip",
|
||||
"want": "7 layer dip"
|
||||
},
|
||||
{
|
||||
"name": "Ƈhili",
|
||||
"want": "chili"
|
||||
},
|
||||
{
|
||||
"name": "Ꞔarbanzo Stew",
|
||||
"want": "carbanzo stew"
|
||||
},
|
||||
{
|
||||
"name": "ΜΟΥΣΑΚΑΣ",
|
||||
"want": "μουσακασ"
|
||||
}
|
||||
],
|
||||
"similar": [
|
||||
@@ -114,6 +126,11 @@
|
||||
"a": "The best",
|
||||
"b": "Easy recipe",
|
||||
"want": false
|
||||
},
|
||||
{
|
||||
"a": "Ƈhili",
|
||||
"b": "Chili",
|
||||
"want": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user