Example #1
0
 def test_rename_item(self):
     project = self.toolbox.project()
     source_name = "source"
     destination_name = "destination"
     add_view(project, source_name)
     add_view(project, destination_name)
     source_item = project.get_item("source")
     project.add_connection(
         Connection(source_name, "left", destination_name, "right"))
     while project.is_busy():
         # Make sure we process all pending signals related to changes in DAG.
         # Otherwise me may rename the item while the old name is still in use.
         QApplication.processEvents()
     project.rename_item("source", "renamed source", "")
     self.assertTrue(bool(project.get_item("renamed source")))
     self.assertEqual(source_item.name, "renamed source")
     self.assertEqual(
         project.connections,
         [Connection("renamed source", "left", destination_name, "right")])
     dags = project.dag_handler.dags()
     self.assertEqual(len(dags), 1)
     self.assertEqual(project.dag_handler.node_successors(dags[0]), {
         "destination": [],
         "renamed source": ["destination"]
     })
     self.assertEqual(source_item.get_icon().name(), "renamed source")
     self.assertEqual(
         os.path.split(source_item.data_dir)[1], shorten("renamed source"))
 def test_remove_connection(self):
     """Tests issue #1310"""
     # Make two DC's connected to a tool and provide a resource from both to Tool.
     # Remove one connection, and test that the other one still provides the resource to Tool
     project = self.toolbox.project()
     add_dc(project, "dc1")
     add_dc(project, "dc2")
     add_tool(project, "t")
     dc1 = project.get_item("dc1")
     dc2 = project.get_item("dc2")
     t = project.get_item("t")
     a = Path(self._temp_dir.name, "a.txt")
     a.touch()
     b = Path(self._temp_dir.name, "b.txt")
     b.touch()
     dc1.add_data_files([a])
     dc2.add_data_files([b])
     project.add_connection(Connection("dc1", "right", "t", "left"))
     project.add_connection(Connection("dc2", "right", "t", "left"))
     self.assertEqual(t._input_file_model.rowCount(),
                      2)  # There should 2 files in Available resources
     connection = project.find_connection("dc2", "t")
     project.remove_connection(connection)
     self.assertEqual(t._input_file_model.rowCount(),
                      1)  # There should 1 resource left
Example #3
0
 def test_serialization_without_filters(self):
     connection = Connection("source", "bottom", "destination", "top")
     connection_dict = connection.to_dict()
     restored = Connection.from_dict(connection_dict)
     self.assertEqual(restored.source, "source")
     self.assertEqual(restored.source_position, "bottom")
     self.assertEqual(restored.destination, "destination")
     self.assertEqual(restored.destination_position, "top")
     self.assertFalse(restored.has_filters())
Example #4
0
 def test_serialization_with_filters(self):
     filters = {"label": {"scenario_filter": {13: True}}}
     connection = Connection("source", "bottom", "destination", "top", filters)
     connection_dict = connection.to_dict()
     restored = Connection.from_dict(connection_dict)
     self.assertEqual(restored.source, "source")
     self.assertEqual(restored.source_position, "bottom")
     self.assertEqual(restored.destination, "destination")
     self.assertEqual(restored.destination_position, "top")
     self.assertTrue(restored.has_filters())
     self.assertEqual(restored.resource_filters, filters)
 def redo(self):
     if self._replaced_connection_dict is None:
         success = self._project.add_connection(
             Connection.from_dict(self._connection_dict))
         if not success:
             self.setObsolete(True)
     else:
         self._project.replace_connection(
             Connection.from_dict(self._replaced_connection_dict),
             Connection.from_dict(self._connection_dict))
     action = "add" if self._replaced_connection_dict is None else "replace"
     self.setText(f"{action} {self._connection_name}")
 def test_replace_connection(self):
     project = self.toolbox.project()
     dc1_name = "DC 1"
     add_dc(project, dc1_name)
     dc2_name = "DC 2"
     add_dc(project, dc2_name)
     project.add_connection(Connection(dc1_name, "left", dc2_name, "right"))
     project.replace_connection(
         Connection(dc1_name, "left", dc2_name, "right"),
         Connection(dc1_name, "top", dc2_name, "bottom"))
     self.assertEqual(project.connections_for_item(dc1_name),
                      [Connection(dc1_name, "top", dc2_name, "bottom")])
     self.assertEqual(project.connections_for_item(dc2_name),
                      [Connection(dc1_name, "top", dc2_name, "bottom")])
     dag = project.dag_handler.dag_with_node(dc1_name)
     self.assertEqual(project.dag_handler.node_successors(dag), {
         dc1_name: [dc2_name],
         dc2_name: []
     })
Example #7
0
 def test_fetch_tools(self):
     connection = Connection("source", "bottom", "destination", "top")
     url = "sqlite:///" + os.path.join(self._temp_dir.name, "db.sqlite")
     db_map = DiffDatabaseMapping(url, create=True)
     import_tools(db_map, ("tool",))
     db_map.commit_session("Add test data.")
     db_map.connection.close()
     resources = [database_resource("source", url)]
     connection.receive_resources_from_source(resources)
     self.assertFalse(connection.has_filters())
     connection.fetch_database_items()
     self.assertTrue(connection.has_filters())
     self.assertEqual(connection.resource_filters, {resources[0].label: {"tool_filter": {1: False}}})
 def undo(self):
     if self._replaced_connection_dict is None:
         connection = self._project.find_connection(self._source_name,
                                                    self._destination_name)
         self._project.remove_connection(connection)
     else:
         connection = self._project.find_connection(self._source_name,
                                                    self._destination_name)
         self._project.replace_connection(
             connection,
             Connection.from_dict(self._replaced_connection_dict))
Example #9
0
 def test_execute_selected_item_within_single_dag(self):
     data_store, data_store_executable = self._make_item(self.add_ds)
     data_connection, data_connection_executable = self._make_item(
         self.add_dc)
     view, view_executable = self._make_item(self.add_view)
     self.toolbox.project().add_connection(
         Connection(data_store.name, "right", data_connection.name, "left"))
     self.toolbox.project().add_connection(
         Connection(data_connection.name, "bottom", view.name, "top"))
     self.toolbox.project().set_item_selected(data_connection)
     with mock.patch("spine_engine.spine_engine.SpineEngine._make_item"
                     ) as mock_make_item:
         mock_make_item.side_effect = lambda name, *args: {
             data_store.name: data_store_executable,
             data_connection.name: data_connection_executable,
             view.name: view_executable,
         }[name]
         self.toolbox.project().execute_selected()
         self._wait_for_execution_finished()
     self.assertFalse(data_store_executable.execute_called)
     self.assertTrue(data_connection_executable.execute_called)
     self.assertFalse(view_executable.execute_called)
Example #10
0
 def test_outgoing_and_incoming_links(self):
     source_icon = ProjectItemIcon(self._toolbox, "", QColor(Qt.gray),
                                   QColor(Qt.green))
     target_icon = ProjectItemIcon(self._toolbox, "", QColor(Qt.gray),
                                   QColor(Qt.green))
     connection = Connection("source item", "bottom", "destination item",
                             "bottom")
     link = Link(self._toolbox, source_icon.conn_button("bottom"),
                 target_icon.conn_button("bottom"), connection)
     link.src_connector.links.append(link)
     link.dst_connector.links.append(link)
     self.assertEqual(source_icon.outgoing_links(), [link])
     self.assertEqual(target_icon.incoming_links(), [link])
 def test_add_connection_updates_resources(self):
     project = self.toolbox.project()
     dc_name = "DC"
     add_dc(project, dc_name)
     tool_name = "Tool"
     add_tool(project, tool_name)
     dc = project.get_item(dc_name)
     data_file = Path(self._temp_dir.name, "a.txt")
     data_file.touch()
     dc.add_data_files([data_file])
     tool = project.get_item(tool_name)
     self.assertEqual(tool._input_file_model.rowCount(), 0)
     project.add_connection(Connection(dc_name, "left", tool_name, "right"))
     self.assertEqual(tool._input_file_model.rowCount(), 1)
 def test_add_connection_updates_dag_handler(self):
     project = self.toolbox.project()
     dc_name = "DC"
     add_dc(project, dc_name)
     importer_name = "Importer"
     add_importer(project, importer_name)
     project.add_connection(
         Connection(dc_name, "right", importer_name, "left"))
     self.assertEqual(len(project.connections), 1)
     dag = project.dag_handler.dag_with_node(dc_name)
     self.assertEqual(project.dag_handler.node_successors(dag), {
         dc_name: [importer_name],
         importer_name: []
     })
    def remove_links(self, links):
        """Pushes a RemoveConnectionsCommand to the Toolbox undo stack.

        Args:
            links (list of Link): links to remove
        """
        connections = list()
        for link in links:
            source = link.src_connector
            destination = link.dst_connector
            connections.append(
                Connection(source.parent_name(), source.position,
                           destination.parent_name(), destination.position))
        self._toolbox.undo_stack.push(
            RemoveConnectionsCommand(self._toolbox.project(), connections))
 def test_rename_item(self):
     project = self.toolbox.project()
     source_name = "source"
     destination_name = "destination"
     add_view(project, source_name)
     add_view(project, destination_name)
     source_item = project.get_item("source")
     project.add_connection(
         Connection(source_name, "left", destination_name, "right"))
     project.rename_item("source", "renamed source", "")
     self.assertTrue(bool(project.get_item("renamed source")))
     self.assertEqual(source_item.name, "renamed source")
     self.assertEqual(
         project.connections,
         [Connection("renamed source", "left", destination_name, "right")])
     dags = project.dag_handler.dags()
     self.assertEqual(len(dags), 1)
     self.assertEqual(project.dag_handler.node_successors(dags[0]), {
         "destination": [],
         "renamed source": ["destination"]
     })
     self.assertEqual(source_item.get_icon().name(), "renamed source")
     self.assertEqual(
         os.path.split(source_item.data_dir)[1], shorten("renamed source"))
Example #15
0
 def test_replace_resource_from_source(self):
     filters = {"database": {"scenario_filter": {13: False}}}
     connection = Connection("source", "bottom", "destination", "top", filters)
     original = database_resource("source", "sqlite:///db.sqlite", label="database")
     connection.receive_resources_from_source([original])
     self.assertEqual(connection.database_resources, {original})
     modified = database_resource("source", "sqlite:///db2.sqlite", label="new database")
     connection.replace_resource_from_source(original, modified)
     self.assertEqual(connection.database_resources, {modified})
     self.assertEqual(connection.resource_filters, {"new database": {"scenario_filter": {13: False}}})
 def test_modifying_connected_item_updates_resources(self):
     project = self.toolbox.project()
     dc_name = "DC"
     add_dc(project, dc_name)
     tool_name = "Tool"
     add_tool(project, tool_name)
     tool = project.get_item(tool_name)
     project.add_connection(Connection(dc_name, "left", tool_name, "right"))
     self.assertEqual(tool._input_file_model.rowCount(), 0)
     dc = project.get_item(dc_name)
     data_file = Path(self._temp_dir.name, "a.txt")
     data_file.touch()
     dc.add_data_files([data_file])
     while dc.data_model.rowCount() == 0:
         QApplication.processEvents(
         )  # DC's file system watcher updates DC here
     self.assertEqual(tool._input_file_model.rowCount(), 1)
 def test_remove_item_by_name_removes_incoming_connections(self):
     project = self.toolbox.project()
     view1_name = "View 1"
     add_view(project, view1_name)
     view2_name = "View 2"
     add_view(project, view2_name)
     project.add_connection(
         Connection(view1_name, "top", view2_name, "bottom"))
     view = self.toolbox.project_item_model.get_item(view1_name)
     self.assertEqual(view1_name, view.name)
     view = self.toolbox.project_item_model.get_item(view2_name)
     self.assertEqual(view2_name, view.name)
     self.assertEqual(len(project.connections), 1)
     project.remove_item_by_name(view2_name)
     self.assertEqual(self.toolbox.project_item_model.n_items(), 1)
     self.assertEqual(len(project.connections), 0)
     view = self.toolbox.project_item_model.get_item(view1_name)
     self.assertEqual(view1_name, view.name)
     self.assertTrue(project.dag_handler.node_is_isolated(view1_name))
Example #18
0
 def setUp(self):
     self._temp_dir = TemporaryDirectory()
     with patch("spinetoolbox.ui_main.SpineDBManager.thread",
                new_callable=PropertyMock) as mock_thread:
         mock_thread.return_value = QApplication.instance().thread()
         self._toolbox = create_toolboxui_with_project(self._temp_dir.name)
     type(self._toolbox.db_mngr).thread = PropertyMock(
         return_value=QApplication.instance().thread())
     source_item_icon = ProjectItemIcon(self._toolbox, "", QColor(Qt.gray),
                                        QColor(Qt.green))
     source_item_icon.update_name_item("source icon")
     destination_item_icon = ProjectItemIcon(self._toolbox, "",
                                             QColor(Qt.gray),
                                             QColor(Qt.green))
     destination_item_icon.update_name_item("destination icon")
     connection = Connection("source icon", "right", "destination icon",
                             "left")
     self._link = Link(self._toolbox, source_item_icon.conn_button(),
                       destination_item_icon.conn_button(), connection)
Example #19
0
    def make_link(self, src_connector, dst_connector, connection=None):
        """Constructs a Link between given connectors.

        Args:
            src_connector (ConnectorButton): Source connector button
            dst_connector (ConnectorButton): Destination connector button
            connection (Connection, optional): Underlying connection

        Returns:
            Link: new link
        """
        if connection is None:
            connection = Connection(
                src_connector.project_item().name,
                src_connector.position,
                dst_connector.project_item().name,
                dst_connector.position,
            )
        return Link(self._toolbox, src_connector, dst_connector, connection)
    def __init__(self, project, source_name, source_position, destination_name,
                 destination_position):
        """Command to add connection between project items.

        Args:
            project (SpineToolboxProject): project
            source_name (str): source item's name
            source_position (str): link's position on source item's icon
            destination_name (str): destination item's name
            destination_position (str): link's position on destination item's icon
        """
        super().__init__()
        self._project = project
        self._source_name = source_name
        self._destination_name = destination_name
        self._connection_dict = Connection(source_name, source_position,
                                           destination_name,
                                           destination_position).to_dict()
        replaced_connection = self._project.find_connection(
            source_name, destination_name)
        self._replaced_connection_dict = replaced_connection.to_dict(
        ) if replaced_connection is not None else None
        self._connection_name = f"link from {source_name} to {destination_name}"
 def test_connections_for_item(self):
     project = self.toolbox.project()
     dc1_name = "My first DC"
     add_dc(project, dc1_name)
     dc2_name = "My second DC"
     add_dc(project, dc2_name)
     dc3_name = "My third and last DC"
     add_dc(project, dc3_name)
     project.add_connection(Connection(dc1_name, "bottom", dc2_name, "top"))
     project.add_connection(Connection(dc2_name, "top", dc3_name, "bottom"))
     self.assertEqual(project.connections_for_item(dc1_name),
                      [Connection(dc1_name, "bottom", dc2_name, "top")])
     self.assertEqual(
         project.connections_for_item(dc2_name),
         [
             Connection(dc1_name, "bottom", dc2_name, "top"),
             Connection(dc2_name, "top", dc3_name, "bottom")
         ],
     )
     self.assertEqual(project.connections_for_item(dc3_name),
                      [Connection(dc2_name, "top", dc3_name, "bottom")])
 def undo(self):
     for connection_dict in self._connections_dict.values():
         self._project.add_connection(Connection.from_dict(connection_dict))
Example #23
0
 def test_set_online(self):
     filters = {"label": {"scenario_filter": {13: False}}}
     connection = Connection("source", "bottom", "destination", "top", filters)
     connection.set_online("label", "scenario_filter", {13: True})
     self.assertEqual(connection.resource_filters, {"label": {"scenario_filter": {13: True}}})
 def undo(self):
     self._project.make_and_add_project_items(self._items_dict,
                                              verbosity=False)
     for connection_dict in self._connection_dicts:
         self._project.add_connection(Connection.from_dict(connection_dict))