shufle order

This commit is contained in:
gitea
2026-01-31 00:32:48 +01:00
parent 2ea573642d
commit 7ab2eb2ba4
15 changed files with 427 additions and 161 deletions
@@ -3,6 +3,7 @@ import 'package:practice_engine/models/deck.dart';
import 'package:practice_engine/models/deck_config.dart';
import 'package:practice_engine/models/question.dart';
import 'package:practice_engine/logic/attempt_service.dart';
import 'package:practice_engine/logic/deck_service.dart';
void main() {
group('Attempt Flow', () {
@@ -152,6 +153,51 @@ void main() {
expect(updated.consecutiveCorrect, equals(3));
expect(updated.isKnown, equals(true));
});
test('processAttempt preserves manual mark as known when using current deck state', () {
// One question, not known, no streak
final question = Question(
id: 'q1',
prompt: 'Test',
answers: ['A', 'B'],
correctAnswerIndices: [0],
consecutiveCorrect: 0,
isKnown: false,
);
final testDeck = Deck(
id: 'deck1',
title: 'Test',
description: 'Test',
questions: [question],
config: const DeckConfig(requiredConsecutiveCorrect: 3),
);
final attempt = attemptService.createAttempt(
deck: testDeck,
attemptSize: 1,
);
expect(attempt.questions.single.isKnown, isFalse);
// User marks as known during the attempt (as in the app)
final deckWithManualKnown = DeckService.markQuestionAsKnown(
deck: testDeck,
questionId: question.id,
);
expect(deckWithManualKnown.questions.single.isKnown, isTrue);
// Complete attempt with correct answer, passing deck that has manual known
final answers = {question.id: question.correctIndices.first};
final result = attemptService.processAttempt(
deck: deckWithManualKnown,
attempt: attempt,
answers: answers,
);
// Manual "known" must be preserved in the result
final updated = result.updatedDeck.questions.first;
expect(updated.isKnown, isTrue, reason: 'Manual mark as known must count towards known after attempt');
});
});
}
@@ -96,6 +96,81 @@ void main() {
expect(deck.practicePercentage, equals(100.0));
});
test('progressPercentage is 0 for empty deck', () {
final deck = Deck(
id: 'deck1',
title: 'Empty Deck',
description: 'No questions',
questions: [],
config: defaultConfig,
);
expect(deck.progressPercentage, equals(0.0));
});
test('progressPercentage equals practicePercentage when no partial streak', () {
final deck = Deck(
id: 'deck1',
title: 'Math Deck',
description: 'Basic math',
questions: sampleQuestions,
config: defaultConfig,
);
expect(deck.progressPercentage, closeTo(deck.practicePercentage, 0.01));
});
test('progressPercentage is 100 when all questions are known', () {
final allKnown = sampleQuestions.map((q) => q.copyWith(isKnown: true)).toList();
final deck = Deck(
id: 'deck1',
title: 'All Known',
description: 'All known',
questions: allKnown,
config: defaultConfig,
);
expect(deck.progressPercentage, equals(100.0));
});
test('progressPercentage includes partial credit from consecutiveCorrect', () {
// requiredConsecutiveCorrect is 3 (default). 3 questions: none known, each at 2/3
final withPartial = [
Question(id: 'q1', prompt: 'A', answers: ['x'], correctAnswerIndices: [0], consecutiveCorrect: 2, isKnown: false),
Question(id: 'q2', prompt: 'B', answers: ['x'], correctAnswerIndices: [0], consecutiveCorrect: 2, isKnown: false),
Question(id: 'q3', prompt: 'C', answers: ['x'], correctAnswerIndices: [0], consecutiveCorrect: 2, isKnown: false),
];
final deck = Deck(
id: 'deck1',
title: 'Partial',
description: 'Partial progress',
questions: withPartial,
config: defaultConfig,
);
expect(deck.practicePercentage, equals(0.0));
expect(deck.progressPercentage, closeTo(66.67, 0.01)); // 3 * (2/3) / 3 * 100
});
test('progressPercentage mixes known and partial correctly', () {
final config = DeckConfig(requiredConsecutiveCorrect: 3);
final questions = [
Question(id: 'q1', prompt: 'A', answers: ['x'], correctAnswerIndices: [0], isKnown: true),
Question(id: 'q2', prompt: 'B', answers: ['x'], correctAnswerIndices: [0], consecutiveCorrect: 2, isKnown: false),
Question(id: 'q3', prompt: 'C', answers: ['x'], correctAnswerIndices: [0], consecutiveCorrect: 0, isKnown: false),
];
final deck = Deck(
id: 'deck1',
title: 'Mixed',
description: 'Mixed',
questions: questions,
config: config,
);
// 1.0 + 2/3 + 0 = 1.667; 1.667/3*100 ≈ 55.56
expect(deck.progressPercentage, closeTo(55.56, 0.01));
});
test('copyWith creates new deck with updated fields', () {
final deck = Deck(
id: 'deck1',