Search in sources :

Example 51 with Models

use of com.ichi2.libanki.Models in project AnkiChinaAndroid by ankichinateam.

the class Collection method addNote.

/**
 * Add a note to the collection. Return number of new cards.
 */
public int addNote(Note note) {
    // check we have card models available, then save
    ArrayList<JSONObject> cms = findTemplates(note);
    if (cms.size() == 0) {
        return 0;
    }
    note.flush();
    // deck conf governs which of these are used
    int due = nextID("pos");
    // add cards
    int ncards = 0;
    for (JSONObject template : cms) {
        _newCard(note, template, due);
        ncards += 1;
    }
    return ncards;
}
Also used : JSONObject(com.ichi2.utils.JSONObject) SuppressLint(android.annotation.SuppressLint)

Example 52 with Models

use of com.ichi2.libanki.Models in project AnkiChinaAndroid by ankichinateam.

the class CardTest method test_gen_or.

@Test
public void test_gen_or() throws ConfirmModSchemaException {
    Collection col = getCol();
    Models models = col.getModels();
    Model model = models.byName("Basic");
    JSONArray flds = model.getJSONArray("flds");
    models.renameField(model, flds.getJSONObject(0), "A");
    models.renameField(model, flds.getJSONObject(1), "B");
    JSONObject fld2 = models.newField("C");
    fld2.put("ord", null);
    models.addField(model, fld2);
    JSONArray tmpls = model.getJSONArray("tmpls");
    tmpls.getJSONObject(0).put("qfmt", "{{A}}{{B}}{{C}}");
    // ensure first card is always generated,
    // because at last one card is generated
    JSONObject tmpl = models.newTemplate("AND_OR");
    tmpl.put("qfmt", "        {{A}}    {{#B}}        {{#C}}            {{B}}        {{/C}}    {{/B}}");
    models.addTemplate(model, tmpl);
    models.save(model);
    models.setCurrent(model);
    Note note = col.newNote();
    note.setItem("A", "foo");
    col.addNote(note);
    assertNoteOrdinalAre(note, new Integer[] { 0, 1 });
    note = col.newNote();
    note.setItem("B", "foo");
    note.setItem("C", "foo");
    col.addNote(note);
    assertNoteOrdinalAre(note, new Integer[] { 0, 1 });
    note = col.newNote();
    note.setItem("B", "foo");
    col.addNote(note);
    assertNoteOrdinalAre(note, new Integer[] { 0 });
    note = col.newNote();
    note.setItem("C", "foo");
    col.addNote(note);
    assertNoteOrdinalAre(note, new Integer[] { 0 });
    note = col.newNote();
    note.setItem("A", "foo");
    note.setItem("B", "foo");
    note.setItem("C", "foo");
    col.addNote(note);
    assertNoteOrdinalAre(note, new Integer[] { 0, 1 });
    note = col.newNote();
    col.addNote(note);
    assertNoteOrdinalAre(note, new Integer[] { 0 });
// First card is generated if no other card
}
Also used : JSONObject(com.ichi2.utils.JSONObject) JSONArray(com.ichi2.utils.JSONArray) RobolectricTest(com.ichi2.anki.RobolectricTest) Test(org.junit.Test)

Example 53 with Models

use of com.ichi2.libanki.Models in project AnkiChinaAndroid by ankichinateam.

the class CardTest method test_gen_not.

@Test
public void test_gen_not() throws ConfirmModSchemaException {
    Collection col = getCol();
    Models models = col.getModels();
    Model model = models.byName("Basic");
    JSONArray flds = model.getJSONArray("flds");
    JSONArray tmpls = model.getJSONArray("tmpls");
    models.renameField(model, flds.getJSONObject(0), "First");
    models.renameField(model, flds.getJSONObject(1), "Front");
    JSONObject fld2 = models.newField("AddIfEmpty");
    fld2.put("name", "AddIfEmpty");
    models.addField(model, fld2);
    // ensure first card is always generated,
    // because at last one card is generated
    tmpls.getJSONObject(0).put("qfmt", "{{AddIfEmpty}}{{Front}}{{First}}");
    JSONObject tmpl = models.newTemplate("NOT");
    tmpl.put("qfmt", "    {{^AddIfEmpty}}        {{Front}}    {{/AddIfEmpty}}    ");
    models.addTemplate(model, tmpl);
    models.save(model);
    models.setCurrent(model);
    Note note = col.newNote();
    note.setItem("First", "foo");
    note.setItem("AddIfEmpty", "foo");
    note.setItem("Front", "foo");
    col.addNote(note);
    assertNoteOrdinalAre(note, new Integer[] { 0 });
    note = col.newNote();
    note.setItem("First", "foo");
    note.setItem("AddIfEmpty", "foo");
    col.addNote(note);
    assertNoteOrdinalAre(note, new Integer[] { 0 });
    note = col.newNote();
    // ensure first note generated
    note.setItem("First", "foo");
    col.addNote(note);
    assertNoteOrdinalAre(note, new Integer[] { 0 });
    note = col.newNote();
    note.setItem("First", "foo");
    note.setItem("Front", "foo");
    col.addNote(note);
    assertNoteOrdinalAre(note, new Integer[] { 0, 1 });
}
Also used : JSONObject(com.ichi2.utils.JSONObject) JSONArray(com.ichi2.utils.JSONArray) RobolectricTest(com.ichi2.anki.RobolectricTest) Test(org.junit.Test)

Example 54 with Models

use of com.ichi2.libanki.Models in project AnkiChinaAndroid by ankichinateam.

the class CollectionTest method test_furigana.

@Test
@Ignore("Pending port of media search from Rust code")
public void test_furigana() {
    Collection col = getCol();
    Models mm = col.getModels();
    Model m = mm.current();
    // filter should work
    m.getJSONArray("tmpls").getJSONObject(0).put("qfmt", "{{kana:Front}}");
    mm.save(m);
    Note n = col.newNote();
    n.setItem("Front", "foo[abc]");
    col.addNote(n);
    Card c = n.cards().get(0);
    assertTrue(c.q().endsWith("abc"));
    // and should avoid sound
    n.setItem("Front", "foo[sound:abc.mp3]");
    n.flush();
    String question = c.q(true);
    assertThat("Question «" + question + "» does not contains «anki:play».", question, containsString("anki:play"));
    // it shouldn't throw an error while people are editing
    m.getJSONArray("tmpls").getJSONObject(0).put("qfmt", "{{kana:}}");
    mm.save(m);
    c.q(true);
}
Also used : Matchers.containsString(org.hamcrest.Matchers.containsString) Ignore(org.junit.Ignore) RobolectricTest(com.ichi2.anki.RobolectricTest) Test(org.junit.Test)

Example 55 with Models

use of com.ichi2.libanki.Models in project AnkiChinaAndroid by ankichinateam.

the class FinderTest method test_findCards.

@Test
public void test_findCards() {
    Collection col = getCol();
    Note note = col.newNote();
    note.setItem("Front", "dog");
    note.setItem("Back", "cat");
    note.addTag("monkey animal_1 * %");
    col.addNote(note);
    long n1id = note.getId();
    long firstCardId = note.cards().get(0).getId();
    note = col.newNote();
    note.setItem("Front", "goats are fun");
    note.setItem("Back", "sheep");
    note.addTag("sheep goat horse animal11");
    col.addNote(note);
    long n2id = note.getId();
    note = col.newNote();
    note.setItem("Front", "cat");
    note.setItem("Back", "sheep");
    col.addNote(note);
    Card catCard = note.cards().get(0);
    Model m = col.getModels().current();
    m = col.getModels().copy(m);
    Models mm = col.getModels();
    JSONObject t = Models.newTemplate("Reverse");
    t.put("qfmt", "{{Back}}");
    t.put("afmt", "{{Front}}");
    mm.addTemplateModChanged(m, t);
    mm.save(m);
    note = col.newNote();
    note.setItem("Front", "test");
    note.setItem("Back", "foo bar");
    col.addNote(note);
    col.save();
    List<Long> latestCardIds = note.cids();
    // tag searches
    assertEquals(5, col.findCards("tag:*").size());
    assertEquals(1, col.findCards("tag:\\*").size());
    assertEquals(5, col.findCards("tag:%").size());
    assertEquals(1, col.findCards("tag:\\%").size());
    assertEquals(2, col.findCards("tag:animal_1").size());
    assertEquals(1, col.findCards("tag:animal\\_1").size());
    assertEquals(0, col.findCards("tag:donkey").size());
    assertEquals(1, col.findCards("tag:sheep").size());
    assertEquals(1, col.findCards("tag:sheep tag:goat").size());
    assertEquals(0, col.findCards("tag:sheep tag:monkey").size());
    assertEquals(1, col.findCards("tag:monkey").size());
    assertEquals(1, col.findCards("tag:sheep -tag:monkey").size());
    assertEquals(4, col.findCards("-tag:sheep").size());
    col.getTags().bulkAdd(col.getDb().queryLongList("select id from notes"), "foo bar");
    assertEquals(5, col.findCards("tag:foo").size());
    assertEquals(5, col.findCards("tag:bar").size());
    col.getTags().bulkRem(col.getDb().queryLongList("select id from notes"), "foo");
    assertEquals(0, col.findCards("tag:foo").size());
    assertEquals(5, col.findCards("tag:bar").size());
    // text searches
    assertEquals(2, col.findCards("cat").size());
    assertEquals(1, col.findCards("cat -dog").size());
    assertEquals(1, col.findCards("cat -dog").size());
    assertEquals(1, col.findCards("are goats").size());
    assertEquals(0, col.findCards("\"are goats\"").size());
    assertEquals(1, col.findCards("\"goats are\"").size());
    // card states
    Card c = note.cards().get(0);
    c.setQueue(QUEUE_TYPE_REV);
    c.setType(CARD_TYPE_REV);
    assertEquals(0, col.findCards("is:review").size());
    c.flush();
    assertEqualsArrayList((new Long[] { c.getId() }), col.findCards("is:review"));
    assertEquals(0, col.findCards("is:due").size());
    c.setDue(0);
    c.setQueue(QUEUE_TYPE_REV);
    c.flush();
    assertEqualsArrayList((new Long[] { c.getId() }), col.findCards("is:due"));
    assertEquals(4, col.findCards("-is:due").size());
    c.setQueue(QUEUE_TYPE_SUSPENDED);
    // ensure this card gets a later mod time
    c.flush();
    col.getDb().execute("update cards set mod = mod + 1 where id = ?", c.getId());
    assertEqualsArrayList((new Long[] { c.getId() }), col.findCards("is:suspended"));
    // nids
    assertEquals(0, col.findCards("nid:54321").size());
    assertEquals(2, col.findCards("nid:" + note.getId()).size());
    assertEquals(2, col.findCards("nid:" + n1id + "," + n2id).size());
    // templates
    assertEquals(0, col.findCards("card:foo").size());
    assertEquals(4, col.findCards("\"card:card 1\"").size());
    assertEquals(1, col.findCards("card:reverse").size());
    assertEquals(4, col.findCards("card:1").size());
    assertEquals(1, col.findCards("card:2").size());
    // fields
    assertEquals(1, col.findCards("front:dog").size());
    assertEquals(4, col.findCards("-front:dog").size());
    assertEquals(0, col.findCards("front:sheep").size());
    assertEquals(2, col.findCards("back:sheep").size());
    assertEquals(3, col.findCards("-back:sheep").size());
    assertEquals(0, col.findCards("front:do").size());
    assertEquals(5, col.findCards("front:*").size());
    // ordering
    col.getConf().put("sortType", "noteCrt");
    col.flush();
    assertTrue(latestCardIds.contains(getLastListElement(col.findCards("front:*", true))));
    assertTrue(latestCardIds.contains(getLastListElement(col.findCards("", true))));
    col.getConf().put("sortType", "noteFld");
    col.flush();
    assertEquals(catCard.getId(), (long) col.findCards("", true).get(0));
    assertTrue(latestCardIds.contains(getLastListElement(col.findCards("", true))));
    col.getConf().put("sortType", "cardMod");
    col.flush();
    assertTrue(latestCardIds.contains(getLastListElement(col.findCards("", true))));
    assertEquals(firstCardId, (long) col.findCards("", true).get(0));
    col.getConf().put("sortBackwards", true);
    col.flush();
    assertTrue(latestCardIds.contains(col.findCards("", true).get(0)));
    /* TODO: Port BuiltinSortKind
           assertEquals(firstCardId,
           col.findCards("", BuiltinSortKind.CARD_DUE, reverse=false).get(0)
           );
           assertNotEquals(firstCardId,
           col.findCards("", BuiltinSortKind.CARD_DUE, reverse=true).get(0));
        */
    // model
    assertEquals(3, col.findCards("note:basic").size());
    assertEquals(2, col.findCards("-note:basic").size());
    assertEquals(5, col.findCards("-note:foo").size());
    // col
    assertEquals(5, col.findCards("deck:default").size());
    assertEquals(0, col.findCards("-deck:default").size());
    assertEquals(5, col.findCards("-deck:foo").size());
    assertEquals(5, col.findCards("deck:def*").size());
    assertEquals(5, col.findCards("deck:*EFAULT").size());
    assertEquals(0, col.findCards("deck:*cefault").size());
    // full search
    note = col.newNote();
    note.setItem("Front", "hello<b>world</b>");
    note.setItem("Back", "abc");
    col.addNote(note);
    // as it's the sort field, it matches
    assertEquals(2, col.findCards("helloworld").size());
    // assertEquals(, col.findCards("helloworld", full=true).size())2 This is commented upstream
    // if we put it on the back, it won't
    String note_front = note.getItem("Front");
    String note_back = note.getItem("Back");
    note.setItem("Front", note_back);
    note.setItem("Back", note_front);
    note.flush();
    assertEquals(0, col.findCards("helloworld").size());
    //  Those lines are commented above
    // assertEquals(, col.findCards("helloworld", full=true).size())2
    // assertEquals(, col.findCards("back:helloworld", full=true).size())2
    // searching for an invalid special tag should not error
    // TODO: ensure the search fail
    // assertThrows(Exception.class, () -> col.findCards("is:invalid").size());
    // should be able to limit to parent col, no children
    long id = col.getDb().queryLongScalar("select id from cards limit 1");
    col.getDb().execute("update cards set did = ? where id = ?", col.getDecks().id("Default::Child"), id);
    col.save();
    assertEquals(7, col.findCards("deck:default").size());
    assertEquals(1, col.findCards("deck:default::child").size());
    assertEquals(6, col.findCards("deck:default -deck:default::*").size());
    // properties
    id = col.getDb().queryLongScalar("select id from cards limit 1");
    col.getDb().execute("update cards set queue=2, ivl=10, reps=20, due=30, factor=2200 where id = ?", id);
    assertEquals(1, col.findCards("prop:ivl>5").size());
    assertThat(col.findCards("prop:ivl<5").size(), greaterThan(1));
    assertEquals(1, col.findCards("prop:ivl>=5").size());
    assertEquals(0, col.findCards("prop:ivl=9").size());
    assertEquals(1, col.findCards("prop:ivl=10").size());
    assertThat(col.findCards("prop:ivl!=10").size(), greaterThan(1));
    assertEquals(1, col.findCards("prop:due>0").size());
    // due dates should work
    assertEquals(0, col.findCards("prop:due=29").size());
    assertEquals(1, col.findCards("prop:due=30").size());
    // ease factors
    assertEquals(0, col.findCards("prop:ease=2.3").size());
    assertEquals(1, col.findCards("prop:ease=2.2").size());
    assertEquals(1, col.findCards("prop:ease>2").size());
    assertThat(col.findCards("-prop:ease>2").size(), greaterThan(1));
    // recently failed
    if (!isNearCutoff(col)) {
        assertEquals(0, col.findCards("rated:1:1").size());
        assertEquals(0, col.findCards("rated:1:2").size());
        c = col.getSched().getCard();
        col.getSched().answerCard(c, 2);
        assertEquals(0, col.findCards("rated:1:1").size());
        assertEquals(1, col.findCards("rated:1:2").size());
        c = col.getSched().getCard();
        col.getSched().answerCard(c, 1);
        assertEquals(1, col.findCards("rated:1:1").size());
        assertEquals(1, col.findCards("rated:1:2").size());
        assertEquals(2, col.findCards("rated:1").size());
        assertEquals(0, col.findCards("rated:0:2").size());
        assertEquals(1, col.findCards("rated:2:2").size());
        // added
        assertEquals(0, col.findCards("added:0").size());
        col.getDb().execute("update cards set id = id - " + SECONDS_PER_DAY * 1000 + " where id = ?", id);
        assertEquals(col.cardCount() - 1, col.findCards("added:1").size());
        assertEquals(col.cardCount(), col.findCards("added:2").size());
    } else {
        Timber.w("some find tests disabled near cutoff");
    }
    // empty field
    assertEquals(0, col.findCards("front:").size());
    note = col.newNote();
    note.setItem("Front", "");
    note.setItem("Back", "abc2");
    assertEquals(1, col.addNote(note));
    assertEquals(1, col.findCards("front:").size());
    // OR searches and nesting
    assertEquals(2, col.findCards("tag:monkey or tag:sheep").size());
    assertEquals(2, col.findCards("(tag:monkey OR tag:sheep)").size());
    assertEquals(6, col.findCards("-(tag:monkey OR tag:sheep)").size());
    assertEquals(2, col.findCards("tag:monkey or (tag:sheep sheep)").size());
    assertEquals(1, col.findCards("tag:monkey or (tag:sheep octopus)").size());
// flag
// Todo: ensure it fails
// assertThrows(Exception.class, () -> col.findCards("flag:12"));
}
Also used : JSONObject(com.ichi2.utils.JSONObject) RobolectricTest(com.ichi2.anki.RobolectricTest) Test(org.junit.Test)

Aggregations

JSONObject (com.ichi2.utils.JSONObject)48 Model (com.ichi2.libanki.Model)28 JSONArray (com.ichi2.utils.JSONArray)26 Test (org.junit.Test)26 Collection (com.ichi2.libanki.Collection)25 RobolectricTest (com.ichi2.anki.RobolectricTest)16 Note (com.ichi2.libanki.Note)16 JSONException (com.ichi2.utils.JSONException)13 ArrayList (java.util.ArrayList)13 Card (com.ichi2.libanki.Card)11 Models (com.ichi2.libanki.Models)11 SuppressLint (android.annotation.SuppressLint)10 ConfirmModSchemaException (com.ichi2.anki.exception.ConfirmModSchemaException)7 ModelManager (com.ichi2.libanki.ModelManager)7 File (java.io.File)6 HashMap (java.util.HashMap)6 List (java.util.List)6 Map (java.util.Map)6 ContentValues (android.content.ContentValues)5 NonNull (androidx.annotation.NonNull)5