Esempio n. 1
0
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()
Esempio n. 2
0
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)
Esempio n. 3
0
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
Esempio n. 4
0
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]
Esempio n. 5
0
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()
Esempio n. 6
0
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()
Esempio n. 7
0
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


        
Esempio n. 8
0
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()
Esempio n. 9
0
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()
Esempio n. 10
0
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()
Esempio n. 11
0
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()
Esempio n. 12
0
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()
Esempio n. 13
0
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)
Esempio n. 15
0
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()
Esempio n. 16
0
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()
Esempio n. 17
0
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</$$>&nbsp;<latex>x^2</latex>&nbsp;<$>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()
Esempio n. 18
0
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)
Esempio n. 19
0
          "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)
Esempio n. 20
0
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      
Esempio n. 21
0
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)
Esempio n. 23
0
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()
Esempio n. 25
0
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
Esempio n. 27
0
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)
Esempio n. 28
0
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()
Esempio n. 29
0
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()
Esempio n. 30
0
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)
Esempio n. 31
0
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)
Esempio n. 32
0
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)
Esempio n. 33
0
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()
Esempio n. 35
0
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
Esempio n. 36
0
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
Esempio n. 37
0
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()
Esempio n. 38
0
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)
Esempio n. 39
0
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()
Esempio n. 40
0
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()
Esempio n. 41
0
     "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()
Esempio n. 42
0
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()
Esempio n. 43
0
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)
Esempio n. 44
0
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"
Esempio n. 45
0
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()
Esempio n. 46
0
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()
Esempio n. 47
0
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]
Esempio n. 48
0
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()
Esempio n. 49
0
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)
Esempio n. 51
0
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)
Esempio n. 52
0
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"
Esempio n. 53
0
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
Esempio n. 54
0
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]
Esempio n. 55
0
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)
Esempio n. 56
0
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
Esempio n. 57
0
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
Esempio n. 58
0
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)
Esempio n. 60
0
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()