92 lines
3 KiB
Dart
92 lines
3 KiB
Dart
|
|
import 'dart:convert';
|
||
|
|
import 'dart:io';
|
||
|
|
|
||
|
|
import 'package:halkyon_learn_curator/src/sources/jlpt.dart';
|
||
|
|
import 'package:halkyon_learn_curator/src/sources/jmdict.dart';
|
||
|
|
import 'package:test/test.dart';
|
||
|
|
|
||
|
|
void main() {
|
||
|
|
late List<Map<String, Object?>> lines;
|
||
|
|
|
||
|
|
setUpAll(() async {
|
||
|
|
final jlpt = await readJlptLevels(Directory('test/fixtures/jlpt'));
|
||
|
|
lines = [
|
||
|
|
for (final line in await jmdictDictionary(
|
||
|
|
File('test/fixtures/jmdict-eng-sample.json')
|
||
|
|
.openRead()
|
||
|
|
.transform(utf8.decoder),
|
||
|
|
jlpt: jlpt,
|
||
|
|
).toList())
|
||
|
|
jsonDecode(line) as Map<String, Object?>,
|
||
|
|
];
|
||
|
|
});
|
||
|
|
|
||
|
|
Map<String, Object?> entry(String headword) =>
|
||
|
|
lines.skip(1).firstWhere((line) => line['headword'] == headword);
|
||
|
|
|
||
|
|
test('the header says what the file holds, and whose it is', () {
|
||
|
|
final header = lines.first;
|
||
|
|
expect(header['format'], 'halkyon-dictionary');
|
||
|
|
expect(header['formatVersion'], 1);
|
||
|
|
expect(header['source'], 'jmdict');
|
||
|
|
expect(header['sourceVersion'], '3.6.2 (2026-10-05)');
|
||
|
|
expect((header['language'], header['glossLanguage']), ('ja', 'en'));
|
||
|
|
expect(header['license'], 'CC-BY-SA-4.0');
|
||
|
|
expect(
|
||
|
|
[
|
||
|
|
for (final credit in header['credits']! as List)
|
||
|
|
(credit as Map)['name'],
|
||
|
|
],
|
||
|
|
['JMdict', 'jmdict-simplified', 'JLPT vocabulary lists'],
|
||
|
|
);
|
||
|
|
expect(lines, hasLength(7));
|
||
|
|
});
|
||
|
|
|
||
|
|
test('a word: its headword and reading, labels, and the keys a search '
|
||
|
|
'matches, in kanji, kana, romaji and its meanings', () {
|
||
|
|
final word = entry('食べる');
|
||
|
|
|
||
|
|
expect(word['id'], '1358280');
|
||
|
|
expect(word['reading'], 'たべる');
|
||
|
|
expect(word['labels'], ['common', 'jlpt:n5']);
|
||
|
|
expect(
|
||
|
|
word['keys'],
|
||
|
|
containsAll(['食べる', '喰べる', 'たべる', 'taberu', 'to eat', 'eat']),
|
||
|
|
);
|
||
|
|
// A form for searching only isn't shown.
|
||
|
|
final forms = (word['entry']! as Map)['forms']! as List;
|
||
|
|
expect([for (final form in forms) (form as Map)['text']], ['食べる']);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('a word written in kana has no reading of its own; katakana is '
|
||
|
|
'searched as hiragana too', () {
|
||
|
|
final word = entry('テレビ');
|
||
|
|
|
||
|
|
expect(word.containsKey('reading'), isFalse);
|
||
|
|
expect(word['keys'], containsAll(['テレビ', 'てれび', 'terebi', 'tv']));
|
||
|
|
});
|
||
|
|
|
||
|
|
test('long vowels are found typed once', () {
|
||
|
|
expect(entry('東京')['keys'], containsAll(['toukyou', 'tokyo']));
|
||
|
|
});
|
||
|
|
|
||
|
|
test('the reading is one that belongs to the headword', () {
|
||
|
|
expect(entry('四')['reading'], 'し');
|
||
|
|
});
|
||
|
|
|
||
|
|
test("the headword is the JLPT lists' spelling, at the easiest level a "
|
||
|
|
'word is listed at', () {
|
||
|
|
final word = entry('歯磨き');
|
||
|
|
|
||
|
|
expect(word['labels'], ['common', 'jlpt:n2']);
|
||
|
|
});
|
||
|
|
|
||
|
|
test('words rank N5 first, then down the levels, then the other common '
|
||
|
|
'words, then the rest', () {
|
||
|
|
int rank(String headword) => entry(headword)['rank']! as int;
|
||
|
|
|
||
|
|
expect(rank('食べる'), lessThan(rank('歯磨き')));
|
||
|
|
expect(rank('歯磨き'), lessThan(rank('東京')));
|
||
|
|
expect(rank('東京'), lessThan(rank('〃')));
|
||
|
|
});
|
||
|
|
}
|