class MyClient(Client): program_name = "Mnemosyne" program_version = "test" capabilities = "TODO" def __init__(self): os.system("rm -fr dot_benchmark") self.mnemosyne = Mnemosyne() self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translator", "GetTextTranslator")) self.mnemosyne.components.append(("test_sync", "Widget")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.review_widget", "ReviewWidget")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "ProgressDialog")) self.mnemosyne.initialise(os.path.abspath(os.path.join(os.getcwdu(), "dot_benchmark"))) self.mnemosyne.review_controller().reset() Client.__init__(self, "client_machine_id", self.mnemosyne.database(), self.mnemosyne.main_widget()) def do_sync(self): self.sync("127.0.0.1", 8190, "user", "pass") self.mnemosyne.database().save()
class TestSmconvImport(MnemosyneTest): def setup(self): self.initialise_data_dir() self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator") ) self.mnemosyne.components.append(("mnemosyne_test", "TestReviewWidget")) self.mnemosyne.components.append(("test_smconv_import", "Widget")) self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.review_controller().reset() def sm7_importer(self): for format in self.mnemosyne.component_manager.all("file_format"): if format.__class__.__name__ == "Smconv_XML": return format def test_1(self): global last_error filename = os.path.join(os.getcwd(), "tests", "files", "smconv.xml") self.sm7_importer().do_import(filename) assert last_error is "" assert len([c for c in self.database().cards()]) == 3 def teardown(self): filename = os.path.join(os.getcwd(), "dot_test", "default.db_media", "a.png") if os.path.exists(filename): os.remove(filename) filename = os.path.join(os.getcwd(), "dot_test", "test.txt") if os.path.exists(filename): os.remove(filename) MnemosyneTest.teardown(self)
class TestDBImport(MnemosyneTest): def setup(self): self.initialise_data_dir() self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.gui_translators.gettext_gui_translator", "GetTextGuiTranslator")) self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \ [("mnemosyne_test", "TestReviewWidget")] self.mnemosyne.components.append(\ ("test_db_import", "Widget")) self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.review_controller().reset() def db_importer(self): for format in self.mnemosyne.component_manager.all("file_format"): if format.__class__.__name__ == "Mnemosyne2Db": return format def test_1(self): print(os.getcwd()) filename = os.path.join(os.getcwd(), "tests", "files", "basedir_to_merge", "config.db") self.db_importer().do_import(filename) assert "configuration database" in last_error def test_2(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") old_card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] assert len([self.database().cards()]) == 1 filename = os.path.join(os.getcwd(), "tests", "files", "basedir_to_merge", "to_merge.db") global last_error last_error = "" self.db_importer().do_import(filename) assert last_error == "" db = self.database() assert db.con.execute("select count() from log where event_type != 26" ).fetchone()[0] == 258 self.review_controller().reset() assert self.database().card_count() == 7 assert self.database().active_count() == 6 assert self.database().fact_count() == 5 card_type = self.database().card_type("2::new clone", is_id_internal=False) assert self.config().card_type_property("background_colour", card_type) == 4278233600
class MnemosyneTest(): def setup(self): os.system("rm -fr dot_test") self.restart() def restart(self): self.mnemosyne = Mnemosyne() self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.main_widget", "MainWidget")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.review_widget", "ReviewWidget")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "ProgressDialog")) self.mnemosyne.initialise(os.path.abspath("dot_test")) self.review_controller().reset() def teardown(self): self.mnemosyne.finalise() def config(self): return self.mnemosyne.component_manager.get_current("config") def log(self): return self.mnemosyne.component_manager.get_current("log") def database(self): return self.mnemosyne.component_manager.get_current("database") def scheduler(self): return self.mnemosyne.component_manager.get_current("scheduler") def main_widget(self): return self.mnemosyne.component_manager.get_current("main_widget") def review_widget(self): return self.mnemosyne.component_manager.get_current("review_widget") def controller(self): return self.mnemosyne.component_manager.get_current("controller") def review_controller(self): return self.mnemosyne.component_manager.get_current("review_controller") def card_types(self): return self.mnemosyne.component_manager.get_all("card_type") def filters(self): return self.mnemosyne.component_manager.get_all("filter") def plugins(self): return self.mnemosyne.component_manager.get_all("plugin") def card_type_by_id(self, id): return self.mnemosyne.component_manager.card_type_by_id[id]
def startup(): global mnemosyne # Note that this also includes building the queue and getting the first card. mnemosyne = Mnemosyne(resource_limited=True) mnemosyne.components = [ ("mnemosyne.libmnemosyne.translator", "NoTranslation"), ("mnemosyne.libmnemosyne.ui_components.main_widget", "MainWidget"), ("mnemosyne.libmnemosyne.ui_components.review_widget", "ReviewWidget"), ("mnemosyne.libmnemosyne.databases.SQLite", "SQLite"), ("mnemosyne.libmnemosyne.configuration", "Configuration"), ("mnemosyne.libmnemosyne.loggers.sql_logger", "SqlLogger"), ("mnemosyne.libmnemosyne.schedulers.SM2_mnemosyne", "SM2Mnemosyne"), ("mnemosyne.libmnemosyne.stopwatch", "Stopwatch"), ("mnemosyne.libmnemosyne.card_types.front_to_back", "FrontToBack"), ("mnemosyne.libmnemosyne.card_types.both_ways", "BothWays"), ("mnemosyne.libmnemosyne.card_types.three_sided", "ThreeSided"), ("mnemosyne.libmnemosyne.renderers.html_css_old", "HtmlCssOld"), ("mnemosyne.libmnemosyne.filters.escape_to_html", "EscapeToHtml"), ("mnemosyne.libmnemosyne.filters.expand_paths", "ExpandPaths"), ("mnemosyne.libmnemosyne.filters.latex", "Latex"), ("mnemosyne.libmnemosyne.controllers.default_controller", "DefaultController"), ("mnemosyne.libmnemosyne.review_controllers.SM2_controller", "SM2Controller"), ("mnemosyne.libmnemosyne.card_types.map", "MapPlugin"), ("mnemosyne.libmnemosyne.card_types.cloze", "ClozePlugin"), ("mnemosyne.libmnemosyne.plugins.cramming_plugin", "CrammingPlugin"), ("mnemosyne.libmnemosyne.file_formats.mnemosyne1_mem", "Mnemosyne1Mem"), ("mnemosyne.libmnemosyne.ui_components.dialogs", "ProgressDialog") ] mnemosyne.initialise(basedir=os.path.abspath("dot_benchmark")) #mnemosyne.initialise(basedir="\SDMMC\.mnemosyne") mnemosyne.review_controller().reset()
class TestMainController(MnemosyneTest): def setup(self): os.system("rm -fr dot_test") self.mnemosyne = Mnemosyne() self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_main_controller", "Widget")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.review_widget", "ReviewWidget")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "AddCardsDialog")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "EditFactDialog")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "BrowseCardsDialog")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "CardAppearanceDialog")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "ActivatePluginsDialog")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "ManageCardTypesDialog")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "StatisticsDialog")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "ConfigurationDialog")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "ActivateCardsDialog")) self.mnemosyne.initialise(os.path.abspath("dot_test")) self.review_controller().reset() def test_coverage(self): self.controller().heartbeat() self.controller().add_cards() card_type = self.card_type_by_id("2") fact_data = {"q": "q", "a": "a"} card_1, card_2 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) self.review_controller().new_question() self.controller().edit_current_card() self.controller().file_new() self.controller().file_open() self.controller().file_save_as() self.controller().card_appearance() self.controller().activate_plugins() self.controller().manage_card_types() self.controller().browse_cards() self.controller().configure() self.controller().show_statistics() self.controller().activate_cards() def test_2(self): self.controller().file_save_as() self.controller().file_open()
class TestDBImport(MnemosyneTest): def setup(self): self.initialise_data_dir() self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("mnemosyne_test", "TestReviewWidget")) self.mnemosyne.components.append(\ ("test_db_import", "Widget")) self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.review_controller().reset() def db_importer(self): for format in self.mnemosyne.component_manager.all("file_format"): if format.__class__.__name__ == "Mnemosyne2Db": return format def test_1(self): filename = os.path.join(os.getcwd(), "tests", "files", "basedir_to_merge", "config.db") self.db_importer().do_import(filename) assert "configuration database" in last_error def test_2(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") old_card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] assert len([self.database().cards()]) == 1 filename = os.path.join(os.getcwd(), "tests", "files", "basedir_to_merge", "to_merge.db") global last_error last_error = "" self.db_importer().do_import(filename) assert last_error == "" db = self.database() assert db.con.execute("select count() from log where event_type != 26").fetchone()[0] == 258 self.review_controller().reset() assert self.database().card_count() == 7 assert self.database().active_count() == 6 assert self.database().fact_count() == 5 card_type = self.database().card_type("2::new clone", is_id_internal=False) assert self.config().card_type_property("background_colour", card_type) == 4278233600
class MyServer(Server): program_name = "Mnemosyne" program_version = "test" capabilities = "TODO" def __init__(self): shutil.rmtree(os.path.abspath("dot_sync_server"), ignore_errors=True) self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True) self.mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.gui_translator", "GetTextGuiTranslator")) self.mnemosyne.components.append(("test_sync", "Widget")) self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \ [("mnemosyne_test", "TestReviewWidget")] self.mnemosyne.initialise(os.path.abspath("dot_sync_server"), automatic_upgrades=False) self.mnemosyne.config().change_user_id("user_id") self.mnemosyne.review_controller().reset() self.supports_binary_transfer = lambda x: False # Add 20 cards to database. card_type = self.mnemosyne.card_type_with_id("1") for i in range(20): fact_data = {"f": "question %d" % (i, ), "b": "answer"} self.mnemosyne.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default" ])[0] self.mnemosyne.database().save() self.mnemosyne.database().release_connection() def authorise(self, login, password): return login == "user" and password == "pass" def load_database(self, database_name): self.mnemosyne.database().load(database_name) return self.mnemosyne.database() def unload_database(self, database): self.mnemosyne.database().release_connection() # Dirty way to make sure we restart the server and create a new database # (as opposed to keep sending old history back and forth)' self.wsgi_server.stop() def run(self): Server.__init__(self, "client_machine_id", 8186, self.mnemosyne.main_widget()) self.serve_until_stopped()
def test_setup(): shutil.rmtree("dot_test", ignore_errors=True) global mnemosyne mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True) mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) mnemosyne.components.append(\ ("test_add_cards", "Widget")) mnemosyne.components.append(\ ("mnemosyne_test", "TestReviewWidget")) mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "EditCardDialog")) mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) mnemosyne.review_controller().reset()
def test_setup(): shutil.rmtree("dot_test", ignore_errors=True) global mnemosyne mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True) mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) mnemosyne.components.append(\ ("test_add_cards", "Widget")) mnemosyne.gui_for_component["ScheduledForgottenNew"] = \ [("mnemosyne_test", "TestReviewWidget")] mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "EditCardDialog")) mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) mnemosyne.review_controller().reset()
class MyServer(Server): program_name = "Mnemosyne" program_version = "test" capabilities = "TODO" def __init__(self): shutil.rmtree(os.path.abspath("dot_sync_server"), ignore_errors=True) self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True) self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translator", "GetTextTranslator")) self.mnemosyne.components.append(("test_sync", "Widget")) self.mnemosyne.components.append(("mnemosyne_test", "TestReviewWidget")) self.mnemosyne.initialise(os.path.abspath("dot_sync_server"), automatic_upgrades=False) self.mnemosyne.config().change_user_id("user_id") self.mnemosyne.review_controller().reset() self.supports_binary_transfer = lambda x : False # Add 20 cards to database. card_type = self.mnemosyne.card_type_with_id("1") for i in range (20): fact_data = {"f": "question %d" % (i,), "b": "answer"} self.mnemosyne.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.mnemosyne.database().save() self.mnemosyne.database().release_connection() def authorise(self, login, password): return login == "user" and password == "pass" def load_database(self, database_name): self.mnemosyne.database().load(database_name) return self.mnemosyne.database() def unload_database(self, database): self.mnemosyne.database().release_connection() # Dirty way to make sure we restart the server and create a new database # (as opposed to keep sending old history back and forth)' self.wsgi_server.stop() def run(self): Server.__init__(self, "client_machine_id", 8186, self.mnemosyne.main_widget()) self.serve_until_stopped()
class MyServer(Server): program_name = "Mnemosyne" program_version = "test" capabilities = "TODO" stop_after_sync = True def __init__(self): os.system("rm -rf sync_from_here") self.mnemosyne = Mnemosyne() self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translator", "GetTextTranslator")) self.mnemosyne.components.append(("test_sync", "Widget")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "ProgressDialog")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.review_widget", "ReviewWidget")) self.mnemosyne.initialise(os.path.abspath("sync_from_here")) self.mnemosyne.config().change_user_id("user_id") self.mnemosyne.review_controller().reset() # Add 20 cards to database. card_type = self.mnemosyne.card_type_by_id("1") for i in range (20): fact_data = {"q": "question %d" % (i,), "a": "answer"} self.mnemosyne.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.mnemosyne.database().save() def authorise(self, login, password): return login == "user" and password == "pass" def open_database(self, database_name): return self.mnemosyne.database() def run(self): Server.__init__(self, "client_machine_id", "192.168.2.54", 8186, self.mnemosyne.main_widget()) # Because we stop_after_sync is True, serve_forever will actually stop # after one sync. self.serve_forever() self.mnemosyne.finalise()
def startup(): global mnemosyne # Note that this also includes building the queue and getting the first card. mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True) mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.translators.no_translator", "NoTranslator")) mnemosyne.components.append( ("mnemosyne.libmnemosyne.ui_components.main_widget", "MainWidget")) mnemosyne.components.append(("mnemosyne_test", "TestReviewWidget")) mnemosyne.initialise(data_dir=os.path.abspath("dot_benchmark"), automatic_upgrades=False) #mnemosyne.initialise(data_dir="\SDMMC\.mnemosyne", #automatic_upgrades=False) mnemosyne.start_review()
class TestSM7Import(MnemosyneTest): def setup(self): self.initialise_data_dir() self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.gui_translators.gettext_gui_translator", "GetTextGuiTranslator")) self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \ [("mnemosyne_test", "TestReviewWidget")] self.mnemosyne.components.append(\ ("test_supermemo_7_text_import", "Widget")) self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.review_controller().reset() def sm7_importer(self): for format in self.mnemosyne.component_manager.all("file_format"): if format.__class__.__name__ == "SuperMemo7Txt": return format def test_1(self): global last_error filename = os.path.join(os.getcwd(), "tests", "files", "sm7.txt") self.sm7_importer().do_import(filename) assert last_error is "" assert len([c for c in self.database().cards()]) == 4 def teardown(self): filename = \ os.path.join(os.getcwd(), "dot_test", "default.db_media", "a.png") if os.path.exists(filename): os.remove(filename) filename = \ os.path.join(os.getcwd(), "dot_test", "test.txt") if os.path.exists(filename): os.remove(filename) MnemosyneTest.teardown(self)
class MyServer(Server, Thread): program_name = "Mnemosyne" program_version = "test" capabilities = "TODO" stop_after_sync = True def __init__(self): Thread.__init__(self) self.mnemosyne = Mnemosyne() self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translator", "GetTextTranslator")) self.mnemosyne.components.append(("test_sync", "Widget")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "ProgressDialog")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.review_widget", "ReviewWidget")) def authorise(self, login, password): return login == "user" and password == "pass" def open_database(self, database_name): return self.mnemosyne.database() def run(self): # We only open the database connection inside the thread to prevent # access problems, as a single connection can only be used inside a # single thread. self.mnemosyne.initialise(os.path.abspath("sync_from_here")) self.mnemosyne.review_controller().reset() Server.__init__(self, "server_machine_id", "127.0.0.1", 8190, self.mnemosyne.main_widget()) # Because we stop_after_sync is True, serve_forever will actually stop # after one sync. self.serve_forever() self.mnemosyne.finalise()
def startup(): global mnemosyne # Note that this also includes building the queue and getting the first card. mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True) mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translators.no_translator", "NoTranslator")) mnemosyne.components.append( ("mnemosyne.libmnemosyne.ui_components.main_widget", "MainWidget")) mnemosyne.components.append( ("mnemosyne_test", "TestReviewWidget")) mnemosyne.initialise(data_dir=os.path.abspath("dot_benchmark"), automatic_upgrades=False) #mnemosyne.initialise(data_dir="\SDMMC\.mnemosyne", #automatic_upgrades=False) mnemosyne.start_review()
class TestAnkiImport(MnemosyneTest): def setup(self): path = os.path.join(os.getcwd(), "..", "mnemosyne", "libmnemosyne", "renderers") if path not in sys.path: sys.path.append(path) self.initialise_data_dir() self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \ [("mnemosyne_test", "TestReviewWidget")] self.mnemosyne.components.append(\ ("test_mem_import", "Widget")) self.mnemosyne.components.append(\ ("test_mem_import", "MyImportDialog")) self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.review_controller().reset() def anki_importer(self): for format in self.mnemosyne.component_manager.all("file_format"): if format.__class__.__name__ == "Anki2": return format def _test_database(self): assert self.database().card_count() == 7 assert self.database().fact_count() == 6 card = self.database().card("1502277582871", is_id_internal=False) assert "img src=\"al.png\"" in card.question(render_chain="plain_text") assert self.config().card_type_property(\ "font", card.card_type, "0") == \ "Algerian,23,-1,5,50,0,0,0,0,0,Regular" assert card.next_rep == 1503021600 assert card.last_rep == card.next_rep - 3 * 86400 card = self.database().card("1502277594395", is_id_internal=False) assert "audio src=\"1.mp3\"" in card.question( render_chain="plain_text") card = self.database().card("1502277686022", is_id_internal=False) assert "<$$>x</$$> <latex>x^2</latex> <$>x^3</$>" in\ card.question(render_chain="plain_text") card = self.database().card("1502797276041", is_id_internal=False) assert "aa <span class=cloze>[...]</span> cc" in\ card.question(render_chain="plain_text") assert "aa <span class=cloze>bbb</span> cc" in\ card.answer(render_chain="plain_text") card = self.database().card("1502797276050", is_id_internal=False) assert "aa bbb <span class=cloze>[...]</span>" in\ card.question(render_chain="plain_text") assert "aa bbb <span class=cloze>cc</span>" in\ card.answer(render_chain="plain_text") assert card.next_rep == -1 assert card.last_rep == -1 card = self.database().card("1502970432696", is_id_internal=False) assert "type answer" in\ card.question(render_chain="plain_text") assert "{{type:Back}}" not in\ card.question(render_chain="plain_text") assert card.next_rep == 1502970472 assert card.last_rep == 1502970472 card = self.database().card("1503047582690", is_id_internal=False) assert "subdeck card" in\ card.question(render_chain="plain_text") assert card.next_rep == -1 assert card.last_rep == -1 assert card.easiness == 2.5 criterion = self.database().criterion(id=2, is_id_internal=True) assert criterion.data_to_string() == "(set(), {2}, set())" assert criterion.name == "Deck 1" assert len(list(self.database().criteria())) == 3 def test_anki_1(self): filename = os.path.join(os.getcwd(), "tests", "files", "anki1", "collection.anki2") self.anki_importer().do_import(filename) self.review_controller().reset() self._test_database() def test_anki_import_twice(self): filename = os.path.join(os.getcwd(), "tests", "files", "anki1", "collection.anki2") self.anki_importer().do_import(filename) self.anki_importer().do_import(filename) self.review_controller().reset() self._test_database() def test_anki_apkg(self): filename = os.path.join( os.getcwd(), "tests", "files", "anki1.apkg", ) self.anki_importer().do_import(filename) self.review_controller().reset() self._test_database()
class TestMedia(MnemosyneTest): def restart(self): self.mnemosyne = Mnemosyne() self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_media", "Widget")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.review_widget", "ReviewWidget")) self.mnemosyne.initialise(os.path.abspath("dot_test")) self.review_controller().reset() def test_sound_1(self): global filename filename = "" self.controller().insert_sound("") def test_sound_2(self): global filename file("a.ogg", "w") filename = os.path.abspath("a.ogg") self.controller().insert_sound("") assert os.path.exists(os.path.join(self.config().mediadir(), "a.ogg")) filename = os.path.join(self.config().mediadir(), "a.ogg") self.controller().insert_sound("") assert os.path.exists(os.path.join(self.config().mediadir(), "a.ogg")) def test_sound_3(self): global filename file("a.ogg", "w") filename = os.path.abspath("a.ogg") self.controller().insert_sound("") assert os.path.exists(os.path.join(self.config().mediadir(), "a.ogg")) self.controller().insert_sound("") assert os.path.exists(os.path.join(self.config().mediadir(), "a_1_.ogg")) self.controller().insert_sound("") assert os.path.exists(os.path.join(self.config().mediadir(), "a_2_.ogg")) def test_img_1(self): global filename filename = "" self.controller().insert_img("") def test_img_2(self): global filename file("a.ogg", "w") filename = os.path.abspath("a.ogg") self.controller().insert_img("") assert os.path.exists(os.path.join(self.config().mediadir(), "a.ogg")) filename = os.path.join(self.config().mediadir(), "a.ogg") self.controller().insert_img("") assert os.path.exists(os.path.join(self.config().mediadir(), "a.ogg")) def test_media_subdir(self): global filename subdir = os.path.join(self.config().mediadir(), "subdir") os.mkdir(subdir) filename = os.path.join(subdir, "b.ogg") os.system("touch %s" % filename) self.controller().insert_img("") assert os.path.exists(os.path.join(self.config().mediadir(), "subdir", "b.ogg")) def test_card(self): file("a.ogg", "w") full_path = os.path.abspath("a.ogg") fact_data = {"q": "<img src=\"%s\">" % full_path, "a": "answer"} card_type = self.card_type_by_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] full_path_in_media_dir = os.path.join(self.config().mediadir(), "a.ogg") assert os.path.exists(full_path_in_media_dir) assert full_path not in card.fact.data["q"] assert full_path_in_media_dir not in card.fact.data["q"] assert full_path not in card.question() assert full_path_in_media_dir in card.question() assert self.database().con.execute(\ "select count() from log where event=?", (self.database().ADDED_MEDIA, )).fetchone()[0] == 1 def test_card_2(self): fact_data = {"q": "<img src=\"a.ogg>", # Missing closing " "a": "answer"} card_type = self.card_type_by_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] assert os.path.join(self.config().mediadir(), "a.ogg") \ not in card.question() def test_card_edit_none(self): file("a.ogg", "w") full_path = os.path.abspath("a.ogg") fact_data = {"q": "<img src=\"%s\">" % full_path, "a": "answer"} card_type = self.card_type_by_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] full_path_in_media_dir = os.path.join(self.config().mediadir(), "a.ogg") fact_data = {"q": "edited <img src=\"%s\">" % "a.ogg", "a": "answer"} self.controller().update_related_cards(card.fact, fact_data, card_type, new_tag_names=["bla"], correspondence=None) assert os.path.exists(full_path_in_media_dir) assert full_path not in card.fact.data["q"] assert full_path_in_media_dir not in card.fact.data["q"] assert full_path not in card.question() assert full_path_in_media_dir in card.question() assert self.database().con.execute(\ "select count() from log where event=?", (self.database().ADDED_MEDIA, )).fetchone()[0] == 1 def test_card_edit_add(self): file("a.ogg", "w") full_path = os.path.abspath("a.ogg") fact_data = {"q": "<img src=\"%s\">" % full_path, "a": "answer"} card_type = self.card_type_by_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] os.system("touch b.ogg") full_path = os.path.abspath("b.ogg") fact_data = {"q": "edited <img src=\"%s\"> <img src=\"%s\">" \ % ("a.ogg", full_path), "a": "answer"} self.controller().update_related_cards(card.fact, fact_data, card_type, new_tag_names=["bla"], correspondence=None) full_path_in_media_dir = os.path.join(self.config().mediadir(), "b.ogg") assert os.path.exists(full_path_in_media_dir) assert full_path not in card.fact.data["q"] assert full_path_in_media_dir not in card.fact.data["q"] assert full_path not in card.question() assert full_path_in_media_dir in card.question() assert self.database().con.execute(\ "select count() from log where event=?", (self.database().ADDED_MEDIA, )).fetchone()[0] == 2 def test_card_edit_delete(self): file("a.ogg", "w") full_path = os.path.abspath("a.ogg") fact_data = {"q": "<img src=\"%s\">" % full_path, "a": "answer"} card_type = self.card_type_by_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact_data = {"q": "edited ", "a": "answer"} self.controller().update_related_cards(card.fact, fact_data, card_type, new_tag_names=["bla"], correspondence=None) full_path_in_media_dir = os.path.join(self.config().mediadir(), "a.ogg") assert not os.path.exists(full_path_in_media_dir) assert full_path_in_media_dir not in card.question() assert self.database().con.execute(\ "select count() from log where event=?", (self.database().ADDED_MEDIA, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select count() from log where event=?", (self.database().DELETED_MEDIA, )).fetchone()[0] == 1 def test_card_edit_delete_used_by_other(self): file("a.ogg", "w") full_path = os.path.abspath("a.ogg") fact_data = {"q": "<img src=\"%s\">" % full_path, "a": "answer"} card_type = self.card_type_by_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact_data = {"q": "2 <img src=\"%s\">" % "a.ogg", "a": "answer"} self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact_data = {"q": "edited", "a": "answer"} self.controller().update_related_cards(card.fact, fact_data, card_type, new_tag_names=["bla"], correspondence=None) full_path_in_media_dir = os.path.join(self.config().mediadir(), "a.ogg") assert os.path.exists(full_path_in_media_dir) # Don't delete file. assert full_path_in_media_dir not in card.question() assert self.database().con.execute(\ "select count() from log where event=?", (self.database().ADDED_MEDIA, )).fetchone()[0] == 2 assert self.database().con.execute(\ "select count() from log where event=?", (self.database().DELETED_MEDIA, )).fetchone()[0] == 1 def test_delete_fact(self): file("a.ogg", "w") full_path = os.path.abspath("a.ogg") fact_data = {"q": "<img src=\"%s\">" % full_path, "a": "answer"} card_type = self.card_type_by_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.database().delete_fact_and_related_data(card.fact) full_path_in_media_dir = os.path.join(self.config().mediadir(), "a.ogg") assert not os.path.exists(full_path_in_media_dir) assert self.database().con.execute(\ "select count() from log where event=?", (self.database().ADDED_MEDIA, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select count() from log where event=?", (self.database().DELETED_MEDIA, )).fetchone()[0] == 1 def test_delete_fact_used_by_other(self): file("a.ogg", "w") full_path = os.path.abspath("a.ogg") fact_data = {"q": "<img src=\"%s\">" % full_path, "a": "answer"} card_type = self.card_type_by_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact_data = {"q": "2 <img src=\"%s\">" % "a.ogg", "a": "answer"} self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.database().delete_fact_and_related_data(card.fact) full_path_in_media_dir = os.path.join(self.config().mediadir(), "a.ogg") assert os.path.exists(full_path_in_media_dir) # Not deleted. assert self.database().con.execute(\ "select count() from log where event=?", (self.database().ADDED_MEDIA, )).fetchone()[0] == 2 assert self.database().con.execute(\ "select count() from log where event=?", (self.database().DELETED_MEDIA, )).fetchone()[0] == 1 def teardown(self): if os.path.exists("a.ogg"): os.remove("a.ogg") if os.path.exists("b.ogg"): os.remove("b.ogg") MnemosyneTest.teardown(self)
"Schedule"), ("mnemosyne.libmnemosyne.statistics_pages.retention_score", "RetentionScore"), ("mnemosyne.libmnemosyne.statistics_pages.cards_added", "CardsAdded"), ("mnemosyne.libmnemosyne.statistics_pages.cards_learned", "CardsLearned"), ("mnemosyne.libmnemosyne.statistics_pages.grades", "Grades"), ("mnemosyne.libmnemosyne.statistics_pages.easiness", "Easiness"), ("mnemosyne.libmnemosyne.statistics_pages.current_card", "CurrentCard"), ("main_wdgt", "MainWdgt")] mnemosyne.initialise(data_dir, filename=filename) # Sync before starting the review server. if mnemosyne.main_widget().show_question(\ "Perform sync?", "Yes", "No", "") == 0: mnemosyne.controller().sync(sync_server, sync_port, sync_username, sync_password) # Make sure the config gets picked up when starting a new # Mnemosyne instance in the web server. mnemosyne.config().save() # Start review server. mnemosyne.database().release_connection() from mnemosyne.web_server.web_server import WebServerThread web_server_thread = WebServerThread\ (mnemosyne.component_manager, is_server_local=True)
class TestLogging(MnemosyneTest): def restart(self): self.mnemosyne = Mnemosyne() self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_logging", "MyMainWidget")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.review_widget", "ReviewWidget")) self.mnemosyne.initialise(os.path.abspath("dot_test")) self.review_controller().reset() def test_logging(self): card_type = self.card_type_by_id("1") fact_data = {"q": "1", "a": "a"} card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.review_controller().new_question() self.review_controller().grade_answer(0) self.review_controller().new_question() self.review_controller().grade_answer(1) self.review_controller().grade_answer(4) self.mnemosyne.finalise() self.restart() fact_data = {"q": "2", "a": "a"} card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.review_controller().new_question() self.controller().delete_current_fact() self.log().dump_to_science_log() sql_res = self.database().con.execute(\ "select * from log where _id=1").fetchone() assert sql_res["event_type"] == EventTypes.STARTED_PROGRAM sql_res = self.database().con.execute(\ "select * from log where _id=2").fetchone() assert sql_res["event_type"] == EventTypes.STARTED_SCHEDULER sql_res = self.database().con.execute(\ "select * from log where _id=3").fetchone() assert sql_res["event_type"] == EventTypes.LOADED_DATABASE assert sql_res["acq_reps"] == 0 assert sql_res["ret_reps"] == 0 assert sql_res["lapses"] == 0 sql_res = self.database().con.execute(\ "select * from log where _id=4").fetchone() assert sql_res["event_type"] == EventTypes.ADDED_FACT assert sql_res["object_id"] is not None sql_res = self.database().con.execute(\ "select * from log where _id=5").fetchone() assert sql_res["event_type"] == EventTypes.ADDED_TAG assert sql_res["object_id"] is not None sql_res = self.database().con.execute(\ "select * from log where _id=6").fetchone() assert sql_res["event_type"] == EventTypes.ADDED_CARD assert sql_res["object_id"] is not None sql_res = self.database().con.execute(\ "select * from log where _id=7").fetchone() assert sql_res["event_type"] == EventTypes.REPETITION assert sql_res["acq_reps"] == 1 assert sql_res["ret_reps"] == 0 assert sql_res["scheduled_interval"] == 0 assert sql_res["actual_interval"] == 0 assert sql_res["new_interval"] == 0 assert sql_res["thinking_time"] == 0 assert sql_res["object_id"] is not None sql_res = self.database().con.execute(\ "select * from log where _id=8").fetchone() assert sql_res["event_type"] == EventTypes.REPETITION assert sql_res["acq_reps"] == 2 assert sql_res["ret_reps"] == 0 assert sql_res["scheduled_interval"] == 0 assert sql_res["actual_interval"] == 0 assert sql_res["new_interval"] == 0 assert sql_res["thinking_time"] == 0 sql_res = self.database().con.execute(\ "select * from log where _id=9").fetchone() assert sql_res["event_type"] == EventTypes.REPETITION assert sql_res["acq_reps"] == 3 assert sql_res["ret_reps"] == 0 assert sql_res["scheduled_interval"] == 0 assert sql_res["actual_interval"] <= 10 # Depends on CPU load. assert sql_res["new_interval"] > 0 assert sql_res["thinking_time"] == 0 sql_res = self.database().con.execute(\ "select * from log where _id=10").fetchone() assert sql_res["event_type"] == EventTypes.SAVED_DATABASE assert sql_res["acq_reps"] == 0 assert sql_res["ret_reps"] == 0 assert sql_res["lapses"] == 1 sql_res = self.database().con.execute(\ "select * from log where _id=11").fetchone() assert sql_res["event_type"] == EventTypes.STOPPED_PROGRAM sql_res = self.database().con.execute(\ "select * from log where _id=12").fetchone() assert sql_res["event_type"] == EventTypes.STARTED_PROGRAM sql_res = self.database().con.execute(\ "select * from log where _id=13").fetchone() assert sql_res["event_type"] == EventTypes.STARTED_SCHEDULER sql_res = self.database().con.execute(\ "select * from log where _id=14").fetchone() assert sql_res["event_type"] == EventTypes.LOADED_DATABASE assert sql_res["acq_reps"] == 0 assert sql_res["ret_reps"] == 0 assert sql_res["lapses"] == 1 sql_res = self.database().con.execute(\ "select * from log where _id=15").fetchone() assert sql_res["event_type"] == EventTypes.ADDED_FACT assert sql_res["object_id"] is not None sql_res = self.database().con.execute(\ "select * from log where _id=16").fetchone() assert sql_res["event_type"] == EventTypes.ADDED_CARD sql_res = self.database().con.execute(\ "select * from log where _id=17").fetchone() assert sql_res["event_type"] == EventTypes.DELETED_CARD assert sql_res["object_id"] is not None sql_res = self.database().con.execute(\ "select * from log where _id=18").fetchone() assert sql_res["event_type"] == EventTypes.DELETED_FACT assert sql_res["object_id"] is not None def test_unique_index(self): fact_data = {"q": "question", "a": "answer"} card_type_2 = self.card_type_by_id("2") card_1, card_2 = self.controller().create_new_cards(fact_data, card_type_2, grade=-1, tag_names=["default"]) log_index = self.database().con.execute(\ """select _id from log order by _id desc limit 1""").fetchone()[0] # Note: we need to keep the last log entry intact, otherwise indices # start again at 1 and mess up the sync. self.database().con.execute("""delete from log where _id <?""", (log_index,)) self.database().con.execute("""vacuum""") self.database().save() fact_data = {"q": "question2", "a": "answer2"} card_type_2 = self.card_type_by_id("1") card_1 = self.controller().create_new_cards(fact_data, card_type_2, grade=-1, tag_names=["default"]) assert self.database().con.execute(\ """select _id from log order by _id limit 1""").fetchone()[0] \ == log_index
class WebServer(Component): def __init__(self, component_manager, port, data_dir, config_dir, filename, is_server_local=False): Component.__init__(self, component_manager) self.port = port self.data_dir = data_dir self.config_dir = config_dir self.filename = filename self.is_server_local = is_server_local # When restarting the server, make sure we discard info from the # browser resending the form from the previous session. self.is_just_started = True self.is_mnemosyne_loaded = False self.is_shutting_down = False self.wsgi_server = wsgiserver.CherryPyWSGIServer(\ ("0.0.0.0", port), self.wsgi_app, server_name="localhost", numthreads=1, timeout=5) # We need to set the timeout relatively low, otherwise it will take # too long for the server to process a 'stop' request. def serve_until_stopped(self): try: self.wsgi_server.start() # Sets self.wsgi_server.ready except KeyboardInterrupt: self.wsgi_server.stop() self.unload_mnemosyne() def stop(self): self.wsgi_server.stop() self.unload_mnemosyne() def load_mnemosyne(self): self.mnemosyne = Mnemosyne(upload_science_logs=True, interested_in_old_reps=True) self.mnemosyne.components.insert( 0, (("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator"))) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.main_widget", "MainWidget")) self.mnemosyne.components.append(\ ("mnemosyne.web_server.review_wdgt", "ReviewWdgt")) self.mnemosyne.components.append(\ ("mnemosyne.web_server.web_server_render_chain", "WebServerRenderChain")) self.mnemosyne.initialise(self.data_dir, config_dir=self.config_dir, filename=self.filename, automatic_upgrades=False) self.mnemosyne.review_controller().set_render_chain("web_server") self.save_after_n_reps = self.mnemosyne.config()["save_after_n_reps"] self.mnemosyne.config()["save_after_n_reps"] = 1 self.mnemosyne.start_review() self.mnemosyne.review_widget().set_is_server_local(\ self.is_server_local) self.is_mnemosyne_loaded = True self.release_database_after_timeout = \ ReleaseDatabaseAfterTimeout(self.port) self.release_database_after_timeout.start() def unload_mnemosyne(self): if not self.is_mnemosyne_loaded: return self.mnemosyne.config()["save_after_n_reps"] = self.save_after_n_reps self.mnemosyne.finalise() self.is_mnemosyne_loaded = False def wsgi_app(self, environ, start_response): filename = environ["PATH_INFO"].decode("utf-8") if filename == "/status": response_headers = [("Content-type", "text/html")] start_response("200 OK", response_headers) return ["200 OK"] # Sometimes, even after the user has clicked 'exit' in the page, # a browser sends a request for e.g. an audio file. if self.is_shutting_down and filename != "/release_database": response_headers = [("Content-type", "text/html")] start_response("503 Service Unavailable", response_headers) return ["Server stopped"] # Load database if needed. if not self.is_mnemosyne_loaded and filename != "/release_database": self.load_mnemosyne() self.release_database_after_timeout.ping() # All our request return to the root page, so if the path is '/', # return the html of the review widget. if filename == "/": # Process clicked buttons in the form. form = cgi.FieldStorage(fp=environ["wsgi.input"], environ=environ) if "show_answer" in form and not self.is_just_started: self.mnemosyne.review_widget().show_answer() page = self.mnemosyne.review_widget().to_html() elif "grade" in form and not self.is_just_started: grade = int(form["grade"].value) self.mnemosyne.review_widget().grade_answer(grade) page = self.mnemosyne.review_widget().to_html() elif "star" in form: self.mnemosyne.controller().star_current_card() page = self.mnemosyne.review_widget().to_html() elif "exit" in form: self.unload_mnemosyne() page = "Server stopped" self.wsgi_server.stop() self.stop_server_after_timeout = \ StopServerAfterTimeout(self.wsgi_server) self.stop_server_after_timeout.start() self.is_shutting_down = True else: page = self.mnemosyne.review_widget().to_html() if self.is_just_started: self.is_just_started = False # Serve the web page. response_headers = [("Content-type", "text/html")] start_response("200 OK", response_headers) return [page] elif filename == "/release_database": self.unload_mnemosyne() response_headers = [("Content-type", "text/html")] start_response("200 OK", response_headers) return ["200 OK"] # We need to serve a media file. else: full_path = self.mnemosyne.database().media_dir() for word in filename.split("/"): full_path = os.path.join(full_path, word) request = Request(environ) # Check if file exists, but work around Android not reporting # the correct filesystem encoding. try: exists = os.path.exists(full_path) except (UnicodeEncodeError, UnicodeDecodeError): _ENCODING = sys.getfilesystemencoding() or \ locale.getdefaultlocale()[1] or "utf-8" full_path = full_path.encode(_ENCODING) if os.path.exists(full_path): etag = "%s-%s-%s" % (os.path.getmtime(full_path), os.path.getsize(full_path), hash(full_path)) else: etag = "none" app = FileApp(full_path, etag=etag) return app(request)(environ, start_response)
class TestTsvImport(MnemosyneTest): def setup(self): self.initialise_data_dir() self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.gui_translators.gettext_gui_translator", "GetTextGuiTranslator")) self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \ [("mnemosyne_test", "TestReviewWidget")] self.mnemosyne.components.append(\ ("test_tsv_import", "Widget")) self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.review_controller().reset() def tsv_importer(self): for format in self.mnemosyne.component_manager.all("file_format"): if format.__class__.__name__ == "Tsv": return format def test_file_not_found(self): global last_error filename = os.path.join(os.getcwd(), "tests", "files", "nothere.tsv") self.tsv_importer().do_import(filename) assert last_error.startswith("Could not load") last_error = "" def test_1(self): filename = os.path.join(os.getcwd(), "tests", "files", "tsv_1.txt") self.tsv_importer().do_import(filename) assert last_error == "" self.review_controller().reset() assert self.database().card_count() == 3 def test_2(self): filename = os.path.join(os.getcwd(), "tests", "files", "tsv_2.txt") self.tsv_importer().do_import(filename, 'extra_tag_name') assert last_error == "" self.review_controller().reset() assert self.database().card_count() == 2 assert chr(33267) in self.review_controller().card.answer() def test_3(self): global last_error filename = os.path.join(os.getcwd(), "tests", "files", "tsv_3.txt") self.tsv_importer().do_import(filename, 'extra_tag_name') assert last_error.startswith("Badly formed input") last_error = "" def test_4(self): global last_error filename = os.path.join(os.getcwd(), "tests", "files", "word_import.txt") self.tsv_importer().do_import(filename, 'extra_tag_name') assert self.database().card_count() == 5 assert last_error == "" def test_5(self): global last_error filename = os.path.join(os.getcwd(), "tests", "files", "excel_import.txt") self.tsv_importer().do_import(filename, 'extra_tag_name') assert self.database().card_count() == 5 assert last_error == "" # We no longer support non-utf-8 encoded files. #def test_6(self): # global last_error # filename = os.path.join(os.getcwd(), "tests", "files", "tsv_4.txt") # self.tsv_importer().do_import(filename, 'extra_tag_name') # assert self.database().card_count() == 1 # self.review_controller().reset() # assert "\\u00E0" in self.review_controller().card.question() # assert last_error == "" #def test_7(self): # global last_error # filename = os.path.join(os.getcwd(), "tests", "files", "tsv_5.txt") # self.tsv_importer().do_import(filename, 'extra_tag_name') # assert self.database().card_count() == 1 # self.review_controller().reset() # assert "\\u00E0" in self.review_controller().card.question() # assert last_error == "" def test_8(self): global last_error filename = os.path.join(os.getcwd(), "tests", "files", "tsv_6.txt") self.tsv_importer().do_import(filename, 'extra_tag_name') assert self.database().card_count() == 2 self.review_controller().reset() assert self.review_controller().card.fact["n"] == "notes" assert last_error == "" def test_media(self): global last_error open( os.path.join(os.getcwd(), "dot_test", "default.db_media", "a.png"), "w") filename = os.path.join(os.getcwd(), "tests", "files", "tsv_media.txt") self.tsv_importer().do_import(filename) assert self.database().card_count() == 2 assert self.database().card_count_for_tags(\ [self.database().get_or_create_tag_with_name("MISSING_MEDIA")], False) == 1 assert last_error == "" fact_data = {"f": "question", "b": ""} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(\ fact_data, card_type, grade=-1, tag_names=["default"])[0] self.tsv_importer().do_export( os.path.join(os.getcwd(), "dot_test", "test.txt")) def teardown(self): filename = \ os.path.join(os.getcwd(), "dot_test", "default.db_media", "a.png") if os.path.exists(filename): os.remove(filename) filename = \ os.path.join(os.getcwd(), "dot_test", "test.txt") if os.path.exists(filename): os.remove(filename) MnemosyneTest.teardown(self)
class TestAddCards(MnemosyneTest): def setup(self): self.initialise_data_dir() path = os.path.join(os.getcwd(), "..", "mnemosyne", "libmnemosyne", "renderers") if path not in sys.path: sys.path.append(path) self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_add_cards", "Widget")) self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \ [("mnemosyne_test", "TestReviewWidget")] self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "EditCardDialog")) self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.review_controller().reset() def test_1(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] assert self.database().is_in_use(card_type) is True self.controller().save_file() assert self.database().fact_count() == 1 assert self.database().card_count() == 1 def test_coverage(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] card.fact["f"] = "new_question" def test_src(self): fact_data = {"f": """<font face="courier">src</font>""", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] card.question() assert self.database().fact_count() == 1 assert self.database().card_count() == 1 def test_comparisons(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] assert card == card assert card.fact == card.fact assert card.fact_view == card.fact_view class A(object): pass a = A() assert card != a assert card.fact != a assert card.fact_view != a tag = card.tags.pop() assert tag == tag assert tag != a def test_1_duplicates(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) assert self.database().fact_count() == 1 assert self.database().card_count() == 1 def test_2(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("2") self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 def test_3(self): fact_data = { "f": "foreign word", "p_1": "pronunciation", "m_1": "translation" } card_type = self.card_type_with_id("3") self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 def test_delete(self): fact_data = {"f": "question1", "b": "answer1"} card_type = self.card_type_with_id("1") card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact_data = {"f": "question2", "b": "answer2"} card_2 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] assert set(tag.name for tag in card_1.tags) == \ set(tag.name for tag in card_2.tags) fact_data = {"f": "question3", "b": "answer3"} card_3 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.review_controller().show_new_question() assert self.review_controller().card == card_1 self.review_controller().grade_answer(0) self.controller().delete_facts_and_their_cards([card_3.fact]) self.review_controller().reset() for i in range(6): assert self.review_controller().card != card_3 self.review_controller().grade_answer(0) def test_delete_2(self): fact_data = {"f": "question1", "b": "answer1"} card_type = self.card_type_with_id("1") card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact_data = {"f": "question2", "b": "answer2"} card_2 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] assert set(tag.name for tag in card_1.tags) == \ set(tag.name for tag in card_2.tags) fact_data = {"f": "question3", "b": "answer3"} card_3 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.review_controller().show_new_question() assert self.review_controller().card == card_1 self.controller().delete_current_card() for i in range(6): assert self.review_controller().card != card_1 self.review_controller().grade_answer(0) def test_change_tag(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.review_controller().show_new_question() self.controller().edit_card_and_sisters(card, fact_data, card_type, ["new"], correspondence={}) new_card = self.database().card(card._id, is_id_internal=True) tag_names = [tag.name for tag in new_card.tags] assert len(tag_names) == 1 assert "new" in tag_names def test_untagged(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=[])[0] assert self.database().fact_count() == 1 assert self.database().card_count() == 1 new_card = self.database().card(card._id, is_id_internal=True) assert len(new_card.tags) == 1 def test_edit_untagged(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["tag"])[0] assert self.database().fact_count() == 1 assert self.database().card_count() == 1 new_card = self.database().card(card._id, is_id_internal=True) assert len(new_card.tags) == 1 self.controller().edit_card_and_sisters(new_card, new_card.fact.data, new_card.card_type, [" "], []) new_card = self.database().card(card._id, is_id_internal=True) assert len(new_card.tags) == 1 def test_edit_untagged_2(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=[""])[0] assert self.database().fact_count() == 1 assert self.database().card_count() == 1 new_card = self.database().card(card._id, is_id_internal=True) _untagged_id = list(new_card.tags)[0]._id self.controller().edit_card_and_sisters(new_card, new_card.fact.data, new_card.card_type, ["tag"], []) new_card = self.database().card(card._id, is_id_internal=True) assert list(new_card.tags)[0]._id != _untagged_id def test_duplicate(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["tag"])[0] self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["tag"]) assert self.database().fact_count() == 1 assert self.database().card_count() == 1 def test_duplicate_2(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["a", "b"])[0] global answer answer = 2 # Merge. fact_data = {"f": "question", "b": "answer2"} card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["b", "c"])[0] assert len(card.tags) == 3 assert self.database().fact_count() == 1 assert self.database().card_count() == 1 answer = 0 def test_duplicate_3(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["tag"])[0] fact_data = {"f": "question", "b": "answer2"} global answer answer = 1 # Add. self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["tag"]) assert self.database().fact_count() == 2 assert self.database().card_count() == 2 answer = 0 def test_duplicate_4(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["tag"])[0] fact_data = {"f": "question", "b": "answer2"} global answer answer = 0 # Don't add. self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["tag"]) assert self.database().fact_count() == 1 assert self.database().card_count() == 1 answer = 0 def test_log(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=3, tag_names=["default"])[0] self.controller().save_file() sql_res = self.database().con.execute(\ "select event_type, object_id from log where _id=14").fetchone() assert sql_res[0] == EventTypes.ADDED_CARD assert sql_res[1] is not None sql_res = self.database().con.execute(\ "select event_type from log where _id=15").fetchone() assert sql_res[0] == EventTypes.REPETITION def test_different_tags_per_sister_card(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("2") card, card_2 = self.controller().create_new_cards( fact_data, card_type, grade=3, tag_names=["default"]) self.database().add_tag_to_cards_with_internal_ids(\ self.database().get_or_create_tag_with_name("extra"), [card._id]) global answer answer = 0 card = self.database().card(card._id, is_id_internal=True) card_2 = self.database().card(card_2._id, is_id_internal=True) self.controller().edit_card_and_sisters(card, card.fact.data, card.card_type, ["extra2"], []) card = self.database().card(card._id, is_id_internal=True) card_2 = self.database().card(card_2._id, is_id_internal=True) assert card.tag_string() == "extra2" assert card_2.tag_string() == "default" def test_different_tags_per_sister_card_2(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("2") card, card_2 = self.controller().create_new_cards( fact_data, card_type, grade=3, tag_names=["default"]) self.database().add_tag_to_cards_with_internal_ids(\ self.database().get_or_create_tag_with_name("extra"), [card._id]) global answer answer = 1 card = self.database().card(card._id, is_id_internal=True) card_2 = self.database().card(card_2._id, is_id_internal=True) self.controller().edit_card_and_sisters(card, card.fact.data, card.card_type, ["extra2"], []) card = self.database().card(card._id, is_id_internal=True) card_2 = self.database().card(card_2._id, is_id_internal=True) assert card.tag_string() == "extra2" assert card_2.tag_string() == "extra2" answer = 0 def test_optional_keys(self): fact_data = {"f": "foreign", "m_1": "meaning", "n": ""} card_type = self.card_type_with_id("3") card = self.controller().create_new_cards(fact_data, card_type, grade=3, tag_names=["default"])[0] self.controller().save_file() assert self.database().con.execute(\ "select count() from data_for_fact where key='n'").fetchone()[0] == 0 fact_data_2 = {"f": "foreign", "m_1": "meaning", "n": "notes"} self.controller().edit_card_and_sisters(card, fact_data_2, card_type, [], {}) self.controller().save_file() assert self.database().con.execute(\ "select count() from data_for_fact where key='n'").fetchone()[0] == 1 self.controller().edit_card_and_sisters(card, fact_data, card_type, [], {}) self.controller().save_file() assert self.database().con.execute(\ "select count() from data_for_fact where key='n'").fetchone()[0] == 0
class MyClient(Client): program_name = "Mnemosyne" program_version = "test" capabilities = "TODO" def __init__(self): shutil.rmtree(os.path.abspath("dot_sync_client"), ignore_errors=True) self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True) self.mnemosyne.components = [ ("mnemosyne.libmnemosyne.translator", "NoTranslation"), ("mnemosyne.libmnemosyne.databases.SQLite", "SQLite"), ("mnemosyne.libmnemosyne.configuration", "Configuration"), ("mnemosyne.libmnemosyne.loggers.database_logger", "DatabaseLogger"), ("mnemosyne.libmnemosyne.schedulers.SM2_mnemosyne", "SM2Mnemosyne"), ("mnemosyne.libmnemosyne.stopwatch", "Stopwatch"), ("mnemosyne.libmnemosyne.card_types.front_to_back", "FrontToBack"), ("mnemosyne.libmnemosyne.card_types.both_ways", "BothWays"), ("mnemosyne.libmnemosyne.card_types.vocabulary", "Vocabulary"), ("mnemosyne.libmnemosyne.renderers.html_css", "HtmlCss"), ("mnemosyne.libmnemosyne.filters.escape_to_html", "EscapeToHtml"), ("mnemosyne.libmnemosyne.filters.expand_paths", "ExpandPaths"), ("mnemosyne.libmnemosyne.filters.latex", "Latex"), ("mnemosyne.libmnemosyne.render_chains.default_render_chain", "DefaultRenderChain"), ("mnemosyne.libmnemosyne.render_chains.plain_text_chain", "PlainTextChain"), ("mnemosyne.libmnemosyne.controllers.default_controller", "DefaultController"), ("mnemosyne.libmnemosyne.review_controllers.SM2_controller", "SM2Controller"), ("mnemosyne.libmnemosyne.card_types.map", "MapPlugin"), ("mnemosyne.libmnemosyne.card_types.cloze", "ClozePlugin"), ("mnemosyne.libmnemosyne.criteria.default_criterion", "DefaultCriterion"), ("mnemosyne.libmnemosyne.databases.SQLite_criterion_applier", "DefaultCriterionApplier"), ("mnemosyne.libmnemosyne.plugins.cramming_plugin", "CrammingPlugin") ] self.mnemosyne.components.append(("benchmark_sync_client", "Widget")) self.mnemosyne.components.append(("benchmark_sync_client", "MyReviewWidget")) self.mnemosyne.initialise(os.path.abspath(os.path.join(os.getcwd(), "dot_sync_client")), automatic_upgrades=False) self.mnemosyne.config().change_user_id("user_id") self.check_for_edited_local_media_files = False self.do_backup = False self.mnemosyne.review_controller().reset() # Do 200 reviews. card_type = self.mnemosyne.card_type_with_id("1") fact_data = {"f": "question", "b": "answer"} card = self.mnemosyne.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.mnemosyne.database().save() self.mnemosyne.review_controller().show_new_question() for i in range(200): self.mnemosyne.review_controller().show_answer() self.mnemosyne.review_controller().grade_answer(0) Client.__init__(self, "client_machine_id", self.mnemosyne.database(), self.mnemosyne.main_widget()) def do_sync(self): #self.BUFFER_SIZE = 10*8192 #self.behind_proxy = True self.sync("localhost", 8186, "user", "pass") self.mnemosyne.database().save()
class TestDatabase(MnemosyneTest): def setup(self): self.initialise_data_dir() self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_database", "Widget")) self.mnemosyne.components.append(\ ("mnemosyne_test", "TestReviewWidget")) self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.review_controller().reset() def test_release(self): self.database().release_connection() self.database().release_connection() self.database().display_name() self.database().abandon() self.database().new("default.mem") def test_tags(self): tag = Tag("test") self.database().add_tag(tag) assert len(self.database().tags()) == 2 assert self.database().tags()[0].name == u"test" tag.name = "test2" self.database().update_tag(tag) assert len(self.database().tags()) == 2 assert self.database().tags()[0].name == u"test2" def test_tag_order(self): tag = Tag("a") self.database().add_tag(tag) tag = Tag("1. a") self.database().add_tag(tag) assert [tag.name for tag in self.database().tags()] == ["1. a", "a", "__UNTAGGED__"] def test_new_cards(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") old_card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] assert len([self.database().cards()]) == 1 old_fact = old_card.fact self.database().unload() self.database().load(self.config()["last_database"]) assert self.database().fact_count() == 1 card = self.database().card(old_card._id, is_id_internal=True) fact = card.fact assert fact.data["f"] == "question" assert fact.data["b"] == "answer" assert fact.id == old_fact.id assert [tag.name for tag in card.tags] == \ [tag.name for tag in old_card.tags] assert card.fact == old_card.fact assert card.fact_view == old_card.fact_view assert card.id == old_card.id assert card.creation_time == old_card.creation_time assert card.modification_time == old_card.modification_time assert card.grade == old_card.grade assert card.easiness == old_card.easiness assert card.acq_reps == old_card.acq_reps assert card.ret_reps == old_card.ret_reps assert card.lapses == old_card.lapses assert card.acq_reps_since_lapse == old_card.acq_reps_since_lapse assert card.last_rep == old_card.last_rep assert card.next_rep == old_card.next_rep assert card.extra_data == old_card.extra_data assert card.scheduler_data == old_card.scheduler_data assert card.active == old_card.active # Modify cards card.grade = -1 card.easiness = -2 card.acq_reps = -3 card.ret_reps = -4 card.lapses = -5 card.acq_reps_since_lapse = -6 card.last_rep = -7 card.next_rep = -8 card.extra_data = "extra" card.scheduler_data = 1 card.in_view = False self.database().update_card(card) new_card = list(self.database().cards_from_fact(fact))[0] assert card.grade == -1 assert card.easiness == -2 assert card.acq_reps == -3 assert card.ret_reps == -4 assert card.lapses == -5 assert card.acq_reps_since_lapse == -6 assert card.last_rep == -7 assert card.next_rep == -8 assert card.extra_data == "extra" assert card.scheduler_data == 1 def test_update_tag(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact self.controller().edit_card_and_sisters(card, fact_data, card_type, new_tag_names=["default1"], correspondence=[]) new_card = self.database().card(card._id, is_id_internal=True) tag_names = [tag.name for tag in new_card.tags] assert len(tag_names) == 1 assert "default1" in tag_names assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.EDITED_CARD, )).fetchone()[0] == 1 def test_empty_argument(self): assert self.database().tags_from_cards_with_internal_ids([]) == [] def test_clones(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact self.controller().clone_card_type(card_type, "my_1") new_card_type = self.card_type_with_id("1::my_1") self.controller().edit_card_and_sisters(card, fact_data, new_card_type, new_tag_names=["default2"], correspondence=[]) self.mnemosyne.finalise() self.restart() assert self.database().fact_count() == 1 _card_id, _fact_id = list(self.database().cards_unseen())[0] fact = self.database().fact(_fact_id, is_id_internal=True) card_type = self.card_type_with_id("1::my_1") assert card_type.id == "1::my_1" assert card_type == card_type def test_plugin_and_clones(self): for plugin in self.plugins(): component = plugin.components[0] if component.component_type == "card_type" and component.id == "4": plugin.activate() fact_data = {"loc": "location", "blank": "blank", "marked": "marked"} card_type = self.card_type_with_id("4") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] assert self.database().fact_count() == 1 fact = card.fact self.controller().clone_card_type(card_type, "my_4") new_card_type = self.card_type_with_id("4::my_4") self.controller().edit_card_and_sisters(card, fact_data, new_card_type, new_tag_names=["default2"], correspondence=[]) assert self.database().fact_count() == 1 self.mnemosyne.finalise() self.restart() assert self.database().fact_count() == 1 _card_id, _fact_id = list(self.database().cards_unseen())[0] fact = self.database().fact(_fact_id, is_id_internal=True) card_type = self.card_type_with_id("4") card_type = self.card_type_with_id("4::my_4") assert card_type.id == "4::my_4" assert card_type == card_type card = self.database().cards_from_fact(fact)[0] card.question() def test_new_database_overriding_existing_one(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) self.database().new(self.config()["last_database"]) assert self.database().fact_count() == 0 def test_delete_fact(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact self.controller().delete_facts_and_their_cards([fact]) assert self.database().fact_count() == 0 assert self.database().card_count() == 0 assert len(self.database().tags()) == 1 @raises(RuntimeError) def test_missing_plugin(self): for plugin in self.plugins(): component = plugin.components[0] if component.component_type == "card_type" and component.id == "4": plugin.activate() fact_data = {"loc": "location", "blank": "blank", "marked": "marked"} card_type = self.card_type_with_id("4") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact self.controller().clone_card_type(card_type, "my_4") new_card_type = self.card_type_with_id("4::my_4") self.controller().edit_card_and_sisters(card, fact_data, new_card_type, new_tag_names=["default2"], correspondence=[]) self.mnemosyne.finalise() self.restart() # Artificially remove plugin. self.database().unload() for plugin in self.plugins(): component = plugin.components[0] if component.component_type == "card_type" and component.id == "4": plugin.deactivate() self.mnemosyne.component_manager.unregister(plugin) def dont_finalise(): from mnemosyne.libmnemosyne.component_manager import clear_component_managers clear_component_managers() self.mnemosyne.finalise = dont_finalise self.database().load(self.config()["last_database"]) def infinity(self): return 1/0 @raises(RuntimeError) def test_corrupt_plugin(self): for plugin in self.plugins(): component = plugin.components[0] if component.component_type == "card_type" and component.id == "4": plugin.activate() fact_data = {"loc": "location", "blank": "blank", "marked": "marked"} card_type = self.card_type_with_id("4") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact self.controller().clone_card_type(card_type, "my_4") new_card_type = self.card_type_with_id("4::my_4") self.controller().edit_card_and_sisters(card, fact_data, new_card_type, new_tag_names=["default2"], correspondence=[]) self.mnemosyne.finalise() self.restart() self.database().unload() # Artificially mutilate plugin. for plugin in self.plugins(): component = plugin.components[0] if component.component_type == "card_type" and component.id == "4": plugin.deactivate() plugin.activate = self.infinity break def dont_finalise(): from mnemosyne.libmnemosyne.component_manager import clear_component_managers clear_component_managers() self.mnemosyne.finalise = dont_finalise self.database().load(self.config()["last_database"]) def test_save_as(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) new_name = self.config()["last_database"] + ".bak" assert self.database().save(self.config()["last_database"] + ".bak") != -1 assert self.config()["last_database"] == new_name assert new_name != expand_path(new_name, self.config().data_dir) def test_duplicates_for_fact(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"], check_for_duplicates=False)[0] fact = card.fact fact_data = {"f": "question_", "b": "answer_"} card_type = self.card_type_with_id("1") self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"], check_for_duplicates=False) assert len(self.database().duplicates_for_fact(fact, card_type)) == 0 fact_data = {"f": "question1", "b": "answer"} card_type = self.card_type_with_id("1") self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"], check_for_duplicates=False) assert len(self.database().duplicates_for_fact(fact, card_type)) == 0 fact_data = {"f": "question", "b": "answer1"} card_type = self.card_type_with_id("1") self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"], check_for_duplicates=False) assert len(self.database().duplicates_for_fact(fact, card_type)) == 1 fact_data = {"f": "question", "b": "answer1"} card_type = self.card_type_with_id("2") self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"], check_for_duplicates=False) assert len(self.database().duplicates_for_fact(fact, card_type)) == 1 def test_card_types_in_use(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) assert len(self.database().card_types_in_use()) == 1 card_type = self.card_type_with_id("2") self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) assert len(self.database().card_types_in_use()) == 2 def test_vacuum(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) for count in range(6): self.database().save() self.database().unload() self.database().load(self.config()["last_database"]) def test_schedule_on_same_day(self): fact_data = {"f": "question", "b": "answer"} card_type_2 = self.card_type_with_id("2") card_1, card_2 = self.controller().create_new_cards(fact_data, card_type_2, grade=-1, tag_names=["default"]) fact_data = {"f": "question2", "b": "answer2"} card_3, card_4 = self.controller().create_new_cards(fact_data, card_type_2, grade=-1, tag_names=["default"]) self.review_controller().show_new_question() assert card_1 == self.review_controller().card assert self.database().sister_card_count_scheduled_between(card_1, 0, DAY) == 0 self.review_controller().grade_answer(2) card_1 = self.database().card(card_1._id, is_id_internal=True) card_3.next_rep = card_1.next_rep card_3.grade = 2 self.database().update_card(card_3) assert self.database().sister_card_count_scheduled_between(card_2, card_1.next_rep, card_1.next_rep+DAY) == 1 assert self.database().sister_card_count_scheduled_between(card_3, card_1.next_rep, card_1.next_rep+DAY) == 0 assert self.database().sister_card_count_scheduled_between(card_1, card_1.next_rep, card_1.next_rep+DAY) == 0 def test_purge_backups(self): backup_dir = os.path.join(self.config().data_dir, "backups") for count in range(15): f = file(os.path.join(backup_dir, "default-%d.db" % count), "w") self.mnemosyne.finalise() backups = [f for f in os.listdir(backup_dir)] assert len(backups) == 10 assert "default-0.db" not in backups self.restart() def test_link_inverse_cards(self): fact_data = {"f": "question", "b": "answer"} card_type_1 = self.card_type_with_id("1") card_type_2 = self.card_type_with_id("2") card_1 = self.controller().create_new_cards(fact_data, card_type_1, grade=-1, tag_names=["tag_1"])[0] fact_data = {"f": "answer", "b": "question"} card_2 = self.controller().create_new_cards(fact_data, card_type_1, grade=-1, tag_names=["tag_1"])[0] self.database().save() self.database().link_inverse_cards() card_1 = self.database().card(card_1._id, is_id_internal=True) assert card_1.card_type == card_type_2 assert card_1.fact_view == card_type_2.fact_views[0] card_1.fact['f'] = "Question" self.database().update_fact(card_1.fact) card_2 = self.database().card(card_2._id, is_id_internal=True) assert card_2.card_type == card_type_2 assert card_2.fact_view == card_type_2.fact_views[1] assert "Question" in card_2.answer() def test_link_inverse_cards_2(self): fact_data = {"f": "question", "b": "answer"} card_type_1 = self.card_type_with_id("1") card_type_2 = self.card_type_with_id("2") card_1 = self.controller().create_new_cards(fact_data, card_type_1, grade=-1, tag_names=["tag_1"])[0] fact_data = {"f": "answer", "b": "question"} card_2 = self.controller().create_new_cards(fact_data, card_type_1, grade=-1, tag_names=["tag_2"])[0] self.database().save() self.database().link_inverse_cards() card_1 = self.database().card(card_1._id, is_id_internal=True) assert card_1.card_type == card_type_1 assert card_1.fact_view == card_type_1.fact_views[0] card_1.fact['f'] = "Question" self.database().update_fact(card_1.fact) card_2 = self.database().card(card_2._id, is_id_internal=True) assert card_2.card_type == card_type_1 assert card_2.fact_view == card_type_1.fact_views[0] assert "Question" not in card_2.answer() def test_link_inverse_cards_3(self): fact_data = {"b": "question", "f": "answer"} card_type_1 = self.card_type_with_id("1") card_type_2 = self.card_type_with_id("2") card_1 = self.controller().create_new_cards(fact_data, card_type_2, grade=-1, tag_names=["tag_1"])[0] fact_data = {"f": "question", "b": "answer"} card_2 = self.controller().create_new_cards(fact_data, card_type_2, grade=-1, tag_names=["tag_2"])[0] self.database().save() self.database().link_inverse_cards() card_1 = self.database().card(card_1._id, is_id_internal=True) card_1.fact['f'] = "Question" self.database().update_fact(card_1.fact) card_2 = self.database().card(card_2._id, is_id_internal=True) assert "Question" not in card_2.answer() def test_link_inverse_cards_4(self): fact_data = {"f": "sukuun", "b": "zien"} card_type_1 = self.card_type_with_id("1") card_type_2 = self.card_type_with_id("2") card_1 = self.controller().create_new_cards(fact_data, card_type_1, grade=-1, tag_names=["tag_1"])[0] fact_data = {"f": "no sukuun", "b": "zien"} card_2 = self.controller().create_new_cards(fact_data, card_type_1, grade=-1, tag_names=["tag_1"])[0] fact_data = {"f": "zien", "b": "sukuun"} card_3 = self.controller().create_new_cards(fact_data, card_type_1, grade=-1, tag_names=["tag_1"])[0] self.database().save() self.database().link_inverse_cards() card_1 = self.database().card(card_1._id, is_id_internal=True) assert card_1.card_type == card_type_2 card_2 = self.database().card(card_2._id, is_id_internal=True) assert card_2.card_type == card_type_1 card_3 = self.database().card(card_3._id, is_id_internal=True) assert card_3.card_type == card_type_2 def test_link_inverse_cards_5(self): fact_data = {"f": "a", "b": "a"} card_type_1 = self.card_type_with_id("1") card_type_2 = self.card_type_with_id("2") card_1 = self.controller().create_new_cards(fact_data, card_type_1, grade=-1, tag_names=["tag_1"])[0] self.database().save() self.database().link_inverse_cards() card_1 = self.database().card(card_1._id, is_id_internal=True) assert card_1.card_type == card_type_1 def test_add_tag_to_card(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] assert self.database().con.execute("select count() from log where event_type=?", (EventTypes.EDITED_CARD, )).fetchone()[0] == 0 tag = self.database().get_or_create_tag_with_name("new") self.database().add_tag_to_cards_with_internal_ids(tag, [card._id]) new_card = self.database().card(card._id, is_id_internal=True) assert len(new_card.tags) == 2 assert self.database().con.execute("select count() from log where event_type=?", (EventTypes.EDITED_CARD, )).fetchone()[0] == 1 sql_res = self.database().con.execute(\ "select event_type, object_id from log where _id=17").fetchone() assert sql_res[0] == EventTypes.EDITED_CARD assert sql_res[1] == card.id self.database().add_tag_to_cards_with_internal_ids(tag, [card._id]) assert self.database().con.execute("select count() from tags_for_card").fetchone()[0] == 2 assert len(new_card.tags) == 2 assert self.database().con.execute("select count() from log where event_type=?", (EventTypes.EDITED_CARD, )).fetchone()[0] == 2 def test_add_tag_to_untagged_card(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=[])[0] assert self.database().con.execute("select count() from log where event_type=?", (EventTypes.EDITED_CARD, )).fetchone()[0] == 0 tag = self.database().get_or_create_tag_with_name("new") self.database().add_tag_to_cards_with_internal_ids(tag, [card._id]) new_card = self.database().card(card._id, is_id_internal=True) assert len(new_card.tags) == 1 assert self.database().con.execute("select count() from log where event_type=?", (EventTypes.EDITED_CARD, )).fetchone()[0] == 1 self.database().add_tag_to_cards_with_internal_ids(tag, [card._id]) assert self.database().con.execute("select count() from tags_for_card").fetchone()[0] == 1 assert len(new_card.tags) == 1 assert self.database().con.execute("select count() from log where event_type=?", (EventTypes.EDITED_CARD, )).fetchone()[0] == 2 def test_remove_tag_from_card(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["a", "b"])[0] assert self.database().con.execute("select count() from log where event_type=?", (EventTypes.EDITED_CARD, )).fetchone()[0] == 0 tag = self.database().get_or_create_tag_with_name("a") self.database().remove_tag_from_cards_with_internal_ids(tag, [card._id]) new_card = self.database().card(card._id, is_id_internal=True) assert len(new_card.tags) == 1 assert self.database().con.execute("select count() from log where event_type=?", (EventTypes.EDITED_CARD, )).fetchone()[0] == 1 sql_res = self.database().con.execute(\ "select event_type, object_id from log where _id=19").fetchone() assert sql_res[0] == EventTypes.EDITED_CARD assert sql_res[1] == card.id def test_remove_tag_from_card_2(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["a"])[0] assert self.database().con.execute("select count() from log where event_type=?", (EventTypes.EDITED_CARD, )).fetchone()[0] == 0 tag = self.database().get_or_create_tag_with_name("a") assert self.database().con.execute("select count() from tags").fetchone()[0] == 2 self.database().remove_tag_from_cards_with_internal_ids(tag, [card._id]) assert self.database().con.execute("select count() from tags").fetchone()[0] == 1 new_card = self.database().card(card._id, is_id_internal=True) assert len(new_card.tags) == 1 assert list(new_card.tags)[0].name == "__UNTAGGED__" assert self.database().con.execute("select count() from tags_for_card where _tag_id=1 and _card_id=?", (card._id, )).fetchone()[0] == 1 assert self.database().con.execute("select count() from log where event_type=?", (EventTypes.EDITED_CARD, )).fetchone()[0] == 1 sql_res = self.database().con.execute(\ "select event_type, object_id from log where _id=17").fetchone() assert sql_res[0] == EventTypes.EDITED_CARD assert sql_res[1] == card.id def test_remove_tag_from_card_3(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=[])[0] assert self.database().con.execute("select count() from log where event_type=?", (EventTypes.EDITED_CARD, )).fetchone()[0] == 0 tag = self.database().get_or_create_tag_with_name("a") self.database().remove_tag_from_cards_with_internal_ids(tag, [card._id]) new_card = self.database().card(card._id, is_id_internal=True) assert len(new_card.tags) == 1 assert list(new_card.tags)[0].name == "__UNTAGGED__" assert self.database().con.execute("select count() from tags_for_card where _tag_id=1 and _card_id=?", (card._id, )).fetchone()[0] == 1 assert self.database().con.execute("select count() from log where event_type=?", (EventTypes.EDITED_CARD, )).fetchone()[0] == 1 sql_res = self.database().con.execute(\ "select event_type, object_id from log where _id=17").fetchone() assert sql_res[0] == EventTypes.EDITED_CARD assert sql_res[1] == card.id def test_tags_for_cards(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["a", "b"])[0] fact_data = {"f": "question2", "b": "answer"} card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["a"])[0] fact_data = {"f": "question3", "b": "answer"} card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["c"])[0] for tag in self.database().tags_from_cards_with_internal_ids([1, 2]): assert tag._id in [2, 3] for tag in self.database().tags_from_cards_with_internal_ids([2]): assert tag._id in [2] for tag in self.database().tags_from_cards_with_internal_ids([2, 3]): assert tag._id in [2, 4] def test_tag_all_duplicates(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["a", "b"])[0] self.database().tag_all_duplicates() card_1 = self.database().card(card_1._id, is_id_internal=True) assert "DUPLICATE" not in card_1.tag_string() global answer answer = 1 # Add anyway card_2 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["a", "b"])[0] fact_data = {"f": "question2", "b": "answer"} card_3 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["a", "b"])[0] answer = None self.database().tag_all_duplicates() card_1 = self.database().card(card_1._id, is_id_internal=True) card_2 = self.database().card(card_2._id, is_id_internal=True) card_3 = self.database().card(card_3._id, is_id_internal=True) assert "DUPLICATE" in card_1.tag_string() assert "DUPLICATE" in card_2.tag_string() assert "DUPLICATE" not in card_3.tag_string() def test_is_accessible(self): # from threading import Thread # import time # class MyThread(Thread): # def __init__(self, mnemosyne): # Thread.__init__(self) # self.mnemosyne = mnemosyne # def run(self): # assert self.mnemosyne.database().is_accessible() == True # self.mnemosyne.database().scheduled_count(0) # time.sleep(0.2) # self.mnemosyne.database().release_connection() assert self.database().is_accessible() == True # self.database().release_connection() # thread = MyThread(self) # thread.start() # time.sleep(0.1) # assert self.database().is_accessible() == False # time.sleep(0.3) def test_upgrade_2(self): shutil.copy(os.path.join("tests", "files", "non_unique_card_ids.db"), os.path.join("dot_test", "tmp.db")) self.database().load(os.path.join("tmp.db")) card_1 = self.database().card(1, is_id_internal=True) card_2 = self.database().card(2, is_id_internal=True) assert card_1.id == "id" assert card_2.id == "id.1"
class TestDatabase(MnemosyneTest): def setup(self): self.initialise_data_dir() path = os.path.join(os.getcwd(), "..", "mnemosyne", "libmnemosyne", "renderers") if path not in sys.path: sys.path.append(path) self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.gui_translators.gettext_gui_translator", "GetTextGuiTranslator")) self.mnemosyne.components.append(\ ("test_database", "Widget")) self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \ [("mnemosyne_test", "TestReviewWidget")] self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.review_controller().reset() def test_release(self): self.database().release_connection() self.database().release_connection() self.database().display_name() self.database().abandon() self.database().new("default.mem") def test_tags(self): tag = Tag("test") self.database().add_tag(tag) assert len(self.database().tags()) == 2 assert self.database().tags()[0].name == "test" tag.name = "test2" self.database().update_tag(tag) assert len(self.database().tags()) == 2 assert self.database().tags()[0].name == "test2" def test_tag_order(self): tag = Tag("a") self.database().add_tag(tag) tag = Tag("1. a") self.database().add_tag(tag) assert [tag.name for tag in self.database().tags() ] == ["1. a", "a", "__UNTAGGED__"] def test_new_cards(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") old_card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] assert len([self.database().cards()]) == 1 old_fact = old_card.fact self.database().unload() self.database().load(self.config()["last_database"]) assert self.database().fact_count() == 1 card = self.database().card(old_card._id, is_id_internal=True) fact = card.fact assert fact.data["f"] == "question" assert fact.data["b"] == "answer" assert fact.id == old_fact.id assert [tag.name for tag in card.tags] == \ [tag.name for tag in old_card.tags] assert card.fact == old_card.fact assert card.fact_view == old_card.fact_view assert card.id == old_card.id assert card.creation_time == old_card.creation_time assert card.modification_time == old_card.modification_time assert card.grade == old_card.grade assert card.easiness == old_card.easiness assert card.acq_reps == old_card.acq_reps assert card.ret_reps == old_card.ret_reps assert card.lapses == old_card.lapses assert card.acq_reps_since_lapse == old_card.acq_reps_since_lapse assert card.last_rep == old_card.last_rep assert card.next_rep == old_card.next_rep assert card.extra_data == old_card.extra_data assert card.scheduler_data == old_card.scheduler_data assert card.active == old_card.active # Modify cards card.grade = -1 card.easiness = -2 card.acq_reps = -3 card.ret_reps = -4 card.lapses = -5 card.acq_reps_since_lapse = -6 card.last_rep = -7 card.next_rep = -8 card.extra_data = "extra" card.scheduler_data = 1 card.in_view = False self.database().update_card(card) new_card = list(self.database().cards_from_fact(fact))[0] assert card.grade == -1 assert card.easiness == -2 assert card.acq_reps == -3 assert card.ret_reps == -4 assert card.lapses == -5 assert card.acq_reps_since_lapse == -6 assert card.last_rep == -7 assert card.next_rep == -8 assert card.extra_data == "extra" assert card.scheduler_data == 1 def test_update_tag(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact self.controller().edit_card_and_sisters(card, fact_data, card_type, new_tag_names=["default1"], correspondence=[]) new_card = self.database().card(card._id, is_id_internal=True) tag_names = [tag.name for tag in new_card.tags] assert len(tag_names) == 1 assert "default1" in tag_names assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.EDITED_CARD, )).fetchone()[0] == 1 def test_empty_argument(self): assert self.database().tags_from_cards_with_internal_ids([]) == [] def test_clones(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact self.controller().clone_card_type(card_type, "my_1") new_card_type = self.card_type_with_id("1::my_1") self.controller().edit_card_and_sisters(card, fact_data, new_card_type, new_tag_names=["default2"], correspondence=[]) self.mnemosyne.finalise() self.restart() assert self.database().fact_count() == 1 _card_id, _fact_id = list(self.database().cards_unseen())[0] fact = self.database().fact(_fact_id, is_id_internal=True) card_type = self.card_type_with_id("1::my_1") assert card_type.id == "1::my_1" assert card_type == card_type def test_plugin_and_clones(self): for plugin in self.plugins(): component = plugin.components[0] if component.component_type == "card_type" and component.id == "4": plugin.activate() fact_data = {"loc": "location", "blank": "blank", "marked": "marked"} card_type = self.card_type_with_id("4") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] assert self.database().fact_count() == 1 fact = card.fact self.controller().clone_card_type(card_type, "my_4") new_card_type = self.card_type_with_id("4::my_4") self.controller().edit_card_and_sisters(card, fact_data, new_card_type, new_tag_names=["default2"], correspondence=[]) assert self.database().fact_count() == 1 self.mnemosyne.finalise() self.restart() assert self.database().fact_count() == 1 _card_id, _fact_id = list(self.database().cards_unseen())[0] fact = self.database().fact(_fact_id, is_id_internal=True) card_type = self.card_type_with_id("4") card_type = self.card_type_with_id("4::my_4") assert card_type.id == "4::my_4" assert card_type == card_type card = self.database().cards_from_fact(fact)[0] card.question() def off_new_database_overriding_existing_one(self): # causes permission problems under windows. fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) self.database().unload() self.database().new(self.config()["last_database"]) assert self.database().fact_count() == 0 def test_missing_plugin(self): for plugin in self.plugins(): component = plugin.components[0] if component.component_type == "card_type" and component.id == "4": plugin.activate() fact_data = {"loc": "location", "blank": "blank", "marked": "marked"} card_type = self.card_type_with_id("4") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact self.controller().clone_card_type(card_type, "my_4") new_card_type = self.card_type_with_id("4::my_4") self.controller().edit_card_and_sisters(card, fact_data, new_card_type, new_tag_names=["default2"], correspondence=[]) self.mnemosyne.finalise() self.restart() # Artificially remove plugin. self.database().unload() for plugin in self.plugins(): component = plugin.components[0] if component.component_type == "card_type" and component.id == "4": plugin.deactivate() self.mnemosyne.component_manager.unregister(plugin) try: self.database().load(self.config()["last_database"]) 1 / 0 except Exception as e: assert type(e) == RuntimeError def test_delete_fact(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact self.controller().delete_facts_and_their_cards([fact]) assert self.database().fact_count() == 0 assert self.database().card_count() == 0 assert len(self.database().tags()) == 1 def infinity(self): return 1 / 0 def test_corrupt_plugin(self): for plugin in self.plugins(): component = plugin.components[0] if component.component_type == "card_type" and component.id == "4": plugin.activate() fact_data = {"loc": "location", "blank": "blank", "marked": "marked"} card_type = self.card_type_with_id("4") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact self.controller().clone_card_type(card_type, "my_4") new_card_type = self.card_type_with_id("4::my_4") self.controller().edit_card_and_sisters(card, fact_data, new_card_type, new_tag_names=["default2"], correspondence=[]) self.mnemosyne.finalise() self.restart() self.database().unload() # Artificially mutilate plugin. for plugin in self.plugins(): component = plugin.components[0] if component.component_type == "card_type" and component.id == "4": plugin.deactivate() plugin.activate = self.infinity break try: self.database().load(self.config()["last_database"]) 1 / 0 except Exception as e: assert type(e) == RuntimeError def test_save_as(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) new_name = self.config()["last_database"] + ".bak" assert self.database().save(self.config()["last_database"] + ".bak") != -1 assert self.config()["last_database"] == new_name assert new_name != expand_path(new_name, self.config().data_dir) def test_duplicates_for_fact(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards( fact_data, card_type, grade=-1, tag_names=["default"], check_for_duplicates=False)[0] fact = card.fact fact_data = {"f": "question_", "b": "answer_"} card_type = self.card_type_with_id("1") self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"], check_for_duplicates=False) assert len(self.database().duplicates_for_fact(fact, card_type)) == 0 fact_data = {"f": "question1", "b": "answer"} card_type = self.card_type_with_id("1") self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"], check_for_duplicates=False) assert len(self.database().duplicates_for_fact(fact, card_type)) == 0 fact_data = {"f": "question", "b": "answer1"} card_type = self.card_type_with_id("1") self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"], check_for_duplicates=False) assert len(self.database().duplicates_for_fact(fact, card_type)) == 1 fact_data = {"f": "question", "b": "answer1"} card_type = self.card_type_with_id("2") self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"], check_for_duplicates=False) assert len(self.database().duplicates_for_fact(fact, card_type)) == 1 def test_card_types_in_use(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) assert len(self.database().card_types_in_use()) == 1 card_type = self.card_type_with_id("2") self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) assert len(self.database().card_types_in_use()) == 2 def test_vacuum(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) for count in range(6): self.database().save() self.database().unload() self.database().load(self.config()["last_database"]) def test_schedule_on_same_day(self): fact_data = {"f": "question", "b": "answer"} card_type_2 = self.card_type_with_id("2") card_1, card_2 = self.controller().create_new_cards( fact_data, card_type_2, grade=-1, tag_names=["default"]) fact_data = {"f": "question2", "b": "answer2"} card_3, card_4 = self.controller().create_new_cards( fact_data, card_type_2, grade=-1, tag_names=["default"]) self.review_controller().show_new_question() assert card_1 == self.review_controller().card assert self.database().sister_card_count_scheduled_between( card_1, 0, DAY) == 0 self.review_controller().grade_answer(2) card_1 = self.database().card(card_1._id, is_id_internal=True) card_3.next_rep = card_1.next_rep card_3.grade = 2 self.database().update_card(card_3) assert self.database().sister_card_count_scheduled_between( card_2, card_1.next_rep, card_1.next_rep + DAY) == 1 assert self.database().sister_card_count_scheduled_between( card_3, card_1.next_rep, card_1.next_rep + DAY) == 0 assert self.database().sister_card_count_scheduled_between( card_1, card_1.next_rep, card_1.next_rep + DAY) == 0 def test_purge_backups(self): backup_dir = os.path.join(self.config().data_dir, "backups") for count in range(15): f = open(os.path.join(backup_dir, "default-%d.db" % count), "w") self.mnemosyne.finalise() backups = [f for f in os.listdir(backup_dir)] assert len(backups) == 10 assert "default-0.db" not in backups self.restart() def test_link_inverse_cards(self): fact_data = {"f": "question", "b": "answer"} card_type_1 = self.card_type_with_id("1") card_type_2 = self.card_type_with_id("2") card_1 = self.controller().create_new_cards(fact_data, card_type_1, grade=-1, tag_names=["tag_1"])[0] fact_data = {"f": "answer", "b": "question"} card_2 = self.controller().create_new_cards(fact_data, card_type_1, grade=-1, tag_names=["tag_1"])[0] self.database().save() self.database().link_inverse_cards() card_1 = self.database().card(card_1._id, is_id_internal=True) assert card_1.card_type == card_type_2 assert card_1.fact_view == card_type_2.fact_views[0] card_1.fact['f'] = "Question" self.database().update_fact(card_1.fact) card_2 = self.database().card(card_2._id, is_id_internal=True) assert card_2.card_type == card_type_2 assert card_2.fact_view == card_type_2.fact_views[1] assert "Question" in card_2.answer() def test_link_inverse_cards_2(self): fact_data = {"f": "question", "b": "answer"} card_type_1 = self.card_type_with_id("1") card_type_2 = self.card_type_with_id("2") card_1 = self.controller().create_new_cards(fact_data, card_type_1, grade=-1, tag_names=["tag_1"])[0] fact_data = {"f": "answer", "b": "question"} card_2 = self.controller().create_new_cards(fact_data, card_type_1, grade=-1, tag_names=["tag_2"])[0] self.database().save() self.database().link_inverse_cards() card_1 = self.database().card(card_1._id, is_id_internal=True) assert card_1.card_type == card_type_1 assert card_1.fact_view == card_type_1.fact_views[0] card_1.fact['f'] = "Question" self.database().update_fact(card_1.fact) card_2 = self.database().card(card_2._id, is_id_internal=True) assert card_2.card_type == card_type_1 assert card_2.fact_view == card_type_1.fact_views[0] assert "Question" not in card_2.answer() def test_link_inverse_cards_3(self): fact_data = {"b": "question", "f": "answer"} card_type_1 = self.card_type_with_id("1") card_type_2 = self.card_type_with_id("2") card_1 = self.controller().create_new_cards(fact_data, card_type_2, grade=-1, tag_names=["tag_1"])[0] fact_data = {"f": "question", "b": "answer"} card_2 = self.controller().create_new_cards(fact_data, card_type_2, grade=-1, tag_names=["tag_2"])[0] self.database().save() self.database().link_inverse_cards() card_1 = self.database().card(card_1._id, is_id_internal=True) card_1.fact['f'] = "Question" self.database().update_fact(card_1.fact) card_2 = self.database().card(card_2._id, is_id_internal=True) assert "Question" not in card_2.answer() def test_link_inverse_cards_4(self): fact_data = {"f": "sukuun", "b": "zien"} card_type_1 = self.card_type_with_id("1") card_type_2 = self.card_type_with_id("2") card_1 = self.controller().create_new_cards(fact_data, card_type_1, grade=-1, tag_names=["tag_1"])[0] fact_data = {"f": "no sukuun", "b": "zien"} card_2 = self.controller().create_new_cards(fact_data, card_type_1, grade=-1, tag_names=["tag_1"])[0] fact_data = {"f": "zien", "b": "sukuun"} card_3 = self.controller().create_new_cards(fact_data, card_type_1, grade=-1, tag_names=["tag_1"])[0] self.database().save() self.database().link_inverse_cards() card_1 = self.database().card(card_1._id, is_id_internal=True) assert card_1.card_type == card_type_2 card_2 = self.database().card(card_2._id, is_id_internal=True) assert card_2.card_type == card_type_1 card_3 = self.database().card(card_3._id, is_id_internal=True) assert card_3.card_type == card_type_2 def test_link_inverse_cards_5(self): fact_data = {"f": "a", "b": "a"} card_type_1 = self.card_type_with_id("1") card_type_2 = self.card_type_with_id("2") card_1 = self.controller().create_new_cards(fact_data, card_type_1, grade=-1, tag_names=["tag_1"])[0] self.database().save() self.database().link_inverse_cards() card_1 = self.database().card(card_1._id, is_id_internal=True) assert card_1.card_type == card_type_1 def test_add_tag_to_card(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] assert self.database().con.execute( "select count() from log where event_type=?", (EventTypes.EDITED_CARD, )).fetchone()[0] == 0 tag = self.database().get_or_create_tag_with_name("new") self.database().add_tag_to_cards_with_internal_ids(tag, [card._id]) new_card = self.database().card(card._id, is_id_internal=True) assert len(new_card.tags) == 2 assert self.database().con.execute( "select count() from log where event_type=?", (EventTypes.EDITED_CARD, )).fetchone()[0] == 1 sql_res = self.database().con.execute(\ "select event_type, object_id from log where _id=17").fetchone() assert sql_res[0] == EventTypes.EDITED_CARD assert sql_res[1] == card.id self.database().add_tag_to_cards_with_internal_ids(tag, [card._id]) assert self.database().con.execute( "select count() from tags_for_card").fetchone()[0] == 2 assert len(new_card.tags) == 2 assert self.database().con.execute( "select count() from log where event_type=?", (EventTypes.EDITED_CARD, )).fetchone()[0] == 2 def test_add_tag_to_untagged_card(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=[])[0] assert self.database().con.execute( "select count() from log where event_type=?", (EventTypes.EDITED_CARD, )).fetchone()[0] == 0 tag = self.database().get_or_create_tag_with_name("new") self.database().add_tag_to_cards_with_internal_ids(tag, [card._id]) new_card = self.database().card(card._id, is_id_internal=True) assert len(new_card.tags) == 1 assert self.database().con.execute( "select count() from log where event_type=?", (EventTypes.EDITED_CARD, )).fetchone()[0] == 1 self.database().add_tag_to_cards_with_internal_ids(tag, [card._id]) assert self.database().con.execute( "select count() from tags_for_card").fetchone()[0] == 1 assert len(new_card.tags) == 1 assert self.database().con.execute( "select count() from log where event_type=?", (EventTypes.EDITED_CARD, )).fetchone()[0] == 2 def test_remove_tag_from_card(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["a", "b"])[0] assert self.database().con.execute( "select count() from log where event_type=?", (EventTypes.EDITED_CARD, )).fetchone()[0] == 0 tag = self.database().get_or_create_tag_with_name("a") self.database().remove_tag_from_cards_with_internal_ids( tag, [card._id]) new_card = self.database().card(card._id, is_id_internal=True) assert len(new_card.tags) == 1 assert self.database().con.execute( "select count() from log where event_type=?", (EventTypes.EDITED_CARD, )).fetchone()[0] == 1 sql_res = self.database().con.execute(\ "select event_type, object_id from log where _id=19").fetchone() assert sql_res[0] == EventTypes.EDITED_CARD assert sql_res[1] == card.id def test_remove_tag_from_card_2(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["a"])[0] assert self.database().con.execute( "select count() from log where event_type=?", (EventTypes.EDITED_CARD, )).fetchone()[0] == 0 tag = self.database().get_or_create_tag_with_name("a") assert self.database().con.execute( "select count() from tags").fetchone()[0] == 2 self.database().remove_tag_from_cards_with_internal_ids( tag, [card._id]) assert self.database().con.execute( "select count() from tags").fetchone()[0] == 1 new_card = self.database().card(card._id, is_id_internal=True) assert len(new_card.tags) == 1 assert list(new_card.tags)[0].name == "__UNTAGGED__" assert self.database().con.execute( "select count() from tags_for_card where _tag_id=1 and _card_id=?", (card._id, )).fetchone()[0] == 1 assert self.database().con.execute( "select count() from log where event_type=?", (EventTypes.EDITED_CARD, )).fetchone()[0] == 1 sql_res = self.database().con.execute(\ "select event_type, object_id from log where _id=17").fetchone() assert sql_res[0] == EventTypes.EDITED_CARD assert sql_res[1] == card.id def test_remove_tag_from_card_3(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=[])[0] assert self.database().con.execute( "select count() from log where event_type=?", (EventTypes.EDITED_CARD, )).fetchone()[0] == 0 tag = self.database().get_or_create_tag_with_name("a") self.database().remove_tag_from_cards_with_internal_ids( tag, [card._id]) new_card = self.database().card(card._id, is_id_internal=True) assert len(new_card.tags) == 1 assert list(new_card.tags)[0].name == "__UNTAGGED__" assert self.database().con.execute( "select count() from tags_for_card where _tag_id=1 and _card_id=?", (card._id, )).fetchone()[0] == 1 assert self.database().con.execute( "select count() from log where event_type=?", (EventTypes.EDITED_CARD, )).fetchone()[0] == 1 sql_res = self.database().con.execute(\ "select event_type, object_id from log where _id=17").fetchone() assert sql_res[0] == EventTypes.EDITED_CARD assert sql_res[1] == card.id def test_tags_for_cards(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["a", "b"])[0] card__id_1 = card._id fact_data = {"f": "question2", "b": "answer"} card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["a"])[0] card__id_2 = card._id fact_data = {"f": "question3", "b": "answer"} card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["c"])[0] card__id_3 = card._id for tag in self.database().tags_from_cards_with_internal_ids( [card__id_1, card__id_2]): assert tag.name in ["a", "b"] for tag in self.database().tags_from_cards_with_internal_ids( [card__id_2]): assert tag.name in ["a"] for tag in self.database().tags_from_cards_with_internal_ids( [card__id_2, card__id_3]): assert tag.name in ["a", "c"] def test_tag_all_duplicates(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["a", "b"])[0] self.database().tag_all_duplicates() card_1 = self.database().card(card_1._id, is_id_internal=True) assert "DUPLICATE" not in card_1.tag_string() global answer answer = 1 # Add anyway card_2 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["a", "b"])[0] fact_data = {"f": "question2", "b": "answer"} card_3 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["a", "b"])[0] answer = None self.database().tag_all_duplicates() card_1 = self.database().card(card_1._id, is_id_internal=True) card_2 = self.database().card(card_2._id, is_id_internal=True) card_3 = self.database().card(card_3._id, is_id_internal=True) assert "DUPLICATE" in card_1.tag_string() assert "DUPLICATE" in card_2.tag_string() assert "DUPLICATE" not in card_3.tag_string() def test_is_accessible(self): # from threading import Thread # import time # class MyThread(Thread): # def __init__(self, mnemosyne): # Thread.__init__(self) # self.mnemosyne = mnemosyne # def run(self): # assert self.mnemosyne.database().is_accessible() == True # self.mnemosyne.database().scheduled_count(0) # time.sleep(0.2) # self.mnemosyne.database().release_connection() assert self.database().is_accessible() == True # self.database().release_connection() # thread = MyThread(self) # thread.start() # time.sleep(0.1) # assert self.database().is_accessible() == False # time.sleep(0.3) def test_upgrade_2(self): shutil.copy(os.path.join("tests", "files", "non_unique_card_ids.db"), os.path.join("dot_test", "tmp.db")) self.database().load(os.path.join("tmp.db")) card_1 = self.database().card(1, is_id_internal=True) card_2 = self.database().card(2, is_id_internal=True) assert card_1.id == "id" assert card_2.id == "id.1" def test_known_recognition(self): card_type = self.card_type_with_id("3") self.controller().clone_card_type(card_type, "my_3") card_type = self.card_type_with_id("3::my_3") fact_data = { "f": "yes_1", "p_1": "pronunciation", "m_1": "translation" } self.controller().create_new_cards(fact_data, card_type, grade=5, tag_names=["default"]) fact_data = {"f": "no_1", "p_1": "pronunciation", "m_1": "translation"} self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) card_type = self.card_type_with_id("3") self.controller().clone_card_type(card_type, "my_3_bis") card_type = self.card_type_with_id("3::my_3_bis") fact_data = {"f": "no_2", "p_1": "pronunciation", "m_1": "translation"} self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) for plugin in self.plugins(): component = plugin.components[0] if component.component_type == "card_type" and component.id == "6": plugin.activate() card_type = self.card_type_with_id("6") fact_data = { "f": "yes_2", "p_1": "pronunciation", "m_1": "translation" } self.controller().create_new_cards(fact_data, card_type, grade=5, tag_names=["default"]) fact_data = {"f": "no_3", "p_1": "pronunciation", "m_1": "translation"} self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) assert self.database().\ known_recognition_questions_count_from_card_types_ids(["3::my_3"]) == 1 assert self.database().\ known_recognition_questions_count_from_card_types_ids(["3::my_3_bis"]) == 0 assert self.database().\ known_recognition_questions_count_from_card_types_ids(["6"]) == 1 assert self.database().\ known_recognition_questions_count_from_card_types_ids(\ ["6", "3::my_3", "3::my_3_bis"]) == 2 assert set((self.database().\ known_recognition_questions_from_card_types_ids(\ ["6", "3::my_3", "3::my_3_bis"]))) == set(["yes_1", "yes_2"]) def _start_and_end_timestamp(self): timestamp = time.time() - 0 - self.config()["day_starts_at"] * HOUR date_only = datetime.date.fromtimestamp(timestamp) # Local date. start_of_day = int(time.mktime(date_only.timetuple())) start_of_day += self.config()["day_starts_at"] * HOUR return start_of_day, start_of_day + DAY def test_has_already_warned(self): now = int(time.time()) start_of_day, end_of_day = self._start_and_end_timestamp() assert self.database().has_already_warned_today( start_of_day, start_of_day + DAY) == False self.database().log_warn_about_too_many_cards(now) assert self.database().has_already_warned_today( start_of_day, start_of_day + DAY) == True def test_fact_ids_forgotten_and_learned_today(self): start_of_day, end_of_day = self._start_and_end_timestamp() assert list(self.database().fact_ids_forgotten_and_learned_today( start_of_day, end_of_day)) == [] # create 5 cards with id 1..5 cards = self._create_n_test_cards(5) # forgot 5 cards (only log) last_timestamp = self._generate_n_forgotten_card_logs(5, cards) # learn 3 forgotten cards (only log) self._learn_n_forgotten_cards_logs(3, last_timestamp, cards) forgotten_and_learned = self.database( ).fact_ids_forgotten_and_learned_today(start_of_day, end_of_day) assert len([x for x in forgotten_and_learned]) == 3 def test_fact_ids_newly_learned_today(self): start_of_day, end_of_day = self._start_and_end_timestamp() cards = self._create_n_test_cards(15) new_fact_ids = [ _fact_ids for _fact_ids in self.database().fact_ids_newly_learned_today( start_of_day, end_of_day) ] assert len(new_fact_ids) == 0 self._learn_n_new_cards_logs(7, start_of_day, cards) new_fact_ids = [ _fact_ids for _fact_ids in self.database().fact_ids_newly_learned_today( start_of_day, end_of_day) ] assert len(new_fact_ids) == 7 def _create_n_test_cards(self, n): """a helper function to generate n cards """ cards = [] card_type = self.card_type_with_id("1") for i in range(n): fact_data = { "f": "foreign word %d" % i, "p_1": "pronunciation %d" % i, "m_1": "translation %d" % i } c = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) cards.append(c[0]) return cards def _generate_n_forgotten_card_logs(self, n, cards): """a helper function to generate n forgotten cards log entry """ start_of_day, end_of_day = self._start_and_end_timestamp() fake_timestamp = start_of_day + 300 for x in range(n): self.database().con.execute( """insert into log(event_type, timestamp, object_id, grade, ret_reps, lapses) values(?,?,?,?,?,?)""", (EventTypes.REPETITION, int(fake_timestamp), cards[x].id, 1, 1, 1)) fake_timestamp += 300 return fake_timestamp def _learn_n_forgotten_cards_logs(self, n, start_timestamp, cards): """a helper function to re-learn n forgotten cards log entry """ fake_timestamp = start_timestamp + 300 for x in range(n): self.database().con.execute( """insert into log(event_type, timestamp, object_id, grade, ret_reps, lapses) values(?,?,?,?,?,?)""", (EventTypes.REPETITION, int(fake_timestamp), cards[x].id, 2, 1, 1)) fake_timestamp += 300 def _learn_n_new_cards_logs(self, n, start_timestamp, cards): """a helper function to learn n new cards log entry """ fake_timestamp = start_timestamp + 300 for x in range(n): self.database().con.execute( """insert into log(event_type, timestamp, object_id, grade, ret_reps, lapses) values(?,?,?,?,?,?)""", (EventTypes.REPETITION, int(fake_timestamp), cards[x].id, 2, 0, 0)) fake_timestamp += 300
class TestMedia(MnemosyneTest): def restart(self): path = os.path.join(os.getcwd(), "..", "mnemosyne", "libmnemosyne", "renderers") if path not in sys.path: sys.path.append(path) self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_media", "Widget")) self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \ [("mnemosyne_test", "TestReviewWidget")] self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.review_controller().reset() def test_sound_1(self): global filename filename = "" self.controller().show_insert_sound_dialog("") def test_sound_2(self): global filename open("a.ogg", "w") filename = os.path.abspath("a.ogg") self.controller().show_insert_sound_dialog("") assert os.path.exists( os.path.join(self.database().media_dir(), "a.ogg")) filename = os.path.join(self.database().media_dir(), "a.ogg") self.controller().show_insert_sound_dialog("") assert os.path.exists( os.path.join(self.database().media_dir(), "a.ogg")) def test_sound_2_unicode(self): global filename open(chr(40960) + "a.ogg", "w") filename = os.path.abspath(chr(40960) + "a.ogg") self.controller().show_insert_sound_dialog("") assert os.path.exists( os.path.join(self.database().media_dir(), chr(40960) + "a.ogg")) filename = os.path.join(self.database().media_dir(), chr(40960) + "a.ogg") self.controller().show_insert_sound_dialog("") assert os.path.exists( os.path.join(self.database().media_dir(), chr(40960) + "a.ogg")) def test_sound_3(self): global filename open("a.ogg", "w") filename = os.path.abspath("a.ogg") self.controller().show_insert_sound_dialog("") assert os.path.exists( os.path.join(self.database().media_dir(), "a.ogg")) self.controller().show_insert_sound_dialog("") assert os.path.exists( os.path.join(self.database().media_dir(), "a_1_.ogg")) self.controller().show_insert_sound_dialog("") assert os.path.exists( os.path.join(self.database().media_dir(), "a_2_.ogg")) def test_img_1(self): global filename filename = "" self.controller().show_insert_img_dialog("") def test_img_2(self): global filename open("a.ogg", "w") filename = os.path.abspath("a.ogg") self.controller().show_insert_img_dialog("") assert os.path.exists( os.path.join(self.database().media_dir(), "a.ogg")) filename = os.path.join(self.database().media_dir(), "a.ogg") self.controller().show_insert_img_dialog("") assert os.path.exists( os.path.join(self.database().media_dir(), "a.ogg")) def test_media_subdir(self): global filename subdir = os.path.join(self.database().media_dir(), "subdir") os.mkdir(subdir) filename = os.path.join(subdir, "b.ogg") open(filename, "w") self.controller().show_insert_img_dialog("") assert os.path.exists( os.path.join(self.database().media_dir(), "subdir", "b.ogg")) def test_card(self): open("a.ogg", "w") full_path = os.path.abspath("a.ogg").replace("\\", "/") fact_data = {"f": "<img src=\"%s\">" % full_path, "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] full_path_in_media_dir = \ os.path.join(self.database().media_dir(), "a.ogg").replace("\\", "/") # Make sure we don't reuse existing objects. card = self.database().card(card._id, is_id_internal=True) assert os.path.exists(full_path_in_media_dir) assert full_path not in card.fact.data["f"] assert full_path_in_media_dir not in card.fact.data["f"] assert full_path not in card.question() assert full_path_in_media_dir in card.question() assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 1 def test_audio_start_stop(self): open("a.ogg", "w") full_path = os.path.abspath("a.ogg").replace("\\", "/") fact_data = { "f": "<audio src=\"%s\" start=\"1\" stop=\"3\">" % full_path, "b": "answer" } card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] full_path_in_media_dir = \ os.path.join(self.database().media_dir(), "a.ogg").replace("\\", "/") # Make sure we don't reuse existing objects. card = self.database().card(card._id, is_id_internal=True) assert os.path.exists(full_path_in_media_dir) assert full_path not in card.fact.data["f"] assert full_path_in_media_dir not in card.fact.data["f"] assert full_path.replace(" ", "%20") not in card.question() assert full_path_in_media_dir.replace(" ", "%20") in card.question() assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 1 def test_external_media(self): fact_data = { "f": "<img src=\"http://www.chine-nouvelle.com/jdd/public/ct/pinyinaudio/shu4.mp3\"", "b": "answer" } card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] assert "http" in card.question() assert "file" not in card.question() assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 0 def test_card_2(self): fact_data = { "f": "<img src=\"a.ogg>", # Missing closing " "b": "answer" } card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] # Make sure we don't reuse existing objects. card = self.database().card(card._id, is_id_internal=True) assert os.path.join(self.database().media_dir(), "a.ogg") \ not in card.question() def test_missing_media(self): fact_data = {"f": "<img src=\"missing.ogg\">", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] assert "src_missing" in card.question() def test_long_media(self): filename = 220 * "a" fact_data = {"f": "<img src=\"%s\">" % (filename, ), "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] def test_card_edit_none(self): open("a.ogg", "w") full_path = os.path.abspath("a.ogg") fact_data = {"f": "<img src=\"%s\">" % full_path, "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] full_path_in_media_dir = \ os.path.join(self.database().media_dir(), "a.ogg").replace("\\", "/") fact_data = {"f": "edited <img src=\"%s\">" % "a.ogg", "b": "answer"} self.controller().edit_card_and_sisters(card, fact_data, card_type, new_tag_names=["bla"], correspondence=None) # Make sure we don't reuse existing objects. card = self.database().card(card._id, is_id_internal=True) assert os.path.exists(full_path_in_media_dir) assert full_path not in card.fact.data["f"] assert full_path_in_media_dir not in card.fact.data["f"] assert full_path not in card.question() assert full_path_in_media_dir in card.question() assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 1 def test_card_edit_add(self): open("a.ogg", "w") full_path = os.path.abspath("a.ogg").replace("\\", "/") fact_data = {"f": "<img src=\"%s\">" % full_path, "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] # Make sure we don't reuse existing objects. card = self.database().card(card._id, is_id_internal=True) open("b.ogg", "w") full_path = os.path.abspath("b.ogg").replace("\\", "/") fact_data = {"f": "edited <img src=\"%s\"> <img src=\"%s\">" \ % ("a.ogg", full_path), "b": "answer"} self.controller().edit_card_and_sisters(card, fact_data, card_type, new_tag_names=["bla"], correspondence=None) card = self.database().card(card._id, is_id_internal=True) full_path_in_media_dir = \ os.path.join(self.database().media_dir(), "b.ogg").replace("\\", "/") assert os.path.exists(full_path_in_media_dir) assert full_path not in card.fact.data["f"] assert full_path_in_media_dir not in card.fact.data["f"] assert full_path not in card.question() assert full_path_in_media_dir in card.question() assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 2 def test_card_edit_delete(self): open("a.ogg", "w") full_path = os.path.abspath("a.ogg").replace("\\", "/") fact_data = {"f": "<img src=\"%s\">" % full_path, "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] # Make sure we don't reuse existing objects. card = self.database().card(card._id, is_id_internal=True) fact_data = {"f": "edited ", "b": "answer"} self.controller().edit_card_and_sisters(card, fact_data, card_type, new_tag_names=["bla"], correspondence=None) # Make sure we don't reuse existing objects. card = self.database().card(card._id, is_id_internal=True) full_path_in_media_dir = \ os.path.join(self.database().media_dir(), "a.ogg").replace("\\", "/") self.database().delete_unused_media_files( self.database().unused_media_files()) assert not os.path.exists(full_path_in_media_dir) assert full_path_in_media_dir not in card.question() assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.DELETED_MEDIA_FILE, )).fetchone()[0] == 1 def test_card_edit_delete_used_by_other(self): open("a.ogg", "w") full_path = os.path.abspath("a.ogg") fact_data = {"f": "<img src=\"%s\">" % full_path, "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] # Make sure we don't reuse existing objects. card = self.database().card(card._id, is_id_internal=True) fact_data = {"f": "2 <img src=\'%s\'>" % "a.ogg", "b": "answer"} self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact_data = {"f": "edited", "b": "answer"} self.controller().edit_card_and_sisters(card, fact_data, card_type, new_tag_names=["bla"], correspondence=None) # Make sure we don't reuse existing objects. card = self.database().card(card._id, is_id_internal=True) full_path_in_media_dir = os.path.join(self.database().media_dir(), "a.ogg") assert os.path.exists(full_path_in_media_dir) # Don't delete file. assert full_path_in_media_dir not in card.question() assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 1 def test_delete_fact(self): open("a.ogg", "w") full_path = os.path.abspath("a.ogg") fact_data = {"f": "<img src=\"%s\">" % full_path, "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] # Make sure we don't reuse existing objects. card = self.database().card(card._id, is_id_internal=True) self.controller().delete_facts_and_their_cards([card.fact]) self.database().delete_unused_media_files( self.database().unused_media_files()) full_path_in_media_dir = os.path.join(self.database().media_dir(), "a.ogg") assert not os.path.exists(full_path_in_media_dir) # Autodelete. assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 1 def test_delete_fact_used_by_other(self): open("a.ogg", "w") full_path = os.path.abspath("a.ogg") fact_data = {"f": "<img src=\"%s\">" % full_path, "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] # Make sure we don't reuse existing objects. card = self.database().card(card._id, is_id_internal=True) fact_data = {"f": "2 <img src=\"%s\">" % "a.ogg", "b": "answer"} self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.controller().delete_facts_and_their_cards([card.fact]) full_path_in_media_dir = os.path.join(self.database().media_dir(), "a.ogg") assert os.path.exists(full_path_in_media_dir) # Not deleted. assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 1 def test_unused(self): open(os.path.join(self.database().media_dir(), "a.ogg"), "w") os.mkdir(os.path.join(self.database().media_dir(), "sub")) open(os.path.join(self.database().media_dir(), "sub", "b.ogg"), "w") os.mkdir(os.path.join(self.database().media_dir(), "_keep")) open(os.path.join(self.database().media_dir(), "_keep", "b.ogg"), "w") open("c.ogg", "w") full_path = os.path.abspath("c.ogg") fact_data = {"f": "<img src=\"%s\">" % full_path, "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] assert os.path.exists( os.path.join(self.database().media_dir(), "a.ogg")) assert os.path.exists(os.path.join(self.database().media_dir(), "sub")) assert os.path.exists( os.path.join(self.database().media_dir(), "sub", "b.ogg")) assert os.path.exists( os.path.join(self.database().media_dir(), "_keep")) assert os.path.exists( os.path.join(self.database().media_dir(), "_keep", "b.ogg")) self.database().delete_unused_media_files( self.database().unused_media_files()) assert not os.path.exists( os.path.join(self.database().media_dir(), "a.ogg")) assert not os.path.exists( os.path.join(self.database().media_dir(), "sub")) assert not os.path.exists( os.path.join(self.database().media_dir(), "sub", "b.ogg")) assert os.path.exists( os.path.join(self.database().media_dir(), "c.ogg")) assert os.path.exists( os.path.join(self.database().media_dir(), "_keep")) assert os.path.exists( os.path.join(self.database().media_dir(), "_keep", "b.ogg")) def test_unused_latex(self): fact_data = {"f": "<latex>a</latex>", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] card.question() latex_dir = os.path.join(self.database().media_dir(), "_latex") assert os.path.exists(latex_dir) self.database().delete_unused_media_files( self.database().unused_media_files()) assert not os.path.exists(latex_dir) def test_database_not_in_datadir(self): assert "dot_test" in self.database().media_dir() self.database().new(os.path.abspath("outside.db")) assert self.database().media_dir() == os.path.join(\ os.path.dirname(os.path.abspath("outside.db")), "outside.db_media").replace("\\", "/") assert "dot_test" not in self.database().media_dir() def teardown(self): if os.path.exists("a.ogg"): os.remove("a.ogg") if os.path.exists("b.ogg"): os.remove("b.ogg") if os.path.exists("c.ogg"): os.remove("c.ogg") if os.path.exists(chr(40960) + "a.ogg"): os.remove(chr(40960) + "a.ogg") if os.path.exists("sub"): shutil.rmtree("sub") if os.path.exists("_keep"): shutil.rmtree("_keep") MnemosyneTest.teardown(self)
class TestConvertCards(MnemosyneTest): def setup(self): os.system("rm -fr dot_test") self.mnemosyne = Mnemosyne() self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_convert_cards", "Widget")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.review_widget", "ReviewWidget")) self.mnemosyne.initialise(os.path.abspath("dot_test")) self.review_controller().reset() def test_1_to_2(self): fact_data = {"q": "question", "a": "answer"} card_type = self.card_type_by_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.controller().file_save() fact = card.fact old_card = copy.copy(self.database().cards_from_fact(fact)[0]) new_fact_data = {"q": "question2", "a": "answer2"} new_card_type = self.card_type_by_id("2") self.controller().update_related_cards(fact, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=[]) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 new_card_1, new_card_2 = self.database().cards_from_fact(fact) assert new_card_1.fact.card_type.id == "2" assert new_card_2.fact.card_type.id == "2" if new_card_1.fact_view.id == "2::1": assert new_card_1 == old_card assert new_card_2 != old_card assert new_card_2.grade == -1 else: assert new_card_2 == old_card assert new_card_1 != old_card assert new_card_1.grade == -1 new_card_1.question() new_card_1.answer() new_card_2.question() new_card_2.answer() def test_2_to_1(self): fact_data = {"q": "question", "a": "answer"} card_type = self.card_type_by_id("2") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.controller().file_save() fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"q": "question2", "a": "answer2"} new_card_type = self.card_type_by_id("1") self.controller().update_related_cards(fact, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=[]) assert self.database().fact_count() == 1 assert self.database().card_count() == 1 new_card = self.database().cards_from_fact(fact)[0] assert new_card.fact.card_type.id == "1" if old_card_1.fact_view.id == "2::1": assert new_card == old_card_1 assert new_card != old_card_2 else: assert new_card == old_card_2 assert new_card != old_card_1 new_card.question() new_card.answer() def test_1_to_3_a(self): fact_data = {"q": "question", "a": "answer"} card_type = self.card_type_by_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.controller().file_save() fact = card.fact old_card = copy.copy(self.database().cards_from_fact(fact)[0]) new_fact_data = {"f": "foreign word", "p": "pronunciation", "t": "translation"} correspondence = {"q": "f", "a": "p"} new_card_type = self.card_type_by_id("3") self.controller().update_related_cards(fact, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 new_card_1, new_card_2 = self.database().cards_from_fact(fact) assert new_card_1.fact.card_type.id == "3" assert new_card_2.fact.card_type.id == "3" if new_card_1.fact_view.id == "3::1": assert new_card_1 == old_card assert new_card_2 != old_card else: assert new_card_2 == old_card assert new_card_1 != old_card new_card_1.question() new_card_1.answer() new_card_2.question() new_card_2.answer() def test_1_to_3_b(self): fact_data = {"q": "question", "a": "answer"} card_type = self.card_type_by_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.controller().file_save() fact = card.fact old_card = copy.copy(self.database().cards_from_fact(fact)[0]) new_fact_data = {"f": "foreign word", "p": "pronunciation", "t": "translation"} correspondence = {"q": "t", "a": "f"} new_card_type = self.card_type_by_id("3") self.controller().update_related_cards(fact, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 new_card_1, new_card_2 = self.database().cards_from_fact(fact) assert new_card_1.fact.card_type.id == "3" assert new_card_2.fact.card_type.id == "3" if new_card_1.fact_view.id == "3::2": assert new_card_1 == old_card assert new_card_2 != old_card else: assert new_card_2 == old_card assert new_card_1 != old_card new_card_1.question() new_card_1.answer() new_card_2.question() new_card_2.answer() def test_3_to_1_a(self): fact_data = {"f": "foreign word", "p": "pronunciation", "t": "translation"} card_type = self.card_type_by_id("3") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.controller().file_save() fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"q": "question", "a": "answer"} correspondence = {"f": "q", "t": "a"} new_card_type = self.card_type_by_id("1") self.controller().update_related_cards(fact, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 1 new_card = self.database().cards_from_fact(fact)[0] assert new_card.fact.card_type.id == "1" if old_card_1.fact_view.id == "3::1": assert new_card == old_card_1 assert new_card != old_card_2 else: assert new_card == old_card_2 assert new_card != old_card_1 new_card.question() new_card.answer() def test_3_to_1_b(self): fact_data = {"f": "foreign word", "p": "pronunciation", "t": "translation"} card_type = self.card_type_by_id("3") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.controller().file_save() fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"q": "question", "a": "answer"} correspondence = {"f": "a", "t": ";"} new_card_type = self.card_type_by_id("1") self.controller().update_related_cards(fact, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 1 new_card = self.database().cards_from_fact(fact)[0] assert new_card.fact.card_type.id == "1" if old_card_1.fact_view.id == "3::2": assert new_card == old_card_1 assert new_card != old_card_2 else: assert new_card == old_card_2 assert new_card != old_card_1 new_card.question() new_card.answer() def test_2_to_3_a(self): fact_data = {"q": "question", "a": "answer"} card_type = self.card_type_by_id("2") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.controller().file_save() fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"f": "foreign word", "p": "pronunciation", "t": "translation"} correspondence = {"q": "f", "a": "t"} new_card_type = self.card_type_by_id("3") self.controller().update_related_cards(fact, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 new_card_1, new_card_2 = self.database().cards_from_fact(fact) assert new_card_1.fact.card_type.id == "3" assert new_card_2.fact.card_type.id == "3" for old in [old_card_1, old_card_2]: for new in [new_card_1, new_card_2]: if old == new: assert old.fact_view.id.split("::")[1] == \ new.fact_view.id.split("::")[1] new_card_1.question() new_card_1.answer() new_card_2.question() new_card_2.answer() def test_2_to_3_b(self): fact_data = {"q": "question", "a": "answer"} card_type = self.card_type_by_id("2") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.controller().file_save() fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"f": "foreign word", "p": "pronunciation", "t": "translation"} correspondence = {"q": "t", "a": "f"} new_card_type = self.card_type_by_id("3") self.controller().update_related_cards(fact, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 new_card_1, new_card_2 = self.database().cards_from_fact(fact) assert new_card_1.fact.card_type.id == "3" assert new_card_2.fact.card_type.id == "3" for old in [old_card_1, old_card_2]: for new in [new_card_1, new_card_2]: if old == new: assert old.fact_view != new.fact_view new_card_1.question() new_card_1.answer() new_card_2.question() new_card_2.answer() def test_3_to_2_a(self): fact_data = {"f": "foreign word", "p": "pronunciation", "t": "translation"} card_type = self.card_type_by_id("3") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.controller().file_save() fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"q": "question", "a": "answer"} correspondence = {"f": "q", "t": "a"} new_card_type = self.card_type_by_id("2") self.controller().update_related_cards(fact, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 new_card_1, new_card_2 = self.database().cards_from_fact(fact) assert new_card_1.fact.card_type.id == "2" assert new_card_2.fact.card_type.id == "2" for old in [old_card_1, old_card_2]: for new in [new_card_1, new_card_2]: if old == new: assert old.fact_view.id.split("::")[1] == \ new.fact_view.id.split("::")[1] new_card_1.question() new_card_1.answer() new_card_2.question() new_card_2.answer() def test_3_to_2_b(self): fact_data = {"f": "foreign word", "p": "pronunciation", "t": "translation"} card_type = self.card_type_by_id("3") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.controller().file_save() fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"q": "question", "a": "answer"} correspondence = {"f": "a", "t": "q"} new_card_type = self.card_type_by_id("2") self.controller().update_related_cards(fact, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 new_card_1, new_card_2 = self.database().cards_from_fact(fact) assert new_card_1.fact.card_type.id == "2" assert new_card_2.fact.card_type.id == "2" for old in [old_card_1, old_card_2]: for new in [new_card_1, new_card_2]: if old == new: assert old.fact_view != new.fact_view new_card_1.question() new_card_1.answer() new_card_2.question() new_card_2.answer() def test_3_clone_to_1_a(self): fact_data = {"f": "foreign word", "p": "pronunciation", "t": "translation"} card_type = self.card_type_by_id("3") self.controller().clone_card_type(card_type, "my_3") card_type = self.card_type_by_id("3::my_3") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.controller().file_save() fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"q": "question", "a": "answer"} correspondence = {"f": "q", "t": "a"} new_card_type = self.card_type_by_id("1") self.controller().update_related_cards(fact, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 1 new_card = self.database().cards_from_fact(fact)[0] assert new_card.fact.card_type.id == "1" if old_card_1.fact_view.id == "3::1": assert new_card == old_card_1 assert new_card != old_card_2 else: assert new_card == old_card_2 assert new_card != old_card_1 new_card.question() new_card.answer() def test_3_to_1_clone_a(self): fact_data = {"f": "foreign word", "p": "pronunciation", "t": "translation"} card_type = self.card_type_by_id("3") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.controller().file_save() fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"q": "question", "a": "answer"} correspondence = {"f": "q", "t": "a"} new_card_type = self.card_type_by_id("1") self.controller().clone_card_type(new_card_type, "my_1") new_card_type = self.card_type_by_id("1::my_1") self.controller().update_related_cards(fact, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 1 new_card = self.database().cards_from_fact(fact)[0] assert new_card.fact.card_type.id == "1::my_1" assert new_card.fact.data["q"] == "question" assert new_card.fact.data["a"] == "answer" if old_card_1.fact_view.id == "3::1": assert new_card == old_card_1 assert new_card != old_card_2 else: assert new_card == old_card_2 assert new_card != old_card_1 new_card.question() new_card.answer() def test_3_clone_to_1_clone_a(self): fact_data = {"f": "foreign word", "p": "pronunciation", "t": "translation"} card_type = self.card_type_by_id("3") self.controller().clone_card_type(card_type, "my_3") card_type = self.card_type_by_id("3::my_3") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.controller().file_save() fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"q": "question", "a": "answer"} correspondence = {"f": "q", "t": "a"} new_card_type = self.card_type_by_id("1") self.controller().clone_card_type(new_card_type, "my_1") new_card_type = self.card_type_by_id("1::my_1") self.controller().update_related_cards(fact, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 1 new_card = self.database().cards_from_fact(fact)[0] assert new_card.fact.card_type.id == "1::my_1" if old_card_1.fact_view.id == "3::1": assert new_card == old_card_1 assert new_card != old_card_2 else: assert new_card == old_card_2 assert new_card != old_card_1 new_card.question() new_card.answer() def test_cloze_to_1(self): from mnemosyne.libmnemosyne.ui_components.statistics_widget import \ StatisticsWidget from mnemosyne.libmnemosyne.statistics_pages.schedule import Schedule class ScheduleWdgt(StatisticsWidget): used_for = Schedule self.mnemosyne.component_manager.register(ScheduleWdgt) for plugin in self.plugins(): component = plugin.components[0] if component.component_type == "card_type" and component.id == "5": plugin.activate() fact_data = {"text": "[question]"} card_type = self.card_type_by_id("5") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.controller().file_save() self.review_controller().reset() print self.review_controller().card new_card_type = self.card_type_by_id("1") fact_data = {"q": "[question]", "a": ""} self.controller().update_related_cards(card.fact, fact_data, new_card_type, new_tag_names=["default2"], correspondence={'text': 'q'}) assert self.database().fact_count() == 1 assert self.database().card_count() == 1 new_card = self.database().cards_from_fact(card.fact)[0] new_card.question() new_card.answer() def test_2_to_2_clone(self): fact_data = {"q": "question", "a": "answer"} card_type = self.card_type_by_id("2") card_1, card_2 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) self.controller().file_save() new_card_type = self.controller().\ clone_card_type(card_type, "my_2") self.controller().update_related_cards(card_1.fact, fact_data, new_card_type, new_tag_names=["default"], correspondence={}) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 new_card = self.database().cards_from_fact(card_1.fact)[0] assert new_card.fact.card_type.id == "2::my_2" assert new_card.fact.data["q"] == "question" assert new_card.fact.data["a"] == "answer" new_card.question() new_card.answer()
mnemosyne.components = [ ("mnemosyne.libmnemosyne.translators.no_translator", "NoTranslator"), ("mnemosyne.ppygui_ui.main_wdgt", "MainWdgt"), ("mnemosyne.ppygui_ui.review_wdgt", "ReviewWdgt"), ("mnemosyne.ppygui_ui.render_chain_WM", "RenderChain_WM"), ("mnemosyne.libmnemosyne.databases.SQLite_no_pregenerated_data", "SQLite_NoPregeneratedData"), ("mnemosyne.libmnemosyne.configuration", "Configuration"), ("mnemosyne.libmnemosyne.loggers.database_logger", "DatabaseLogger"), ("mnemosyne.libmnemosyne.schedulers.SM2_mnemosyne", "SM2Mnemosyne"), ("mnemosyne.libmnemosyne.stopwatch", "Stopwatch"), ("mnemosyne.libmnemosyne.card_types.front_to_back", "FrontToBack"), ("mnemosyne.libmnemosyne.card_types.both_ways", "BothWays"), ("mnemosyne.libmnemosyne.card_types.vocabulary", "Vocabulary"), ("mnemosyne.libmnemosyne.controllers.default_controller", "DefaultController"), ("mnemosyne.libmnemosyne.review_controllers.SM2_controller", "SM2Controller"), ("mnemosyne.libmnemosyne.card_types.map", "MapPlugin"), ("mnemosyne.libmnemosyne.card_types.cloze", "ClozePlugin"), ("mnemosyne.libmnemosyne.criteria.default_criterion", "DefaultCriterion"), ("mnemosyne.libmnemosyne.databases.SQLite_criterion_applier", "DefaultCriterionApplier") ] # Run Mnemosyne. mnemosyne.initialise(data_dir=data_dir) mnemosyne.start_review() app.mainframe = mnemosyne.main_widget() app.run() mnemosyne.finalise()
class TestMemImport(MnemosyneTest): def setup(self): self.initialise_data_dir() self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \ [("mnemosyne_test", "TestReviewWidget")] self.mnemosyne.components.append(\ ("test_mem_import", "Widget")) self.mnemosyne.components.append(\ ("test_mem_import", "MyImportDialog")) self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.review_controller().reset() def mem_importer(self): for format in self.mnemosyne.component_manager.all("file_format"): if format.__class__.__name__ == "Mnemosyne1Mem": return format @mock.patch("mnemosyne.libmnemosyne.file_formats.mnemosyne1_mem.open", mock.Mock(side_effect=[FileNotFoundError, IndexError("Mocked Error")])) def test_exceptions(self): filename = os.path.join(os.getcwd(), "tests", "files", "nothere.mem") self.mem_importer().do_import(filename) assert last_error.startswith("Unable to open") self.mem_importer().do_import("name_does_not_matter") assert last_error.strip().endswith("IndexError: Mocked Error") def test_card_type_1(self): filename = os.path.join(os.getcwd(), "tests", "files", "1sided.mem") self.mem_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 1 card = self.review_controller().card assert card.grade == 2 assert card.easiness == 2.5 assert card.acq_reps == 1 assert card.ret_reps == 0 assert card.lapses == 0 assert card.acq_reps_since_lapse == 1 assert card.ret_reps_since_lapse == 0 assert [tag.name for tag in card.tags] == ["__UNTAGGED__"] assert card.last_rep == 1247529600 assert card.next_rep == 1247616000 assert card.id == "9cff728f" def test_card_type_1_unseen(self): filename = os.path.join(os.getcwd(), "tests", "files", "1sided_unseen.mem") self.mem_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 1 card = self.review_controller().card assert card.grade == -1 assert card.easiness == 2.5 assert card.acq_reps == 0 assert card.ret_reps == 0 assert card.lapses == 0 assert card.acq_reps_since_lapse == 0 assert card.ret_reps_since_lapse == 0 assert card.last_rep == -1 assert card.next_rep == -1 assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 def test_card_type_1_edited(self): filename = os.path.join(os.getcwd(), "tests", "files", "1sided.mem") self.mem_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 1 card = self.review_controller().card assert card.id == "9cff728f" assert "question" in card.question() filename = os.path.join(os.getcwd(), "tests", "files", "1sided.mem") self.mem_importer().do_import(filename) assert last_error.startswith("These cards seem to have been imported before") def test_card_type_2(self): filename = os.path.join(os.getcwd(), "tests", "files", "2sided.mem") self.mem_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 2 card_1 = self.review_controller().card assert "question" in card_1.question() assert "answer" in card_1.answer() cards = self.database().cards_from_fact(card_1.fact) if cards[0] == card_1: card_2 = cards[1] else: card_2 = cards[0] assert "question" in card_2.answer() assert "answer" in card_2.question() assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 2 def test_card_type_3(self): filename = os.path.join(os.getcwd(), "tests", "files", "3sided.mem") self.mem_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 2 card_1 = self.review_controller().card assert card_1.fact.data == {"f": "f", "p_1": "p", "m_1": "t"} assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 2 def test_card_type_3_corrupt(self): filename = os.path.join(os.getcwd(), "tests", "files", "3sided_corrupt.mem") self.mem_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 2 card_1 = self.review_controller().card assert card_1.fact.data == {"f": "f", "m_1": "t"} assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 2 def test_card_type_3_missing(self): filename = os.path.join(os.getcwd(), "tests", "files", "3sided_missing.mem") self.mem_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 1 card_1 = self.review_controller().card assert card_1.fact.data == {"f": "t", "b": "f\np"} assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 def test_media(self): os.mkdir(os.path.join(os.getcwd(), "tests", "files", "figs")) os.mkdir(os.path.join(os.getcwd(), "tests", "files", "figs", "figs")) figures = [\ os.path.join(os.getcwd(), "tests", "files", "a.png"), os.path.join(os.getcwd(), "tests", "files", "figs", "a.png"), os.path.join(os.getcwd(), "tests", "files", "figs", "figs", "a.png")] for filename in figures: open(filename, "w") filename = os.path.join(os.getcwd(), "tests", "files", "media.mem") self.mem_importer().do_import(filename) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "a.png")) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "figs", "a.png")) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "figs", "a.png")) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 3 def test_media_missing(self): os.mkdir(os.path.join(os.getcwd(), "tests", "files", "figs")) os.mkdir(os.path.join(os.getcwd(), "tests", "files", "figs", "figs")) figures = [\ os.path.join(os.getcwd(), "tests", "files", "a.png"), os.path.join(os.getcwd(), "tests", "files", "figs", "a.png")] for filename in figures: open(filename, "w") filename = os.path.join(os.getcwd(), "tests", "files", "media.mem") self.mem_importer().do_import(filename) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "a.png")) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "figs", "a.png")) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 2 def test_media_missing_2(self): filename = os.path.join(os.getcwd(), "tests", "files", "media.mem") self.mem_importer().do_import(filename) assert not os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "a.png")) assert not os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "figs", "a.png")) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 0 def test_media_slashes(self): os.mkdir(os.path.join(os.getcwd(), "tests", "files", "figs")) os.mkdir(os.path.join(os.getcwd(), "tests", "files", "figs", "figs")) figures = [\ os.path.join(os.getcwd(), "tests", "files", "a.png"), os.path.join(os.getcwd(), "tests", "files", "figs", "a.png"), os.path.join(os.getcwd(), "tests", "files", "figs", "figs", "a.png")] for filename in figures: open(filename, "w") filename = os.path.join(os.getcwd(), "tests", "files", "media_slashes.mem") self.mem_importer().do_import(filename) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "a.png")) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "figs", "a.png")) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "figs", "a.png")) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 3 def test_media_quotes(self): filename = os.path.join(os.getcwd(), "tests", "files", "basedir_media", "default.mem") self.mem_importer().do_import(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 1 def test_sound(self): os.mkdir(os.path.join(\ os.getcwd(), "tests", "files", "soundfiles")) soundname = os.path.join(os.path.join(\ os.getcwd(), "tests", "files", "soundfiles", "a.ogg")) open(soundname, "w") filename = os.path.join(os.getcwd(), "tests", "files", "sound.mem") self.mem_importer().do_import(filename) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "soundfiles", "a.ogg")) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 1 self.review_controller().reset() card = self.review_controller().card assert card.fact["f"] == """<audio src="soundfiles/a.ogg">""" def test_map(self): filename = os.path.join(os.getcwd(), "tests", "files", "map.mem") self.mem_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 2 card = self.review_controller().card assert card.fact["loc"] == "<b>Drenthe</b>" assert card.fact["marked"] == \ """<img src_missing="maps/Netherlands-Provinces/Drenthe.png">""" assert card.fact["blank"] == \ """<img src_missing="maps/Netherlands-Provinces/Netherlands-Provinces.png">""" def test_dups(self): filename = os.path.join(os.getcwd(), "tests", "files", "dups.mem") self.mem_importer().do_import(filename) self.review_controller().reset() assert self.review_controller().card.fact["loc"] == \ """<b>Freistaat Th\xfcringen (Free State of Thuringia)</b>""" assert self.review_controller().card.tag_string() == "Germany: States, MISSING_MEDIA" def test_logs_new_1(self): self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "new_1.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.REPETITION, )).fetchone()[0] == 10 assert self.database().con.execute(\ "select acq_reps from log where event_type=? and object_id='9525224f'", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select acq_reps_since_lapse from log where event_type=? and object_id='9525224f'", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ """select scheduled_interval from log where event_type=? and object_id='9525224f' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] == (6)*60*60*24 assert self.database().con.execute(\ """select actual_interval from log where event_type=? and object_id='9525224f' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] == 0 # This is an artificial log. timestamp = self.database().con.execute(\ """select timestamp from log where event_type=? and object_id='9525224f' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] next_rep = self.database().con.execute(\ """select next_rep from log where event_type=? and object_id='9525224f' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] assert next_rep - timestamp == (14-3)*60*60*24 assert self.database().con.execute(\ "select count() from log").fetchone()[0] == 25 assert self.database().con.execute(\ "select acq_reps from log where event_type=? order by _id desc limit 1", (EventTypes.LOADED_DATABASE, )).fetchone()[0] == 0 assert self.database().con.execute(\ "select ret_reps from log where event_type=? order by _id desc limit 1", (EventTypes.LOADED_DATABASE, )).fetchone()[0] == 7 assert self.database().con.execute(\ "select lapses from log where event_type=? order by _id desc limit 1", (EventTypes.LOADED_DATABASE, )).fetchone()[0] == 336 assert self.database().con.execute(\ "select acq_reps from log where event_type=? order by _id desc limit 1", (EventTypes.SAVED_DATABASE, )).fetchone()[0] == 0 assert self.database().con.execute(\ "select ret_reps from log where event_type=? order by _id desc limit 1", (EventTypes.SAVED_DATABASE, )).fetchone()[0] == 12 assert self.database().con.execute(\ "select lapses from log where event_type=? order by _id desc limit 1", (EventTypes.SAVED_DATABASE, )).fetchone()[0] == 341 def test_logs_new_2(self): self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "new_2.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select acq_reps from log where event_type=? and object_id='8da62cfb'", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select acq_reps_since_lapse from log where event_type=? and object_id='8da62cfb'", (EventTypes.REPETITION, )).fetchone()[0] == 1 def test_logs_new_3(self): self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "new_3.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.REPETITION, )).fetchone()[0] == 4 assert self.database().con.execute(\ "select acq_reps from log where event_type=? and object_id='5106b621'", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select acq_reps_since_lapse from log where event_type=? and object_id='5106b621'", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ """select acq_reps from log where event_type=? and object_id='5106b621' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ """select acq_reps_since_lapse from log where event_type=? and object_id='5106b621' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] == 1 def test_logs_new_4(self): self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "new_4.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.REPETITION, )).fetchone()[0] == 2 assert self.database().con.execute(\ "select acq_reps from log where event_type=? and object_id='b7601e0c'", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select ret_reps from log where event_type=? and object_id='b7601e0c'", (EventTypes.REPETITION, )).fetchone()[0] == 0 assert self.database().con.execute(\ "select acq_reps_since_lapse from log where event_type=? and object_id='b7601e0c'", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ """select acq_reps from log where event_type=? and object_id='b7601e0c' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ """select ret_reps from log where event_type=? and object_id='b7601e0c' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ """select acq_reps_since_lapse from log where event_type=? and object_id='b7601e0c' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] == 1 def test_logs_new_5(self): self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "new_5.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.REPETITION, )).fetchone()[0] == 2 assert self.database().con.execute(\ "select acq_reps from log where event_type=? and object_id='9c8ce28e-1a4b-4148-8287-b8a7790d86d0.1.1'", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select ret_reps from log where event_type=? and object_id='9c8ce28e-1a4b-4148-8287-b8a7790d86d0.1.1'", (EventTypes.REPETITION, )).fetchone()[0] == 0 assert self.database().con.execute(\ "select acq_reps_since_lapse from log where event_type=? and object_id='9c8ce28e-1a4b-4148-8287-b8a7790d86d0.1.1'", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ """select acq_reps from log where event_type=? and object_id='9c8ce28e-1a4b-4148-8287-b8a7790d86d0.1.1' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] == 2 assert self.database().con.execute(\ """select ret_reps from log where event_type=? and object_id='9c8ce28e-1a4b-4148-8287-b8a7790d86d0.1.1' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] == 0 assert self.database().con.execute(\ """select acq_reps_since_lapse from log where event_type=? and object_id='9c8ce28e-1a4b-4148-8287-b8a7790d86d0.1.1' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] == 2 assert self.database().con.execute(\ """select object_id from log where event_type=?""", (EventTypes.STARTED_SCHEDULER, )).fetchone()[0] == "SM2 Mnemosyne" def test_logs_new_6(self): self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "new_6.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.REPETITION, )).fetchone()[0] == 2 sql_res = self.database().con.execute(\ "select * from log where event_type=? and object_id='4c53e29a-f9e9-498b-8beb-d3a494f61bca.1.1'", (EventTypes.REPETITION, )).fetchone() assert sql_res[4] == 5 assert sql_res[5] == 2.5 assert sql_res[6] == 1 assert sql_res[7] == 0 assert sql_res[8] == 0 assert sql_res[9] == 1 assert sql_res[10] == 0 assert sql_res[11] == 0 assert sql_res[12] == 0 assert sql_res[14] - sql_res[2] == 345600 assert sql_res[13] == 0 sql_res = self.database().con.execute(\ """select * from log where event_type=? and object_id='4c53e29a-f9e9-498b-8beb-d3a494f61bca.1.1' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone() assert sql_res[4] == 2 assert sql_res[5] == 2.5 assert sql_res[6] == 1 assert sql_res[7] == 1 assert sql_res[8] == 0 assert sql_res[9] == 1 assert sql_res[10] == 1 assert sql_res[11] == 302986 assert sql_res[12] == 10 assert sql_res[14] - sql_res[2] == 475774 assert sql_res[13] == 1 def test_logs_imported_1(self): self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "imported_1.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.REPETITION, )).fetchone()[0] == 3 assert self.database().con.execute(\ "select acq_reps from log where event_type=? and object_id='f5d9bbe7'", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select ret_reps from log where event_type=? and object_id='f5d9bbe7'", (EventTypes.REPETITION, )).fetchone()[0] == 0 assert self.database().con.execute(\ "select acq_reps_since_lapse from log where event_type=? and object_id='f5d9bbe7'", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ """select acq_reps from log where event_type=? and object_id='f5d9bbe7' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ """select ret_reps from log where event_type=? and object_id='f5d9bbe7' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] == 2 assert self.database().con.execute(\ """select acq_reps_since_lapse from log where event_type=? and object_id='f5d9bbe7' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] == 1 def test_logs_imported_2(self): self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "imported_2.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select acq_reps from log where event_type=? and object_id='14670f10'", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select ret_reps from log where event_type=? and object_id='14670f10'", (EventTypes.REPETITION, )).fetchone()[0] == 0 assert self.database().con.execute(\ "select acq_reps_since_lapse from log where event_type=? and object_id='14670f10'", (EventTypes.REPETITION, )).fetchone()[0] == 1 def test_logs_imported_3(self): self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "imported_3.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 def test_restored_1(self): self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "restored_1.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.REPETITION, )).fetchone()[0] == 1 sql_res = self.database().con.execute(\ "select * from log where event_type=?", (EventTypes.REPETITION, )).fetchone() assert sql_res[4] == 1 assert sql_res[5] == 2.36 assert sql_res[6] == 23 assert sql_res[7] == 8 assert sql_res[8] == 2 assert sql_res[9] == 0 assert sql_res[10] == 0 assert sql_res[11] == 89 * 24 * 60 * 60 assert sql_res[12] == 0 # No last rep data. assert sql_res[14] - sql_res[2] == 0 assert sql_res[13] == 5 def test_restored_2(self): self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "restored_2.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 def test_logs_act_interval(self): self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "actinterval_1.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ """select actual_interval from log where event_type=? and object_id='f1300e5a' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] == 5 def test_logs_deleted(self): self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "delete_1.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.DELETED_CARD, )).fetchone()[0] == 1 def test_logs_corrupt_1(self): # Wrong data, missing creation event. self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "corrupt_1.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select count() from log where object_id=?", ("4b59b830", )).fetchone()[0] == 3 def test_logs_corrupt_2(self): # Wrong data, isolated deletion event. self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "corrupt_2.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 0 assert self.database().con.execute(\ "select count() from log where object_id=?", ("4b59b830", )).fetchone()[0] == 0 def test_two_mem_files_sharing_same_logs(self): filename = os.path.join(os.getcwd(), "tests", "files", "basedir_2_mem", "deck1.mem") self.mem_importer().do_import(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.REPETITION, )).fetchone()[0] == 1 filename = os.path.join(os.getcwd(), "tests", "files", "basedir_2_mem", "deck2.mem") self.mem_importer().do_import(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.REPETITION, )).fetchone()[0] == 3 assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 2 card = self.database().card("4c8fff73", is_id_internal=False) assert self.database().average_thinking_time(card) == 1.5 assert self.database().total_thinking_time(card) == 3.0 assert self.database().card_count_for_grade(0, active_only=True) == 2 tag = self.database().get_or_create_tag_with_name("666") assert self.database().card_count_for_grade_and_tag(0, tag, active_only=True) == 0 from mnemosyne.libmnemosyne.statistics_pages.grades import Grades page = Grades(component_manager=self.mnemosyne.component_manager) page.prepare_statistics(tag._id) assert page.y == [0, 0, 0, 0, 0, 0, 0] page.prepare_statistics(-1) assert page.y == [0, 2, 0, 0, 0, 0, 0] def test_bz2(self): filename = os.path.join(os.getcwd(), "tests", "files", "basedir_bz2", "default.mem") self.mem_importer().do_import(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.REPETITION, )).fetchone()[0] == 0 assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select count() from log where object_id=?", ("82f2ed0d", )).fetchone()[0] == 0 def test_sch(self): self.controller().show_import_file_dialog() assert self.database().card_count_scheduled_n_days_ago(0) == 1 def test_upgrade(self): old_data_dir = os.path.join(os.getcwd(), "tests", "files", "basedir_bz2") from mnemosyne.libmnemosyne.upgrades.upgrade1 import Upgrade1 Upgrade1(self.mnemosyne.component_manager).upgrade_from_old_data_dir(old_data_dir) assert self.config()["dvipng"].rstrip() == \ "dvipng -D 300 -T tight tmp.dvi\necho" assert "14pt" in self.config()["latex_preamble"] assert self.config()["user_id"] == "f3fb13c7" assert self.log().log_index_of_last_upload() == 2 assert os.path.exists(os.path.join(old_data_dir, "DIRECTORY_NO_LONGER_USED_BY_MNEMOSYNE2")) assert os.path.exists(os.path.join(self.mnemosyne.config().data_dir, "history", "a_2.bz2")) log = open(os.path.join(self.mnemosyne.config().data_dir, "log.txt")) assert log.readline().strip() == \ "2005-11-01 09:29:08 : Imported item 82f2ed0d 0 0 0 0 0" def teardown(self): filename = os.path.join(os.getcwd(), "tests", "files", "basedir_bz2", "DIRECTORY_NO_LONGER_USED_BY_MNEMOSYNE2") if os.path.exists(filename): os.remove(filename) filename = os.path.join(os.getcwd(), "tests", "files", "a.png") if os.path.exists(filename): os.remove(filename) filename = os.path.join(os.getcwd(), "tests", "files", "a.ogg") if os.path.exists(filename): os.remove(filename) dirname = os.path.join(os.getcwd(), "tests", "files", "figs") if os.path.exists(dirname): shutil.rmtree(dirname) dirname = os.path.join(os.getcwd(), "tests", "files", "soundfiles") if os.path.exists(dirname): shutil.rmtree(dirname) MnemosyneTest.teardown(self)
class TestMnemosyne1XMLImport(MnemosyneTest): def setup(self): self.initialise_data_dir() path = os.path.join(os.getcwd(), "..", "mnemosyne", "libmnemosyne", "renderers") if path not in sys.path: sys.path.append(path) self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.gui_translators.gettext_gui_translator", "GetTextGuiTranslator")) self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \ [("mnemosyne_test", "TestReviewWidget")] self.mnemosyne.components.append(\ ("test_mnemosyne1xml_import", "Widget")) self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.review_controller().reset() def xml_importer(self): for format in self.mnemosyne.component_manager.all("file_format"): if format.__class__.__name__ == "Mnemosyne1XML": return format def test_file_not_found(self): filename = os.path.join(os.getcwd(), "tests", "files", "nothere.xml") self.xml_importer().do_import(filename) assert last_error.startswith("Unable to open") def test_wrong_format(self): filename = os.path.join(os.getcwd(), "tests", "files", "wrong_format.xml") self.xml_importer().do_import(filename) assert last_error.startswith("Unable to parse") def test_bad_version(self): filename = os.path.join(os.getcwd(), "tests", "files", "bad_version.xml") self.xml_importer().do_import(filename) assert last_error.startswith("XML file does not seem") def test_card_type_1(self): global answer answer = 0 filename = os.path.join(os.getcwd(), "tests", "files", "1sided.xml") self.xml_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 4 card = self.review_controller().card assert card.grade == 2 assert card.easiness == 2.5 assert card.acq_reps == 1 assert card.ret_reps == 0 assert card.lapses == 0 assert card.acq_reps_since_lapse == 1 assert card.ret_reps_since_lapse == 0 assert [tag.name for tag in card.tags] == ["__UNTAGGED__"] assert card.last_rep == 1247529600 assert card.next_rep == 1247616000 assert card.id == "9cff728f" def test_card_type_1_abort(self): global answer answer = 1 filename = os.path.join(os.getcwd(), "tests", "files", "1sided.xml") self.xml_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 0 def test_card_type_1_unseen(self): global answer answer = 0 filename = os.path.join(os.getcwd(), "tests", "files", "1sided_unseen.xml") self.xml_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 1 card = self.review_controller().card assert card.grade == -1 assert card.easiness == 2.5 assert card.acq_reps == 0 assert card.ret_reps == 0 assert card.lapses == 0 assert card.acq_reps_since_lapse == 0 assert card.ret_reps_since_lapse == 0 assert card.last_rep == -1 assert card.next_rep == -1 assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 def test_card_type_1_edited(self): filename = os.path.join(os.getcwd(), "tests", "files", "1sided.xml") self.xml_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 4 card = self.review_controller().card assert card.id == "9cff728f" assert "question" in card.question() filename = os.path.join(os.getcwd(), "tests", "files", "1sided.xml") self.xml_importer().do_import(filename) assert last_error.startswith( "These cards seem to have been imported before") def test_card_type_2(self): global answer answer = 0 filename = os.path.join(os.getcwd(), "tests", "files", "2sided.xml") self.xml_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 2 card_1 = self.review_controller().card assert "question" in card_1.question() assert "answer" in card_1.answer() cards = self.database().cards_from_fact(card_1.fact) if cards[0] == card_1: card_2 = cards[1] else: card_2 = cards[0] assert "question" in card_2.answer() assert "answer" in card_2.question() assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 2 def test_card_type_3(self): global answer answer = 0 filename = os.path.join(os.getcwd(), "tests", "files", "3sided.xml") self.xml_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 2 card_1 = self.review_controller().card assert card_1.fact.data == {"f": "f", "p_1": "p", "m_1": "t"} assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 2 def test_card_type_3_corrupt(self): global answer answer = 0 filename = os.path.join(os.getcwd(), "tests", "files", "3sided_corrupt.xml") self.xml_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 2 card_1 = self.review_controller().card assert card_1.fact.data == {"f": "f", "m_1": "t"} assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 2 def test_card_type_3_missing(self): global answer answer = 0 filename = os.path.join(os.getcwd(), "tests", "files", "3sided_missing.xml") self.xml_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 1 card_1 = self.review_controller().card assert card_1.fact.data == {"f": "t", "b": "f\np"} assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 def test_media(self): global answer answer = 0 os.mkdir(os.path.join(os.getcwd(), "tests", "files", "figs")) os.mkdir(os.path.join(os.getcwd(), "tests", "files", "figs", "figs")) figures = [\ os.path.join(os.getcwd(), "tests", "files", "a.png"), os.path.join(os.getcwd(), "tests", "files", "figs", "a.png"), os.path.join(os.getcwd(), "tests", "files", "figs", "figs", "a.png")] for filename in figures: open(filename, "w") filename = os.path.join(os.getcwd(), "tests", "files", "media.xml") self.xml_importer().do_import(filename) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "a.png")) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "figs", "a.png")) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "figs", "a.png")) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 3 def test_media_missing(self): global answer answer = 0 os.mkdir(os.path.join(os.getcwd(), "tests", "files", "figs")) os.mkdir(os.path.join(os.getcwd(), "tests", "files", "figs", "figs")) figures = [\ os.path.join(os.getcwd(), "tests", "files", "a.png"), os.path.join(os.getcwd(), "tests", "files", "figs", "a.png")] for filename in figures: open(filename, "w") filename = os.path.join(os.getcwd(), "tests", "files", "media.xml") self.xml_importer().do_import(filename) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "a.png")) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "figs", "a.png")) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 2 def test_media_missing_2(self): global answer answer = 0 filename = os.path.join(os.getcwd(), "tests", "files", "media.xml") self.xml_importer().do_import(filename) assert not os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "a.png")) assert not os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "figs", "a.png")) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 0 def test_media_slashes(self): global answer answer = 0 os.mkdir(os.path.join(os.getcwd(), "tests", "files", "figs")) os.mkdir(os.path.join(os.getcwd(), "tests", "files", "figs", "figs")) figures = [\ os.path.join(os.getcwd(), "tests", "files", "a.png"), os.path.join(os.getcwd(), "tests", "files", "figs", "a.png"), os.path.join(os.getcwd(), "tests", "files", "figs", "figs", "a.png")] for filename in figures: open(filename, "w") filename = os.path.join(os.getcwd(), "tests", "files", "media_slashes.xml") self.xml_importer().do_import(filename) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "a.png")) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "figs", "a.png")) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "figs", "a.png")) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 3 def test_sound(self): global answer answer = 0 os.mkdir(os.path.join(\ os.getcwd(), "tests", "files", "soundfiles")) soundname = os.path.join(os.path.join(\ os.getcwd(), "tests", "files", "soundfiles", "a.ogg")) open(soundname, "w") filename = os.path.join(os.getcwd(), "tests", "files", "sound.xml") self.xml_importer().do_import(filename) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "soundfiles", "a.ogg")) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 1 self.review_controller().reset() card = self.review_controller().card assert card.fact["f"] == """<audio src="soundfiles/a.ogg">""" def test_map(self): filename = os.path.join(os.getcwd(), "tests", "files", "map.xml") self.xml_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 2 card = self.review_controller().card assert card.fact["loc"] == "<b>Drenthe</b>" assert card.fact["marked"] == \ """<img src_missing="maps/Netherlands-Provinces/Drenthe.png">""" assert card.fact["blank"] == \ """<img src_missing="maps/Netherlands-Provinces/Netherlands-Provinces.png">""" def test_dups(self): global answer answer = 0 filename = os.path.join(os.getcwd(), "tests", "files", "dups.xml") self.xml_importer().do_import(filename) self.review_controller().reset() assert self.review_controller().card.fact["loc"] == \ """<b>Freistaat Th\xfcringen (Free State of Thuringia)</b>""" assert self.review_controller().card.tag_string( ) == "Germany: States, MISSING_MEDIA" def test_anon_id(self): global answer answer = 0 filename = os.path.join(os.getcwd(), "tests", "files", "anon_id.xml") self.xml_importer().do_import(filename) self.review_controller().reset() fact = self.review_controller().card.fact for card in self.database().cards_from_fact(fact): assert not card.id.startswith("_") assert self.database().card_count() == 2 def test_anon_id_2(self): global answer, last_error answer = 0 last_error = None filename = os.path.join(os.getcwd(), "tests", "files", "anon_id.xml") self.xml_importer().do_import(filename) assert last_error == None self.xml_importer().do_import(filename) assert last_error == None self.review_controller().reset() fact = self.review_controller().card.fact for card in self.database().cards_from_fact(fact): assert not card.id.startswith("_") assert self.database().card_count() == 4 def test_no_id(self): global answer answer = 0 filename = os.path.join(os.getcwd(), "tests", "files", "no_id.xml") self.xml_importer().do_import(filename) self.review_controller().reset() fact = self.review_controller().card.fact for card in self.database().cards_from_fact(fact): assert card.id def test_bad_xml(self): global answer answer = 0 filename = os.path.join(os.getcwd(), "tests", "files", "bad_xml.xml") self.xml_importer().do_import(filename) assert last_error.startswith("Unable to parse") def test_tags(self): global answer answer = 0 filename = os.path.join(os.getcwd(), "tests", "files", "tag.xml") self.xml_importer().do_import(filename, extra_tag_names="extra") self.review_controller().reset() assert len(self.review_controller().card.tags) == 2 def test_log(self): global answer answer = 0 filename = os.path.join(os.getcwd(), "tests", "files", "sound.xml") self.xml_importer().do_import(filename) ids = [cursor[0] for cursor in self.database().con.execute(\ "select distinct object_id from log where event_type='6' or event_type='7'")] assert ids == ['ef2e21e1'] def teardown(self): global answer answer = 0 filename = os.path.join(os.getcwd(), "tests", "files", "basedir_bz2", "DIRECTORY_NO_LONGER_USED_BY_MNEMOSYNE2") if os.path.exists(filename): os.remove(filename) filename = os.path.join(os.getcwd(), "tests", "files", "a.png") if os.path.exists(filename): os.remove(filename) filename = os.path.join(os.getcwd(), "tests", "files", "a.ogg") if os.path.exists(filename): os.remove(filename) dirname = os.path.join(os.getcwd(), "tests", "files", "figs") if os.path.exists(dirname): shutil.rmtree(dirname) dirname = os.path.join(os.getcwd(), "tests", "files", "soundfiles") if os.path.exists(dirname): shutil.rmtree(dirname) MnemosyneTest.teardown(self)
class TestTsvImport(MnemosyneTest): def setup(self): self.initialise_data_dir() self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("mnemosyne_test", "TestReviewWidget")) self.mnemosyne.components.append(\ ("test_tsv_import", "Widget")) self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.review_controller().reset() def tsv_importer(self): for format in self.mnemosyne.component_manager.all("file_format"): if format.__class__.__name__ == "Tsv": return format def test_file_not_found(self): global last_error filename = os.path.join(os.getcwd(), "tests", "files", "nothere.tsv") self.tsv_importer().do_import(filename) assert last_error.startswith("Could not load") last_error = "" def test_1(self): filename = os.path.join(os.getcwd(), "tests", "files", "tsv_1.txt") self.tsv_importer().do_import(filename) assert last_error == "" self.review_controller().reset() assert self.database().card_count() == 3 def test_2(self): filename = os.path.join(os.getcwd(), "tests", "files", "tsv_2.txt") self.tsv_importer().do_import(filename, 'extra_tag_name') assert last_error == "" self.review_controller().reset() assert self.database().card_count() == 2 assert unichr(33267) in self.review_controller().card.answer() def test_3(self): global last_error filename = os.path.join(os.getcwd(), "tests", "files", "tsv_3.txt") self.tsv_importer().do_import(filename, 'extra_tag_name') assert last_error.startswith("Badly formed input") last_error = "" def test_4(self): global last_error filename = os.path.join(os.getcwd(), "tests", "files", "word_import.txt") self.tsv_importer().do_import(filename, 'extra_tag_name') assert self.database().card_count() == 5 assert last_error == "" def test_5(self): global last_error filename = os.path.join(os.getcwd(), "tests", "files", "excel_import.txt") self.tsv_importer().do_import(filename, 'extra_tag_name') assert self.database().card_count() == 5 assert last_error == "" def test_6(self): global last_error filename = os.path.join(os.getcwd(), "tests", "files", "tsv_4.txt") self.tsv_importer().do_import(filename, 'extra_tag_name') assert self.database().card_count() == 1 self.review_controller().reset() assert u"\u00E0" in self.review_controller().card.question() assert last_error == "" def test_7(self): global last_error filename = os.path.join(os.getcwd(), "tests", "files", "tsv_5.txt") self.tsv_importer().do_import(filename, 'extra_tag_name') assert self.database().card_count() == 1 self.review_controller().reset() assert u"\u00E0" in self.review_controller().card.question() assert last_error == "" def test_8(self): global last_error filename = os.path.join(os.getcwd(), "tests", "files", "tsv_6.txt") self.tsv_importer().do_import(filename, 'extra_tag_name') assert self.database().card_count() == 2 self.review_controller().reset() assert self.review_controller().card.fact["n"] == "notes" assert last_error == "" def test_media(self): global last_error file(os.path.join(os.getcwd(), "dot_test", "default.db_media", "a.png"), "w") filename = os.path.join(os.getcwd(), "tests", "files", "tsv_media.txt") self.tsv_importer().do_import(filename) assert self.database().card_count() == 2 assert self.database().card_count_for_tags(\ [self.database().get_or_create_tag_with_name("MISSING_MEDIA")], False) == 1 assert last_error == "" fact_data = {"f": "question", "b": ""} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(\ fact_data, card_type, grade=-1, tag_names=["default"])[0] self.tsv_importer().do_export(os.path.join(os.getcwd(), "dot_test", "test.txt")) def teardown(self): filename = \ os.path.join(os.getcwd(), "dot_test", "default.db_media", "a.png") if os.path.exists(filename): os.remove(filename) filename = \ os.path.join(os.getcwd(), "dot_test", "test.txt") if os.path.exists(filename): os.remove(filename) MnemosyneTest.teardown(self)
class TestConvertCards(MnemosyneTest): def setup(self): self.initialise_data_dir() path = os.path.join(os.getcwd(), "..", "mnemosyne", "libmnemosyne", "renderers") if path not in sys.path: sys.path.append(path) self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_convert_cards", "Widget")) self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \ [("mnemosyne_test", "TestReviewWidget")] self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.review_controller().reset() from mnemosyne.libmnemosyne.card_types.map import MapPlugin for plugin in self.plugins(): if isinstance(plugin, MapPlugin): plugin.activate() break def test_1_to_2(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact old_card = copy.copy(self.database().cards_from_fact(fact)[0]) new_fact_data = {"f": "question2", "b": "answer2"} new_card_type = self.card_type_with_id("2") self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=[]) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 new_card_1, new_card_2 = self.database().cards_from_fact(fact) assert new_card_1.card_type.id == "2" assert new_card_2.card_type.id == "2" if new_card_1.fact_view.id == "2.1": assert new_card_1 == old_card assert new_card_2 != old_card assert new_card_2.grade == -1 else: assert new_card_2 == old_card assert new_card_1 != old_card assert new_card_1.grade == -1 new_card_1.question() new_card_1.answer() new_card_2.question() new_card_2.answer() def test_1_to_2_multi(self): open("a.ogg", "w") full_path = os.path.abspath("a.ogg") fact_data = {"f": "<img src=\"%s\">" % full_path, "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact old_card = copy.copy(self.database().cards_from_fact(fact)[0]) new_fact_data = {"f": "question2", "b": "answer2"} new_card_type = self.card_type_with_id("2") self.controller().change_card_type([fact], card.card_type, new_card_type, correspondence=[]) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 new_card_1, new_card_2 = self.database().cards_from_fact(fact) assert new_card_1.card_type.id == "2" assert new_card_2.card_type.id == "2" if new_card_1.fact_view.id == "2.1": assert new_card_1 == old_card assert new_card_2 != old_card assert new_card_2.grade == -1 else: assert new_card_2 == old_card assert new_card_1 != old_card assert new_card_1.grade == -1 new_card_1.question() new_card_1.answer() new_card_2.question() new_card_2.answer() def test_1_to_2_multi_no_media(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact old_card = copy.copy(self.database().cards_from_fact(fact)[0]) new_fact_data = {"f": "question2", "b": "answer2"} new_card_type = self.card_type_with_id("2") self.controller().change_card_type([fact], card.card_type, new_card_type, correspondence=[]) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 new_card_1, new_card_2 = self.database().cards_from_fact(fact) assert new_card_1.card_type.id == "2" assert new_card_2.card_type.id == "2" if new_card_1.fact_view.id == "2.1": assert new_card_1 == old_card assert new_card_2 != old_card assert new_card_2.grade == -1 else: assert new_card_2 == old_card assert new_card_1 != old_card assert new_card_1.grade == -1 new_card_1.question() new_card_1.answer() new_card_2.question() new_card_2.answer() def test_2_to_1(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("2") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"f": "question2", "b": "answer2"} new_card_type = self.card_type_with_id("1") self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=[]) assert self.database().fact_count() == 1 assert self.database().card_count() == 1 new_card = self.database().cards_from_fact(fact)[0] assert new_card.card_type.id == "1" if old_card_1.fact_view.id == "2.1": assert new_card == old_card_1 assert new_card != old_card_2 else: assert new_card == old_card_2 assert new_card != old_card_1 new_card.question() new_card.answer() def test_1_to_3_a(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact old_card = copy.copy(self.database().cards_from_fact(fact)[0]) new_fact_data = {"f": "foreign word", "p_1": "pronunciation", "m_1": "translation"} correspondence = {"f": "f", "b": "p_1"} new_card_type = self.card_type_with_id("3") self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 new_card_1, new_card_2 = self.database().cards_from_fact(fact) assert new_card_1.card_type.id == "3" assert new_card_2.card_type.id == "3" if new_card_1.fact_view.id == "3.1": assert new_card_1 == old_card assert new_card_2 != old_card else: assert new_card_2 == old_card assert new_card_1 != old_card new_card_1.question() new_card_1.answer() new_card_2.question() new_card_2.answer() def test_1_to_3_b(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact old_card = copy.copy(self.database().cards_from_fact(fact)[0]) new_fact_data = {"f": "foreign word", "p_1": "pronunciation", "m_1": "translation"} correspondence = {"f": "m_1", "b": "f"} new_card_type = self.card_type_with_id("3") self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 new_card_1, new_card_2 = self.database().cards_from_fact(fact) assert new_card_1.card_type.id == "3" assert new_card_2.card_type.id == "3" if new_card_1.fact_view.id == "3.2": assert new_card_1 == old_card assert new_card_2 != old_card else: assert new_card_2 == old_card assert new_card_1 != old_card new_card_1.question() new_card_1.answer() new_card_2.question() new_card_2.answer() def test_3_to_1_a(self): fact_data = {"f": "foreign word", "p_1": "pronunciation", "m_1": "translation"} card_type = self.card_type_with_id("3") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"f": "question", "b": "answer"} correspondence = {"f": "f", "m_1": "b"} new_card_type = self.card_type_with_id("1") self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 1 new_card = self.database().cards_from_fact(fact)[0] assert new_card.card_type.id == "1" if old_card_1.fact_view.id == "3.1": assert new_card == old_card_1 assert new_card != old_card_2 else: assert new_card == old_card_2 assert new_card != old_card_1 new_card.question() new_card.answer() def test_3_to_1_b(self): fact_data = {"f": "foreign word", "p_1": "pronunciation", "m_1": "translation"} card_type = self.card_type_with_id("3") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"f": "question", "b": "answer"} correspondence = {"f": "b", "m_1": "f"} new_card_type = self.card_type_with_id("1") self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 1 new_card = self.database().cards_from_fact(fact)[0] assert new_card.card_type.id == "1" if old_card_1.fact_view.id == "3.2": assert new_card == old_card_1 assert new_card != old_card_2 else: assert new_card == old_card_2 assert new_card != old_card_1 new_card.question() new_card.answer() def test_3_to_1_c(self): # Missing required field. fact_data = {"f": "foreign word", "m_1": "meaning"} card_type = self.card_type_with_id("3") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"b": "foreign word"} correspondence = {"f": "b", "p_1": "f"} new_card_type = self.card_type_with_id("1") self.controller().change_card_type([fact], card_type, new_card_type, correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 card_1, card_2 = self.database().cards_from_fact(fact) assert card_1.card_type.id == "3" assert card_2.card_type.id == "3" def test_2_to_3_a(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("2") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"f": "foreign word", "p_1": "pronunciation", "m_1": "translation"} correspondence = {"f": "f", "b": "m_1"} new_card_type = self.card_type_with_id("3") self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 new_card_1, new_card_2 = self.database().cards_from_fact(fact) assert new_card_1.card_type.id == "3" assert new_card_2.card_type.id == "3" for old in [old_card_1, old_card_2]: for new in [new_card_1, new_card_2]: if old == new: assert old.fact_view.id.split(".")[1] == \ new.fact_view.id.split(".")[1] new_card_1.question() new_card_1.answer() new_card_2.question() new_card_2.answer() def test_2_to_3_b(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("2") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"f": "foreign word", "p_1": "pronunciation", "m_1": "translation"} correspondence = {"f": "m_1", "b": "f"} new_card_type = self.card_type_with_id("3") self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 new_card_1, new_card_2 = self.database().cards_from_fact(fact) assert new_card_1.card_type.id == "3" assert new_card_2.card_type.id == "3" for old in [old_card_1, old_card_2]: for new in [new_card_1, new_card_2]: if old == new: assert old.fact_view != new.fact_view new_card_1.question() new_card_1.answer() new_card_2.question() new_card_2.answer() def test_3_to_2_a(self): fact_data = {"f": "foreign word", "p_1": "pronunciation", "m_1": "translation"} card_type = self.card_type_with_id("3") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"f": "question", "b": "answer"} correspondence = {"f": "f", "m_1": "b"} new_card_type = self.card_type_with_id("2") self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 new_card_1, new_card_2 = self.database().cards_from_fact(fact) assert new_card_1.card_type.id == "2" assert new_card_2.card_type.id == "2" for old in [old_card_1, old_card_2]: for new in [new_card_1, new_card_2]: if old == new: assert old.fact_view.id.split(".")[1] == \ new.fact_view.id.split(".")[1] new_card_1.question() new_card_1.answer() new_card_2.question() new_card_2.answer() def test_3_to_2_b(self): fact_data = {"f": "foreign word", "p_1": "pronunciation", "m_1": "translation"} card_type = self.card_type_with_id("3") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"f": "question", "b": "answer"} correspondence = {"f": "b", "m_1": "f"} new_card_type = self.card_type_with_id("2") self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 new_card_1, new_card_2 = self.database().cards_from_fact(fact) assert new_card_1.card_type.id == "2" assert new_card_2.card_type.id == "2" for old in [old_card_1, old_card_2]: for new in [new_card_1, new_card_2]: if old == new: assert old.fact_view != new.fact_view new_card_1.question() new_card_1.answer() new_card_2.question() new_card_2.answer() def test_3_clone_to_1_a(self): fact_data = {"f": "foreign word", "p_1": "pronunciation", "m_1": "translation"} card_type = self.card_type_with_id("3") self.controller().clone_card_type(card_type, "my_3") card_type = self.card_type_with_id("3::my_3") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"f": "question", "b": "answer"} correspondence = {"f": "f", "m_1": "b"} new_card_type = self.card_type_with_id("1") self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 1 new_card = self.database().cards_from_fact(fact)[0] assert new_card.card_type.id == "1" if old_card_1.fact_view.id == "3::my_3.1": assert new_card == old_card_1 assert new_card != old_card_2 else: assert new_card == old_card_2 assert new_card != old_card_1 new_card.question() new_card.answer() def test_3_to_1_clone_a(self): fact_data = {"f": "foreign word", "p_1": "pronunciation", "m_1": "translation"} card_type = self.card_type_with_id("3") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"f": "question", "b": "answer"} correspondence = {"f": "f", "m_1": "b"} new_card_type = self.card_type_with_id("1") self.controller().clone_card_type(new_card_type, "my_1") new_card_type = self.card_type_with_id("1::my_1") self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 1 new_card = self.database().cards_from_fact(fact)[0] assert new_card.card_type.id == "1::my_1" assert new_card.fact.data["f"] == "question" assert new_card.fact.data["b"] == "answer" if old_card_1.fact_view.id == "3.1": assert new_card == old_card_1 assert new_card != old_card_2 else: assert new_card == old_card_2 assert new_card != old_card_1 new_card.question() new_card.answer() def test_3_clone_to_1_clone_a(self): fact_data = {"f": "foreign word", "p_1": "pronunciation", "m_1": "translation"} card_type = self.card_type_with_id("3") self.controller().clone_card_type(card_type, "my_3") card_type = self.card_type_with_id("3::my_3") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"f": "question", "b": "answer"} correspondence = {"f": "f", "m_1": "b"} new_card_type = self.card_type_with_id("1") self.controller().clone_card_type(new_card_type, "my_1") new_card_type = self.card_type_with_id("1::my_1") self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 1 new_card = self.database().cards_from_fact(fact)[0] assert new_card.card_type.id == "1::my_1" if old_card_1.fact_view.id == "3::my_3.1": assert new_card == old_card_1 assert new_card != old_card_2 else: assert new_card == old_card_2 assert new_card != old_card_1 new_card.question() new_card.answer() def test_cloze_to_1(self): from mnemosyne.libmnemosyne.ui_components.statistics_widget import \ StatisticsWidget from mnemosyne.libmnemosyne.statistics_pages.schedule import Schedule class ScheduleWdgt(StatisticsWidget): used_for = Schedule self.mnemosyne.component_manager.register(ScheduleWdgt) for plugin in self.plugins(): component = plugin.components[0] if component.component_type == "card_type" and component.id == "5": plugin.activate() fact_data = {"text": "[question]"} card_type = self.card_type_with_id("5") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.review_controller().reset() new_card_type = self.card_type_with_id("1") fact_data = {"f": "[question]", "b": ""} self.controller().edit_card_and_sisters(card, fact_data, new_card_type, new_tag_names=["default2"], correspondence={'text': "f"}) assert self.database().fact_count() == 1 assert self.database().card_count() == 1 new_card = self.database().cards_from_fact(card.fact)[0] new_card.question() new_card.answer() def test_2_to_2_clone(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("2") card_1, card_2 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) new_card_type = self.controller().\ clone_card_type(card_type, "my_2") self.controller().edit_card_and_sisters(card_1, fact_data, new_card_type, new_tag_names=["default"], correspondence={}) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 new_card = self.database().cards_from_fact(card_1.fact)[0] assert new_card.card_type.id == "2::my_2" assert new_card.fact.data["f"] == "question" assert new_card.fact.data["b"] == "answer" new_card.question() new_card.answer() def test_1_to_3_clone(self): card_type = self.card_type_with_id("1") # Production only. fact_data = {"f": "translation", "b": "foreign"} card = self.controller().create_new_cards(fact_data, card_type, grade=2, tag_names=["default"])[0] new_card_type = self.controller().\ clone_card_type(self.card_type_with_id("3"), "my_language") correspondence = {"f": "m_1", "b": "f"} self.controller().change_card_type([card.fact], card_type, new_card_type, correspondence=correspondence) fact = self.database().fact(card.fact._id, is_id_internal=True) assert fact["f"] == "foreign" card_1, card_2 = self.database().cards_from_fact(fact) assert len(card_1.tags) == 1 assert len(card_2.tags) == 1 for tag in card_1.tags: assert tag.name == "default" for tag in card_2.tags: assert tag.name == "default" assert self.database().con.execute("select tags from cards where _id=?", (card_1._id, )).fetchone()[0] == "default" assert self.database().con.execute("select tags from cards where _id=?", (card_2._id, )).fetchone()[0] == "default" assert card_1.active == True assert card_2.active == True if card_1.fact_view.id == "3.1": # Recognition assert "foreign" in card_1.question() assert "translation" in card_2.question() assert card_1.grade == -1 assert card_2.grade == 2 else: assert "foreign" in card_2.question() assert "translation" in card_1.question() assert card_2.grade == -1 assert card_1.grade == 2 def test_1_to_3_clone_bis(self): card_type = self.card_type_with_id("1") # Production only. fact_data = {"f": "translation", "b": "foreign"} card = self.controller().create_new_cards(fact_data, card_type, grade=2, tag_names=["default"])[0] new_card_type = self.controller().\ clone_card_type(self.card_type_with_id("3"), "my_language") correspondence = {"f": "m_1", "b": "f"} new_fact_data = {"m_1": "translation", "f": "foreign"} self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, new_tag_names=["default"], correspondence=correspondence) fact = self.database().fact(card.fact._id, is_id_internal=True) assert fact["f"] == "foreign" card_1, card_2 = self.database().cards_from_fact(fact) assert len(card_1.tags) == 1 assert len(card_2.tags) == 1 for tag in card_1.tags: assert tag.name == "default" for tag in card_2.tags: assert tag.name == "default" assert self.database().con.execute("select tags from cards where _id=?", (card_1._id, )).fetchone()[0] == "default" assert self.database().con.execute("select tags from cards where _id=?", (card_2._id, )).fetchone()[0] == "default" assert card_1.active == True assert card_2.active == True if card_1.fact_view.id == "3.1": # Recognition assert "foreign" in card_1.question() assert "translation" in card_2.question() assert card_1.grade == -1 assert card_2.grade == 2 else: assert "foreign" in card_2.question() assert "translation" in card_1.question() assert card_2.grade == -1 assert card_1.grade == 2 def test_convert_duplicates(self): card_type_map = self.card_type_with_id("4") fact_data = {"loc": "test", "blank": "test1", "marked": "test2"} card = self.controller().create_new_cards(fact_data, card_type_map, grade=2, tag_names=["default"])[0] card_type = self.card_type_with_id("1") fact_data = {"f": "test1", "b": "test2"} card = self.controller().create_new_cards(fact_data, card_type, grade=2, tag_names=["default"])[0] correspondence = {"f": "blank", "b": "marked"} new_fact_data = {"loc": "test", "blank": "test1", "marked": "test2"} self.controller().edit_card_and_sisters(card, new_fact_data, card_type_map, new_tag_names=["default"], correspondence=correspondence) def teardown(self): if os.path.exists("a.ogg"): os.remove("a.ogg") MnemosyneTest.teardown(self)
class TestConfiguration(MnemosyneTest): def setup(self): self.initialise_data_dir() path = os.path.join(os.getcwd(), "..", "mnemosyne", "libmnemosyne", "renderers") if path not in sys.path: sys.path.append(path) self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.gui_translators.gettext_gui_translator", "GetTextGuiTranslator")) self.mnemosyne.components.append(\ ("test_add_cards", "Widget")) self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \ [("mnemosyne_test", "TestReviewWidget")] self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "EditCardDialog")) self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.review_controller().reset() def test_default_language_default(self): # the default language should be the en assert self.config().default_language() == 'en' def test_supported_language_as_default(self): locale_map_to_test = { "[email protected]": "ca@valencia", "de_DE.UTF-8": "de", "en_US.UTF-8": "en", "hu_HU.UTF-8": "hu", "ja_JP.UTF-8": "ja", "pt_BR.UTF-8": "pt_BR", "pt_PT.UTF-8": "pt", "sv_SE.UTF-8": "sv", "zh_CN.UTF-8": "zh_CN", "zh_HK.UTF-8": "zh_HK", "zh_TW.UTF-8": "zh_TW", } with patch( 'mnemosyne.libmnemosyne.gui_translators.gettext_gui_translator.GetTextGuiTranslator.supported_languages' ) as mock_supported: # in development mode, we need to mock the supported_languages mock_supported.return_value = [ 'ca', 'gl', 'ja', 'pt', 'pl', 'nb', 'tr', 'id', 'ca@valencia', 'zh_TW', 'cs', 'zh_CN', 'nl', 'fr', 'he', 'it', 'da', 'sr', 'de', 'pt_BR', 'ru', 'eo', 'hr', 'sv', 'uk', 'fa', 'hu', 'zh_HK', 'es' ] for lang_locale in locale_map_to_test: lang_code, encoding = lang_locale.split(".") with patch( 'mnemosyne.libmnemosyne.configuration.getdefaultlocale' ) as mock_locale: mock_locale.return_value = (lang_code, encoding) lang = self.config().default_language() assert lang == locale_map_to_test[lang_locale] mock_locale.assert_called_once()
class TestReviewController(MnemosyneTest): def setup(self): global expected_scheduled_count expected_scheduled_count = None self.initialise_data_dir() path = os.path.join(os.getcwd(), "..", "mnemosyne", "libmnemosyne", "renderers") if path not in sys.path: sys.path.append(path) self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.gui_translators.gettext_gui_translator", "GetTextGuiTranslator")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.main_widget", "MainWidget")) self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \ [("test_review_controller", "MyReviewWidget")] self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "EditCardDialog")) self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.review_controller().reset() def test_1(self): card_1 = None self.review_controller().reset() for i in range(10): fact_data = {"f": "question" + str(i), "b": "answer" + str(i)} if i % 2: card_type = self.card_type_with_id("1") else: card_type = self.card_type_with_id("2") card = self.controller().create_new_cards(fact_data, card_type, grade=4, tag_names=[ "default" + str(i) ])[0] if i == 0: card_1 = card card.next_rep -= 1000 * 24 * 60 * 60 self.database().update_card(card) self.review_controller().set_render_chain("default") self.review_controller().show_new_question() self.review_controller().reset_but_try_to_keep_current_card() self.review_controller().show_answer() assert self.review_controller().card == card_1 assert self.review_controller().counters() == (1, 0, 15) self.review_controller().grade_answer(0) assert self.review_controller().counters() == (0, 1, 15) self.review_controller().grade_answer(2) assert self.review_controller().counters() == (0, 0, 15) self.review_controller().next_rep_string(0) self.review_controller().next_rep_string(1) self.review_controller().next_rep_string(2) def test_2(self): card_1 = None self.review_controller().reset() for i in range(10): fact_data = {"f": "question" + str(i), "b": "answer" + str(i)} if i % 2: card_type = self.card_type_with_id("1") else: card_type = self.card_type_with_id("2") card = self.controller().create_new_cards(fact_data, card_type, grade=4, tag_names=[ "default" + str(i) ])[0] if i == 0: card_1 = card card.next_rep -= 1000 * 24 * 60 * 60 self.database().update_card(card) self.review_controller().show_new_question() assert self.review_controller().card == card_1 self.review_controller().reload_counters() assert self.review_controller().counters() == (1, 0, 15) self.review_controller().grade_answer(0) self.review_controller().reload_counters() assert self.review_controller().counters() == (0, 1, 15) self.review_controller().grade_answer(2) self.review_controller().reload_counters() assert self.review_controller().counters() == (0, 0, 15) self.mnemosyne.review_widget().set_grade_enabled(1, True) def test_reset_but_try_to_keep_current_card_turned_inactive(self): card_type = self.card_type_with_id("1") fact_data = {"f": "1", "b": "b"} card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["forbidden"])[0] self.review_controller().show_new_question() assert self.review_controller().card == card c = DefaultCriterion(self.mnemosyne.component_manager) c.deactivated_card_type_fact_view_ids = set() c._tag_ids_active = set( [self.database().get_or_create_tag_with_name("active")._id]) c._tag_ids_forbidden = set( [self.database().get_or_create_tag_with_name("forbidden")._id]) self.database().set_current_criterion(c) assert self.database().active_count() == 0 assert self.review_controller().card == card self.review_controller().reset_but_try_to_keep_current_card() assert self.review_controller().card is None def test_last_card(self): card_type = self.card_type_with_id("1") for data in ["1", "2", "3"]: fact_data = {"f": data, "b": data} self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=[]) self.review_controller().show_new_question() self.review_controller().show_answer() for i in range(5): self.review_controller().grade_answer(0) self.review_controller().show_answer() for i in range(2): self.review_controller().grade_answer(2) self.review_controller().show_answer() for i in range(6): self.review_controller().grade_answer(0) self.review_controller().show_answer() def test_counters(self): global expected_scheduled_count card_type = self.card_type_with_id("1") fact_data = {"f": '1', "b": '1'} card = self.controller().create_new_cards(fact_data, card_type, grade=5, tag_names=[])[0] card.next_rep = 0 self.database().update_card(card) expected_scheduled_count = 1 self.review_controller().show_new_question() assert self.review_controller().scheduled_count == 1 assert self.review_controller().counters()[0] == 1 self.review_controller().show_answer() expected_scheduled_count = 0 self.review_controller().grade_answer(0) assert self.review_controller().scheduled_count == 0 assert self.review_controller().counters()[0] == 0 def test_counters_prefetch(self): global expected_scheduled_count card_type = self.card_type_with_id("1") for data in ['1', '2', '3', '4']: fact_data = {"f": data, "b": data} card = self.controller().create_new_cards(fact_data, card_type, grade=5, tag_names=[])[0] card.next_rep = 0 self.database().update_card(card) expected_scheduled_count = 4 self.review_controller().show_new_question() assert self.review_controller().scheduled_count == 4 assert self.review_controller().counters()[0] == 4 self.review_controller().show_answer() expected_scheduled_count = 3 self.review_controller().grade_answer(3) assert self.review_controller().scheduled_count == 3 assert self.review_controller().counters()[0] == 3
class TestPlugin(MnemosyneTest): def setup(self): self.initialise_data_dir() self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.gui_translators.gettext_gui_translator", "GetTextGuiTranslator")) self.mnemosyne.components.append(\ ("test_plugin", "Widget")) self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \ [("mnemosyne_test", "TestReviewWidget")] self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.review_controller().reset() @raises(AssertionError) def test_1(self): from mnemosyne.libmnemosyne.plugin import Plugin p = Plugin(self.mnemosyne.component_manager) def test_2(self): from mnemosyne.libmnemosyne.card_types.front_to_back import FrontToBack from mnemosyne.libmnemosyne.plugin import Plugin class MyCardType(FrontToBack): id = "666" class MyPlugin(Plugin): name = "myplugin" description = "MyPlugin" components = [MyCardType] supported_API_level = 3 p = MyPlugin(self.mnemosyne.component_manager) old_length = len(self.card_types()) p.activate() assert len(self.card_types()) == old_length + 1 p.deactivate() assert len(self.card_types()) == old_length p.activate() fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("666") self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) p.deactivate() # Pops up an information box that this is not possible. global last_error assert last_error.startswith("Cannot deactivate") last_error = "" def test_deactivate_clone(self): from mnemosyne.libmnemosyne.card_types.front_to_back import FrontToBack from mnemosyne.libmnemosyne.plugin import Plugin class MyCardType(FrontToBack): id = "666" class MyPlugin(Plugin): name = "myplugin" description = "MyPlugin" components = [MyCardType] supported_API_level = 3 p = MyPlugin(self.mnemosyne.component_manager) old_length = len(self.card_types()) p.activate() assert len(self.card_types()) == old_length + 1 p.deactivate() assert len(self.card_types()) == old_length p.activate() card_type = self.mnemosyne.card_type_with_id("666") self.mnemosyne.controller().clone_card_type(card_type, "new_name") p.deactivate() # Pops up an information box that this is not possible. global last_error assert last_error.startswith("Cannot deactivate") last_error = "" def test_3(self): from mnemosyne.libmnemosyne.card_types.front_to_back import FrontToBack from mnemosyne.libmnemosyne.plugin import Plugin class MyCardType(FrontToBack): id = "666" class MyPlugin(Plugin): name = "myplugin" description = "MyPlugin" components = [MyCardType] supported_API_level = 3 p = MyPlugin(self.mnemosyne.component_manager) old_length = len(self.card_types()) p.activate() assert len(self.card_types()) == old_length + 1 p.deactivate() assert len(self.card_types()) == old_length p.activate() fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("666") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact self.controller().delete_facts_and_their_cards([fact]) p.deactivate() # Should work without problems. def test_4(self): from mnemosyne.libmnemosyne.plugin import Plugin from mnemosyne.libmnemosyne.card_types.front_to_back import FrontToBack from mnemosyne.pyqt_ui.card_type_wdgt_generic import GenericCardTypeWdgt class RedGenericCardTypeWdgt(GenericCardTypeWdgt): used_for = FrontToBack def __init__(self, parent, component_manager): GenericCardTypeWdgt.__init__(self, component_manager, parent, FrontToBack()) class RedPlugin(Plugin): name = "Red" description = "Red widget for front-to-back cards" components = [RedGenericCardTypeWdgt] supported_API_level = 3 p = RedPlugin(self.mnemosyne.component_manager) p.activate() assert self.mnemosyne.component_manager.current\ ("generic_card_type_widget", used_for=FrontToBack) != None p.deactivate() assert self.mnemosyne.component_manager.current\ ("generic_card_type_widget", used_for=FrontToBack) == None def test_5(self): for plugin in self.plugins(): component = plugin.components[0] if component.component_type == "card_type" and component.id == "4": plugin.activate() plugin.activate() @raises(NotImplementedError) def test_6(self): from mnemosyne.libmnemosyne.hook import Hook Hook(self.mnemosyne.component_manager).run() def test_install_plugin(self): global filename filename = os.path.join(os.getcwd(), "tests", "files", "hide_toolbar.plugin") self.controller().install_plugin() assert os.path.exists( os.path.join(os.getcwd(), "dot_test", "plugins", "plugin_data")) assert len(self.plugins()) == 4 # Try to install twice. self.controller().install_plugin() assert len(self.plugins()) == 4 # Uninstall. for plugin in self.plugins(): if plugin.__class__.__name__ == "HideToolbarPlugin": self.controller().delete_plugin(plugin) break assert not os.path.exists( os.path.join(os.getcwd(), "dot_test", "plugins", "plugin_data")) assert not os.path.exists( os.path.join(os.getcwd(), "dot_test", "plugins", "HideToolbarPlugin.manifest")) assert os.path.exists(os.path.join(os.getcwd(), "dot_test", "plugins")) assert len(self.plugins()) == 3 # Try to reinstall immediately. self.controller().install_plugin() assert len(self.plugins()) == 4 def test_install_plugin_cancel(self): global filename filename = "" self.controller().install_plugin() def test_install_plugin_missing(self): global filename global last_error filename = os.path.join(os.getcwd(), "tests", "files", "hide_toolbar_missing.plugin") self.controller().install_plugin() assert last_error.startswith("No plugin found") last_error = None def test_install_plugin_corrupt(self): global filename global last_error filename = os.path.join(os.getcwd(), "tests", "files", "hide_toolbar_corrupt.plugin") self.controller().install_plugin() assert last_error.startswith("Error when running") last_error = None
class TestPlugin(MnemosyneTest): def setup(self): os.system("rm -fr dot_test") self.mnemosyne = Mnemosyne() self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_plugin", "Widget")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.review_widget", "ReviewWidget")) self.mnemosyne.initialise(os.path.abspath("dot_test")) self.review_controller().reset() @raises(AssertionError) def test_1(self): from mnemosyne.libmnemosyne.plugin import Plugin p = Plugin(self.mnemosyne.component_manager) @raises(NotImplementedError) def test_2(self): from mnemosyne.libmnemosyne.card_types.front_to_back import FrontToBack from mnemosyne.libmnemosyne.plugin import Plugin class MyCardType(FrontToBack): id = "666" class MyPlugin(Plugin): name = "myplugin" description = "MyPlugin" components = [MyCardType] p = MyPlugin(self.mnemosyne.component_manager) old_length = len(self.card_types()) p.activate() assert len(self.card_types()) == old_length + 1 p.deactivate() assert len(self.card_types()) == old_length p.activate() fact_data = {"q": "question", "a": "answer"} card_type = self.card_type_by_id("666") self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) p.deactivate() # Pops up an information box that this is not possible. def test_3(self): from mnemosyne.libmnemosyne.card_types.front_to_back import FrontToBack from mnemosyne.libmnemosyne.plugin import Plugin class MyCardType(FrontToBack): id = "666" class MyPlugin(Plugin): name = "myplugin" description = "MyPlugin" components = [MyCardType] p = MyPlugin(self.mnemosyne.component_manager) old_length = len(self.card_types()) p.activate() assert len(self.card_types()) == old_length + 1 p.deactivate() assert len(self.card_types()) == old_length p.activate() fact_data = {"q": "question", "a": "answer"} card_type = self.card_type_by_id("666") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact self.database().delete_fact_and_related_data(fact) p.deactivate() # Should work without problems. def test_4(self): from mnemosyne.libmnemosyne.plugin import Plugin from mnemosyne.libmnemosyne.card_types.front_to_back import FrontToBack from mnemosyne.pyqt_ui.generic_card_type_widget import GenericCardTypeWdgt class RedGenericCardTypeWdgt(GenericCardTypeWdgt): used_for = FrontToBack def __init__(self, parent, component_manager): GenericCardTypeWdgt.__init__(self, FrontToBack, parent, component_manager) class RedPlugin(Plugin): name = "Red" description = "Red widget for front-to-back cards" components = [RedGenericCardTypeWdgt] p = RedPlugin(self.mnemosyne.component_manager) p.activate() assert self.mnemosyne.component_manager.get_current\ ("generic_card_type_widget", used_for=FrontToBack) != None p.deactivate() assert self.mnemosyne.component_manager.get_current\ ("generic_card_type_widget", used_for=FrontToBack) == None def test_5(self): for plugin in self.plugins(): component = plugin.components[0] if component.component_type == "card_type" and component.id == "4": plugin.activate() plugin.activate()
class WebServer(Component): def __init__(self, component_manager, port, data_dir, config_dir, filename, is_server_local=False): Component.__init__(self, component_manager) self.port = port self.data_dir = data_dir self.config_dir = config_dir self.filename = filename self.is_server_local = is_server_local # When restarting the server, make sure we discard info from the # browser resending the form from the previous session. self.is_just_started = True self.is_mnemosyne_loaded = False self.is_shutting_down = False self.wsgi_server = wsgiserver.CherryPyWSGIServer(\ ("0.0.0.0", port), self.wsgi_app, server_name="localhost", numthreads=1, timeout=5) # We need to set the timeout relatively low, otherwise it will take # too long for the server to process a 'stop' request. def serve_until_stopped(self): try: self.wsgi_server.start() # Sets self.wsgi_server.ready except KeyboardInterrupt: self.wsgi_server.stop() self.unload_mnemosyne() def stop(self): self.wsgi_server.stop() self.unload_mnemosyne() def load_mnemosyne(self): self.mnemosyne = Mnemosyne(upload_science_logs=True, interested_in_old_reps=True) self.mnemosyne.components.insert(0, ( ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator"))) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.main_widget", "MainWidget")) self.mnemosyne.components.append(\ ("mnemosyne.web_server.review_wdgt", "ReviewWdgt")) self.mnemosyne.components.append(\ ("mnemosyne.web_server.web_server_render_chain", "WebServerRenderChain")) self.mnemosyne.initialise(self.data_dir, config_dir=self.config_dir, filename=self.filename, automatic_upgrades=False) self.mnemosyne.review_controller().set_render_chain("web_server") self.save_after_n_reps = self.mnemosyne.config()["save_after_n_reps"] self.mnemosyne.config()["save_after_n_reps"] = 1 self.mnemosyne.start_review() self.mnemosyne.review_widget().set_is_server_local(\ self.is_server_local) self.is_mnemosyne_loaded = True self.release_database_after_timeout = \ ReleaseDatabaseAfterTimeout(self.port) self.release_database_after_timeout.start() def unload_mnemosyne(self): if not self.is_mnemosyne_loaded: return self.mnemosyne.config()["save_after_n_reps"] = self.save_after_n_reps self.mnemosyne.finalise() self.is_mnemosyne_loaded = False def wsgi_app(self, environ, start_response): filename = environ["PATH_INFO"].decode("utf-8") if filename == "/status": response_headers = [("Content-type", "text/html")] start_response("200 OK", response_headers) return ["200 OK"] # Sometimes, even after the user has clicked 'exit' in the page, # a browser sends a request for e.g. an audio file. if self.is_shutting_down and filename != "/release_database": response_headers = [("Content-type", "text/html")] start_response("503 Service Unavailable", response_headers) return ["Server stopped"] # Load database if needed. if not self.is_mnemosyne_loaded and filename != "/release_database": self.load_mnemosyne() self.release_database_after_timeout.ping() # All our request return to the root page, so if the path is '/', # return the html of the review widget. if filename == "/": # Process clicked buttons in the form. form = cgi.FieldStorage(fp=environ["wsgi.input"], environ=environ) if "show_answer" in form and not self.is_just_started: self.mnemosyne.review_widget().show_answer() page = self.mnemosyne.review_widget().to_html() elif "grade" in form and not self.is_just_started: grade = int(form["grade"].value) self.mnemosyne.review_widget().grade_answer(grade) page = self.mnemosyne.review_widget().to_html() elif "star" in form: self.mnemosyne.controller().star_current_card() page = self.mnemosyne.review_widget().to_html() elif "exit" in form: self.unload_mnemosyne() page = "Server stopped" self.wsgi_server.stop() self.stop_server_after_timeout = \ StopServerAfterTimeout(self.wsgi_server) self.stop_server_after_timeout.start() self.is_shutting_down = True else: page = self.mnemosyne.review_widget().to_html() if self.is_just_started: self.is_just_started = False # Serve the web page. response_headers = [("Content-type", "text/html")] start_response("200 OK", response_headers) return [page] elif filename == "/release_database": self.unload_mnemosyne() response_headers = [("Content-type", "text/html")] start_response("200 OK", response_headers) return ["200 OK"] # We need to serve a media file. else: full_path = self.mnemosyne.database().media_dir() for word in filename.split("/"): full_path = os.path.join(full_path, word) request = Request(environ) # Check if file exists, but work around Android not reporting # the correct filesystem encoding. try: exists = os.path.exists(full_path) except (UnicodeEncodeError, UnicodeDecodeError): _ENCODING = sys.getfilesystemencoding() or \ locale.getdefaultlocale()[1] or "utf-8" full_path = full_path.encode(_ENCODING) if os.path.exists(full_path): etag = "%s-%s-%s" % (os.path.getmtime(full_path), os.path.getsize(full_path), hash(full_path)) else: etag = "none" app = FileApp(full_path, etag=etag) return app(request)(environ, start_response)
class TestCloze(MnemosyneTest): def setup(self): self.initialise_data_dir() path = os.path.join(os.getcwd(), "..", "mnemosyne", "libmnemosyne", "renderers") if path not in sys.path: sys.path.append(path) self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_cloze", "Widget")) self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \ [("mnemosyne_test", "TestReviewWidget")] self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.review_controller().reset() from mnemosyne.libmnemosyne.card_types.cloze import ClozePlugin for plugin in self.plugins(): if isinstance(plugin, ClozePlugin): plugin.activate() break def test_validate(self): card_type = self.card_type_with_id("5") fact_data = {"text": "incomplete"} assert card_type.is_fact_data_valid(fact_data) == False fact_data = {"text": "[incomplete"} assert card_type.is_fact_data_valid(fact_data) == False fact_data = {"text": "incomplete]"} assert card_type.is_fact_data_valid(fact_data) == False fact_data = {"text": "[]"} assert card_type.is_fact_data_valid(fact_data) == False fact_data = {"text": "[complete]"} assert card_type.is_fact_data_valid(fact_data) == True def test_add(self): card_type = self.card_type_with_id("5") fact_data = {"text": "a [b] c"} card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact card = self.database().cards_from_fact(fact)[0] assert self.database().fact_count() == 1 assert self.database().card_count() == 1 assert "div.b { text-align: center; }" in card.question() assert "div.b { text-align: center; }" in card.answer() def test_edit(self): card_type = self.card_type_with_id("5") fact_data = {"text": "a [b] [c]"} card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact card = self.database().cards_from_fact(fact)[0] assert self.database().fact_count() == 1 assert self.database().card_count() == 2 fact_data = {"text": "a_ [b_] [c_]"} self.controller().edit_card_and_sisters(card, fact_data, card_type, new_tag_names=["default2"], correspondence=[]) for c in self.database().cards_from_fact(fact): assert c.extra_data["cloze"] in c.fact["text"] assert self.database().fact_count() == 1 assert self.database().card_count() == 2 fact_data = {"text": "a_ [b_]"} self.controller().edit_card_and_sisters(card, fact_data, card_type, new_tag_names=["default2"], correspondence=[]) for c in self.database().cards_from_fact(fact): assert c.extra_data["cloze"] in c.fact["text"] assert self.database().fact_count() == 1 assert self.database().card_count() == 1 fact_data = {"text": "a_ [b_] [d] [e]"} self.controller().edit_card_and_sisters(card, fact_data, card_type, new_tag_names=["default2"], correspondence=[]) for c in self.database().cards_from_fact(fact): assert c.extra_data["cloze"] in c.fact["text"] assert self.database().fact_count() == 1 assert self.database().card_count() == 3 def test_convert(self): card_type = self.card_type_with_id("5") fact_data = {"text": "a [b] [c]"} card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact card = self.database().cards_from_fact(fact)[0] new_card_type = self.card_type_with_id("1") global answer answer = 0 # OK. self.controller().change_card_type([fact], card_type, new_card_type, {'text': 'f'}) assert self.database().fact_count() == 1 assert self.database().card_count() == 1 def test_convert_2(self): card_type = self.card_type_with_id("1") fact_data = {"f": "a [b] [c]"} card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact new_fact_data = {"text": "a [b] [c]"} new_card_type = self.card_type_with_id("5") global answer answer = 0 # OK. self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, ["default"], {"f": "text"}) def test_convert_3(self): card_type = self.card_type_with_id("2") fact_data = {"f": "a b c", "b": "back"} card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] # Make sure the card is not the last one in the database, such that # sqlite does not recycle its id. fact_data = {"f": "__a b c", "b": "__back"} self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact new_fact_data = {"text": "a [b] [c]"} new_card_type = self.card_type_with_id("5") global answer answer = 0 # OK. self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, ["default"], {"f": "text"}) def test_convert_abort(self): card_type = self.card_type_with_id("5") fact_data = {"text": "a [b] [c]"} card = self.controller().create_new_cards(fact_data, card_type, grade=5, tag_names=["default"])[0] fact = card.fact card = self.database().cards_from_fact(fact)[0] new_card_type = self.card_type_with_id("1") global answer answer = 1 # Cancel. self.controller().change_card_type([fact], card_type, new_card_type, {'text': 'f'}) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 def test_overlap(self): card_type = self.card_type_with_id("5") fact_data = {"text": "[as] [a]"} cards = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) fact = cards[0].fact assert "[...] a" in cards[0].question() assert "as [...]" in cards[1].question() fact_data = {"text": "[buds] [bud]"} self.controller().edit_card_and_sisters(cards[0], fact_data, card_type, new_tag_names=["default"], correspondence={}) cards = self.database().cards_from_fact(fact) assert "[...] bud" in cards[0].question() assert "buds [...]" in cards[1].question() def test_overlap_2(self): card_type = self.card_type_with_id("5") fact_data = {"text": "[as] [a]"} cards = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) fact = cards[0].fact assert "[...] a" in cards[0].question() assert "as [...]" in cards[1].question() fact_data = {"text": "[as] [bud]"} self.controller().edit_card_and_sisters(cards[0], fact_data, card_type, new_tag_names=["default"], correspondence={}) cards = self.database().cards_from_fact(fact) assert "[...] bud" in cards[0].question() assert "as [...]" in cards[1].question() def test_overlap_3(self): card_type = self.card_type_with_id("5") fact_data = {"text": "[as] [a]"} cards = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) fact = cards[0].fact assert "[...] a" in cards[0].question() assert "as [...]" in cards[1].question() fact_data = {"text": "[buds] [a]"} self.controller().edit_card_and_sisters(cards[0], fact_data, card_type, new_tag_names=["default"], correspondence={}) cards = self.database().cards_from_fact(fact) assert "[...] a" in cards[0].question() assert "buds [...]" in cards[1].question() def test_edit_2(self): card_type = self.card_type_with_id("5") fact_data = {"text": "[consumerist] lifestyles"} cards = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) fact = cards[0].fact fact_data = {"text": "[consumerism]"} self.controller().edit_card_and_sisters(cards[0], fact_data, card_type, new_tag_names=["default"], correspondence={}) cards = self.database().cards_from_fact(fact) question = cards[0].question() assert "[...]" in question assert "consumerism" not in question assert "consumerist" not in question assert "lifestyles" not in question def test_duplicate(self): card_type = self.card_type_with_id("5") fact_data = {"text": "[a] [a]"} cards = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) assert "[...] a" in cards[0].question() assert "a [...]" in cards[1].question() def test_henrik_1(self): card_type = self.card_type_with_id("5") fact_data = {"text": """I [1302] ble [Ingebjorg] (datteren til [Eufemia] og [Hakon V]) lovet bort til hertug [Erik] av [Sverige]. Hun var da [ett] ar gammel...."""} cards = self.controller().create_new_cards(fact_data, card_type, grade=3, tag_names=["default"]) next_reps = [] for card in cards: assert card.question().count("[") == 1 next_reps.append(card.next_rep) assert len(next_reps) == len(cards) def test_henrik_2(self): card_type = self.card_type_with_id("5") fact_data = {"text": """Since his death in [1992], [Francis Bacon]'s reputation has steadily grown. Despite [Margaret Thatcher] having famously described him as "that man who paints those [dreadful pictures]", he was the subject of two major [Tate retrospectives] during his lifetime and received a third in 2008"""} cards = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) for card in cards: assert card.question().count("[") == 1 def test_convert_many(self): card_type = self.card_type_with_id("5") fact_data = {"text": "[a] [b]"} cards = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) fact = cards[0].fact global answer answer = 0 # OK self.controller().change_card_type([fact], card_type, self.card_type_with_id("1"), correspondence={"text": "f"}) fact = self.database().fact(fact._id, is_id_internal=True) assert "text" not in fact.data assert "f" in fact.data def test_convert_many_cancel(self): card_type = self.card_type_with_id("5") fact_data = {"text": "[a] [b]"} cards = self.controller().create_new_cards(fact_data, card_type, grade=5, tag_names=["default"]) fact = cards[0].fact global answer answer = 1 # cancel self.controller().change_card_type([fact], card_type, self.card_type_with_id("1"), correspondence={"text": "f"}) fact = self.database().fact(fact._id, is_id_internal=True) assert "text" in fact.data assert "f" not in fact.data def test_hint(self): card_type = self.card_type_with_id("5") fact_data = {"text": """bla [cloze:hint]"""} card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] assert "cloze" not in card.question() assert "hint" in card.question() assert "cloze" in card.answer() assert "hint" not in card.answer() def test_hint_2(self): card_type = self.card_type_with_id("5") fact_data = {"text": """bla [cloze:hint] [other cloze:other_hint]"""} card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] assert "bla [hint] other cloze" in card.question() assert "other hint" not in card.question() def test_clone(self): card_type = self.card_type_with_id("5") card_type = self.controller().clone_card_type(\ card_type, ("5 clone")) fact_data = {"text": """bla [cloze:hint] [other cloze:other_hint]"""} card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] assert "bla [hint] other cloze" in card.question() assert "other hint" not in card.question() def test_latex(self): card_type = self.card_type_with_id("5") fact_data = {"text": """<$>[\mathbf{F}]=[q]([\mathbf{E}]+[\mathbf{v}\times\mathbf{B}]</$>"""} card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] assert "<img src" in card.answer() fact_data = {"text": """<$$>[\mathbf{F}]=[q]([\mathbf{E}]+[\mathbf{v}\times\mathbf{B}]</$$>"""} card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] assert "<img src" in card.answer() fact_data = {"text": """<latex>[\mathbf{F}]=[q]([\mathbf{E}]+[\mathbf{v}\times\mathbf{B}]</latex>"""} card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] assert "<img src" in card.answer() def test_latex_2(self): card_type = self.card_type_with_id("5") fact_data = {"text": """<$>[a]\\left[b\\right]</$>"""} cards = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) assert len(cards) == 1 card = cards[0] assert "<img src" in card.question() assert "<img src" in card.answer()
class TestController(MnemosyneTest): def setup(self): self.initialise_data_dir() self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_controller", "Widget")) self.mnemosyne.components.append(\ ("test_controller", "ExportWidget")) self.mnemosyne.components.append(\ ("test_controller", "DataWidget")) self.mnemosyne.components.append(\ ("mnemosyne_test", "TestReviewWidget")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "AddCardsDialog")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "EditCardDialog")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "BrowseCardsDialog")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "SyncDialog")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "ManagePluginsDialog")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "ManageCardTypesDialog")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "StatisticsDialog")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "ConfigurationDialog")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "ActivateCardsDialog")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "ImportDialog")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "TipDialog")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "GettingStartedDialog")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "AboutDialog")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.dialogs", "CompactDatabaseDialog")) self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.review_controller().reset() def test_coverage(self): global save_file os.path.join(os.getcwd(), "dot_test", "copy.db") self.controller().heartbeat() self.controller().show_add_cards_dialog() card_type = self.card_type_with_id("2") fact_data = {"f": "f", "b": "b"} card_1, card_2 = self.controller().create_new_cards( fact_data, card_type, grade=-1, tag_names=["default"]) self.review_controller().show_new_question() self.controller().show_edit_card_dialog() self.controller().show_new_file_dialog() self.controller().show_open_file_dialog() self.controller().show_save_file_as_dialog() self.controller().show_compact_database_dialog() self.controller().show_manage_plugins_dialog() self.controller().show_manage_card_types_dialog() self.controller().show_browse_cards_dialog() self.controller().show_configuration_dialog() self.controller().show_statistics_dialog() self.controller().show_activate_cards_dialog() self.controller().show_tip_dialog() self.controller().show_getting_started_dialog() self.controller().show_about_dialog() self.controller().show_download_source_dialog() self.controller().show_sync_dialog() def test_star(self): card_type = self.card_type_with_id("1") fact_data = {"f": "f", "b": "b"} card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.review_controller().show_new_question() self.controller().star_current_card() card = self.database().card(card._id, is_id_internal=True) assert "Starred" in card.tag_string() def test_2(self): self.controller().show_save_file_as_dialog() self.controller().show_open_file_dialog() def test_overwrite(self): global save_file os.path.join(os.getcwd(), "dot_test", "default.db") card_type = self.card_type_with_id("2") fact_data = {"f": "f", "b": "b"} card_1, card_2 = self.controller().create_new_cards( fact_data, card_type, grade=-1, tag_names=["default"]) self.controller().save_file() self.controller().show_new_file_dialog() def test_coverage_2(self): from mnemosyne.libmnemosyne.ui_components.main_widget import MainWidget w = MainWidget(self.mnemosyne.component_manager) w.show_information("") w.show_error("") w.set_status_bar_message("") self.controller().show_add_cards_dialog() self.controller().show_edit_card_dialog() self.controller().show_insert_sound_dialog("") self.controller().show_insert_video_dialog("") self.controller().show_insert_flash_dialog("") self.controller().show_download_source_dialog() self.controller().show_sync_dialog() self.controller().show_manage_plugins_dialog() self.controller().show_manage_card_types_dialog() self.controller().show_statistics_dialog() self.controller().show_configuration_dialog() self.controller().show_browse_cards_dialog() self.controller().show_activate_cards_dialog() self.controller().show_import_file_dialog() self.controller().show_export_file_dialog() self.controller().next_rollover = 0 self.controller().heartbeat() def test_delete_current(self): card_type = self.card_type_with_id("1") fact_data = {"f": "1", "b": "1"} self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=[]) fact_data = {"f": "2", "b": "2"} self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=[]) self.review_controller().show_new_question() self.review_controller().grade_answer(0) self.review_controller().grade_answer(0) self.review_controller().grade_answer(2) global answer answer = 0 self.controller().delete_current_card() def test_delete_current_2(self): card_type = self.card_type_with_id("1") fact_data = {"f": "1", "b": "1"} self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=[]) fact_data = {"f": "2", "b": "2"} self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=[]) self.review_controller().show_new_question() self.review_controller().grade_answer(0) self.review_controller().grade_answer(0) self.review_controller().grade_answer(0) self.review_controller().grade_answer(2) global answer answer = 0 self.controller().delete_current_card()
"DatabaseLogger"), ("mnemosyne.libmnemosyne.schedulers.SM2_mnemosyne", "SM2Mnemosyne"), ("mnemosyne.libmnemosyne.stopwatch", "Stopwatch"), ("mnemosyne.libmnemosyne.card_types.front_to_back", "FrontToBack"), ("mnemosyne.libmnemosyne.card_types.both_ways", "BothWays"), ("mnemosyne.libmnemosyne.card_types.vocabulary", "Vocabulary"), ("mnemosyne.libmnemosyne.controllers.default_controller", "DefaultController"), ("mnemosyne.libmnemosyne.review_controllers.SM2_controller", "SM2Controller"), ("mnemosyne.libmnemosyne.card_types.map", "MapPlugin"), ("mnemosyne.libmnemosyne.card_types.cloze", "ClozePlugin"), ("mnemosyne.libmnemosyne.criteria.default_criterion", "DefaultCriterion"), ("mnemosyne.libmnemosyne.databases.SQLite_criterion_applier", "DefaultCriterionApplier") ] # Run Mnemosyne. mnemosyne.initialise(data_dir=data_dir) mnemosyne.start_review() app.mainframe = mnemosyne.main_widget() app.run() mnemosyne.finalise()
class TestSentence(MnemosyneTest): def setup(self): self.initialise_data_dir() self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_cloze", "Widget")) self.mnemosyne.components.append(\ ("mnemosyne_test", "TestReviewWidget")) self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.review_controller().reset() from mnemosyne.libmnemosyne.card_types.sentence import SentencePlugin for plugin in self.plugins(): if isinstance(plugin, SentencePlugin): plugin.activate() break def test_1(self): card_type = self.card_type_with_id("6") fact_data = {"f": "La [casa:house] es [grande:big]"} cards = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) assert "La casa es grande" in cards[0].question() assert "La [house] es grande" in cards[1].question() assert "La casa es [big]" in cards[2].question() def test_2(self): card_type = self.card_type_with_id("6") fact_data = {"f": "[sentence]", "m_1": "meaning"} cards = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) assert "meaning" in cards[1].question() assert "[" not in cards[1].question() assert "meaning" not in cards[1].answer() def test_edit(self): card_type = self.card_type_with_id("6") fact_data = {"f": "La [casa:house] es [grande:big]"} cards = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) fact = cards[0].fact fact_data = {"f": "[La casa es grande]"} self.controller().edit_card_and_sisters(cards[0], fact_data, card_type, new_tag_names=["default"], correspondence={}) cards = self.database().cards_from_fact(fact) assert len(cards) == 2 def test_edit_2(self): card_type = self.card_type_with_id("6") fact_data = {"f": "La [casa:house] es [grande:big]"} cards = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) fact = cards[0].fact fact_data = {"f": "[La casa] es grande"} self.controller().edit_card_and_sisters(cards[0], fact_data, card_type, new_tag_names=["default"], correspondence={}) cards = self.database().cards_from_fact(fact) assert len(cards) == 2 def test_edit_3(self): card_type = self.card_type_with_id("6") fact_data = {"f": "La [casa:house] es [grande:big]"} cards = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) fact = cards[0].fact fact_data = {"f": "[La casa] [es] [grande]"} self.controller().edit_card_and_sisters(cards[0], fact_data, card_type, new_tag_names=["default"], correspondence={}) cards = self.database().cards_from_fact(fact) assert len(cards) == 4 for card in cards: assert card.card_type.id == "6" for card in cards[1:]: assert card.fact_view.id == "6.2" def test_clone(self): card_type = self.card_type_with_id("6") card_type = self.controller().clone_card_type(\ card_type, ("6 clone")) fact_data = {"f": "La [casa:house] es [grande:big]"} cards = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) assert "La casa es grande" in cards[0].question() assert "La [house] es grande" in cards[1].question() assert "La casa es [big]" in cards[2].question()
class WebServer(Component): def __init__(self, port, data_dir, config_dir, filename, **kwds): if "client_on_same_machine_as_server" in kwds: self.client_on_same_machine_as_server = \ kwds["client_on_same_machine_as_server"] del kwds["client_on_same_machine_as_server"] else: self.client_on_same_machine_as_server = False super().__init__(**kwds) self.wsgi_server = None self.port = port self.data_dir = data_dir self.config_dir = config_dir self.filename = filename # When restarting the server, make sure we discard info from the # browser resending the form from the previous session. self.is_just_started = True self.is_mnemosyne_loaded = False self.is_shutting_down = False def activate(self): Component.activate(self) # Late import to speed up application startup. from cheroot import wsgi self.wsgi_server = wsgi.Server(\ ("0.0.0.0", self.port), self.wsgi_app, server_name="localhost", numthreads=1, timeout=5) # We need to set the timeout relatively low, otherwise it will take # too long for the server to process a 'stop' request. def serve_until_stopped(self): try: self.wsgi_server.start() # Sets self.wsgi_server.ready except KeyboardInterrupt: self.wsgi_server.stop() self.unload_mnemosyne() def stop(self): if self.wsgi_server: self.wsgi_server.stop() self.unload_mnemosyne() def load_mnemosyne(self): self.mnemosyne = Mnemosyne(upload_science_logs=True, interested_in_old_reps=True) self.mnemosyne.components.insert( 0, (("mnemosyne.libmnemosyne.gui_translators.gettext_gui_translator", "GetTextGuiTranslator"))) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.main_widget", "MainWidget")) self.mnemosyne.components.append(\ ("mnemosyne.web_server.web_server_render_chain", "WebServerRenderChain")) self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = [\ ("mnemosyne.web_server.review_wdgt", "ReviewWdgt")] self.mnemosyne.gui_for_component["NewOnly"] = [\ ("mnemosyne.web_server.review_wdgt", "ReviewWdgt")] self.mnemosyne.gui_for_component["CramAll"] = [\ ("mnemosyne.web_server.review_wdgt", "ReviewWdgt")] self.mnemosyne.gui_for_component["CramRecent"] = [\ ("mnemosyne.web_server.review_wdgt", "ReviewWdgt")] self.mnemosyne.initialise(self.data_dir, config_dir=self.config_dir, filename=self.filename, automatic_upgrades=False) self.save_after_n_reps = self.mnemosyne.config()["save_after_n_reps"] self.mnemosyne.config()["save_after_n_reps"] = 1 self.mnemosyne.config()["study_mode"] = "ScheduledForgottenNew" self.mnemosyne.config()["QA_split"] = "fixed" self.mnemosyne.review_widget().set_client_on_same_machine_as_server(\ self.client_on_same_machine_as_server) self.mnemosyne.controller().reset_study_mode() self.is_mnemosyne_loaded = True self.release_database_after_timeout = \ ReleaseDatabaseAfterTimeout(self.port) self.release_database_after_timeout.start() def unload_mnemosyne(self): if not self.is_mnemosyne_loaded: return self.mnemosyne.config()["save_after_n_reps"] = self.save_after_n_reps self.mnemosyne.finalise() self.is_mnemosyne_loaded = False def wsgi_app(self, environ, start_response): filename = environ["PATH_INFO"] if filename == "/status": response_headers = [("Content-type", "text/html")] start_response("200 OK", response_headers) return [b"200 OK"] # Sometimes, even after the user has clicked 'exit' in the page, # a browser sends a request for e.g. an audio file. if self.is_shutting_down and filename != "/release_database": response_headers = [("Content-type", "text/html")] start_response("503 Service Unavailable", response_headers) return [b"Server stopped"] # Load database if needed. if not self.is_mnemosyne_loaded and filename != "/release_database": self.load_mnemosyne() self.release_database_after_timeout.ping() # All our request return to the root page, so if the path is '/', # return the html of the review widget. if filename == "/": # Process clicked buttons in the form. form = cgi.FieldStorage(fp=environ["wsgi.input"], environ=environ) if "show_answer" in form and not self.is_just_started: self.mnemosyne.review_widget().show_answer() page = self.mnemosyne.review_widget().to_html() elif "grade" in form and not self.is_just_started: grade = int(form["grade"].value) self.mnemosyne.review_widget().grade_answer(grade) page = self.mnemosyne.review_widget().to_html() elif "star" in form: self.mnemosyne.controller().star_current_card() page = self.mnemosyne.review_widget().to_html() elif "exit" in form: self.unload_mnemosyne() page = "Server stopped" self.wsgi_server.stop() self.stop_server_after_timeout = \ StopServerAfterTimeout(self.wsgi_server) self.stop_server_after_timeout.start() self.is_shutting_down = True else: page = self.mnemosyne.review_widget().to_html() if self.is_just_started: self.is_just_started = False # Serve the web page. response_headers = [("Content-type", "text/html")] start_response("200 OK", response_headers) return [page] elif filename == "/release_database": self.unload_mnemosyne() response_headers = [("Content-type", "text/html")] start_response("200 OK", response_headers) return [b"200 OK"] # We need to serve a media file. else: # Late import to speed up application startup. from webob import Request from webob.static import FileApp full_path = self.mnemosyne.database().media_dir() for word in filename.split("/"): full_path = os.path.join(full_path, word) request = Request(environ) if os.path.exists(full_path): etag = "%s-%s-%s" % (os.path.getmtime(full_path), os.path.getsize(full_path), hash(full_path)) else: etag = "none" app = FileApp(full_path, etag=etag) return app(request)(environ, start_response)
class TestCardType(MnemosyneTest): def setup(self): self.initialise_data_dir() self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator") ) self.mnemosyne.components.append(("test_card_type", "DecoratedThreeSided")) self.mnemosyne.components.append(("test_card_type", "Widget")) self.mnemosyne.components.append(("mnemosyne_test", "TestReviewWidget")) self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.review_controller().reset() def test_card_types(self): card_type = self.card_type_with_id("1") assert self.database().is_in_use(card_type) is False assert card_type.fact_key_with_name("Front") == "f" assert card_type.is_fact_data_valid({"f": "foo"}) == True assert self.card_type_with_id("1") == self.card_type_with_id("1") assert self.card_type_with_id("1") != None def test_database(self): card_type = self.card_type_with_id("1") card_type.fact_views[0].type_answer = True card_type.fact_views[0].extra_data = {"b": "b"} card_type = self.controller().clone_card_type(card_type, ("1 clone")) card_type.extra_data = {"b": "b"} self.database().update_card_type(card_type) self.mnemosyne.component_manager.unregister(card_type) card_type_out = self.database().card_type(card_type.id, is_id_internal=False) assert card_type_out.id == "1::1 clone" assert card_type_out.fact_key_with_name("Front") == "f" assert card_type_out.required_fact_keys == ["f"] assert card_type_out.is_fact_data_valid({"f": "foo"}) == True assert card_type_out.is_fact_data_valid({"q": "foo"}) == False assert card_type_out.fact_key_names() == ["Front", "Back"] assert card_type_out.fact_keys_and_names == card_type.fact_keys_and_names assert card_type_out.unique_fact_keys == card_type.unique_fact_keys assert card_type_out.keyboard_shortcuts == card_type.keyboard_shortcuts assert card_type_out.fact_views[0].type_answer == True assert card_type_out.fact_views[0].extra_data == {"b": "b"} assert card_type_out.extra_data == {"b": "b"} assert len(card_type.fact_views) == 1 assert len(card_type_out.fact_views) == 1 assert card_type_out.fact_views[0].id == card_type.fact_views[0].id assert card_type_out.fact_views[0].name == card_type.fact_views[0].name assert card_type_out.fact_views[0].q_fact_keys == card_type.fact_views[0].q_fact_keys assert card_type_out.fact_views[0].a_fact_keys == card_type.fact_views[0].a_fact_keys assert card_type_out.fact_views[0].a_on_top_of_q == card_type.fact_views[0].a_on_top_of_q # Reset global variables. self.mnemosyne.component_manager.register(card_type) card_type = self.card_type_with_id("1") card_type.fact_views[0].type_answer = False card_type.fact_views[0].extra_data = {} card_type_orig = self.database().card_type("1", is_id_internal=False) assert card_type_orig.fact_views[0].type_answer == False def test_rename_two_clones(self): card_type = self.card_type_with_id("1") card_type_1 = self.controller().clone_card_type(card_type, "1 clone") card_type = self.card_type_with_id("2") card_type_2 = self.controller().clone_card_type(card_type, "2 clone") self.controller().rename_card_type(card_type_1, "1 clone new") assert set([c.name for c in self.card_types() if self.database().is_user_card_type(c)]) == set( ["1 clone new", "2 clone"] ) def test_rename_two_clones_b(self): card_type = self.card_type_with_id("1") card_type_1 = self.controller().clone_card_type(card_type, "1 clone") card_type = self.card_type_with_id("2") card_type_2 = self.controller().clone_card_type(card_type, "2 clone") self.controller().rename_card_type(card_type_2, "2 clone new") assert set([c.name for c in self.card_types() if self.database().is_user_card_type(c)]) == set( ["1 clone", "2 clone new"] ) def test_delete(self): card_type = self.card_type_with_id("1") card_type_1 = self.controller().clone_card_type(card_type, "1 clone") card_type = self.card_type_with_id("2") card_type_2 = self.controller().clone_card_type(card_type, "2 clone") self.controller().delete_card_type(card_type_1) card_type_out = self.database().card_type(card_type_2.id, is_id_internal=False) assert card_type_out.fact_views[0].id == card_type_2.fact_views[0].id assert card_type_out.fact_views[0].name == card_type_2.fact_views[0].name assert card_type_out.fact_views[0].q_fact_keys == card_type_2.fact_views[0].q_fact_keys assert card_type_out.fact_views[0].a_fact_keys == card_type_2.fact_views[0].a_fact_keys assert card_type_out.fact_views[0].a_on_top_of_q == card_type_2.fact_views[0].a_on_top_of_q assert card_type_out.fact_views[1].id == card_type_2.fact_views[1].id assert card_type_out.fact_views[1].name == card_type_2.fact_views[1].name assert card_type_out.fact_views[1].q_fact_keys == card_type_2.fact_views[1].q_fact_keys assert card_type_out.fact_views[1].a_fact_keys == card_type_2.fact_views[1].a_fact_keys assert card_type_out.fact_views[1].a_on_top_of_q == card_type_2.fact_views[1].a_on_top_of_q def test_delete_with_formatting(self): card_type = self.card_type_with_id("1") card_type_1 = self.controller().clone_card_type(card_type, "1 clone") card_type = self.card_type_with_id("2") card_type_2 = self.controller().clone_card_type(card_type, "2 clone") self.config().set_card_type_property("background_colour", "black", card_type_1) self.controller().delete_card_type(card_type_1) def test_cannot_delete(self): global last_error last_error = None card_type = self.card_type_with_id("1") self.controller().delete_card_type(card_type) assert "in use" in last_error last_error = None card_type_1 = self.controller().clone_card_type(card_type, "1 clone") card_type = self.card_type_with_id("2") card_type_2 = self.controller().clone_card_type(card_type, "2 clone") fact_data = {"f": "question", "b": "answer"} old_card = self.controller().create_new_cards(fact_data, card_type_1, grade=-1, tag_names=["default"])[0] self.controller().delete_card_type(card_type_1) assert "in use" in last_error last_error = None def test_rename(self): card_type = self.card_type_with_id("1") card_type_1 = self.controller().clone_card_type(card_type, "1 clone") self.controller().rename_card_type(card_type_1, "newname") card_type_out = self.database().card_type(card_type_1.id, is_id_internal=False) assert card_type_out.name == "newname" def test_cannot_rename(self): global last_error last_error = None card_type = self.card_type_with_id("1") self.controller().rename_card_type(card_type, "newname") assert last_error.startswith("Cannot rename") last_error = None def test_cannot_rename_duplicate(self): global last_error last_error = None card_type = self.card_type_with_id("1") card_type_1 = self.controller().clone_card_type(card_type, "1 clone") self.controller().rename_card_type(card_type_1, "Vocabulary") assert "in use" in last_error last_error = None def test_has_clones(self): global last_error last_error = None card_type = self.card_type_with_id("1") assert self.database().has_clones(card_type) == False card_type_1 = self.controller().clone_card_type(card_type, "1 clone") card_type_2 = self.controller().clone_card_type(card_type_1, "1 clone clone") assert self.database().has_clones(card_type) == True assert self.database().has_clones(card_type_1) == True self.controller().delete_card_type(card_type_1) assert "clone" in last_error last_error = None def test_clone_of_clone(self): card_type = self.card_type_with_id("1") assert self.database().is_user_card_type(card_type) == False card_type.fact_views[0].type_answer = True card_type.fact_views[0].extra_data = {"b": "b"} card_type = self.controller().clone_card_type(card_type, ("1 clone")) assert self.database().is_user_card_type(card_type) == True card_type = self.controller().clone_card_type(card_type, ("1 clone cloned")) assert self.database().is_user_card_type(card_type) == True card_type.extra_data = {"b": "b"} self.database().update_card_type(card_type) self.mnemosyne.component_manager.unregister(card_type) card_type_out = self.database().card_type(card_type.id, is_id_internal=False) assert card_type_out.fact_key_with_name("Front") == "f" assert card_type_out.required_fact_keys == ["f"] assert card_type_out.is_fact_data_valid({"f": "foo"}) == True assert card_type_out.fact_keys_and_names == card_type.fact_keys_and_names assert card_type_out.unique_fact_keys == card_type.unique_fact_keys assert card_type_out.keyboard_shortcuts == card_type.keyboard_shortcuts assert card_type_out.fact_views[0].type_answer == True assert card_type_out.fact_views[0].extra_data == {"b": "b"} assert card_type_out.extra_data == {"b": "b"} assert len(card_type.fact_views) == 1 assert len(card_type_out.fact_views) == 1 assert card_type_out.fact_views[0].id == card_type.fact_views[0].id assert card_type_out.fact_views[0].name == card_type.fact_views[0].name assert card_type_out.fact_views[0].q_fact_keys == card_type.fact_views[0].q_fact_keys assert card_type_out.fact_views[0].a_fact_keys == card_type.fact_views[0].a_fact_keys assert card_type_out.fact_views[0].a_on_top_of_q == card_type.fact_views[0].a_on_top_of_q # Reset global variables. self.mnemosyne.component_manager.register(card_type) card_type.fact_views[0].type_answer = False card_type.fact_views[0].extra_data = {} fact_data = {"f": "question", "b": "answer"} card = self.mnemosyne.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] path = self.mnemosyne.database().path() self.mnemosyne.database().unload() self.mnemosyne.database().load(path) def test_decorators(self): fact_data = {"f": "foreign word", "p_1": "pronunciation", "m_1": "translation"} card_type = self.card_type_with_id("3_decorated") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] assert "What is the translation of foreign word?" in card.question() def test_properties(self): card_type = self.card_type_with_id("1") self.config().set_card_type_property("font", "myfont", card_type) self.config().set_card_type_property("background_colour", "mycolour", card_type) card_type = self.controller().clone_card_type(card_type, ("1 clone")) assert self.config().card_type_property("font", card_type, "f") == "myfont" assert self.config().card_type_property("background_colour", card_type) == "mycolour"
def startup(): import gettext _ = gettext.gettext import os import sys from optparse import OptionParser from PyQt5.QtGui import QApplication from mnemosyne.libmnemosyne import Mnemosyne # Parse options. parser = OptionParser() parser.usage = "%prog [<database_file>]" parser.add_option("-d", "--datadir", dest="data_dir", help=_("data directory"), default=None) (options, args) = parser.parse_args() # Check if we have to override the data_dir determined in libmnemosyne, # either because we explicitly specified a data_dir on the command line, # or because there is a mnemosyne2 directory present in the current directory. # The latter is handy when Mnemosyne is run from a USB key, so that there # is no need to refer to a drive letter which can change from computer to # computer. data_dir = None if options.data_dir != None: data_dir = os.path.abspath(options.data_dir) elif os.path.exists(os.path.join(os.getcwd(), "mnemosyne2")): data_dir = os.path.abspath(os.path.join(os.getcwd(), "mnemosyne2")) # Filename argument. if len(args) > 0: filename = os.path.abspath(args[0]) else: filename = None # Load the Mnemosyne library. mnemosyne = Mnemosyne(upload_science_logs=True) # Initialise GUI toolkit. a = QApplication(sys.argv) a.setApplicationName("Mnemosyne") # TODO: install translator for Qt messages. # Under Windows, move out of library.zip to get the true prefix. # from mnemosyne.pyqt_ui.main_window import prefix #if sys.platform == "win32": # prefix = os.path.split(prefix)[0] # prefix = os.path.split(prefix)[0] # prefix = os.path.split(prefix)[0] #translator = QTranslator(a) #translator.load("qt_" + loc + ".qm", os.path.join(prefix, 'locale')) #a.installTranslator(translator) # Add other components we need. The translator should obviously come first, # and the UI components should come in the order they should be instantiated, # but apart from that, the order does not matter. mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.translator", "GetTextTranslator")) mnemosyne.components.append(("mnemosyne.pyqt_ui.main_wdgt", "MainWdgt")) mnemosyne.components.append( ("mnemosyne.pyqt_ui.review_wdgt", "ReviewWdgt")) mnemosyne.components.append( ("mnemosyne.pyqt_ui.configuration", "PyQtConfiguration")) mnemosyne.components.append( ("mnemosyne.pyqt_ui.pyqt_render_chain", "PyQtRenderChain")) mnemosyne.components.append( ("mnemosyne.pyqt_ui.add_cards_dlg", "AddCardsDlg")) mnemosyne.components.append( ("mnemosyne.pyqt_ui.edit_card_dlg", "EditCardDlg")) mnemosyne.components.append( ("mnemosyne.pyqt_ui.browse_cards_dlg", "BrowseCardsDlg")) mnemosyne.components.append( ("mnemosyne.pyqt_ui.activate_cards_dlg", "ActivateCardsDlg")) mnemosyne.components.append( ("mnemosyne.pyqt_ui.cloned_card_types_list_dlg", "ClonedCardTypesListDlg")) mnemosyne.components.append( ("mnemosyne.pyqt_ui.card_appearance_dlg", "CardAppearanceDlg")) mnemosyne.components.append( ("mnemosyne.pyqt_ui.activate_plugins_dlg", "ActivatePluginsDlg")) mnemosyne.components.append( ("mnemosyne.pyqt_ui.statistics_dlg", "StatisticsDlg")) mnemosyne.components.append( ("mnemosyne.pyqt_ui.card_type_wdgt_generic", "GenericCardTypeWdgt")) mnemosyne.components.append( ("mnemosyne.pyqt_ui.statistics_wdgts_plotting", "ScheduleWdgt")) mnemosyne.components.append( ("mnemosyne.pyqt_ui.statistics_wdgts_plotting", "RetentionScoreWdgt")) mnemosyne.components.append( ("mnemosyne.pyqt_ui.statistics_wdgts_plotting", "GradesWdgt")) mnemosyne.components.append( ("mnemosyne.pyqt_ui.statistics_wdgts_plotting", "EasinessWdgt")) mnemosyne.components.append( ("mnemosyne.pyqt_ui.statistics_wdgts_plotting", "CardsAddedWdgt")) mnemosyne.components.append( ("mnemosyne.pyqt_ui.statistics_wdgt_html", "HtmlStatisticsWdgt")) mnemosyne.components.append( ("mnemosyne.pyqt_ui.criterion_wdgt_default", "DefaultCriterionWdgt")) mnemosyne.components.append( ("mnemosyne.pyqt_ui.configuration_dlg", "ConfigurationDlg")) mnemosyne.components.append(("mnemosyne.pyqt_ui.sync_dlg", "SyncDlg")) mnemosyne.components.append( ("mnemosyne.pyqt_ui.qt_sync_server", "QtSyncServer")) mnemosyne.components.append( ("mnemosyne.pyqt_ui.configuration_wdgt_main", "ConfigurationWdgtMain")) mnemosyne.components.append( ("mnemosyne.pyqt_ui.configuration_wdgt_sync_server", "ConfigurationWdgtSyncServer")) # Run Mnemosyne. mnemosyne.initialise(data_dir=data_dir, filename=filename) mnemosyne.main_widget().show() mnemosyne.main_widget().raise_() # Needed for OSX. # TODO: check first run wizard. #if config()["first_run"] == True: # w.productTour() # config()["first_run"] = False #elif config()["show_daily_tips"] == True: # w.Tip() a.exec_() mnemosyne.finalise()
class TestCrammingScheduler(MnemosyneTest): def setup(self): self.initialise_data_dir() self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_cramming", "Widget")) self.mnemosyne.components.append(\ ("mnemosyne_test", "TestReviewWidget")) self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) from mnemosyne.libmnemosyne.plugins.cramming_plugin import CrammingPlugin for plugin in self.plugins(): if isinstance(plugin, CrammingPlugin): plugin.activate() break self.mnemosyne.start_review() def test_1(self): from mnemosyne.libmnemosyne.schedulers.cramming import Cramming card_type = self.card_type_with_id("1") fact_data = {"f": "1", "b": "b"} card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact_data = {"f": "2", "b": "b"} card_2 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact_data = {"f": "3", "b": "b"} card_3 = self.controller().create_new_cards(fact_data, card_type, grade=2, tag_names=["default"])[0] fact_data = {"f": "4", "b": "b"} card_4 = self.controller().create_new_cards(fact_data, card_type, grade=2, tag_names=["default"])[0] card_4.next_rep -= 1000 self.database().update_card(card_4) self.review_controller().start_review() assert self.database().scheduler_data_count(Cramming.UNSEEN) == 4 assert self.database().scheduler_data_count(Cramming.WRONG) == 0 self.review_controller().grade_answer(0) assert self.database().scheduler_data_count(Cramming.UNSEEN) == 3 assert self.database().scheduler_data_count(Cramming.WRONG) == 1 self.review_controller().grade_answer(5) assert self.database().scheduler_data_count(Cramming.UNSEEN) == 2 assert self.database().scheduler_data_count(Cramming.WRONG) == 1 # Fail the cards a couple of times. for i in range(8): self.review_controller().grade_answer(0) # Pass the cards a couple of times. for i in range(8): self.review_controller().grade_answer(5) def test_reset(self): from mnemosyne.libmnemosyne.schedulers.cramming import Cramming card_type = self.card_type_with_id("1") fact_data = {"f": "1", "b": "b"} card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact_data = {"f": "2", "b": "b"} card_2 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact_data = {"f": "3", "b": "b"} card_3 = self.controller().create_new_cards(fact_data, card_type, grade=2, tag_names=["default"])[0] fact_data = {"f": "4", "b": "b"} card_4 = self.controller().create_new_cards(fact_data, card_type, grade=2, tag_names=["default"])[0] card_4.next_rep -= 1000 self.database().update_card(card_4) self.review_controller().start_review() assert self.database().scheduler_data_count(Cramming.UNSEEN) == 4 assert self.database().scheduler_data_count(Cramming.WRONG) == 0 assert self.review_controller().counters() == (0, 4, 4) self.review_controller().grade_answer(0) assert self.database().scheduler_data_count(Cramming.UNSEEN) == 3 assert self.database().scheduler_data_count(Cramming.WRONG) == 1 assert self.review_controller().counters() == (1, 3, 4) self.review_controller().reset_but_try_to_keep_current_card() self.review_controller().update_dialog(redraw_all=True) assert self.database().scheduler_data_count(Cramming.UNSEEN) == 3 assert self.database().scheduler_data_count(Cramming.WRONG) == 1 assert self.review_controller().counters() == (1, 3, 4) def test_2(self): card_type = self.card_type_with_id("1") fact_data = {"f": "1", "b": "b"} card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.review_controller().show_new_question() self.controller().delete_current_card() assert self.review_controller().card == None def test_3(self): card_type = self.card_type_with_id("1") fact_data = {"f": "1", "b": "b"} card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.review_controller().show_new_question() self.review_controller().show_answer() self.review_controller().grade_answer(0) self.review_controller().counters() self.mnemosyne.finalise() self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_cramming", "Widget")) self.mnemosyne.components.append(\ ("mnemosyne_test", "TestReviewWidget")) self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.mnemosyne.start_review() assert self.scheduler().name == "cramming" def test_4(self): card_type = self.card_type_with_id("1") fact_data = {"f": "1", "b": "b"} card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.review_controller().show_new_question() self.database().unload() self.review_controller().reset() self.restart()
class MnemosyneTest(): def initialise_data_dir(self, data_dir="dot_test"): # Creating a new database seems a very time-consuming operation, # so we don't delete the test directory everytime, but take a short # cut. # Note: disabled this, as it does not seem to be very reliable. if os.path.exists(data_dir): shutil.rmtree(data_dir) assert not os.path.exists(data_dir) return if os.path.exists(data_dir): shutil.copy(os.path.join("mnemosyne", "tests", "files", "empty.db"), os.path.join(data_dir, "default.db")) for directory in ["default.db_media", "plugins", "backups", "history"]: full_path = str(os.path.join(data_dir, directory)) if os.path.exists(full_path): shutil.rmtree(full_path) for file in ["default.db-journal", "config", "config.py", "machine.id", "log.txt"]: full_path = str(os.path.join(data_dir, file)) if os.path.exists(full_path): os.remove(full_path) def setup(self): self.initialise_data_dir() self.restart() def restart(self): # If there is another Mnemosyne still running, finalise it so as to # avoid having multiple component_managers active. if hasattr(self, "mnemosyne"): try: self.mnemosyne.finalise() except: pass path = os.path.join(os.getcwd(), "..", "mnemosyne", "libmnemosyne", "renderers") if path not in sys.path: sys.path.append(path) self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.gui_translators.gettext_gui_translator", "GetTextGuiTranslator")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.main_widget", "MainWidget")) self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \ [("mnemosyne_test", "TestReviewWidget")] self.mnemosyne.gui_for_component["CramAll"] = \ [("mnemosyne_test", "TestReviewWidget")] self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.mnemosyne.start_review() def teardown(self): try: self.mnemosyne.finalise() # Avoid having multiple component_managers active. from mnemosyne.libmnemosyne.component_manager import clear_component_managers clear_component_managers() except: # Can throw some errors when we artificially mutilate plugins. self.mnemosyne.database().abandon() def config(self): return self.mnemosyne.component_manager.current("config") def log(self): return self.mnemosyne.component_manager.current("log") def database(self): return self.mnemosyne.component_manager.current("database") def scheduler(self): return self.mnemosyne.component_manager.current("scheduler") def main_widget(self): return self.mnemosyne.component_manager.current("main_widget") def review_widget(self): return self.mnemosyne.component_manager.current("review_widget") def controller(self): return self.mnemosyne.component_manager.current("controller") def review_controller(self): return self.mnemosyne.component_manager.current("review_controller") def card_types(self): return self.mnemosyne.component_manager.all("card_type") def filters(self): return self.mnemosyne.component_manager.all("filter") def plugins(self): return self.mnemosyne.component_manager.all("plugin") def render_chain(self, id="default"): return self.mnemosyne.component_manager.render_chain_with_id[id] def card_type_with_id(self, id): return self.mnemosyne.component_manager.card_type_with_id[id]
class TestCrammingScheduler(MnemosyneTest): def setup(self): os.system("rm -fr dot_test") self.mnemosyne = Mnemosyne() self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_cramming", "Widget")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.review_widget", "ReviewWidget")) self.mnemosyne.initialise(os.path.abspath("dot_test")) from mnemosyne.libmnemosyne.plugins.cramming_plugin import CrammingPlugin for plugin in self.plugins(): if isinstance(plugin, CrammingPlugin): plugin.activate() break self.review_controller().reset() def test_1(self): from mnemosyne.libmnemosyne.schedulers.cramming import Cramming card_type = self.card_type_by_id("1") fact_data = {"q": "1", "a": "a"} card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact_data = {"q": "2", "a": "a"} card_2 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact_data = {"q": "3", "a": "a"} card_3 = self.controller().create_new_cards(fact_data, card_type, grade=2, tag_names=["default"])[0] fact_data = {"q": "4", "a": "a"} card_4 = self.controller().create_new_cards(fact_data, card_type, grade=2, tag_names=["default"])[0] card_4.next_rep -= 1000 self.database().update_card(card_4) assert self.database().scheduler_data_count(Cramming.UNSEEN) == 4 assert self.database().scheduler_data_count(Cramming.WRONG) == 0 card = self.scheduler().get_next_card() self.scheduler().grade_answer(card, 0) self.database().update_card(card) assert self.database().scheduler_data_count(Cramming.UNSEEN) == 3 assert self.database().scheduler_data_count(Cramming.WRONG) == 1 card = self.scheduler().get_next_card() self.scheduler().grade_answer(card, 5) self.database().update_card(card) assert self.database().scheduler_data_count(Cramming.UNSEEN) == 2 assert self.database().scheduler_data_count(Cramming.WRONG) == 1 # Fail the cards a couple of times. for i in range(8): card = self.scheduler().get_next_card() self.scheduler().grade_answer(card, 0) self.database().update_card(card) # Pass the cards a couple of times. for i in range(8): card = self.scheduler().get_next_card() self.scheduler().grade_answer(card, 5) self.database().update_card(card) def test_2(self): card_type = self.card_type_by_id("1") fact_data = {"q": "1", "a": "a"} card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.review_controller().new_question() self.controller().delete_current_fact() assert self.review_controller().card == None def test_3(self): card_type = self.card_type_by_id("1") fact_data = {"q": "1", "a": "a"} card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.review_controller().new_question() self.mnemosyne.finalise() self.mnemosyne.initialise(os.path.abspath("dot_test")) assert self.scheduler().name == "cramming" def test_4(self): card_type = self.card_type_by_id("1") fact_data = {"q": "1", "a": "a"} card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.review_controller().new_question() self.database().unload() self.review_controller().reset() self.restart()
class TestCrammingScheduler(MnemosyneTest): def setup(self): self.initialise_data_dir() path = os.path.join(os.getcwd(), "..", "mnemosyne", "libmnemosyne", "renderers") if path not in sys.path: sys.path.append(path) self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_cramming", "Widget")) self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \ [("mnemosyne_test", "TestReviewWidget")] self.mnemosyne.gui_for_component["CramAll"] = \ [("mnemosyne_test", "TestReviewWidget")] self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.config()["study_mode"] = "CramAll" self.mnemosyne.start_review() def test_1(self): from mnemosyne.libmnemosyne.schedulers.cramming import Cramming card_type = self.card_type_with_id("1") fact_data = {"f": "1", "b": "b"} card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact_data = {"f": "2", "b": "b"} card_2 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact_data = {"f": "3", "b": "b"} card_3 = self.controller().create_new_cards(fact_data, card_type, grade=2, tag_names=["default"])[0] fact_data = {"f": "4", "b": "b"} card_4 = self.controller().create_new_cards(fact_data, card_type, grade=2, tag_names=["default"])[0] card_4.next_rep -= 1000 self.database().update_card(card_4) self.review_controller().reset() assert self.database().scheduler_data_count(Cramming.UNSEEN) == 4 assert self.database().scheduler_data_count(Cramming.WRONG) == 0 self.review_controller().grade_answer(0) assert self.database().scheduler_data_count(Cramming.UNSEEN) == 3 assert self.database().scheduler_data_count(Cramming.WRONG) == 1 self.review_controller().grade_answer(5) assert self.database().scheduler_data_count(Cramming.UNSEEN) == 2 assert self.database().scheduler_data_count(Cramming.WRONG) == 1 # Fail the cards a couple of times. for i in range(8): self.review_controller().grade_answer(0) # Pass the cards a couple of times. for i in range(8): self.review_controller().grade_answer(5) def test_reset(self): from mnemosyne.libmnemosyne.schedulers.cramming import Cramming card_type = self.card_type_with_id("1") fact_data = {"f": "1", "b": "b"} card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact_data = {"f": "2", "b": "b"} card_2 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact_data = {"f": "3", "b": "b"} card_3 = self.controller().create_new_cards(fact_data, card_type, grade=2, tag_names=["default"])[0] fact_data = {"f": "4", "b": "b"} card_4 = self.controller().create_new_cards(fact_data, card_type, grade=2, tag_names=["default"])[0] card_4.next_rep -= 1000 self.database().update_card(card_4) self.review_controller().reset() assert self.database().scheduler_data_count(Cramming.UNSEEN) == 4 assert self.database().scheduler_data_count(Cramming.WRONG) == 0 assert self.review_controller().counters() == (0, 4, 4) self.review_controller().grade_answer(0) assert self.database().scheduler_data_count(Cramming.UNSEEN) == 3 assert self.database().scheduler_data_count(Cramming.WRONG) == 1 assert self.review_controller().counters() == (1, 3, 4) self.review_controller().reset_but_try_to_keep_current_card() self.review_controller().update_dialog(redraw_all=True) assert self.database().scheduler_data_count(Cramming.UNSEEN) == 3 assert self.database().scheduler_data_count(Cramming.WRONG) == 1 assert self.review_controller().counters() == (1, 3, 4) def test_2(self): card_type = self.card_type_with_id("1") fact_data = {"f": "1", "b": "b"} card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.review_controller().show_new_question() self.controller().delete_current_card() assert self.review_controller().card == None def test_3( self ): # suffers from some sort of race condition with the finalise. card_type = self.card_type_with_id("1") fact_data = {"f": "1", "b": "b"} card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.review_controller().show_new_question() self.review_controller().show_answer() self.review_controller().grade_answer(0) self.review_controller().counters() self.mnemosyne.finalise() self.mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_cramming", "Widget")) self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \ [("mnemosyne_test", "TestReviewWidget")] self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.mnemosyne.start_review() assert self.scheduler().name == "cramming" def test_4(self): card_type = self.card_type_with_id("1") fact_data = {"f": "1", "b": "b"} card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.review_controller().reset() self.review_controller().show_new_question() self.database().unload() self.review_controller().reset() self.restart()
class TestMnemosyne2Cards(MnemosyneTest): def setup(self): self.initialise_data_dir() self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_mnemosyne2cards", "Widget")) self.mnemosyne.components.append(\ ("test_mnemosyne2cards", "MyMainWidget")) self.mnemosyne.components.append(\ ("mnemosyne_test", "TestReviewWidget")) self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.review_controller().reset() from mnemosyne.libmnemosyne.card_types.cloze import ClozePlugin for plugin in self.plugins(): if isinstance(plugin, ClozePlugin): plugin.activate() break def cards_format(self): for format in self.mnemosyne.component_manager.all("file_format"): if format.__class__.__name__ == "Mnemosyne2Cards": return format def test_tag(self): fact_data = {"f": "question", "b": "answer"} card_type_2 = self.card_type_with_id("2") card_1, card_2 = self.controller().create_new_cards(\ fact_data, card_type_2, grade=-1, tag_names=["default"]) self.database().save() self.cards_format().do_export(os.path.abspath("test.cards")) self.database().new("import.db") assert len([c for c in self.database().cards()]) == 0 self.cards_format().do_import(os.path.abspath("test.cards")) self.database().save() assert len([c for c in self.database().cards()]) == 2 for _card_id, _fact_id in self.database().cards(): card = self.database().card(_card_id, is_id_internal=True) assert card.active == True assert card.id self.cards_format().do_import(os.path.abspath("test.cards"), "tag1, tag2") self.database().save() assert len([tag.name for tag in self.database().tags()]) == 4 assert len([c for c in self.database().cards()]) == 2 for _card_id, _fact_id in self.database().cards(): card = self.database().card(_card_id, is_id_internal=True) assert card.active == True assert card.id def test_card_type(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card_type = self.controller().clone_card_type(\ card_type, ("1 clone")) card_type = self.controller().clone_card_type(\ card_type, ("1 clone cloned")) card_type.extra_data = {1:1} card_type.fact_views[0].extra_data = {2:2} card_1 = self.controller().create_new_cards(\ fact_data, card_type, grade=-1, tag_names=["default"]) self.database().save() self.cards_format().do_export(os.path.abspath("test.cards")) self.database().new("import.db") assert len([c for c in self.database().cards()]) == 0 self.cards_format().do_import(os.path.abspath("test.cards")) self.database().save() assert len([c for c in self.database().cards()]) == 1 for _card_id, _fact_id in self.database().cards(): card = self.database().card(_card_id, is_id_internal=True) assert card.active == True assert card.id self.cards_format().do_import(os.path.abspath("test.cards")) self.database().save() assert len([c for c in self.database().cards()]) == 1 def test_existing_tag(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card_1 = self.controller().create_new_cards(\ fact_data, card_type, grade=-1, tag_names=["default"]) self.database().save() self.cards_format().do_export(os.path.abspath("test.cards")) self.database().new("import.db") assert len([c for c in self.database().cards()]) == 0 self.database().get_or_create_tag_with_name("default") assert len(self.database().tags()) == 2 self.cards_format().do_import(os.path.abspath("test.cards")) assert len(self.database().tags()) == 3 self.cards_format().do_import(os.path.abspath("test.cards")) assert len(self.database().tags()) == 3 def test_rename_tags(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card_1 = self.controller().create_new_cards(\ fact_data, card_type, grade=-1, tag_names=["default"]) self.database().save() self.cards_format().do_export(os.path.abspath("test.cards")) self.database().new("import.db") assert len([c for c in self.database().cards()]) == 0 self.cards_format().do_import(os.path.abspath("test.cards")) assert len(self.database().tags()) == 2 tag = self.database().get_or_create_tag_with_name("default") tag.name = "edited" self.database().update_tag(tag) assert self.database().tags()[0].name == "edited" self.cards_format().do_import(os.path.abspath("test.cards")) assert self.database().tags()[0].name == "default" def test_existing_card_type(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") assert len(self.card_types()) == 4 card_type = self.controller().clone_card_type(\ card_type, ("1 clone")) assert len(self.card_types()) == 5 card_type = self.controller().clone_card_type(\ card_type, ("1 clone cloned")) assert len(self.card_types()) == 6 card_type.extra_data = {1:1} card_type.fact_views[0].extra_data = {2:2} card_1 = self.controller().create_new_cards(\ fact_data, card_type, grade=-1, tag_names=["default"]) self.database().save() self.cards_format().do_export(os.path.abspath("test.cards")) self.database().new("import.db") assert len(self.card_types()) == 4 card_type = self.card_type_with_id("1") card_type = self.controller().clone_card_type(\ card_type, ("1 clone cloned")) assert len(self.card_types()) == 5 self.cards_format().do_import(os.path.abspath("test.cards")) assert len(self.card_types()) == 7 self.cards_format().do_import(os.path.abspath("test.cards")) assert len(self.card_types()) == 7 def test_rename_card_type(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") assert len(self.card_types()) == 4 card_type = self.controller().clone_card_type(\ card_type, ("1 clone")) assert len(self.card_types()) == 5 card_type = self.controller().clone_card_type(\ card_type, ("1 clone cloned")) assert len(self.card_types()) == 6 card_type.extra_data = {1:1} card_type.fact_views[0].extra_data = {2:2} card_1 = self.controller().create_new_cards(\ fact_data, card_type, grade=-1, tag_names=["default"]) self.database().save() filename = os.path.join(os.path.abspath("dot_test"), os.path.abspath("test.cards")) file(filename, "w") self.cards_format().do_export(os.path.abspath("test.cards")) self.database().new("import.db") self.cards_format().do_import(os.path.abspath("test.cards")) assert len(self.card_types()) == 6 card_type = self.card_type_with_id("1::1 clone") card_type.name = "renamed" self.database().update_card_type(card_type) assert "renamed" in [card_type.name for card_type in self.card_types()] self.cards_format().do_import(os.path.abspath("test.cards")) assert len(self.card_types()) == 6 assert "renamed" not in [card_type.name for card_type in self.card_types()] self.cards_format().do_import(os.path.abspath("test.cards")) assert len(self.card_types()) == 6 assert "renamed" not in [card_type.name for card_type in self.card_types()] def test_update_fact(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(\ fact_data, card_type, grade=-1, tag_names=["default"]) self.cards_format().do_export(os.path.abspath("test.cards")) self.database().new("import.db") self.cards_format().do_import(os.path.abspath("test.cards")) _card_id, _fact_id = self.database().cards().next() card = self.database().card(_card_id, is_id_internal=True) card.fact["f"] = "edited" self.database().update_fact(card.fact) assert "edited" in card.question() self.cards_format().do_import(os.path.abspath("test.cards")) _card_id, _fact_id = self.database().cards().next() card = self.database().card(_card_id, is_id_internal=True) assert "edited" not in card.question() def test_extra_tag(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(\ fact_data, card_type, grade=-1, tag_names=[]) self.cards_format().do_export(os.path.abspath("test.cards")) self.database().new("import.db") self.cards_format().do_import(os.path.abspath("test.cards"), "extra") _card_id, _fact_id = self.database().cards().next() card = self.database().card(_card_id, is_id_internal=True) assert len(card.tags) == 1 assert card.tags.pop().name == "extra" def test_import_multiple(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(\ fact_data, card_type, grade=-1, tag_names=["default"])[0] self.cards_format().do_export(os.path.abspath("test.cards")) card.tags = set([self.database().get_or_create_tag_with_name("new_tag")]) self.database().update_card(card) self.cards_format().do_export(os.path.abspath("test2.cards")) self.database().new("import.db") self.cards_format().do_import(os.path.abspath("test.cards")) _card_id, _fact_id = self.database().cards().next() card = self.database().card(_card_id, is_id_internal=True) card.grade = 2 self.database().update_card(card) self.cards_format().do_import(os.path.abspath("test2.cards")) card = self.database().card(_card_id, is_id_internal=True) tag_names = [tag.name for tag in card.tags] assert "new_tag" in tag_names assert "default" in tag_names assert card.grade == 2 self.cards_format().do_import("test2.cards") card = self.database().card(_card_id, is_id_internal=True) assert len(list(card.tags)) == 2 assert card.grade == 2 def test_cloze(self): fact_data = {"text": "que[sti]on"} card_type = self.card_type_with_id("5") card = self.controller().create_new_cards(\ fact_data, card_type, grade=-1, tag_names=["default"])[0] self.cards_format().do_export(os.path.abspath("test.cards")) card.tags = set([self.database().get_or_create_tag_with_name("new_tag")]) self.database().new("import.db") self.cards_format().do_import(os.path.abspath("test.cards")) _card_id, _fact_id = self.database().cards().next() card = self.database().card(_card_id, is_id_internal=True) def test_media(self): filename_a = os.path.join(os.path.abspath("dot_test"), "default.db_media", unichr(0x628) + u"a.ogg") f = file(filename_a, "w") print >> f, "a" f.close() os.mkdir(os.path.join(os.path.abspath("dot_test"), "default.db_media", "b")) filename_b = os.path.join(os.path.abspath("dot_test"), "default.db_media", "b", unichr(0x628) + u"b.ogg") f = file(filename_b, "w") print >> f, "b" f.close() fact_data = {"f": "question\n<img src=\"%s\">" % (filename_a), "b": "question\n<img src=\"%s\">" % (filename_b)} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(\ fact_data, card_type, grade=-1, tag_names=["default"]) self.cards_format().do_export(os.path.abspath("test.cards")) self.database().new("import.db") self.cards_format().do_import(os.path.abspath("test.cards")) assert os.path.exists(os.path.join("dot_test", "import.db_media", unichr(0x628) + u"a.ogg")) assert os.path.exists(os.path.join("dot_test", "import.db_media", "b", unichr(0x628) + u"b.ogg")) def test_missing_media(self): filename_a = os.path.join(os.path.abspath("dot_test"), "default.db_media", unichr(0x628) + u"a.ogg") f = file(filename_a, "w") print >> f, "a" f.close() os.mkdir(os.path.join(os.path.abspath("dot_test"), "default.db_media", "b")) filename_b = os.path.join(os.path.abspath("dot_test"), "default.db_media", "b", unichr(0x628) + u"b.ogg") f = file(filename_b, "w") print >> f, "b" f.close() fact_data = {"f": "question\n<img src=\"%s\">" % (filename_a), "b": "question\n<img src=\"%s\">" % (filename_b)} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(\ fact_data, card_type, grade=-1, tag_names=["default"]) os.remove(filename_a) self.cards_format().do_export(os.path.abspath("test.cards")) global last_error assert last_error.startswith("Missing") last_error = None def teardown(self): if os.path.exists(os.path.abspath("test.cards")): os.remove(os.path.abspath("test.cards")) if os.path.exists("test2.cards"): os.remove("test2.cards") MnemosyneTest.teardown(self)
class TestMnemosyne2Cards(MnemosyneTest): def setup(self): self.initialise_data_dir() self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator") ) self.mnemosyne.components.append(("test_mnemosyne2cards", "Widget")) self.mnemosyne.components.append(("test_mnemosyne2cards", "MyMainWidget")) self.mnemosyne.components.append(("mnemosyne_test", "TestReviewWidget")) self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.review_controller().reset() from mnemosyne.libmnemosyne.card_types.cloze import ClozePlugin for plugin in self.plugins(): if isinstance(plugin, ClozePlugin): plugin.activate() break def cards_format(self): for format in self.mnemosyne.component_manager.all("file_format"): if format.__class__.__name__ == "Mnemosyne2Cards": return format def test_tag(self): fact_data = {"f": "question", "b": "answer"} card_type_2 = self.card_type_with_id("2") card_1, card_2 = self.controller().create_new_cards(fact_data, card_type_2, grade=-1, tag_names=["default"]) self.database().save() self.cards_format().do_export(os.path.abspath("test.cards")) self.database().new("import.db") assert len([c for c in self.database().cards()]) == 0 self.cards_format().do_import(os.path.abspath("test.cards")) self.database().save() assert len([c for c in self.database().cards()]) == 2 for _card_id, _fact_id in self.database().cards(): card = self.database().card(_card_id, is_id_internal=True) assert card.active == True assert card.id self.cards_format().do_import(os.path.abspath("test.cards"), "tag1, tag2") self.database().save() assert len([tag.name for tag in self.database().tags()]) == 4 assert len([c for c in self.database().cards()]) == 2 for _card_id, _fact_id in self.database().cards(): card = self.database().card(_card_id, is_id_internal=True) assert card.active == True assert card.id def test_card_type(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card_type = self.controller().clone_card_type(card_type, ("1 clone")) card_type = self.controller().clone_card_type(card_type, ("1 clone cloned")) card_type.extra_data = {1: 1} card_type.fact_views[0].extra_data = {2: 2} card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) self.database().save() self.cards_format().do_export(os.path.abspath("test.cards")) self.database().new("import.db") assert len([c for c in self.database().cards()]) == 0 self.cards_format().do_import(os.path.abspath("test.cards")) self.database().save() assert len([c for c in self.database().cards()]) == 1 for _card_id, _fact_id in self.database().cards(): card = self.database().card(_card_id, is_id_internal=True) assert card.active == True assert card.id self.cards_format().do_import(os.path.abspath("test.cards")) self.database().save() assert len([c for c in self.database().cards()]) == 1 def test_existing_tag(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) self.database().save() self.cards_format().do_export(os.path.abspath("test.cards")) self.database().new("import.db") assert len([c for c in self.database().cards()]) == 0 self.database().get_or_create_tag_with_name("default") assert len(self.database().tags()) == 2 self.cards_format().do_import(os.path.abspath("test.cards")) assert len(self.database().tags()) == 3 self.cards_format().do_import(os.path.abspath("test.cards")) assert len(self.database().tags()) == 3 def test_rename_tags(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) self.database().save() self.cards_format().do_export(os.path.abspath("test.cards")) self.database().new("import.db") assert len([c for c in self.database().cards()]) == 0 self.cards_format().do_import(os.path.abspath("test.cards")) assert len(self.database().tags()) == 2 tag = self.database().get_or_create_tag_with_name("default") tag.name = "edited" self.database().update_tag(tag) assert self.database().tags()[0].name == "edited" self.cards_format().do_import(os.path.abspath("test.cards")) assert self.database().tags()[0].name == "default" def test_existing_card_type(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") assert len(self.card_types()) == 4 card_type = self.controller().clone_card_type(card_type, ("1 clone")) assert len(self.card_types()) == 5 card_type = self.controller().clone_card_type(card_type, ("1 clone cloned")) assert len(self.card_types()) == 6 card_type.extra_data = {1: 1} card_type.fact_views[0].extra_data = {2: 2} card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) self.database().save() self.cards_format().do_export(os.path.abspath("test.cards")) self.database().new("import.db") assert len(self.card_types()) == 4 card_type = self.card_type_with_id("1") card_type = self.controller().clone_card_type(card_type, ("1 clone cloned")) assert len(self.card_types()) == 5 self.cards_format().do_import(os.path.abspath("test.cards")) assert len(self.card_types()) == 7 self.cards_format().do_import(os.path.abspath("test.cards")) assert len(self.card_types()) == 7 def test_rename_card_type(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") assert len(self.card_types()) == 4 card_type = self.controller().clone_card_type(card_type, ("1 clone")) assert len(self.card_types()) == 5 card_type = self.controller().clone_card_type(card_type, ("1 clone cloned")) assert len(self.card_types()) == 6 card_type.extra_data = {1: 1} card_type.fact_views[0].extra_data = {2: 2} card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) self.database().save() filename = os.path.join(os.path.abspath("dot_test"), os.path.abspath("test.cards")) file(filename, "w") self.cards_format().do_export(os.path.abspath("test.cards")) self.database().new("import.db") self.cards_format().do_import(os.path.abspath("test.cards")) assert len(self.card_types()) == 6 card_type = self.card_type_with_id("1::1 clone") card_type.name = "renamed" self.database().update_card_type(card_type) assert "renamed" in [card_type.name for card_type in self.card_types()] self.cards_format().do_import(os.path.abspath("test.cards")) assert len(self.card_types()) == 6 assert "renamed" not in [card_type.name for card_type in self.card_types()] self.cards_format().do_import(os.path.abspath("test.cards")) assert len(self.card_types()) == 6 assert "renamed" not in [card_type.name for card_type in self.card_types()] def test_update_fact(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) self.cards_format().do_export(os.path.abspath("test.cards")) self.database().new("import.db") self.cards_format().do_import(os.path.abspath("test.cards")) _card_id, _fact_id = self.database().cards().next() card = self.database().card(_card_id, is_id_internal=True) card.fact["f"] = "edited" self.database().update_fact(card.fact) assert "edited" in card.question() self.cards_format().do_import(os.path.abspath("test.cards")) _card_id, _fact_id = self.database().cards().next() card = self.database().card(_card_id, is_id_internal=True) assert "edited" not in card.question() def test_extra_tag(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=[]) self.cards_format().do_export(os.path.abspath("test.cards")) self.database().new("import.db") self.cards_format().do_import(os.path.abspath("test.cards"), "extra") _card_id, _fact_id = self.database().cards().next() card = self.database().card(_card_id, is_id_internal=True) assert len(card.tags) == 1 assert card.tags.pop().name == "extra" def test_import_multiple(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.cards_format().do_export(os.path.abspath("test.cards")) card.tags = set([self.database().get_or_create_tag_with_name("new_tag")]) self.database().update_card(card) self.cards_format().do_export(os.path.abspath("test2.cards")) self.database().new("import.db") self.cards_format().do_import(os.path.abspath("test.cards")) _card_id, _fact_id = self.database().cards().next() card = self.database().card(_card_id, is_id_internal=True) card.grade = 2 self.database().update_card(card) self.cards_format().do_import(os.path.abspath("test2.cards")) card = self.database().card(_card_id, is_id_internal=True) tag_names = [tag.name for tag in card.tags] assert "new_tag" in tag_names assert "default" in tag_names assert card.grade == 2 self.cards_format().do_import("test2.cards") card = self.database().card(_card_id, is_id_internal=True) assert len(list(card.tags)) == 2 assert card.grade == 2 def test_cloze(self): fact_data = {"text": "que[sti]on"} card_type = self.card_type_with_id("5") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.cards_format().do_export(os.path.abspath("test.cards")) card.tags = set([self.database().get_or_create_tag_with_name("new_tag")]) self.database().new("import.db") self.cards_format().do_import(os.path.abspath("test.cards")) _card_id, _fact_id = self.database().cards().next() card = self.database().card(_card_id, is_id_internal=True) def test_media(self): filename_a = os.path.join(os.path.abspath("dot_test"), "default.db_media", unichr(0x628) + u"a.ogg") f = file(filename_a, "w") print >> f, "a" f.close() os.mkdir(os.path.join(os.path.abspath("dot_test"), "default.db_media", "b")) filename_b = os.path.join(os.path.abspath("dot_test"), "default.db_media", "b", unichr(0x628) + u"b.ogg") f = file(filename_b, "w") print >> f, "b" f.close() fact_data = {"f": 'question\n<img src="%s">' % (filename_a), "b": 'question\n<img src="%s">' % (filename_b)} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) self.cards_format().do_export(os.path.abspath("test.cards")) self.database().new("import.db") self.cards_format().do_import(os.path.abspath("test.cards")) assert os.path.exists(os.path.join("dot_test", "import.db_media", unichr(0x628) + u"a.ogg")) assert os.path.exists(os.path.join("dot_test", "import.db_media", "b", unichr(0x628) + u"b.ogg")) def test_missing_media(self): filename_a = os.path.join(os.path.abspath("dot_test"), "default.db_media", unichr(0x628) + u"a.ogg") f = file(filename_a, "w") print >> f, "a" f.close() os.mkdir(os.path.join(os.path.abspath("dot_test"), "default.db_media", "b")) filename_b = os.path.join(os.path.abspath("dot_test"), "default.db_media", "b", unichr(0x628) + u"b.ogg") f = file(filename_b, "w") print >> f, "b" f.close() fact_data = {"f": 'question\n<img src="%s">' % (filename_a), "b": 'question\n<img src="%s">' % (filename_b)} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) os.remove(filename_a) self.cards_format().do_export(os.path.abspath("test.cards")) global last_error assert last_error.startswith("Missing") last_error = None def teardown(self): if os.path.exists(os.path.abspath("test.cards")): os.remove(os.path.abspath("test.cards")) if os.path.exists("test2.cards"): os.remove("test2.cards") MnemosyneTest.teardown(self)
class TestCardType(MnemosyneTest): def setup(self): self.initialise_data_dir() self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_card_type", "DecoratedThreeSided")) self.mnemosyne.components.append(\ ("test_card_type", "Widget")) self.mnemosyne.components.append(\ ("mnemosyne_test", "TestReviewWidget")) self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.review_controller().reset() def test_card_types(self): card_type = self.card_type_with_id("1") assert self.database().is_in_use(card_type) is False assert card_type.fact_key_with_name("Front") == "f" assert card_type.is_fact_data_valid({"f": "foo"}) == True assert self.card_type_with_id("1") == self.card_type_with_id("1") assert self.card_type_with_id("1") != None def test_database(self): card_type = self.card_type_with_id("1") card_type.fact_views[0].type_answer = True card_type.fact_views[0].extra_data = {"b": "b"} card_type = self.controller().clone_card_type(\ card_type, ("1 clone")) card_type.extra_data = {"b": "b"} self.database().update_card_type(card_type) self.mnemosyne.component_manager.unregister(card_type) card_type_out = self.database().card_type(card_type.id, is_id_internal=False) assert card_type_out.id == "1::1 clone" assert card_type_out.fact_key_with_name("Front") == "f" assert card_type_out.required_fact_keys == ["f"] assert card_type_out.is_fact_data_valid({"f": "foo"}) == True assert card_type_out.is_fact_data_valid({"q": "foo"}) == False assert card_type_out.fact_key_names() == ["Front", "Back"] assert card_type_out.fact_keys_and_names == card_type.fact_keys_and_names assert card_type_out.unique_fact_keys == card_type.unique_fact_keys assert card_type_out.keyboard_shortcuts == card_type.keyboard_shortcuts assert card_type_out.fact_views[0].type_answer == True assert card_type_out.fact_views[0].extra_data == {"b": "b"} assert card_type_out.extra_data == {"b": "b"} assert len(card_type.fact_views) == 1 assert len(card_type_out.fact_views) == 1 assert card_type_out.fact_views[0].id == \ card_type.fact_views[0].id assert card_type_out.fact_views[0].name == \ card_type.fact_views[0].name assert card_type_out.fact_views[0].q_fact_keys == \ card_type.fact_views[0].q_fact_keys assert card_type_out.fact_views[0].a_fact_keys == \ card_type.fact_views[0].a_fact_keys assert card_type_out.fact_views[0].a_on_top_of_q == \ card_type.fact_views[0].a_on_top_of_q # Reset global variables. self.mnemosyne.component_manager.register(card_type) card_type = self.card_type_with_id("1") card_type.fact_views[0].type_answer = False card_type.fact_views[0].extra_data = {} card_type_orig = self.database().card_type("1", is_id_internal=False) assert card_type_orig.fact_views[0].type_answer == False def test_rename_two_clones(self): card_type = self.card_type_with_id("1") card_type_1 = self.controller().clone_card_type(\ card_type, "1 clone") card_type = self.card_type_with_id("2") card_type_2 = self.controller().clone_card_type(\ card_type, "2 clone") self.controller().rename_card_type(card_type_1, "1 clone new") assert set([c.name for c in self.card_types() if \ self.database().is_user_card_type(c)]) == \ set(["1 clone new", "2 clone"]) def test_rename_two_clones_b(self): card_type = self.card_type_with_id("1") card_type_1 = self.controller().clone_card_type(\ card_type, "1 clone") card_type = self.card_type_with_id("2") card_type_2 = self.controller().clone_card_type(\ card_type, "2 clone") self.controller().rename_card_type(card_type_2, "2 clone new") assert set([c.name for c in self.card_types() if \ self.database().is_user_card_type(c)]) == \ set(["1 clone", "2 clone new"]) def test_delete(self): card_type = self.card_type_with_id("1") card_type_1 = self.controller().clone_card_type(\ card_type, "1 clone") card_type = self.card_type_with_id("2") card_type_2 = self.controller().clone_card_type(\ card_type, "2 clone") self.controller().delete_card_type(card_type_1) card_type_out = self.database().card_type(card_type_2.id, is_id_internal=False) assert card_type_out.fact_views[0].id == \ card_type_2.fact_views[0].id assert card_type_out.fact_views[0].name == \ card_type_2.fact_views[0].name assert card_type_out.fact_views[0].q_fact_keys == \ card_type_2.fact_views[0].q_fact_keys assert card_type_out.fact_views[0].a_fact_keys == \ card_type_2.fact_views[0].a_fact_keys assert card_type_out.fact_views[0].a_on_top_of_q == \ card_type_2.fact_views[0].a_on_top_of_q assert card_type_out.fact_views[1].id == \ card_type_2.fact_views[1].id assert card_type_out.fact_views[1].name == \ card_type_2.fact_views[1].name assert card_type_out.fact_views[1].q_fact_keys == \ card_type_2.fact_views[1].q_fact_keys assert card_type_out.fact_views[1].a_fact_keys == \ card_type_2.fact_views[1].a_fact_keys assert card_type_out.fact_views[1].a_on_top_of_q == \ card_type_2.fact_views[1].a_on_top_of_q def test_delete_with_formatting(self): card_type = self.card_type_with_id("1") card_type_1 = self.controller().clone_card_type(\ card_type, "1 clone") card_type = self.card_type_with_id("2") card_type_2 = self.controller().clone_card_type(\ card_type, "2 clone") self.config().set_card_type_property("background_colour", "black", card_type_1) self.controller().delete_card_type(card_type_1) def test_cannot_delete(self): global last_error last_error = None card_type = self.card_type_with_id("1") self.controller().delete_card_type(card_type) assert "in use" in last_error last_error = None card_type_1 = self.controller().clone_card_type(\ card_type, "1 clone") card_type = self.card_type_with_id("2") card_type_2 = self.controller().clone_card_type(\ card_type, "2 clone") fact_data = {"f": "question", "b": "answer"} old_card = self.controller().create_new_cards(fact_data, card_type_1, grade=-1, tag_names=["default"])[0] self.controller().delete_card_type(card_type_1) assert "in use" in last_error last_error = None def test_rename(self): card_type = self.card_type_with_id("1") card_type_1 = self.controller().clone_card_type(\ card_type, "1 clone") self.controller().rename_card_type(card_type_1, "newname") card_type_out = self.database().card_type(card_type_1.id, is_id_internal=False) assert card_type_out.name == "newname" def test_cannot_rename(self): global last_error last_error = None card_type = self.card_type_with_id("1") self.controller().rename_card_type(card_type, "newname") assert last_error.startswith("Cannot rename") last_error = None def test_cannot_rename_duplicate(self): global last_error last_error = None card_type = self.card_type_with_id("1") card_type_1 = self.controller().clone_card_type(\ card_type, "1 clone") self.controller().rename_card_type(card_type_1, "Vocabulary") assert "in use" in last_error last_error = None def test_has_clones(self): global last_error last_error = None card_type = self.card_type_with_id("1") assert self.database().has_clones(card_type) == False card_type_1 = self.controller().clone_card_type(\ card_type, "1 clone") card_type_2 = self.controller().clone_card_type(\ card_type_1, "1 clone clone") assert self.database().has_clones(card_type) == True assert self.database().has_clones(card_type_1) == True self.controller().delete_card_type(card_type_1) assert "clone" in last_error last_error = None def test_clone_of_clone(self): card_type = self.card_type_with_id("1") assert self.database().is_user_card_type(card_type) == False card_type.fact_views[0].type_answer = True card_type.fact_views[0].extra_data = {"b": "b"} card_type = self.controller().clone_card_type(\ card_type, ("1 clone")) assert self.database().is_user_card_type(card_type) == True card_type = self.controller().clone_card_type(\ card_type, ("1 clone cloned")) assert self.database().is_user_card_type(card_type) == True card_type.extra_data = {"b": "b"} self.database().update_card_type(card_type) self.mnemosyne.component_manager.unregister(card_type) card_type_out = self.database().card_type(card_type.id, is_id_internal=False) assert card_type_out.fact_key_with_name("Front") == "f" assert card_type_out.required_fact_keys == ["f"] assert card_type_out.is_fact_data_valid({"f": "foo"}) == True assert card_type_out.fact_keys_and_names == card_type.fact_keys_and_names assert card_type_out.unique_fact_keys == card_type.unique_fact_keys assert card_type_out.keyboard_shortcuts == card_type.keyboard_shortcuts assert card_type_out.fact_views[0].type_answer == True assert card_type_out.fact_views[0].extra_data == {"b": "b"} assert card_type_out.extra_data == {"b": "b"} assert len(card_type.fact_views) == 1 assert len(card_type_out.fact_views) == 1 assert card_type_out.fact_views[0].id == \ card_type.fact_views[0].id assert card_type_out.fact_views[0].name == \ card_type.fact_views[0].name assert card_type_out.fact_views[0].q_fact_keys == \ card_type.fact_views[0].q_fact_keys assert card_type_out.fact_views[0].a_fact_keys == \ card_type.fact_views[0].a_fact_keys assert card_type_out.fact_views[0].a_on_top_of_q == \ card_type.fact_views[0].a_on_top_of_q # Reset global variables. self.mnemosyne.component_manager.register(card_type) card_type.fact_views[0].type_answer = False card_type.fact_views[0].extra_data = {} fact_data = {"f": "question", "b": "answer"} card = self.mnemosyne.controller().create_new_cards( fact_data, card_type, grade=-1, tag_names=["default"])[0] path = self.mnemosyne.database().path() self.mnemosyne.database().unload() self.mnemosyne.database().load(path) def test_decorators(self): fact_data = { "f": "foreign word", "p_1": "pronunciation", "m_1": "translation" } card_type = self.card_type_with_id("3_decorated") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] assert "What is the translation of foreign word?" in card.question() def test_properties(self): card_type = self.card_type_with_id("1") self.config().set_card_type_property("font", "myfont", card_type) self.config().set_card_type_property("background_colour", "mycolour", card_type) card_type = self.controller().clone_card_type(\ card_type, ("1 clone")) assert self.config().card_type_property("font", card_type, 'f') == "myfont" assert self.config().card_type_property("background_colour", card_type) == "mycolour"
class TestLogging(MnemosyneTest): def restart(self): self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_logging", "MyMainWidget")) self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \ [("mnemosyne_test", "TestReviewWidget")] self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) def test_logging(self): card_type = self.card_type_with_id("1") fact_data = {"f": "1", "b": "b"} card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] card_id_1 = card.id self.review_controller().show_new_question() self.review_controller().grade_answer(0) self.review_controller().show_new_question() self.review_controller().grade_answer(1) self.review_controller().grade_answer(4) self.mnemosyne.finalise() self.restart() card_type = self.card_type_with_id("1") fact_data = {"f": "2", "b": "b"} card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.review_controller().show_new_question() self.controller().delete_current_card() self.log().dump_to_science_log() sql_res = self.database().con.execute(\ "select * from log where _id=1").fetchone() assert sql_res[1] == EventTypes.STARTED_PROGRAM sql_res = self.database().con.execute(\ "select * from log where _id=2").fetchone() assert sql_res[1] == EventTypes.STARTED_SCHEDULER sql_res = self.database().con.execute(\ "select * from log where _id=3").fetchone() assert sql_res[1] == EventTypes.LOADED_DATABASE assert sql_res[6] == 0 assert sql_res[7] == 0 assert sql_res[8] == 0 sql_res = self.database().con.execute(\ "select * from log where _id=11").fetchone() assert sql_res[1] == EventTypes.ADDED_TAG assert sql_res[3] is not None sql_res = self.database().con.execute(\ "select * from log where _id=12").fetchone() assert sql_res[1] == EventTypes.EDITED_CRITERION assert sql_res[3] is not None sql_res = self.database().con.execute(\ "select * from log where _id=13").fetchone() assert sql_res[1] == EventTypes.ADDED_FACT assert sql_res[3] is not None sql_res = self.database().con.execute(\ "select * from log where _id=14").fetchone() assert sql_res[1] == EventTypes.ADDED_CARD assert sql_res[3] is not None sql_res = self.database().con.execute(\ "select * from log where _id=15").fetchone() assert sql_res[1] == EventTypes.REPETITION assert sql_res[6] == 1 assert sql_res[7] == 0 assert sql_res[11] == 0 assert sql_res[12] == 0 assert sql_res[14] - sql_res[2] == 0 assert sql_res[13] == 0 assert sql_res[3] is not None sql_res = self.database().con.execute(\ "select * from log where _id=16").fetchone() assert sql_res[1] == EventTypes.REPETITION assert sql_res[6] == 2 assert sql_res[7] == 0 assert sql_res[11] == 0 assert sql_res[12] <= 10 # Depends on CPU load. assert sql_res[14] - sql_res[2] == 0 assert sql_res[13] == 0 sql_res = self.database().con.execute(\ "select * from log where _id=17").fetchone() assert sql_res[1] == EventTypes.REPETITION assert sql_res[6] == 3 assert sql_res[7] == 0 assert sql_res[11] == 0 assert sql_res[12] <= 10 # Depends on CPU load. new_interval = sql_res[14] - sql_res[2] assert new_interval > 0 assert sql_res[13] == 0 sql_res = self.database().con.execute(\ "select * from log where _id=18").fetchone() assert sql_res[1] == EventTypes.SAVED_DATABASE assert sql_res[6] == 0 assert sql_res[7] == 0 assert sql_res[8] == 1 sql_res = self.database().con.execute(\ "select * from log where _id=19").fetchone() assert sql_res[1] == EventTypes.STOPPED_PROGRAM sql_res = self.database().con.execute(\ "select * from log where _id=20").fetchone() assert sql_res[1] == EventTypes.STARTED_PROGRAM sql_res = self.database().con.execute(\ "select * from log where _id=21").fetchone() assert sql_res[1] == EventTypes.STARTED_SCHEDULER sql_res = self.database().con.execute(\ "select * from log where _id=22").fetchone() assert sql_res[1] == EventTypes.LOADED_DATABASE assert sql_res[6] == 0 assert sql_res[7] == 0 assert sql_res[8] == 1 sql_res = self.database().con.execute(\ "select * from log where _id=30").fetchone() assert sql_res[1] == EventTypes.ADDED_FACT assert sql_res[3] is not None sql_res = self.database().con.execute(\ "select * from log where _id=31").fetchone() assert sql_res[1] == EventTypes.ADDED_CARD sql_res = self.database().con.execute(\ "select * from log where _id=32").fetchone() assert sql_res[1] == EventTypes.DELETED_CARD assert sql_res[3] is not None sql_res = self.database().con.execute(\ "select * from log where _id=33").fetchone() assert sql_res[1] == EventTypes.DELETED_FACT assert sql_res[3] is not None self.config()["upload_science_logs"] = True self.database().dump_to_science_log() logfile = os.path.join(os.path.abspath("dot_test"), "log.txt") found = False for line in open(logfile): if "R " + card_id_1 + " 4" in line: found = True assert str(new_interval) + " 0 | 0.0" in line assert found == True def test_unique_index(self): fact_data = {"f": "question", "b": "answer"} card_type_2 = self.card_type_with_id("2") card_1, card_2 = self.controller().create_new_cards( fact_data, card_type_2, grade=-1, tag_names=["default"]) log_index = self.database().con.execute(\ """select _id from log order by _id desc limit 1""").fetchone()[0] # Note: we need to keep the last log entry intact, otherwise indexes # start again at 1 and mess up the sync. self.database().con.execute("""delete from log where _id <?""", (log_index, )) self.database().save() self.database().con.execute("""vacuum""") fact_data = {"f": "question2", "b": "answer2"} card_type_2 = self.card_type_with_id("1") card_1 = self.controller().create_new_cards(fact_data, card_type_2, grade=-1, tag_names=["default"]) assert self.database().con.execute(\ """select _id from log order by _id limit 1""").fetchone()[0] \ == log_index def test_recover_user_id(self): assert self.config()["user_id"] is not None MnemosyneTest.teardown(self) open( os.path.join(os.getcwd(), "dot_test", "history", "userid_001.bz2"), "w") os.remove(os.path.join(os.getcwd(), "dot_test", "config.db")) self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_logging", "MyMainWidget")) self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \ [("mnemosyne_test", "TestReviewWidget")] self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.mnemosyne.start_review() assert self.config()["user_id"] == "userid" def test_recover_user_id_2(self): assert self.config()["user_id"] is not None MnemosyneTest.teardown(self) open( os.path.join(os.getcwd(), "dot_test", "history", "userid_machine_001.bz2"), "w") os.remove(os.path.join(os.getcwd(), "dot_test", "config.db")) self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_logging", "MyMainWidget")) self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \ [("mnemosyne_test", "TestReviewWidget")] self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.mnemosyne.start_review() assert self.config()["user_id"] == "userid" def test_log_index_of_last_upload_1(self): assert self.log().log_index_of_last_upload() == 0 def test_log_index_of_last_upload_2(self): machine_id = self.config().machine_id() for filename in ["user_001.bz2", "user_%s_2.bz2" % machine_id]: open(os.path.join(os.getcwd(), "dot_test", "history", filename), "w") assert self.log().log_index_of_last_upload() == 2 def test_log_index_of_last_upload_3(self): machine_id = self.config().machine_id() for filename in ["user_001.bz2"]: open(os.path.join(os.getcwd(), "dot_test", "history", filename), "w") assert self.log().log_index_of_last_upload() == 1 def test_log_index_of_last_upload_4(self): machine_id = self.config().machine_id() for filename in ["user_005.bz2"]: open(os.path.join(os.getcwd(), "dot_test", "history", filename), "w") assert self.log().log_index_of_last_upload() == 5 def test_log_index_of_last_upload_5(self): machine_id = self.config().machine_id() for filename in ["user_othermachine_005.bz2"]: open(os.path.join(os.getcwd(), "dot_test", "history", filename), "w") assert self.log().log_index_of_last_upload() == 0 def test_log_index_of_last_upload_6(self): machine_id = self.config().machine_id() for filename in [ "user_othermachine_005.bz2", "user_%s_2.bz2" % machine_id ]: open(os.path.join(os.getcwd(), "dot_test", "history", filename), "w") assert self.log().log_index_of_last_upload() == 2 def test_log_index_of_last_upload_7(self): machine_id = self.config().machine_id() for filename in [ "user_001.bz2", "user_othermachine_005.bz2", "user_%s_2.bz2" % machine_id ]: open(os.path.join(os.getcwd(), "dot_test", "history", filename), "w") assert self.log().log_index_of_last_upload() == 2 def test_log_upload(self): machine_id_file = os.path.join(self.mnemosyne.config().config_dir, "machine.id") f = open(machine_id_file, "w") print("TESTMACHINE", file=f) f.close() self.config().change_user_id("UPLOADTEST") self.config()["max_log_size_before_upload"] = 1 MnemosyneTest.teardown(self) self.mnemosyne = Mnemosyne(upload_science_logs=True, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_logging", "MyMainWidget")) self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \ [("mnemosyne_test", "TestReviewWidget")] self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.mnemosyne.start_review() MnemosyneTest.teardown(self) self.mnemosyne = Mnemosyne(upload_science_logs=True, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_logging", "MyMainWidget")) self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \ [("mnemosyne_test", "TestReviewWidget")] self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.mnemosyne.start_review() MnemosyneTest.teardown(self) self.mnemosyne = Mnemosyne(upload_science_logs=True, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_logging", "MyMainWidget")) self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \ [("mnemosyne_test", "TestReviewWidget")] self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.mnemosyne.start_review() def test_log_upload_bad_server(self): # Most reliable way of setting this variable is throug config.py, otherwise # it will stay alive in a dangling imported userconfig. config_py_file = os.path.join(self.mnemosyne.config().config_dir, "config.py") f = open(config_py_file, "w") print("science_server = \"noserver:80\"", file=f) f.close() machine_id_file = os.path.join(self.mnemosyne.config().config_dir, "machine.id") f = open(machine_id_file, "w") print("TESTMACHINE", file=f) f.close() self.config().change_user_id("UPLOADTEST") self.config()["max_log_size_before_upload"] = 1 MnemosyneTest.teardown(self) self.mnemosyne = Mnemosyne(upload_science_logs=True, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_logging", "MyMainWidget")) self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \ [("mnemosyne_test", "TestReviewWidget")] self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.mnemosyne.start_review() MnemosyneTest.teardown(self) self.mnemosyne = Mnemosyne(upload_science_logs=True, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_logging", "MyMainWidget")) self.mnemosyne.gui_for_component["ScheduledForgottenNew"] = \ [("mnemosyne_test", "TestReviewWidget")] self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.mnemosyne.start_review() def mem_importer(self): for format in self.mnemosyne.component_manager.all("file_format"): if format.__class__.__name__ == "Mnemosyne1Mem": return format def test_archive_old_logs(self): # Import old history. filename = os.path.join(os.getcwd(), "tests", "files", "basedir_bz2", "default.mem") self.mem_importer().do_import(filename) assert self.database().con.execute( "select count() from log").fetchone()[0] == 23 assert not os.path.exists(os.path.join("dot_test", "archive")) # Archive. self.database().archive_old_logs() assert self.database().con.execute( "select count() from log").fetchone()[0] == 12 archive_name = os.listdir( os.path.join(os.getcwd(), "dot_test", "archive"))[0] archive_path = os.path.join(os.getcwd(), "dot_test", "archive", archive_name) import sqlite3 arch_con = sqlite3.connect(archive_path) assert arch_con.execute("select count() from log").fetchone()[0] == 11
class MnemosyneTest(): def initialise_data_dir(self, data_dir="dot_test"): # Creating a new database seems a very time-consuming operation, # so we don't delete the test directory everytime, but take a short # cut. # Note: disabled this, as it does not seem to be very reliable. shutil.rmtree(data_dir, ignore_errors=True) if os.path.exists(data_dir): shutil.copy(os.path.join("tests", "files", "empty.db"), os.path.join(data_dir, "default.db")) for directory in ["default.db_media", "plugins", "backups", "history"]: full_path = unicode(os.path.join(data_dir, directory)) if os.path.exists(full_path): shutil.rmtree(full_path) for file in ["default.db-journal", "config", "config.py", "machine.id", "log.txt"]: full_path = unicode(os.path.join(data_dir, file)) if os.path.exists(full_path): os.remove(full_path) def setup(self): self.initialise_data_dir() self.restart() def restart(self): # If there is another Mnemosyne still running, finalise it so as to # avoid having multiple component_managers active. if hasattr(self, "mnemosyne"): try: self.mnemosyne.finalise() except: pass self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.main_widget", "MainWidget")) self.mnemosyne.components.append(\ ("mnemosyne_test", "TestReviewWidget")) self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.mnemosyne.start_review() def teardown(self): self.mnemosyne.finalise() # Avoid having multiple component_managers active. from mnemosyne.libmnemosyne.component_manager import clear_component_managers clear_component_managers() def config(self): return self.mnemosyne.component_manager.current("config") def log(self): return self.mnemosyne.component_manager.current("log") def database(self): return self.mnemosyne.component_manager.current("database") def scheduler(self): return self.mnemosyne.component_manager.current("scheduler") def main_widget(self): return self.mnemosyne.component_manager.current("main_widget") def review_widget(self): return self.mnemosyne.component_manager.current("review_widget") def controller(self): return self.mnemosyne.component_manager.current("controller") def review_controller(self): return self.mnemosyne.component_manager.current("review_controller") def card_types(self): return self.mnemosyne.component_manager.all("card_type") def filters(self): return self.mnemosyne.component_manager.all("filter") def plugins(self): return self.mnemosyne.component_manager.all("plugin") def render_chain(self, id="default"): return self.mnemosyne.component_manager.render_chain_by_id[id] def card_type_with_id(self, id): return self.mnemosyne.component_manager.card_type_with_id[id]
class TestConvertCards(MnemosyneTest): def setup(self): self.initialise_data_dir() self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_convert_cards", "Widget")) self.mnemosyne.components.append(\ ("mnemosyne_test", "TestReviewWidget")) self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.review_controller().reset() from mnemosyne.libmnemosyne.card_types.map import MapPlugin for plugin in self.plugins(): if isinstance(plugin, MapPlugin): plugin.activate() break def test_1_to_2(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact old_card = copy.copy(self.database().cards_from_fact(fact)[0]) new_fact_data = {"f": "question2", "b": "answer2"} new_card_type = self.card_type_with_id("2") self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=[]) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 new_card_1, new_card_2 = self.database().cards_from_fact(fact) assert new_card_1.card_type.id == "2" assert new_card_2.card_type.id == "2" if new_card_1.fact_view.id == "2.1": assert new_card_1 == old_card assert new_card_2 != old_card assert new_card_2.grade == -1 else: assert new_card_2 == old_card assert new_card_1 != old_card assert new_card_1.grade == -1 new_card_1.question() new_card_1.answer() new_card_2.question() new_card_2.answer() def test_1_to_2_multi(self): file("a.ogg", "w") full_path = os.path.abspath("a.ogg") fact_data = {"f": "<img src=\"%s\">" % full_path, "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact old_card = copy.copy(self.database().cards_from_fact(fact)[0]) new_fact_data = {"f": "question2", "b": "answer2"} new_card_type = self.card_type_with_id("2") self.controller().change_card_type([fact], card.card_type, new_card_type, correspondence=[]) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 new_card_1, new_card_2 = self.database().cards_from_fact(fact) assert new_card_1.card_type.id == "2" assert new_card_2.card_type.id == "2" if new_card_1.fact_view.id == "2.1": assert new_card_1 == old_card assert new_card_2 != old_card assert new_card_2.grade == -1 else: assert new_card_2 == old_card assert new_card_1 != old_card assert new_card_1.grade == -1 new_card_1.question() new_card_1.answer() new_card_2.question() new_card_2.answer() def test_1_to_2_multi_no_media(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact old_card = copy.copy(self.database().cards_from_fact(fact)[0]) new_fact_data = {"f": "question2", "b": "answer2"} new_card_type = self.card_type_with_id("2") self.controller().change_card_type([fact], card.card_type, new_card_type, correspondence=[]) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 new_card_1, new_card_2 = self.database().cards_from_fact(fact) assert new_card_1.card_type.id == "2" assert new_card_2.card_type.id == "2" if new_card_1.fact_view.id == "2.1": assert new_card_1 == old_card assert new_card_2 != old_card assert new_card_2.grade == -1 else: assert new_card_2 == old_card assert new_card_1 != old_card assert new_card_1.grade == -1 new_card_1.question() new_card_1.answer() new_card_2.question() new_card_2.answer() def test_2_to_1(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("2") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"f": "question2", "b": "answer2"} new_card_type = self.card_type_with_id("1") self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=[]) assert self.database().fact_count() == 1 assert self.database().card_count() == 1 new_card = self.database().cards_from_fact(fact)[0] assert new_card.card_type.id == "1" if old_card_1.fact_view.id == "2.1": assert new_card == old_card_1 assert new_card != old_card_2 else: assert new_card == old_card_2 assert new_card != old_card_1 new_card.question() new_card.answer() def test_1_to_3_a(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact old_card = copy.copy(self.database().cards_from_fact(fact)[0]) new_fact_data = {"f": "foreign word", "p_1": "pronunciation", "m_1": "translation"} correspondence = {"f": "f", "b": "p_1"} new_card_type = self.card_type_with_id("3") self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 new_card_1, new_card_2 = self.database().cards_from_fact(fact) assert new_card_1.card_type.id == "3" assert new_card_2.card_type.id == "3" if new_card_1.fact_view.id == "3.1": assert new_card_1 == old_card assert new_card_2 != old_card else: assert new_card_2 == old_card assert new_card_1 != old_card new_card_1.question() new_card_1.answer() new_card_2.question() new_card_2.answer() def test_1_to_3_b(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact old_card = copy.copy(self.database().cards_from_fact(fact)[0]) new_fact_data = {"f": "foreign word", "p_1": "pronunciation", "m_1": "translation"} correspondence = {"f": "m_1", "b": "f"} new_card_type = self.card_type_with_id("3") self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 new_card_1, new_card_2 = self.database().cards_from_fact(fact) assert new_card_1.card_type.id == "3" assert new_card_2.card_type.id == "3" if new_card_1.fact_view.id == "3.2": assert new_card_1 == old_card assert new_card_2 != old_card else: assert new_card_2 == old_card assert new_card_1 != old_card new_card_1.question() new_card_1.answer() new_card_2.question() new_card_2.answer() def test_3_to_1_a(self): fact_data = {"f": "foreign word", "p_1": "pronunciation", "m_1": "translation"} card_type = self.card_type_with_id("3") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"f": "question", "b": "answer"} correspondence = {"f": "f", "m_1": "b"} new_card_type = self.card_type_with_id("1") self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 1 new_card = self.database().cards_from_fact(fact)[0] assert new_card.card_type.id == "1" if old_card_1.fact_view.id == "3.1": assert new_card == old_card_1 assert new_card != old_card_2 else: assert new_card == old_card_2 assert new_card != old_card_1 new_card.question() new_card.answer() def test_3_to_1_b(self): fact_data = {"f": "foreign word", "p_1": "pronunciation", "m_1": "translation"} card_type = self.card_type_with_id("3") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"f": "question", "b": "answer"} correspondence = {"f": "b", "m_1": "f"} new_card_type = self.card_type_with_id("1") self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 1 new_card = self.database().cards_from_fact(fact)[0] assert new_card.card_type.id == "1" if old_card_1.fact_view.id == "3.2": assert new_card == old_card_1 assert new_card != old_card_2 else: assert new_card == old_card_2 assert new_card != old_card_1 new_card.question() new_card.answer() def test_3_to_1_c(self): # Missing required field. fact_data = {"f": "foreign word", "m_1": "meaning"} card_type = self.card_type_with_id("3") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"b": "foreign word"} correspondence = {"f": "b", "p_1": "f"} new_card_type = self.card_type_with_id("1") self.controller().change_card_type([fact], card_type, new_card_type, correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 card_1, card_2 = self.database().cards_from_fact(fact) assert card_1.card_type.id == "3" assert card_2.card_type.id == "3" def test_2_to_3_a(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("2") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"f": "foreign word", "p_1": "pronunciation", "m_1": "translation"} correspondence = {"f": "f", "b": "m_1"} new_card_type = self.card_type_with_id("3") self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 new_card_1, new_card_2 = self.database().cards_from_fact(fact) assert new_card_1.card_type.id == "3" assert new_card_2.card_type.id == "3" for old in [old_card_1, old_card_2]: for new in [new_card_1, new_card_2]: if old == new: assert old.fact_view.id.split(".")[1] == \ new.fact_view.id.split(".")[1] new_card_1.question() new_card_1.answer() new_card_2.question() new_card_2.answer() def test_2_to_3_b(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("2") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"f": "foreign word", "p_1": "pronunciation", "m_1": "translation"} correspondence = {"f": "m_1", "b": "f"} new_card_type = self.card_type_with_id("3") self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 new_card_1, new_card_2 = self.database().cards_from_fact(fact) assert new_card_1.card_type.id == "3" assert new_card_2.card_type.id == "3" for old in [old_card_1, old_card_2]: for new in [new_card_1, new_card_2]: if old == new: assert old.fact_view != new.fact_view new_card_1.question() new_card_1.answer() new_card_2.question() new_card_2.answer() def test_3_to_2_a(self): fact_data = {"f": "foreign word", "p_1": "pronunciation", "m_1": "translation"} card_type = self.card_type_with_id("3") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"f": "question", "b": "answer"} correspondence = {"f": "f", "m_1": "b"} new_card_type = self.card_type_with_id("2") self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 new_card_1, new_card_2 = self.database().cards_from_fact(fact) assert new_card_1.card_type.id == "2" assert new_card_2.card_type.id == "2" for old in [old_card_1, old_card_2]: for new in [new_card_1, new_card_2]: if old == new: assert old.fact_view.id.split(".")[1] == \ new.fact_view.id.split(".")[1] new_card_1.question() new_card_1.answer() new_card_2.question() new_card_2.answer() def test_3_to_2_b(self): fact_data = {"f": "foreign word", "p_1": "pronunciation", "m_1": "translation"} card_type = self.card_type_with_id("3") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"f": "question", "b": "answer"} correspondence = {"f": "b", "m_1": "f"} new_card_type = self.card_type_with_id("2") self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 new_card_1, new_card_2 = self.database().cards_from_fact(fact) assert new_card_1.card_type.id == "2" assert new_card_2.card_type.id == "2" for old in [old_card_1, old_card_2]: for new in [new_card_1, new_card_2]: if old == new: assert old.fact_view != new.fact_view new_card_1.question() new_card_1.answer() new_card_2.question() new_card_2.answer() def test_3_clone_to_1_a(self): fact_data = {"f": "foreign word", "p_1": "pronunciation", "m_1": "translation"} card_type = self.card_type_with_id("3") self.controller().clone_card_type(card_type, "my_3") card_type = self.card_type_with_id("3::my_3") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"f": "question", "b": "answer"} correspondence = {"f": "f", "m_1": "b"} new_card_type = self.card_type_with_id("1") self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 1 new_card = self.database().cards_from_fact(fact)[0] assert new_card.card_type.id == "1" if old_card_1.fact_view.id == "3::my_3.1": assert new_card == old_card_1 assert new_card != old_card_2 else: assert new_card == old_card_2 assert new_card != old_card_1 new_card.question() new_card.answer() def test_3_to_1_clone_a(self): fact_data = {"f": "foreign word", "p_1": "pronunciation", "m_1": "translation"} card_type = self.card_type_with_id("3") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"f": "question", "b": "answer"} correspondence = {"f": "f", "m_1": "b"} new_card_type = self.card_type_with_id("1") self.controller().clone_card_type(new_card_type, "my_1") new_card_type = self.card_type_with_id("1::my_1") self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 1 new_card = self.database().cards_from_fact(fact)[0] assert new_card.card_type.id == "1::my_1" assert new_card.fact.data["f"] == "question" assert new_card.fact.data["b"] == "answer" if old_card_1.fact_view.id == "3.1": assert new_card == old_card_1 assert new_card != old_card_2 else: assert new_card == old_card_2 assert new_card != old_card_1 new_card.question() new_card.answer() def test_3_clone_to_1_clone_a(self): fact_data = {"f": "foreign word", "p_1": "pronunciation", "m_1": "translation"} card_type = self.card_type_with_id("3") self.controller().clone_card_type(card_type, "my_3") card_type = self.card_type_with_id("3::my_3") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact = card.fact card_1, card_2 = self.database().cards_from_fact(fact) old_card_1 = copy.copy(card_1) old_card_2 = copy.copy(card_2) new_fact_data = {"f": "question", "b": "answer"} correspondence = {"f": "f", "m_1": "b"} new_card_type = self.card_type_with_id("1") self.controller().clone_card_type(new_card_type, "my_1") new_card_type = self.card_type_with_id("1::my_1") self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, new_tag_names=["default2"], correspondence=correspondence) assert self.database().fact_count() == 1 assert self.database().card_count() == 1 new_card = self.database().cards_from_fact(fact)[0] assert new_card.card_type.id == "1::my_1" if old_card_1.fact_view.id == "3::my_3.1": assert new_card == old_card_1 assert new_card != old_card_2 else: assert new_card == old_card_2 assert new_card != old_card_1 new_card.question() new_card.answer() def test_cloze_to_1(self): from mnemosyne.libmnemosyne.ui_components.statistics_widget import \ StatisticsWidget from mnemosyne.libmnemosyne.statistics_pages.schedule import Schedule class ScheduleWdgt(StatisticsWidget): used_for = Schedule self.mnemosyne.component_manager.register(ScheduleWdgt) for plugin in self.plugins(): component = plugin.components[0] if component.component_type == "card_type" and component.id == "5": plugin.activate() fact_data = {"text": "[question]"} card_type = self.card_type_with_id("5") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.review_controller().reset() new_card_type = self.card_type_with_id("1") fact_data = {"f": "[question]", "b": ""} self.controller().edit_card_and_sisters(card, fact_data, new_card_type, new_tag_names=["default2"], correspondence={'text': "f"}) assert self.database().fact_count() == 1 assert self.database().card_count() == 1 new_card = self.database().cards_from_fact(card.fact)[0] new_card.question() new_card.answer() def test_2_to_2_clone(self): fact_data = {"f": "question", "b": "answer"} card_type = self.card_type_with_id("2") card_1, card_2 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) new_card_type = self.controller().\ clone_card_type(card_type, "my_2") self.controller().edit_card_and_sisters(card_1, fact_data, new_card_type, new_tag_names=["default"], correspondence={}) assert self.database().fact_count() == 1 assert self.database().card_count() == 2 new_card = self.database().cards_from_fact(card_1.fact)[0] assert new_card.card_type.id == "2::my_2" assert new_card.fact.data["f"] == "question" assert new_card.fact.data["b"] == "answer" new_card.question() new_card.answer() def test_1_to_3_clone(self): card_type = self.card_type_with_id("1") # Production only. fact_data = {"f": "translation", "b": "foreign"} card = self.controller().create_new_cards(fact_data, card_type, grade=2, tag_names=["default"])[0] new_card_type = self.controller().\ clone_card_type(self.card_type_with_id("3"), "my_language") correspondence = {"f": "m_1", "b": "f"} self.controller().change_card_type([card.fact], card_type, new_card_type, correspondence=correspondence) fact = self.database().fact(card.fact._id, is_id_internal=True) assert fact["f"] == "foreign" card_1, card_2 = self.database().cards_from_fact(fact) assert len(card_1.tags) == 1 assert len(card_2.tags) == 1 for tag in card_1.tags: assert tag.name == "default" for tag in card_2.tags: assert tag.name == "default" assert self.database().con.execute("select tags from cards where _id=?", (card_1._id, )).fetchone()[0] == "default" assert self.database().con.execute("select tags from cards where _id=?", (card_2._id, )).fetchone()[0] == "default" assert card_1.active == True assert card_2.active == True if card_1.fact_view.id == "3.1": # Recognition assert "foreign" in card_1.question() assert "translation" in card_2.question() assert card_1.grade == -1 assert card_2.grade == 2 else: assert "foreign" in card_2.question() assert "translation" in card_1.question() assert card_2.grade == -1 assert card_1.grade == 2 def test_1_to_3_clone_bis(self): card_type = self.card_type_with_id("1") # Production only. fact_data = {"f": "translation", "b": "foreign"} card = self.controller().create_new_cards(fact_data, card_type, grade=2, tag_names=["default"])[0] new_card_type = self.controller().\ clone_card_type(self.card_type_with_id("3"), "my_language") correspondence = {"f": "m_1", "b": "f"} new_fact_data = {"m_1": "translation", "f": "foreign"} self.controller().edit_card_and_sisters(card, new_fact_data, new_card_type, new_tag_names=["default"], correspondence=correspondence) fact = self.database().fact(card.fact._id, is_id_internal=True) assert fact["f"] == "foreign" card_1, card_2 = self.database().cards_from_fact(fact) assert len(card_1.tags) == 1 assert len(card_2.tags) == 1 for tag in card_1.tags: assert tag.name == "default" for tag in card_2.tags: assert tag.name == "default" assert self.database().con.execute("select tags from cards where _id=?", (card_1._id, )).fetchone()[0] == "default" assert self.database().con.execute("select tags from cards where _id=?", (card_2._id, )).fetchone()[0] == "default" assert card_1.active == True assert card_2.active == True if card_1.fact_view.id == "3.1": # Recognition assert "foreign" in card_1.question() assert "translation" in card_2.question() assert card_1.grade == -1 assert card_2.grade == 2 else: assert "foreign" in card_2.question() assert "translation" in card_1.question() assert card_2.grade == -1 assert card_1.grade == 2 def test_convert_duplicates(self): card_type_map = self.card_type_with_id("4") fact_data = {"loc": "test", "blank": "test1", "marked": "test2"} card = self.controller().create_new_cards(fact_data, card_type_map, grade=2, tag_names=["default"])[0] card_type = self.card_type_with_id("1") fact_data = {"f": "test1", "b": "test2"} card = self.controller().create_new_cards(fact_data, card_type, grade=2, tag_names=["default"])[0] correspondence = {"f": "blank", "b": "marked"} new_fact_data = {"loc": "test", "blank": "test1", "marked": "test2"} self.controller().edit_card_and_sisters(card, new_fact_data, card_type_map, new_tag_names=["default"], correspondence=correspondence) def teardown(self): if os.path.exists("a.ogg"): os.remove("a.ogg") MnemosyneTest.teardown(self)
class TestReviewController(MnemosyneTest): def setup(self): global expected_scheduled_count expected_scheduled_count = None self.initialise_data_dir() self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert( 0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator") ) self.mnemosyne.components.append(("mnemosyne.libmnemosyne.ui_components.main_widget", "MainWidget")) self.mnemosyne.components.append(("test_review_controller", "MyReviewWidget")) self.mnemosyne.components.append(("mnemosyne.libmnemosyne.ui_components.dialogs", "EditCardDialog")) self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.review_controller().reset() def test_1(self): card_1 = None self.review_controller().reset() for i in range(10): fact_data = {"f": "question" + str(i), "b": "answer" + str(i)} if i % 2: card_type = self.card_type_with_id("1") else: card_type = self.card_type_with_id("2") card = self.controller().create_new_cards(fact_data, card_type, grade=4, tag_names=["default" + str(i)])[0] if i == 0: card_1 = card card.next_rep -= 1000 * 24 * 60 * 60 self.database().update_card(card) self.review_controller().set_render_chain("default") self.review_controller().show_new_question() self.review_controller().reset_but_try_to_keep_current_card() self.review_controller().show_answer() assert self.review_controller().card == card_1 assert self.review_controller().counters() == (1, 0, 15) self.review_controller().grade_answer(0) assert self.review_controller().counters() == (0, 1, 15) self.review_controller().grade_answer(2) assert self.review_controller().counters() == (0, 0, 15) self.review_controller().next_rep_string(0) self.review_controller().next_rep_string(1) self.review_controller().next_rep_string(2) def test_2(self): card_1 = None self.review_controller().reset() for i in range(10): fact_data = {"f": "question" + str(i), "b": "answer" + str(i)} if i % 2: card_type = self.card_type_with_id("1") else: card_type = self.card_type_with_id("2") card = self.controller().create_new_cards(fact_data, card_type, grade=4, tag_names=["default" + str(i)])[0] if i == 0: card_1 = card card.next_rep -= 1000 * 24 * 60 * 60 self.database().update_card(card) self.review_controller().show_new_question() assert self.review_controller().card == card_1 self.review_controller().reload_counters() assert self.review_controller().counters() == (1, 0, 15) self.review_controller().grade_answer(0) self.review_controller().reload_counters() assert self.review_controller().counters() == (0, 1, 15) self.review_controller().grade_answer(2) self.review_controller().reload_counters() assert self.review_controller().counters() == (0, 0, 15) self.mnemosyne.review_widget().set_grade_enabled(1, True) def test_reset_but_try_to_keep_current_card_turned_inactive(self): card_type = self.card_type_with_id("1") fact_data = {"f": "1", "b": "b"} card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["forbidden"])[0] self.review_controller().show_new_question() assert self.review_controller().card == card c = DefaultCriterion(self.mnemosyne.component_manager) c.deactivated_card_type_fact_view_ids = set() c._tag_ids_active = set([self.database().get_or_create_tag_with_name("active")._id]) c._tag_ids_forbidden = set([self.database().get_or_create_tag_with_name("forbidden")._id]) self.database().set_current_criterion(c) assert self.database().active_count() == 0 assert self.review_controller().card == card self.review_controller().reset_but_try_to_keep_current_card() assert self.review_controller().card is None def test_last_card(self): card_type = self.card_type_with_id("1") for data in ["1", "2", "3"]: fact_data = {"f": data, "b": data} self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=[]) self.review_controller().show_new_question() self.review_controller().show_answer() for i in range(5): self.review_controller().grade_answer(0) self.review_controller().show_answer() for i in range(2): self.review_controller().grade_answer(2) self.review_controller().show_answer() for i in range(6): self.review_controller().grade_answer(0) self.review_controller().show_answer() def test_counters(self): global expected_scheduled_count card_type = self.card_type_with_id("1") fact_data = {"f": "1", "b": "1"} card = self.controller().create_new_cards(fact_data, card_type, grade=5, tag_names=[])[0] card.next_rep = 0 self.database().update_card(card) expected_scheduled_count = 1 self.review_controller().show_new_question() assert self.review_controller().scheduled_count == 1 assert self.review_controller().counters()[0] == 1 self.review_controller().show_answer() expected_scheduled_count = 0 self.review_controller().grade_answer(0) assert self.review_controller().scheduled_count == 0 assert self.review_controller().counters()[0] == 0 def test_counters_prefetch(self): global expected_scheduled_count card_type = self.card_type_with_id("1") for data in ["1", "2", "3", "4"]: fact_data = {"f": data, "b": data} card = self.controller().create_new_cards(fact_data, card_type, grade=5, tag_names=[])[0] card.next_rep = 0 self.database().update_card(card) expected_scheduled_count = 4 self.review_controller().show_new_question() assert self.review_controller().scheduled_count == 4 assert self.review_controller().counters()[0] == 4 self.review_controller().show_answer() expected_scheduled_count = 3 self.review_controller().grade_answer(3) assert self.review_controller().scheduled_count == 3 assert self.review_controller().counters()[0] == 3
class TestAddCards(MnemosyneTest): def setup(self): os.system("rm -fr dot_test") self.mnemosyne = Mnemosyne() self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_add_cards", "Widget")) self.mnemosyne.components.append(\ ("mnemosyne.libmnemosyne.ui_components.review_widget", "ReviewWidget")) self.mnemosyne.initialise(os.path.abspath("dot_test")) self.review_controller().reset() def test_1(self): fact_data = {"q": "question", "a": "answer"} card_type = self.card_type_by_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.controller().file_save() assert self.database().fact_count() == 1 assert self.database().card_count() == 1 def test_src(self): fact_data = {"q": """<font face="courier">src</font>""", "a": "answer"} card_type = self.card_type_by_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] card.question() self.controller().file_save() assert self.database().fact_count() == 1 assert self.database().card_count() == 1 def test_comparisons(self): fact_data = {"q": "question", "a": "answer"} card_type = self.card_type_by_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.controller().file_save() assert card == card assert card.fact == card.fact assert card.fact_view == card.fact_view class A(object): pass a = A() assert card != a assert card.fact != a assert card.fact_view != a tag = card.tags.pop() assert tag == tag assert tag != a def test_1_duplicates(self): fact_data = {"q": "question", "a": "answer"} card_type = self.card_type_by_id("1") self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) self.controller().file_save() self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) assert self.database().fact_count() == 1 assert self.database().card_count() == 1 def test_2(self): fact_data = {"q": "question", "a": "answer"} card_type = self.card_type_by_id("2") self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) self.controller().file_save() assert self.database().fact_count() == 1 assert self.database().card_count() == 2 def test_3(self): fact_data = {"f": "foreign word", "p": "pronunciation", "t": "translation"} card_type = self.card_type_by_id("3") self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"]) self.controller().file_save() assert self.database().fact_count() == 1 assert self.database().card_count() == 2 def test_delete(self): fact_data = {"q": "question1", "a": "answer1"} card_type = self.card_type_by_id("1") card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact_data = {"q": "question2", "a": "answer2"} card_2 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] assert set(tag.name for tag in card_1.tags) == \ set(tag.name for tag in card_2.tags) fact_data = {"q": "question3", "a": "answer3"} card_3 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.review_controller().new_question() assert self.review_controller().card == card_1 self.review_controller().grade_answer(0) self.database().delete_fact_and_related_data(card_3.fact) self.review_controller().reset() for i in range(6): assert self.review_controller().card != card_3 self.review_controller().grade_answer(0) def test_delete_2(self): fact_data = {"q": "question1", "a": "answer1"} card_type = self.card_type_by_id("1") card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact_data = {"q": "question2", "a": "answer2"} card_2 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] assert set(tag.name for tag in card_1.tags) == \ set(tag.name for tag in card_2.tags) fact_data = {"q": "question3", "a": "answer3"} card_3 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.review_controller().new_question() assert self.review_controller().card == card_1 self.controller().delete_current_fact() for i in range(6): assert self.review_controller().card != card_1 self.review_controller().grade_answer(0) def test_change_tag(self): fact_data = {"q": "question", "a": "answer"} card_type = self.card_type_by_id("1") card = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.review_controller().new_question() self.controller().update_related_cards(card.fact, fact_data, \ card_type, ["new"], correspondence={}) new_card = self.database().get_card(card._id, id_is_internal=True) tag_names = [tag.name for tag in new_card.tags] assert len(tag_names) == 1 assert "new" in tag_names
class TestMemImport(MnemosyneTest): def setup(self): self.initialise_data_dir() self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("mnemosyne_test", "TestReviewWidget")) self.mnemosyne.components.append(\ ("test_mem_import", "Widget")) self.mnemosyne.components.append(\ ("test_mem_import", "MyImportDialog")) self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.review_controller().reset() def mem_importer(self): for format in self.mnemosyne.component_manager.all("file_format"): if format.__class__.__name__ == "Mnemosyne1Mem": return format def test_file_not_found(self): filename = os.path.join(os.getcwd(), "tests", "files", "nothere.mem") self.mem_importer().do_import(filename) assert last_error.startswith("Unable to open") def test_card_type_1(self): filename = os.path.join(os.getcwd(), "tests", "files", "1sided.mem") self.mem_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 1 card = self.review_controller().card assert card.grade == 2 assert card.easiness == 2.5 assert card.acq_reps == 1 assert card.ret_reps == 0 assert card.lapses == 0 assert card.acq_reps_since_lapse == 1 assert card.ret_reps_since_lapse == 0 assert [tag.name for tag in card.tags] == ["__UNTAGGED__"] assert card.last_rep == 1247529600 assert card.next_rep == 1247616000 assert card.id == "9cff728f" def test_card_type_1_unseen(self): filename = os.path.join(os.getcwd(), "tests", "files", "1sided_unseen.mem") self.mem_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 1 card = self.review_controller().card assert card.grade == -1 assert card.easiness == 2.5 assert card.acq_reps == 0 assert card.ret_reps == 0 assert card.lapses == 0 assert card.acq_reps_since_lapse == 0 assert card.ret_reps_since_lapse == 0 assert card.last_rep == -1 assert card.next_rep == -1 assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 def test_card_type_1_edited(self): filename = os.path.join(os.getcwd(), "tests", "files", "1sided.mem") self.mem_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 1 card = self.review_controller().card assert card.id == "9cff728f" assert "question" in card.question() filename = os.path.join(os.getcwd(), "tests", "files", "1sided.mem") self.mem_importer().do_import(filename) assert last_error.startswith("These cards seem to have been imported before") def test_card_type_2(self): filename = os.path.join(os.getcwd(), "tests", "files", "2sided.mem") self.mem_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 2 card_1 = self.review_controller().card assert "question" in card_1.question() assert "answer" in card_1.answer() cards = self.database().cards_from_fact(card_1.fact) if cards[0] == card_1: card_2 = cards[1] else: card_2 = cards[0] assert "question" in card_2.answer() assert "answer" in card_2.question() assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 2 def test_card_type_3(self): filename = os.path.join(os.getcwd(), "tests", "files", "3sided.mem") self.mem_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 2 card_1 = self.review_controller().card assert card_1.fact.data == {"f": "f", "p_1": "p", "m_1": "t"} assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 2 def test_card_type_3_corrupt(self): filename = os.path.join(os.getcwd(), "tests", "files", "3sided_corrupt.mem") self.mem_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 2 card_1 = self.review_controller().card assert card_1.fact.data == {"f": "f", "m_1": "t"} assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 2 def test_card_type_3_missing(self): filename = os.path.join(os.getcwd(), "tests", "files", "3sided_missing.mem") self.mem_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 1 card_1 = self.review_controller().card assert card_1.fact.data == {"f": "t", "b": "f\np"} assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 def test_media(self): os.mkdir(os.path.join(os.getcwd(), "tests", "files", "figs")) os.mkdir(os.path.join(os.getcwd(), "tests", "files", "figs", "figs")) figures = [\ os.path.join(os.getcwd(), "tests", "files", "a.png"), os.path.join(os.getcwd(), "tests", "files", "figs", "a.png"), os.path.join(os.getcwd(), "tests", "files", "figs", "figs", "a.png")] for filename in figures: file(filename, "w") filename = os.path.join(os.getcwd(), "tests", "files", "media.mem") self.mem_importer().do_import(filename) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "a.png")) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "figs", "a.png")) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "figs", "a.png")) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 3 def test_media_missing(self): os.mkdir(os.path.join(os.getcwd(), "tests", "files", "figs")) os.mkdir(os.path.join(os.getcwd(), "tests", "files", "figs", "figs")) figures = [\ os.path.join(os.getcwd(), "tests", "files", "a.png"), os.path.join(os.getcwd(), "tests", "files", "figs", "a.png")] for filename in figures: file(filename, "w") filename = os.path.join(os.getcwd(), "tests", "files", "media.mem") self.mem_importer().do_import(filename) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "a.png")) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "figs", "a.png")) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 2 def test_media_missing_2(self): filename = os.path.join(os.getcwd(), "tests", "files", "media.mem") self.mem_importer().do_import(filename) assert not os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "a.png")) assert not os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "figs", "a.png")) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 0 def test_media_slashes(self): os.mkdir(os.path.join(os.getcwd(), "tests", "files", "figs")) os.mkdir(os.path.join(os.getcwd(), "tests", "files", "figs", "figs")) figures = [\ os.path.join(os.getcwd(), "tests", "files", "a.png"), os.path.join(os.getcwd(), "tests", "files", "figs", "a.png"), os.path.join(os.getcwd(), "tests", "files", "figs", "figs", "a.png")] for filename in figures: file(filename, "w") filename = os.path.join(os.getcwd(), "tests", "files", "media_slashes.mem") self.mem_importer().do_import(filename) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "a.png")) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "figs", "a.png")) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "figs", "a.png")) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 3 def test_media_quotes(self): filename = os.path.join(os.getcwd(), "tests", "files", "basedir_media", "default.mem") self.mem_importer().do_import(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 1 def test_sound(self): os.mkdir(os.path.join(\ os.getcwd(), "tests", "files", "soundfiles")) soundname = os.path.join(os.path.join(\ os.getcwd(), "tests", "files", "soundfiles", "a.ogg")) file(soundname, "w") filename = os.path.join(os.getcwd(), "tests", "files", "sound.mem") self.mem_importer().do_import(filename) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "soundfiles", "a.ogg")) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 1 self.review_controller().reset() card = self.review_controller().card assert card.fact["f"] == """<audio src="soundfiles/a.ogg">""" def test_map(self): filename = os.path.join(os.getcwd(), "tests", "files", "map.mem") self.mem_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 2 card = self.review_controller().card assert card.fact["loc"] == "<b>Drenthe</b>" assert card.fact["marked"] == \ """<img src_missing="maps/Netherlands-Provinces/Drenthe.png">""" assert card.fact["blank"] == \ """<img src_missing="maps/Netherlands-Provinces/Netherlands-Provinces.png">""" def test_dups(self): filename = os.path.join(os.getcwd(), "tests", "files", "dups.mem") self.mem_importer().do_import(filename) self.review_controller().reset() assert self.review_controller().card.fact["loc"] == \ u"""<b>Freistaat Th\xfcringen (Free State of Thuringia)</b>""" assert self.review_controller().card.tag_string() == "Germany: States, MISSING_MEDIA" def test_logs_new_1(self): self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "new_1.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.REPETITION, )).fetchone()[0] == 10 assert self.database().con.execute(\ "select acq_reps from log where event_type=? and object_id='9525224f'", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select acq_reps_since_lapse from log where event_type=? and object_id='9525224f'", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ """select scheduled_interval from log where event_type=? and object_id='9525224f' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] == (6)*60*60*24 assert self.database().con.execute(\ """select actual_interval from log where event_type=? and object_id='9525224f' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] == 0 # This is an artificial log. timestamp = self.database().con.execute(\ """select timestamp from log where event_type=? and object_id='9525224f' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] next_rep = self.database().con.execute(\ """select next_rep from log where event_type=? and object_id='9525224f' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] assert next_rep - timestamp == (14-3)*60*60*24 assert self.database().con.execute(\ "select count() from log").fetchone()[0] == 25 assert self.database().con.execute(\ "select acq_reps from log where event_type=? order by _id desc limit 1", (EventTypes.LOADED_DATABASE, )).fetchone()[0] == 0 assert self.database().con.execute(\ "select ret_reps from log where event_type=? order by _id desc limit 1", (EventTypes.LOADED_DATABASE, )).fetchone()[0] == 7 assert self.database().con.execute(\ "select lapses from log where event_type=? order by _id desc limit 1", (EventTypes.LOADED_DATABASE, )).fetchone()[0] == 336 assert self.database().con.execute(\ "select acq_reps from log where event_type=? order by _id desc limit 1", (EventTypes.SAVED_DATABASE, )).fetchone()[0] == 0 assert self.database().con.execute(\ "select ret_reps from log where event_type=? order by _id desc limit 1", (EventTypes.SAVED_DATABASE, )).fetchone()[0] == 12 assert self.database().con.execute(\ "select lapses from log where event_type=? order by _id desc limit 1", (EventTypes.SAVED_DATABASE, )).fetchone()[0] == 341 def test_logs_new_2(self): self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "new_2.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select acq_reps from log where event_type=? and object_id='8da62cfb'", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select acq_reps_since_lapse from log where event_type=? and object_id='8da62cfb'", (EventTypes.REPETITION, )).fetchone()[0] == 1 def test_logs_new_3(self): self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "new_3.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.REPETITION, )).fetchone()[0] == 4 assert self.database().con.execute(\ "select acq_reps from log where event_type=? and object_id='5106b621'", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select acq_reps_since_lapse from log where event_type=? and object_id='5106b621'", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ """select acq_reps from log where event_type=? and object_id='5106b621' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ """select acq_reps_since_lapse from log where event_type=? and object_id='5106b621' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] == 1 def test_logs_new_4(self): self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "new_4.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.REPETITION, )).fetchone()[0] == 2 assert self.database().con.execute(\ "select acq_reps from log where event_type=? and object_id='b7601e0c'", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select ret_reps from log where event_type=? and object_id='b7601e0c'", (EventTypes.REPETITION, )).fetchone()[0] == 0 assert self.database().con.execute(\ "select acq_reps_since_lapse from log where event_type=? and object_id='b7601e0c'", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ """select acq_reps from log where event_type=? and object_id='b7601e0c' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ """select ret_reps from log where event_type=? and object_id='b7601e0c' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ """select acq_reps_since_lapse from log where event_type=? and object_id='b7601e0c' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] == 1 def test_logs_new_5(self): self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "new_5.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.REPETITION, )).fetchone()[0] == 2 assert self.database().con.execute(\ "select acq_reps from log where event_type=? and object_id='9c8ce28e-1a4b-4148-8287-b8a7790d86d0.1.1'", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select ret_reps from log where event_type=? and object_id='9c8ce28e-1a4b-4148-8287-b8a7790d86d0.1.1'", (EventTypes.REPETITION, )).fetchone()[0] == 0 assert self.database().con.execute(\ "select acq_reps_since_lapse from log where event_type=? and object_id='9c8ce28e-1a4b-4148-8287-b8a7790d86d0.1.1'", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ """select acq_reps from log where event_type=? and object_id='9c8ce28e-1a4b-4148-8287-b8a7790d86d0.1.1' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] == 2 assert self.database().con.execute(\ """select ret_reps from log where event_type=? and object_id='9c8ce28e-1a4b-4148-8287-b8a7790d86d0.1.1' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] == 0 assert self.database().con.execute(\ """select acq_reps_since_lapse from log where event_type=? and object_id='9c8ce28e-1a4b-4148-8287-b8a7790d86d0.1.1' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] == 2 assert self.database().con.execute(\ """select object_id from log where event_type=?""", (EventTypes.STARTED_SCHEDULER, )).fetchone()[0] == "SM2 Mnemosyne" def test_logs_new_6(self): self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "new_6.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.REPETITION, )).fetchone()[0] == 2 sql_res = self.database().con.execute(\ "select * from log where event_type=? and object_id='4c53e29a-f9e9-498b-8beb-d3a494f61bca.1.1'", (EventTypes.REPETITION, )).fetchone() assert sql_res[4] == 5 assert sql_res[5] == 2.5 assert sql_res[6] == 1 assert sql_res[7] == 0 assert sql_res[8] == 0 assert sql_res[9] == 1 assert sql_res[10] == 0 assert sql_res[11] == 0 assert sql_res[12] == 0 assert sql_res[14] - sql_res[2] == 345600 assert sql_res[13] == 0 sql_res = self.database().con.execute(\ """select * from log where event_type=? and object_id='4c53e29a-f9e9-498b-8beb-d3a494f61bca.1.1' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone() assert sql_res[4] == 2 assert sql_res[5] == 2.5 assert sql_res[6] == 1 assert sql_res[7] == 1 assert sql_res[8] == 0 assert sql_res[9] == 1 assert sql_res[10] == 1 assert sql_res[11] == 302986 assert sql_res[12] == 10 assert sql_res[14] - sql_res[2] == 475774 assert sql_res[13] == 1 def test_logs_imported_1(self): self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "imported_1.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.REPETITION, )).fetchone()[0] == 3 assert self.database().con.execute(\ "select acq_reps from log where event_type=? and object_id='f5d9bbe7'", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select ret_reps from log where event_type=? and object_id='f5d9bbe7'", (EventTypes.REPETITION, )).fetchone()[0] == 0 assert self.database().con.execute(\ "select acq_reps_since_lapse from log where event_type=? and object_id='f5d9bbe7'", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ """select acq_reps from log where event_type=? and object_id='f5d9bbe7' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ """select ret_reps from log where event_type=? and object_id='f5d9bbe7' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] == 2 assert self.database().con.execute(\ """select acq_reps_since_lapse from log where event_type=? and object_id='f5d9bbe7' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] == 1 def test_logs_imported_2(self): self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "imported_2.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select acq_reps from log where event_type=? and object_id='14670f10'", (EventTypes.REPETITION, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select ret_reps from log where event_type=? and object_id='14670f10'", (EventTypes.REPETITION, )).fetchone()[0] == 0 assert self.database().con.execute(\ "select acq_reps_since_lapse from log where event_type=? and object_id='14670f10'", (EventTypes.REPETITION, )).fetchone()[0] == 1 def test_logs_imported_3(self): self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "imported_3.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 def test_restored_1(self): self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "restored_1.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.REPETITION, )).fetchone()[0] == 1 sql_res = self.database().con.execute(\ "select * from log where event_type=?", (EventTypes.REPETITION, )).fetchone() assert sql_res[4] == 1 assert sql_res[5] == 2.36 assert sql_res[6] == 23 assert sql_res[7] == 8 assert sql_res[8] == 2 assert sql_res[9] == 0 assert sql_res[10] == 0 assert sql_res[11] == 89 * 24 * 60 * 60 assert sql_res[12] == 0 # No last rep data. assert sql_res[14] - sql_res[2] == 0 assert sql_res[13] == 5 def test_restored_2(self): self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "restored_2.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 def test_logs_act_interval(self): self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "actinterval_1.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ """select actual_interval from log where event_type=? and object_id='f1300e5a' order by _id desc limit 1""", (EventTypes.REPETITION, )).fetchone()[0] == 5 def test_logs_deleted(self): self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "delete_1.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.DELETED_CARD, )).fetchone()[0] == 1 def test_logs_corrupt_1(self): # Wrong data, missing creation event. self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "corrupt_1.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select count() from log where object_id=?", ("4b59b830", )).fetchone()[0] == 3 def test_logs_corrupt_2(self): # Wrong data, isolated deletion event. self.database().update_card_after_log_import = (lambda x, y, z: 0) self.database().before_1x_log_import() filename = os.path.join(os.getcwd(), "tests", "files", "corrupt_2.txt") ScienceLogParser(self.database()).parse(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 0 assert self.database().con.execute(\ "select count() from log where object_id=?", ("4b59b830", )).fetchone()[0] == 0 def test_two_mem_files_sharing_same_logs(self): filename = os.path.join(os.getcwd(), "tests", "files", "basedir_2_mem", "deck1.mem") self.mem_importer().do_import(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.REPETITION, )).fetchone()[0] == 1 filename = os.path.join(os.getcwd(), "tests", "files", "basedir_2_mem", "deck2.mem") self.mem_importer().do_import(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.REPETITION, )).fetchone()[0] == 3 assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 2 card = self.database().card("4c8fff73", is_id_internal=False) assert self.database().average_thinking_time(card) == 1.5 assert self.database().total_thinking_time(card) == 3.0 assert self.database().card_count_for_grade(0, active_only=True) == 2 tag = self.database().get_or_create_tag_with_name("666") assert self.database().card_count_for_grade_and_tag(0, tag, active_only=True) == 0 from mnemosyne.libmnemosyne.statistics_pages.grades import Grades page = Grades(self.mnemosyne.component_manager) page.prepare_statistics(tag._id) assert page.y == [0, 0, 0, 0, 0, 0, 0] page.prepare_statistics(-1) assert page.y == [0, 2, 0, 0, 0, 0, 0] def test_bz2(self): filename = os.path.join(os.getcwd(), "tests", "files", "basedir_bz2", "default.mem") self.mem_importer().do_import(filename) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.REPETITION, )).fetchone()[0] == 0 assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 assert self.database().con.execute(\ "select count() from log where object_id=?", ("82f2ed0d", )).fetchone()[0] == 0 def test_sch(self): self.controller().show_import_file_dialog() assert self.database().card_count_scheduled_n_days_ago(0) == 1 def test_upgrade(self): old_data_dir = os.path.join(os.getcwd(), "tests", "files", "basedir_bz2") from mnemosyne.libmnemosyne.upgrades.upgrade1 import Upgrade1 Upgrade1(self.mnemosyne.component_manager).upgrade_from_old_data_dir(old_data_dir) assert self.config()["dvipng"].rstrip() == \ "dvipng -D 300 -T tight tmp.dvi\necho" assert "14pt" in self.config()["latex_preamble"] assert self.config()["user_id"] == "f3fb13c7" assert self.log().log_index_of_last_upload() == 2 assert os.path.exists(os.path.join(old_data_dir, "DIRECTORY_NO_LONGER_USED_BY_MNEMOSYNE2")) assert os.path.exists(os.path.join(self.mnemosyne.config().data_dir, "history", "a_2.bz2")) log = file(os.path.join(self.mnemosyne.config().data_dir, "log.txt")) assert log.readline().strip() == \ "2005-11-01 09:29:08 : Imported item 82f2ed0d 0 0 0 0 0" def teardown(self): filename = os.path.join(os.getcwd(), "tests", "files", "basedir_bz2", "DIRECTORY_NO_LONGER_USED_BY_MNEMOSYNE2") if os.path.exists(filename): os.remove(filename) filename = os.path.join(os.getcwd(), "tests", "files", "a.png") if os.path.exists(filename): os.remove(filename) filename = os.path.join(os.getcwd(), "tests", "files", "a.ogg") if os.path.exists(filename): os.remove(filename) dirname = os.path.join(os.getcwd(), "tests", "files", "figs") if os.path.exists(dirname): shutil.rmtree(dirname) dirname = os.path.join(os.getcwd(), "tests", "files", "soundfiles") if os.path.exists(dirname): shutil.rmtree(dirname) MnemosyneTest.teardown(self)
class TestMnemosyne1XMLImport(MnemosyneTest): def setup(self): self.initialise_data_dir() self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("mnemosyne_test", "TestReviewWidget")) self.mnemosyne.components.append(\ ("test_mnemosyne1xml_import", "Widget")) self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) self.review_controller().reset() def xml_importer(self): for format in self.mnemosyne.component_manager.all("file_format"): if format.__class__.__name__ == "Mnemosyne1XML": return format def test_file_not_found(self): filename = os.path.join(os.getcwd(), "tests", "files", "nothere.xml") self.xml_importer().do_import(filename) assert last_error.startswith("Unable to open") def test_wrong_format(self): filename = os.path.join(os.getcwd(), "tests", "files", "wrong_format.xml") self.xml_importer().do_import(filename) assert last_error.startswith("Unable to parse") def test_bad_version(self): filename = os.path.join(os.getcwd(), "tests", "files", "bad_version.xml") self.xml_importer().do_import(filename) assert last_error.startswith("XML file does not seem") def test_card_type_1(self): global answer answer = 0 filename = os.path.join(os.getcwd(), "tests", "files", "1sided.xml") self.xml_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 4 card = self.review_controller().card assert card.grade == 2 assert card.easiness == 2.5 assert card.acq_reps == 1 assert card.ret_reps == 0 assert card.lapses == 0 assert card.acq_reps_since_lapse == 1 assert card.ret_reps_since_lapse == 0 assert [tag.name for tag in card.tags] == ["__UNTAGGED__"] assert card.last_rep == 1247529600 assert card.next_rep == 1247616000 assert card.id == "9cff728f" def test_card_type_1_abort(self): global answer answer = 1 filename = os.path.join(os.getcwd(), "tests", "files", "1sided.xml") self.xml_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 0 def test_card_type_1_unseen(self): global answer answer = 0 filename = os.path.join(os.getcwd(), "tests", "files", "1sided_unseen.xml") self.xml_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 1 card = self.review_controller().card assert card.grade == -1 assert card.easiness == 2.5 assert card.acq_reps == 0 assert card.ret_reps == 0 assert card.lapses == 0 assert card.acq_reps_since_lapse == 0 assert card.ret_reps_since_lapse == 0 assert card.last_rep == -1 assert card.next_rep == -1 assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 def test_card_type_1_edited(self): filename = os.path.join(os.getcwd(), "tests", "files", "1sided.xml") self.xml_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 4 card = self.review_controller().card assert card.id == "9cff728f" assert "question" in card.question() filename = os.path.join(os.getcwd(), "tests", "files", "1sided.xml") self.xml_importer().do_import(filename) assert last_error.startswith("These cards seem to have been imported before") def test_card_type_2(self): global answer answer = 0 filename = os.path.join(os.getcwd(), "tests", "files", "2sided.xml") self.xml_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 2 card_1 = self.review_controller().card assert "question" in card_1.question() assert "answer" in card_1.answer() cards = self.database().cards_from_fact(card_1.fact) if cards[0] == card_1: card_2 = cards[1] else: card_2 = cards[0] assert "question" in card_2.answer() assert "answer" in card_2.question() assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 2 def test_card_type_3(self): global answer answer = 0 filename = os.path.join(os.getcwd(), "tests", "files", "3sided.xml") self.xml_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 2 card_1 = self.review_controller().card assert card_1.fact.data == {"f": "f", "p_1": "p", "m_1": "t"} assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 2 def test_card_type_3_corrupt(self): global answer answer = 0 filename = os.path.join(os.getcwd(), "tests", "files", "3sided_corrupt.xml") self.xml_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 2 card_1 = self.review_controller().card assert card_1.fact.data == {"f": "f", "m_1": "t"} assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 2 def test_card_type_3_missing(self): global answer answer = 0 filename = os.path.join(os.getcwd(), "tests", "files", "3sided_missing.xml") self.xml_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 1 card_1 = self.review_controller().card assert card_1.fact.data == {"f": "t", "b": "f\np"} assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_CARD, )).fetchone()[0] == 1 def test_media(self): global answer answer = 0 os.mkdir(os.path.join(os.getcwd(), "tests", "files", "figs")) os.mkdir(os.path.join(os.getcwd(), "tests", "files", "figs", "figs")) figures = [\ os.path.join(os.getcwd(), "tests", "files", "a.png"), os.path.join(os.getcwd(), "tests", "files", "figs", "a.png"), os.path.join(os.getcwd(), "tests", "files", "figs", "figs", "a.png")] for filename in figures: file(filename, "w") filename = os.path.join(os.getcwd(), "tests", "files", "media.xml") self.xml_importer().do_import(filename) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "a.png")) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "figs", "a.png")) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "figs", "a.png")) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 3 def test_media_missing(self): global answer answer = 0 os.mkdir(os.path.join(os.getcwd(), "tests", "files", "figs")) os.mkdir(os.path.join(os.getcwd(), "tests", "files", "figs", "figs")) figures = [\ os.path.join(os.getcwd(), "tests", "files", "a.png"), os.path.join(os.getcwd(), "tests", "files", "figs", "a.png")] for filename in figures: file(filename, "w") filename = os.path.join(os.getcwd(), "tests", "files", "media.xml") self.xml_importer().do_import(filename) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "a.png")) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "figs", "a.png")) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 2 def test_media_missing_2(self): global answer answer = 0 filename = os.path.join(os.getcwd(), "tests", "files", "media.xml") self.xml_importer().do_import(filename) assert not os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "a.png")) assert not os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "figs", "a.png")) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 0 def test_media_slashes(self): global answer answer = 0 os.mkdir(os.path.join(os.getcwd(), "tests", "files", "figs")) os.mkdir(os.path.join(os.getcwd(), "tests", "files", "figs", "figs")) figures = [\ os.path.join(os.getcwd(), "tests", "files", "a.png"), os.path.join(os.getcwd(), "tests", "files", "figs", "a.png"), os.path.join(os.getcwd(), "tests", "files", "figs", "figs", "a.png")] for filename in figures: file(filename, "w") filename = os.path.join(os.getcwd(), "tests", "files", "media_slashes.xml") self.xml_importer().do_import(filename) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "a.png")) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "figs", "a.png")) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "figs", "a.png")) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 3 def test_sound(self): global answer answer = 0 os.mkdir(os.path.join(\ os.getcwd(), "tests", "files", "soundfiles")) soundname = os.path.join(os.path.join(\ os.getcwd(), "tests", "files", "soundfiles", "a.ogg")) file(soundname, "w") filename = os.path.join(os.getcwd(), "tests", "files", "sound.xml") self.xml_importer().do_import(filename) assert os.path.exists(os.path.join(\ os.path.abspath("dot_test"), "default.db_media", "soundfiles", "a.ogg")) assert self.database().con.execute(\ "select count() from log where event_type=?", (EventTypes.ADDED_MEDIA_FILE, )).fetchone()[0] == 1 self.review_controller().reset() card = self.review_controller().card assert card.fact["f"] == """<audio src="soundfiles/a.ogg">""" def test_map(self): filename = os.path.join(os.getcwd(), "tests", "files", "map.xml") self.xml_importer().do_import(filename) self.review_controller().reset() assert self.database().card_count() == 2 card = self.review_controller().card assert card.fact["loc"] == "<b>Drenthe</b>" assert card.fact["marked"] == \ """<img src_missing="maps/Netherlands-Provinces/Drenthe.png">""" assert card.fact["blank"] == \ """<img src_missing="maps/Netherlands-Provinces/Netherlands-Provinces.png">""" def test_dups(self): global answer answer = 0 filename = os.path.join(os.getcwd(), "tests", "files", "dups.xml") self.xml_importer().do_import(filename) self.review_controller().reset() assert self.review_controller().card.fact["loc"] == \ u"""<b>Freistaat Th\xfcringen (Free State of Thuringia)</b>""" assert self.review_controller().card.tag_string() == "Germany: States, MISSING_MEDIA" def test_anon_id(self): global answer answer = 0 filename = os.path.join(os.getcwd(), "tests", "files", "anon_id.xml") self.xml_importer().do_import(filename) self.review_controller().reset() fact = self.review_controller().card.fact for card in self.database().cards_from_fact(fact): assert not card.id.startswith("_") assert self.database().card_count() == 2 def test_anon_id_2(self): global answer, last_error answer = 0 last_error = None filename = os.path.join(os.getcwd(), "tests", "files", "anon_id.xml") self.xml_importer().do_import(filename) assert last_error == None self.xml_importer().do_import(filename) assert last_error == None self.review_controller().reset() fact = self.review_controller().card.fact for card in self.database().cards_from_fact(fact): assert not card.id.startswith("_") assert self.database().card_count() == 4 def test_no_id(self): global answer answer = 0 filename = os.path.join(os.getcwd(), "tests", "files", "no_id.xml") self.xml_importer().do_import(filename) self.review_controller().reset() fact = self.review_controller().card.fact for card in self.database().cards_from_fact(fact): assert card.id def test_bad_xml(self): global answer answer = 0 filename = os.path.join(os.getcwd(), "tests", "files", "bad_xml.xml") self.xml_importer().do_import(filename) assert last_error.startswith("Unable to parse") def test_tags(self): global answer answer = 0 filename = os.path.join(os.getcwd(), "tests", "files", "tag.xml") self.xml_importer().do_import(filename, extra_tag_names="extra") self.review_controller().reset() assert len(self.review_controller().card.tags) == 2 def test_log(self): global answer answer = 0 filename = os.path.join(os.getcwd(), "tests", "files", "sound.xml") self.xml_importer().do_import(filename) ids = [cursor[0] for cursor in self.database().con.execute(\ "select distinct object_id from log where event_type='6' or event_type='7'")] assert ids == ['ef2e21e1'] def teardown(self): global answer answer = 0 filename = os.path.join(os.getcwd(), "tests", "files", "basedir_bz2", "DIRECTORY_NO_LONGER_USED_BY_MNEMOSYNE2") if os.path.exists(filename): os.remove(filename) filename = os.path.join(os.getcwd(), "tests", "files", "a.png") if os.path.exists(filename): os.remove(filename) filename = os.path.join(os.getcwd(), "tests", "files", "a.ogg") if os.path.exists(filename): os.remove(filename) dirname = os.path.join(os.getcwd(), "tests", "files", "figs") if os.path.exists(dirname): shutil.rmtree(dirname) dirname = os.path.join(os.getcwd(), "tests", "files", "soundfiles") if os.path.exists(dirname): shutil.rmtree(dirname) MnemosyneTest.teardown(self)
class TestCrammingScheduler(MnemosyneTest): def setup(self): self.initialise_data_dir() self.mnemosyne = Mnemosyne(upload_science_logs=False, interested_in_old_reps=True, asynchronous_database=True) self.mnemosyne.components.insert(0, ("mnemosyne.libmnemosyne.translators.gettext_translator", "GetTextTranslator")) self.mnemosyne.components.append(\ ("test_cramming", "Widget")) self.mnemosyne.components.append(\ ("mnemosyne_test", "TestReviewWidget")) self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) from mnemosyne.libmnemosyne.plugins.cramming_plugin import CrammingPlugin for plugin in self.plugins(): if isinstance(plugin, CrammingPlugin): plugin.activate() break self.mnemosyne.start_review() def test_1(self): from mnemosyne.libmnemosyne.schedulers.cramming import Cramming card_type = self.card_type_with_id("1") fact_data = {"f": "1", "b": "b"} card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact_data = {"f": "2", "b": "b"} card_2 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact_data = {"f": "3", "b": "b"} card_3 = self.controller().create_new_cards(fact_data, card_type, grade=2, tag_names=["default"])[0] fact_data = {"f": "4", "b": "b"} card_4 = self.controller().create_new_cards(fact_data, card_type, grade=2, tag_names=["default"])[0] card_4.next_rep -= 1000 self.database().update_card(card_4) self.review_controller().start_review() assert self.database().scheduler_data_count(Cramming.UNSEEN) == 4 assert self.database().scheduler_data_count(Cramming.WRONG) == 0 self.review_controller().grade_answer(0) assert self.database().scheduler_data_count(Cramming.UNSEEN) == 3 assert self.database().scheduler_data_count(Cramming.WRONG) == 1 self.review_controller().grade_answer(5) assert self.database().scheduler_data_count(Cramming.UNSEEN) == 2 assert self.database().scheduler_data_count(Cramming.WRONG) == 1 # Fail the cards a couple of times. for i in range(8): self.review_controller().grade_answer(0) # Pass the cards a couple of times. for i in range(8): self.review_controller().grade_answer(5) def test_reset(self): from mnemosyne.libmnemosyne.schedulers.cramming import Cramming card_type = self.card_type_with_id("1") fact_data = {"f": "1", "b": "b"} card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact_data = {"f": "2", "b": "b"} card_2 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] fact_data = {"f": "3", "b": "b"} card_3 = self.controller().create_new_cards(fact_data, card_type, grade=2, tag_names=["default"])[0] fact_data = {"f": "4", "b": "b"} card_4 = self.controller().create_new_cards(fact_data, card_type, grade=2, tag_names=["default"])[0] card_4.next_rep -= 1000 self.database().update_card(card_4) self.review_controller().start_review() assert self.database().scheduler_data_count(Cramming.UNSEEN) == 4 assert self.database().scheduler_data_count(Cramming.WRONG) == 0 assert self.review_controller().counters() == (0, 4, 4) self.review_controller().grade_answer(0) assert self.database().scheduler_data_count(Cramming.UNSEEN) == 3 assert self.database().scheduler_data_count(Cramming.WRONG) == 1 assert self.review_controller().counters() == (1, 3, 4) self.review_controller().reset_but_try_to_keep_current_card() self.review_controller().update_dialog(redraw_all=True) assert self.database().scheduler_data_count(Cramming.UNSEEN) == 3 assert self.database().scheduler_data_count(Cramming.WRONG) == 1 assert self.review_controller().counters() == (1, 3, 4) def test_2(self): card_type = self.card_type_with_id("1") fact_data = {"f": "1", "b": "b"} card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.review_controller().show_new_question() self.controller().delete_current_card() assert self.review_controller().card == None def test_3(self): card_type = self.card_type_with_id("1") fact_data = {"f": "1", "b": "b"} card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.review_controller().show_new_question() self.review_controller().show_answer() self.review_controller().grade_answer(0) self.review_controller().counters() self.mnemosyne.finalise() self.mnemosyne.initialise(os.path.abspath("dot_test"), automatic_upgrades=False) assert self.scheduler().name == "cramming" def test_4(self): card_type = self.card_type_with_id("1") fact_data = {"f": "1", "b": "b"} card_1 = self.controller().create_new_cards(fact_data, card_type, grade=-1, tag_names=["default"])[0] self.review_controller().show_new_question() self.database().unload() self.review_controller().reset() self.restart()