Exemplo n.º 1
0
 def setUp(self):
     app_settings = MagicMock()
     self._temp_dir = TemporaryDirectory()
     url = "sqlite:///" + os.path.join(self._temp_dir.name, "db.sqlite")
     db_map = DiffDatabaseMapping(url, create=True)
     import_object_classes(db_map, ("class1",))
     import_object_parameters(db_map, (("class1", "parameter1"), ("class1", "parameter2")))
     import_objects(db_map, (("class1", "object1"), ("class1", "object2")))
     import_object_parameter_values(
         db_map,
         (
             ("class1", "object1", "parameter1", 1.0),
             ("class1", "object2", "parameter1", 3.0),
             ("class1", "object1", "parameter2", 5.0),
             ("class1", "object2", "parameter2", 7.0),
         ),
     )
     db_map.commit_session("Add test data.")
     db_map.connection.close()
     with patch("spinetoolbox.spine_db_manager.SpineDBManager.thread", new_callable=PropertyMock) as mock_thread:
         mock_thread.return_value = QApplication.instance().thread()
         self._db_mngr = SpineDBManager(app_settings, None)
         with patch.object(SpineDBEditor, "restore_ui"):
             self._editor = SpineDBEditor(self._db_mngr, {url: db_map.codename})
     object_class_index = self._editor.object_tree_model.index(0, 0)
     self._editor.object_tree_model.fetchMore(object_class_index)
     index = self._editor.object_tree_model.index(0, 0, object_class_index)
     self._editor.reload_pivot_table(index)
     self._model = self._editor.pivot_table_model
     self._model.start_fetching()
Exemplo n.º 2
0
class TestDataStoreFormBase(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        if not QApplication.instance():
            QApplication()

    def setUp(self):
        """Builds a DataStoreFormBase object."""
        with mock.patch(
                "spinetoolbox.spine_db_manager.DiffDatabaseMapping"
        ) as mock_DiffDBMapping, mock.patch(
                "spinetoolbox.data_store_form.widgets.data_store_form.DataStoreForm.restore_ui"
        ), mock.patch(
                "spinetoolbox.data_store_form.widgets.data_store_form.DataStoreForm.show"
        ):
            mock_settings = mock.Mock()
            mock_settings.value.side_effect = lambda *args, **kwards: 0
            self.db_mngr = SpineDBManager(mock_settings, None, None)
            self.db_mngr.fetch_db_maps_for_listener = lambda *args: None

            def DiffDBMapping_side_effect(url, upgrade=False, codename=None):
                mock_db_map = mock.MagicMock()
                mock_db_map.codename = codename
                return mock_db_map

            mock_DiffDBMapping.side_effect = DiffDBMapping_side_effect
            self.db_mngr.show_data_store_form({"mock_url": "mock_db"}, None)
            db_map = self.db_mngr._db_maps["mock_url"]
            self.form = DataStoreFormBase(self.db_mngr, db_map)

    def tearDown(self):
        """Frees resources after each test."""
        with mock.patch(
                "spinetoolbox.data_store_form.widgets.data_store_form.DataStoreForm.save_window_state"
        ), mock.patch("spinetoolbox.spine_db_manager.QMessageBox"):
            self.form.close()
        self.form.deleteLater()
        self.form = None

    def test_save_window_state(self):
        self.form.save_window_state()
        self.form.qsettings.beginGroup.assert_called_once_with("dataStoreForm")
        self.form.qsettings.endGroup.assert_called_once_with()
        qsettings_save_calls = self.form.qsettings.setValue.call_args_list
        self.assertEqual(len(qsettings_save_calls), 5)
        saved_dict = {
            saved[0][0]: saved[0][1]
            for saved in qsettings_save_calls
        }
        self.assertIn("windowSize", saved_dict)
        self.assertIn("windowPosition", saved_dict)
        self.assertIn("windowState", saved_dict)
        self.assertIn("windowMaximized", saved_dict)
        self.assertIn("n_screens", saved_dict)
Exemplo n.º 3
0
 def setUp(self):
     app_settings = MagicMock()
     self._logger = MagicMock(
     )  # Collects error messages therefore handy for debugging.
     self._db_mngr = SpineDBManager(app_settings, None)
     self._db_map = self._db_mngr.get_db_map("sqlite://",
                                             self._logger,
                                             codename="test_db",
                                             create=True)
     self._listener = MagicMock()
     self._fetcher = self._db_mngr.get_fetcher()
 def setUp(self):
     app_settings = MagicMock()
     logger = MagicMock()
     with unittest.mock.patch(
             "spinetoolbox.spine_db_manager.SpineDBManager.thread",
             new_callable=PropertyMock) as mock_thread:
         mock_thread.return_value = QApplication.instance().thread()
         self._db_mngr = SpineDBManager(app_settings, None)
     self._db_editor = SpineDBEditor(self._db_mngr)
     self._db_map = self._db_mngr.get_db_map("sqlite://",
                                             logger,
                                             codename="test_db",
                                             create=True)
    def setUp(self):
        """Overridden method. Runs before each test. Makes instances of DataStoreForm classes."""
        with mock.patch("spinetoolbox.spine_db_manager.DiffDatabaseMapping") as mock_DiffDBMapping, mock.patch(
            "spinetoolbox.widgets.data_store_widget.DataStoreForm.restore_ui"
        ):
            self.db_mngr = SpineDBManager(None, None)

            def DiffDBMapping_side_effect(url, upgrade=False, codename=None):
                mock_db_map = mock.MagicMock()
                mock_db_map.codename = codename
                return mock_db_map

            mock_DiffDBMapping.side_effect = DiffDBMapping_side_effect
            self.tree_view_form = DataStoreForm(self.db_mngr, ("mock_url", "mock_db"))
            self.mock_db_map = self.tree_view_form.db_map
Exemplo n.º 6
0
def main(argv):
    """Launches Spine Db Editor as it's own application.

    Args:
        argv (list): Command line arguments
    """
    if not pyside2_version_check():
        return 1
    try:
        urls = argv[1:]
    except IndexError:
        return 2
    app = QApplication(argv)
    status = QFontDatabase.addApplicationFont(
        ":/fonts/fontawesome5-solid-webfont.ttf")
    if status < 0:
        logging.warning(
            "Could not load fonts from resources file. Some icons may not render properly."
        )
    locale.setlocale(locale.LC_NUMERIC, 'C')
    settings = QSettings("SpineProject", "Spine Toolbox")
    db_mngr = SpineDBManager(settings, None)
    editor = MultiSpineDBEditor(db_mngr, {url: None
                                          for url in urls},
                                create=True)
    editor.show()
    return_code = app.exec_()
    return return_code
Exemplo n.º 7
0
 def setUp(self):
     """Overridden method. Runs before each test. Makes instances of SpineDBEditor classes."""
     with mock.patch(
             "spinetoolbox.spine_db_editor.widgets.spine_db_editor.SpineDBEditor.restore_ui"
     ), mock.patch(
             "spinetoolbox.spine_db_editor.widgets.spine_db_editor.SpineDBEditor.show"
     ):
         mock_settings = mock.Mock()
         mock_settings.value.side_effect = lambda *args, **kwards: 0
         self.db_mngr = SpineDBManager(mock_settings, None)
         # TODO: Use a temp file?
         url = "sqlite:///test.sqlite"
         create_new_spine_database(url)
         self.db_mngr.fetch_db_maps_for_listener = lambda *args: None
         self.spine_db_editor = SpineDBEditor(self.db_mngr, {url: "db"})
         self.db_map = self.spine_db_editor.first_db_map
         self.spine_db_editor.pivot_table_model = mock.MagicMock()
    def setUp(self):
        """Builds a SpineDBEditorBase object."""
        with mock.patch("spinetoolbox.spine_db_worker.DiffDatabaseMapping") as mock_DiffDBMapping, mock.patch(
            "spinetoolbox.spine_db_editor.widgets.spine_db_editor.SpineDBEditor.restore_ui"
        ), mock.patch("spinetoolbox.spine_db_editor.widgets.spine_db_editor.SpineDBEditor.show"):
            mock_settings = mock.Mock()
            mock_settings.value.side_effect = lambda *args, **kwards: 0
            self.db_mngr = SpineDBManager(mock_settings, None)
            self.db_mngr.fetch_db_maps_for_listener = lambda *args: None

            def DiffDBMapping_side_effect(url, codename=None, upgrade=False, create=False):
                mock_db_map = mock.MagicMock()
                mock_db_map.codename = codename
                mock_db_map.db_url = url
                return mock_db_map

            mock_DiffDBMapping.side_effect = DiffDBMapping_side_effect
            self.db_editor = SpineDBEditorBase(self.db_mngr)
class TestSpineDBEditorBase(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        if not QApplication.instance():
            QApplication()

    def setUp(self):
        """Builds a SpineDBEditorBase object."""
        with mock.patch("spinetoolbox.spine_db_worker.DiffDatabaseMapping") as mock_DiffDBMapping, mock.patch(
            "spinetoolbox.spine_db_editor.widgets.spine_db_editor.SpineDBEditor.restore_ui"
        ), mock.patch("spinetoolbox.spine_db_editor.widgets.spine_db_editor.SpineDBEditor.show"):
            mock_settings = mock.Mock()
            mock_settings.value.side_effect = lambda *args, **kwards: 0
            self.db_mngr = SpineDBManager(mock_settings, None)
            self.db_mngr.fetch_db_maps_for_listener = lambda *args: None

            def DiffDBMapping_side_effect(url, codename=None, upgrade=False, create=False):
                mock_db_map = mock.MagicMock()
                mock_db_map.codename = codename
                mock_db_map.db_url = url
                return mock_db_map

            mock_DiffDBMapping.side_effect = DiffDBMapping_side_effect
            self.db_editor = SpineDBEditorBase(self.db_mngr)

    def tearDown(self):
        """Frees resources after each test."""
        with mock.patch(
            "spinetoolbox.spine_db_editor.widgets.spine_db_editor.SpineDBEditor.save_window_state"
        ), mock.patch("spinetoolbox.spine_db_manager.QMessageBox"):
            self.db_editor.close()
        self.db_mngr.close_all_sessions()
        self.db_mngr.clean_up()
        self.db_editor.deleteLater()
        self.db_editor = None

    def test_save_window_state(self):
        self.db_editor.save_window_state()
        self.db_editor.qsettings.beginGroup.assert_has_calls([mock.call("spineDBEditor"), mock.call("")])
        self.db_editor.qsettings.endGroup.assert_has_calls([mock.call(), mock.call()])
        qsettings_save_calls = self.db_editor.qsettings.setValue.call_args_list
        self.assertEqual(len(qsettings_save_calls), 1)
        saved_dict = {saved[0][0]: saved[0][1] for saved in qsettings_save_calls}
        self.assertIn("windowState", saved_dict)
 def setUp(self):
     """Overridden method. Runs before each test. Makes instances of SpineDBEditor classes."""
     self._temp_dir = TemporaryDirectory()
     url = "sqlite:///" + os.path.join(self._temp_dir.name, "test.sqlite")
     with mock.patch(
             "spinetoolbox.spine_db_editor.widgets.spine_db_editor.SpineDBEditor.restore_ui"
     ), mock.patch(
             "spinetoolbox.spine_db_editor.widgets.spine_db_editor.SpineDBEditor.show"
     ):
         mock_settings = mock.Mock()
         mock_settings.value.side_effect = lambda *args, **kwards: 0
         self.db_mngr = SpineDBManager(mock_settings, None)
         logger = mock.MagicMock()
         self.db_map = self.db_mngr.get_db_map(url,
                                               logger,
                                               codename="db",
                                               create=True)
         self.spine_db_editor = SpineDBEditor(self.db_mngr, {url: "db"})
         self.spine_db_editor.pivot_table_model = mock.MagicMock()
 def setUp(self):
     """Overridden method. Runs before each test. Makes instances of SpineDBEditor classes."""
     self._temp_dir = TemporaryDirectory()
     url = "sqlite:///" + os.path.join(self._temp_dir.name, "test.sqlite")
     create_new_spine_database(url)
     with mock.patch(
             "spinetoolbox.spine_db_editor.widgets.spine_db_editor.SpineDBEditor.restore_ui"
     ), mock.patch(
             "spinetoolbox.spine_db_editor.widgets.spine_db_editor.SpineDBEditor.show"
     ):
         mock_settings = mock.Mock()
         mock_settings.value.side_effect = lambda *args, **kwards: 0
         with mock.patch(
                 "spinetoolbox.spine_db_manager.SpineDBManager.thread",
                 new_callable=mock.PropertyMock) as mock_thread:
             mock_thread.return_value = QApplication.instance().thread()
             self.db_mngr = SpineDBManager(mock_settings, None)
         self.spine_db_editor = SpineDBEditor(self.db_mngr, {url: "db"})
         self.db_map = self.spine_db_editor.first_db_map
         self.spine_db_editor.pivot_table_model = mock.MagicMock()
Exemplo n.º 12
0
    def setUp(self):
        """Overridden method. Runs before each test. Makes instances of SpineDBEditor classes."""
        with mock.patch(
                "spinetoolbox.spine_db_editor.widgets.spine_db_editor.SpineDBEditor.restore_ui"
        ), mock.patch(
                "spinetoolbox.spine_db_editor.widgets.spine_db_editor.SpineDBEditor.show"
        ):
            mock_settings = mock.Mock()
            mock_settings.value.side_effect = lambda *args, **kwards: 0
            self.db_mngr = SpineDBManager(mock_settings, None)
            self.db_mngr.fetch_db_maps_for_listener = lambda *args: None

            logger = mock.MagicMock()
            self.db_mngr.get_db_map("sqlite://",
                                    logger,
                                    codename="database",
                                    create=True)
            self.spine_db_editor = SpineDBEditor(self.db_mngr,
                                                 {"sqlite://": "database"})
            self.mock_db_map = self.spine_db_editor.first_db_map
            self.spine_db_editor.pivot_table_model = mock.MagicMock()
 def setUp(self):
     """Overridden method. Runs before each test."""
     app_settings = mock.MagicMock()
     logger = mock.MagicMock()
     with mock.patch("spinetoolbox.spine_db_manager.SpineDBManager.thread",
                     new_callable=mock.PropertyMock) as mock_thread:
         mock_thread.return_value = QApplication.instance().thread()
         self._db_mngr = SpineDBManager(app_settings, None)
         fetcher = self._db_mngr.get_fetcher()
     self._db_map = self._db_mngr.get_db_map("sqlite://",
                                             logger,
                                             codename="mock_db",
                                             create=True)
     import_object_classes(self._db_map, ("dog", "fish"))
     import_object_parameters(self._db_map, (("dog", "breed"), ))
     import_objects(self._db_map, (("dog", "pluto"), ("fish", "nemo")))
     import_relationship_classes(self._db_map,
                                 (("dog__fish", ("dog", "fish")), ))
     import_relationship_parameters(self._db_map,
                                    (("dog__fish", "relative_speed"), ))
     import_relationships(self._db_map, (("dog_fish", ("pluto", "nemo")), ))
     self._db_map.commit_session("Add test data")
     fetcher.fetch([self._db_map])
     self.object_table_header = [
         "object_class_name",
         "object_name",
         "parameter_name",
         "alternative_id",
         "value",
         "database",
     ]
     self.relationship_table_header = [
         "relationship_class_name",
         "object_name_list",
         "parameter_name",
         "alternative_id",
         "value",
         "database",
     ]
Exemplo n.º 14
0
def main(argv):
    """Launches Data Store view as it's own application.

    Args:
        argv (list): Command line arguments
    """
    if not pyside2_version_check():
        return 1
    try:
        file_path = argv[1]
    except IndexError:
        return 0
    app = QApplication(argv)
    QFontDatabase.addApplicationFont(":/fonts/fontawesome5-solid-webfont.ttf")
    locale.setlocale(locale.LC_NUMERIC, 'C')
    url = f"sqlite:///{file_path}"
    settings = QSettings("SpineProject", "Spine Toolbox")
    logger = SimpleLogger()
    db_mngr = SpineDBManager(settings, logger, None)
    codename = os.path.splitext(os.path.basename(file_path))[0]
    db_mngr.show_data_store_form({url: codename}, logger)
    return_code = app.exec_()
    return return_code
Exemplo n.º 15
0
    def setUp(self):
        """Builds a DataStoreFormBase object."""
        with mock.patch(
                "spinetoolbox.spine_db_manager.DiffDatabaseMapping"
        ) as mock_DiffDBMapping, mock.patch(
                "spinetoolbox.data_store_form.widgets.data_store_form.DataStoreForm.restore_ui"
        ), mock.patch(
                "spinetoolbox.data_store_form.widgets.data_store_form.DataStoreForm.show"
        ):
            mock_settings = mock.Mock()
            mock_settings.value.side_effect = lambda *args, **kwards: 0
            self.db_mngr = SpineDBManager(mock_settings, None, None)
            self.db_mngr.fetch_db_maps_for_listener = lambda *args: None

            def DiffDBMapping_side_effect(url, upgrade=False, codename=None):
                mock_db_map = mock.MagicMock()
                mock_db_map.codename = codename
                return mock_db_map

            mock_DiffDBMapping.side_effect = DiffDBMapping_side_effect
            self.db_mngr.show_data_store_form({"mock_url": "mock_db"}, None)
            db_map = self.db_mngr._db_maps["mock_url"]
            self.form = DataStoreFormBase(self.db_mngr, db_map)
Exemplo n.º 16
0
    def setUp(self):
        """Overridden method. Runs before each test. Makes instances of DataStoreForm classes."""
        with mock.patch(
                "spinetoolbox.spine_db_manager.DiffDatabaseMapping"
        ) as mock_DiffDBMapping, mock.patch(
                "spinetoolbox.data_store_form.widgets.data_store_form.DataStoreForm.restore_ui"
        ), mock.patch(
                "spinetoolbox.data_store_form.widgets.data_store_form.DataStoreForm.show"
        ):
            mock_settings = mock.Mock()
            mock_settings.value.side_effect = lambda *args, **kwards: 0
            self.db_mngr = SpineDBManager(mock_settings, None, None)
            self.db_mngr.fetch_db_maps_for_listener = lambda *args: None

            def DiffDBMapping_side_effect(url, upgrade=False, codename=None):
                mock_db_map = mock.MagicMock()
                mock_db_map.codename = codename
                return mock_db_map

            mock_DiffDBMapping.side_effect = DiffDBMapping_side_effect
            self.db_mngr.show_data_store_form({"mock_url": "mock_db"}, None)
            self.tree_view_form = self.db_mngr._ds_forms[("mock_url", )]
            self.mock_db_map = self.tree_view_form.db_map
            self.tree_view_form.pivot_table_model = mock.MagicMock()
    def setUp(self):
        """Overridden method. Runs before each test. Makes instances of SpineDBEditor classes."""
        with mock.patch("spinetoolbox.spine_db_manager.DiffDatabaseMapping") as mock_DiffDBMapping, mock.patch(
            "spinetoolbox.spine_db_editor.widgets.spine_db_editor.SpineDBEditor.restore_ui"
        ), mock.patch("spinetoolbox.spine_db_editor.widgets.spine_db_editor.SpineDBEditor.show"):
            mock_settings = mock.Mock()
            mock_settings.value.side_effect = lambda *args, **kwards: 0
            self.db_mngr = SpineDBManager(mock_settings, None)
            self.db_mngr.fetch_db_maps_for_listener = lambda *args: None

            def DiffDBMapping_side_effect(url, codename=None, upgrade=False, create=False):
                mock_db_map = mock.MagicMock()
                mock_db_map.db_url = url
                mock_db_map.codename = codename
                return mock_db_map

            mock_DiffDBMapping.side_effect = DiffDBMapping_side_effect
            self.spine_db_editor = SpineDBEditor(self.db_mngr, {"mock_url": "mock_db"})
            self.mock_db_map = self.spine_db_editor.first_db_map
            self.spine_db_editor.pivot_table_model = mock.MagicMock()
Exemplo n.º 18
0
def main(argv):
    """Launches Data Store view as it's own application.

    Args:
        argv (list): Command line arguments
    """
    if not pyside2_version_check():
        return 0
    if not spinedb_api_version_check():
        return 0
    try:
        path = argv[1]
    except IndexError:
        return 0
    app = QApplication(argv)
    QFontDatabase.addApplicationFont(":/fonts/fontawesome5-solid-webfont.ttf")
    locale.setlocale(locale.LC_NUMERIC, 'C')
    url = f"sqlite:///{path}"
    db_mngr = SpineDBManager(SimpleLogger(), None)
    tree = DataStoreForm(db_mngr, (url, "main"))
    tree.show()
    return_code = app.exec_()
    return return_code
class TestAlternativeScenarioModel(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        if not QApplication.instance():
            QApplication()

    def setUp(self):
        app_settings = MagicMock()
        logger = MagicMock()
        with unittest.mock.patch(
                "spinetoolbox.spine_db_manager.SpineDBManager.thread",
                new_callable=PropertyMock) as mock_thread:
            mock_thread.return_value = QApplication.instance().thread()
            self._db_mngr = SpineDBManager(app_settings, None)
        self._db_editor = SpineDBEditor(self._db_mngr)
        self._db_map = self._db_mngr.get_db_map("sqlite://",
                                                logger,
                                                codename="test_db",
                                                create=True)

    def tearDown(self):
        self._db_mngr.close_all_sessions()
        self._db_mngr.clean_up()

    def test_initial_state(self):
        model = AlternativeScenarioModel(self._db_editor, self._db_mngr,
                                         self._db_map)
        model.build_tree()
        data = self._model_data_to_dict(model)
        expected = [[
            {
                "test_db": [
                    [{
                        "alternative":
                        [["Type new alternative name here...", ""]]
                    }, None],
                    [{
                        "scenario": [["Type new scenario name here...", ""]]
                    }, None],
                ]
            },
            None,
        ]]
        self.assertEqual(data, expected)

    def test_add_alternatives(self):
        self._db_mngr.add_alternatives(
            {self._db_map: [{
                "name": "alternative_1"
            }]})
        model = AlternativeScenarioModel(self._db_editor, self._db_mngr,
                                         self._db_map)
        model.build_tree()
        model.add_alternatives({self._db_map: [{"id": 2}]})
        data = self._model_data_to_dict(model)
        expected = [[
            {
                "test_db": [
                    [{
                        "alternative":
                        [["alternative_1", ""],
                         ["Type new alternative name here...", ""]]
                    }, None],
                    [{
                        "scenario": [["Type new scenario name here...", ""]]
                    }, None],
                ]
            },
            None,
        ]]
        self.assertEqual(data, expected)
        index = model.index(0, 0)
        index = model.index(0, 0, index)
        index = model.index(0, 0, index)
        self.assertTrue(model.setData(index, "perse"))

    def test_add_alternatives_with_scenario_alternative(self):
        self._db_mngr.add_alternatives(
            {self._db_map: [{
                "name": "alternative_1"
            }]})
        self._db_mngr.add_scenarios({self._db_map: [{"name": "scenario_1"}]})
        self._db_mngr.set_scenario_alternatives(
            {self._db_map: [{
                "id": 1,
                "alternative_id_list": "2"
            }]})
        model = AlternativeScenarioModel(self._db_editor, self._db_mngr,
                                         self._db_map)
        model.build_tree()
        model.add_alternatives({self._db_map: [{"id": 2}]})
        model.add_scenarios({self._db_map: [{"id": 1}]})
        data = self._model_data_to_dict(model)
        expected = [[
            {
                "test_db": [
                    [{
                        "alternative":
                        [["alternative_1", ""],
                         ["Type new alternative name here...", ""]]
                    }, None],
                    [
                        {
                            "scenario": [
                                [
                                    {
                                        "scenario_1": [
                                            ["active: no", None],
                                            [{
                                                "scenario_alternative":
                                                [["alternative_1", ""]]
                                            }, None],
                                        ]
                                    },
                                    "",
                                ],
                                ["Type new scenario name here...", ""],
                            ]
                        },
                        None,
                    ],
                ]
            },
            None,
        ]]
        self.assertEqual(data, expected)
        index = model.index(0, 0)
        index = model.index(0, 0, index)
        index = model.index(0, 0, index)
        self.assertTrue(model.setData(index, "perse"))

    def test_update_alternatives(self):
        self._db_mngr.add_alternatives(
            {self._db_map: [{
                "name": "alternative_1"
            }]})
        model = AlternativeScenarioModel(self._db_editor, self._db_mngr,
                                         self._db_map)
        model.build_tree()
        model.add_alternatives({self._db_map: [{"id": 2}]})
        self._db_mngr.update_alternatives(
            {self._db_map: [{
                "id": 2,
                "name": "renamed"
            }]})
        model.update_alternatives({self._db_map: [{"id": 2}]})
        data = self._model_data_to_dict(model)
        expected = [[
            {
                "test_db": [
                    [{
                        "alternative":
                        [["renamed", ""],
                         ["Type new alternative name here...", ""]]
                    }, None],
                    [{
                        "scenario": [["Type new scenario name here...", ""]]
                    }, None],
                ]
            },
            None,
        ]]
        self.assertEqual(data, expected)

    def test_update_alternatives_with_scenario_alternatives(self):
        self._db_mngr.add_alternatives(
            {self._db_map: [{
                "name": "alternative_1"
            }]})
        self._db_mngr.add_scenarios({self._db_map: [{"name": "scenario_1"}]})
        self._db_mngr.set_scenario_alternatives(
            {self._db_map: [{
                "id": 1,
                "alternative_id_list": "2"
            }]})
        model = AlternativeScenarioModel(self._db_editor, self._db_mngr,
                                         self._db_map)
        model.build_tree()
        model.add_alternatives({self._db_map: [{"id": 2}]})
        model.add_scenarios({self._db_map: [{"id": 1}]})
        self._db_mngr.update_alternatives(
            {self._db_map: [{
                "id": 2,
                "name": "renamed"
            }]})
        model.update_alternatives({self._db_map: [{"id": 2}]})
        data = self._model_data_to_dict(model)
        expected = [[
            {
                "test_db": [
                    [{
                        "alternative":
                        [["renamed", ""],
                         ["Type new alternative name here...", ""]]
                    }, None],
                    [
                        {
                            "scenario": [
                                [
                                    {
                                        "scenario_1": [
                                            ["active: no", None],
                                            [{
                                                "scenario_alternative":
                                                [["renamed", ""]]
                                            }, None],
                                        ]
                                    },
                                    "",
                                ],
                                ["Type new scenario name here...", ""],
                            ]
                        },
                        None,
                    ],
                ]
            },
            None,
        ]]
        self.assertEqual(data, expected)

    def test_remove_alternatives(self):
        self._db_mngr.add_alternatives(
            {self._db_map: [{
                "name": "alternative_1"
            }]})
        model = AlternativeScenarioModel(self._db_editor, self._db_mngr,
                                         self._db_map)
        model.build_tree()
        model.add_alternatives({self._db_map: [{"id": 2}]})
        model.remove_alternatives({self._db_map: [{"id": 2}]})
        data = self._model_data_to_dict(model)
        expected = [[
            {
                "test_db": [
                    [{
                        "alternative":
                        [["Type new alternative name here...", ""]]
                    }, None],
                    [{
                        "scenario": [["Type new scenario name here...", ""]]
                    }, None],
                ]
            },
            None,
        ]]
        self.assertEqual(data, expected)

    def _model_data_to_dict(self, model, parent=QModelIndex()):
        self.assertEqual(model.columnCount(parent), 2)
        rows = list()
        for row in range(model.rowCount(parent)):
            index = model.index(row, 0, parent)
            child_data = self._model_data_to_dict(model, index)
            data1 = {index.data(): child_data} if child_data else index.data()
            index = model.index(row, 1, parent)
            child_data = self._model_data_to_dict(model, index)
            data2 = {index.data(): child_data} if child_data else index.data()
            rows.append([data1, data2])
        return rows
class TestTreeViewForm(
    TestTreeViewFormAddMixin,
    TestTreeViewFormUpdateMixin,
    TestTreeViewFormRemoveMixin,
    TestTreeViewFormFilterMixin,
    unittest.TestCase,
):
    @staticmethod
    def _object_class(*args):
        return dict(zip(["id", "name", "description", "display_order", "display_icon"], args))

    @staticmethod
    def _object(*args):
        return dict(zip(["id", "class_id", "name", "description"], args))

    @staticmethod
    def _relationship_class(*args):
        return dict(zip(["id", "name", "object_class_id_list", "object_class_name_list"], args))

    @staticmethod
    def _relationship(*args):
        return dict(zip(["id", "class_id", "name", "class_name", "object_id_list", "object_name_list"], args))

    @staticmethod
    def _object_parameter_definition(*args):
        d = dict(zip(["id", "object_class_id", "object_class_name", "parameter_name"], args))
        d["name"] = d["parameter_name"]
        return d

    @staticmethod
    def _relationship_parameter_definition(*args):
        d = dict(
            zip(
                [
                    "id",
                    "relationship_class_id",
                    "relationship_class_name",
                    "object_class_id_list",
                    "object_class_name_list",
                    "parameter_name",
                ],
                args,
            )
        )
        d["name"] = d["parameter_name"]
        return d

    @staticmethod
    def _object_parameter_value(*args):
        return dict(
            zip(
                [
                    "id",
                    "object_class_id",
                    "object_class_name",
                    "object_id",
                    "object_name",
                    "parameter_id",
                    "parameter_name",
                    "value",
                ],
                args,
            )
        )

    @staticmethod
    def _relationship_parameter_value(*args):
        return dict(
            zip(
                [
                    "id",
                    "relationship_class_id",
                    "relationship_class_name",
                    "object_class_id_list",
                    "object_class_name_list",
                    "relationship_id",
                    "object_id_list",
                    "object_name_list",
                    "parameter_id",
                    "parameter_name",
                    "value",
                ],
                args,
            )
        )

    @classmethod
    def setUpClass(cls):
        """Overridden method. Runs once before all tests in this class."""
        try:
            cls.app = QApplication().processEvents()
        except RuntimeError:
            pass
        logging.basicConfig(
            stream=sys.stderr,
            level=logging.DEBUG,
            format='%(asctime)s %(levelname)s: %(message)s',
            datefmt='%Y-%m-%d %H:%M:%S',
        )
        cls.create_mock_dataset()

    @classmethod
    def create_mock_dataset(cls):
        cls.fish_class = cls._object_class(1, "fish", "A fish.", 1, None)
        cls.dog_class = cls._object_class(2, "dog", "A dog.", 3, None)
        cls.fish_dog_class = cls._relationship_class(
            3,
            "fish__dog",
            str(cls.fish_class["id"]) + "," + str(cls.dog_class["id"]),
            cls.fish_class["name"] + "," + cls.dog_class["name"],
        )
        cls.dog_fish_class = cls._relationship_class(
            4,
            "dog__fish",
            str(cls.dog_class["id"]) + "," + str(cls.fish_class["id"]),
            cls.dog_class["name"] + "," + cls.fish_class["name"],
        )
        cls.nemo_object = cls._object(1, cls.fish_class["id"], 'nemo', 'The lost one.')
        cls.pluto_object = cls._object(2, cls.dog_class["id"], 'pluto', "Mickey's.")
        cls.scooby_object = cls._object(3, cls.dog_class["id"], 'scooby', 'Scooby-Dooby-Doo.')
        cls.pluto_nemo_rel = cls._relationship(
            4,
            cls.dog_fish_class["id"],
            "dog__fish_pluto__nemo",
            cls.dog_fish_class["name"],
            str(cls.pluto_object["id"]) + "," + str(cls.nemo_object["id"]),
            cls.pluto_object["name"] + "," + cls.nemo_object["name"],
        )
        cls.nemo_pluto_rel = cls._relationship(
            5,
            cls.fish_dog_class["id"],
            "fish__dog_nemo__pluto",
            cls.fish_dog_class["name"],
            str(cls.nemo_object["id"]) + "," + str(cls.pluto_object["id"]),
            cls.nemo_object["name"] + "," + cls.pluto_object["name"],
        )
        cls.nemo_scooby_rel = cls._relationship(
            6,
            cls.fish_dog_class["id"],
            "fish__dog_nemo__scooby",
            cls.fish_dog_class["name"],
            str(cls.nemo_object["id"]) + "," + str(cls.scooby_object["id"]),
            cls.nemo_object["name"] + "," + cls.scooby_object["name"],
        )
        cls.water_parameter = cls._object_parameter_definition(1, cls.fish_class["id"], cls.fish_class["name"], "water")
        cls.breed_parameter = cls._object_parameter_definition(2, cls.dog_class["id"], cls.dog_class["name"], "breed")
        cls.relative_speed_parameter = cls._relationship_parameter_definition(
            3,
            cls.fish_dog_class["id"],
            cls.fish_dog_class["name"],
            cls.fish_dog_class["object_class_id_list"],
            cls.fish_dog_class["object_class_name_list"],
            "relative_speed",
        )
        cls.combined_mojo_parameter = cls._relationship_parameter_definition(
            4,
            cls.dog_fish_class["id"],
            cls.dog_fish_class["name"],
            cls.dog_fish_class["object_class_id_list"],
            cls.dog_fish_class["object_class_name_list"],
            "combined_mojo",
        )
        cls.nemo_water = cls._object_parameter_value(
            1,
            cls.water_parameter["object_class_id"],
            cls.water_parameter["object_class_name"],
            cls.nemo_object["id"],
            cls.nemo_object["name"],
            cls.water_parameter["id"],
            cls.water_parameter["parameter_name"],
            '"salt"',
        )
        cls.pluto_breed = cls._object_parameter_value(
            2,
            cls.breed_parameter["object_class_id"],
            cls.breed_parameter["object_class_name"],
            cls.pluto_object["id"],
            cls.pluto_object["name"],
            cls.breed_parameter["id"],
            cls.breed_parameter["parameter_name"],
            '"bloodhound"',
        )
        cls.scooby_breed = cls._object_parameter_value(
            3,
            cls.breed_parameter["object_class_id"],
            cls.breed_parameter["object_class_name"],
            cls.scooby_object["id"],
            cls.scooby_object["name"],
            cls.breed_parameter["id"],
            cls.breed_parameter["parameter_name"],
            '"great dane"',
        )
        cls.nemo_pluto_relative_speed = cls._relationship_parameter_value(
            4,
            cls.relative_speed_parameter["relationship_class_id"],
            cls.relative_speed_parameter["relationship_class_name"],
            cls.relative_speed_parameter["object_class_id_list"],
            cls.relative_speed_parameter["object_class_name_list"],
            cls.nemo_pluto_rel["id"],
            cls.nemo_pluto_rel["object_id_list"],
            cls.nemo_pluto_rel["object_name_list"],
            cls.relative_speed_parameter["id"],
            cls.relative_speed_parameter["parameter_name"],
            "-1",
        )
        cls.nemo_scooby_relative_speed = cls._relationship_parameter_value(
            5,
            cls.relative_speed_parameter["relationship_class_id"],
            cls.relative_speed_parameter["relationship_class_name"],
            cls.relative_speed_parameter["object_class_id_list"],
            cls.relative_speed_parameter["object_class_name_list"],
            cls.nemo_scooby_rel["id"],
            cls.nemo_scooby_rel["object_id_list"],
            cls.nemo_scooby_rel["object_name_list"],
            cls.relative_speed_parameter["id"],
            cls.relative_speed_parameter["parameter_name"],
            "5",
        )
        cls.pluto_nemo_combined_mojo = cls._relationship_parameter_value(
            6,
            cls.combined_mojo_parameter["relationship_class_id"],
            cls.combined_mojo_parameter["relationship_class_name"],
            cls.combined_mojo_parameter["object_class_id_list"],
            cls.combined_mojo_parameter["object_class_name_list"],
            cls.pluto_nemo_rel["id"],
            cls.pluto_nemo_rel["object_id_list"],
            cls.pluto_nemo_rel["object_name_list"],
            cls.combined_mojo_parameter["id"],
            cls.combined_mojo_parameter["parameter_name"],
            "100",
        )

    def setUp(self):
        """Overridden method. Runs before each test. Makes instances of DataStoreForm classes."""
        with mock.patch("spinetoolbox.spine_db_manager.DiffDatabaseMapping") as mock_DiffDBMapping, mock.patch(
            "spinetoolbox.widgets.data_store_widget.DataStoreForm.restore_ui"
        ):
            self.db_mngr = SpineDBManager(None, None)

            def DiffDBMapping_side_effect(url, upgrade=False, codename=None):
                mock_db_map = mock.MagicMock()
                mock_db_map.codename = codename
                return mock_db_map

            mock_DiffDBMapping.side_effect = DiffDBMapping_side_effect
            self.tree_view_form = DataStoreForm(self.db_mngr, ("mock_url", "mock_db"))
            self.mock_db_map = self.tree_view_form.db_map

    def tearDown(self):
        """Overridden method. Runs after each test.
        Use this to free resources after a test if needed.
        """
        with mock.patch(
            "spinetoolbox.widgets.data_store_widget.DataStoreForm.save_window_state"
        ) as mock_save_w_s, mock.patch("spinetoolbox.spine_db_manager.QMessageBox"):
            self.tree_view_form.close()
            mock_save_w_s.assert_called_once()
        self.tree_view_form.deleteLater()
        self.tree_view_form = None

    def put_mock_object_classes_in_db_mngr(self):
        """Put fish and dog object classes in the db mngr."""

        def _get_object_classes(db_map):
            self.db_mngr.cache_items("object class", {db_map: [self.fish_class, self.dog_class]})
            return [self.fish_class, self.dog_class]

        self.db_mngr.get_object_classes = _get_object_classes

    def put_mock_objects_in_db_mngr(self):
        """Put nemo, pluto and scooby objects in the db mngr."""

        def _get_objects(db_map, class_id=None):
            self.db_mngr.cache_items("object", {db_map: [self.nemo_object, self.pluto_object, self.scooby_object]})
            if class_id == self.fish_class["id"]:
                return [self.nemo_object]
            if class_id == self.dog_class["id"]:
                return [self.pluto_object, self.scooby_object]
            if class_id is None:
                return [self.nemo_object, self.pluto_object, self.scooby_object]
            return []

        self.db_mngr.get_objects = _get_objects

    def put_mock_relationship_classes_in_db_mngr(self):
        """Put dog__fish and fish__dog relationship classes in the db mngr."""

        def _get_relationship_classes(db_map, ids=None, object_class_id=None):
            self.db_mngr.cache_items("relationship class", {db_map: [self.fish_dog_class, self.dog_fish_class]})
            if object_class_id in (self.fish_class["id"], self.dog_class["id"]):
                return [self.fish_dog_class, self.dog_fish_class]
            if object_class_id is None:
                return [self.fish_dog_class, self.dog_fish_class]
            return []

        self.db_mngr.get_relationship_classes = _get_relationship_classes

    def put_mock_relationships_in_db_mngr(self):
        """Put pluto_nemo, nemo_pluto and nemo_scooby relationships in the db mngr."""

        def _get_relationships(db_map, class_id=None, object_id=None):
            self.db_mngr.cache_items(
                "relationship", {db_map: [self.pluto_nemo_rel, self.nemo_pluto_rel, self.nemo_scooby_rel]}
            )
            if class_id == self.dog_fish_class["id"]:
                if object_id in (self.nemo_object["id"], self.pluto_object["id"]):
                    return [self.pluto_nemo_rel]
            if class_id == self.fish_dog_class["id"]:
                if object_id == self.nemo_object["id"]:
                    return [self.nemo_pluto_rel, self.nemo_scooby_rel]
                if object_id == self.pluto_object["id"]:
                    return [self.nemo_pluto_rel]
                if object_id == self.scooby_object["id"]:
                    return [self.nemo_scooby_rel]
            if class_id is None and object_id is None:
                return [self.pluto_nemo_rel, self.nemo_pluto_rel, self.nemo_scooby_rel]
            return []

        self.db_mngr.get_relationships = _get_relationships

    def put_mock_object_parameter_definitions_in_db_mngr(self):
        """Put water and breed object parameter definitions in the db mngr."""

        def _get_object_parameter_definitions(db_map, ids=None, object_class_id=None):
            self.db_mngr.cache_items("parameter definition", {db_map: [self.water_parameter, self.breed_parameter]})
            if object_class_id == self.fish_class["id"]:
                return [self.water_parameter]
            if object_class_id == self.dog_class["id"]:
                return [self.breed_parameter]
            if object_class_id is None:
                return [self.water_parameter, self.breed_parameter]
            return []

        self.db_mngr.get_object_parameter_definitions = _get_object_parameter_definitions

    def put_mock_relationship_parameter_definitions_in_db_mngr(self):
        """Put relative speed and combined mojo relationship parameter definitions in the db mngr."""

        def _get_relationship_parameter_definitions(db_map, ids=None, relationship_class_id=None):
            self.db_mngr.cache_items(
                "parameter definition", {db_map: [self.relative_speed_parameter, self.combined_mojo_parameter]}
            )
            if relationship_class_id == self.fish_dog_class["id"]:
                return [self.relative_speed_parameter]
            if relationship_class_id == self.dog_fish_class["id"]:
                return [self.combined_mojo_parameter]
            if relationship_class_id is None:
                return [self.relative_speed_parameter, self.combined_mojo_parameter]
            return []

        self.db_mngr.get_relationship_parameter_definitions = _get_relationship_parameter_definitions

    def put_mock_object_parameter_values_in_db_mngr(self):
        """Put some object parameter values in the db mngr."""

        def _get_object_parameter_values(db_map, ids=None, object_class_id=None):
            self.db_mngr.cache_items(
                "parameter value", {db_map: [self.nemo_water, self.pluto_breed, self.scooby_breed]}
            )
            if object_class_id == self.fish_class["id"]:
                return [self.nemo_water]
            if object_class_id == self.dog_class["id"]:
                return [self.pluto_breed, self.scooby_breed]
            if object_class_id is None:
                return [self.nemo_water, self.pluto_breed, self.scooby_breed]
            return []

        self.db_mngr.get_object_parameter_values = _get_object_parameter_values

    def put_mock_relationship_parameter_values_in_db_mngr(self):
        """Put some relationship parameter values in the db mngr."""

        def _get_relationship_parameter_values(db_map, ids=None, relationship_class_id=None):
            self.db_mngr.cache_items(
                "parameter value",
                {
                    db_map: [
                        self.nemo_pluto_relative_speed,
                        self.nemo_scooby_relative_speed,
                        self.pluto_nemo_combined_mojo,
                    ]
                },
            )
            if relationship_class_id == self.fish_dog_class["id"]:
                return [self.nemo_pluto_relative_speed, self.nemo_scooby_relative_speed]
            if relationship_class_id == self.dog_fish_class["id"]:
                return [self.pluto_nemo_combined_mojo]
            if relationship_class_id is None:
                return [self.nemo_pluto_relative_speed, self.nemo_scooby_relative_speed, self.pluto_nemo_combined_mojo]
            return []

        self.db_mngr.get_relationship_parameter_values = _get_relationship_parameter_values

    def put_mock_dataset_in_db_mngr(self):
        """Put mock dataset in the db mngr."""
        self.put_mock_object_classes_in_db_mngr()
        self.put_mock_objects_in_db_mngr()
        self.put_mock_relationship_classes_in_db_mngr()
        self.put_mock_relationships_in_db_mngr()
        self.put_mock_object_parameter_definitions_in_db_mngr()
        self.put_mock_relationship_parameter_definitions_in_db_mngr()
        self.put_mock_object_parameter_values_in_db_mngr()
        self.put_mock_relationship_parameter_values_in_db_mngr()

    def test_set_object_parameter_definition_defaults(self):
        """Test that defaults are set in object parameter definition models according the object tree selection."""
        self.put_mock_object_classes_in_db_mngr()
        self.tree_view_form.init_models()
        for item in self.tree_view_form.object_tree_model.visit_all():
            item.fetch_more()
        # Select fish item in object tree
        root_item = self.tree_view_form.object_tree_model.root_item
        fish_item = root_item.child(0)
        fish_index = self.tree_view_form.object_tree_model.index_from_item(fish_item)
        self.tree_view_form.ui.treeView_object.setCurrentIndex(fish_index)
        self.tree_view_form.ui.treeView_object.selectionModel().select(fish_index, QItemSelectionModel.Select)
        # Check default in object parameter definition
        model = self.tree_view_form.object_parameter_definition_model
        model.empty_model.fetchMore()
        h = model.header.index
        row_data = []
        for row in range(model.rowCount()):
            row_data.append(tuple(model.index(row, h(field)).data() for field in ("object_class_name", "database")))
        self.assertTrue(("fish", "mock_db") in row_data)

    @unittest.skip("TODO")
    def test_set_object_parameter_value_defaults(self):
        """Test that defaults are set in relationship parameter definition
        models according the object tree selection.
        """
        self.fail()

    @unittest.skip("TODO")
    def test_set_relationship_parameter_definition_defaults(self):
        """Test that defaults are set in relationship parameter definition
        models according the object tree selection.
        """
        self.fail()

    @unittest.skip("TODO")
    def test_set_relationship_parameter_value_defaults(self):
        """Test that defaults are set in relationship parameter definition
        models according the object tree selection.
        """
        self.fail()
Exemplo n.º 21
0
class TestSpineDBFetcher(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        if not QApplication.instance():
            QApplication()

    def setUp(self):
        app_settings = MagicMock()
        self._logger = MagicMock(
        )  # Collects error messages therefore handy for debugging.
        self._db_mngr = SpineDBManager(app_settings, None)
        self._db_map = self._db_mngr.get_db_map("sqlite://",
                                                self._logger,
                                                codename="test_db",
                                                create=True)
        self._listener = MagicMock()
        self._fetcher = self._db_mngr.get_fetcher()

    def tearDown(self):
        self._db_mngr.close_all_sessions()
        self._db_mngr.clean_up()

    def _fetch(self):
        waiter = SignalWaiter()
        self._fetcher.finished.connect(waiter.trigger)
        self._fetcher.fetch(self._listener, [self._db_map])
        waiter.wait()

    def test_fetch_empty_database(self):
        self._fetch()
        self.assertTrue(self._listener.silenced)
        self._listener.receive_alternatives_added.assert_called_once_with({
            self._db_map: [{
                "id": 1,
                "name": "Base",
                "description": "Base alternative",
                "commit_id": 1
            }]
        })
        self.assertEqual(
            self._db_mngr.get_item(self._db_map, "alternative", 1),
            {
                'commit_id': 1,
                'description': 'Base alternative',
                'id': 1,
                'name': 'Base'
            },
        )
        self._listener.receive_scenarios_added.assert_not_called()
        self._listener.receive_scenario_alternatives_added.assert_not_called()
        self._listener.receive_object_classes_added.assert_not_called()
        self._listener.receive_objects_added.assert_not_called()
        self._listener.receive_relationship_classes_added.assert_not_called()
        self._listener.receive_relationships_added.assert_not_called()
        self._listener.receive_entity_groups_added.assert_not_called()
        self._listener.receive_parameter_definitions_added.assert_not_called()
        self._listener.receive_parameter_definition_tags_added.assert_not_called(
        )
        self._listener.receive_parameter_values_added.assert_not_called()
        self._listener.receive_parameter_value_lists_added.assert_not_called()
        self._listener.receive_parameter_tags_added.assert_not_called()
        self._listener.receive_features_added.assert_not_called()
        self._listener.receive_tools_added.assert_not_called()
        self._listener.receive_tool_features_added.assert_not_called()
        self._listener.receive_tool_feature_methods_added.assert_not_called()

    def _import_data(self, **data):
        waiter = SignalWaiter()
        self._db_mngr.data_imported.connect(waiter.trigger)
        self._db_mngr.import_data({self._db_map: data})
        waiter.wait()
        self._db_mngr.data_imported.disconnect(waiter.trigger)
        self._db_mngr._get_commit_msg = lambda *args, **kwargs: "Add test data."
        self._db_mngr.session_committed.connect(waiter.trigger)
        self._db_mngr.commit_session(self._db_map)
        waiter.wait()
        self._db_mngr.session_committed.disconnect(waiter.trigger)

    def test_fetch_alternatives(self):
        self._import_data(alternatives=("alt", ))
        self._fetch()
        self._listener.receive_alternatives_added.assert_called_once_with({
            self._db_map: [
                {
                    'id': 1,
                    'name': 'Base',
                    'description': 'Base alternative',
                    'commit_id': 1
                },
                {
                    'id': 2,
                    'name': 'alt',
                    'description': None,
                    'commit_id': 2
                },
            ]
        })
        self.assertEqual(
            self._db_mngr.get_item(self._db_map, "alternative", 2),
            {
                'commit_id': 2,
                'description': None,
                'id': 2,
                'name': 'alt'
            },
        )

    def test_fetch_scenarios(self):
        self._import_data(scenarios=("scenario", ))
        self._fetch()
        self._listener.receive_scenarios_added.assert_called_once_with({
            self._db_map: [{
                'id': 1,
                'name': 'scenario',
                'description': None,
                'active': False,
                'alternative_id_list': None,
                'alternative_name_list': None,
            }]
        })
        self.assertEqual(
            self._db_mngr.get_item(self._db_map, "scenario", 1),
            {
                'active': False,
                'alternative_id_list': None,
                'alternative_name_list': None,
                'description': None,
                'id': 1,
                'name': 'scenario',
            },
        )

    def test_fetch_scenario_alternatives(self):
        self._import_data(alternatives=("alt", ),
                          scenarios=("scenario", ),
                          scenario_alternatives=(("scenario", "alt"), ))
        self._fetch()
        self.assertEqual(
            self._db_mngr.get_item(self._db_map, "scenario_alternative", 1),
            {
                'alternative_id': 2,
                'commit_id': 2,
                'id': 1,
                'rank': 1,
                'scenario_id': 1
            },
        )

    def test_fetch_object_classes(self):
        self._import_data(object_classes=("oc", ))
        self._fetch()
        self._listener.receive_object_classes_added.assert_called_once_with({
            self._db_map: [{
                'id': 1,
                'name': 'oc',
                'description': None,
                'display_order': 99,
                'display_icon': None,
                'hidden': 0,
                'commit_id': 2,
            }]
        })
        self.assertIsInstance(
            self._db_mngr.entity_class_icon(self._db_map, "object_class", 1),
            QIcon)
        self.assertEqual(
            self._db_mngr.get_item(self._db_map, "object_class", 1),
            {
                'commit_id': 2,
                'description': None,
                'display_icon': None,
                'display_order': 99,
                'hidden': 0,
                'id': 1,
                'name': 'oc',
            },
        )

    def test_fetch_objects(self):
        self._import_data(object_classes=("oc", ), objects=(("oc", "obj"), ))
        self._fetch()
        self._listener.receive_objects_added.assert_called_once_with({
            self._db_map: [{
                'id': 1,
                'class_id': 1,
                'class_name': 'oc',
                'name': 'obj',
                'description': None
            }]
        })
        self.assertEqual(
            self._db_mngr.get_item(self._db_map, "object", 1),
            {
                'class_id': 1,
                'class_name': 'oc',
                'description': None,
                'id': 1,
                'name': 'obj'
            },
        )

    def test_fetch_relationship_classes(self):
        self._import_data(object_classes=("oc", ),
                          relationship_classes=(("rc", ("oc", )), ))
        self._fetch()
        self._listener.receive_relationship_classes_added.assert_called_once_with(
            {
                self._db_map: [{
                    'id': 2,
                    'name': 'rc',
                    'description': None,
                    'object_class_id_list': '1',
                    'object_class_name_list': 'oc',
                }]
            })
        self.assertEqual(
            self._db_mngr.get_item(self._db_map, "relationship_class", 2),
            {
                'description': None,
                'id': 2,
                'name': 'rc',
                'object_class_id_list': '1',
                'object_class_name_list': 'oc'
            },
        )

    def test_fetch_relationships(self):
        self._import_data(
            object_classes=("oc", ),
            objects=(("oc", "obj"), ),
            relationship_classes=(("rc", ("oc", )), ),
            relationships=(("rc", ("obj", )), ),
        )
        self._fetch()
        self._listener.receive_relationships_added.assert_called_once_with({
            self._db_map: [{
                'id': 2,
                'name': 'rc_obj',
                'class_id': 2,
                'class_name': 'rc',
                'object_id_list': '1',
                'object_name_list': 'obj',
                'object_class_id_list': '1',
                'object_class_name_list': 'oc',
            }]
        })
        self.assertEqual(
            self._db_mngr.get_item(self._db_map, "relationship", 2),
            {
                'class_id': 2,
                'class_name': 'rc',
                'id': 2,
                'name': 'rc_obj',
                'object_class_id_list': '1',
                'object_class_name_list': 'oc',
                'object_id_list': '1',
                'object_name_list': 'obj',
            },
        )

    def test_fetch_object_groups(self):
        self._import_data(object_classes=("oc", ),
                          objects=(("oc", "obj"), ("oc", "group")),
                          object_groups=(("oc", "group", "obj"), ))
        self._fetch()
        self._listener.receive_entity_groups_added.assert_called_once_with({
            self._db_map: [{
                'id': 1,
                'class_id': 1,
                'group_id': 2,
                'member_id': 1,
                'class_name': 'oc',
                'group_name': 'group',
                'member_name': 'obj',
            }]
        })
        self.assertEqual(
            self._db_mngr.get_item(self._db_map, "entity_group", 1),
            {
                'id': 1,
                'class_id': 1,
                'group_id': 2,
                'member_id': 1,
                'class_name': 'oc',
                'group_name': 'group',
                'member_name': 'obj',
            },
        )

    def test_fetch_parameter_definitions(self):
        self._import_data(object_classes=("oc", ),
                          object_parameters=(("oc", "param"), ))
        self._fetch()
        self._listener.receive_parameter_definitions_added.assert_called_once_with(
            {
                self._db_map: [{
                    'id': 1,
                    'entity_class_id': 1,
                    'object_class_id': 1,
                    'object_class_name': 'oc',
                    'parameter_name': 'param',
                    'value_list_id': None,
                    'value_list_name': None,
                    'parameter_tag_id_list': None,
                    'parameter_tag_list': None,
                    'default_value': None,
                    'description': None,
                }]
            })
        self.assertEqual(
            self._db_mngr.get_item(self._db_map, "parameter_definition", 1),
            {
                'default_value': None,
                'description': None,
                'entity_class_id': 1,
                'id': 1,
                'object_class_id': 1,
                'object_class_name': 'oc',
                'parameter_name': 'param',
                'parameter_tag_id_list': None,
                'parameter_tag_list': None,
                'value_list_id': None,
                'value_list_name': None,
            },
        )

    def test_fetch_parameter_values(self):
        self._import_data(
            object_classes=("oc", ),
            objects=(("oc", "obj"), ),
            object_parameters=(("oc", "param"), ),
            object_parameter_values=(("oc", "obj", "param", 2.3), ),
        )
        self._fetch()
        self._listener.receive_parameter_values_added.assert_called_once_with({
            self._db_map: [{
                'id': 1,
                'entity_class_id': 1,
                'object_class_id': 1,
                'object_class_name': 'oc',
                'entity_id': 1,
                'object_id': 1,
                'object_name': 'obj',
                'parameter_id': 1,
                'parameter_name': 'param',
                'alternative_id': 1,
                'alternative_name': 'Base',
                'value': '2.3',
            }]
        })
        self.assertEqual(
            self._db_mngr.get_item(self._db_map, "parameter_value", 1),
            {
                'alternative_id': 1,
                'alternative_name': 'Base',
                'entity_class_id': 1,
                'entity_id': 1,
                'id': 1,
                'object_class_id': 1,
                'object_class_name': 'oc',
                'object_id': 1,
                'object_name': 'obj',
                'parameter_id': 1,
                'parameter_name': 'param',
                'value': '2.3',
            },
        )

    def test_fetch_parameter_value_lists(self):
        self._import_data(parameter_value_lists=(("value_list", (2.3, )), ))
        self._fetch()
        self._listener.receive_parameter_value_lists_added.assert_called_once_with(
            {
                self._db_map: [{
                    'id': 1,
                    'name': 'value_list',
                    'value_index_list': '0',
                    'value_list': '[2.3]'
                }]
            })
        self.assertEqual(
            self._db_mngr.get_item(self._db_map, "parameter_value_list", 1),
            {
                'id': 1,
                'name': 'value_list',
                'value_index_list': '0',
                'value_list': '[2.3]'
            },
        )

    def test_fetch_features(self):
        self._import_data(
            object_classes=("oc", ),
            parameter_value_lists=(("value_list", (2.3, )), ),
            object_parameters=(("oc", "param", 2.3, "value_list"), ),
            features=(("oc", "param"), ),
        )
        self._fetch()
        self._listener.receive_features_added.assert_called_once_with({
            self._db_map: [{
                'id': 1,
                'entity_class_id': 1,
                'entity_class_name': 'oc',
                'parameter_definition_id': 1,
                'parameter_definition_name': 'param',
                'parameter_value_list_id': 1,
                'parameter_value_list_name': 'value_list',
                'description': None,
            }]
        })
        self.assertEqual(
            self._db_mngr.get_item(self._db_map, "feature", 1),
            {
                'description': None,
                'entity_class_id': 1,
                'entity_class_name': 'oc',
                'id': 1,
                'parameter_definition_id': 1,
                'parameter_definition_name': 'param',
                'parameter_value_list_id': 1,
                'parameter_value_list_name': 'value_list',
            },
        )

    def test_fetch_tools(self):
        self._import_data(tools=("tool", ))
        self._fetch()
        self._listener.receive_tools_added.assert_called_once_with({
            self._db_map: [{
                'id': 1,
                'name': 'tool',
                'description': None,
                'commit_id': 2
            }]
        })
        self.assertEqual(
            self._db_mngr.get_item(self._db_map, "tool", 1),
            {
                'commit_id': 2,
                'description': None,
                'id': 1,
                'name': 'tool'
            },
        )

    def test_fetch_tool_features(self):
        self._import_data(
            object_classes=("oc", ),
            parameter_value_lists=(("value_list", (2.3, )), ),
            object_parameters=(("oc", "param", 2.3, "value_list"), ),
            features=(("oc", "param"), ),
            tools=("tool", ),
            tool_features=(("tool", "oc", "param"), ),
        )
        self._fetch()
        self._listener.receive_tool_features_added.assert_called_once_with({
            self._db_map: [{
                'id': 1,
                'tool_id': 1,
                'feature_id': 1,
                'parameter_value_list_id': 1,
                'required': False,
                'commit_id': 2,
            }]
        })
        self.assertEqual(
            self._db_mngr.get_item(self._db_map, "tool_feature", 1),
            {
                'commit_id': 2,
                'feature_id': 1,
                'id': 1,
                'parameter_value_list_id': 1,
                'required': False,
                'tool_id': 1
            },
        )

    def test_fetch_tool_feature_methods(self):
        self._import_data(
            object_classes=("oc", ),
            parameter_value_lists=(("value_list", "m"), ),
            object_parameters=(("oc", "param", "m", "value_list"), ),
            features=(("oc", "param"), ),
            tools=("tool", ),
            tool_features=(("tool", "oc", "param"), ),
            tool_feature_methods=(("tool", "oc", "param", "m"), ),
        )
        self._fetch()
        self._listener.receive_tool_feature_methods_added.assert_called_once_with(
            {
                self._db_map: [{
                    'id': 1,
                    'tool_feature_id': 1,
                    'parameter_value_list_id': 1,
                    'method_index': 0,
                    'commit_id': 2
                }]
            })
        self.assertEqual(
            self._db_mngr.get_item(self._db_map, "tool_feature_method", 1),
            {
                'commit_id': 2,
                'id': 1,
                'method_index': 0,
                'parameter_value_list_id': 1,
                'tool_feature_id': 1
            },
        )
Exemplo n.º 22
0
class TestIndexExpansionPivotTableModel(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        if not QApplication.instance():
            QApplication()

    def setUp(self):
        app_settings = MagicMock()
        self._temp_dir = TemporaryDirectory()
        url = "sqlite:///" + os.path.join(self._temp_dir.name, "db.sqlite")
        db_map = DiffDatabaseMapping(url, create=True)
        import_object_classes(db_map, ("class1",))
        import_object_parameters(db_map, (("class1", "parameter1"), ("class1", "parameter2")))
        import_objects(db_map, (("class1", "object1"), ("class1", "object2")))
        import_object_parameter_values(
            db_map,
            (
                ("class1", "object1", "parameter1", Map(["A", "B"], [1.1, 2.1])),
                ("class1", "object2", "parameter1", Map(["C", "D"], [1.2, 2.2])),
                ("class1", "object1", "parameter2", Map(["C", "D"], [-1.1, -2.1])),
                ("class1", "object2", "parameter2", Map(["A", "B"], [-1.2, -2.2])),
            ),
        )
        db_map.commit_session("Add test data.")
        db_map.connection.close()
        with patch("spinetoolbox.spine_db_manager.SpineDBManager.thread", new_callable=PropertyMock) as mock_thread:
            mock_thread.return_value = QApplication.instance().thread()
            self._db_mngr = SpineDBManager(app_settings, None)
            with patch.object(SpineDBEditor, "restore_ui"):
                self._editor = SpineDBEditor(self._db_mngr, {url: db_map.codename})
        object_class_index = self._editor.object_tree_model.index(0, 0)
        self._editor.object_tree_model.fetchMore(object_class_index)
        index = self._editor.object_tree_model.index(0, 0, object_class_index)
        for action in self._editor.pivot_action_group.actions():
            if action.text() == self._editor._INDEX_EXPANSION:
                action.trigger()
                break
        self._editor.reload_pivot_table(index)
        self._model = self._editor.pivot_table_model
        self._model.start_fetching()

    def tearDown(self):
        self._db_mngr.close_all_sessions()
        self._db_mngr.clean_up()
        self._temp_dir.cleanup()

    def test_data(self):
        self.assertEqual(self._model.rowCount(), 11)
        self.assertEqual(self._model.columnCount(), 5)
        model_data = list()
        i = self._model.index
        for row in range(11):
            model_data.append(list(i(row, column).data() for column in range(5)))
        expected = [
            [None, "parameter", "parameter1", "parameter2", None],
            ["class1", "index", None, None, None],
            ["object1", "A", str(1.1), None, None],
            ["object1", "B", str(2.1), None, None],
            ["object2", "C", str(1.2), None, None],
            ["object2", "D", str(2.2), None, None],
            ["object1", "C", None, str(-1.1), None],
            ["object1", "D", None, str(-2.1), None],
            ["object2", "A", None, str(-1.2), None],
            ["object2", "B", None, str(-2.2), None],
            [None, None, None, None, None],
        ]
        self.assertEqual(model_data, expected)
class TestCompoundRelationshipParameterDefinitionModel(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        if not QApplication.instance():
            QApplication()

    def setUp(self):
        app_settings = MagicMock()
        logger = MagicMock()
        with unittest.mock.patch(
                "spinetoolbox.spine_db_manager.SpineDBManager.thread",
                new_callable=PropertyMock) as mock_thread:
            mock_thread.return_value = QApplication.instance().thread()
            self._db_mngr = SpineDBManager(app_settings, None)
        self._db_editor = SpineDBEditor(self._db_mngr)
        self._db_map = self._db_mngr.get_db_map("sqlite://",
                                                logger,
                                                codename="test_db",
                                                create=True)

    def tearDown(self):
        self._db_mngr.close_all_sessions()
        self._db_mngr.clean_up()

    def test_horizontal_header(self):
        model = CompoundRelationshipParameterDefinitionModel(
            self._db_editor, self._db_mngr, self._db_map)
        model.init_model()
        expected_header = [
            "relationship_class_name",
            "object_class_name_list",
            "parameter_name",
            "value_list_name",
            "parameter_tag_list",
            "default_value",
            "description",
            "database",
        ]
        header = [model.headerData(i) for i in range(model.columnCount())]
        self.assertEqual(header, expected_header)

    def test_data_for_single_parameter_definition(self):
        model = CompoundRelationshipParameterDefinitionModel(
            self._db_editor, self._db_mngr, self._db_map)
        model.init_model()
        self._db_mngr.add_object_classes({self._db_map: [{"name": "oc"}]})
        self._db_mngr.add_relationship_classes(
            {self._db_map: [{
                "name": "rc",
                "object_class_id_list": [1]
            }]})
        self._db_mngr.add_parameter_definitions(
            {self._db_map: [{
                "name": "p",
                "relationship_class_id": 2
            }]})
        definition_data = self._db_mngr.find_cascading_parameter_data(
            {self._db_map: [2]}, "parameter_definition")
        model.receive_parameter_data_added(definition_data)
        self.assertEqual(model.rowCount(), 1)
        self.assertEqual(model.columnCount(), 8)
        row = [
            model.index(0, column).data()
            for column in range(model.columnCount())
        ]
        expected = ["rc", "oc", "p", None, None, "None", None, "test_db"]
        self.assertEqual(row, expected)
class TestSpineDBEditorWithDBMapping(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        """Overridden method. Runs once before all tests in this class."""
        try:
            cls.app = QApplication().processEvents()
        except RuntimeError:
            pass
        logging.basicConfig(
            stream=sys.stderr,
            level=logging.DEBUG,
            format='%(asctime)s %(levelname)s: %(message)s',
            datefmt='%Y-%m-%d %H:%M:%S',
        )

    def setUp(self):
        """Overridden method. Runs before each test. Makes instances of SpineDBEditor classes."""
        self._temp_dir = TemporaryDirectory()
        url = "sqlite:///" + os.path.join(self._temp_dir.name, "test.sqlite")
        with mock.patch(
                "spinetoolbox.spine_db_editor.widgets.spine_db_editor.SpineDBEditor.restore_ui"
        ), mock.patch(
                "spinetoolbox.spine_db_editor.widgets.spine_db_editor.SpineDBEditor.show"
        ):
            mock_settings = mock.Mock()
            mock_settings.value.side_effect = lambda *args, **kwards: 0
            self.db_mngr = SpineDBManager(mock_settings, None)
            logger = mock.MagicMock()
            self.db_map = self.db_mngr.get_db_map(url,
                                                  logger,
                                                  codename="db",
                                                  create=True)
            self.spine_db_editor = SpineDBEditor(self.db_mngr, {url: "db"})
            self.spine_db_editor.pivot_table_model = mock.MagicMock()

    def tearDown(self):
        """Overridden method. Runs after each test.
        Use this to free resources after a test if needed.
        """
        with mock.patch(
                "spinetoolbox.spine_db_editor.widgets.spine_db_editor.SpineDBEditor.save_window_state"
        ) as mock_save_w_s, mock.patch(
                "spinetoolbox.spine_db_manager.QMessageBox"):
            self.spine_db_editor.close()
            mock_save_w_s.assert_called_once()
        QApplication.removePostedEvents(
            None)  # Clean up unfinished fetcher signals
        self.db_mngr.close_all_sessions()
        self.db_mngr.clean_up()
        self.db_mngr = None  # Ensure the database file is closed to allow the temporary directory to be removed.
        self.spine_db_editor.deleteLater()
        self.spine_db_editor = None
        self._temp_dir.cleanup()

    def fetch_object_tree_model(self):
        for item in self.spine_db_editor.object_tree_model.visit_all():
            if item.can_fetch_more():
                item.fetch_more()

    def test_duplicate_object_in_object_tree_model(self):
        data = dict()
        data["object_classes"] = ["fish", "dog"]
        data["relationship_classes"] = [("fish__dog", ("fish", "dog"))]
        data["objects"] = [("fish", "nemo"), ("dog", "pluto")]
        data["relationships"] = [("fish__dog", ("nemo", "pluto"))]
        data["object_parameters"] = [("fish", "color")]
        data["object_parameter_values"] = [("fish", "nemo", "color", "orange")]
        with mock.patch(
                "spinetoolbox.spine_db_manager.SpineDBManager.entity_class_icon"
        ) as mock_icon:
            mock_icon.return_value = None
            loop = QEventLoop()
            self.db_mngr.data_imported.connect(loop.quit)
            self.db_mngr.import_data({self.db_map: data})
            loop.exec_()
            loop.deleteLater()
            mock_icon.assert_called()
        self.fetch_object_tree_model()
        root_item = self.spine_db_editor.object_tree_model.root_item
        fish_item = next(
            iter(item for item in root_item.children
                 if item.display_data == "fish"))
        nemo_item = fish_item.child(0)
        with mock.patch(
                "spinetoolbox.spine_db_editor.widgets.tree_view_mixin.QInputDialog"
        ) as mock_input_dialog:
            mock_input_dialog.getText.side_effect = lambda *args, **kwargs: (
                "nemo_copy", True)
            loop = QEventLoop()
            self.db_mngr.data_imported.connect(loop.quit)
            self.spine_db_editor.duplicate_object(nemo_item.index())
            loop.exec_()
            loop.deleteLater()
        nemo_dupe = fish_item.child(1)
        self.assertEqual(nemo_dupe.display_data, "nemo_copy")
Exemplo n.º 25
0
class TestParameterValuePivotTableModel(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        if not QApplication.instance():
            QApplication()

    def setUp(self):
        app_settings = MagicMock()
        self._temp_dir = TemporaryDirectory()
        url = "sqlite:///" + os.path.join(self._temp_dir.name, "db.sqlite")
        db_map = DiffDatabaseMapping(url, create=True)
        import_object_classes(db_map, ("class1",))
        import_object_parameters(db_map, (("class1", "parameter1"), ("class1", "parameter2")))
        import_objects(db_map, (("class1", "object1"), ("class1", "object2")))
        import_object_parameter_values(
            db_map,
            (
                ("class1", "object1", "parameter1", 1.0),
                ("class1", "object2", "parameter1", 3.0),
                ("class1", "object1", "parameter2", 5.0),
                ("class1", "object2", "parameter2", 7.0),
            ),
        )
        db_map.commit_session("Add test data.")
        db_map.connection.close()
        with patch("spinetoolbox.spine_db_manager.SpineDBManager.thread", new_callable=PropertyMock) as mock_thread:
            mock_thread.return_value = QApplication.instance().thread()
            self._db_mngr = SpineDBManager(app_settings, None)
            with patch.object(SpineDBEditor, "restore_ui"):
                self._editor = SpineDBEditor(self._db_mngr, {url: db_map.codename})
        object_class_index = self._editor.object_tree_model.index(0, 0)
        self._editor.object_tree_model.fetchMore(object_class_index)
        index = self._editor.object_tree_model.index(0, 0, object_class_index)
        self._editor.reload_pivot_table(index)
        self._model = self._editor.pivot_table_model
        self._model.start_fetching()

    def tearDown(self):
        self._db_mngr.close_all_sessions()
        self._db_mngr.clean_up()
        self._temp_dir.cleanup()

    def test_x_flag(self):
        self.assertIsNone(self._model.plot_x_column)
        self._model.set_plot_x_column(1, True)
        self.assertEqual(self._model.plot_x_column, 1)
        self._model.set_plot_x_column(1, False)
        self.assertIsNone(self._model.plot_x_column)

    def test_header_name(self):
        self.assertEqual(self._model.rowCount(), 5)
        self.assertEqual(self._model.columnCount(), 4)
        self.assertEqual(self._model.header_name(self._model.index(2, 0)), 'object1')
        self.assertEqual(self._model.header_name(self._model.index(0, 1)), 'parameter1')
        self.assertEqual(self._model.header_name(self._model.index(3, 0)), 'object2')
        self.assertEqual(self._model.header_name(self._model.index(0, 2)), 'parameter2')

    def test_data(self):
        self.assertEqual(self._model.rowCount(), 5)
        self.assertEqual(self._model.columnCount(), 4)
        self.assertEqual(self._model.index(0, 0).data(), "parameter")
        self.assertEqual(self._model.index(1, 0).data(), "class1")
        self.assertEqual(self._model.index(2, 0).data(), "object1")
        self.assertEqual(self._model.index(3, 0).data(), "object2")
        self.assertEqual(self._model.index(4, 0).data(), None)
        self.assertEqual(self._model.index(0, 1).data(), "parameter1")
        self.assertEqual(self._model.index(1, 1).data(), None)
        self.assertEqual(self._model.index(2, 1).data(), str(1.0))
        self.assertEqual(self._model.index(3, 1).data(), str(3.0))
        self.assertEqual(self._model.index(4, 1).data(), None)
        self.assertEqual(self._model.index(0, 2).data(), "parameter2")
        self.assertEqual(self._model.index(1, 2).data(), None)
        self.assertEqual(self._model.index(2, 2).data(), str(5.0))
        self.assertEqual(self._model.index(3, 2).data(), str(7.0))
        self.assertEqual(self._model.index(4, 2).data(), None)
        self.assertEqual(self._model.index(0, 3).data(), None)
        self.assertEqual(self._model.index(1, 3).data(), None)
        self.assertEqual(self._model.index(2, 3).data(), None)
        self.assertEqual(self._model.index(3, 3).data(), None)
        self.assertEqual(self._model.index(4, 3).data(), None)

    def test_header_row_count(self):
        self.assertEqual(self._model.headerRowCount(), 2)
Exemplo n.º 26
0
class TestSpineDBEditor(
        TestSpineDBEditorAddMixin,
        TestSpineDBEditorUpdateMixin,
        TestSpineDBEditorRemoveMixin,
        TestSpineDBEditorFilterMixin,
        unittest.TestCase,
):
    @staticmethod
    def _object_class(*args):
        return dict(
            zip(["id", "name", "description", "display_order", "display_icon"],
                args))

    @staticmethod
    def _object(*args):
        return dict(zip(["id", "class_id", "name", "description"], args))

    @staticmethod
    def _relationship_class(*args):
        return dict(
            zip([
                "id", "name", "object_class_id_list", "object_class_name_list"
            ], args))

    @staticmethod
    def _relationship(*args):
        return dict(
            zip(
                [
                    "id", "class_id", "name", "class_name",
                    "object_class_id_list", "object_id_list",
                    "object_name_list"
                ],
                args,
            ))

    @staticmethod
    def _object_parameter_definition(*args):
        d = dict(
            zip([
                "id", "object_class_id", "object_class_name", "parameter_name"
            ], args))
        return d

    @staticmethod
    def _relationship_parameter_definition(*args):
        d = dict(
            zip(
                [
                    "id",
                    "relationship_class_id",
                    "relationship_class_name",
                    "object_class_id_list",
                    "object_class_name_list",
                    "parameter_name",
                ],
                args,
            ))
        return d

    @staticmethod
    def _object_parameter_value(*args):
        d = dict(
            zip(
                [
                    "id",
                    "object_class_id",
                    "object_class_name",
                    "object_id",
                    "object_name",
                    "parameter_id",
                    "parameter_name",
                    "value",
                ],
                args,
            ))
        d["entity_id"] = d["object_id"]
        return d

    @staticmethod
    def _relationship_parameter_value(*args):
        d = dict(
            zip(
                [
                    "id",
                    "relationship_class_id",
                    "relationship_class_name",
                    "object_class_id_list",
                    "object_class_name_list",
                    "relationship_id",
                    "object_id_list",
                    "object_name_list",
                    "parameter_id",
                    "parameter_name",
                    "value",
                ],
                args,
            ))
        d["entity_id"] = d["relationship_id"]
        return d

    @classmethod
    def setUpClass(cls):
        """Overridden method. Runs once before all tests in this class."""
        try:
            cls.app = QApplication().processEvents()
        except RuntimeError:
            pass
        logging.basicConfig(
            stream=sys.stderr,
            level=logging.DEBUG,
            format='%(asctime)s %(levelname)s: %(message)s',
            datefmt='%Y-%m-%d %H:%M:%S',
        )
        cls.create_mock_dataset()

    @classmethod
    def create_mock_dataset(cls):
        cls.fish_class = cls._object_class(1, "fish", "A fish.", 1, None)
        cls.dog_class = cls._object_class(2, "dog", "A dog.", 3, None)
        cls.fish_dog_class = cls._relationship_class(
            3,
            "fish__dog",
            str(cls.fish_class["id"]) + "," + str(cls.dog_class["id"]),
            cls.fish_class["name"] + "," + cls.dog_class["name"],
        )
        cls.dog_fish_class = cls._relationship_class(
            4,
            "dog__fish",
            str(cls.dog_class["id"]) + "," + str(cls.fish_class["id"]),
            cls.dog_class["name"] + "," + cls.fish_class["name"],
        )
        cls.nemo_object = cls._object(1, cls.fish_class["id"], 'nemo',
                                      'The lost one.')
        cls.pluto_object = cls._object(2, cls.dog_class["id"], 'pluto',
                                       "Mickey's.")
        cls.scooby_object = cls._object(3, cls.dog_class["id"], 'scooby',
                                        'Scooby-Dooby-Doo.')
        cls.pluto_nemo_rel = cls._relationship(
            4,
            cls.dog_fish_class["id"],
            "dog__fish_pluto__nemo",
            cls.dog_fish_class["name"],
            str(cls.dog_class["id"]) + "," + str(cls.fish_class["id"]),
            str(cls.pluto_object["id"]) + "," + str(cls.nemo_object["id"]),
            cls.pluto_object["name"] + "," + cls.nemo_object["name"],
        )
        cls.nemo_pluto_rel = cls._relationship(
            5,
            cls.fish_dog_class["id"],
            "fish__dog_nemo__pluto",
            cls.fish_dog_class["name"],
            str(cls.fish_class["id"]) + "," + str(cls.dog_class["id"]),
            str(cls.nemo_object["id"]) + "," + str(cls.pluto_object["id"]),
            cls.nemo_object["name"] + "," + cls.pluto_object["name"],
        )
        cls.nemo_scooby_rel = cls._relationship(
            6,
            cls.fish_dog_class["id"],
            "fish__dog_nemo__scooby",
            cls.fish_dog_class["name"],
            str(cls.fish_class["id"]) + "," + str(cls.dog_class["id"]),
            str(cls.nemo_object["id"]) + "," + str(cls.scooby_object["id"]),
            cls.nemo_object["name"] + "," + cls.scooby_object["name"],
        )
        cls.water_parameter = cls._object_parameter_definition(
            1, cls.fish_class["id"], cls.fish_class["name"], "water")
        cls.breed_parameter = cls._object_parameter_definition(
            2, cls.dog_class["id"], cls.dog_class["name"], "breed")
        cls.relative_speed_parameter = cls._relationship_parameter_definition(
            3,
            cls.fish_dog_class["id"],
            cls.fish_dog_class["name"],
            cls.fish_dog_class["object_class_id_list"],
            cls.fish_dog_class["object_class_name_list"],
            "relative_speed",
        )
        cls.combined_mojo_parameter = cls._relationship_parameter_definition(
            4,
            cls.dog_fish_class["id"],
            cls.dog_fish_class["name"],
            cls.dog_fish_class["object_class_id_list"],
            cls.dog_fish_class["object_class_name_list"],
            "combined_mojo",
        )
        cls.nemo_water = cls._object_parameter_value(
            1,
            cls.water_parameter["object_class_id"],
            cls.water_parameter["object_class_name"],
            cls.nemo_object["id"],
            cls.nemo_object["name"],
            cls.water_parameter["id"],
            cls.water_parameter["parameter_name"],
            '"salt"',
        )
        cls.pluto_breed = cls._object_parameter_value(
            2,
            cls.breed_parameter["object_class_id"],
            cls.breed_parameter["object_class_name"],
            cls.pluto_object["id"],
            cls.pluto_object["name"],
            cls.breed_parameter["id"],
            cls.breed_parameter["parameter_name"],
            '"bloodhound"',
        )
        cls.scooby_breed = cls._object_parameter_value(
            3,
            cls.breed_parameter["object_class_id"],
            cls.breed_parameter["object_class_name"],
            cls.scooby_object["id"],
            cls.scooby_object["name"],
            cls.breed_parameter["id"],
            cls.breed_parameter["parameter_name"],
            '"great dane"',
        )
        cls.nemo_pluto_relative_speed = cls._relationship_parameter_value(
            4,
            cls.relative_speed_parameter["relationship_class_id"],
            cls.relative_speed_parameter["relationship_class_name"],
            cls.relative_speed_parameter["object_class_id_list"],
            cls.relative_speed_parameter["object_class_name_list"],
            cls.nemo_pluto_rel["id"],
            cls.nemo_pluto_rel["object_id_list"],
            cls.nemo_pluto_rel["object_name_list"],
            cls.relative_speed_parameter["id"],
            cls.relative_speed_parameter["parameter_name"],
            "-1",
        )
        cls.nemo_scooby_relative_speed = cls._relationship_parameter_value(
            5,
            cls.relative_speed_parameter["relationship_class_id"],
            cls.relative_speed_parameter["relationship_class_name"],
            cls.relative_speed_parameter["object_class_id_list"],
            cls.relative_speed_parameter["object_class_name_list"],
            cls.nemo_scooby_rel["id"],
            cls.nemo_scooby_rel["object_id_list"],
            cls.nemo_scooby_rel["object_name_list"],
            cls.relative_speed_parameter["id"],
            cls.relative_speed_parameter["parameter_name"],
            "5",
        )
        cls.pluto_nemo_combined_mojo = cls._relationship_parameter_value(
            6,
            cls.combined_mojo_parameter["relationship_class_id"],
            cls.combined_mojo_parameter["relationship_class_name"],
            cls.combined_mojo_parameter["object_class_id_list"],
            cls.combined_mojo_parameter["object_class_name_list"],
            cls.pluto_nemo_rel["id"],
            cls.pluto_nemo_rel["object_id_list"],
            cls.pluto_nemo_rel["object_name_list"],
            cls.combined_mojo_parameter["id"],
            cls.combined_mojo_parameter["parameter_name"],
            "100",
        )

    def setUp(self):
        """Overridden method. Runs before each test. Makes instances of SpineDBEditor classes."""
        with mock.patch(
                "spinetoolbox.spine_db_editor.widgets.spine_db_editor.SpineDBEditor.restore_ui"
        ), mock.patch(
                "spinetoolbox.spine_db_editor.widgets.spine_db_editor.SpineDBEditor.show"
        ):
            mock_settings = mock.Mock()
            mock_settings.value.side_effect = lambda *args, **kwards: 0
            self.db_mngr = SpineDBManager(mock_settings, None)
            self.db_mngr.fetch_db_maps_for_listener = lambda *args: None

            logger = mock.MagicMock()
            self.db_mngr.get_db_map("sqlite://",
                                    logger,
                                    codename="database",
                                    create=True)
            self.spine_db_editor = SpineDBEditor(self.db_mngr,
                                                 {"sqlite://": "database"})
            self.mock_db_map = self.spine_db_editor.first_db_map
            self.spine_db_editor.pivot_table_model = mock.MagicMock()

    def tearDown(self):
        """Overridden method. Runs after each test.
        Use this to free resources after a test if needed.
        """
        with mock.patch(
                "spinetoolbox.spine_db_editor.widgets.spine_db_editor.SpineDBEditor.save_window_state"
        ) as mock_save_w_s, mock.patch(
                "spinetoolbox.spine_db_manager.QMessageBox"):
            self.spine_db_editor.close()
            mock_save_w_s.assert_called_once()
        QApplication.removePostedEvents(
            None)  # Clean up unfinished fetcher signals
        self.db_mngr.close_all_sessions()
        self.db_mngr.clean_up()
        self.spine_db_editor.deleteLater()
        self.spine_db_editor = None

    def put_mock_object_classes_in_db_mngr(self):
        """Put fish and dog object classes in the db mngr."""
        object_classes = [self.fish_class, self.dog_class]
        with mock.patch(
                "spinetoolbox.spine_db_manager.SpineDBManager.entity_class_icon"
        ) as mock_icon:
            mock_icon.return_value = None
            self.db_mngr.object_classes_added.emit(
                {self.mock_db_map: object_classes})
            mock_icon.assert_called()

    def put_mock_objects_in_db_mngr(self):
        """Put nemo, pluto and scooby objects in the db mngr."""
        objects = [self.nemo_object, self.pluto_object, self.scooby_object]
        self.db_mngr.objects_added.emit({self.mock_db_map: objects})

    def put_mock_relationship_classes_in_db_mngr(self):
        """Put dog__fish and fish__dog relationship classes in the db mngr."""
        relationship_classes = [self.fish_dog_class, self.dog_fish_class]
        with mock.patch(
                "spinetoolbox.spine_db_manager.SpineDBManager.entity_class_icon"
        ) as mock_icon:
            mock_icon.return_value = None
            self.db_mngr.relationship_classes_added.emit(
                {self.mock_db_map: relationship_classes})
            mock_icon.assert_called()

    def put_mock_relationships_in_db_mngr(self):
        """Put pluto_nemo, nemo_pluto and nemo_scooby relationships in the db mngr."""
        relationships = [
            self.pluto_nemo_rel, self.nemo_pluto_rel, self.nemo_scooby_rel
        ]
        self.db_mngr.relationships_added.emit(
            {self.mock_db_map: relationships})

    def put_mock_object_parameter_definitions_in_db_mngr(self):
        """Put water and breed object parameter definitions in the db mngr."""
        parameter_definitions = [self.water_parameter, self.breed_parameter]
        with mock.patch.object(CompoundParameterModel,
                               "_modify_data_in_filter_menus"):
            self.db_mngr.parameter_definitions_added.emit(
                {self.mock_db_map: parameter_definitions})

    def put_mock_relationship_parameter_definitions_in_db_mngr(self):
        """Put relative speed and combined mojo relationship parameter definitions in the db mngr."""
        parameter_definitions = [
            self.relative_speed_parameter, self.combined_mojo_parameter
        ]
        with mock.patch.object(CompoundParameterModel,
                               "_modify_data_in_filter_menus"):
            self.db_mngr.parameter_definitions_added.emit(
                {self.mock_db_map: parameter_definitions})

    def put_mock_object_parameter_values_in_db_mngr(self):
        """Put some object parameter values in the db mngr."""
        parameter_values = [
            self.nemo_water, self.pluto_breed, self.scooby_breed
        ]
        with mock.patch.object(CompoundParameterModel,
                               "_modify_data_in_filter_menus"):
            self.db_mngr.parameter_values_added.emit(
                {self.mock_db_map: parameter_values})

    def put_mock_relationship_parameter_values_in_db_mngr(self):
        """Put some relationship parameter values in the db mngr."""
        parameter_values = [
            self.nemo_pluto_relative_speed,
            self.nemo_scooby_relative_speed,
            self.pluto_nemo_combined_mojo,
        ]
        with mock.patch.object(CompoundParameterModel,
                               "_modify_data_in_filter_menus"):
            self.db_mngr.parameter_values_added.emit(
                {self.mock_db_map: parameter_values})

    def put_mock_dataset_in_db_mngr(self):
        """Put mock dataset in the db mngr."""
        self.put_mock_object_classes_in_db_mngr()
        self.put_mock_objects_in_db_mngr()
        self.put_mock_relationship_classes_in_db_mngr()
        self.put_mock_relationships_in_db_mngr()
        self.put_mock_object_parameter_definitions_in_db_mngr()
        self.put_mock_relationship_parameter_definitions_in_db_mngr()
        self.put_mock_object_parameter_values_in_db_mngr()
        self.put_mock_relationship_parameter_values_in_db_mngr()
        self.fetch_object_tree_model()

    def fetch_object_tree_model(self):
        for item in self.spine_db_editor.object_tree_model.visit_all():
            if item.can_fetch_more():
                item.fetch_more()

    def test_set_object_parameter_definition_defaults(self):
        """Test that defaults are set in object parameter_definition models according the object tree selection."""
        self.spine_db_editor.init_models()
        self.put_mock_object_classes_in_db_mngr()
        self.fetch_object_tree_model()
        # Select fish item in object tree
        root_item = self.spine_db_editor.object_tree_model.root_item
        fish_item = root_item.child(0)
        fish_index = self.spine_db_editor.object_tree_model.index_from_item(
            fish_item)
        self.spine_db_editor.ui.treeView_object.setCurrentIndex(fish_index)
        self.spine_db_editor.ui.treeView_object.selectionModel().select(
            fish_index, QItemSelectionModel.Select)
        # Check default in object parameter_definition
        model = self.spine_db_editor.object_parameter_definition_model
        model.empty_model.fetchMore()
        h = model.header.index
        row_data = []
        for row in range(model.rowCount()):
            row_data.append(
                tuple(
                    model.index(row, h(field)).data()
                    for field in ("object_class_name", "database")))
        self.assertIn(("fish", "database"), row_data)

    @unittest.skip("TODO")
    def test_set_object_parameter_value_defaults(self):
        """Test that defaults are set in relationship parameter_definition
        models according the object tree selection.
        """
        self.fail()

    @unittest.skip("TODO")
    def test_set_relationship_parameter_definition_defaults(self):
        """Test that defaults are set in relationship parameter_definition
        models according the object tree selection.
        """
        self.fail()

    @unittest.skip("TODO")
    def test_set_relationship_parameter_value_defaults(self):
        """Test that defaults are set in relationship parameter_definition
        models according the object tree selection.
        """
        self.fail()
Exemplo n.º 27
0
 def setUp(self):
     self.db_mngr = SpineDBManager(None, None)
     self.db_mngr.get_item = Mock()
Exemplo n.º 28
0
class TestParameterValueFormatting(unittest.TestCase):
    """Tests for parameter_value formatting in SpineDBManager."""

    @classmethod
    def setUpClass(cls):
        if not QApplication.instance():
            QApplication()

    def setUp(self):
        self.db_mngr = SpineDBManager(None, None)
        self.db_mngr.get_item = Mock()

    def get_value(self, role):
        mock_db_map = Mock()
        id_ = 0
        return self.db_mngr.get_value(mock_db_map, "parameter_value", id_, role)

    def test_plain_number_in_display_role(self):
        value = 2.3
        self.db_mngr.get_item.return_value = {"value": to_database(value)}
        formatted = self.get_value(Qt.DisplayRole)
        self.assertEqual(formatted, "2.3")

    def test_plain_number_in_edit_role(self):
        value = 2.3
        self.db_mngr.get_item.return_value = {"value": to_database(value)}
        formatted = self.get_value(Qt.EditRole)
        self.assertEqual(formatted, "2.3")

    def test_plain_number_in_tool_tip_role(self):
        value = 2.3
        self.db_mngr.get_item.return_value = {"value": to_database(value)}
        self.assertIsNone(self.get_value(Qt.ToolTipRole))

    def test_date_time_in_display_role(self):
        value = DateTime("2019-07-12T16:00")
        self.db_mngr.get_item.return_value = {"value": to_database(value)}
        formatted = self.get_value(Qt.DisplayRole)
        self.assertEqual(formatted, "2019-07-12 16:00:00")

    def test_date_time_in_edit_role(self):
        value = DateTime("2019-07-12T16:00")
        self.db_mngr.get_item.return_value = {"value": to_database(value)}
        formatted = self.get_value(Qt.EditRole)
        self.assertEqual(formatted, to_database(value))

    def test_date_time_in_tool_tip_role(self):
        value = DateTime("2019-07-12T16:00")
        self.db_mngr.get_item.return_value = {"value": to_database(value)}
        self.assertIsNone(self.get_value(Qt.ToolTipRole))

    def test_duration_in_display_role(self):
        value = Duration("3Y")
        self.db_mngr.get_item.return_value = {"value": to_database(value)}
        formatted = self.get_value(Qt.DisplayRole)
        self.assertEqual(formatted, "3Y")

    def test_duration_in_edit_role(self):
        value = Duration("2M")
        self.db_mngr.get_item.return_value = {"value": to_database(value)}
        formatted = self.get_value(Qt.EditRole)
        self.assertEqual(formatted, to_database(value))

    def test_duration_in_tool_tip_role(self):
        value = Duration("13D")
        self.db_mngr.get_item.return_value = {"value": to_database(value)}
        self.assertIsNone(self.get_value(Qt.ToolTipRole))

    def test_time_pattern_in_display_role(self):
        value = TimePattern(["1-12m"], [5.0])
        self.db_mngr.get_item.return_value = {"value": to_database(value)}
        formatted = self.get_value(Qt.DisplayRole)
        self.assertEqual(formatted, "Time pattern")

    def test_time_pattern_in_edit_role(self):
        value = TimePattern(["1-12m"], [5.0])
        self.db_mngr.get_item.return_value = {"value": to_database(value)}
        formatted = self.get_value(Qt.EditRole)
        self.assertEqual(formatted, to_database(value))

    def test_time_pattern_in_tool_tip_role(self):
        value = TimePattern(["1-12m"], [5.0])
        self.db_mngr.get_item.return_value = {"value": to_database(value)}
        self.assertIsNone(self.get_value(Qt.ToolTipRole))

    def test_time_series_in_display_role(self):
        value = TimeSeriesFixedResolution("2019-07-12T08:00", "7 hours", [1.1, 2.2, 3.3], False, False)
        self.db_mngr.get_item.return_value = {"value": to_database(value)}
        formatted = self.get_value(Qt.DisplayRole)
        self.assertEqual(formatted, "Time series")
        value = TimeSeriesVariableResolution(["2019-07-12T08:00", "2019-07-12T16:00"], [0.0, 100.0], False, False)
        self.db_mngr.get_item.return_value = {"value": to_database(value)}
        formatted = self.get_value(Qt.DisplayRole)
        self.assertEqual(formatted, "Time series")

    def test_time_series_in_edit_role(self):
        value = TimeSeriesFixedResolution("2019-07-12T08:00", "7 hours", [1.1, 2.2, 3.3], False, False)
        self.db_mngr.get_item.return_value = {"value": to_database(value)}
        formatted = self.get_value(Qt.EditRole)
        self.assertEqual(formatted, to_database(value))
        value = TimeSeriesVariableResolution(["2019-07-12T08:00", "2019-07-12T16:00"], [0.0, 100.0], False, False)
        self.db_mngr.get_item.return_value = {"value": to_database(value)}
        formatted = self.get_value(Qt.EditRole)
        self.assertEqual(formatted, to_database(value))

    def test_time_series_in_tool_tip_role(self):
        value = TimeSeriesFixedResolution("2019-07-12T08:00", ["7 hours", "12 hours"], [1.1, 2.2, 3.3], False, False)
        self.db_mngr.get_item.return_value = {"value": to_database(value)}
        formatted = self.get_value(Qt.ToolTipRole)
        self.assertEqual(formatted, "Start: 2019-07-12 08:00:00, resolution: [7h, 12h], length: 3")
        value = TimeSeriesVariableResolution(["2019-07-12T08:00", "2019-07-12T16:00"], [0.0, 100.0], False, False)
        self.db_mngr.get_item.return_value = {"value": to_database(value)}
        formatted = self.get_value(Qt.ToolTipRole)
        self.assertEqual(formatted, "Start: 2019-07-12T08:00:00, resolution: variable, length: 2")

    def test_broken_value_in_display_role(self):
        value = "dubbidubbidu"
        self.db_mngr.get_item.return_value = {"value": value}
        formatted = self.get_value(Qt.DisplayRole)
        self.assertEqual(formatted, "Error")

    def test_broken_value_in_edit_role(self):
        value = "diibadaaba"
        self.db_mngr.get_item.return_value = {"value": value}
        formatted = self.get_value(Qt.EditRole)
        self.assertEqual(formatted, "diibadaaba")

    def test_broken_value_in_tool_tip_role(self):
        value = "diibadaaba"
        self.db_mngr.get_item.return_value = {"value": value}
        formatted = self.get_value(Qt.ToolTipRole)
        self.assertTrue(formatted.startswith('Could not decode the value'))
class TestEmptyParameterModel(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        if not QApplication.instance():
            QApplication()

    def setUp(self):
        """Overridden method. Runs before each test."""
        app_settings = mock.MagicMock()
        logger = mock.MagicMock()
        with mock.patch("spinetoolbox.spine_db_manager.SpineDBManager.thread",
                        new_callable=mock.PropertyMock) as mock_thread:
            mock_thread.return_value = QApplication.instance().thread()
            self._db_mngr = SpineDBManager(app_settings, None)
            fetcher = self._db_mngr.get_fetcher()
        self._db_map = self._db_mngr.get_db_map("sqlite://",
                                                logger,
                                                codename="mock_db",
                                                create=True)
        import_object_classes(self._db_map, ("dog", "fish"))
        import_object_parameters(self._db_map, (("dog", "breed"), ))
        import_objects(self._db_map, (("dog", "pluto"), ("fish", "nemo")))
        import_relationship_classes(self._db_map,
                                    (("dog__fish", ("dog", "fish")), ))
        import_relationship_parameters(self._db_map,
                                       (("dog__fish", "relative_speed"), ))
        import_relationships(self._db_map, (("dog_fish", ("pluto", "nemo")), ))
        self._db_map.commit_session("Add test data")
        fetcher.fetch([self._db_map])
        self.object_table_header = [
            "object_class_name",
            "object_name",
            "parameter_name",
            "alternative_id",
            "value",
            "database",
        ]
        self.relationship_table_header = [
            "relationship_class_name",
            "object_name_list",
            "parameter_name",
            "alternative_id",
            "value",
            "database",
        ]

    def tearDown(self):
        self._db_mngr.close_all_sessions()
        self._db_mngr.clean_up()
        self._db_mngr.deleteLater()

    def test_add_object_parameter_values_to_db(self):
        """Test that object parameter values are added to the db when editing the table."""
        header = self.object_table_header
        model = EmptyObjectParameterValueModel(None, header, self._db_mngr)
        model.fetchMore()
        self.assertTrue(
            model.batch_set_data(
                _empty_indexes(model),
                ["dog", "pluto", "breed", 1, "bloodhound", "mock_db"]))
        values = next(self._db_mngr.get_object_parameter_values(self._db_map),
                      [])
        self.assertEqual(len(values), 1)
        self.assertEqual(values[0]["object_class_name"], "dog")
        self.assertEqual(values[0]["object_name"], "pluto")
        self.assertEqual(values[0]["parameter_name"], "breed")
        self.assertEqual(values[0]["value"], "bloodhound")

    def test_do_not_add_invalid_object_parameter_values(self):
        """Test that object parameter values aren't added to the db if data is incomplete."""
        header = self.object_table_header
        model = EmptyObjectParameterValueModel(None, header, self._db_mngr)
        model.fetchMore()
        self.assertTrue(
            model.batch_set_data(
                _empty_indexes(model),
                ["fish", "nemo", "water", "salty", "mock_db"]))
        values = next(self._db_mngr.get_object_parameter_values(self._db_map),
                      [])
        self.assertEqual(values, [])

    def test_infer_class_from_object_and_parameter(self):
        """Test that object classes are inferred from the object and parameter if possible."""
        header = self.object_table_header
        model = EmptyObjectParameterValueModel(None, header, self._db_mngr)
        model.fetchMore()
        indexes = _empty_indexes(model)
        self.assertTrue(
            model.batch_set_data(
                indexes,
                ["cat", "pluto", "breed", 1, "bloodhound", "mock_db"]))
        self.assertEqual(indexes[0].data(), "dog")
        values = next(self._db_mngr.get_object_parameter_values(self._db_map),
                      [])
        self.assertEqual(len(values), 1)
        self.assertEqual(values[0]["object_class_name"], "dog")
        self.assertEqual(values[0]["object_name"], "pluto")
        self.assertEqual(values[0]["parameter_name"], "breed")
        self.assertEqual(values[0]["value"], "bloodhound")

    def test_add_relationship_parameter_values_to_db(self):
        """Test that relationship parameter values are added to the db when editing the table."""
        header = self.relationship_table_header
        model = EmptyRelationshipParameterValueModel(None, header,
                                                     self._db_mngr)
        model.fetchMore()
        self.assertTrue(
            model.batch_set_data(_empty_indexes(model), [
                "dog__fish", "pluto,nemo", "relative_speed", 1, -1, "mock_db"
            ]))
        values = next(
            self._db_mngr.get_relationship_parameter_values(self._db_map), [])
        self.assertEqual(len(values), 1)
        self.assertEqual(values[0]["relationship_class_name"], "dog__fish")
        self.assertEqual(values[0]["object_name_list"], "pluto,nemo")
        self.assertEqual(values[0]["parameter_name"], "relative_speed")
        self.assertEqual(values[0]["value"], "-1")

    def test_do_not_add_invalid_relationship_parameter_values(self):
        """Test that relationship parameter values aren't added to the db if data is incomplete."""
        header = self.relationship_table_header
        model = EmptyRelationshipParameterValueModel(None, header,
                                                     self._db_mngr)
        model.fetchMore()
        self.assertTrue(
            model.batch_set_data(
                _empty_indexes(model),
                ["dog__fish", "pluto,nemo", "combined_mojo", 100, "mock_db"]))
        values = next(
            self._db_mngr.get_relationship_parameter_values(self._db_map), [])
        self.assertEqual(values, [])

    def test_add_object_parameter_definitions_to_db(self):
        """Test that object parameter definitions are added to the db when editing the table."""
        header = [
            "object_class_name", "parameter_name", "value_list_name",
            "parameter_tag_list", "database"
        ]
        model = EmptyObjectParameterDefinitionModel(None, header,
                                                    self._db_mngr)
        model.fetchMore()
        self.assertTrue(
            model.batch_set_data(_empty_indexes(model),
                                 ["dog", "color", None, None, "mock_db"]))
        definitions = next(
            self._db_mngr.get_object_parameter_definitions(self._db_map), [])
        self.assertEqual(len(definitions), 2)
        names = {d["parameter_name"] for d in definitions}
        self.assertEqual(names, {"breed", "color"})

    def test_do_not_add_invalid_object_parameter_definitions(self):
        """Test that object parameter definitions aren't added to the db if data is incomplete."""
        header = self.object_table_header
        model = EmptyObjectParameterDefinitionModel(None, header,
                                                    self._db_mngr)
        model.fetchMore()
        self.assertTrue(
            model.batch_set_data(_empty_indexes(model),
                                 ["cat", "color", None, None, "mock_db"]))
        definitions = next(
            self._db_mngr.get_object_parameter_definitions(self._db_map), [])
        self.assertEqual(len(definitions), 1)
        self.assertEqual(definitions[0]["parameter_name"], "breed")

    def test_add_relationship_parameter_definitions_to_db(self):
        """Test that relationship parameter definitions are added to the db when editing the table."""
        header = [
            "relationship_class_name", "parameter_name", "value_list_name",
            "parameter_tag_list", "database"
        ]
        model = EmptyRelationshipParameterDefinitionModel(
            None, header, self._db_mngr)
        model.fetchMore()
        self.assertTrue(
            model.batch_set_data(
                _empty_indexes(model),
                ["dog__fish", "combined_mojo", None, None, "mock_db"]))
        definitions = next(
            self._db_mngr.get_relationship_parameter_definitions(self._db_map),
            [])
        self.assertEqual(len(definitions), 2)
        names = {d["parameter_name"] for d in definitions}
        self.assertEqual(names, {"relative_speed", "combined_mojo"})

    def test_do_not_add_invalid_relationship_parameter_definitions(self):
        """Test that relationship parameter definitions aren't added to the db if data is incomplete."""
        header = self.relationship_table_header
        model = EmptyRelationshipParameterDefinitionModel(
            None, header, self._db_mngr)
        model.fetchMore()
        self.assertTrue(
            model.batch_set_data(
                _empty_indexes(model),
                ["fish__dog", "each_others_opinion", None, None, "mock_db"]))
        definitions = next(
            self._db_mngr.get_relationship_parameter_definitions(self._db_map),
            [])
        self.assertEqual(len(definitions), 1)
        self.assertEqual(definitions[0]["parameter_name"], "relative_speed")