Beispiel #1
0
def test_findCards():
    deck = getEmptyCol()
    f = deck.newNote()
    f["Front"] = "dog"
    f["Back"] = "cat"
    f.tags.append("monkey animal_1 * %")
    deck.addNote(f)
    f1id = f.id
    firstCardId = f.cards()[0].id
    f = deck.newNote()
    f["Front"] = "goats are fun"
    f["Back"] = "sheep"
    f.tags.append("sheep goat horse animal11")
    deck.addNote(f)
    f2id = f.id
    f = deck.newNote()
    f["Front"] = "cat"
    f["Back"] = "sheep"
    deck.addNote(f)
    catCard = f.cards()[0]
    m = deck.models.current()
    m = deck.models.copy(m)
    mm = deck.models
    t = mm.newTemplate("Reverse")
    t["qfmt"] = "{{Back}}"
    t["afmt"] = "{{Front}}"
    mm.addTemplate(m, t)
    mm.save(m)
    f = deck.newNote()
    f["Front"] = "test"
    f["Back"] = "foo bar"
    deck.addNote(f)
    deck.save()
    latestCardIds = [c.id for c in f.cards()]
    # tag searches
    assert len(deck.findCards("tag:*")) == 5
    assert len(deck.findCards("tag:\\*")) == 1
    assert len(deck.findCards("tag:%")) == 5
    assert len(deck.findCards("tag:\\%")) == 1
    assert len(deck.findCards("tag:animal_1")) == 2
    assert len(deck.findCards("tag:animal\\_1")) == 1
    assert not deck.findCards("tag:donkey")
    assert len(deck.findCards("tag:sheep")) == 1
    assert len(deck.findCards("tag:sheep tag:goat")) == 1
    assert len(deck.findCards("tag:sheep tag:monkey")) == 0
    assert len(deck.findCards("tag:monkey")) == 1
    assert len(deck.findCards("tag:sheep -tag:monkey")) == 1
    assert len(deck.findCards("-tag:sheep")) == 4
    deck.tags.bulkAdd(deck.db.list("select id from notes"), "foo bar")
    assert len(deck.findCards("tag:foo")) == len(
        deck.findCards("tag:bar")) == 5
    deck.tags.bulkRem(deck.db.list("select id from notes"), "foo")
    assert len(deck.findCards("tag:foo")) == 0
    assert len(deck.findCards("tag:bar")) == 5
    # text searches
    assert len(deck.findCards("cat")) == 2
    assert len(deck.findCards("cat -dog")) == 1
    assert len(deck.findCards("cat -dog")) == 1
    assert len(deck.findCards("are goats")) == 1
    assert len(deck.findCards('"are goats"')) == 0
    assert len(deck.findCards('"goats are"')) == 1
    # card states
    c = f.cards()[0]
    c.queue = c.type = CARD_TYPE_REV
    assert deck.findCards("is:review") == []
    c.flush()
    assert deck.findCards("is:review") == [c.id]
    assert deck.findCards("is:due") == []
    c.due = 0
    c.queue = QUEUE_TYPE_REV
    c.flush()
    assert deck.findCards("is:due") == [c.id]
    assert len(deck.findCards("-is:due")) == 4
    c.queue = -1
    # ensure this card gets a later mod time
    c.flush()
    deck.db.execute("update cards set mod = mod + 1 where id = ?", c.id)
    assert deck.findCards("is:suspended") == [c.id]
    # nids
    assert deck.findCards("nid:54321") == []
    assert len(deck.findCards("nid:%d" % f.id)) == 2
    assert len(deck.findCards("nid:%d,%d" % (f1id, f2id))) == 2
    # templates
    assert len(deck.findCards("card:foo")) == 0
    assert len(deck.findCards('"card:card 1"')) == 4
    assert len(deck.findCards("card:reverse")) == 1
    assert len(deck.findCards("card:1")) == 4
    assert len(deck.findCards("card:2")) == 1
    # fields
    assert len(deck.findCards("front:dog")) == 1
    assert len(deck.findCards("-front:dog")) == 4
    assert len(deck.findCards("front:sheep")) == 0
    assert len(deck.findCards("back:sheep")) == 2
    assert len(deck.findCards("-back:sheep")) == 3
    assert len(deck.findCards("front:do")) == 0
    assert len(deck.findCards("front:*")) == 5
    # ordering
    deck.conf["sortType"] = "noteCrt"
    deck.flush()
    assert deck.findCards("front:*", order=True)[-1] in latestCardIds
    assert deck.findCards("", order=True)[-1] in latestCardIds
    deck.conf["sortType"] = "noteFld"
    deck.flush()
    assert deck.findCards("", order=True)[0] == catCard.id
    assert deck.findCards("", order=True)[-1] in latestCardIds
    deck.conf["sortType"] = "cardMod"
    deck.flush()
    assert deck.findCards("", order=True)[-1] in latestCardIds
    assert deck.findCards("", order=True)[0] == firstCardId
    deck.conf["sortBackwards"] = True
    deck.flush()
    assert deck.findCards("", order=True)[0] in latestCardIds
    assert (deck.find_cards("", order=BuiltinSortKind.CARD_DUE,
                            reverse=False)[0] == firstCardId)
    assert (deck.find_cards("", order=BuiltinSortKind.CARD_DUE,
                            reverse=True)[0] != firstCardId)
    # model
    assert len(deck.findCards("note:basic")) == 3
    assert len(deck.findCards("-note:basic")) == 2
    assert len(deck.findCards("-note:foo")) == 5
    # deck
    assert len(deck.findCards("deck:default")) == 5
    assert len(deck.findCards("-deck:default")) == 0
    assert len(deck.findCards("-deck:foo")) == 5
    assert len(deck.findCards("deck:def*")) == 5
    assert len(deck.findCards("deck:*EFAULT")) == 5
    assert len(deck.findCards("deck:*cefault")) == 0
    # full search
    f = deck.newNote()
    f["Front"] = "hello<b>world</b>"
    f["Back"] = "abc"
    deck.addNote(f)
    # as it's the sort field, it matches
    assert len(deck.findCards("helloworld")) == 2
    # assert len(deck.findCards("helloworld", full=True)) == 2
    # if we put it on the back, it won't
    (f["Front"], f["Back"]) = (f["Back"], f["Front"])
    f.flush()
    assert len(deck.findCards("helloworld")) == 0
    # assert len(deck.findCards("helloworld", full=True)) == 2
    # assert len(deck.findCards("back:helloworld", full=True)) == 2
    # searching for an invalid special tag should not error
    with pytest.raises(Exception):
        len(deck.findCards("is:invalid"))
    # should be able to limit to parent deck, no children
    id = deck.db.scalar("select id from cards limit 1")
    deck.db.execute("update cards set did = ? where id = ?",
                    deck.decks.id("Default::Child"), id)
    deck.save()
    assert len(deck.findCards("deck:default")) == 7
    assert len(deck.findCards("deck:default::child")) == 1
    assert len(deck.findCards("deck:default -deck:default::*")) == 6
    # properties
    id = deck.db.scalar("select id from cards limit 1")
    deck.db.execute(
        "update cards set queue=2, ivl=10, reps=20, due=30, factor=2200 "
        "where id = ?",
        id,
    )
    assert len(deck.findCards("prop:ivl>5")) == 1
    assert len(deck.findCards("prop:ivl<5")) > 1
    assert len(deck.findCards("prop:ivl>=5")) == 1
    assert len(deck.findCards("prop:ivl=9")) == 0
    assert len(deck.findCards("prop:ivl=10")) == 1
    assert len(deck.findCards("prop:ivl!=10")) > 1
    assert len(deck.findCards("prop:due>0")) == 1
    # due dates should work
    assert len(deck.findCards("prop:due=29")) == 0
    assert len(deck.findCards("prop:due=30")) == 1
    # ease factors
    assert len(deck.findCards("prop:ease=2.3")) == 0
    assert len(deck.findCards("prop:ease=2.2")) == 1
    assert len(deck.findCards("prop:ease>2")) == 1
    assert len(deck.findCards("-prop:ease>2")) > 1
    # recently failed
    if not isNearCutoff():
        assert len(deck.findCards("rated:1:1")) == 0
        assert len(deck.findCards("rated:1:2")) == 0
        c = deck.sched.getCard()
        deck.sched.answerCard(c, 2)
        assert len(deck.findCards("rated:1:1")) == 0
        assert len(deck.findCards("rated:1:2")) == 1
        c = deck.sched.getCard()
        deck.sched.answerCard(c, 1)
        assert len(deck.findCards("rated:1:1")) == 1
        assert len(deck.findCards("rated:1:2")) == 1
        assert len(deck.findCards("rated:1")) == 2
        assert len(deck.findCards("rated:0:2")) == 0
        assert len(deck.findCards("rated:2:2")) == 1
        # added
        assert len(deck.findCards("added:0")) == 0
        deck.db.execute("update cards set id = id - 86400*1000 where id = ?",
                        id)
        assert len(deck.findCards("added:1")) == deck.cardCount() - 1
        assert len(deck.findCards("added:2")) == deck.cardCount()
    else:
        print("some find tests disabled near cutoff")
    # empty field
    assert len(deck.findCards("front:")) == 0
    f = deck.newNote()
    f["Front"] = ""
    f["Back"] = "abc2"
    assert deck.addNote(f) == 1
    assert len(deck.findCards("front:")) == 1
    # OR searches and nesting
    assert len(deck.findCards("tag:monkey or tag:sheep")) == 2
    assert len(deck.findCards("(tag:monkey OR tag:sheep)")) == 2
    assert len(deck.findCards("-(tag:monkey OR tag:sheep)")) == 6
    assert len(deck.findCards("tag:monkey or (tag:sheep sheep)")) == 2
    assert len(deck.findCards("tag:monkey or (tag:sheep octopus)")) == 1
    # flag
    with pytest.raises(Exception):
        deck.findCards("flag:12")
Beispiel #2
0
def test_find_cards():
    col = getEmptyCol()
    note = col.newNote()
    note["Front"] = "dog"
    note["Back"] = "cat"
    note.tags.append("monkey animal_1 * %")
    col.addNote(note)
    n1id = note.id
    firstCardId = note.cards()[0].id
    note = col.newNote()
    note["Front"] = "goats are fun"
    note["Back"] = "sheep"
    note.tags.append("sheep goat horse animal11")
    col.addNote(note)
    n2id = note.id
    note = col.newNote()
    note["Front"] = "cat"
    note["Back"] = "sheep"
    col.addNote(note)
    catCard = note.cards()[0]
    m = col.models.current()
    m = col.models.copy(m)
    mm = col.models
    t = mm.new_template("Reverse")
    t["qfmt"] = "{{Back}}"
    t["afmt"] = "{{Front}}"
    mm.add_template(m, t)
    mm.save(m)
    note = col.newNote()
    note["Front"] = "test"
    note["Back"] = "foo bar"
    col.addNote(note)
    col.save()
    latestCardIds = [c.id for c in note.cards()]
    # tag searches
    assert len(col.find_cards("tag:*")) == 5
    assert len(col.find_cards("tag:\\*")) == 1
    assert len(col.find_cards("tag:%")) == 1
    assert len(col.find_cards("tag:sheep_goat")) == 0
    assert len(col.find_cards('"tag:sheep goat"')) == 0
    assert len(col.find_cards('"tag:* *"')) == 0
    assert len(col.find_cards("tag:animal_1")) == 2
    assert len(col.find_cards("tag:animal\\_1")) == 1
    assert not col.find_cards("tag:donkey")
    assert len(col.find_cards("tag:sheep")) == 1
    assert len(col.find_cards("tag:sheep tag:goat")) == 1
    assert len(col.find_cards("tag:sheep tag:monkey")) == 0
    assert len(col.find_cards("tag:monkey")) == 1
    assert len(col.find_cards("tag:sheep -tag:monkey")) == 1
    assert len(col.find_cards("-tag:sheep")) == 4
    col.tags.bulk_add(col.db.list("select id from notes"), "foo bar")
    assert len(col.find_cards("tag:foo")) == len(
        col.find_cards("tag:bar")) == 5
    col.tags.bulkRem(col.db.list("select id from notes"), "foo")
    assert len(col.find_cards("tag:foo")) == 0
    assert len(col.find_cards("tag:bar")) == 5
    # text searches
    assert len(col.find_cards("cat")) == 2
    assert len(col.find_cards("cat -dog")) == 1
    assert len(col.find_cards("cat -dog")) == 1
    assert len(col.find_cards("are goats")) == 1
    assert len(col.find_cards('"are goats"')) == 0
    assert len(col.find_cards('"goats are"')) == 1
    # card states
    c = note.cards()[0]
    c.queue = c.type = CARD_TYPE_REV
    assert col.find_cards("is:review") == []
    c.flush()
    assert col.find_cards("is:review") == [c.id]
    assert col.find_cards("is:due") == []
    c.due = 0
    c.queue = QUEUE_TYPE_REV
    c.flush()
    assert col.find_cards("is:due") == [c.id]
    assert len(col.find_cards("-is:due")) == 4
    c.queue = QUEUE_TYPE_SUSPENDED
    # ensure this card gets a later mod time
    c.flush()
    col.db.execute("update cards set mod = mod + 1 where id = ?", c.id)
    assert col.find_cards("is:suspended") == [c.id]
    # nids
    assert col.find_cards("nid:54321") == []
    assert len(col.find_cards(f"nid:{note.id}")) == 2
    assert len(col.find_cards(f"nid:{n1id},{n2id}")) == 2
    # templates
    assert len(col.find_cards("card:foo")) == 0
    assert len(col.find_cards('"card:card 1"')) == 4
    assert len(col.find_cards("card:reverse")) == 1
    assert len(col.find_cards("card:1")) == 4
    assert len(col.find_cards("card:2")) == 1
    # fields
    assert len(col.find_cards("front:dog")) == 1
    assert len(col.find_cards("-front:dog")) == 4
    assert len(col.find_cards("front:sheep")) == 0
    assert len(col.find_cards("back:sheep")) == 2
    assert len(col.find_cards("-back:sheep")) == 3
    assert len(col.find_cards("front:do")) == 0
    assert len(col.find_cards("front:*")) == 5
    # ordering
    col.conf["sortType"] = "noteCrt"
    assert col.find_cards("front:*", order=True)[-1] in latestCardIds
    assert col.find_cards("", order=True)[-1] in latestCardIds
    col.conf["sortType"] = "noteFld"
    assert col.find_cards("", order=True)[0] == catCard.id
    assert col.find_cards("", order=True)[-1] in latestCardIds
    col.conf["sortType"] = "cardMod"
    assert col.find_cards("", order=True)[-1] in latestCardIds
    assert col.find_cards("", order=True)[0] == firstCardId
    col.set_config(BrowserConfig.CARDS_SORT_BACKWARDS_KEY, True)
    assert col.find_cards("", order=True)[0] in latestCardIds
    assert (col.find_cards("",
                           order=col.get_browser_column("cardDue"),
                           reverse=False)[0] == firstCardId)
    assert (col.find_cards("",
                           order=col.get_browser_column("cardDue"),
                           reverse=True)[0] != firstCardId)
    # model
    assert len(col.find_cards("note:basic")) == 3
    assert len(col.find_cards("-note:basic")) == 2
    assert len(col.find_cards("-note:foo")) == 5
    # col
    assert len(col.find_cards("deck:default")) == 5
    assert len(col.find_cards("-deck:default")) == 0
    assert len(col.find_cards("-deck:foo")) == 5
    assert len(col.find_cards("deck:def*")) == 5
    assert len(col.find_cards("deck:*EFAULT")) == 5
    assert len(col.find_cards("deck:*cefault")) == 0
    # full search
    note = col.newNote()
    note["Front"] = "hello<b>world</b>"
    note["Back"] = "abc"
    col.addNote(note)
    # as it's the sort field, it matches
    assert len(col.find_cards("helloworld")) == 2
    # assert len(col.find_cards("helloworld", full=True)) == 2
    # if we put it on the back, it won't
    (note["Front"], note["Back"]) = (note["Back"], note["Front"])
    note.flush()
    assert len(col.find_cards("helloworld")) == 0
    # assert len(col.find_cards("helloworld", full=True)) == 2
    # assert len(col.find_cards("back:helloworld", full=True)) == 2
    # searching for an invalid special tag should not error
    with pytest.raises(Exception):
        len(col.find_cards("is:invalid"))
    # should be able to limit to parent col, no children
    id = col.db.scalar("select id from cards limit 1")
    col.db.execute("update cards set did = ? where id = ?",
                   col.decks.id("Default::Child"), id)
    col.save()
    assert len(col.find_cards("deck:default")) == 7
    assert len(col.find_cards("deck:default::child")) == 1
    assert len(col.find_cards("deck:default -deck:default::*")) == 6
    # properties
    id = col.db.scalar("select id from cards limit 1")
    col.db.execute(
        "update cards set queue=2, ivl=10, reps=20, due=30, factor=2200 "
        "where id = ?",
        id,
    )
    assert len(col.find_cards("prop:ivl>5")) == 1
    assert len(col.find_cards("prop:ivl<5")) > 1
    assert len(col.find_cards("prop:ivl>=5")) == 1
    assert len(col.find_cards("prop:ivl=9")) == 0
    assert len(col.find_cards("prop:ivl=10")) == 1
    assert len(col.find_cards("prop:ivl!=10")) > 1
    assert len(col.find_cards("prop:due>0")) == 1
    # due dates should work
    assert len(col.find_cards("prop:due=29")) == 0
    assert len(col.find_cards("prop:due=30")) == 1
    # ease factors
    assert len(col.find_cards("prop:ease=2.3")) == 0
    assert len(col.find_cards("prop:ease=2.2")) == 1
    assert len(col.find_cards("prop:ease>2")) == 1
    assert len(col.find_cards("-prop:ease>2")) > 1
    # recently failed
    if not isNearCutoff():
        # rated
        assert len(col.find_cards("rated:1:1")) == 0
        assert len(col.find_cards("rated:1:2")) == 0
        c = col.sched.getCard()
        col.sched.answerCard(c, 2)
        assert len(col.find_cards("rated:1:1")) == 0
        assert len(col.find_cards("rated:1:2")) == 1
        c = col.sched.getCard()
        col.sched.answerCard(c, 1)
        assert len(col.find_cards("rated:1:1")) == 1
        assert len(col.find_cards("rated:1:2")) == 1
        assert len(col.find_cards("rated:1")) == 2
        assert len(col.find_cards("rated:2:2")) == 1
        assert len(col.find_cards("rated:0")) == len(col.find_cards("rated:1"))

        # added
        col.db.execute("update cards set id = id - 86400*1000 where id = ?",
                       id)
        assert len(col.find_cards("added:1")) == col.card_count() - 1
        assert len(col.find_cards("added:2")) == col.card_count()
        assert len(col.find_cards("added:0")) == len(col.find_cards("added:1"))
    else:
        print("some find tests disabled near cutoff")
    # empty field
    assert len(col.find_cards("front:")) == 0
    note = col.newNote()
    note["Front"] = ""
    note["Back"] = "abc2"
    assert col.addNote(note) == 1
    assert len(col.find_cards("front:")) == 1
    # OR searches and nesting
    assert len(col.find_cards("tag:monkey or tag:sheep")) == 2
    assert len(col.find_cards("(tag:monkey OR tag:sheep)")) == 2
    assert len(col.find_cards("-(tag:monkey OR tag:sheep)")) == 6
    assert len(col.find_cards("tag:monkey or (tag:sheep sheep)")) == 2
    assert len(col.find_cards("tag:monkey or (tag:sheep octopus)")) == 1
    # flag
    with pytest.raises(Exception):
        col.find_cards("flag:12")