halkyon/halkyon_learn_flutter/test/feature/dictionary/dictionary_data_test.dart

173 lines
5.5 KiB
Dart
Raw Normal View History

import 'package:flutter_test/flutter_test.dart';
import 'package:halkyon_learn_flutter/src/feature/card/data/card_repository.dart';
import 'package:halkyon_learn_flutter/src/feature/card/model/card_content.dart';
import 'package:halkyon_learn_flutter/src/feature/dictionary/data/dictionary_adder.dart';
import 'package:halkyon_learn_flutter/src/feature/dictionary/data/dictionary_repository.dart';
import 'package:halkyon_learn_flutter/src/feature/dictionary/model/dictionary.dart';
import 'package:halkyon_learn_flutter/src/feature/tag/data/tag_repository.dart';
import '../../support/fake_card_gateway.dart';
import '../../support/fake_dictionary_gateway.dart';
import '../../support/fake_tag_gateway.dart';
final taberu = word(
'1358280',
'食べる',
reading: 'たべる',
glosses: ['to eat'],
labels: ['common', 'jlpt:n5'],
pos: ['v1', 'vt'],
);
final terebi = word(
'1080510',
'テレビ',
glosses: ['television', 'TV'],
labels: ['common', 'jlpt:n5'],
pos: ['n'],
);
void main() {
group('a word', () {
test('reads its senses from the entry, the codes with them', () {
final read = DictionaryWord.fromEntry(
ref: (source: 'jmdict', id: '1358280'),
headword: '食べる',
reading: 'たべる',
labels: ['common', 'jlpt:n5'],
entry:
'{"forms":[{"text":"食べる"}],"senses":[{"glosses":["to eat"],'
'"pos":["v1","vt"]},{"glosses":["to live on"],"misc":["uk"]}]}',
);
expect(read.senses, const [
VocabularySense(glosses: ['to eat'], pos: ['v1', 'vt']),
VocabularySense(glosses: ['to live on'], misc: ['uk']),
]);
expect(read.jlpt, 5);
});
test('becomes a vocabulary card that keeps where it is from; a word in '
'kana has no reading', () {
final card = taberu.card;
expect(card.type, CardType.vocabulary);
expect(card.front.plainText.trim(), '食べる');
expect(card.reading, 'たべる');
expect(card.meanings, ['to eat']);
expect(card.entry, (source: 'jmdict', id: '1358280'));
expect(terebi.card.reading, '');
});
});
group('the repository', () {
test('asks for the dictionaries once, again after a failure', () async {
final gateway = FakeDictionaryGateway()..fail = Exception('offline');
final repository = DictionaryRepository(gateway);
await expectLater(repository.dictionaries(), throwsException);
gateway.fail = null;
expect(await repository.dictionaries(), [jmdict]);
await repository.dictionaries();
expect(gateway.asked, 2);
});
test("finds a studyset's dictionary by its front's language, with "
"meanings in its back's, else in English", () async {
const german = Dictionary(
source: 'jmdict',
sourceVersion: '1',
language: 'ja',
glossLanguage: 'de',
license: 'CC-BY-SA-4.0',
credits: [],
entryCount: 1,
);
final repository = DictionaryRepository(
FakeDictionaryGateway(available: [jmdict, german]),
);
expect(await repository.dictionaryFor((front: 'ja', back: 'de')), german);
expect(await repository.dictionaryFor((front: 'ja', back: 'fr')), jmdict);
expect(await repository.dictionaryFor((front: 'ja', back: null)), jmdict);
expect(await repository.dictionaryFor((front: 'ko', back: 'en')), isNull);
expect(await repository.dictionaryFor((front: null, back: 'en')), isNull);
});
test('brings every word of a level, a page at a time', () async {
final words = [
for (var i = 0; i < DictionaryRepository.page + 3; i++)
word('$i', 'w$i', labels: ['jlpt:n5']),
];
final counts = <int>[];
final all = await DictionaryRepository(
FakeDictionaryGateway(words: words),
).allLabelled(jmdict, 'jlpt:n5', onProgress: counts.add);
expect(all, words);
expect(counts, [
DictionaryRepository.page,
DictionaryRepository.page + 3,
]);
});
});
group('adding words', () {
late CardRepository cards;
late TagRepository tags;
late DictionaryAdder adder;
setUp(() {
cards = CardRepository(FakeCardGateway());
tags = TagRepository(FakeTagGateway());
adder = DictionaryAdder(cards, tags);
});
tearDown(() async {
await cards.dispose();
await tags.dispose();
});
test('makes each word a card once, tagged with its level and word '
'class, marked as from the dictionary', () async {
expect(await adder.add('japanese', [taberu]), (added: 1, skipped: 0));
expect(
await adder.add('japanese', [taberu, terebi]),
(added: 1, skipped: 1),
);
final made = await cards.cardsOf('japanese');
expect(
[for (final card in made) card.content.entry?.id],
[
'1358280',
'1080510',
],
);
final tagging = await tags.read();
expect(
[for (final tag in tagging.of(made.first.id)) tag.name],
[
'JLPT-N5',
'Verb',
],
);
expect(
[for (final tag in tagging.of(made.last.id)) tag.name],
[
'JLPT-N5',
'Noun',
],
);
expect((await cards.allCards()).every((card) => card.imported), isTrue);
});
test('names the tags by level and word class', () {
expect(tagNamesOf(taberu), ['JLPT-N5', 'Verb']);
expect(
tagNamesOf(word('1', 'x', pos: ['adj-na', 'n'])),
['na-Adjective', 'Noun'],
);
expect(tagNamesOf(word('2', 'y', pos: ['vt'])), isEmpty);
});
});
}