Commit Graph
3 Commits
Author SHA1 Message Date
tiennm99 39ef45730f feat(dict): derive the corpus from undertheseanlp's wiktionary rows
Replace the 179 MB minhqnd SQLite aggregate with the 4.8 MB
undertheseanlp/dictionary JSONL, pinned by commit and SHA-256, reading
only rows tagged "wiktionary". The two other wordlists in that file are
never read: hongocduc is GPL and would force a relicense, tudientv is an
unlicensed derivative of a commercial dictionary.

build-dictionary gains --merged and --sources (names validated, default
wiktionary), a shared finish() tail, and meta rows for the source commit
and the sources kept and excluded. The SQLite --in path, its schema
auto-detection and their tests are removed. Fixture builds now record
that they carry no upstream data instead of inheriting a licence string.
The --min-words floor moves from 40,000 to 20,000; the corpus is 26,845
words, down from 48,216, all of the loss being words absent from the
2018 Wiktionary scrape. Capitalization is not a filter.

The data licence follows the source text: CC BY-SA 3.0 Unported, which
is what vi.wiktionary.org carried in 2018. LICENSE, NOTICE, ATTRIBUTION,
the README, the image docs, the builder's meta string and the in-game
footer all name Wiktionary tiếng Việt's contributors as the authors and
undertheseanlp as the intermediary. The Makefile/Dockerfile pin test now
also checks the commit the builder stamps into the database.
2026-09-08 16:37:34 +07:00
tiennm99 2f896584f8 test(e2e): bind the test server to loopback only
The suite only ever talks to localhost, and a listener on every interface
is what makes Windows Firewall ask to allow the binary — which `go run`
rebuilds to a new temporary path each time, so answering never sticks.
2026-09-08 14:23:28 +07:00
tiennm99 e162574556 test(e2e): drive both modes through a real browser
Twenty-one Playwright specs against the real binary serving the real bundle: a
bot game with its rejections, an online game across two browser contexts, and
the reconnect path. The server plays against the fixture dictionary, so nothing
here downloads the upstream release.

Every wait is on a state the server produced — the turn indicator, the required
syllable, a word appearing in the chain — never a sleep. Moves are chosen by
reading the same wordlist the server has rather than scripting a fixed
sequence, because the bot is entitled to pick a different reply.

Two things that do not work are recorded where the next person will look.
Offline emulation does not cut a loopback socket, so a test that went offline
kept playing happily. Routing the socket cuts it for real, but the close does
not reliably reach the server, so the grace window never starts: those tests
take the page away instead.
2026-09-05 14:18:18 +07:00