halkyon/halkyon_learn_curator/test/kanjivg_test.dart
Tizian 「ティツィアーン」 e42cdfbfcb
feat(curator): KANJIDIC2 and the kana as a dictionary of characters; KanjiVG's strokes for the app
A dictionary file now says whether it holds words or characters (`kind`).
The kanjidic adapter turns KANJIDIC2 into one entry per kanji that has a
Japanese reading or an English meaning (12,633), with its readings,
meanings, school grade, strokes, frequency and JLPT level (Jonathan
Waller's, through kanji-data's kanji.json), labelled `jlpt:nX`,
`grade:N`/`grade:secondary`, followed by the 71 hiragana and katakana of
the kana table with their romaji. A kun reading is found whole; its kanji
part only as a loose key, so typing "ta" brings た before every kanji read
so.

`curate kanjivg` writes KanjiVG's strokes and components as the app's
stroke files, one gzipped JSON file per 256 code points, keyed by the code
point in each entry's id (KanjiVG's 橅 names itself 機).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MMm7usAo6q9ZZRoPkWjoxi
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-09 18:09:32 +02:00

49 lines
1.6 KiB
Dart

import 'dart:io';
import 'package:halkyon_learn_curator/src/sources/kanjivg.dart';
import 'package:test/test.dart';
void main() {
late Map<String, CharacterStrokes> strokes;
setUpAll(() async {
strokes = kanjivgStrokes(
await File('test/fixtures/kanjivg-sample.xml').readAsString(),
);
});
test("a character's strokes are its paths in the order they're written", () {
final eat = strokes['食']!;
expect(eat.strokes, hasLength(9));
expect(eat.strokes.first, startsWith('M52.75,10.5c'));
expect(eat.strokes.last, startsWith('M51.5,71C'));
expect(strokes['あ']!.strokes, hasLength(3));
});
test('its components are the characters KanjiVG first splits it into, '
'looking through groups that are none', () {
expect(strokes['語']!.components, ['言', '吾']);
expect(strokes['食']!.components, isEmpty);
});
test("the character is the code point in the entry's id, not KanjiVG's "
'element name, which can be wrong', () {
// KanjiVG's U+6A45 (橅) names itself 機.
expect(strokes.keys, containsAll(['橅', 'あ', '食', '語']));
expect(strokes.keys, isNot(contains('機')));
});
test('the stroke files hold every 256 code points, named by their upper '
'bits', () {
expect(strokeFileOf('食'), '098');
expect(strokeFileOf('あ'), '030');
expect(strokeFileOf('𠀋'), '200');
final files = strokeFiles(strokes);
expect(files.keys, containsAll(['030', '098', '08a', '06a']));
expect(files['08a']!['語'], {
's': strokes['語']!.strokes,
'c': ['言', '吾'],
});
expect(files['098']!['食'], {'s': strokes['食']!.strokes});
});
}