package info.opencards.learnstrats.ltm; import info.opencards.core.FlashCard; import junit.framework.Assert; import org.junit.Test; import java.util.Date; /** * Some unit-tests which aim to ensure that the scheduling algorithm somehow makes sense. * * @author Holger Brandl */ public class SchedulerIntegrityTest { private static final int mxRecursions = 9; // this will aleady take some time /** * Tests that given an item in an arbitrary state, the scheduled dates are monotically increasing with increasingly * positive feedback. */ @Test public void testIntegrity() { LTMItem ltmItem = new LTMItem(new FlashCard(1, "A", 1)); recurseFeedbacks(ltmItem, mxRecursions); } private void recurseFeedbacks(LTMItem ltmItem, int curRecursionDepth) { Date today = ltmItem.getNextScheduledDate(); // System.out.println("Testing item: " + ltmItem.toString()); for (int i = 1; i <= 4; i++) { String errMsg = "mismatch on recDepthLevel=" + (mxRecursions - curRecursionDepth) + " and feeback=" + i + "\n" + ltmItem.toString(); // assume that we've reached <code>today</code> ScheduleUtils.testToday = today; LTMItem curItem = copy(ltmItem); curItem.updateEFactor(i); Date curItDate = curItem.getNextScheduledDate(); LTMItem nextItem = copy(ltmItem); nextItem.updateEFactor(i + 1); // better feedback Date nextItDate = nextItem.getNextScheduledDate(); // scheduling should never schedule something to the past if (!(ScheduleUtils.getDayDiff(curItDate, today) >= 0)) Assert.fail(errMsg); // if the feedback is greater than 2 an item should always be scheduled for a future date if (i > 2 && ScheduleUtils.getDayDiff(curItDate, today) == 0) { Assert.fail(errMsg); } // make sure that the higher feedback gives at least an equal next scheduled review-date if (ScheduleUtils.getDayDiff(curItDate, nextItDate) > 0) Assert.fail(errMsg); } // stop further testing if the maximal recursion depth has been reached if (curRecursionDepth == 0) return; // now recurse into the next level for (int i = 1; i <= 5; i++) { LTMItem updatedItem = copy(ltmItem); updatedItem.updateEFactor(i); recurseFeedbacks(updatedItem, curRecursionDepth - 1); } } private static LTMItem copy(LTMItem ltmItem) { return (LTMItem) ltmItem.clone(); } }