Add a stroke rendering regression test over a type/head/tail matrix - #19
Merged
Conversation
The existing `testKage` cases in test/index.js compare three hand-written
glyphs against inlined polygon coordinates. That is precise, but narrow:
between them they exercise 10 distinct (stroke type, head type, tail type)
combinations, all in mincho with `kUseCurve` off. Stroke types 3, 6 and 7
are never drawn, and gothic is never rendered at all.
This adds test/strokes.js, which trades precision for breadth. It renders a
deterministic matrix -- stroke types {1,2,3,4,6,7} x 9 head types x 15 tail
types x 4 control point geometries x both shotai, plus a `kUseCurve` sample
over the curve-bearing stroke types, plus whole-glyph cases covering buhin
expansion, the two-segment stretch mode and the 0:97/98/99 transforms --
and compares a fingerprint of each result (polygon count, point count, sha1
of the coordinates) against test/strokes-golden.tsv. 7,614 cases, ~0.3s.
Notes on the design:
- One of the four geometries runs right-to-left and upwards. The README
lists several head/tail shapes that behave oddly in that direction and are
deliberately left alone for now; pinning them down means a later fix shows
up as an explicit golden update rather than silently.
- A case that throws records `ERROR <message>` as its expected value instead
of failing the run. Some combinations in the matrix are not meaningful for
their stroke type, and what matters is that the engine's answer to them
stays put -- a combination that starts or stops throwing is exactly the
kind of change this is meant to surface. Non-finite coordinates are
recorded the same way.
- The fingerprint only answers "did the output change", never "is the output
correct". Intentional changes are handled with
`UPDATE_GOLDEN=1 node test/strokes.js` followed by reading the diff.
The current baseline is 0 throwing cases and 32 that draw nothing. The 32
are mincho straight lines with head type 2 or 7 where the stroke is not
horizontal; I checked these against kamichikoichi/kage-engine and the
behavior is identical there, so they are recorded as-is rather than treated
as a defect.
Sanity check that the test actually bites: changing `Mincho`'s kMinWidthY
from 2 to 2.05 makes it report 2282 changed cases.
frankslin
added a commit
to frankslin/kage-engine
that referenced
this pull request
Jul 29, 2026
先前寫「npm test 完全沒有涵蓋筆畫繪製」是錯的。test/index.js 裡的 testKage 自 2017 年起就在逐點比對三個字形的完整多邊形輸出(容差 0.5、on/off-curve 旗標、NaN 檢查),只是通過時靜默,npm test 的輸出只看得到 「Buhin#onMissing: ok」,我據此下了結論沒有往下讀。 實際缺口比原本寫的窄但確實存在:實測枚舉過,現有測試只觸及 10 組(筆畫類型/ 頭形/尾形)組合,全部是明朝體且 kUseCurve 關閉,筆畫類型 3/6/7 從未被畫出, 黑體完全沒有渲染過。 補齊用的矩陣回歸測試(7,614 個 case)已提到上游 kurgm#19, 本 repo 不另外維護一份;若被合併,git merge kurgm/master 會一併帶進來。 文件改為說明這個狀態。
Owner
|
Thank you for your contribution! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The
testKagecases intest/index.jscompare three hand-written glyphsagainst inlined polygon coordinates. That is precise, but narrow: between them
they exercise 10 distinct (stroke type, head type, tail type) combinations, all
in mincho with
kUseCurveoff. Stroke types 3, 6 and 7 are never drawn, andgothic is never rendered at all.
This PR adds
test/strokes.js, which trades precision for breadth. It renders adeterministic matrix and compares a fingerprint of each result against a
committed golden file:
{1,2,3,4,6,7}x 9 head types x 15 tail types x 4 control pointgeometries x both shotai
kUseCurvesample over the curve-bearing stroke types (that code path incdDrawCurveUis currently untested)(
sx > 100) and the0:97/0:98/0:99transforms7,614 cases, about 0.3 s.
npm testnow runstest/index.jsand thentest/strokes.js.The fingerprint is
(polygon count, point count, sha1 of the coordinates),stored in
test/strokes-golden.tsv. It only answers "did the output change",never "is the output correct" — deciding the latter is still a visual job. When
output changes on purpose:
UPDATE_GOLDEN=1 node test/strokes.js, then read thediff. Each changed line is one stroke whose shape moved, so a diff that is
larger than expected is itself a signal.
Design notes
One geometry runs right-to-left and upwards. The README lists several
head/tail shapes that behave oddly when a stroke points that way, deliberately
left alone for now to avoid affecting non-kanji glyphs. Pinning them down means
that when they do get fixed, it shows up as an explicit golden-file update
rather than silently.
A case that throws records
ERROR <message>as its expected value insteadof failing the run. Some combinations in the matrix are not meaningful for their
stroke type, and what matters is that the engine's answer to them stays put — a
combination that starts or stops throwing is exactly the kind of change this is
meant to surface. Non-finite coordinates are recorded the same way.
The corpus is entirely fixed literals — no RNG, no dates — so the golden
file is reproducible across machines and runs.
Baseline
0 throwing cases, 32 that draw nothing. The 32 are mincho straight lines with
head type 2 or 7 where the stroke is not horizontal, e.g.
1:2:2:50:20:50:80.I checked those inputs against
kamichikoichi/kage-engineand the behavior isidentical there, so they are recorded as-is rather than treated as a defect.
Sanity check that the test actually bites
Changing
Mincho'skMinWidthYfrom2to2.05makes it report 2282 changedcases; reverting restores a pass.
Notes
src/changes, so no CHANGELOG entry — following the precedent ofc9b8baa ("Add tests for rotation (0:99:2)"), which was also test-only.
test/strokes.jspasseseslintunder the existing flat config.am happy to shrink it — truncating the hashes, dropping the
rlgeometry, ornarrowing the tail-type list would each cut it substantially.