summaryrefslogtreecommitdiff
path: root/tests/unit/SpacedRepetitionModel/SRModel_schedule_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/unit/SpacedRepetitionModel/SRModel_schedule_test.cpp')
-rw-r--r--tests/unit/SpacedRepetitionModel/SRModel_schedule_test.cpp304
1 files changed, 304 insertions, 0 deletions
diff --git a/tests/unit/SpacedRepetitionModel/SRModel_schedule_test.cpp b/tests/unit/SpacedRepetitionModel/SRModel_schedule_test.cpp
new file mode 100644
index 0000000..cd65154
--- /dev/null
+++ b/tests/unit/SpacedRepetitionModel/SRModel_schedule_test.cpp
@@ -0,0 +1,304 @@
+#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);
+}