Search in sources :

Example 81 with DeckConfig

use of com.ichi2.libanki.DeckConfig in project Anki-Android by ankidroid.

the class SchedV2Test method test_reviewsV2.

@Test
public void test_reviewsV2() throws Exception {
    Collection col = getColV2();
    // add a note
    Note note = col.newNote();
    note.setItem("Front", "one");
    note.setItem("Back", "two");
    col.addNote(note);
    // set the card up as a review card, due 8 days ago
    Card c = note.cards().get(0);
    c.setType(CARD_TYPE_REV);
    c.setQueue(QUEUE_TYPE_REV);
    c.setDue(col.getSched().getToday() - 8);
    c.setFactor(STARTING_FACTOR);
    c.setReps(3);
    c.setLapses(1);
    c.setIvl(100);
    c.startTimer();
    c.flush();
    // save it for later use as well
    Card cardcopy = c.clone();
    // try with an ease of 2
    // //////////////////////////////////////////////////////////////////////////////////////////////////
    c = cardcopy.clone();
    c.flush();
    col.reset();
    col.getSched().answerCard(c, BUTTON_TWO);
    assertEquals(QUEUE_TYPE_REV, c.getQueue());
    // the new interval should be (100) * 1.2 = 120
    assertTrue(checkRevIvl(col, c, 120));
    assertEquals(col.getSched().getToday() + c.getIvl(), c.getDue());
    // factor should have been decremented
    assertEquals(2350, c.getFactor());
    // check counters
    assertEquals(1, c.getLapses());
    assertEquals(4, c.getReps());
    // ease 3
    // //////////////////////////////////////////////////////////////////////////////////////////////////
    c = cardcopy.clone();
    c.flush();
    col.getSched().answerCard(c, BUTTON_THREE);
    // the new interval should be (100 + 8/2) * 2.5 = 260
    assertTrue(checkRevIvl(col, c, 260));
    assertEquals(col.getSched().getToday() + c.getIvl(), c.getDue());
    // factor should have been left alone
    assertEquals(STARTING_FACTOR, c.getFactor());
    // ease 4
    // //////////////////////////////////////////////////////////////////////////////////////////////////
    c = cardcopy.clone();
    c.flush();
    col.getSched().answerCard(c, BUTTON_FOUR);
    // the new interval should be (100 + 8) * 2.5 * 1.3 = 351
    assertTrue(checkRevIvl(col, c, 351));
    assertEquals(col.getSched().getToday() + c.getIvl(), c.getDue());
    // factor should have been increased
    assertEquals(2650, c.getFactor());
    // leech handling
    // //////////////////////////////////////////////////////////////////////////////////////////////////
    DeckConfig conf = col.getDecks().getConf(1);
    conf.getJSONObject("lapse").put("leechAction", LEECH_SUSPEND);
    col.getDecks().save(conf);
    c = cardcopy.clone();
    c.setLapses(7);
    c.flush();
/* todo hook
        // steup hook
        hooked = new [] {};

        def onLeech(card):
        hooked.append(1);

        hooks.card_did_leech.append(onLeech);
        col.getSched().answerCard(c, BUTTON_ONE);
        assertTrue(hooked);
        assertEquals(QUEUE_TYPE_SUSPENDED, c.getQueue());
        c.load();
        assertEquals(QUEUE_TYPE_SUSPENDED, c.getQueue());
        */
}
Also used : Note(com.ichi2.libanki.Note) Collection(com.ichi2.libanki.Collection) DeckConfig(com.ichi2.libanki.DeckConfig) Card(com.ichi2.libanki.Card) RobolectricTest(com.ichi2.anki.RobolectricTest) Test(org.junit.Test)

Example 82 with DeckConfig

use of com.ichi2.libanki.DeckConfig in project Anki-Android by ankidroid.

the class SchedTest method test_failmultV1.

@Test
public void test_failmultV1() throws Exception {
    Collection col = getColV1();
    Note note = col.newNote();
    note.setItem("Front", "one");
    note.setItem("Back", "two");
    col.addNote(note);
    Card c = note.cards().get(0);
    c.setType(CARD_TYPE_REV);
    c.setQueue(QUEUE_TYPE_REV);
    c.setIvl(100);
    c.setDue(col.getSched().getToday() - c.getIvl());
    c.setFactor(STARTING_FACTOR);
    c.setReps(3);
    c.setLapses(1);
    c.startTimer();
    c.flush();
    DeckConfig conf = col.getSched()._cardConf(c);
    conf.getJSONObject("lapse").put("mult", 0.5);
    col.getDecks().save(conf);
    c = getCard();
    col.getSched().answerCard(c, BUTTON_ONE);
    assertEquals(50, c.getIvl());
    col.getSched().answerCard(c, BUTTON_ONE);
    assertEquals(25, c.getIvl());
}
Also used : Note(com.ichi2.libanki.Note) Collection(com.ichi2.libanki.Collection) DeckConfig(com.ichi2.libanki.DeckConfig) Card(com.ichi2.libanki.Card) RobolectricTest(com.ichi2.anki.RobolectricTest) Test(org.junit.Test)

Example 83 with DeckConfig

use of com.ichi2.libanki.DeckConfig in project Anki-Android by ankidroid.

the class SchedTest method test_nextIvlV1.

@Test
public void test_nextIvlV1() throws Exception {
    Collection col = getColV1();
    Note note = col.newNote();
    note.setItem("Front", "one");
    note.setItem("Back", "two");
    col.addNote(note);
    col.reset();
    DeckConfig conf = col.getDecks().confForDid(1);
    conf.getJSONObject("new").put("delays", new JSONArray(new double[] { 0.5, 3, 10 }));
    conf.getJSONObject("lapse").put("delays", new JSONArray(new double[] { 1, 5, 9 }));
    col.getDecks().save(conf);
    Card c = getCard();
    // new cards
    // //////////////////////////////////////////////////////////////////////////////////////////////////
    assertEquals(30, col.getSched().nextIvl(c, BUTTON_ONE));
    assertEquals(180, col.getSched().nextIvl(c, BUTTON_TWO));
    assertEquals(4 * SECONDS_PER_DAY, col.getSched().nextIvl(c, BUTTON_THREE));
    col.getSched().answerCard(c, BUTTON_ONE);
    // cards in learning
    // //////////////////////////////////////////////////////////////////////////////////////////////////
    assertEquals(30, col.getSched().nextIvl(c, BUTTON_ONE));
    assertEquals(180, col.getSched().nextIvl(c, BUTTON_TWO));
    assertEquals(4 * SECONDS_PER_DAY, col.getSched().nextIvl(c, BUTTON_THREE));
    col.getSched().answerCard(c, BUTTON_TWO);
    assertEquals(30, col.getSched().nextIvl(c, BUTTON_ONE));
    assertEquals(600, col.getSched().nextIvl(c, BUTTON_TWO));
    assertEquals(4 * SECONDS_PER_DAY, col.getSched().nextIvl(c, BUTTON_THREE));
    col.getSched().answerCard(c, BUTTON_TWO);
    // normal graduation is tomorrow
    assertEquals(SECONDS_PER_DAY, col.getSched().nextIvl(c, BUTTON_TWO));
    assertEquals(4 * SECONDS_PER_DAY, col.getSched().nextIvl(c, BUTTON_THREE));
    // lapsed cards
    // //////////////////////////////////////////////////////////////////////////////////////////////////
    c.setType(CARD_TYPE_REV);
    c.setIvl(100);
    c.setFactor(STARTING_FACTOR);
    assertEquals(60, col.getSched().nextIvl(c, BUTTON_ONE));
    assertEquals(100 * SECONDS_PER_DAY, col.getSched().nextIvl(c, BUTTON_TWO));
    assertEquals(100 * SECONDS_PER_DAY, col.getSched().nextIvl(c, BUTTON_THREE));
    // review cards
    // //////////////////////////////////////////////////////////////////////////////////////////////////
    c.setQueue(QUEUE_TYPE_REV);
    c.setIvl(100);
    c.setFactor(STARTING_FACTOR);
    // failing it should put it at 60s
    assertEquals(60, col.getSched().nextIvl(c, BUTTON_ONE));
    // or 1 day if relearn is false
    conf.getJSONObject("lapse").put("delays", new JSONArray(new double[] {}));
    col.getDecks().save(conf);
    assertEquals(SECONDS_PER_DAY, col.getSched().nextIvl(c, BUTTON_ONE));
    // (* 100 1.2 SECONDS_PER_DAY)10368000.0
    assertEquals(10368000, col.getSched().nextIvl(c, BUTTON_TWO));
    // (* 100 2.5 SECONDS_PER_DAY)21600000.0
    assertEquals(21600000, col.getSched().nextIvl(c, BUTTON_THREE));
    // (* 100 2.5 1.3 SECONDS_PER_DAY)28080000.0
    assertEquals(28080000, col.getSched().nextIvl(c, BUTTON_FOUR));
    assertThat(without_unicode_isolation(col.getSched().nextIvlStr(getTargetContext(), c, BUTTON_FOUR)), is("10.8 mo"));
}
Also used : Note(com.ichi2.libanki.Note) JSONArray(com.ichi2.utils.JSONArray) Collection(com.ichi2.libanki.Collection) DeckConfig(com.ichi2.libanki.DeckConfig) Card(com.ichi2.libanki.Card) RobolectricTest(com.ichi2.anki.RobolectricTest) Test(org.junit.Test)

Example 84 with DeckConfig

use of com.ichi2.libanki.DeckConfig in project Anki-Android by ankidroid.

the class SchedTest method test_timingV1.

@Test
public void test_timingV1() throws Exception {
    Collection col = getColV1();
    // add a few review cards, due today
    for (int i = 0; i < 5; i++) {
        Note note = col.newNote();
        note.setItem("Front", "num" + i);
        col.addNote(note);
        Card c = note.cards().get(0);
        c.setType(CARD_TYPE_REV);
        c.setQueue(QUEUE_TYPE_REV);
        c.setDue(0);
        c.flush();
    }
    // fail the first one
    col.reset();
    Card c = getCard();
    // set a a fail delay of 4 seconds
    DeckConfig conf = col.getSched()._cardConf(c);
    conf.getJSONObject("lapse").getJSONArray("delays").put(0, 1 / 15.0);
    col.getDecks().save(conf);
    col.getSched().answerCard(c, BUTTON_ONE);
    // the next card should be another review
    c = getCard();
    assertEquals(QUEUE_TYPE_REV, c.getQueue());
/* TODO time
        // but if we wait for a few seconds, the failed card should come back
        orig_time = time.time;

        def adjusted_time():
        return orig_time() + 5;

        time.time = adjusted_time;
        c = getCard();
        assertEquals(QUEUE_TYPE_LRN, c.getQueue());
        time.time = orig_time;

        */
}
Also used : Note(com.ichi2.libanki.Note) Collection(com.ichi2.libanki.Collection) DeckConfig(com.ichi2.libanki.DeckConfig) Card(com.ichi2.libanki.Card) RobolectricTest(com.ichi2.anki.RobolectricTest) Test(org.junit.Test)

Example 85 with DeckConfig

use of com.ichi2.libanki.DeckConfig in project Anki-Android by ankidroid.

the class SchedTest method test_learnV1.

@Test
public void test_learnV1() throws Exception {
    Collection col = getColV1();
    // add a note
    Note note = col.newNote();
    note.setItem("Front", "one");
    note.setItem("Back", "two");
    col.addNote(note);
    // set as a learn card and rebuild queues
    col.getDb().execute("update cards set queue=0, type=0");
    col.reset();
    // sched.getCard should return it, since it's due in the past
    Card c = getCard();
    assertNotNull(c);
    DeckConfig conf = col.getSched()._cardConf(c);
    conf.getJSONObject("new").put("delays", new JSONArray(new double[] { 0.5, 3, 10 }));
    col.getDecks().save(conf);
    // fail it
    col.getSched().answerCard(c, BUTTON_ONE);
    // it should have three reps left to graduation
    assertEquals(3, c.getLeft() % 1000);
    assertEquals(3, c.getLeft() / 1000);
    // it should be due in 30 seconds
    long t = Math.round(c.getDue() - col.getTime().intTime());
    assertThat(t, is(greaterThanOrEqualTo(25L)));
    assertThat(t, is(lessThanOrEqualTo(40L)));
    // pass it once
    col.getSched().answerCard(c, BUTTON_TWO);
    // it should be due in 3 minutes
    assertEquals(Math.round(c.getDue() - col.getTime().intTime()), 179, 1);
    assertEquals(2, c.getLeft() % 1000);
    assertEquals(2, c.getLeft() / 1000);
    // check log is accurate
    Cursor log = col.getDb().getDatabase().query("select * from revlog order by id desc");
    assertTrue(log.moveToFirst());
    assertEquals(2, log.getInt(3));
    assertEquals(-180, log.getInt(4));
    assertEquals(-30, log.getInt(5));
    // pass again
    col.getSched().answerCard(c, BUTTON_TWO);
    // it should be due in 10 minutes
    assertEquals(c.getDue() - col.getTime().intTime(), 599, 1);
    assertEquals(1, c.getLeft() % 1000);
    assertEquals(1, c.getLeft() / 1000);
    // the next pass should graduate the card
    assertEquals(QUEUE_TYPE_LRN, c.getQueue());
    assertEquals(CARD_TYPE_LRN, c.getType());
    col.getSched().answerCard(c, BUTTON_TWO);
    assertEquals(QUEUE_TYPE_REV, c.getQueue());
    assertEquals(CARD_TYPE_REV, c.getType());
    // should be due tomorrow, with an interval of 1
    assertEquals(col.getSched().getToday() + 1, c.getDue());
    assertEquals(1, c.getIvl());
    // or normal removal
    c.setType(CARD_TYPE_NEW);
    c.setQueue(QUEUE_TYPE_LRN);
    col.getSched().answerCard(c, BUTTON_THREE);
    assertEquals(CARD_TYPE_REV, c.getType());
    assertEquals(QUEUE_TYPE_REV, c.getQueue());
    assertTrue(checkRevIvl(col, c, 4));
    // revlog should have been updated each time
    assertEquals(5, col.getDb().queryScalar("select count() from revlog where type = 0"));
    // now failed card handling
    c.setType(CARD_TYPE_REV);
    c.setQueue(QUEUE_TYPE_LRN);
    c.setODue(123);
    col.getSched().answerCard(c, BUTTON_THREE);
    assertEquals(123, c.getDue());
    assertEquals(CARD_TYPE_REV, c.getType());
    assertEquals(QUEUE_TYPE_REV, c.getQueue());
    // we should be able to remove manually, too
    c.setType(CARD_TYPE_REV);
    c.setQueue(QUEUE_TYPE_LRN);
    c.setODue(321);
    c.flush();
    ((Sched) col.getSched()).removeLrn();
    c.load();
    assertEquals(QUEUE_TYPE_REV, c.getQueue());
    assertEquals(321, c.getDue());
}
Also used : Note(com.ichi2.libanki.Note) JSONArray(com.ichi2.utils.JSONArray) Collection(com.ichi2.libanki.Collection) Cursor(android.database.Cursor) DeckConfig(com.ichi2.libanki.DeckConfig) Card(com.ichi2.libanki.Card) RobolectricTest(com.ichi2.anki.RobolectricTest) Test(org.junit.Test)

Aggregations

DeckConfig (com.ichi2.libanki.DeckConfig)85 Collection (com.ichi2.libanki.Collection)57 Card (com.ichi2.libanki.Card)50 Test (org.junit.Test)49 RobolectricTest (com.ichi2.anki.RobolectricTest)48 Note (com.ichi2.libanki.Note)47 JSONArray (com.ichi2.utils.JSONArray)42 JSONObject (com.ichi2.utils.JSONObject)27 Deck (com.ichi2.libanki.Deck)14 NonNull (androidx.annotation.NonNull)12 Cursor (android.database.Cursor)5 JSONException (com.ichi2.utils.JSONException)5 ArrayList (java.util.ArrayList)5 Model (com.ichi2.libanki.Model)4 HashMap (java.util.HashMap)4 SuppressLint (android.annotation.SuppressLint)3 Map (java.util.Map)3 TreeMap (java.util.TreeMap)3 ContentValues (android.content.ContentValues)2 Intent (android.content.Intent)2