You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
191 lines
5.7 KiB
191 lines
5.7 KiB
import 'package:test/test.dart';
|
|
import 'package:practice_engine/models/deck.dart';
|
|
import 'package:practice_engine/models/deck_config.dart';
|
|
import 'package:practice_engine/models/question.dart';
|
|
|
|
void main() {
|
|
group('Deck', () {
|
|
late DeckConfig defaultConfig;
|
|
late List<Question> sampleQuestions;
|
|
|
|
setUp(() {
|
|
defaultConfig = const DeckConfig();
|
|
sampleQuestions = [
|
|
Question(
|
|
id: 'q1',
|
|
prompt: 'What is 2+2?',
|
|
answers: ['3', '4', '5'],
|
|
correctAnswerIndices: [1],
|
|
isKnown: true,
|
|
),
|
|
Question(
|
|
id: 'q2',
|
|
prompt: 'What is 3+3?',
|
|
answers: ['5', '6', '7'],
|
|
correctAnswerIndices: [1],
|
|
isKnown: false,
|
|
),
|
|
Question(
|
|
id: 'q3',
|
|
prompt: 'What is 4+4?',
|
|
answers: ['7', '8', '9'],
|
|
correctAnswerIndices: [1],
|
|
isKnown: true,
|
|
),
|
|
];
|
|
});
|
|
|
|
test('calculates numberOfQuestions correctly', () {
|
|
final deck = Deck(
|
|
id: 'deck1',
|
|
title: 'Math Deck',
|
|
description: 'Basic math',
|
|
questions: sampleQuestions,
|
|
config: defaultConfig,
|
|
);
|
|
|
|
expect(deck.numberOfQuestions, equals(3));
|
|
});
|
|
|
|
test('calculates knownCount correctly', () {
|
|
final deck = Deck(
|
|
id: 'deck1',
|
|
title: 'Math Deck',
|
|
description: 'Basic math',
|
|
questions: sampleQuestions,
|
|
config: defaultConfig,
|
|
);
|
|
|
|
expect(deck.knownCount, equals(2));
|
|
});
|
|
|
|
test('calculates practicePercentage correctly', () {
|
|
final deck = Deck(
|
|
id: 'deck1',
|
|
title: 'Math Deck',
|
|
description: 'Basic math',
|
|
questions: sampleQuestions,
|
|
config: defaultConfig,
|
|
);
|
|
|
|
expect(deck.practicePercentage, closeTo(66.67, 0.01));
|
|
});
|
|
|
|
test('practicePercentage is 0 for empty deck', () {
|
|
final deck = Deck(
|
|
id: 'deck1',
|
|
title: 'Empty Deck',
|
|
description: 'No questions',
|
|
questions: [],
|
|
config: defaultConfig,
|
|
);
|
|
|
|
expect(deck.practicePercentage, equals(0.0));
|
|
});
|
|
|
|
test('practicePercentage 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.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',
|
|
title: 'Math Deck',
|
|
description: 'Basic math',
|
|
questions: sampleQuestions,
|
|
config: defaultConfig,
|
|
);
|
|
|
|
final updated = deck.copyWith(title: 'Updated Title');
|
|
expect(updated.title, equals('Updated Title'));
|
|
expect(updated.id, equals(deck.id));
|
|
expect(updated.questions, equals(deck.questions));
|
|
});
|
|
});
|
|
}
|
|
|