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

202 lines
6.3 KiB
Dart
Raw Normal View History

import 'package:flutter_test/flutter_test.dart';
import 'package:halkyon_learn_flutter/src/core/content/rich_content.dart';
import 'package:halkyon_learn_flutter/src/core/router/route_paths.dart';
import 'package:halkyon_learn_flutter/src/feature/card/data/card_repository.dart';
import 'package:halkyon_learn_flutter/src/feature/studyset/data/studyset_payload.dart';
import 'package:halkyon_learn_flutter/src/feature/studyset/model/studyset_content.dart';
import 'package:material_ui/material_ui.dart';
import '../../support/fake_card_gateway.dart';
import '../../support/fake_dictionary_gateway.dart';
import '../../support/fake_studyset_gateway.dart';
import '../../support/pump_app.dart';
import '../../support/test_dependencies.dart';
final taberu = word(
'1358280',
'食べる',
reading: 'たべる',
glosses: ['to eat'],
labels: ['common', 'jlpt:n5'],
pos: ['v1'],
);
final terebi = word(
'1080510',
'テレビ',
glosses: ['television'],
labels: ['common', 'jlpt:n5'],
pos: ['n'],
);
final toukyou = word(
'1447690',
'東京',
reading: 'とうきょう',
glosses: ['Tokyo'],
labels: ['common'],
pos: ['n'],
);
void main() {
late FakeCardGateway cardGateway;
late CardRepository cards;
setUp(() {
cardGateway = FakeCardGateway();
cards = CardRepository(cardGateway);
});
tearDown(() => cards.dispose());
/// Lets the editors' timers run out and the screen settle.
Future<void> settle(WidgetTester tester) async {
await tester.pump(const Duration(seconds: 1));
await tester.pumpAndSettle();
}
/// Opens the studyset [id]: `japanese` (Japanese with English meanings)
/// or `german`, on an instance with JMdict.
Future<void> show(WidgetTester tester, {String id = 'japanese'}) async {
tester.view.physicalSize = const Size(1400, 1600);
tester.view.devicePixelRatio = 1;
addTearDown(tester.view.reset);
final studysets = FakeStudysetGateway()
..receiveRemoteChange(
'japanese',
encodeStudysetPayload(
StudysetContent(
title: 'Japanese',
description: RichContent.empty(),
frontLanguage: 'ja',
backLanguage: 'en',
),
),
)
..receiveRemoteChange(
'german',
encodeStudysetPayload(
StudysetContent(
title: 'German',
description: RichContent.empty(),
frontLanguage: 'de',
backLanguage: 'en',
),
),
);
await pumpApp(
tester,
testDependencies(
studysetGateway: studysets,
cardGateway: cardGateway,
dictionaryGateway: FakeDictionaryGateway(
words: [taberu, terebi, toukyou],
),
),
location: RoutePaths.studyset(id),
);
await settle(tester);
}
/// Chooses [item] under Add material.
Future<void> addMaterial(WidgetTester tester, String item) async {
await tester.tap(find.text('Add material'));
await tester.pumpAndSettle();
await tester.tap(find.text(item));
await tester.pump();
await tester.pump();
await settle(tester);
}
testWidgets('Add material offers the dictionary only where the '
"studyset's language has one", (tester) async {
await show(tester, id: 'german');
await tester.tap(find.text('Add material'));
await tester.pumpAndSettle();
expect(find.text('From the dictionary'), findsNothing);
});
testWidgets('a word found is added as a flashcard, and then shows as in '
'the studyset; the screen credits its sources', (tester) async {
await show(tester);
await addMaterial(tester, 'From the dictionary');
expect(find.textContaining('Words from JMdict'), findsOneWidget);
await tester.enterText(find.byType(TextField), 'たべ');
await tester.pump(const Duration(milliseconds: 300));
await tester.pumpAndSettle();
expect(find.textContaining('食べる'), findsOneWidget);
await tester.tap(find.text('Add'));
await tester.pumpAndSettle();
expect(find.text('Added “食べる”.'), findsOneWidget);
expect(find.byTooltip('In this studyset'), findsOneWidget);
final card = (await cards.cardsOf('japanese')).single;
expect(card.content.entry, (source: 'jmdict', id: '1358280'));
expect(card.content.reading, 'たべる');
});
testWidgets('a whole level becomes flashcards, its words in its order', (
tester,
) async {
await show(tester);
await addMaterial(tester, 'From the dictionary');
expect(find.text('N5'), findsOneWidget);
await tester.tap(find.text('Add 2 words'));
await tester.pumpAndSettle();
expect(find.text('Added 2 words.'), findsOneWidget);
expect(
[
for (final card in await cards.cardsOf('japanese'))
card.content.front.plainText.trim(),
],
['食べる', 'テレビ'],
);
});
testWidgets('Look up fills a vocabulary card with a word of the '
'dictionary', (tester) async {
await show(tester);
await addMaterial(tester, 'Create flashcards');
await tester.tap(find.text('Vocabulary'));
await settle(tester);
await tester.tap(find.byTooltip('Look up in the dictionary'));
await tester.pumpAndSettle();
await tester.enterText(find.byType(TextField).last, 'たべる');
await tester.pump(const Duration(milliseconds: 300));
await tester.pumpAndSettle();
await tester.tap(find.textContaining('食べる').last);
await settle(tester);
expect(find.text('食べる', findRichText: true), findsWidgets);
expect(find.widgetWithText(TextField, 'たべる'), findsOneWidget);
expect(find.text('to eat'), findsWidgets);
});
testWidgets("About names whose work the instance's dictionaries are", (
tester,
) async {
await pumpApp(
tester,
testDependencies(dictionaryGateway: FakeDictionaryGateway()),
location: RoutePaths.settings,
);
await tester.scrollUntilVisible(
find.text('About Halkyon Learn'),
200,
scrollable: find.byType(Scrollable).first,
);
await tester.tap(find.text('About Halkyon Learn'));
await tester.pumpAndSettle();
expect(find.text('Dictionaries on this instance'), findsOneWidget);
expect(
find.text(
'JMdict: Electronic Dictionary Research and Development Group '
'(EDRDG), CC-BY-SA-4.0',
),
findsOneWidget,
);
});
}