feat(app): kanji and kana in the dictionary, beside the words
Where the instance holds the characters of a studyset's language, the dictionary screen has a tab for them, Kanji & kana: search by character, reading (kana or romaji) or meaning, and whole levels to add, under their names: the kana (hiragana, katakana), the JLPT levels and the school grades. A character becomes a character card, its meanings (a kana's romaji) and readings, tagged with its level (JLPT-N5), school grade (Grade 1 … Grade 6, Secondary school) and script (Hiragana, Katakana). A character card's Look up searches the characters, and an entry looked up again on a card swaps the tags the one before brought, as words do. A dictionary's entries are now words or characters (DictionaryItem), as its kind says. 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>
This commit is contained in:
parent
2fc4205010
commit
cec518350a
1 changed files with 1034 additions and 158 deletions
|
|
@ -2,6 +2,7 @@ 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/card/model/card_content.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';
|
||||
|
|
@ -36,6 +37,23 @@ final toukyou = word(
|
|||
pos: ['n'],
|
||||
);
|
||||
|
||||
final shoku = character(
|
||||
'食',
|
||||
meanings: ['eat', 'food'],
|
||||
on: ['ショク'],
|
||||
kun: ['た.べる'],
|
||||
labels: ['jlpt:n5', 'grade:2'],
|
||||
grade: 2,
|
||||
strokes: 9,
|
||||
);
|
||||
final a = character('あ', labels: ['hiragana'], romaji: 'a');
|
||||
|
||||
/// An instance with JMdict and KANJIDIC2.
|
||||
FakeDictionaryGateway withKanji() => FakeDictionaryGateway(
|
||||
available: [jmdict, kanjidic],
|
||||
words: [taberu, terebi, shoku, a],
|
||||
);
|
||||
|
||||
void main() {
|
||||
late FakeCardGateway cardGateway;
|
||||
late CardRepository cards;
|
||||
|
|
@ -203,6 +221,72 @@ void main() {
|
|||
);
|
||||
});
|
||||
|
||||
testWidgets('beside the words, kanji and kana: their levels in groups, '
|
||||
'one added as character cards tagged with level and grade', (
|
||||
tester,
|
||||
) async {
|
||||
await show(tester, dictionaries: withKanji());
|
||||
await addMaterial(tester, 'From the dictionary');
|
||||
|
||||
expect(find.text('Words'), findsOneWidget);
|
||||
await tester.tap(find.text('Kanji & kana'));
|
||||
await settle(tester);
|
||||
expect(find.text('Kana'), findsOneWidget);
|
||||
expect(find.text('JLPT levels'), findsOneWidget);
|
||||
expect(find.text('School grades'), findsOneWidget);
|
||||
expect(find.text('Grade 2'), findsOneWidget);
|
||||
await tester.tap(find.text('N5').hitTestable());
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.text('Add 1 character'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('Added 1 character.'), findsOneWidget);
|
||||
final made = (await cards.cardsOf('japanese')).single;
|
||||
expect(made.content.type, CardType.character);
|
||||
expect(made.content.onReadings, ['ショク']);
|
||||
expect(made.content.entry, (source: 'kanjidic', id: '食'));
|
||||
});
|
||||
|
||||
testWidgets('a character found shows its readings and strokes, and is '
|
||||
'added as a card', (tester) async {
|
||||
await show(tester, dictionaries: withKanji());
|
||||
await addMaterial(tester, 'From the dictionary');
|
||||
await tester.tap(find.text('Kanji & kana'));
|
||||
await settle(tester);
|
||||
|
||||
await tester.enterText(find.byType(TextField).hitTestable(), 'ショク');
|
||||
await tester.pump(const Duration(milliseconds: 300));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('ショク · た.べる'), findsOneWidget);
|
||||
expect(find.text('9 strokes'), findsOneWidget);
|
||||
await tester.tap(find.text('Add').hitTestable());
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('Added “食”.'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Look up fills a character card with its meanings, readings '
|
||||
'and tags', (tester) async {
|
||||
await show(tester, dictionaries: withKanji());
|
||||
await addMaterial(tester, 'Create flashcards');
|
||||
await tester.tap(find.text('Character'));
|
||||
await settle(tester);
|
||||
|
||||
await tester.tap(find.byTooltip('Look up in the dictionary'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.enterText(find.byType(TextField).last, 'eat');
|
||||
await tester.pump(const Duration(milliseconds: 300));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.text('eat; food'));
|
||||
await settle(tester);
|
||||
|
||||
expect(find.widgetWithText(TextField, 'eat'), findsOneWidget);
|
||||
expect(find.widgetWithText(TextField, 'ショク'), findsOneWidget);
|
||||
expect(find.widgetWithText(TextField, 'た.べる'), findsOneWidget);
|
||||
expect(find.text('JLPT-N5'), findsOneWidget);
|
||||
expect(find.text('Grade 2'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Look up fills a vocabulary card with a word of the '
|
||||
'dictionary', (tester) async {
|
||||
await show(tester);
|
||||
|
|
|
|||
Loading…
Reference in a new issue