feat(app): quiz vocabulary as multiple choice

The session settings' new Vocabulary section quizzes words as multiple
choice: their meaning (the default), their reading, the expression for
the meaning, or the reading and the meaning in turn ("Mixed"). The
wrong answers come from the other words studied; none of the word's
own meanings counts as wrong, whatever its case. A word without what is
asked, or without two others to draw from, stays a word to flip. It is
asked the same way each time it comes, and rated as any card.

The settings keep both (`quizVocabulary`, `quizAspect`; settings schema
5), on every device.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-10-07 21:57:04 +02:00
commit 6893db7da8
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -74,6 +74,28 @@ void main() {
);
});
test('quizzing vocabulary as multiple choice survives a round trip, in the '
'fifth schema; an aspect of a newer app reads as the meaning', () {
const settings = PersonSettings(
study: StudyOptions(
quizVocabulary: true,
quizAspect: VocabularyQuizAspect.mixed,
),
);
expect(settingsSchemaVersion, 5);
expect(decodeSettingsPayload(encodeSettingsPayload(settings)), settings);
expect(
decodeSettingsPayload(
encodePayload(5, {
'studyTags': {},
'study': {'quizVocabulary': true, 'quizAspect': 'kanji'},
}),
).study,
const StudyOptions(quizVocabulary: true),
);
});
test('study options keep their numbers in range', () {
final options = const StudyOptions().copyWith(
cardsPerRound: 50,
@ -166,7 +188,7 @@ void main() {
doNotDisturb: true,
);
test('survive a round trip, in the fourth schema', () {
test('survive a round trip, in the newest schema', () {
const settings = PersonSettings(
pomodoro: PomodoroSettings(
profiles: [PomodoroProfile.classic, mine],
@ -176,18 +198,23 @@ void main() {
final payload = encodeSettingsPayload(settings);
expect(settingsSchemaVersion, 4);
expect(decodePayload(payload, newestSchema: 4)['schemaVersion'], 4);
expect(
decodePayload(
payload,
newestSchema: settingsSchemaVersion,
)['schemaVersion'],
settingsSchemaVersion,
);
expect(decodeSettingsPayload(payload), settings);
});
test('as they come, are left out, in the fourth schema all the same', () {
test('as they come, are left out, in the newest schema all the same', () {
final payload = decodePayload(
encodeSettingsPayload(const PersonSettings()),
newestSchema: 4,
newestSchema: settingsSchemaVersion,
);
expect(payload['schemaVersion'], 4);
expect(payload['schemaVersion'], settingsSchemaVersion);
expect(payload.keys, isNot(contains('pomodoro')));
});