def test_graphs(): from anki import Deck d = Deck(os.path.expanduser("~/test.anki")) g = d.stats() rep = g.report() open(os.path.expanduser("~/test.html"), "w").write(rep) return
def test_localsync_threeway(): # deck1 (client) <-> deck2 (server) <-> deck3 (client) deck3 = Deck() client2 = SyncClient(deck3) server2 = SyncServer(deck2) client2.setServer(server2) client.sync() client2.sync() # add a new question f = deck1.newFact() f['Front'] = u"a"; f['Back'] = u"b" f = deck1.addFact(f) card = f.cards[0] client.sync() assert deck1.cardCount() == 6 assert deck2.cardCount() == 6 # check it propagates from server to deck3 client2.sync() assert deck3.cardCount() == 6 # delete a card on deck1 deck1.deleteCard(card.id) client.sync() deck1.reset(); deck2.reset() assert deck1.cardCount() == 5 assert deck2.cardCount() == 5 # make sure the delete is now propagated from the server to deck3 client2.sync() assert deck3.cardCount() == 5
def test_localsync_threeway(): # deck1 (client) <-> deck2 (server) <-> deck3 (client) deck3 = Deck() client2 = SyncClient(deck3) server2 = SyncServer(deck2) client2.setServer(server2) client.sync() client2.sync() # add a new question f = deck1.newFact() f['Front'] = u"a" f['Back'] = u"b" f = deck1.addFact(f) card = f.cards[0] client.sync() assert deck1.cardCount() == 6 assert deck2.cardCount() == 6 # check it propagates from server to deck3 client2.sync() assert deck3.cardCount() == 6 # delete a card on deck1 deck1.deleteCard(card.id) client.sync() deck1.reset() deck2.reset() assert deck1.cardCount() == 5 assert deck2.cardCount() == 5 # make sure the delete is now propagated from the server to deck3 client2.sync() assert deck3.cardCount() == 5
def test_mnemosyne10(): deck = Deck() deck.addModel(BasicModel()) file = unicode(os.path.join(testDir, "importing/test.mem")) i = mnemosyne10.Mnemosyne10Importer(deck, file) i.doImport() assert i.total == 5 deck.close()
def test_openReadOnly(): # non-writeable dir assertException(Exception, lambda: Deck("/attachroot")) # reuse tmp file from before, test non-writeable file os.chmod(newPath, 0) assertException(Exception, lambda: Deck(newPath)) os.chmod(newPath, 0666) os.unlink(newPath)
def test_supermemo_xml_01_unicode(): deck = Deck() deck.addModel(BasicModel()) file = unicode(os.path.join(testDir, "importing/supermemo1.xml")) i = supermemo_xml.SupermemoXmlImporter(deck, file) #i.META.logToStdOutput = True i.doImport() # only returning top-level elements? assert i.total == 1 deck.close()
def test_csv_tags(): deck = Deck() deck.addModel(BasicModel()) file = unicode(os.path.join(testDir, "importing/text-tags.txt")) i = csvfile.TextImporter(deck, file) i.doImport() facts = deck.db.query(Fact).all() assert len(facts) == 2 assert facts[0].tags == "baz qux" or facts[1].tags == "baz qux" deck.close()
def test_csv(): deck = Deck() deck.addModel(BasicModel()) file = unicode(os.path.join(testDir, "importing/text-2fields.txt")) i = csvfile.TextImporter(deck, file) i.doImport() # four problems - missing front, dupe front, wrong num of fields assert len(i.log) == 4 assert i.total == 5 deck.close()
def setup1(): global deck deck = Deck() deck.addModel(BasicModel()) deck.currentModel.cardModels[1].active = True f = deck.newFact() f['Front'] = u"foo"; f['Back'] = u"bar"; f.tags = u"tag, tag2" deck.addFact(f) f = deck.newFact() f['Front'] = u"baz"; f['Back'] = u"qux" deck.addFact(f)
def _checkDecks(self): self._decks = [] decks = self.mw.config.recentDecks() if not decks: return tx = time.time() self.mw.progress.start(max=len(decks)) for c, d in enumerate(decks): self.mw.progress.update( _("Checking deck %(x)d of %(y)d...") % { 'x': c + 1, 'y': len(decks) }) base = os.path.basename(d) if not os.path.exists(d): self._decks.append({ 'name': base, 'state': 'missing', 'path': d }) continue try: mod = os.stat(d)[stat.ST_MTIME] t = time.time() deck = Deck(d, queue=False, lock=False) counts = deck.sched.selCounts() dtime = deck.sched.timeToday() dreps = deck.sched.repsToday() self._decks.append({ 'path': d, 'state': 'ok', 'name': deck.name(), 'due': counts[1] + counts[2], 'new': counts[0], 'mod': deck.mod, # these multiply deck check time by a factor of 6 'time': dtime, 'reps': dreps }) deck.close(save=False) # reset modification time for the sake of backup systems try: os.utime(d, (mod, mod)) except: # some misbehaving filesystems may fail here pass except Exception, e: if "locked" in unicode(e): state = "in use" else: state = "corrupt" self._decks.append({'name': base, 'state': state, 'path': d})
def test_create(): global newPath, newMod path = "/tmp/test_attachNew.anki" try: os.unlink(path) except OSError: pass deck = Deck(path) # for open() newPath = deck.path deck.save() newMod = deck.mod deck.close() del deck
def test_upgrade(): import tempfile, shutil src = os.path.join(testDir, "support", "anki12.anki") (fd, dst) = tempfile.mkstemp(suffix=".anki") print "upgrade to", dst shutil.copy(src, dst) deck = Deck(dst) # creation time should have been adjusted d = datetime.datetime.fromtimestamp(deck.crt) assert d.hour == 4 and d.minute == 0 # 3 new, 2 failed, 1 due assert deck.sched.counts() == (3, 2, 1) # now's a good time to test the integrity check too deck.fixIntegrity()
def test_upgrade(): import tempfile, shutil src = os.path.join(testDir, "support", "anki12.anki") (fd, dst) = tempfile.mkstemp(suffix=".anki") print "upgrade to", dst shutil.copy(src, dst) deck = Deck(dst) # creation time should have been adjusted d = datetime.datetime.fromtimestamp(deck.crt) assert d.hour == 4 and d.minute == 0 # 3 new, 2 failed, 1 due assert deck.sched.counts() == (3,2,1) # now's a good time to test the integrity check too deck.fixIntegrity()
def _checkDecks(self): self._decks = [] decks = self.mw.config.recentDecks() if not decks: return tx = time.time() self.mw.progress.start(max=len(decks)) for c, d in enumerate(decks): self.mw.progress.update(_("Checking deck %(x)d of %(y)d...") % { 'x': c+1, 'y': len(decks)}) base = os.path.basename(d) if not os.path.exists(d): self._decks.append({'name': base, 'state': 'missing', 'path':d}) continue try: mod = os.stat(d)[stat.ST_MTIME] t = time.time() deck = Deck(d, queue=False, lock=False) counts = deck.sched.selCounts() dtime = deck.sched.timeToday() dreps = deck.sched.repsToday() self._decks.append({ 'path': d, 'state': 'ok', 'name': deck.name(), 'due': counts[1]+counts[2], 'new': counts[0], 'mod': deck.mod, # these multiply deck check time by a factor of 6 'time': dtime, 'reps': dreps }) deck.close(save=False) # reset modification time for the sake of backup systems try: os.utime(d, (mod, mod)) except: # some misbehaving filesystems may fail here pass except Exception, e: if "locked" in unicode(e): state = "in use" else: state = "corrupt" self._decks.append({'name': base, 'state':state, 'path':d})
def test_dingsbums(): deck = Deck() deck.addModel(BasicModel()) startNumberOfFacts = deck.factCount() file = unicode(os.path.join(testDir, "importing/dingsbums.xml")) i = dingsbums.DingsBumsImporter(deck, file) i.doImport() assert 7 == i.total deck.close()
def test_updating(): # get the standard csv deck first deck = Deck() deck.addModel(BasicModel()) file = unicode(os.path.join(testDir, "importing/text-2fields.txt")) i = csvfile.TextImporter(deck, file) i.doImport() # now update file = unicode(os.path.join(testDir, "importing/text-update.txt")) i = csvfile.TextImporter(deck, file) # first field i.updateKey = (0, deck.currentModel.fieldModels[0].id) i.multipleCardsAllowed = False i.doImport() ans = deck.db.scalar( u"select answer from cards where question like '%食べる%'") assert "to ate" in ans # try again with tags i.updateKey = (0, deck.currentModel.fieldModels[0].id) i.mapping[1] = 0 i.doImport() deck.close()
def test_anki10(): # though these are not modified, sqlite updates the mtime, so copy to tmp # first file_ = unicode(os.path.join(testDir, "importing/test10.anki")) file = "/tmp/test10.anki" shutil.copy(file_, file) file2_ = unicode(os.path.join(testDir, "importing/test10-2.anki")) file2 = "/tmp/test10-2.anki" shutil.copy(file2_, file2) deck = Deck() i = anki10.Anki10Importer(deck, file) i.doImport() assert i.total == 2 deck.db.rollback() deck.close() # import a deck into itself - 10-2 is the same as test10, but with one # card answered and another deleted. nothing should be synced to client deck = Deck(file, backup=False) i = anki10.Anki10Importer(deck, file2) i.doImport() assert i.total == 0 deck.db.rollback()
def test_export_anki(): oldTime = deck.modified e = AnkiExporter(deck) newname = unicode(tempfile.mkstemp(prefix="ankitest")[1]) os.unlink(newname) e.exportInto(newname) assert deck.modified == oldTime # connect to new deck d2 = Deck(newname, backup=False) assert d2.cardCount() == 4 # try again, limited to a tag newname = unicode(tempfile.mkstemp(prefix="ankitest")[1]) os.unlink(newname) e.limitTags = ['tag'] e.exportInto(newname) d2 = Deck(newname, backup=False) assert d2.cardCount() == 2
def test_anki10_modtime(): deck1 = Deck() deck2 = Deck() client = SyncClient(deck1) server = SyncServer(deck2) client.setServer(server) deck1.addModel(BasicModel()) f = deck1.newFact() f['Front'] = u"foo" f['Back'] = u"bar" deck1.addFact(f) assert deck1.cardCount() == 1 assert deck2.cardCount() == 0 client.sync() assert deck1.cardCount() == 1 assert deck2.cardCount() == 1 file_ = unicode(os.path.join(testDir, "importing/test10-3.anki")) file = "/tmp/test10-3.anki" shutil.copy(file_, file) i = anki10.Anki10Importer(deck1, file) i.doImport() client.sync() assert i.total == 1 assert deck2.db.scalar("select count(*) from cards") == 2 assert deck2.db.scalar("select count(*) from facts") == 2 assert deck2.db.scalar("select count(*) from models") == 2
def test_anki10_modtime(): deck1 = Deck() deck2 = Deck() client = SyncClient(deck1) server = SyncServer(deck2) client.setServer(server) deck1.addModel(BasicModel()) f = deck1.newFact() f['Front'] = u"foo"; f['Back'] = u"bar" deck1.addFact(f) assert deck1.cardCount() == 1 assert deck2.cardCount() == 0 client.sync() assert deck1.cardCount() == 1 assert deck2.cardCount() == 1 file_ = unicode(os.path.join(testDir, "importing/test10-3.anki")) file = "/tmp/test10-3.anki" shutil.copy(file_, file) i = anki10.Anki10Importer(deck1, file) i.doImport() client.sync() assert i.total == 1 assert deck2.db.scalar("select count(*) from cards") == 2 assert deck2.db.scalar("select count(*) from facts") == 2 assert deck2.db.scalar("select count(*) from models") == 2
def setup_local(loadDecks=None): global deck1, deck2, client, server if loadDecks: deck1 = Deck(loadDecks[0], backup=False) deck2 = Deck(loadDecks[1], backup=False) else: deck1 = Deck() deck1.addModel(BasicModel()) deck1.currentModel.cardModels[1].active = True deck1.newCardOrder = 1 f = deck1.newFact() f['Front'] = u"foo"; f['Back'] = u"bar"; f.tags = u"foo" deck1.addFact(f) deck2 = Deck() deck2.addModel(BasicModel()) deck2.currentModel.cardModels[1].active = True f = deck2.newFact() f['Front'] = u"baz"; f['Back'] = u"qux"; f.tags = u"bar" deck2.addFact(f) deck2.newCardOrder = 1 # normally such syncs would trigger a conflict, but we ignore it deck1.setVar("schemaMod", 0) deck2.setVar("schemaMod", 0) client = SyncClient(deck1) server = SyncServer(deck2) client.setServer(server)
def getEmptyDeck(): (fd, nam) = tempfile.mkstemp(suffix=".anki") os.unlink(nam) return Deck(nam)
def setup_local(loadDecks=None): global deck1, deck2, client, server if loadDecks: deck1 = Deck(loadDecks[0], backup=False) deck2 = Deck(loadDecks[1], backup=False) else: deck1 = Deck() deck1.addModel(BasicModel()) deck1.currentModel.cardModels[1].active = True deck1.newCardOrder = 1 f = deck1.newFact() f['Front'] = u"foo" f['Back'] = u"bar" f.tags = u"foo" deck1.addFact(f) deck2 = Deck() deck2.addModel(BasicModel()) deck2.currentModel.cardModels[1].active = True f = deck2.newFact() f['Front'] = u"baz" f['Back'] = u"qux" f.tags = u"bar" deck2.addFact(f) deck2.newCardOrder = 1 # normally such syncs would trigger a conflict, but we ignore it deck1.setVar("schemaMod", 0) deck2.setVar("schemaMod", 0) client = SyncClient(deck1) server = SyncServer(deck2) client.setServer(server)
def test_open(): deck = Deck(newPath) assert deck.mod == newMod deck.close()
def setup_local(loadDecks=None): global deck1, deck2, client, server if loadDecks: deck1 = Deck(loadDecks[0], backup=False) deck2 = Deck(loadDecks[1], backup=False) else: deck1 = getEmptyDeck() f = deck1.newFact() f['Front'] = u"foo"; f['Back'] = u"bar"; f.tags = [u"foo"] deck1.addFact(f) deck1.syncName = "abc" deck2 = getEmptyDeck() f = deck2.newFact() f['Front'] = u"foo"; f['Back'] = u"bar"; f.tags = [u"foo"] deck2.addFact(f) deck2.syncName = "abc" deck1.lastSync = deck2.lastSync = intTime() deck1.scm = deck2.scm = 0 time.sleep(1) # now add another fact to deck1 that hasn't been synced yet f = deck1.newFact() f['Front'] = u"bar"; f['Back'] = u"baz" deck1.addFact(f) # and another to deck2 f = deck2.newFact() f['Front'] = u"qux"; f['Back'] = u"baz" deck2.addFact(f) deck2.reset() c = deck2.sched.getCard() deck2.sched.answerCard(c, 3) # change deck1's model deck1.currentModel().flush() deck1.save(); deck2.save() client = SyncClient(deck1) server = SyncServer(deck2) print "deck1", client.deck.db.all("select * from facts") print "deck2", server.deck.db.all("select * from facts") client.setServer(server)