Search in sources :

Example 16 with AbstractSched

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

the class SchedV2Test method regression_test_preview.

@Test
public void regression_test_preview() throws Exception {
    // "https://github.com/ankidroid/Anki-Android/issues/7285"
    Collection col = getColV2();
    DeckManager decks = col.getDecks();
    AbstractSched sched = col.getSched();
    addNoteUsingBasicModel("foo", "bar");
    long did = addDynamicDeck("test");
    Deck deck = decks.get(did);
    deck.put("resched", false);
    sched.rebuildDyn(did);
    col.reset();
    Card card;
    for (int i = 0; i < 3; i++) {
        advanceRobolectricLooperWithSleep();
        card = sched.getCard();
        assertNotNull(card);
        sched.answerCard(card, BUTTON_ONE);
    }
    advanceRobolectricLooperWithSleep();
    assertEquals(1, sched.lrnCount());
    card = sched.getCard();
    assertEquals(1, sched.counts(card).getLrn());
    advanceRobolectricLooperWithSleep();
    sched.answerCard(card, BUTTON_ONE);
    assertDoesNotThrow(col::undo);
}
Also used : Collection(com.ichi2.libanki.Collection) Deck(com.ichi2.libanki.Deck) DeckManager(com.ichi2.libanki.DeckManager) Card(com.ichi2.libanki.Card) RobolectricTest(com.ichi2.anki.RobolectricTest) Test(org.junit.Test)

Example 17 with AbstractSched

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

the class DeckPickerTest method limitAppliedAfterReview.

@Test
public void limitAppliedAfterReview() {
    Collection col = getCol();
    AbstractSched sched = col.getSched();
    DeckConfig dconf = col.getDecks().getConf(1);
    assertNotNull(dconf);
    dconf.getJSONObject("new").put("perDay", 10);
    col.getDecks().save(dconf);
    for (int i = 0; i < 11; i++) {
        addNoteUsingBasicModel("Which card is this ?", Integer.toString(i));
    }
    // This set a card as current card
    sched.getCard();
    ensureCollectionLoadIsSynchronous();
    DeckPicker deckPicker = super.startActivityNormallyOpenCollectionWithIntent(DeckPicker.class, new Intent());
    assertEquals(10, deckPicker.mDueTree.get(0).getNewCount());
}
Also used : AbstractSched(com.ichi2.libanki.sched.AbstractSched) Collection(com.ichi2.libanki.Collection) Intent(android.content.Intent) DeckConfig(com.ichi2.libanki.DeckConfig) Test(org.junit.Test)

Example 18 with AbstractSched

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

the class Collection method createScheduler.

// This duplicates _loadScheduler (but returns the value and sets the report limit).
public AbstractSched createScheduler(int reportLimit) {
    int ver = schedVer();
    if (ver == 1) {
        mSched = new Sched(this);
    } else if (ver == 2) {
        mSched = new SchedV2(this);
    }
    mSched.setReportLimit(reportLimit);
    return mSched;
}
Also used : AbstractSched(com.ichi2.libanki.sched.AbstractSched) Sched(com.ichi2.libanki.sched.Sched) SuppressLint(android.annotation.SuppressLint) SchedV2(com.ichi2.libanki.sched.SchedV2)

Example 19 with AbstractSched

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

the class CardContentProvider method answerCard.

private void answerCard(Collection col, AbstractSched sched, Card cardToAnswer, @Consts.BUTTON_TYPE int ease, long timeTaken) {
    try {
        DB db = col.getDb();
        db.getDatabase().beginTransaction();
        try {
            if (cardToAnswer != null) {
                if (timeTaken != -1) {
                    cardToAnswer.setTimerStarted(col.getTime().intTimeMS() - timeTaken);
                }
                sched.answerCard(cardToAnswer, ease);
            }
            db.getDatabase().setTransactionSuccessful();
        } finally {
            DB.safeEndInTransaction(db);
        }
    } catch (RuntimeException e) {
        Timber.e(e, "answerCard - RuntimeException on answering card");
        AnkiDroidApp.sendExceptionReport(e, "doInBackgroundAnswerCard");
    }
}
Also used : DB(com.ichi2.libanki.DB)

Example 20 with AbstractSched

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

the class Syncer method sanityCheck.

public JSONObject sanityCheck() {
    JSONObject result = new JSONObject();
    try {
        if (mCol.getDb().queryScalar("SELECT count() FROM cards WHERE nid NOT IN (SELECT id FROM notes)") != 0) {
            Timber.e("Sync - SanityCheck: there are cards without mother notes");
            result.put("client", "missing notes");
            return result;
        }
        if (mCol.getDb().queryScalar("SELECT count() FROM notes WHERE id NOT IN (SELECT DISTINCT nid FROM cards)") != 0) {
            Timber.e("Sync - SanityCheck: there are notes without cards");
            result.put("client", "missing cards");
            return result;
        }
        if (mCol.getDb().queryScalar("SELECT count() FROM cards WHERE usn = -1") != 0) {
            Timber.e("Sync - SanityCheck: there are unsynced cards");
            result.put("client", "cards had usn = -1");
            return result;
        }
        if (mCol.getDb().queryScalar("SELECT count() FROM notes WHERE usn = -1") != 0) {
            Timber.e("Sync - SanityCheck: there are unsynced notes");
            result.put("client", "notes had usn = -1");
            return result;
        }
        if (mCol.getDb().queryScalar("SELECT count() FROM revlog WHERE usn = -1") != 0) {
            Timber.e("Sync - SanityCheck: there are unsynced revlogs");
            result.put("client", "revlog had usn = -1");
            return result;
        }
        if (mCol.getDb().queryScalar("SELECT count() FROM graves WHERE usn = -1") != 0) {
            Timber.e("Sync - SanityCheck: there are unsynced graves");
            result.put("client", "graves had usn = -1");
            return result;
        }
        for (Deck g : mCol.getDecks().all()) {
            if (g.getInt("usn") == -1) {
                Timber.e("Sync - SanityCheck: unsynced deck: %s", g.getString("name"));
                result.put("client", "deck had usn = -1");
                return result;
            }
        }
        if (mCol.getTags().minusOneValue()) {
            Timber.e("Sync - SanityCheck: there are unsynced tags");
            result.put("client", "tag had usn = -1");
            return result;
        }
        boolean found = false;
        for (JSONObject m : mCol.getModels().all()) {
            if (mCol.getServer()) {
                // the web upgrade was mistakenly setting usn
                if (m.getInt("usn") < 0) {
                    m.put("usn", 0);
                    found = true;
                }
            } else {
                if (m.getInt("usn") == -1) {
                    Timber.e("Sync - SanityCheck: unsynced model: %s", m.getString("name"));
                    result.put("client", "model had usn = -1");
                    return result;
                }
            }
        }
        if (found) {
            mCol.getModels().save();
        }
        // check for missing parent decks
        mCol.getSched().deckDueList();
        // return summary of deck
        JSONArray check = new JSONArray();
        JSONArray counts = new JSONArray();
        // #5666 - not in libAnki
        // We modified mReportLimit inside the scheduler, and this causes issues syncing dynamic decks.
        AbstractSched syncScheduler = mCol.createScheduler(SYNC_SCHEDULER_REPORT_LIMIT);
        syncScheduler.resetCounts();
        Counts counts_ = syncScheduler.counts();
        counts.put(counts_.getNew());
        counts.put(counts_.getLrn());
        counts.put(counts_.getRev());
        check.put(counts);
        check.put(mCol.getDb().queryScalar("SELECT count() FROM cards"));
        check.put(mCol.getDb().queryScalar("SELECT count() FROM notes"));
        check.put(mCol.getDb().queryScalar("SELECT count() FROM revlog"));
        check.put(mCol.getDb().queryScalar("SELECT count() FROM graves"));
        check.put(mCol.getModels().all().size());
        check.put(mCol.getDecks().all().size());
        check.put(mCol.getDecks().allConf().size());
        result.put("client", check);
        return result;
    } catch (JSONException e) {
        Timber.e(e, "Syncer.sanityCheck()");
        throw new RuntimeException(e);
    }
}
Also used : Counts(com.ichi2.libanki.sched.Counts) JSONObject(com.ichi2.utils.JSONObject) AbstractSched(com.ichi2.libanki.sched.AbstractSched) JSONArray(com.ichi2.utils.JSONArray) Deck(com.ichi2.libanki.Deck) JSONException(com.ichi2.utils.JSONException)

Aggregations

Card (com.ichi2.libanki.Card)28 Collection (com.ichi2.libanki.Collection)28 Test (org.junit.Test)23 AbstractSched (com.ichi2.libanki.sched.AbstractSched)19 RobolectricTest (com.ichi2.anki.RobolectricTest)18 Note (com.ichi2.libanki.Note)12 DeckConfig (com.ichi2.libanki.DeckConfig)9 JSONObject (com.ichi2.utils.JSONObject)9 Deck (com.ichi2.libanki.Deck)5 JSONArray (com.ichi2.utils.JSONArray)5 Cursor (android.database.Cursor)4 DB (com.ichi2.libanki.DB)4 Model (com.ichi2.libanki.Model)4 Matchers.containsString (org.hamcrest.Matchers.containsString)4 Models (com.ichi2.libanki.Models)3 Undoable (com.ichi2.libanki.Undoable)3 Sched (com.ichi2.libanki.sched.Sched)3 SchedV2 (com.ichi2.libanki.sched.SchedV2)3 JSONException (com.ichi2.utils.JSONException)3 SuppressLint (android.annotation.SuppressLint)2