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()
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)
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
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
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()
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", ]
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
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 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()
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()
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 }, )
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")
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)
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()
def setUp(self): self.db_mngr = SpineDBManager(None, None) self.db_mngr.get_item = Mock()
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")