#include "SRModel_schedule_test.h" #include "../../../src/utils/TimeProvider.h" const double SRModel_schedule_Test::startE = StudySettings().initEasiness; void SRModel_schedule_Test::SetUp() { StudySettings::inst()->schedRandomness = StudySettings().schedRandomness; randomGenerator->setDouble(0.3); cardName = createCard(); } static const StudySettings* ss = StudySettings::inst(); // New // Grades 1, 2, 3 not used TEST_F(SRModel_schedule_Test, new_good) // Levels: 1 -> 2 { setNewCard(); schedule(4); checkStudy(StudyRecord::ShortLearning, startE, ss->unknownInterval); } TEST_F(SRModel_schedule_Test, new_easy) // Levels: 1 -> 3 { setNewCard(); schedule(5); checkStudy(StudyRecord::LongLearning, startE, ss->learningInterval); } // Short Learning TEST_F(SRModel_schedule_Test, short_unknown) // same level { setStudy({StudyRecord::ShortLearning, 4, startE, ss->unknownInterval}); schedule(1); checkStudy(StudyRecord::ShortLearning, startE, ss->unknownInterval); } TEST_F(SRModel_schedule_Test, short_incor) // same level with longer interval { setStudy({StudyRecord::ShortLearning, 4, startE, ss->unknownInterval}); schedule(2); checkStudy(StudyRecord::ShortLearning, startE, ss->incorrectInterval); } // grade 3 not used TEST_F(SRModel_schedule_Test, short_good) // Levels: 2 -> 3 { setStudy({StudyRecord::ShortLearning, 4, startE, ss->unknownInterval}); schedule(4); checkStudy(StudyRecord::LongLearning, startE, ss->learningInterval); } TEST_F(SRModel_schedule_Test, short_easy) // Levels: 2 -> repeat next day { setStudy({StudyRecord::ShortLearning, 4, startE, ss->unknownInterval}); schedule(5); checkStudy(StudyRecord::Repeating, startE, ss->nextDayInterval); } // Short learning from previous day: // Is promoted directly to next day repeating TEST_F(SRModel_schedule_Test, short_prevDay_difficult) { setStudy({StudyRecord::ShortLearning, 4, 2.5, ss->unknownInterval}, -1); schedule(3); checkStudy(StudyRecord::Repeating, 2.36, 2.18772); } TEST_F(SRModel_schedule_Test, short_prevDay_good) { setStudy({StudyRecord::ShortLearning, 4, startE, ss->unknownInterval}, -1); schedule(4); checkStudy(StudyRecord::Repeating, startE, 2.3175); } TEST_F(SRModel_schedule_Test, short_prevDay_easy) { setStudy({StudyRecord::ShortLearning, 4, 2.5, ss->unknownInterval}, -1); schedule(5); checkStudy(StudyRecord::Repeating, 2.6, 2.4102); } // Long Learning TEST_F(SRModel_schedule_Test, long_unknown) // Levels: 3 -> 2 { setStudy({StudyRecord::LongLearning, 4, startE, ss->learningInterval}); schedule(1); checkStudy(StudyRecord::ShortLearning, startE, ss->unknownInterval); } TEST_F(SRModel_schedule_Test, long_incor) // Levels: 3 -> 2 { setStudy({StudyRecord::LongLearning, 4, startE, ss->learningInterval}); schedule(2); checkStudy(StudyRecord::ShortLearning, startE, ss->incorrectInterval); } // grade 3 not used TEST_F(SRModel_schedule_Test, long_good) // Levels: 3 -> repeat next day { setStudy({StudyRecord::LongLearning, 4, startE, ss->learningInterval}); schedule(4); checkStudy(StudyRecord::Repeating, startE, ss->nextDayInterval); } TEST_F(SRModel_schedule_Test, long_easy) // Levels: 3 -> repeat in 2 days { setStudy({StudyRecord::LongLearning, 4, startE, ss->learningInterval}); schedule(5); checkStudy(StudyRecord::Repeating, startE, ss->twoDaysInterval); } // Long learning from previous day: // Is promoted directly to next day repeating TEST_F(SRModel_schedule_Test, long_prevDay_difficult) { setStudy({StudyRecord::LongLearning, 4, 2.5, ss->learningInterval}, -1); schedule(3); checkStudy(StudyRecord::Repeating, 2.36, 2.18772); } TEST_F(SRModel_schedule_Test, long_prevDay_good) { setStudy({StudyRecord::LongLearning, 4, startE, ss->learningInterval}, -1); schedule(4); checkStudy(StudyRecord::Repeating, startE, 2.3175); } TEST_F(SRModel_schedule_Test, long_prevDay_easy) { setStudy({StudyRecord::LongLearning, 4, 2.5, ss->learningInterval}, -1); schedule(5); checkStudy(StudyRecord::Repeating, 2.6, 2.4102); } // First repeating day TEST_F(SRModel_schedule_Test, firstRep_unknown) // -> 2 { setStudy({StudyRecord::Repeating, 4, startE, ss->nextDayInterval}); schedule(1); checkStudy(StudyRecord::ShortLearning, startE, ss->unknownInterval); } TEST_F(SRModel_schedule_Test, firstRep_incor) // -> 2 { setStudy({StudyRecord::Repeating, 4, startE, ss->nextDayInterval}); schedule(2); checkStudy(StudyRecord::ShortLearning, startE, ss->incorrectInterval); } TEST_F(SRModel_schedule_Test, firstRep_difficult) { setStudy({StudyRecord::Repeating, 4, startE, ss->nextDayInterval}); schedule(3); checkStudy(StudyRecord::Repeating, 2.36, 2.18772); } TEST_F(SRModel_schedule_Test, firstRep_good) { setStudy({StudyRecord::Repeating, 4, startE, ss->nextDayInterval}); schedule(4); checkStudy(StudyRecord::Repeating, startE, 2.3175); } TEST_F(SRModel_schedule_Test, firstRep_easy) { setStudy({StudyRecord::Repeating, 4, startE, ss->nextDayInterval}); schedule(5); checkStudy(StudyRecord::Repeating, 2.6, 2.4102); } // Normal repeating TEST_F(SRModel_schedule_Test, repeat_unknown) { setStudy({StudyRecord::Repeating, 4, startE, 5}); schedule(1); checkStudy(StudyRecord::ShortLearning, startE, ss->unknownInterval); } TEST_F(SRModel_schedule_Test, repeat_incor) { setStudy({StudyRecord::Repeating, 4, startE, 5}); schedule(2); checkStudy(StudyRecord::ShortLearning, startE, ss->incorrectInterval); } TEST_F(SRModel_schedule_Test, repeat_difficult) { setStudy({StudyRecord::Repeating, 4, 2.5, 5}); schedule(3); checkStudy(StudyRecord::Repeating, 2.36, 12.1540); } TEST_F(SRModel_schedule_Test, repeat_good) { setStudy({StudyRecord::Repeating, 4, startE, 5}); schedule(4); checkStudy(StudyRecord::Repeating, startE, 12.875); } TEST_F(SRModel_schedule_Test, repeat_easy) { setStudy({StudyRecord::Repeating, 4, 2.5, 5}); schedule(5); checkStudy(StudyRecord::Repeating, 2.6, 13.39); } // Mature repeating TEST_F(SRModel_schedule_Test, mature_difficult) { setStudy({StudyRecord::Repeating, 4, 3.1, 23}); schedule(3); checkStudy(StudyRecord::Repeating, 2.96, 70.1224); } TEST_F(SRModel_schedule_Test, mature_good) { setStudy({StudyRecord::Repeating, 4, 3.1, 23}); schedule(4); checkStudy(StudyRecord::Repeating, 3.1, 73.439); } // Re-learning unknown and incorrect cards TEST_F(SRModel_schedule_Test, unknown_incor) { setStudy({StudyRecord::ShortLearning, 1, startE, ss->unknownInterval}); schedule(2); checkStudy(StudyRecord::ShortLearning, startE, ss->incorrectInterval); } TEST_F(SRModel_schedule_Test, incor_unknown) { setStudy({StudyRecord::ShortLearning, 2, startE, ss->incorrectInterval}); schedule(1); checkStudy(StudyRecord::ShortLearning, startE, ss->unknownInterval); } TEST_F(SRModel_schedule_Test, unknown_good) { setStudy({StudyRecord::ShortLearning, 1, startE, ss->unknownInterval}); schedule(4); checkStudy(StudyRecord::LongLearning, startE, ss->learningInterval); } TEST_F(SRModel_schedule_Test, incor_good) { setStudy({StudyRecord::ShortLearning, 2, startE, ss->incorrectInterval}); schedule(4); checkStudy(StudyRecord::LongLearning, startE, ss->learningInterval); } void SRModel_schedule_Test::setNewCard() { pack.addStudyRecord(cardName, StudyRecord()); } void SRModel_schedule_Test::setStudy(StudyRecord study, double daysDelta) { study.date = timeFromDelta(daysDelta); pack.addStudyRecord(cardName, study); } QDateTime SRModel_schedule_Test::timeFromDelta(double daysDelta) { return TimeProvider::get().addSecs((int)(daysDelta * 24 * 60 * 60)); } void SRModel_schedule_Test::schedule(int grade) { this->grade = grade; model.scheduleCard(grade); } void SRModel_schedule_Test::checkStudy(int expLevel, double expEasiness, double expInterval) { StudyRecord newStudy = pack.getStudyRecord(cardName); ASSERT_EQ(grade, newStudy.grade); ASSERT_EQ(expLevel, newStudy.level); ASSERT_DOUBLE_EQ(expEasiness, newStudy.easiness); ASSERT_NEAR(expInterval, newStudy.interval, 0.00000001); }