import 'dart:convert'; import 'dart:io'; import 'package:archive/archive.dart'; import 'package:halkyon_learn_curator/src/sources/krdict.dart'; import 'package:halkyon_learn_curator/src/sources/wiktionary.dart'; import 'package:halkyon_learn_curator/src/wordfreq.dart'; import 'package:test/test.dart'; void main() { /// The fixture packed as KRDict packs its export: its first file. List export() => ZipEncoder().encodeBytes( Archive()..add( ArchiveFile.bytes( '1_5000_20260919.json', File('test/fixtures/krdict-sample.json').readAsBytesSync(), ), ), ); Future>> converted({ WordFrequencies? frequencies, WiktionaryKorean? korean, }) async { final (:version, :entries) = krdictExport(export()); return [ for (final line in await krdictDictionary( entries, sourceVersion: version, frequencies: frequencies, korean: korean, ).toList()) jsonDecode(line) as Map, ]; } test("KRDict's words with their level, pronunciation where it differs from " 'the spelling, Hanja, forms and English senses', () async { final [header, ...entries] = await converted(); expect(header['source'], 'krdict'); expect(header['language'], 'ko'); expect(header['sourceVersion'], '2026-09-19'); expect( [ for (final credit in header['credits']! as List) (credit as Map)['name'], ], ['한국어기초사전 (Basic Korean Dictionary)'], ); final school = entries.singleWhere((entry) => entry['headword'] == '학교'); expect(school['id'], '73276'); expect(school['reading'], '학꾜'); expect(school['labels'], ['level:beginner']); expect(school['keys'], containsAll(['학교', '學校', 'school'])); const definition = 'An institution that educates students according to a specific ' 'purpose, curriculum, system, etc.'; expect(school['entry'], { 'pos': 'noun', 'hanja': ['學校'], 'senses': [ { 'glosses': ['school'], 'info': [definition], }, ], }); final read = entries.singleWhere((entry) => entry['headword'] == '읽다'); expect(read['reading'], '익따'); expect(read['textKeys'], containsAll(['읽다', '읽어', '읽고'])); expect( (read['entry']! as Map)['inflections'], contains(equals({'text': '읽어'})), ); final together = entries.where((entry) => entry['headword'] == '같이'); expect( [for (final entry in together) (entry['entry']! as Map)['pos']], ['particle', 'adv'], ); }); test('an idiom or a proverb is an entry of its own, never found in running ' 'text, with an id told apart from its word', () async { final [_, ...entries] = await converted(); final proverb = entries.singleWhere( (entry) => entry['headword'] == '가는 날이 장날', ); expect(proverb['id'], '27500:가는 날이 장날'); expect((proverb['entry']! as Map)['pos'], 'proverb'); expect(proverb.containsKey('textKeys'), isFalse); expect( entries.singleWhere((entry) => entry['headword'] == '가다')['id'], '27500', ); }); test("Wiktionary's forms find a word in text; a verb rarely written as " 'the dictionary writes it ranks by its most used form', () async { final korean = WiktionaryKorean()..forms['가다'] = {'가요', '갔어요', '갑니다'}; final [_, ...entries] = await converted( korean: korean, frequencies: WordFrequencies(const {'갔어요': 50}), ); final go = entries.singleWhere((entry) => entry['headword'] == '가다'); expect(go['textKeys'], containsAll(['가다', '가요', '갔어요'])); expect(go['labels'], contains('common')); expect(go['rank'], 100000 + 100); }); test("the export's JSON download is the third its page offers", () { expect( krdictJsonDownloadOf(''' '''), '217', ); expect(krdictJsonDownloadOf("batchDownload('0')"), isNull); }); }