import 'package:test/test.dart'; import 'package:practice_engine/models/question.dart'; import 'package:practice_engine/models/deck_config.dart'; import 'package:practice_engine/logic/deck_service.dart'; void main() { group('Question State Transitions', () { late DeckConfig config; setUp(() { config = const DeckConfig(requiredConsecutiveCorrect: 3); }); test('correct answer increments streak', () { final question = Question( id: 'q1', prompt: 'Test', answers: ['A', 'B'], correctAnswerIndices: [0], consecutiveCorrect: 1, ); final updated = DeckService.updateQuestionAfterAnswer( question: question, isCorrect: true, config: config, currentAttemptIndex: 0, ); expect(updated.consecutiveCorrect, equals(2)); }); test('incorrect answer resets streak', () { final question = Question( id: 'q1', prompt: 'Test', answers: ['A', 'B'], correctAnswerIndices: [0], consecutiveCorrect: 2, ); final updated = DeckService.updateQuestionAfterAnswer( question: question, isCorrect: false, config: config, currentAttemptIndex: 0, ); expect(updated.consecutiveCorrect, equals(0)); }); test('question becomes known when streak reaches threshold', () { final question = Question( id: 'q1', prompt: 'Test', answers: ['A', 'B'], correctAnswerIndices: [0], consecutiveCorrect: 2, isKnown: false, ); final updated = DeckService.updateQuestionAfterAnswer( question: question, isCorrect: true, config: config, currentAttemptIndex: 0, ); expect(updated.consecutiveCorrect, equals(3)); expect(updated.isKnown, equals(true)); }); test('incorrect answer sets isKnown to false', () { final question = Question( id: 'q1', prompt: 'Test', answers: ['A', 'B'], correctAnswerIndices: [0], consecutiveCorrect: 3, isKnown: true, ); final updated = DeckService.updateQuestionAfterAnswer( question: question, isCorrect: false, config: config, currentAttemptIndex: 0, ); expect(updated.isKnown, equals(false)); expect(updated.consecutiveCorrect, equals(0)); }); test('priority increases on incorrect answer', () { final question = Question( id: 'q1', prompt: 'Test', answers: ['A', 'B'], correctAnswerIndices: [0], priorityPoints: 5, ); final updated = DeckService.updateQuestionAfterAnswer( question: question, isCorrect: false, config: config, currentAttemptIndex: 0, ); expect(updated.priorityPoints, equals(5 + config.priorityIncreaseOnIncorrect)); }); test('priority decreases on correct answer', () { final question = Question( id: 'q1', prompt: 'Test', answers: ['A', 'B'], correctAnswerIndices: [0], priorityPoints: 10, ); final updated = DeckService.updateQuestionAfterAnswer( question: question, isCorrect: true, config: config, currentAttemptIndex: 0, ); expect(updated.priorityPoints, equals(10 - config.priorityDecreaseOnCorrect)); }); test('priority cannot go below 0', () { final question = Question( id: 'q1', prompt: 'Test', answers: ['A', 'B'], correctAnswerIndices: [0], priorityPoints: 1, ); final updated = DeckService.updateQuestionAfterAnswer( question: question, isCorrect: true, config: config, currentAttemptIndex: 0, ); expect(updated.priorityPoints, equals(0)); }); test('lastAttemptIndex is updated', () { final question = Question( id: 'q1', prompt: 'Test', answers: ['A', 'B'], correctAnswerIndices: [0], lastAttemptIndex: 5, ); final updated = DeckService.updateQuestionAfterAnswer( question: question, isCorrect: true, config: config, currentAttemptIndex: 10, ); expect(updated.lastAttemptIndex, equals(10)); }); test('totalAttempts increments on both correct and incorrect', () { final question = Question( id: 'q1', prompt: 'Test', answers: ['A', 'B'], correctAnswerIndices: [0], totalAttempts: 5, totalCorrectAttempts: 3, ); final updatedCorrect = DeckService.updateQuestionAfterAnswer( question: question, isCorrect: true, config: config, currentAttemptIndex: 0, ); expect(updatedCorrect.totalAttempts, equals(6)); expect(updatedCorrect.totalCorrectAttempts, equals(4)); final updatedIncorrect = DeckService.updateQuestionAfterAnswer( question: question, isCorrect: false, config: config, currentAttemptIndex: 0, ); expect(updatedIncorrect.totalAttempts, equals(6)); expect(updatedIncorrect.totalCorrectAttempts, equals(3)); }); }); }