diff --git a/main.py b/main.py index 0c9011b315ab742a328a4ac8ee5de1d8242cb0d5..cccf74b80f96e025ee9f2e3c7842d905f6d15940 100644 --- a/main.py +++ b/main.py @@ -34,29 +34,29 @@ def test_graph(): graph = StateMachineGraph() # Create some nodes. - node_1 = graph.create_node('A') - node_2 = graph.create_node('B') - node_3 = graph.create_node('C') - node_4 = graph.create_node('D') + node_1 = graph.nodes.create('A') + node_2 = graph.nodes.create('B') + node_3 = graph.nodes.create('C') + node_4 = graph.nodes.create('D') - node_5 = graph.create_node('AA') - node_6 = graph.create_node('BB') - node_7 = graph.create_node('CC') - node_8 = graph.create_node('DD') + node_5 = graph.nodes.create('AA') + node_6 = graph.nodes.create('BB') + node_7 = graph.nodes.create('CC') + node_8 = graph.nodes.create('DD') # Connect nodes. - graph.connect_nodes(node_1, node_1, 'A') - graph.connect_nodes(node_1, node_2, 'a') - graph.connect_nodes(node_2, node_3, 'b') - graph.connect_nodes(node_4, node_3, 'c') - graph.connect_nodes(node_4, node_2, ['a', 'b']) - graph.connect_nodes(node_4, node_1, 'd') - - graph.connect_nodes(node_5, node_6, 'a') - graph.connect_nodes(node_6, node_7, 'b') - graph.connect_nodes(node_8, node_7, 'c') - graph.connect_nodes(node_8, node_6, ['a', 'b']) - graph.connect_nodes(node_8, node_5, 'd') + graph.nodes.connect(node_1, node_1, 'A') + graph.nodes.connect(node_1, node_2, 'a') + graph.nodes.connect(node_2, node_3, 'b') + graph.nodes.connect(node_4, node_3, 'c') + graph.nodes.connect(node_4, node_2, ['a', 'b']) + graph.nodes.connect(node_4, node_1, 'd') + + graph.nodes.connect(node_5, node_6, 'a') + graph.nodes.connect(node_6, node_7, 'b') + graph.nodes.connect(node_8, node_7, 'c') + graph.nodes.connect(node_8, node_6, ['a', 'b']) + graph.nodes.connect(node_8, node_5, 'd') # Add initial/final states. node_1.toggle_node_state_initial() @@ -69,7 +69,7 @@ def test_graph(): # Display graph mapping. graph_title = 'Custom Graph Library - Graph Visual Mapping<br>Test Graph' - graph.draw_graph_map(graph_title) + graph.display.draw_graph_map(graph_title) logger.info('Finished displaying "Test Graph".') logger.info('') @@ -84,59 +84,59 @@ def basic_print_example(): # Create some nodes. logger.info('Creating 3 unconnected nodes.') - node_1 = graph.create_node() - node_2 = graph.create_node() - node_3 = graph.create_node() + node_1 = graph.nodes.create() + node_2 = graph.nodes.create() + node_3 = graph.nodes.create() # Connect nodes. logger.info('Connecting first node to all others.') - graph.connect_nodes(node_1, node_2) - graph.connect_nodes(node_1, node_3) + graph.nodes.connect(node_1, node_2) + graph.nodes.connect(node_1, node_3) logger.info('') # Print individual node info. logger.info('Printing first node\'s connection info...') - graph.print_node_edge_connections(node_1) - graph.print_node_connected_nodes(node_1) + graph.display.print_node_edge_connections(node_1) + graph.display.print_node_connected_nodes(node_1) logger.info('Printing info for other two nodes...') - graph.print_node_connected_nodes(node_2) - graph.print_node_connected_nodes(node_3) + graph.display.print_node_connected_nodes(node_2) + graph.display.print_node_connected_nodes(node_3) logger.info('') # Create more nodes. logger.info('Creating 3 more nodes.') - node_4 = graph.create_node() - node_5 = graph.create_node() - node_6 = graph.create_node() + node_4 = graph.nodes.create() + node_5 = graph.nodes.create() + node_6 = graph.nodes.create() # Fully connect first three nodes to entire graph. logger.info('Connecting first three nodes to all other nodes.') - graph.connect_nodes(node_1, node_4) - graph.connect_nodes(node_1, node_5) - graph.connect_nodes(node_1, node_6) - graph.connect_nodes(node_2, node_3) - graph.connect_nodes(node_2, node_4) - graph.connect_nodes(node_2, node_5) - graph.connect_nodes(node_2, node_6) - graph.connect_nodes(node_3, node_4) - graph.connect_nodes(node_3, node_5) - graph.connect_nodes(node_3, node_6) + graph.nodes.connect(node_1, node_4) + graph.nodes.connect(node_1, node_5) + graph.nodes.connect(node_1, node_6) + graph.nodes.connect(node_2, node_3) + graph.nodes.connect(node_2, node_4) + graph.nodes.connect(node_2, node_5) + graph.nodes.connect(node_2, node_6) + graph.nodes.connect(node_3, node_4) + graph.nodes.connect(node_3, node_5) + graph.nodes.connect(node_3, node_6) # Print full graph info. logger.info('Printing all edge connections and node connections in graph...') - graph.print_all_node_edge_connections() - graph.print_all_node_connected_nodes() + graph.display.print_all_node_edge_connections() + graph.display.print_all_node_connected_nodes() logger.info('') # Remove node 3. logger.info('Removing node 3.') - graph.remove_node(node_3) + graph.nodes.remove(node_3) # Print full graph info. logger.info('Printing updated graph info...') - graph.print_all_node_edge_connections() - graph.print_all_node_connected_nodes() + graph.display.print_all_node_edge_connections() + graph.display.print_all_node_connected_nodes() #region Graph Drawing Examples @@ -165,31 +165,31 @@ def draw_10_chained_nodes(): graph = BasicGraph() # Create some nodes. - node_1 = graph.create_node('A') - node_2 = graph.create_node('B') - node_3 = graph.create_node('C') - node_4 = graph.create_node('D') - node_5 = graph.create_node('E') - node_6 = graph.create_node('F') - node_7 = graph.create_node('G') - node_8 = graph.create_node('H') - node_9 = graph.create_node('I') - node_10 = graph.create_node('J') + node_1 = graph.nodes.create('A') + node_2 = graph.nodes.create('B') + node_3 = graph.nodes.create('C') + node_4 = graph.nodes.create('D') + node_5 = graph.nodes.create('E') + node_6 = graph.nodes.create('F') + node_7 = graph.nodes.create('G') + node_8 = graph.nodes.create('H') + node_9 = graph.nodes.create('I') + node_10 = graph.nodes.create('J') # Connect nodes. - graph.connect_nodes(node_1, node_2) - graph.connect_nodes(node_2, node_3) - graph.connect_nodes(node_3, node_4) - graph.connect_nodes(node_4, node_5) - graph.connect_nodes(node_5, node_6) - graph.connect_nodes(node_6, node_7) - graph.connect_nodes(node_7, node_8) - graph.connect_nodes(node_8, node_9) - graph.connect_nodes(node_9, node_10) + graph.nodes.connect(node_1, node_2) + graph.nodes.connect(node_2, node_3) + graph.nodes.connect(node_3, node_4) + graph.nodes.connect(node_4, node_5) + graph.nodes.connect(node_5, node_6) + graph.nodes.connect(node_6, node_7) + graph.nodes.connect(node_7, node_8) + graph.nodes.connect(node_8, node_9) + graph.nodes.connect(node_9, node_10) # Display graph mapping. graph_title = 'Custom Graph Library - Graph Visual Mapping<br>10 Nodes Connected in a Chain' - graph.draw_graph_map(graph_title) + graph.display.draw_graph_map(graph_title) logger.info('Finished displaying "10 nodes connected in a chain".') logger.info('') @@ -209,7 +209,7 @@ def draw_random_nodes_small(): # Randomly creates between 2 and 10 nodes. node_count = randint(2, 10) for index in range(node_count): - graph.create_node() + graph.nodes.create() # Loop through and randomly connect nodes. # Note, this logic only works when nodes are named as integers in sequential number. @@ -222,15 +222,15 @@ def draw_random_nodes_small(): node_2_name = randint(1, node_count) # Got names. Now connect nodes. - graph.connect_nodes(graph.get_node(node_1_name), graph.get_node(node_2_name)) + graph.nodes.connect(graph.nodes.get(node_1_name), graph.nodes.get(node_2_name)) # Print graph info to console for comparison. - graph.print_all_node_edge_connections() - graph.print_all_node_connected_nodes() + graph.display.print_all_node_edge_connections() + graph.display.print_all_node_connected_nodes() # Display graph mapping. graph_title = 'Custom Graph Library - Graph Visual Mapping<br>Up to 10 Randomly Generated Nodes' - graph.draw_graph_map(graph_title) + graph.display.draw_graph_map(graph_title) logger.info('Finished displaying "between 2 and 10 randomized nodes".') logger.info('') @@ -249,7 +249,7 @@ def draw_random_nodes_med(): # Randomly creates between 10 and 50 nodes. node_count = randint(10, 50) for index in range(node_count): - graph.create_node() + graph.nodes.create() # Loop through and randomly connect nodes. May potentially have up to each node connecting to each other node. # Note, this logic only works when nodes are named as integers in sequential number. @@ -265,15 +265,15 @@ def draw_random_nodes_med(): node_2_name = randint(1, node_count) # Got names. Now connect nodes. - graph.connect_nodes(graph.get_node(node_1_name), graph.get_node(node_2_name)) + graph.nodes.connect(graph.nodes.get(node_1_name), graph.nodes.get(node_2_name)) # Print graph info to console for comparison. - graph.print_all_node_edge_connections() - graph.print_all_node_connected_nodes() + graph.display.print_all_node_edge_connections() + graph.display.print_all_node_connected_nodes() # Display graph mapping. graph_title = 'Custom Graph Library - Graph Visual Mapping<br>Between 10 and 50 Randomly Generated Nodes' - graph.draw_graph_map(graph_title) + graph.display.draw_graph_map(graph_title) logger.info('Finished displaying "between 10 and 50 randomized nodes".') logger.info('') @@ -292,7 +292,7 @@ def draw_random_nodes_large(): # Randomly creates between 50 and 100 nodes. node_count = randint(50, 100) for index in range(node_count): - graph.create_node() + graph.nodes.create() # Loop through and randomly connect nodes. May potentially have up to each node connecting to each other node. # Note, this logic only works when nodes are named as integers in sequential number. @@ -308,16 +308,16 @@ def draw_random_nodes_large(): node_2_name = randint(1, node_count) # Got names. Now connect nodes. - graph.connect_nodes(graph.get_node(node_1_name), graph.get_node(node_2_name)) + graph.nodes.connect(graph.nodes.get(node_1_name), graph.nodes.get(node_2_name)) # Print graph info to console for comparison. - graph.print_all_node_edge_connections() - graph.print_all_node_connected_nodes() + graph.display.print_all_node_edge_connections() + graph.display.print_all_node_connected_nodes() # Display graph mapping. graph_title = 'Custom Graph Library - Graph Visual Mapping<br>Between 50 and 100 Randomly Generated Nodes<br>' \ '(Minimal Connections to Reduce Generation Time and Improve Graph Visual Clarity)' - graph.draw_graph_map(graph_title) + graph.display.draw_graph_map(graph_title) logger.info('Finished displaying "between 50 and 100 randomized nodes".') logger.info('') @@ -334,21 +334,21 @@ def draw_directed_graph(): graph = DirectedGraph() # Create some nodes. - node_1 = graph.create_node('A') - node_2 = graph.create_node('B') - node_3 = graph.create_node('C') - node_4 = graph.create_node('D') + node_1 = graph.nodes.create('A') + node_2 = graph.nodes.create('B') + node_3 = graph.nodes.create('C') + node_4 = graph.nodes.create('D') # Connect nodes. - graph.connect_nodes(node_1, node_2) - graph.connect_nodes(node_2, node_3) - graph.connect_nodes(node_4, node_3) - graph.connect_nodes(node_4, node_2) - graph.connect_nodes(node_4, node_1) + graph.nodes.connect(node_1, node_2) + graph.nodes.connect(node_2, node_3) + graph.nodes.connect(node_4, node_3) + graph.nodes.connect(node_4, node_2) + graph.nodes.connect(node_4, node_1) # Display graph mapping. graph_title = 'Custom Graph Library - Graph Visual Mapping<br>Directed Graph' - graph.draw_graph_map(graph_title) + graph.display.draw_graph_map(graph_title) logger.info('Finished displaying "Directed Graph".') logger.info('') @@ -365,29 +365,29 @@ def draw_state_machine(): graph = StateMachineGraph() # Create some nodes. - node_1 = graph.create_node('A') - node_2 = graph.create_node('B') - node_3 = graph.create_node('C') - node_4 = graph.create_node('D') + node_1 = graph.nodes.create('A') + node_2 = graph.nodes.create('B') + node_3 = graph.nodes.create('C') + node_4 = graph.nodes.create('D') - node_5 = graph.create_node('AA') - node_6 = graph.create_node('BB') - node_7 = graph.create_node('CC') - node_8 = graph.create_node('DD') + node_5 = graph.nodes.create('AA') + node_6 = graph.nodes.create('BB') + node_7 = graph.nodes.create('CC') + node_8 = graph.nodes.create('DD') # Connect nodes. - graph.connect_nodes(node_1, node_1, 'A') - graph.connect_nodes(node_1, node_2, 'a') - graph.connect_nodes(node_2, node_3, 'b') - graph.connect_nodes(node_4, node_3, 'c') - graph.connect_nodes(node_4, node_2, ['a', 'b']) - graph.connect_nodes(node_4, node_1, 'd') - - graph.connect_nodes(node_5, node_6, 'a') - graph.connect_nodes(node_6, node_7, 'b') - graph.connect_nodes(node_8, node_7, 'c') - graph.connect_nodes(node_8, node_6, ['a', 'b']) - graph.connect_nodes(node_8, node_5, 'd') + graph.nodes.connect(node_1, node_1, 'A') + graph.nodes.connect(node_1, node_2, 'a') + graph.nodes.connect(node_2, node_3, 'b') + graph.nodes.connect(node_4, node_3, 'c') + graph.nodes.connect(node_4, node_2, ['a', 'b']) + graph.nodes.connect(node_4, node_1, 'd') + + graph.nodes.connect(node_5, node_6, 'a') + graph.nodes.connect(node_6, node_7, 'b') + graph.nodes.connect(node_8, node_7, 'c') + graph.nodes.connect(node_8, node_6, ['a', 'b']) + graph.nodes.connect(node_8, node_5, 'd') # Add initial/final states. node_1.toggle_node_state_initial() @@ -396,7 +396,7 @@ def draw_state_machine(): # Display graph mapping. graph_title = 'Custom Graph Library - Graph Visual Mapping<br>State Machine Graph' - graph.draw_graph_map(graph_title) + graph.display.draw_graph_map(graph_title) logger.info('Finished displaying "State Machine Graph".') logger.info('') @@ -564,58 +564,58 @@ def basic_graph_class_example(): logger.info('') logger.info('Creating 3 nodes in graph. Only first one will have a unique name, which will be "Test Node".') - node_1 = graph.create_node('Test Node') - node_2 = graph.create_node() - node_3 = graph.create_node() + node_1 = graph.nodes.create('Test Node') + node_2 = graph.nodes.create() + node_3 = graph.nodes.create() logger.info('') logger.info('Connecting first node to both other nodes.') - logger.info('graph.connect_nodes(node_1, node_2): {0}'.format(graph.connect_nodes(node_1, node_2))) - logger.info('graph.connect_nodes(node_1, node_3): {0}'.format(graph.connect_nodes(node_1, node_3))) + logger.info('graph.nodes.connect(node_1, node_2): {0}'.format(graph.nodes.connect(node_1, node_2))) + logger.info('graph.nodes.connect(node_1, node_3): {0}'.format(graph.nodes.connect(node_1, node_3))) logger.info('') logger.info('Displaying graph "node info".') - logger.info('graph.get_node_count(): {0}'.format(graph.get_node_count())) - logger.info('graph.get_all_nodes(): {0}'.format(graph.get_all_nodes())) - logger.info('graph.check_if_node_in_graph(node_1): {0}'.format(graph.check_if_node_in_graph(node_1))) - logger.info('graph.get_node(node_1): {0}'.format(graph.get_node(node_1))) - logger.info('graph.get_node_degree(node_1): {0}'.format(graph.get_node_degree(node_1))) - logger.info('graph.get_edges_connected_to_node(node_1): {0}'.format(graph.get_edges_connected_to_node(node_1))) - logger.info('graph.get_connected_nodes(node_1): {0}'.format(graph.get_connected_nodes(node_1))) - logger.info('graph.determine_node_adjacency(node_1, node_2): {0}'.format(graph.determine_node_adjacency(node_1, node_2))) + logger.info('graph.nodes.count(): {0}'.format(graph.nodes.count())) + logger.info('graph.nodes.all(): {0}'.format(graph.nodes.all())) + logger.info('graph.nodes.check_if_in_graph(node_1): {0}'.format(graph.nodes.check_if_in_graph(node_1))) + logger.info('graph.nodes.get(node_1): {0}'.format(graph.nodes.get(node_1))) + logger.info('graph.nodes.degree(node_1): {0}'.format(graph.nodes.degree(node_1))) + logger.info('graph.nodes.edge_connections_to_node(node_1): {0}'.format(graph.nodes.edge_connections_to_node(node_1))) + logger.info('graph.nodes.node_connections_to_node(node_1): {0}'.format(graph.nodes.node_connections_to_node(node_1))) + logger.info('graph.nodes.determine_adjacency(node_1, node_2): {0}'.format(graph.nodes.determine_adjacency(node_1, node_2))) logger.info('') logger.info('Displaying graph "edge info".') - logger.info('graph.get_edge_count(): {0}'.format(graph.get_edge_count())) - logger.info('graph.get_all_edges(): {0}'.format(graph.get_all_edges())) - logger.info('graph.check_if_edge_in_graph(1): {0}'.format(graph.check_if_edge_in_graph(graph.get_edge(1)))) - logger.info('graph.get_edge(1): {0}'.format(graph.get_edge(1))) - logger.info('graph.get_nodes_connected_to_edge(1): {0}'.format(graph.get_nodes_connected_to_edge(1))) + logger.info('graph.edges.count(): {0}'.format(graph.edges.count())) + logger.info('graph.edges.all(): {0}'.format(graph.edges.all())) + logger.info('graph.edges.check_if_in_graph(1): {0}'.format(graph.edges.check_if_in_graph(graph.edges.get(1)))) + logger.info('graph.edges.get(1): {0}'.format(graph.edges.get(1))) + logger.info('graph.edges.node_connections_to_edge(1): {0}'.format(graph.edges.node_connections_to_edge(1))) logger.info('') logger.info('Adding more edges.') - logger.info('graph.add_node(BasicNode(\'A\'); {0}'.format(graph.add_node(BasicNode('A')))) - logger.info('graph.add_node_list([BasicNode(\'B\'), BasicNode(\'C\')]): {0}'.format( - graph.add_node_list([BasicNode('B'), BasicNode('C')]) + logger.info('graph.nodes.add(BasicNode(\'A\'); {0}'.format(graph.nodes.add(BasicNode('A')))) + logger.info('graph.nodes.add_list([BasicNode(\'B\'), BasicNode(\'C\')]): {0}'.format( + graph.nodes.add_list([BasicNode('B'), BasicNode('C')]) )) - logger.info('graph.get_all_nodes(): {0}'.format(graph.get_all_nodes())) + logger.info('graph.nodes.all(): {0}'.format(graph.nodes.all())) logger.info('') logger.info('Disconnecting an edge.') - logger.info('graph.disconnect_nodes(node_1, node_2): {0}'.format(graph.disconnect_nodes(node_1_identifier=node_1, node_2_identifier=node_2))) - logger.info('graph.get_all_edges(): {0}'.format(graph.get_all_edges())) + logger.info('graph.nodes.disconnect(node_1, node_2): {0}'.format(graph.nodes.disconnect(node_1_identifier=node_1, node_2_identifier=node_2))) + logger.info('graph.edges.all(): {0}'.format(graph.edges.all())) logger.info('') logger.info('Removing a node.') - logger.info('graph.remove_node(node_1): {0}'.format(graph.remove_node(node_1))) - logger.info('graph.get_all_nodes(): {0}'.format(graph.get_all_nodes())) - logger.info('graph.get_all_edges(): {0}'.format(graph.get_all_edges())) + logger.info('graph.nodes.remove(node_1): {0}'.format(graph.nodes.remove(node_1))) + logger.info('graph.nodes.all(): {0}'.format(graph.nodes.all())) + logger.info('graph.edges.all(): {0}'.format(graph.edges.all())) logger.info('') diff --git a/resources/graphs/basic_graph/graph.py b/resources/graphs/basic_graph/graph.py index f0a94a16f72e13114e5a33c401dff10e7f2d8f90..d0d289146b8d493ce55ca5accfb5ff0c47d6da62 100644 --- a/resources/graphs/basic_graph/graph.py +++ b/resources/graphs/basic_graph/graph.py @@ -52,6 +52,11 @@ class BasicGraph(): self._graph_type = BasicGraph self._node_type = BasicNode + # Get associated child classes. + self.display = BasicGraphDisplay(self) + self.edges = BasicGraphEdges(self) + self.nodes = BasicGraphNodes(self) + #region Private Information Functions def _get_node_auto_name(self): @@ -102,9 +107,16 @@ class BasicGraph(): #endregion Private Information Functions - #region Display Functions - #region Console Display Functions +class BasicGraphDisplay(): + def __init__(self, parent, *args, **kwargs): + if not isinstance(parent, BasicGraph): + raise TypeError('Expected parent of type BasicGraph.') + + # Get calling parent. + self._parent = parent + + # region Console Display Functions def print_node_edge_connections(self, node_identifier): """ @@ -112,7 +124,7 @@ class BasicGraph(): :param node_identifier: Node or name of node to print connections of. """ # Get node. - node = self.get_node(node_identifier) + node = self._parent.nodes.get(node_identifier) # Check that we got a return value. if node is not None: @@ -124,7 +136,7 @@ class BasicGraph(): :param node_identifier: Node or name of node to print connections of. """ # Get node. - node = self.get_node(node_identifier) + node = self._parent.nodes.get(node_identifier) # Check that we got a return value. if node is not None: @@ -135,7 +147,7 @@ class BasicGraph(): Prints out all connected edges for each node. """ # Loop through all existing nodes and print edge connection info for each one. - for graph_node in self.get_all_nodes().values(): + for graph_node in self._parent.nodes.all().values(): graph_node.print_edge_connections() def print_all_node_connected_nodes(self): @@ -143,12 +155,12 @@ class BasicGraph(): Prints out all connected nodes for each node. """ # Loop through all existing nodes and print connected node info for each one. - for graph_node in self.get_all_nodes().values(): + for graph_node in self._parent.nodes.all().values(): graph_node.print_connected_nodes() - #endregion Console Display Functions + # endregion Console Display Functions - #region Graph Visual Mapping Functions + # region Graph Visual Mapping Functions def draw_graph_map(self, title=None): """ @@ -221,12 +233,12 @@ class BasicGraph(): # Now go through all nodes, assigning one to a random position. # As long as there are less than 1000 nodes, this should work without issues. - for node in self.get_all_nodes().values(): + for node in self._parent.nodes.all().values(): # Get a random position. index = randint(0, len(possible_positions) - 1) position = possible_positions.pop(index) - self._nodes[node.get_name()].x_coord = position[0] - self._nodes[node.get_name()].y_coord = position[1] + self._parent._nodes[node.get_name()].x_coord = position[0] + self._parent._nodes[node.get_name()].y_coord = position[1] # Record extreme positions. if position[0] > farthest_x[0]: @@ -249,7 +261,7 @@ class BasicGraph(): farthest_y[1].y_coord = 90 # Now go through all edges and do similar. - for edge in self.get_all_edges().values(): + for edge in self._parent.edges.all().values(): node_list = edge.get_nodes() # Handle if list (basic graph). @@ -262,10 +274,10 @@ class BasicGraph(): node_2 = node_list['head_node'] # Assign edge coordinates. - self._edges[edge.get_name()].x1_coord = node_1.x_coord - self._edges[edge.get_name()].x2_coord = node_2.x_coord - self._edges[edge.get_name()].y1_coord = node_1.y_coord - self._edges[edge.get_name()].y2_coord = node_2.y_coord + self._parent._edges[edge.get_name()].x1_coord = node_1.x_coord + self._parent._edges[edge.get_name()].x2_coord = node_2.x_coord + self._parent._edges[edge.get_name()].y1_coord = node_1.y_coord + self._parent._edges[edge.get_name()].y2_coord = node_2.y_coord def _create_node_mapping(self): """ @@ -282,7 +294,7 @@ class BasicGraph(): node_hover_text = self._create_node_hover_text() # Loop through all nodes. - for node in self.get_all_nodes().values(): + for node in self._parent.nodes.all().values(): node_x.append(node.x_coord) node_y.append(node.y_coord) @@ -328,7 +340,7 @@ class BasicGraph(): # Adjust color values, based on number of node connections. # Probably can define this above somehow. node_adjacencies = [] - for node in self.get_all_nodes().values(): + for node in self._parent.nodes.all().values(): edge_count = node.get_edge_count() node_adjacencies.append(edge_count) @@ -346,7 +358,7 @@ class BasicGraph(): node_text = [] # Loop through all nodes and get name values as text. - for node in self.get_all_nodes().values(): + for node in self._parent.nodes.all().values(): node_text.append(node.get_name()) return node_text @@ -359,8 +371,9 @@ class BasicGraph(): node_hover_text = [] # Loop through all nodes and create hover text. - for node in self.get_all_nodes().values(): - node_hover_text.append('Node: {0}<br>Connection Count: {1}'.format(node.get_name(), node.get_edge_count())) + for node in self._parent.nodes.all().values(): + node_hover_text.append( + 'Node: {0}<br>Connection Count: {1}'.format(node.get_name(), node.get_edge_count())) return node_hover_text @@ -384,7 +397,7 @@ class BasicGraph(): edge_mappings = [] # Loop through all edges. - for edge in self.get_all_edges().values(): + for edge in self._parent.edges.all().values(): # Check if node is linking to itself. if edge.x1_coord == edge.x2_coord and edge.y1_coord == edge.y2_coord: @@ -439,9 +452,9 @@ class BasicGraph(): # Set "mode" value based on display text. if edge_text is None or len(edge_text) == 0: - mode='lines' + mode = 'lines' else: - mode='lines+text' + mode = 'lines+text' # Set "hoverinfo" value based on hover text. if edge_hover_text is None or len(edge_hover_text) == 0: @@ -468,9 +481,9 @@ class BasicGraph(): 'color': 'white', }, line={ - 'width': 0.5, - 'color': '#888' - }, + 'width': 0.5, + 'color': '#888' + }, )) additional_edge_mappings = self._create_additional_edge_mappings() @@ -504,27 +517,34 @@ class BasicGraph(): # We don't need any for a basic graph so return an empty list. return [] - #endregion Graph Visual Mapping Functions + # endregion Graph Visual Mapping Functions + + +class BasicGraphNodes(): + def __init__(self, parent, *args, **kwargs): + if not isinstance(parent, BasicGraph): + raise TypeError('Expected parent of type BasicGraph.') - #endregion Display Functions + # Get calling parent. + self._parent = parent #region Node Information Functions - def get_node_count(self): + def count(self): """ Counts all nodes within graph. :return: Count of nodes in graph. """ - return len(self._nodes) + return len(self._parent._nodes) - def get_all_nodes(self): + def all(self): """ Returns list of all nodes in graph. :return: List of nodes in graph. """ - return self._nodes + return self._parent._nodes - def check_if_node_in_graph(self, node_identifier): + def check_if_in_graph(self, node_identifier): """ Returns bool indicating if Node exists in graph. :param node_identifier: Node or name of node to check for. @@ -533,7 +553,7 @@ class BasicGraph(): # Check for passed arg types. if node_identifier is None: raise AttributeError('Node identifier arg cannot be empty.') - elif isinstance(node_identifier, self._node_type): + elif isinstance(node_identifier, self._parent._node_type): # Arg was of Node object instance. Not sure why anyone would want this but we'll handle for it anyways. node_name = node_identifier.get_name() else: @@ -542,7 +562,7 @@ class BasicGraph(): # Search for node. try: - test = self._nodes[node_name] + self._parent._nodes[node_name] # If we got this far, then node exists in graph. return True @@ -550,7 +570,7 @@ class BasicGraph(): # Failed to find node in graph. return False - def get_node(self, node_identifier): + def get(self, node_identifier): """ Returns associated node, if present in graph. :param node_identifier: Node or name of node to return. @@ -559,7 +579,7 @@ class BasicGraph(): # Check for passed arg types. if node_identifier is None: raise AttributeError('Node identifier arg cannot be empty.') - elif isinstance(node_identifier, self._node_type): + elif isinstance(node_identifier, self._parent._node_type): # Arg was of Node object instance. Not sure why anyone would want this but we'll handle for it anyways. node_name = node_identifier.get_name() else: @@ -568,19 +588,19 @@ class BasicGraph(): # Attempt to return node. try: - return self._nodes[node_name] + return self._parent._nodes[node_name] except KeyError: logger.warning('Could not find node "{0}" in graph.'.format(node_name)) return None - def get_node_degree(self, node_identifier): + def degree(self, node_identifier): """ Gets node degree, aka number of connected edges for node. :param node_identifier: Node or name of node to get degree of. :return: Number of connected edges for node | None if node not found. """ # Attempt to get node. - node_to_check = self.get_node(node_identifier) + node_to_check = self.get(node_identifier) # Check if we got a match. if node_to_check is not None: @@ -589,14 +609,14 @@ class BasicGraph(): # Node not found in tree. return None - def get_edges_connected_to_node(self, node_identifier): + def edge_connections_to_node(self, node_identifier): """ Gets list of edges connected to node. :param node_identifier: Node or name of node to get connected edges of. :return: List of edges connected to node | None if node not found. """ # Attempt to get node. - node_to_check = self.get_node(node_identifier) + node_to_check = self.get(node_identifier) # Check if we got a match. if node_to_check is not None: @@ -605,14 +625,14 @@ class BasicGraph(): # Node not found in tree. return None - def get_connected_nodes(self, node_identifier): + def node_connections_to_node(self, node_identifier): """ Get list of nodes connected to node. :param node_identifier: Node or name of node to get connected nodes of. :return: List of edges connected to node | None if node not found. """ # Attempt to get node. - node_to_check = self.get_node(node_identifier) + node_to_check = self.get(node_identifier) # Check if we got a match. if node_to_check is not None: @@ -621,7 +641,7 @@ class BasicGraph(): # Node not found in tree. return None - def determine_node_adjacency(self, node_1_identifier, node_2_identifier): + def determine_adjacency(self, node_1_identifier, node_2_identifier): """ Determines if two nodes are adjacent (aka directly connected). :param node_1_identifier: Node or name of node to check connection of. @@ -629,8 +649,8 @@ class BasicGraph(): :return: Bool indicating if nodes are directly connected. """ # First make sure both nodes exist in graph. - node_1 = self.get_node(node_1_identifier) - node_2 = self.get_node(node_2_identifier) + node_1 = self.get(node_1_identifier) + node_2 = self.get(node_2_identifier) # Check that we got both nodes. if node_1 is None or node_2 is None: @@ -655,103 +675,19 @@ class BasicGraph(): #endregion Node Information Functions - #region Edge Information Functions - - def get_edge_count(self): - """ - Counts all edges within graph. - :return: Count of edges in graph. - """ - return len(self._edges) - - def get_all_edges(self): - """ - Returns list of all edges in graph. - :return: List of all edges in graph. - """ - return self._edges - - def check_if_edge_in_graph(self, edge_identifier): - """ - Returns bool indicating if Edge exists in graph. - :param edge_identifier: Edge or name of edge to check for. - :return: Bool indicating if edge exists in graph. - """ - # Check for passed arg types. - if edge_identifier is None: - raise AttributeError('Edge identifier arg cannot be empty.') - elif isinstance(edge_identifier, self._edge_type): - # Arg was of Edge object instance. Not sure why anyone would want this but we'll handle for it anyways. - edge_name = edge_identifier.get_name() - else: - # Assume arg was for edge name. - edge_name = str(edge_identifier) - - # Search for edge. - try: - test = self._edges[edge_name] - - # If we got this far, then edge exists in graph. - return True - except KeyError: - # Failed to find edge in graph. - return False - - def get_edge(self, edge_identifier): - """ - Returns associated edge, if present in graph. - :param edge_identifier: Edge or name of edge to return. - :return: Edge from graph | None if not found. - """ - # Check for passed arg types. - if edge_identifier is None: - raise AttributeError('Edge identifier arg cannot be empty.') - elif isinstance(edge_identifier, self._edge_type): - # Arg was of Edge object instance. Not sure why anyone would want this but we'll handle for it anyways. - edge_name = edge_identifier.get_name() - else: - # Assume arg was for edge name. - edge_name = str(edge_identifier) - - # Attempt to return edge. - try: - return self._edges[edge_name] - except KeyError: - logger.warning('Could not find edge "{0}" in graph.'.format(edge_name)) - return None - - def get_nodes_connected_to_edge(self, edge_identifier): - """ - Returns list of nodes connected to edge. - :param edge_identifier: Edge or name of edge to check. - :return: List of nodes connected to edge | None if edge not found. - """ - # Attempt to get edge. - edge_to_check = self.get_edge(edge_identifier) - - # Check if we got a match. - if edge_to_check is not None: - # Edge found. Return nodes. - return edge_to_check.get_nodes() - else: - # Failed to find edge. - return None - - #endregion Edge Information Functions - #region Node Upkeep Functions - def create_node(self, node_name=None): + def create(self, node_name=None): """ Creates new node within graph. :param node_name: Optional name to use for new node. """ # Check node_name arg. if node_name is None: - node_name = self._get_node_auto_name() + node_name = self._parent._get_node_auto_name() # Check that node name does not already exist in graph. try: - test = self._nodes[node_name] + self._parent._nodes[node_name] # If we got this far, then name already exists. Raise error. raise ValueError('Node name "{0}" already exists in graph.'.format(node_name)) @@ -759,43 +695,43 @@ class BasicGraph(): # Name does not exist. This is what we want. pass - new_node = self._node_type(node_name) - self._nodes[new_node._name] = new_node - new_node._graph = self + new_node = self._parent._node_type(node_name) + self._parent._nodes[new_node._name] = new_node + new_node._graph = self._parent return new_node - def add_node(self, new_node): + def add(self, new_node): """ Adds passed node to graph, along with any existing connections. :param new_node: Node to add to graph. """ # Check for passed arg types. - if not isinstance(new_node, self._node_type): + if not isinstance(new_node, self._parent._node_type): raise TypeError('Passed arg is not of type Node.') # Check that node does not already exist within graph. - if self.check_if_node_in_graph(new_node): + if self._parent.nodes.check_if_in_graph(new_node): # Node already exists in graph. Exit. (We don't raise errors since this is a recursive function.) logger.warning('Node with name "{0}" already exists in graph.'.format(new_node.get_name())) return # Add new_node to graph. - self._nodes[new_node.get_name()] = new_node - new_node._graph = self + self._parent._nodes[new_node.get_name()] = new_node + new_node._graph = self._parent # Check all node connections. For any that don't exist in graph, add those as well. for new_connected_node in new_node.get_connected_nodes().values(): # Check if connected node already exists in graph. - if not self.check_if_node_in_graph(new_connected_node): + if not self._parent.nodes.check_if_in_graph(new_connected_node): # Connected node does not exist in graph. Recursively add it and all connected add it. - self.add_node(new_connected_node) + self._parent.nodes.add(new_connected_node) # For each connection between the nodes, add them to graph as well. new_connecting_edge = new_node.get_edge_by_connected_node(new_connected_node) - self._edges[new_connecting_edge.get_name()] = new_connecting_edge + self._parent._edges[new_connecting_edge.get_name()] = new_connecting_edge - def add_node_list(self, node_list): + def add_list(self, node_list): """ Adds list of nodes to graph. :param node_list: List of nodes or node names. @@ -821,17 +757,17 @@ class BasicGraph(): if potential_node is None: # Item was empty. raise AttributeError('Item in list is of type None.') - elif isinstance(potential_node, self._node_type): + elif isinstance(potential_node, self._parent._node_type): # Arg was of Node object instance. node_name = potential_node.get_name() else: # Assume arg was for node name. node_name = str(potential_node) - potential_node = self._node_type(node_name) + potential_node = self._parent._node_type(node_name) # Check that node with given name does not already exist in graph. try: - test = self._nodes[node_name] + self._parent._nodes[node_name] # If we got this far, then node exists in graph already. Raise error. raise ValueError('Node with name "{0}" already exists in graph.'.format(node_name)) @@ -841,34 +777,151 @@ class BasicGraph(): # If we made it this far, then all desired nodes are valid new additions. Add all to graph. for new_node in nodes_to_add: - self.add_node(new_node) + self._parent.nodes.add(new_node) - def remove_node(self, node_indentifier): + def remove(self, node_indentifier): """ Removes node from graph. :param node_indentifier: Node or name of node to remove. :return: Removed node. """ # Attempt to get node. - node_to_remove = self.get_node(node_indentifier) + node_to_remove = self._parent.nodes.get(node_indentifier) node_edges_to_remove = list(node_to_remove.get_edges().values()) # Check if we got a match. if node_to_remove is not None: # Remove node and all associated connections. - self._nodes.pop(node_to_remove.get_name()) + self._parent._nodes.pop(node_to_remove.get_name()) for edge_connection in node_edges_to_remove: - self._edges.pop(edge_connection.get_name()) + self._parent._edges.pop(edge_connection.get_name()) edge_connection.disconnect_nodes() # Return removed node. return node_to_remove + def connect(self, node_1, node_2, edge_name=None): + """ + Connects two nodes in graph. + :param node_1: First node to connect. + :param node_2: Second node to connect. + :param edge_name: Optional name to use for new edge. + :return: Newly created edge to connect nodes. + """ + return self._parent.edges.connect(node_1, node_2, edge_name=edge_name) + + def disconnect(self, node_1_identifier=None, node_2_identifier=None, edge_identifier=None): + """ + Disconnects two nodes in graph. + :param node_1_identifier: First connected node or name of first connected node. + :param node_2_identifier: Second connected node or name of second connected node. + :param edge_identifier: Connecting edge or name of connecting edge. + :return: Removed edge from removed connection. + """ + return self._parent.edges.disconnect( + node_1_identifier=node_1_identifier, + node_2_identifier=node_2_identifier, + edge_identifier=edge_identifier, + ) + #endregion Node Upkeep Functions + +class BasicGraphEdges(): + def __init__(self, parent, *args, **kwargs): + if not isinstance(parent, BasicGraph): + raise TypeError('Expected parent of type BasicGraph.') + + # Get calling parent. + self._parent = parent + + #region Edge Information Functions + + def count(self): + """ + Counts all edges within graph. + :return: Count of edges in graph. + """ + return len(self._parent._edges) + + def all(self): + """ + Returns list of all edges in graph. + :return: List of all edges in graph. + """ + return self._parent._edges + + def check_if_in_graph(self, edge_identifier): + """ + Returns bool indicating if Edge exists in graph. + :param edge_identifier: Edge or name of edge to check for. + :return: Bool indicating if edge exists in graph. + """ + # Check for passed arg types. + if edge_identifier is None: + raise AttributeError('Edge identifier arg cannot be empty.') + elif isinstance(edge_identifier, self._parent._edge_type): + # Arg was of Edge object instance. Not sure why anyone would want this but we'll handle for it anyways. + edge_name = edge_identifier.get_name() + else: + # Assume arg was for edge name. + edge_name = str(edge_identifier) + + # Search for edge. + try: + self._parent._edges[edge_name] + + # If we got this far, then edge exists in graph. + return True + except KeyError: + # Failed to find edge in graph. + return False + + def get(self, edge_identifier): + """ + Returns associated edge, if present in graph. + :param edge_identifier: Edge or name of edge to return. + :return: Edge from graph | None if not found. + """ + # Check for passed arg types. + if edge_identifier is None: + raise AttributeError('Edge identifier arg cannot be empty.') + elif isinstance(edge_identifier, self._parent._edge_type): + # Arg was of Edge object instance. Not sure why anyone would want this but we'll handle for it anyways. + edge_name = edge_identifier.get_name() + else: + # Assume arg was for edge name. + edge_name = str(edge_identifier) + + # Attempt to return edge. + try: + return self._parent._edges[edge_name] + except KeyError: + logger.warning('Could not find edge "{0}" in graph.'.format(edge_name)) + return None + + def node_connections_to_edge(self, edge_identifier): + """ + Returns list of nodes connected to edge. + :param edge_identifier: Edge or name of edge to check. + :return: List of nodes connected to edge | None if edge not found. + """ + # Attempt to get edge. + edge_to_check = self._parent.edges.get(edge_identifier) + + # Check if we got a match. + if edge_to_check is not None: + # Edge found. Return nodes. + return edge_to_check.get_nodes() + else: + # Failed to find edge. + return None + + #endregion Edge Information Functions + #region Edge Upkeep Functions - def connect_nodes(self, node_1, node_2, edge_name=None): + def connect(self, node_1, node_2, edge_name=None): """ Connects two nodes in graph. :param node_1: First node to connect. @@ -877,17 +930,17 @@ class BasicGraph(): :return: Newly created edge to connect nodes. """ # Check if node_1 is type Node. - if not isinstance(node_1, self._node_type): + if not isinstance(node_1, self._parent._node_type): raise TypeError('Arg "node_1" must be of type node.') - if not isinstance(node_2, self._node_type): + if not isinstance(node_2, self._parent._node_type): raise TypeError('Arg "node_2" must be of type node.') # Check edge_name arg. if edge_name is None: - edge_name = self._get_edge_auto_name() + edge_name = self._parent._get_edge_auto_name() # Check that node name does not already exist in graph. try: - test = self._nodes[edge_name] + self._parent._nodes[edge_name] # If we got this far, then name already exists. Raise error. raise ValueError('Edge name "{0}" already exists in graph.'.format(edge_name)) @@ -896,13 +949,13 @@ class BasicGraph(): pass # Connect nodes. - connecting_edge = self._edge_type(edge_name) + connecting_edge = self._parent._edge_type(edge_name) connecting_edge.connect_nodes(node_1, node_2) - self._edges[connecting_edge.get_name()] = connecting_edge + self._parent._edges[connecting_edge.get_name()] = connecting_edge return connecting_edge - def disconnect_nodes(self, node_1_identifier=None, node_2_identifier=None, edge_identifier=None): + def disconnect(self, node_1_identifier=None, node_2_identifier=None, edge_identifier=None): """ Disconnects two nodes in graph. :param node_1_identifier: First connected node or name of first connected node. @@ -915,7 +968,7 @@ class BasicGraph(): raise AttributeError('Must pass in either edge value or node values to disconnect. Got both.') # Check if edge identifier was passed. elif edge_identifier is not None: - connected_edge = self.get_edge(edge_identifier) + connected_edge = self._parent.edges.get(edge_identifier) # Check that edge was found. if connected_edge is not None: @@ -924,7 +977,7 @@ class BasicGraph(): # If successful, then remove edge from graph edge list. if removed_edge is not None: - self._edges.pop(removed_edge.get_name()) + self._parent._edges.pop(removed_edge.get_name()) # Return removed edge. return removed_edge @@ -936,8 +989,8 @@ class BasicGraph(): # Check if node identifiers were passed. elif node_1_identifier is not None and node_2_identifier is not None: - connected_node_1 = self.get_node(node_1_identifier) - connected_node_2 = self.get_node(node_2_identifier) + connected_node_1 = self._parent.nodes.get(node_1_identifier) + connected_node_2 = self._parent.nodes.get(node_2_identifier) # Check that both nodes were found. if connected_node_1 is not None and connected_node_2 is not None: @@ -946,7 +999,7 @@ class BasicGraph(): # If successful, then remove edge from graph edge list. if removed_edge is not None: - self._edges.pop(removed_edge.get_name()) + self._parent._edges.pop(removed_edge.get_name()) # Return removed edge. return removed_edge diff --git a/resources/graphs/directed_graph/graph.py b/resources/graphs/directed_graph/graph.py index cbb28d4289d8dedfdc1ed623ce9ef2a13ad19c3b..130297829ff0c3129a7666d350232abda7820834 100644 --- a/resources/graphs/directed_graph/graph.py +++ b/resources/graphs/directed_graph/graph.py @@ -14,7 +14,7 @@ import math # User Class Imports. from .components import DirectedEdge, DirectedNode -from ..basic_graph.graph import BasicGraph +from ..basic_graph.graph import BasicGraph, BasicGraphDisplay, BasicGraphEdges, BasicGraphNodes #region Logging Initialization @@ -47,6 +47,22 @@ class DirectedGraph(BasicGraph): self._graph_type = DirectedGraph self._node_type = DirectedNode + # Get associated child classes. + self.display = DirectedGraphDisplay(self) + self.edges = DirectedGraphEdges(self) + self.nodes = DirectedGraphNodes(self) + + +class DirectedGraphDisplay(BasicGraphDisplay): + def __init__(self, parent, *args, **kwargs): + super().__init__(parent, *args, *kwargs) + + if not isinstance(parent, DirectedGraph): + raise TypeError('Expected parent of type DirectedGraph.') + + # Get calling parent. + self._parent = parent + def _create_additional_edge_mappings(self): """ Creates additional visual edge direction "pointer" mappings for all edge. @@ -60,7 +76,7 @@ class DirectedGraph(BasicGraph): edge_pointers = [] # Loop through all edges. - for edge in self.get_all_edges().values(): + for edge in self._parent.edges.all().values(): # Get associated head and tail nodes. tail_node = edge.get_tail_node() head_node = edge.get_head_node() @@ -88,8 +104,8 @@ class DirectedGraph(BasicGraph): # Node is linking to another node. # Calculate "midpoint". In our case, we want it slightly offset from center, closer to head node. - mid_x = ( 1/4 * tail_x ) + ( 3/4 * head_x ) - mid_y = ( 1/4 * tail_y ) + ( 3/4 * head_y ) + mid_x = (1 / 4 * tail_x) + (3 / 4 * head_x) + mid_y = (1 / 4 * tail_y) + (3 / 4 * head_y) # Get arrow "length" and "distance" values. length, distance = self._calc_distance_and_length(head_x, head_y, tail_x, tail_y) @@ -207,3 +223,26 @@ class DirectedGraph(BasicGraph): ) # Return 3-value list so that each point of the arrow will show hover text. return [edge_text, edge_text, edge_text] + + +class DirectedGraphNodes(BasicGraphNodes): + def __init__(self, parent, *args, **kwargs): + super().__init__(parent, *args, *kwargs) + + if not isinstance(parent, DirectedGraph): + raise TypeError('Expected parent of type DirectedGraph.') + + # Get calling parent. + self._parent = parent + + +class DirectedGraphEdges(BasicGraphEdges): + def __init__(self, parent, *args, **kwargs): + super().__init__(parent, *args, *kwargs) + + if not isinstance(parent, DirectedGraph): + raise TypeError('Expected parent of type DirectedGraph.') + + # Get calling parent. + self._parent = parent + diff --git a/resources/graphs/state_machine/graph.py b/resources/graphs/state_machine/graph.py index d8e9f06c81dc6582dd51f5e5f41d9af08975780d..3b7ad1c781c739e2f3416199c7a2d582459a5668 100644 --- a/resources/graphs/state_machine/graph.py +++ b/resources/graphs/state_machine/graph.py @@ -14,7 +14,7 @@ from random import randint # User Class Imports. from .components import StateMachineEdge, StateMachineNode -from ..directed_graph.graph import DirectedGraph +from ..directed_graph.graph import DirectedGraph, DirectedGraphDisplay, DirectedGraphEdges, DirectedGraphNodes #region Logging Initialization @@ -51,6 +51,22 @@ class StateMachineGraph(DirectedGraph): self._graph_type = StateMachineGraph self._node_type = StateMachineNode + # Get associated child classes. + self.display = StateMachineGraphDisplay(self) + self.edges = StateMachineGraphEdges(self) + self.nodes = StateMachineGraphNodes(self) + + +class StateMachineGraphDisplay(DirectedGraphDisplay): + def __init__(self, parent, *args, **kwargs): + super().__init__(parent, *args, *kwargs) + + if not isinstance(parent, StateMachineGraph): + raise TypeError('Expected parent of type StateMachineGraph.') + + # Get calling parent. + self._parent = parent + def _assign_node_coordinates(self): """ Assigns Graph mapping coordinates for all nodes. @@ -80,10 +96,10 @@ class StateMachineGraph(DirectedGraph): # Final states are done first, in case a node is both final and initial. In this case, we want it on the left. # Going first means that the intial state logic will override the final state logic, putting it left like we # want. - final_state_count = len(self._final_states) + final_state_count = len(self._parent._final_states) state_index = 1 grid_length = max_direction / final_state_count - for final_state in self._final_states.values(): + for final_state in self._parent._final_states.values(): # Get grid values. current_grid_end = grid_length * state_index current_grid_start = current_grid_end - grid_length @@ -92,8 +108,8 @@ class StateMachineGraph(DirectedGraph): # Assign node to calculated grid. x_coord = 95 y_coord = int((current_grid_start + current_grid_end) / 2) - self._nodes[final_state.get_name()].x_coord = x_coord - self._nodes[final_state.get_name()].y_coord = y_coord + self._parent._nodes[final_state.get_name()].x_coord = x_coord + self._parent._nodes[final_state.get_name()].y_coord = y_coord # Record extreme positions. if x_coord > farthest_x[0]: @@ -107,10 +123,10 @@ class StateMachineGraph(DirectedGraph): # Loop through all initial states, assigning y-coords based on a divided grid setup. # Grids are from top to bottom, to evenly distribute space to all start nodes. - initial_state_count = len(self._initial_states) + initial_state_count = len(self._parent._initial_states) state_index = 1 grid_length = max_direction / initial_state_count - for initial_state in self._initial_states.values(): + for initial_state in self._parent._initial_states.values(): # Get grid values. current_grid_end = grid_length * state_index current_grid_start = current_grid_end - grid_length @@ -119,8 +135,8 @@ class StateMachineGraph(DirectedGraph): # Assign node to calculated grid. x_coord = 5 y_coord = int((current_grid_start + current_grid_end) / 2) - self._nodes[initial_state.get_name()].x_coord = x_coord - self._nodes[initial_state.get_name()].y_coord = y_coord + self._parent._nodes[initial_state.get_name()].x_coord = x_coord + self._parent._nodes[initial_state.get_name()].y_coord = y_coord # Record extreme positions. if x_coord > farthest_x[0]: @@ -133,14 +149,14 @@ class StateMachineGraph(DirectedGraph): shortest_y = (y_coord, initial_state) # Now loop through all other nodes and assign coordinates. - for node in self.get_all_nodes().values(): + for node in self._parent.nodes.all().values(): # Make sure node is not already assigned coordinates. if node.x_coord is None or node.y_coord is None: # Get a random position. index = randint(0, len(possible_positions)) position = possible_positions.pop(index) - self._nodes[node.get_name()].x_coord = position[0] - self._nodes[node.get_name()].y_coord = position[1] + self._parent._nodes[node.get_name()].x_coord = position[0] + self._parent._nodes[node.get_name()].y_coord = position[1] # Record extreme positions. if position[0] > farthest_x[0]: @@ -163,17 +179,17 @@ class StateMachineGraph(DirectedGraph): farthest_y[1].y_coord = 90 # Now go through all edges and do similar. - for edge in self.get_all_edges().values(): + for edge in self._parent.edges.all().values(): node_list = edge.get_nodes() node_1 = node_list['tail_node'] node_2 = node_list['head_node'] # Assign edge coordinates. - self._edges[edge.get_name()].x1_coord = node_1.x_coord - self._edges[edge.get_name()].x2_coord = node_2.x_coord - self._edges[edge.get_name()].y1_coord = node_1.y_coord - self._edges[edge.get_name()].y2_coord = node_2.y_coord + self._parent._edges[edge.get_name()].x1_coord = node_1.x_coord + self._parent._edges[edge.get_name()].x2_coord = node_2.x_coord + self._parent._edges[edge.get_name()].y1_coord = node_1.y_coord + self._parent._edges[edge.get_name()].y2_coord = node_2.y_coord def _create_node_hover_text(self): """ @@ -183,7 +199,7 @@ class StateMachineGraph(DirectedGraph): node_hover_text = [] # Loop through all nodes and create hover text. - for node in self.get_all_nodes().values(): + for node in self._parent.nodes.all().values(): hover_text = 'Node: {0}<br>Connection Count: {1}'.format(node.get_name(), node.get_edge_count()) # Check if node is initial state. @@ -212,7 +228,7 @@ class StateMachineGraph(DirectedGraph): node_y = [] # Loop through all nodes. - for node in self.get_all_nodes().values(): + for node in self._parent.nodes.all().values(): # Only do anything if node is set to be a final state. if node.is_final: node_x.append(node.x_coord) @@ -255,10 +271,9 @@ class StateMachineGraph(DirectedGraph): edge_mappings = super()._create_additional_edge_mappings() # Loop through all nodes. - for node in self.get_all_nodes().values(): + for node in self._parent.nodes.all().values(): # Only do anything if node is set to be a final state. if node.is_initial: - # Get associated coordinates. node_x = node.x_coord node_y = node.y_coord @@ -319,7 +334,39 @@ class StateMachineGraph(DirectedGraph): # Return 3-value list so that each point of the arrow will show hover text. return [edge_text, edge_text, edge_text] - def connect_nodes(self, node_1, node_2, state_change_condition, edge_name=None): + +class StateMachineGraphNodes(DirectedGraphNodes): + def __init__(self, parent, *args, **kwargs): + super().__init__(parent, *args, *kwargs) + + if not isinstance(parent, StateMachineGraph): + raise TypeError('Expected parent of type StateMachineGraph.') + + # Get calling parent. + self._parent = parent + + def connect(self, node_1, node_2, state_change_condition, edge_name=None): + """ + Connects two nodes in graph. + :param node_1: First node to connect. + :param node_2: Second node to connect. + :param state_change_condition: Value that allows a state change through this connection. + :param edge_name: Optional name to use for new edge. + :return: Newly created edge to connect nodes. + """ + return self._parent.edges.connect(node_1, node_2, state_change_condition, edge_name=edge_name) + +class StateMachineGraphEdges(DirectedGraphEdges): + def __init__(self, parent, *args, **kwargs): + super().__init__(parent, *args, *kwargs) + + if not isinstance(parent, StateMachineGraph): + raise TypeError('Expected parent of type StateMachineGraph.') + + # Get calling parent. + self._parent = parent + + def connect(self, node_1, node_2, state_change_condition, edge_name=None): """ Connects two nodes in graph with given state change condition. :param node_1: First node to connect. @@ -332,17 +379,17 @@ class StateMachineGraph(DirectedGraph): raise ValueError('State change condition cannot be none.') # Check if node_1 is type Node. - if not isinstance(node_1, self._node_type): + if not isinstance(node_1, self._parent._node_type): raise TypeError('Arg "node_1" must be of type node.') - if not isinstance(node_2, self._node_type): + if not isinstance(node_2, self._parent._node_type): raise TypeError('Arg "node_2" must be of type node.') # Check edge_name arg. if edge_name is None: - edge_name = self._get_edge_auto_name() + edge_name = self._parent._get_edge_auto_name() # Check that edge name does not already exist in graph. try: - self._nodes[edge_name] + self._parent._nodes[edge_name] # If we got this far, then name already exists. Raise error. raise ValueError('Edge name "{0}" already exists in graph.'.format(edge_name)) @@ -351,27 +398,27 @@ class StateMachineGraph(DirectedGraph): pass # Connect nodes. - connecting_edge = self._edge_type(edge_name) + connecting_edge = self._parent._edge_type(edge_name) connecting_edge.connect_nodes(node_1, node_2, state_change_condition) - self._edges[connecting_edge.get_name()] = connecting_edge + self._parent._edges[connecting_edge.get_name()] = connecting_edge return connecting_edge - def remove_node(self, node_indentifier): + def remove(self, node_indentifier): """ Removes node from graph. :param node_indentifier: Node or name of node to remove. :return: Removed node. """ - node = self.get_node(node_indentifier) + node = self._parent.nodes.get(node_indentifier) # Remove initial state, if present. if node.is_initial: - self._initial_states.pop(node.get_name()) + self._parent._initial_states.pop(node.get_name()) # Remove final state, if present. if node.is_final: - self._final_states.pop(node.get_name()) + self._parent._final_states.pop(node.get_name()) # Call parent implementation. - return super().remove_node(node_indentifier) + return super()._parent.nodes.remove(node_indentifier) diff --git a/tests/resources/graphs/basic_graph/graph.py b/tests/resources/graphs/basic_graph/graph.py index 4764e68609fa1c42791cdbec352b0ca6993f07de..e51e41777ae2b6baf4789eca758baf832aea977e 100644 --- a/tests/resources/graphs/basic_graph/graph.py +++ b/tests/resources/graphs/basic_graph/graph.py @@ -21,8 +21,8 @@ class TestBasicGraph(unittest.TestCase): self.test_graph = BasicGraph() def test__graph_initialization(self): - self.assertEqual(self.test_graph.get_all_edges(), {}) - self.assertEqual(self.test_graph.get_all_nodes(), {}) + self.assertEqual(self.test_graph.edges.all(), {}) + self.assertEqual(self.test_graph.nodes.all(), {}) self.assertEqual(self.test_graph._edge_name_auto_counter, 1) self.assertEqual(self.test_graph._node_name_auto_counter, 1) @@ -47,15 +47,15 @@ class TestBasicGraph(unittest.TestCase): self.assertEqual(4, self.test_graph._get_node_auto_name()) # Manually add entries 5, 6, and 7 to graph. - self.test_graph.add_node(BasicNode(5)) - self.test_graph.add_node(BasicNode(6)) - self.test_graph.add_node(BasicNode(7)) + self.test_graph.nodes.add(BasicNode(5)) + self.test_graph.nodes.add(BasicNode(6)) + self.test_graph.nodes.add(BasicNode(7)) # Test that auto_name now provides 8 as the name. self.assertEqual(self.test_graph._get_node_auto_name(), 8) # Manually add one more. - self.test_graph.add_node(BasicNode(9)) + self.test_graph.nodes.add(BasicNode(9)) # Test that auto_name now provides 10. self.assertEqual(self.test_graph._get_node_auto_name(), 10) @@ -102,184 +102,189 @@ class TestBasicGraph(unittest.TestCase): #endregion Private Information Function Tests - #region Node Information Function Tests - def test__get_node_count(self): +class TestBasicGraphNodes(unittest.TestCase): + def setUp(self): + self.test_graph = BasicGraph() + + # region Node Information Function Tests + + def test__count(self): # Test with no nodes. - self.assertEqual(self.test_graph.get_node_count(), 0) + self.assertEqual(self.test_graph.nodes.count(), 0) # Test with one nodes. - self.test_graph.create_node() - self.assertEqual(self.test_graph.get_node_count(), 1) + self.test_graph.nodes.create() + self.assertEqual(self.test_graph.nodes.count(), 1) # Test with two nodes. - self.test_graph.create_node() - self.assertEqual(self.test_graph.get_node_count(), 2) + self.test_graph.nodes.create() + self.assertEqual(self.test_graph.nodes.count(), 2) # Works with 0, 1, and 2 nodes. Assuming works with all further n nodes. - def test__get_all_nodes(self): + def test__all(self): node_1 = BasicNode(self.test_graph._get_node_auto_name()) node_2 = BasicNode(self.test_graph._get_node_auto_name()) # Test with no node. - self.assertEqual(self.test_graph.get_node_count(), 0) - self.assertEqual(self.test_graph.get_all_nodes(), {}) + self.assertEqual(self.test_graph.nodes.count(), 0) + self.assertEqual(self.test_graph.nodes.all(), {}) # Test with one nodes. - self.test_graph.add_node(node_1) - self.assertEqual(self.test_graph.get_node_count(), 1) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.test_graph.nodes.add(node_1) + self.assertEqual(self.test_graph.nodes.count(), 1) + self.assertEqual(self.test_graph.nodes.all(), { node_1.get_name(): node_1, }) # Test with two nodes. - self.test_graph.add_node(node_2) - self.assertEqual(self.test_graph.get_node_count(), 2) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.test_graph.nodes.add(node_2) + self.assertEqual(self.test_graph.nodes.count(), 2) + self.assertEqual(self.test_graph.nodes.all(), { node_1.get_name(): node_1, node_2.get_name(): node_2, }) # Works with 0, 1, and 2 nodes. Assuming works with all further n nodes. - def test__check_if_node_in_graph__success(self): + def test__check_if_in_graph__success(self): # Create nodes. - node_1 = self.test_graph.create_node() - node_2 = self.test_graph.create_node() + node_1 = self.test_graph.nodes.create() + node_2 = self.test_graph.nodes.create() node_3 = BasicNode('Node 3') with self.subTest('Check by Node class.'): # Test node 1. - self.assertTrue(self.test_graph.check_if_node_in_graph(node_1)) + self.assertTrue(self.test_graph.nodes.check_if_in_graph(node_1)) # Test node 2. - self.assertTrue(self.test_graph.check_if_node_in_graph(node_2)) + self.assertTrue(self.test_graph.nodes.check_if_in_graph(node_2)) # Test node 3. - self.assertFalse(self.test_graph.check_if_node_in_graph(node_3)) + self.assertFalse(self.test_graph.nodes.check_if_in_graph(node_3)) with self.subTest('Check by Node name.'): # Test node 1. - self.assertTrue(self.test_graph.check_if_node_in_graph(node_1.get_name())) + self.assertTrue(self.test_graph.nodes.check_if_in_graph(node_1.get_name())) # Test node 2. - self.assertTrue(self.test_graph.check_if_node_in_graph(node_2.get_name())) + self.assertTrue(self.test_graph.nodes.check_if_in_graph(node_2.get_name())) # Test node 3. - self.assertFalse(self.test_graph.check_if_node_in_graph(node_3.get_name())) + self.assertFalse(self.test_graph.nodes.check_if_in_graph(node_3.get_name())) - def test__check_if_node_in_graph__failure(self): + def test__check_if_in_graph__failure(self): with self.subTest('Arg is None'): with self.assertRaises(AttributeError): - self.test_graph.check_if_node_in_graph(None) + self.test_graph.nodes.check_if_in_graph(None) - def test__get_node__success(self): + def test__get__success(self): # Create nodes. - node_1 = self.test_graph.create_node() - node_2 = self.test_graph.create_node() + node_1 = self.test_graph.nodes.create() + node_2 = self.test_graph.nodes.create() with self.subTest('Get node by Node class.'): # Test first node. - self.assertEqual(self.test_graph.get_node(node_1), node_1) + self.assertEqual(self.test_graph.nodes.get(node_1), node_1) # Test second node. - self.assertEqual(self.test_graph.get_node(node_2), node_2) + self.assertEqual(self.test_graph.nodes.get(node_2), node_2) with self.subTest('Get node by Node name.'): # Test first node. - self.assertEqual(self.test_graph.get_node(node_1.get_name()), node_1) + self.assertEqual(self.test_graph.nodes.get(node_1.get_name()), node_1) # Test second node. - self.assertEqual(self.test_graph.get_node(node_2.get_name()), node_2) + self.assertEqual(self.test_graph.nodes.get(node_2.get_name()), node_2) - def test__get_node__failure(self): + def test__get__failure(self): with self.subTest('Arg is None.'): with self.assertRaises(AttributeError): - self.test_graph.get_node(None) + self.test_graph.nodes.get(None) with self.subTest('Node is not in graph - by Node class.'): node_1 = BasicNode(self.test_graph._get_node_auto_name()) with self.assertLogs(level='WARNING'): - self.assertIsNone(self.test_graph.get_node(node_1)) + self.assertIsNone(self.test_graph.nodes.get(node_1)) with self.subTest('Node is not in graph - by Node name.'): with self.assertLogs(level='WARNING'): - self.assertIsNone(self.test_graph.get_node('Test')) + self.assertIsNone(self.test_graph.nodes.get('Test')) - def test__get_node_degree__success(self): + def test__degree__success(self): with self.subTest('By node class.'): # Create nodes. - node_1 = self.test_graph.create_node() - node_2 = self.test_graph.create_node() - node_3 = self.test_graph.create_node() + node_1 = self.test_graph.nodes.create() + node_2 = self.test_graph.nodes.create() + node_3 = self.test_graph.nodes.create() # Test with no connections. - self.assertEqual(self.test_graph.get_node_degree(node_1), 0) + self.assertEqual(self.test_graph.nodes.degree(node_1), 0) # Test with one connection. - self.test_graph.connect_nodes(node_1, node_2) - self.assertEqual(self.test_graph.get_node_degree(node_1), 1) + self.test_graph.nodes.connect(node_1, node_2) + self.assertEqual(self.test_graph.nodes.degree(node_1), 1) # Test with two connections. - self.test_graph.connect_nodes(node_1, node_3) - self.assertEqual(self.test_graph.get_node_degree(node_1), 2) + self.test_graph.nodes.connect(node_1, node_3) + self.assertEqual(self.test_graph.nodes.degree(node_1), 2) # Works with 0, 1, and 2 connections. Assuming works with all further n connections. with self.subTest('By node name.'): # Create nodes. - node_1 = self.test_graph.create_node() - node_2 = self.test_graph.create_node() - node_3 = self.test_graph.create_node() - node_4 = self.test_graph.create_node() + node_1 = self.test_graph.nodes.create() + node_2 = self.test_graph.nodes.create() + node_3 = self.test_graph.nodes.create() + node_4 = self.test_graph.nodes.create() # Test with no connections. - self.assertEqual(self.test_graph.get_node_degree(node_1.get_name()), 0) + self.assertEqual(self.test_graph.nodes.degree(node_1.get_name()), 0) # Test with one connection. - self.test_graph.connect_nodes(node_1, node_2) - self.assertEqual(self.test_graph.get_node_degree(node_1.get_name()), 1) + self.test_graph.nodes.connect(node_1, node_2) + self.assertEqual(self.test_graph.nodes.degree(node_1.get_name()), 1) # Test with two connections. - self.test_graph.connect_nodes(node_1, node_3) - self.assertEqual(self.test_graph.get_node_degree(node_1.get_name()), 2) + self.test_graph.nodes.connect(node_1, node_3) + self.assertEqual(self.test_graph.nodes.degree(node_1.get_name()), 2) # Works with 0, 1, and 2 connections. Assuming works with all further n connections. - def test__get_node_degree__failure(self): + def test__degree__failure(self): with self.subTest('Arg is None.'): with self.assertRaises(AttributeError): - self.test_graph.get_node_degree(None) + self.test_graph.nodes.degree(None) with self.subTest('Node is not in graph - by Node Class.'): node_1 = BasicNode(self.test_graph._get_node_auto_name()) with self.assertLogs(level='WARNING'): - self.assertIsNone(self.test_graph.get_node_degree(node_1)) + self.assertIsNone(self.test_graph.nodes.degree(node_1)) with self.subTest('Node is not in graph - by Node name.'): with self.assertLogs(level='WARNING'): - self.assertIsNone(self.test_graph.get_node_degree('Test')) + self.assertIsNone(self.test_graph.nodes.degree('Test')) - def test__get_edges_connected_to_node__success(self): + def test__edge_connections_to_node__success(self): with self.subTest('By node class.'): # Create nodes. - node_1 = self.test_graph.create_node() - node_2 = self.test_graph.create_node() - node_3 = self.test_graph.create_node() + node_1 = self.test_graph.nodes.create() + node_2 = self.test_graph.nodes.create() + node_3 = self.test_graph.nodes.create() # Test with no connections. - self.assertEqual(self.test_graph.get_edges_connected_to_node(node_1), {}) + self.assertEqual(self.test_graph.nodes.edge_connections_to_node(node_1), {}) # Test with one connection. - edge_1 = self.test_graph.connect_nodes(node_1, node_2) - self.assertEqual(self.test_graph.get_edges_connected_to_node(node_1), { + edge_1 = self.test_graph.nodes.connect(node_1, node_2) + self.assertEqual(self.test_graph.nodes.edge_connections_to_node(node_1), { edge_1.get_name(): edge_1, }) # Test with two connections. - edge_2 = self.test_graph.connect_nodes(node_1, node_3) - self.assertEqual(self.test_graph.get_edges_connected_to_node(node_1), { + edge_2 = self.test_graph.nodes.connect(node_1, node_3) + self.assertEqual(self.test_graph.nodes.edge_connections_to_node(node_1), { edge_1.get_name(): edge_1, edge_2.get_name(): edge_2, }) @@ -288,68 +293,68 @@ class TestBasicGraph(unittest.TestCase): with self.subTest('By node name.'): # Create nodes. - node_1 = self.test_graph.create_node() - node_2 = self.test_graph.create_node() - node_3 = self.test_graph.create_node() + node_1 = self.test_graph.nodes.create() + node_2 = self.test_graph.nodes.create() + node_3 = self.test_graph.nodes.create() # Test with no connections. - self.assertEqual(self.test_graph.get_edges_connected_to_node(node_1), {}) + self.assertEqual(self.test_graph.nodes.edge_connections_to_node(node_1), {}) # Test with one connection. - edge_1 = self.test_graph.connect_nodes(node_1, node_2) - self.assertEqual(self.test_graph.get_edges_connected_to_node(node_1), { + edge_1 = self.test_graph.nodes.connect(node_1, node_2) + self.assertEqual(self.test_graph.nodes.edge_connections_to_node(node_1), { edge_1.get_name(): edge_1, }) # Test with two connections. - edge_2 = self.test_graph.connect_nodes(node_1, node_3) - self.assertEqual(self.test_graph.get_edges_connected_to_node(node_1), { + edge_2 = self.test_graph.nodes.connect(node_1, node_3) + self.assertEqual(self.test_graph.nodes.edge_connections_to_node(node_1), { edge_1.get_name(): edge_1, edge_2.get_name(): edge_2, }) # Works with 0, 1, and 2 connections. Assuming works with all further n connections. - def test__get_edges_connected_to_node__failure(self): + def test__edges_connections_to_node__failure(self): with self.subTest('Arg is None.'): with self.assertRaises(AttributeError): - self.test_graph.get_edges_connected_to_node(None) + self.test_graph.nodes.edge_connections_to_node(None) with self.subTest('Node is not in graph - by Node Class.'): node_1 = BasicNode(self.test_graph._get_node_auto_name()) with self.assertLogs(level='WARNING'): - self.assertIsNone(self.test_graph.get_edges_connected_to_node(node_1)) + self.assertIsNone(self.test_graph.nodes.edge_connections_to_node(node_1)) with self.subTest('Node is not in graph - by Node name.'): with self.assertLogs(level='WARNING'): - self.assertIsNone(self.test_graph.get_edges_connected_to_node('Test')) + self.assertIsNone(self.test_graph.nodes.edge_connections_to_node('Test')) - def test__get_connected_nodes__success(self): + def test__node_connections_to_nodes__success(self): with self.subTest('By node class.'): # Create nodes. - node_1 = self.test_graph.create_node() - node_2 = self.test_graph.create_node() - node_3 = self.test_graph.create_node() + node_1 = self.test_graph.nodes.create() + node_2 = self.test_graph.nodes.create() + node_3 = self.test_graph.nodes.create() # Test with no connections. - self.assertEqual(self.test_graph.get_connected_nodes(node_1), {}) + self.assertEqual(self.test_graph.nodes.node_connections_to_node(node_1), {}) # Test with one connection. - self.test_graph.connect_nodes(node_1, node_2) - self.assertEqual(self.test_graph.get_connected_nodes(node_1), { + self.test_graph.nodes.connect(node_1, node_2) + self.assertEqual(self.test_graph.nodes.node_connections_to_node(node_1), { node_2.get_name(): node_2, }) - self.assertEqual(self.test_graph.get_connected_nodes(node_2), { + self.assertEqual(self.test_graph.nodes.node_connections_to_node(node_2), { node_1.get_name(): node_1, }) # Test with two connections. - self.test_graph.connect_nodes(node_1, node_3) - self.assertEqual(self.test_graph.get_connected_nodes(node_1), { + self.test_graph.nodes.connect(node_1, node_3) + self.assertEqual(self.test_graph.nodes.node_connections_to_node(node_1), { node_2.get_name(): node_2, node_3.get_name(): node_3, }) - self.assertEqual(self.test_graph.get_connected_nodes(node_3), { + self.assertEqual(self.test_graph.nodes.node_connections_to_node(node_3), { node_1.get_name(): node_1, }) @@ -357,292 +362,141 @@ class TestBasicGraph(unittest.TestCase): with self.subTest('By node name.'): # Create nodes. - node_1 = self.test_graph.create_node() - node_2 = self.test_graph.create_node() - node_3 = self.test_graph.create_node() + node_1 = self.test_graph.nodes.create() + node_2 = self.test_graph.nodes.create() + node_3 = self.test_graph.nodes.create() # Test with no connections. - self.assertEqual(self.test_graph.get_connected_nodes(node_1), {}) + self.assertEqual(self.test_graph.nodes.node_connections_to_node(node_1), {}) # Test with one connection. - self.test_graph.connect_nodes(node_1, node_2) - self.assertEqual(self.test_graph.get_connected_nodes(node_1.get_name()), { + self.test_graph.nodes.connect(node_1, node_2) + self.assertEqual(self.test_graph.nodes.node_connections_to_node(node_1.get_name()), { node_2.get_name(): node_2, }) - self.assertEqual(self.test_graph.get_connected_nodes(node_2.get_name()), { + self.assertEqual(self.test_graph.nodes.node_connections_to_node(node_2.get_name()), { node_1.get_name(): node_1, }) # Test with two connections. - self.test_graph.connect_nodes(node_1, node_3) + self.test_graph.nodes.connect(node_1, node_3) - self.assertEqual(self.test_graph.get_connected_nodes(node_1.get_name()), { + self.assertEqual(self.test_graph.nodes.node_connections_to_node(node_1.get_name()), { node_2.get_name(): node_2, node_3.get_name(): node_3, }) - self.assertEqual(self.test_graph.get_connected_nodes(node_3.get_name()), { + self.assertEqual(self.test_graph.nodes.node_connections_to_node(node_3.get_name()), { node_1.get_name(): node_1, }) # Works with 0, 1, and 2 connections. Assuming works with all further n connections. - def test__get_connected_nodes__failure(self): + def test__node_connections_to_nodes__failure(self): with self.subTest('Arg is None.'): with self.assertRaises(AttributeError): - self.test_graph.get_connected_nodes(None) + self.test_graph.nodes.node_connections_to_node(None) with self.subTest('Node is not in graph - by Node Class.'): node_1 = BasicNode(self.test_graph._get_node_auto_name()) with self.assertLogs(level='WARNING'): - self.assertIsNone(self.test_graph.get_connected_nodes(node_1)) + self.assertIsNone(self.test_graph.nodes.node_connections_to_node(node_1)) with self.subTest('Node is not in graph - by Node name.'): with self.assertLogs(level='WARNING'): - self.assertIsNone(self.test_graph.get_connected_nodes('Test')) + self.assertIsNone(self.test_graph.nodes.node_connections_to_node('Test')) - def test__determine_node_adjacency__success(self): + def test__determine_adjacency__success(self): # Create nodes. - node_1 = self.test_graph.create_node() - node_2 = self.test_graph.create_node() - node_3 = self.test_graph.create_node() - node_4 = self.test_graph.create_node() + node_1 = self.test_graph.nodes.create() + node_2 = self.test_graph.nodes.create() + node_3 = self.test_graph.nodes.create() + node_4 = self.test_graph.nodes.create() # Connect nodes 1, 2, and 4. - self.test_graph.connect_nodes(node_1, node_2) - self.test_graph.connect_nodes(node_1, node_4) + self.test_graph.nodes.connect(node_1, node_2) + self.test_graph.nodes.connect(node_1, node_4) with self.subTest('Test adjacency by Node class.'): # Test adjacency of node 2. - self.assertTrue(self.test_graph.determine_node_adjacency(node_1, node_2)) - self.assertTrue(self.test_graph.determine_node_adjacency(node_2, node_1)) + self.assertTrue(self.test_graph.nodes.determine_adjacency(node_1, node_2)) + self.assertTrue(self.test_graph.nodes.determine_adjacency(node_2, node_1)) # Test adjacency of node 3. - self.assertFalse(self.test_graph.determine_node_adjacency(node_1, node_3)) - self.assertFalse(self.test_graph.determine_node_adjacency(node_3, node_1)) + self.assertFalse(self.test_graph.nodes.determine_adjacency(node_1, node_3)) + self.assertFalse(self.test_graph.nodes.determine_adjacency(node_3, node_1)) # Test adjacency of node 4. - self.assertTrue(self.test_graph.determine_node_adjacency(node_1, node_4)) - self.assertTrue(self.test_graph.determine_node_adjacency(node_4, node_1)) + self.assertTrue(self.test_graph.nodes.determine_adjacency(node_1, node_4)) + self.assertTrue(self.test_graph.nodes.determine_adjacency(node_4, node_1)) with self.subTest('Test adjacency by Node name.'): # Test adjacency of node 2. - self.assertTrue(self.test_graph.determine_node_adjacency(node_1.get_name(), node_2.get_name())) - self.assertTrue(self.test_graph.determine_node_adjacency(node_2.get_name(), node_1.get_name())) + self.assertTrue(self.test_graph.nodes.determine_adjacency(node_1.get_name(), node_2.get_name())) + self.assertTrue(self.test_graph.nodes.determine_adjacency(node_2.get_name(), node_1.get_name())) # Test adjacency of node 3. - self.assertFalse(self.test_graph.determine_node_adjacency(node_1.get_name(), node_3.get_name())) - self.assertFalse(self.test_graph.determine_node_adjacency(node_3.get_name(), node_1.get_name())) + self.assertFalse(self.test_graph.nodes.determine_adjacency(node_1.get_name(), node_3.get_name())) + self.assertFalse(self.test_graph.nodes.determine_adjacency(node_3.get_name(), node_1.get_name())) # Test adjacency of node 4. - self.assertTrue(self.test_graph.determine_node_adjacency(node_1.get_name(), node_4.get_name())) - self.assertTrue(self.test_graph.determine_node_adjacency(node_4.get_name(), node_1.get_name())) + self.assertTrue(self.test_graph.nodes.determine_adjacency(node_1.get_name(), node_4.get_name())) + self.assertTrue(self.test_graph.nodes.determine_adjacency(node_4.get_name(), node_1.get_name())) - def test__determine_node_adjacency__failure(self): + def test__determine_adjacency__failure(self): # Create nodes. - node_1 = self.test_graph.create_node() - node_2 = self.test_graph.create_node() + node_1 = self.test_graph.nodes.create() + node_2 = self.test_graph.nodes.create() with self.subTest('Both nodes None.'): with self.assertRaises(AttributeError): - self.test_graph.determine_node_adjacency(None, None) + self.test_graph.nodes.determine_adjacency(None, None) with self.subTest('Node_1 is None.'): with self.assertRaises(AttributeError): - self.test_graph.determine_node_adjacency(None, node_2) + self.test_graph.nodes.determine_adjacency(None, node_2) with self.subTest('Node_1 is None.'): with self.assertRaises(AttributeError): - self.test_graph.determine_node_adjacency(node_1, None) + self.test_graph.nodes.determine_adjacency(node_1, None) #endregion Node Information Function Tests - #region Edge Information Function Tests - - def test__get_edge_count(self): - # Create edges to add to graph. - edge_1 = BasicEdge(self.test_graph._get_node_auto_name()) - edge_2 = BasicEdge(self.test_graph._get_node_auto_name()) - - # Test with no edges. - self.assertEqual(self.test_graph.get_edge_count(), 0) - - # Test with one edges. - self.test_graph._edges[edge_1.get_name()] = edge_1 - self.assertEqual(self.test_graph.get_edge_count(), 1) - - # Test with two edges. - self.test_graph._edges[edge_2.get_name()] = edge_2 - self.assertEqual(self.test_graph.get_edge_count(), 2) - - # Works with 0, 1, and 2 edges. Assuming works with all further n edges. - - def test__get_all_edges(self): - # Create edges to add to graph. - edge_1 = BasicEdge(self.test_graph._get_node_auto_name()) - edge_2 = BasicEdge(self.test_graph._get_node_auto_name()) - - # Test with no edges. - self.assertEqual(self.test_graph.get_all_edges(), {}) - - # Test with one edge. - self.test_graph._edges[edge_1.get_name()] = edge_1 - self.assertEqual(self.test_graph.get_all_edges(), { - edge_1.get_name(): edge_1, - }) - - # Test with two edges. - self.test_graph._edges[edge_2.get_name()] = edge_2 - self.assertEqual(self.test_graph.get_all_edges(), { - edge_1.get_name(): edge_1, - edge_2.get_name(): edge_2, - }) - - # Works with 0, 1, and 2 edges. Assuming works with all further n edges. - - def test__check_if_edge_in_graph__success(self): - # Create nodes. - node_1 = self.test_graph.create_node() - node_2 = self.test_graph.create_node() - node_3 = self.test_graph.create_node() - node_4 = BasicNode('Node 4') - node_5 = BasicNode('Node 5') - - # Create connections. - edge_1 = self.test_graph.connect_nodes(node_1, node_2) - edge_2 = self.test_graph.connect_nodes(node_1, node_3) - edge_3 = node_4.connect_node(node_5) - - with self.subTest('Check by Edge class.'): - # Test edge 1. - self.assertTrue(self.test_graph.check_if_edge_in_graph(edge_1)) - - # Test edge 2. - self.assertTrue(self.test_graph.check_if_edge_in_graph(edge_2)) - - # Test edge 3. - self.assertFalse(self.test_graph.check_if_edge_in_graph(edge_3)) - - with self.subTest('Check by Edge name.'): - # Test edge 1. - self.assertTrue(self.test_graph.check_if_edge_in_graph(edge_1.get_name())) - - # Test edge 2. - self.assertTrue(self.test_graph.check_if_edge_in_graph(edge_2.get_name())) - - # Test edge 3. - self.assertFalse(self.test_graph.check_if_edge_in_graph(edge_3.get_name())) - - def test__check_if_edge_in_graph__failure(self): - with self.subTest('Arg is None'): - with self.assertRaises(AttributeError): - self.test_graph.check_if_edge_in_graph(None) - - def test__get_edge__success(self): - # Create and connect nodes. - node_1 = self.test_graph.create_node() - node_2 = self.test_graph.create_node() - node_3 = self.test_graph.create_node() - edge_1 = self.test_graph.connect_nodes(node_1, node_2) - edge_2 = self.test_graph.connect_nodes(node_1, node_3) - - with self.subTest('By Edge class.'): - # Test first edge. - self.assertEqual(self.test_graph.get_edge(edge_1), edge_1) - - # Test second edge. - self.assertEqual(self.test_graph.get_edge(edge_2), edge_2) - - with self.subTest('By Edge name.'): - # Test first edge. - self.assertEqual(self.test_graph.get_edge(edge_1.get_name()), edge_1) - - # Test second edge. - self.assertEqual(self.test_graph.get_edge(edge_2.get_name()), edge_2) - - def test__get_edge__failure(self): - with self.subTest('Arg is None.'): - with self.assertRaises(AttributeError): - self.test_graph.get_edge(None) - - with self.subTest('Edge is not in graph - By Edge class.'): - edge_1 = BasicEdge(self.test_graph._get_edge_auto_name()) - with self.assertLogs(level='WARNING'): - self.assertIsNone(self.test_graph.get_edge(edge_1)) - - with self.subTest('Edge is not in graph - By Edge name.'): - with self.assertLogs(level='WARNING'): - self.assertIsNone(self.test_graph.get_edge('Test')) - - def test__get_nodes_connected_to_edge__success(self): - with self.subTest('By Edge class.'): - # Create and connect nodes. - node_1 = self.test_graph.create_node() - node_2 = self.test_graph.create_node() - edge_1 = self.test_graph.connect_nodes(node_1, node_2) - - # Test function. - self.assertEqual(self.test_graph.get_nodes_connected_to_edge(edge_1), (node_1, node_2)) - with self.subTest('By Edge name.'): - # Create and connect nodes. - node_1 = self.test_graph.create_node() - node_2 = self.test_graph.create_node() - edge_1 = self.test_graph.connect_nodes(node_1, node_2) - - # Test function. - self.assertEqual(self.test_graph.get_nodes_connected_to_edge(edge_1.get_name()), (node_1, node_2)) - - def test__get_nodes_connected_to_edge__failure(self): - with self.subTest('Arg is None.'): - with self.assertRaises(AttributeError): - self.test_graph.get_nodes_connected_to_edge(None) - - with self.subTest('Edge is not in graph - By edge class.'): - edge_1 = BasicEdge(self.test_graph._get_edge_auto_name()) - with self.assertLogs(level='WARNING'): - self.assertIsNone(self.test_graph.get_nodes_connected_to_edge(edge_1)) - - with self.subTest('Edge is not in graph - By edge name.'): - with self.assertLogs(level='WARNING'): - self.assertIsNone(self.test_graph.get_nodes_connected_to_edge('Test')) - - #endregion Edge Information Function Tests - #region Node Upkeep Function Tests - def test__create_node(self): + def test__create(self): with self.subTest('With automatic node names.'): # Verify start state. - self.assertEqual(self.test_graph.get_node_count(), 0) + self.assertEqual(self.test_graph.nodes.count(), 0) self.assertEqual(self.test_graph._nodes, {}) self.assertEqual(len(self.test_graph._nodes), 0) # Test with no nodes. - node_1 = self.test_graph.create_node() + node_1 = self.test_graph.nodes.create() self.assertTrue(isinstance(node_1, BasicNode)) self.assertEqual(node_1._graph, self.test_graph) - self.assertEqual(self.test_graph.get_node_count(), 1) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.assertEqual(self.test_graph.nodes.count(), 1) + self.assertEqual(self.test_graph.nodes.all(), { node_1.get_name(): node_1, }) self.assertEqual(node_1.get_name(), '1') # Test with one node. - node_2 = self.test_graph.create_node() + node_2 = self.test_graph.nodes.create() self.assertTrue(isinstance(node_2, BasicNode)) self.assertEqual(node_2._graph, self.test_graph) - self.assertEqual(self.test_graph.get_node_count(), 2) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.assertEqual(self.test_graph.nodes.count(), 2) + self.assertEqual(self.test_graph.nodes.all(), { node_1.get_name(): node_1, node_2.get_name(): node_2, }) self.assertEqual(node_2.get_name(), '2') # Test with two nodes. - node_3 = self.test_graph.create_node() + node_3 = self.test_graph.nodes.create() self.assertTrue(isinstance(node_3, BasicNode)) self.assertEqual(node_3._graph, self.test_graph) - self.assertEqual(self.test_graph.get_node_count(), 3) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.assertEqual(self.test_graph.nodes.count(), 3) + self.assertEqual(self.test_graph.nodes.all(), { node_1.get_name(): node_1, node_2.get_name(): node_2, node_3.get_name(): node_3, @@ -652,45 +506,45 @@ class TestBasicGraph(unittest.TestCase): # Works with 0, 1, and 2 nodes. Assuming works with all further n nodes. # Reset for next subtest. - self.test_graph.remove_node(node_1) - self.test_graph.remove_node(node_2) - self.test_graph.remove_node(node_3) + self.test_graph.nodes.remove(node_1) + self.test_graph.nodes.remove(node_2) + self.test_graph.nodes.remove(node_3) self.test_graph._edge_name_auto_counter = 0 self.test_graph._node_name_auto_counter = 0 with self.subTest('With manual node names.'): # Verify start state. - self.assertEqual(self.test_graph.get_node_count(), 0) + self.assertEqual(self.test_graph.nodes.count(), 0) self.assertEqual(self.test_graph._nodes, {}) self.assertEqual(len(self.test_graph._nodes), 0) # Test with no nodes. - node_1 = self.test_graph.create_node(node_name='Node 1') + node_1 = self.test_graph.nodes.create(node_name='Node 1') self.assertTrue(isinstance(node_1, BasicNode)) self.assertEqual(node_1._graph, self.test_graph) - self.assertEqual(self.test_graph.get_node_count(), 1) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.assertEqual(self.test_graph.nodes.count(), 1) + self.assertEqual(self.test_graph.nodes.all(), { node_1.get_name(): node_1, }) self.assertEqual(node_1.get_name(), 'Node 1') # Test with one node. - node_2 = self.test_graph.create_node(node_name='Node 2') + node_2 = self.test_graph.nodes.create(node_name='Node 2') self.assertTrue(isinstance(node_2, BasicNode)) self.assertEqual(node_2._graph, self.test_graph) - self.assertEqual(self.test_graph.get_node_count(), 2) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.assertEqual(self.test_graph.nodes.count(), 2) + self.assertEqual(self.test_graph.nodes.all(), { node_1.get_name(): node_1, node_2.get_name(): node_2, }) self.assertEqual(node_2.get_name(), 'Node 2') # Test with two nodes. - node_3 = self.test_graph.create_node(node_name='Node 3') + node_3 = self.test_graph.nodes.create(node_name='Node 3') self.assertTrue(isinstance(node_3, BasicNode)) self.assertEqual(node_3._graph, self.test_graph) - self.assertEqual(self.test_graph.get_node_count(), 3) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.assertEqual(self.test_graph.nodes.count(), 3) + self.assertEqual(self.test_graph.nodes.all(), { node_1.get_name(): node_1, node_2.get_name(): node_2, node_3.get_name(): node_3, @@ -699,7 +553,7 @@ class TestBasicGraph(unittest.TestCase): # Works with 0, 1, and 2 nodes. Assuming works with all further n nodes. - def test__add_node__success(self): + def test__add__success(self): with self.subTest('With basic, unconnected nodes.'): # Create nodes to connect. node_1 = BasicNode(self.test_graph._get_node_auto_name()) @@ -707,34 +561,34 @@ class TestBasicGraph(unittest.TestCase): node_3 = BasicNode(self.test_graph._get_node_auto_name()) # Verify start state. - self.assertEqual(self.test_graph.get_node_count(), 0) - self.assertEqual(self.test_graph.get_all_nodes(), {}) + self.assertEqual(self.test_graph.nodes.count(), 0) + self.assertEqual(self.test_graph.nodes.all(), {}) self.assertIsNone(node_1._graph) self.assertIsNone(node_2._graph) self.assertIsNone(node_3._graph) # Test with no nodes. - self.test_graph.add_node(node_1) + self.test_graph.nodes.add(node_1) self.assertEqual(node_1._graph, self.test_graph) - self.assertEqual(self.test_graph.get_node_count(), 1) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.assertEqual(self.test_graph.nodes.count(), 1) + self.assertEqual(self.test_graph.nodes.all(), { node_1.get_name(): node_1, }) # Test with one node. - self.test_graph.add_node(node_2) + self.test_graph.nodes.add(node_2) self.assertEqual(node_2._graph, self.test_graph) - self.assertEqual(self.test_graph.get_node_count(), 2) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.assertEqual(self.test_graph.nodes.count(), 2) + self.assertEqual(self.test_graph.nodes.all(), { node_1.get_name(): node_1, node_2.get_name(): node_2, }) # Test with two nodes. - self.test_graph.add_node(node_3) + self.test_graph.nodes.add(node_3) self.assertEqual(node_3._graph, self.test_graph) - self.assertEqual(self.test_graph.get_node_count(), 3) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.assertEqual(self.test_graph.nodes.count(), 3) + self.assertEqual(self.test_graph.nodes.all(), { node_1.get_name(): node_1, node_2.get_name(): node_2, node_3.get_name(): node_3, @@ -743,9 +597,9 @@ class TestBasicGraph(unittest.TestCase): # Works with 0, 1, and 2 nodes. Assuming works with all further n nodes. # Reset graph for next subtest. - self.test_graph.remove_node(node_1) - self.test_graph.remove_node(node_2) - self.test_graph.remove_node(node_3) + self.test_graph.nodes.remove(node_1) + self.test_graph.nodes.remove(node_2) + self.test_graph.nodes.remove(node_3) with self.subTest('With interconnected nodes - None in graph.'): # Create nodes to connect. @@ -768,44 +622,44 @@ class TestBasicGraph(unittest.TestCase): edge_6 = node_6.connect_node(node_9) # Verify start state. - self.assertEqual(self.test_graph.get_node_count(), 0) - self.assertEqual(self.test_graph.get_all_nodes(), {}) - self.assertEqual(self.test_graph.get_edge_count(), 0) - self.assertEqual(self.test_graph.get_all_edges(), {}) + self.assertEqual(self.test_graph.nodes.count(), 0) + self.assertEqual(self.test_graph.nodes.all(), {}) + self.assertEqual(self.test_graph.edges.count(), 0) + self.assertEqual(self.test_graph.edges.all(), {}) # Test adding a node with 1 pre-existing connection. - self.test_graph.add_node(node_1) - self.assertEqual(self.test_graph.get_node_count(), 2) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.test_graph.nodes.add(node_1) + self.assertEqual(self.test_graph.nodes.count(), 2) + self.assertEqual(self.test_graph.nodes.all(), { node_1.get_name(): node_1, node_2.get_name(): node_2, }) - self.assertEqual(self.test_graph.get_edge_count(), 1) - self.assertEqual(self.test_graph.get_all_edges(), { + self.assertEqual(self.test_graph.edges.count(), 1) + self.assertEqual(self.test_graph.edges.all(), { edge_1.get_name(): edge_1, }) # Test adding a node with 2 pre-existing connections. - self.test_graph.add_node(node_3) - self.assertEqual(self.test_graph.get_node_count(), 5) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.test_graph.nodes.add(node_3) + self.assertEqual(self.test_graph.nodes.count(), 5) + self.assertEqual(self.test_graph.nodes.all(), { node_1.get_name(): node_1, node_2.get_name(): node_2, node_3.get_name(): node_3, node_4.get_name(): node_4, node_5.get_name(): node_5, }) - self.assertEqual(self.test_graph.get_edge_count(), 3) - self.assertEqual(self.test_graph.get_all_edges(), { + self.assertEqual(self.test_graph.edges.count(), 3) + self.assertEqual(self.test_graph.edges.all(), { edge_1.get_name(): edge_1, edge_2.get_name(): edge_2, edge_3.get_name(): edge_3, }) # Test adding a node with 3 pre-existing connections. - self.test_graph.add_node(node_6) - self.assertEqual(self.test_graph.get_node_count(), 9) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.test_graph.nodes.add(node_6) + self.assertEqual(self.test_graph.nodes.count(), 9) + self.assertEqual(self.test_graph.nodes.all(), { node_1.get_name(): node_1, node_2.get_name(): node_2, node_3.get_name(): node_3, @@ -816,8 +670,8 @@ class TestBasicGraph(unittest.TestCase): node_8.get_name(): node_8, node_9.get_name(): node_9, }) - self.assertEqual(self.test_graph.get_edge_count(), 6) - self.assertEqual(self.test_graph.get_all_edges(), { + self.assertEqual(self.test_graph.edges.count(), 6) + self.assertEqual(self.test_graph.edges.all(), { edge_1.get_name(): edge_1, edge_2.get_name(): edge_2, edge_3.get_name(): edge_3, @@ -830,15 +684,15 @@ class TestBasicGraph(unittest.TestCase): # Assuming works with all further n pre-existing connections. # Reset graph for next subtest. - self.test_graph.remove_node(node_1) - self.test_graph.remove_node(node_2) - self.test_graph.remove_node(node_3) - self.test_graph.remove_node(node_4) - self.test_graph.remove_node(node_5) - self.test_graph.remove_node(node_6) - self.test_graph.remove_node(node_7) - self.test_graph.remove_node(node_8) - self.test_graph.remove_node(node_9) + self.test_graph.nodes.remove(node_1) + self.test_graph.nodes.remove(node_2) + self.test_graph.nodes.remove(node_3) + self.test_graph.nodes.remove(node_4) + self.test_graph.nodes.remove(node_5) + self.test_graph.nodes.remove(node_6) + self.test_graph.nodes.remove(node_7) + self.test_graph.nodes.remove(node_8) + self.test_graph.nodes.remove(node_9) with self.subTest('With interconnected nodes - Some nodes in graph.'): # NOTE: If the graph functions are used, then this case should never happen in practice. @@ -846,14 +700,14 @@ class TestBasicGraph(unittest.TestCase): # Create nodes to connect. node_1 = BasicNode(self.test_graph._get_node_auto_name()) - node_2 = self.test_graph.create_node() + node_2 = self.test_graph.nodes.create() node_3 = BasicNode(self.test_graph._get_node_auto_name()) - node_4 = self.test_graph.create_node() + node_4 = self.test_graph.nodes.create() node_5 = BasicNode(self.test_graph._get_node_auto_name()) node_6 = BasicNode(self.test_graph._get_node_auto_name()) - node_7 = self.test_graph.create_node() + node_7 = self.test_graph.nodes.create() node_8 = BasicNode(self.test_graph._get_node_auto_name()) - node_9 = self.test_graph.create_node() + node_9 = self.test_graph.nodes.create() # Connect nodes. edge_1 = node_1.connect_node(node_2) @@ -864,35 +718,35 @@ class TestBasicGraph(unittest.TestCase): edge_6 = node_6.connect_node(node_9) # Verify start state. - self.assertEqual(self.test_graph.get_node_count(), 4) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.assertEqual(self.test_graph.nodes.count(), 4) + self.assertEqual(self.test_graph.nodes.all(), { node_2.get_name(): node_2, node_4.get_name(): node_4, node_7.get_name(): node_7, node_9.get_name(): node_9, }) - self.assertEqual(self.test_graph.get_edge_count(), 0) - self.assertEqual(self.test_graph.get_all_edges(), {}) + self.assertEqual(self.test_graph.edges.count(), 0) + self.assertEqual(self.test_graph.edges.all(), {}) # Test adding a node with 1 pre-existing connection. - self.test_graph.add_node(node_1) - self.assertEqual(self.test_graph.get_node_count(), 5) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.test_graph.nodes.add(node_1) + self.assertEqual(self.test_graph.nodes.count(), 5) + self.assertEqual(self.test_graph.nodes.all(), { node_1.get_name(): node_1, node_2.get_name(): node_2, node_4.get_name(): node_4, node_7.get_name(): node_7, node_9.get_name(): node_9, }) - self.assertEqual(self.test_graph.get_edge_count(), 1) - self.assertEqual(self.test_graph.get_all_edges(), { + self.assertEqual(self.test_graph.edges.count(), 1) + self.assertEqual(self.test_graph.edges.all(), { edge_1.get_name(): edge_1, }) # Test adding a node with 2 pre-existing connections. - self.test_graph.add_node(node_3) - self.assertEqual(self.test_graph.get_node_count(), 7) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.test_graph.nodes.add(node_3) + self.assertEqual(self.test_graph.nodes.count(), 7) + self.assertEqual(self.test_graph.nodes.all(), { node_1.get_name(): node_1, node_2.get_name(): node_2, node_3.get_name(): node_3, @@ -901,17 +755,17 @@ class TestBasicGraph(unittest.TestCase): node_7.get_name(): node_7, node_9.get_name(): node_9, }) - self.assertEqual(self.test_graph.get_edge_count(), 3) - self.assertEqual(self.test_graph.get_all_edges(), { + self.assertEqual(self.test_graph.edges.count(), 3) + self.assertEqual(self.test_graph.edges.all(), { edge_1.get_name(): edge_1, edge_2.get_name(): edge_2, edge_3.get_name(): edge_3, }) # Test adding a node with 3 pre-existing connections. - self.test_graph.add_node(node_6) - self.assertEqual(self.test_graph.get_node_count(), 9) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.test_graph.nodes.add(node_6) + self.assertEqual(self.test_graph.nodes.count(), 9) + self.assertEqual(self.test_graph.nodes.all(), { node_1.get_name(): node_1, node_2.get_name(): node_2, node_3.get_name(): node_3, @@ -922,8 +776,8 @@ class TestBasicGraph(unittest.TestCase): node_8.get_name(): node_8, node_9.get_name(): node_9, }) - self.assertEqual(self.test_graph.get_edge_count(), 6) - self.assertEqual(self.test_graph.get_all_edges(), { + self.assertEqual(self.test_graph.edges.count(), 6) + self.assertEqual(self.test_graph.edges.all(), { edge_1.get_name(): edge_1, edge_2.get_name(): edge_2, edge_3.get_name(): edge_3, @@ -932,28 +786,28 @@ class TestBasicGraph(unittest.TestCase): edge_6.get_name(): edge_6, }) - def test__add_node__failure(self): + def test__add__failure(self): with self.subTest('Arg is not of type Node.'): with self.assertRaises(TypeError): - self.test_graph.add_node(1234) + self.test_graph.nodes.add(1234) # Add node to graph for following subtests. new_node = BasicNode(self.test_graph._get_node_auto_name()) - self.assertEqual(self.test_graph.get_node_count(), 0) + self.assertEqual(self.test_graph.nodes.count(), 0) # Add initial node. - self.test_graph.add_node(new_node) + self.test_graph.nodes.add(new_node) with self.subTest('Node already exists within graph.'): # Verify start state. - self.assertEqual(self.test_graph.get_node_count(), 1) + self.assertEqual(self.test_graph.nodes.count(), 1) with self.assertLogs(level='WARNING'): # Attempt to re-add same node. Verify that count did not change. - self.test_graph.add_node(new_node) - self.assertEqual(self.test_graph.get_node_count(), 1) + self.test_graph.nodes.add(new_node) + self.assertEqual(self.test_graph.nodes.count(), 1) - def test__add_node_list__success(self): + def test__add_list__success(self): # Create nodes to add. node_1 = BasicNode(self.test_graph._get_node_auto_name()) node_2 = BasicNode(self.test_graph._get_node_auto_name()) @@ -969,29 +823,29 @@ class TestBasicGraph(unittest.TestCase): list_3 = [node_4, node_5, node_6] # Verify start state. - self.assertEqual(self.test_graph.get_node_count(), 0) - self.assertEqual(self.test_graph.get_all_nodes(), {}) + self.assertEqual(self.test_graph.nodes.count(), 0) + self.assertEqual(self.test_graph.nodes.all(), {}) # Test adding a list of 1 item. - self.test_graph.add_node_list(list_1) - self.assertEqual(self.test_graph.get_node_count(), 1) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.test_graph.nodes.add_list(list_1) + self.assertEqual(self.test_graph.nodes.count(), 1) + self.assertEqual(self.test_graph.nodes.all(), { node_1.get_name(): node_1, }) # Test adding a list of 2 items. - self.test_graph.add_node_list(list_2) - self.assertEqual(self.test_graph.get_node_count(), 3) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.test_graph.nodes.add_list(list_2) + self.assertEqual(self.test_graph.nodes.count(), 3) + self.assertEqual(self.test_graph.nodes.all(), { node_1.get_name(): node_1, node_2.get_name(): node_2, node_3.get_name(): node_3, }) # Test adding a list of 3 items. - self.test_graph.add_node_list(list_3) - self.assertEqual(self.test_graph.get_node_count(), 6) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.test_graph.nodes.add_list(list_3) + self.assertEqual(self.test_graph.nodes.count(), 6) + self.assertEqual(self.test_graph.nodes.all(), { node_1.get_name(): node_1, node_2.get_name(): node_2, node_3.get_name(): node_3, @@ -1003,12 +857,12 @@ class TestBasicGraph(unittest.TestCase): # Works with lists of size 1, 2, and 3s. Assuming works with all further n-sized lists. # Reset graph for next subtest. - self.test_graph.remove_node(node_1) - self.test_graph.remove_node(node_2) - self.test_graph.remove_node(node_3) - self.test_graph.remove_node(node_4) - self.test_graph.remove_node(node_5) - self.test_graph.remove_node(node_6) + self.test_graph.nodes.remove(node_1) + self.test_graph.nodes.remove(node_2) + self.test_graph.nodes.remove(node_3) + self.test_graph.nodes.remove(node_4) + self.test_graph.nodes.remove(node_5) + self.test_graph.nodes.remove(node_6) with self.subTest('List is tuple type.'): # Create tuples. @@ -1017,29 +871,29 @@ class TestBasicGraph(unittest.TestCase): list_3 = (node_4, node_5, node_6,) # Verify start state. - self.assertEqual(self.test_graph.get_node_count(), 0) - self.assertEqual(self.test_graph.get_all_nodes(), {}) + self.assertEqual(self.test_graph.nodes.count(), 0) + self.assertEqual(self.test_graph.nodes.all(), {}) # Test adding a list of 1 item. - self.test_graph.add_node_list(list_1) - self.assertEqual(self.test_graph.get_node_count(), 1) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.test_graph.nodes.add_list(list_1) + self.assertEqual(self.test_graph.nodes.count(), 1) + self.assertEqual(self.test_graph.nodes.all(), { node_1.get_name(): node_1, }) # Test adding a list of 2 items. - self.test_graph.add_node_list(list_2) - self.assertEqual(self.test_graph.get_node_count(), 3) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.test_graph.nodes.add_list(list_2) + self.assertEqual(self.test_graph.nodes.count(), 3) + self.assertEqual(self.test_graph.nodes.all(), { node_1.get_name(): node_1, node_2.get_name(): node_2, node_3.get_name(): node_3, }) # Test adding a list of 3 items. - self.test_graph.add_node_list(list_3) - self.assertEqual(self.test_graph.get_node_count(), 6) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.test_graph.nodes.add_list(list_3) + self.assertEqual(self.test_graph.nodes.count(), 6) + self.assertEqual(self.test_graph.nodes.all(), { node_1.get_name(): node_1, node_2.get_name(): node_2, node_3.get_name(): node_3, @@ -1051,12 +905,12 @@ class TestBasicGraph(unittest.TestCase): # Works with lists of size 1, 2, and 3s. Assuming works with all further n-sized lists. # Reset graph for next subtest. - self.test_graph.remove_node(node_1) - self.test_graph.remove_node(node_2) - self.test_graph.remove_node(node_3) - self.test_graph.remove_node(node_4) - self.test_graph.remove_node(node_5) - self.test_graph.remove_node(node_6) + self.test_graph.nodes.remove(node_1) + self.test_graph.nodes.remove(node_2) + self.test_graph.nodes.remove(node_3) + self.test_graph.nodes.remove(node_4) + self.test_graph.nodes.remove(node_5) + self.test_graph.nodes.remove(node_6) with self.subTest('List is dict type.'): # Create dictionaries. @@ -1065,29 +919,29 @@ class TestBasicGraph(unittest.TestCase): list_3 = {node_4.get_name(): node_4, node_5.get_name(): node_5, node_6.get_name(): node_6} # Verify start state. - self.assertEqual(self.test_graph.get_node_count(), 0) - self.assertEqual(self.test_graph.get_all_nodes(), {}) + self.assertEqual(self.test_graph.nodes.count(), 0) + self.assertEqual(self.test_graph.nodes.all(), {}) # Test adding a list of 1 item. - self.test_graph.add_node_list(list_1) - self.assertEqual(self.test_graph.get_node_count(), 1) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.test_graph.nodes.add_list(list_1) + self.assertEqual(self.test_graph.nodes.count(), 1) + self.assertEqual(self.test_graph.nodes.all(), { node_1.get_name(): node_1, }) # Test adding a list of 2 items. - self.test_graph.add_node_list(list_2) - self.assertEqual(self.test_graph.get_node_count(), 3) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.test_graph.nodes.add_list(list_2) + self.assertEqual(self.test_graph.nodes.count(), 3) + self.assertEqual(self.test_graph.nodes.all(), { node_1.get_name(): node_1, node_2.get_name(): node_2, node_3.get_name(): node_3, }) # Test adding a list of 3 items. - self.test_graph.add_node_list(list_3) - self.assertEqual(self.test_graph.get_node_count(), 6) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.test_graph.nodes.add_list(list_3) + self.assertEqual(self.test_graph.nodes.count(), 6) + self.assertEqual(self.test_graph.nodes.all(), { node_1.get_name(): node_1, node_2.get_name(): node_2, node_3.get_name(): node_3, @@ -1099,88 +953,88 @@ class TestBasicGraph(unittest.TestCase): # Works with lists of size 1, 2, and 3s. Assuming works with all further n-sized lists. # Reset graph for next subtest. - self.test_graph.remove_node(node_1) - self.test_graph.remove_node(node_2) - self.test_graph.remove_node(node_3) - self.test_graph.remove_node(node_4) - self.test_graph.remove_node(node_5) - self.test_graph.remove_node(node_6) - - def test__add_node_list__failure(self): + self.test_graph.nodes.remove(node_1) + self.test_graph.nodes.remove(node_2) + self.test_graph.nodes.remove(node_3) + self.test_graph.nodes.remove(node_4) + self.test_graph.nodes.remove(node_5) + self.test_graph.nodes.remove(node_6) + + def test__add_list__failure(self): node_1 = BasicNode(self.test_graph._get_node_auto_name()) with self.subTest('Arg is not of type list, tuple, or dict.'): with self.assertRaises(TypeError): - self.test_graph.add_node_list(1234) + self.test_graph.nodes.add_list(1234) with self.subTest('At least one item in list is None'): # Verify starting node count. - self.assertEqual(self.test_graph.get_node_count(), 0) + self.assertEqual(self.test_graph.nodes.count(), 0) # Test None is only item in list. with self.assertRaises(AttributeError): - self.test_graph.add_node_list([None]) + self.test_graph.nodes.add_list([None]) # Test None is first item in list. with self.assertRaises(AttributeError): - self.test_graph.add_node_list([None, node_1]) + self.test_graph.nodes.add_list([None, node_1]) # Test None is last item in list. with self.assertRaises(AttributeError): - self.test_graph.add_node_list([node_1, None]) + self.test_graph.nodes.add_list([node_1, None]) # Verify node count did not change. - self.assertEqual(self.test_graph.get_node_count(), 0) + self.assertEqual(self.test_graph.nodes.count(), 0) with self.subTest('At least one item in list is already in graph - by Node class.'): - node_2 = self.test_graph.create_node() + node_2 = self.test_graph.nodes.create() # Verify starting node count. - self.assertEqual(self.test_graph.get_node_count(), 1) + self.assertEqual(self.test_graph.nodes.count(), 1) # Test existing node is only item in list. with self.assertRaises(ValueError): - self.test_graph.add_node_list([node_2]) + self.test_graph.nodes.add_list([node_2]) # Test existing node is first item in list. with self.assertRaises(ValueError): - self.test_graph.add_node_list([node_2, node_1]) + self.test_graph.nodes.add_list([node_2, node_1]) # Test existing node is last item in list. with self.assertRaises(ValueError): - self.test_graph.add_node_list([node_1, node_2]) + self.test_graph.nodes.add_list([node_1, node_2]) # Verify node count did not change. - self.assertEqual(self.test_graph.get_node_count(), 1) + self.assertEqual(self.test_graph.nodes.count(), 1) with self.subTest('At least one item in list is already in graph - by Node name.'): # Verify starting node count. - self.assertEqual(self.test_graph.get_node_count(), 1) + self.assertEqual(self.test_graph.nodes.count(), 1) # Test existing node is only item in list. with self.assertRaises(ValueError): - self.test_graph.add_node_list([node_2.get_name()]) + self.test_graph.nodes.add_list([node_2.get_name()]) # Test existing node is first item in list. with self.assertRaises(ValueError): - self.test_graph.add_node_list([node_2.get_name(), node_1.get_name()]) + self.test_graph.nodes.add_list([node_2.get_name(), node_1.get_name()]) # Test existing node is last item in list. with self.assertRaises(ValueError): - self.test_graph.add_node_list([node_1.get_name(), node_2.get_name()]) + self.test_graph.nodes.add_list([node_1.get_name(), node_2.get_name()]) # Verify node count did not change. - self.assertEqual(self.test_graph.get_node_count(), 1) + self.assertEqual(self.test_graph.nodes.count(), 1) - def test__remove_node__success(self): + def test__remove__success(self): with self.subTest('With basic, unconnected nodes.'): # Create nodes. - node_1 = self.test_graph.create_node() - node_2 = self.test_graph.create_node() - node_3 = self.test_graph.create_node() + node_1 = self.test_graph.nodes.create() + node_2 = self.test_graph.nodes.create() + node_3 = self.test_graph.nodes.create() # Verify start state. - self.assertEqual(self.test_graph.get_node_count(), 3) + self.assertEqual(self.test_graph.nodes.count(), 3) self.assertEqual(self.test_graph._nodes, { node_1.get_name(): node_1, node_2.get_name(): node_2, @@ -1188,55 +1042,55 @@ class TestBasicGraph(unittest.TestCase): }) # Test removal with 3 nodes. - removed_node_1 = self.test_graph.remove_node(node_3) + removed_node_1 = self.test_graph.nodes.remove(node_3) self.assertEqual(node_3, removed_node_1) - self.assertEqual(self.test_graph.get_node_count(), 2) + self.assertEqual(self.test_graph.nodes.count(), 2) self.assertEqual(self.test_graph._nodes, { node_1.get_name(): node_1, node_2.get_name(): node_2, }) # Test removal with 2 nodes. - removed_node_2 = self.test_graph.remove_node(node_2) + removed_node_2 = self.test_graph.nodes.remove(node_2) self.assertEqual(node_2, removed_node_2) - self.assertEqual(self.test_graph.get_node_count(), 1) + self.assertEqual(self.test_graph.nodes.count(), 1) self.assertEqual(self.test_graph._nodes, { node_1.get_name(): node_1, }) # Test removal with 1 node. - removed_node_3 = self.test_graph.remove_node(node_1) + removed_node_3 = self.test_graph.nodes.remove(node_1) self.assertEqual(node_1, removed_node_3) - self.assertEqual(self.test_graph.get_node_count(), 0) + self.assertEqual(self.test_graph.nodes.count(), 0) self.assertEqual(self.test_graph._nodes, {}) # Works with 1, 2, and 3 nodes. Assuming works with all further n nodes. with self.subTest('With interconnected nodes.'): # Create nodes. - node_1 = self.test_graph.create_node() - node_2 = self.test_graph.create_node() - node_3 = self.test_graph.create_node() - node_4 = self.test_graph.create_node() + node_1 = self.test_graph.nodes.create() + node_2 = self.test_graph.nodes.create() + node_3 = self.test_graph.nodes.create() + node_4 = self.test_graph.nodes.create() # Create connections. - edge_1 = self.test_graph.connect_nodes(node_1, node_2) - edge_2 = self.test_graph.connect_nodes(node_1, node_3) - edge_3 = self.test_graph.connect_nodes(node_1, node_4) - edge_4 = self.test_graph.connect_nodes(node_2, node_3) - edge_5 = self.test_graph.connect_nodes(node_2, node_4) - edge_6 = self.test_graph.connect_nodes(node_3, node_4) + edge_1 = self.test_graph.nodes.connect(node_1, node_2) + edge_2 = self.test_graph.nodes.connect(node_1, node_3) + edge_3 = self.test_graph.nodes.connect(node_1, node_4) + edge_4 = self.test_graph.nodes.connect(node_2, node_3) + edge_5 = self.test_graph.nodes.connect(node_2, node_4) + edge_6 = self.test_graph.nodes.connect(node_3, node_4) # Verify start state. - self.assertEqual(self.test_graph.get_node_count(), 4) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.assertEqual(self.test_graph.nodes.count(), 4) + self.assertEqual(self.test_graph.nodes.all(), { node_1.get_name(): node_1, node_2.get_name(): node_2, node_3.get_name(): node_3, node_4.get_name(): node_4, }) - self.assertEqual(self.test_graph.get_edge_count(), 6) - self.assertEqual(self.test_graph.get_all_edges(), { + self.assertEqual(self.test_graph.edges.count(), 6) + self.assertEqual(self.test_graph.edges.all(), { edge_1.get_name(): edge_1, edge_2.get_name(): edge_2, edge_3.get_name(): edge_3, @@ -1254,15 +1108,15 @@ class TestBasicGraph(unittest.TestCase): self.assertEqual(node_4.get_connected_node_count(), 3) # Test removal when node has 3 connections. - self.test_graph.remove_node(node_1) - self.assertEqual(self.test_graph.get_node_count(), 3) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.test_graph.nodes.remove(node_1) + self.assertEqual(self.test_graph.nodes.count(), 3) + self.assertEqual(self.test_graph.nodes.all(), { node_2.get_name(): node_2, node_3.get_name(): node_3, node_4.get_name(): node_4, }) - self.assertEqual(self.test_graph.get_edge_count(), 3) - self.assertEqual(self.test_graph.get_all_edges(), { + self.assertEqual(self.test_graph.edges.count(), 3) + self.assertEqual(self.test_graph.edges.all(), { edge_4.get_name(): edge_4, edge_5.get_name(): edge_5, edge_6.get_name(): edge_6, @@ -1277,14 +1131,14 @@ class TestBasicGraph(unittest.TestCase): self.assertEqual(node_4.get_connected_node_count(), 2) # Test removal when node has 2 connections. - self.test_graph.remove_node(node_2) - self.assertEqual(self.test_graph.get_node_count(), 2) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.test_graph.nodes.remove(node_2) + self.assertEqual(self.test_graph.nodes.count(), 2) + self.assertEqual(self.test_graph.nodes.all(), { node_3.get_name(): node_3, node_4.get_name(): node_4, }) - self.assertEqual(self.test_graph.get_edge_count(), 1) - self.assertEqual(self.test_graph.get_all_edges(), { + self.assertEqual(self.test_graph.edges.count(), 1) + self.assertEqual(self.test_graph.edges.all(), { edge_6.get_name(): edge_6, }) self.assertEqual(node_1.get_edge_count(), 0) @@ -1297,13 +1151,13 @@ class TestBasicGraph(unittest.TestCase): self.assertEqual(node_4.get_connected_node_count(), 1) # Test removal when node has 1 connections. - self.test_graph.remove_node(node_3) - self.assertEqual(self.test_graph.get_node_count(), 1) - self.assertEqual(self.test_graph.get_all_nodes(), { + self.test_graph.nodes.remove(node_3) + self.assertEqual(self.test_graph.nodes.count(), 1) + self.assertEqual(self.test_graph.nodes.all(), { node_4.get_name(): node_4, }) - self.assertEqual(self.test_graph.get_edge_count(), 0) - self.assertEqual(self.test_graph.get_all_edges(), {}) + self.assertEqual(self.test_graph.edges.count(), 0) + self.assertEqual(self.test_graph.edges.all(), {}) self.assertEqual(node_1.get_edge_count(), 0) self.assertEqual(node_2.get_edge_count(), 0) self.assertEqual(node_3.get_edge_count(), 0) @@ -1314,11 +1168,11 @@ class TestBasicGraph(unittest.TestCase): self.assertEqual(node_4.get_connected_node_count(), 0) # Test removal when node has 0 connections. - self.test_graph.remove_node(node_4) - self.assertEqual(self.test_graph.get_node_count(), 0) - self.assertEqual(self.test_graph.get_all_nodes(), {}) - self.assertEqual(self.test_graph.get_edge_count(), 0) - self.assertEqual(self.test_graph.get_all_edges(), {}) + self.test_graph.nodes.remove(node_4) + self.assertEqual(self.test_graph.nodes.count(), 0) + self.assertEqual(self.test_graph.nodes.all(), {}) + self.assertEqual(self.test_graph.edges.count(), 0) + self.assertEqual(self.test_graph.edges.all(), {}) self.assertEqual(node_1.get_edge_count(), 0) self.assertEqual(node_2.get_edge_count(), 0) self.assertEqual(node_3.get_edge_count(), 0) @@ -1330,30 +1184,186 @@ class TestBasicGraph(unittest.TestCase): # Works with 0, 1, 2, and 3 node connections. Assuming works with all further n node connections. - def test__remove_node__failure(self): + def test__remove__failure(self): with self.subTest('Arg is None'): with self.assertRaises(AttributeError): - self.test_graph.remove_node(None) + self.test_graph.nodes.remove(None) with self.subTest('Node is not in graph - by Node class.'): node_1 = BasicNode(self.test_graph._get_node_auto_name()) with self.assertLogs(level='WARNING'): - self.assertIsNone(self.test_graph.get_node(node_1)) + self.assertIsNone(self.test_graph.nodes.get(node_1)) with self.subTest('Node is not in graph - by Node name.'): with self.assertLogs(level='WARNING'): - self.assertIsNone(self.test_graph.get_node('Test')) + self.assertIsNone(self.test_graph.nodes.get('Test')) #endregion Node Upkeep Function Tests + +class TestBasicGraphEdges(unittest.TestCase): + def setUp(self): + self.test_graph = BasicGraph() + + #region Edge Information Function Tests + + def test__count(self): + # Create edges to add to graph. + edge_1 = BasicEdge(self.test_graph._get_node_auto_name()) + edge_2 = BasicEdge(self.test_graph._get_node_auto_name()) + + # Test with no edges. + self.assertEqual(self.test_graph.edges.count(), 0) + + # Test with one edges. + self.test_graph._edges[edge_1.get_name()] = edge_1 + self.assertEqual(self.test_graph.edges.count(), 1) + + # Test with two edges. + self.test_graph._edges[edge_2.get_name()] = edge_2 + self.assertEqual(self.test_graph.edges.count(), 2) + + # Works with 0, 1, and 2 edges. Assuming works with all further n edges. + + def test__all(self): + # Create edges to add to graph. + edge_1 = BasicEdge(self.test_graph._get_node_auto_name()) + edge_2 = BasicEdge(self.test_graph._get_node_auto_name()) + + # Test with no edges. + self.assertEqual(self.test_graph.edges.all(), {}) + + # Test with one edge. + self.test_graph._edges[edge_1.get_name()] = edge_1 + self.assertEqual(self.test_graph.edges.all(), { + edge_1.get_name(): edge_1, + }) + + # Test with two edges. + self.test_graph._edges[edge_2.get_name()] = edge_2 + self.assertEqual(self.test_graph.edges.all(), { + edge_1.get_name(): edge_1, + edge_2.get_name(): edge_2, + }) + + # Works with 0, 1, and 2 edges. Assuming works with all further n edges. + + def test__check_if_in_graph__success(self): + # Create nodes. + node_1 = self.test_graph.nodes.create() + node_2 = self.test_graph.nodes.create() + node_3 = self.test_graph.nodes.create() + node_4 = BasicNode('Node 4') + node_5 = BasicNode('Node 5') + + # Create connections. + edge_1 = self.test_graph.nodes.connect(node_1, node_2) + edge_2 = self.test_graph.nodes.connect(node_1, node_3) + edge_3 = node_4.connect_node(node_5) + + with self.subTest('Check by Edge class.'): + # Test edge 1. + self.assertTrue(self.test_graph.edges.check_if_in_graph(edge_1)) + + # Test edge 2. + self.assertTrue(self.test_graph.edges.check_if_in_graph(edge_2)) + + # Test edge 3. + self.assertFalse(self.test_graph.edges.check_if_in_graph(edge_3)) + + with self.subTest('Check by Edge name.'): + # Test edge 1. + self.assertTrue(self.test_graph.edges.check_if_in_graph(edge_1.get_name())) + + # Test edge 2. + self.assertTrue(self.test_graph.edges.check_if_in_graph(edge_2.get_name())) + + # Test edge 3. + self.assertFalse(self.test_graph.edges.check_if_in_graph(edge_3.get_name())) + + def test__check_if_in_graph__failure(self): + with self.subTest('Arg is None'): + with self.assertRaises(AttributeError): + self.test_graph.edges.check_if_in_graph(None) + + def test__get__success(self): + # Create and connect nodes. + node_1 = self.test_graph.nodes.create() + node_2 = self.test_graph.nodes.create() + node_3 = self.test_graph.nodes.create() + edge_1 = self.test_graph.nodes.connect(node_1, node_2) + edge_2 = self.test_graph.nodes.connect(node_1, node_3) + + with self.subTest('By Edge class.'): + # Test first edge. + self.assertEqual(self.test_graph.edges.get(edge_1), edge_1) + + # Test second edge. + self.assertEqual(self.test_graph.edges.get(edge_2), edge_2) + + with self.subTest('By Edge name.'): + # Test first edge. + self.assertEqual(self.test_graph.edges.get(edge_1.get_name()), edge_1) + + # Test second edge. + self.assertEqual(self.test_graph.edges.get(edge_2.get_name()), edge_2) + + def test__get__failure(self): + with self.subTest('Arg is None.'): + with self.assertRaises(AttributeError): + self.test_graph.edges.get(None) + + with self.subTest('Edge is not in graph - By Edge class.'): + edge_1 = BasicEdge(self.test_graph._get_edge_auto_name()) + with self.assertLogs(level='WARNING'): + self.assertIsNone(self.test_graph.edges.get(edge_1)) + + with self.subTest('Edge is not in graph - By Edge name.'): + with self.assertLogs(level='WARNING'): + self.assertIsNone(self.test_graph.edges.get('Test')) + + def test__node_connections_to_edge__success(self): + with self.subTest('By Edge class.'): + # Create and connect nodes. + node_1 = self.test_graph.nodes.create() + node_2 = self.test_graph.nodes.create() + edge_1 = self.test_graph.nodes.connect(node_1, node_2) + + # Test function. + self.assertEqual(self.test_graph.edges.node_connections_to_edge(edge_1), (node_1, node_2)) + with self.subTest('By Edge name.'): + # Create and connect nodes. + node_1 = self.test_graph.nodes.create() + node_2 = self.test_graph.nodes.create() + edge_1 = self.test_graph.nodes.connect(node_1, node_2) + + # Test function. + self.assertEqual(self.test_graph.edges.node_connections_to_edge(edge_1.get_name()), (node_1, node_2)) + + def test__node_connections_to_edge__failure(self): + with self.subTest('Arg is None.'): + with self.assertRaises(AttributeError): + self.test_graph.edges.node_connections_to_edge(None) + + with self.subTest('Edge is not in graph - By edge class.'): + edge_1 = BasicEdge(self.test_graph._get_edge_auto_name()) + with self.assertLogs(level='WARNING'): + self.assertIsNone(self.test_graph.edges.node_connections_to_edge(edge_1)) + + with self.subTest('Edge is not in graph - By edge name.'): + with self.assertLogs(level='WARNING'): + self.assertIsNone(self.test_graph.edges.node_connections_to_edge('Test')) + + # endregion Edge Information Function Tests + #region Edge Upkeep Function Tests - def test__connect_nodes(self): + def test__connect(self): # Create nodes to connect. - node_1 = self.test_graph.create_node() - node_2 = self.test_graph.create_node() - node_3 = self.test_graph.create_node() - node_4 = self.test_graph.create_node() + node_1 = self.test_graph.nodes.create() + node_2 = self.test_graph.nodes.create() + node_3 = self.test_graph.nodes.create() + node_4 = self.test_graph.nodes.create() # Check that all nodes start with 0 connections. self.assertEqual(node_1.get_edge_count(), 0) @@ -1362,7 +1372,7 @@ class TestBasicGraph(unittest.TestCase): self.assertEqual(node_4.get_edge_count(), 0) # Test with 0 connections. - edge_1 = self.test_graph.connect_nodes(node_1, node_2) + edge_1 = self.test_graph.nodes.connect(node_1, node_2) # Check node connection count. self.assertEqual(node_1.get_edge_count(), 1) self.assertEqual(node_2.get_edge_count(), 1) @@ -1375,7 +1385,7 @@ class TestBasicGraph(unittest.TestCase): self.assertEqual(connected_node_2, node_2) # Test with 1 connection. - edge_2 = self.test_graph.connect_nodes(node_1, node_3) + edge_2 = self.test_graph.nodes.connect(node_1, node_3) # Check node connection count. self.assertEqual(node_1.get_edge_count(), 2) self.assertEqual(node_2.get_edge_count(), 1) @@ -1388,7 +1398,7 @@ class TestBasicGraph(unittest.TestCase): self.assertEqual(connected_node_3, node_3) # Test with 2 connections. - edge_3 = self.test_graph.connect_nodes(node_1, node_4) + edge_3 = self.test_graph.nodes.connect(node_1, node_4) # Check node connection count. self.assertEqual(node_1.get_edge_count(), 3) self.assertEqual(node_2.get_edge_count(), 1) @@ -1402,22 +1412,22 @@ class TestBasicGraph(unittest.TestCase): # Works with 0, 1, and 2 connections. Assuming works with all further n connections. - def test__disconnect_nodes__success(self): + def test__disconnect__success(self): # Create nodes. - node_1 = self.test_graph.create_node() - node_2 = self.test_graph.create_node() - node_3 = self.test_graph.create_node() - node_4 = self.test_graph.create_node() + node_1 = self.test_graph.nodes.create() + node_2 = self.test_graph.nodes.create() + node_3 = self.test_graph.nodes.create() + node_4 = self.test_graph.nodes.create() with self.subTest('Disconnect by node classes.'): # Create node connections. - edge_1 = self.test_graph.connect_nodes(node_1, node_2) - edge_2 = self.test_graph.connect_nodes(node_1, node_3) - edge_3 = self.test_graph.connect_nodes(node_1, node_4) + edge_1 = self.test_graph.nodes.connect(node_1, node_2) + edge_2 = self.test_graph.nodes.connect(node_1, node_3) + edge_3 = self.test_graph.nodes.connect(node_1, node_4) # Verify start state. - self.assertEqual(self.test_graph.get_edge_count(), 3) - self.assertEqual(self.test_graph.get_node_count(), 4) + self.assertEqual(self.test_graph.edges.count(), 3) + self.assertEqual(self.test_graph.nodes.count(), 4) self.assertEqual(node_1.get_edge_count(), 3) self.assertEqual(node_1.get_edges(), { edge_1.get_name(): edge_1, @@ -1432,10 +1442,10 @@ class TestBasicGraph(unittest.TestCase): }) # Test disconnect with 3 connections. - disconnected_edge = self.test_graph.disconnect_nodes(node_1_identifier=node_1, node_2_identifier=node_4) + disconnected_edge = self.test_graph.nodes.disconnect(node_1_identifier=node_1, node_2_identifier=node_4) self.assertEqual(disconnected_edge, edge_3) - self.assertEqual(self.test_graph.get_edge_count(), 2) - self.assertEqual(self.test_graph.get_node_count(), 4) + self.assertEqual(self.test_graph.edges.count(), 2) + self.assertEqual(self.test_graph.nodes.count(), 4) self.assertEqual(node_1.get_edge_count(), 2) self.assertEqual(node_1.get_edges(), { edge_1.get_name(): edge_1, @@ -1448,10 +1458,10 @@ class TestBasicGraph(unittest.TestCase): }) # Test disconnect with 2 connections. - disconnected_edge = self.test_graph.disconnect_nodes(node_1_identifier=node_1, node_2_identifier=node_3) + disconnected_edge = self.test_graph.nodes.disconnect(node_1_identifier=node_1, node_2_identifier=node_3) self.assertEqual(disconnected_edge, edge_2) - self.assertEqual(self.test_graph.get_edge_count(), 1) - self.assertEqual(self.test_graph.get_node_count(), 4) + self.assertEqual(self.test_graph.edges.count(), 1) + self.assertEqual(self.test_graph.nodes.count(), 4) self.assertEqual(node_1.get_edge_count(), 1) self.assertEqual(node_1.get_edges(), { edge_1.get_name(): edge_1, @@ -1462,10 +1472,10 @@ class TestBasicGraph(unittest.TestCase): }) # Test disconnect with 1 connections. - disconnected_edge = self.test_graph.disconnect_nodes(node_1_identifier=node_1, node_2_identifier=node_2) + disconnected_edge = self.test_graph.nodes.disconnect(node_1_identifier=node_1, node_2_identifier=node_2) self.assertEqual(disconnected_edge, edge_1) - self.assertEqual(self.test_graph.get_edge_count(), 0) - self.assertEqual(self.test_graph.get_node_count(), 4) + self.assertEqual(self.test_graph.edges.count(), 0) + self.assertEqual(self.test_graph.nodes.count(), 4) self.assertEqual(node_1.get_edge_count(), 0) self.assertEqual(node_1.get_edges(), {}) self.assertEqual(node_1.get_connected_node_count(), 0) @@ -1475,13 +1485,13 @@ class TestBasicGraph(unittest.TestCase): with self.subTest('Disconnect by node names.'): # Create node connections. - edge_1 = self.test_graph.connect_nodes(node_1, node_2) - edge_2 = self.test_graph.connect_nodes(node_1, node_3) - edge_3 = self.test_graph.connect_nodes(node_1, node_4) + edge_1 = self.test_graph.nodes.connect(node_1, node_2) + edge_2 = self.test_graph.nodes.connect(node_1, node_3) + edge_3 = self.test_graph.nodes.connect(node_1, node_4) # Verify start state. - self.assertEqual(self.test_graph.get_edge_count(), 3) - self.assertEqual(self.test_graph.get_node_count(), 4) + self.assertEqual(self.test_graph.edges.count(), 3) + self.assertEqual(self.test_graph.nodes.count(), 4) self.assertEqual(node_1.get_edge_count(), 3) self.assertEqual(node_1.get_edges(), { edge_1.get_name(): edge_1, @@ -1496,13 +1506,13 @@ class TestBasicGraph(unittest.TestCase): }) # Test disconnect with 3 connections. - disconnected_edge = self.test_graph.disconnect_nodes( + disconnected_edge = self.test_graph.nodes.disconnect( node_1_identifier=node_1.get_name(), node_2_identifier=node_4.get_name(), ) self.assertEqual(disconnected_edge, edge_3) - self.assertEqual(self.test_graph.get_edge_count(), 2) - self.assertEqual(self.test_graph.get_node_count(), 4) + self.assertEqual(self.test_graph.edges.count(), 2) + self.assertEqual(self.test_graph.nodes.count(), 4) self.assertEqual(node_1.get_edge_count(), 2) self.assertEqual(node_1.get_edges(), { edge_1.get_name(): edge_1, @@ -1515,13 +1525,13 @@ class TestBasicGraph(unittest.TestCase): }) # Test disconnect with 2 connections. - disconnected_edge = self.test_graph.disconnect_nodes( + disconnected_edge = self.test_graph.nodes.disconnect( node_1_identifier=node_1.get_name(), node_2_identifier=node_3.get_name(), ) self.assertEqual(disconnected_edge, edge_2) - self.assertEqual(self.test_graph.get_edge_count(), 1) - self.assertEqual(self.test_graph.get_node_count(), 4) + self.assertEqual(self.test_graph.edges.count(), 1) + self.assertEqual(self.test_graph.nodes.count(), 4) self.assertEqual(node_1.get_edge_count(), 1) self.assertEqual(node_1.get_edges(), { edge_1.get_name(): edge_1, @@ -1532,13 +1542,13 @@ class TestBasicGraph(unittest.TestCase): }) # Test disconnect with 1 connections. - disconnected_edge = self.test_graph.disconnect_nodes( + disconnected_edge = self.test_graph.nodes.disconnect( node_1_identifier=node_1.get_name(), node_2_identifier=node_2.get_name(), ) self.assertEqual(disconnected_edge, edge_1) - self.assertEqual(self.test_graph.get_edge_count(), 0) - self.assertEqual(self.test_graph.get_node_count(), 4) + self.assertEqual(self.test_graph.edges.count(), 0) + self.assertEqual(self.test_graph.nodes.count(), 4) self.assertEqual(node_1.get_edge_count(), 0) self.assertEqual(node_1.get_edges(), {}) self.assertEqual(node_1.get_connected_node_count(), 0) @@ -1548,13 +1558,13 @@ class TestBasicGraph(unittest.TestCase): with self.subTest('Disconnect by edge classes.'): # Create node connections. - edge_1 = self.test_graph.connect_nodes(node_1, node_2) - edge_2 = self.test_graph.connect_nodes(node_1, node_3) - edge_3 = self.test_graph.connect_nodes(node_1, node_4) + edge_1 = self.test_graph.nodes.connect(node_1, node_2) + edge_2 = self.test_graph.nodes.connect(node_1, node_3) + edge_3 = self.test_graph.nodes.connect(node_1, node_4) # Verify start state. - self.assertEqual(self.test_graph.get_edge_count(), 3) - self.assertEqual(self.test_graph.get_node_count(), 4) + self.assertEqual(self.test_graph.edges.count(), 3) + self.assertEqual(self.test_graph.nodes.count(), 4) self.assertEqual(node_1.get_edge_count(), 3) self.assertEqual(node_1.get_edges(), { edge_1.get_name(): edge_1, @@ -1569,10 +1579,10 @@ class TestBasicGraph(unittest.TestCase): }) # Test disconnect with 3 connections. - disconnected_edge = self.test_graph.disconnect_nodes(edge_identifier=edge_3) + disconnected_edge = self.test_graph.nodes.disconnect(edge_identifier=edge_3) self.assertEqual(disconnected_edge, edge_3) - self.assertEqual(self.test_graph.get_edge_count(), 2) - self.assertEqual(self.test_graph.get_node_count(), 4) + self.assertEqual(self.test_graph.edges.count(), 2) + self.assertEqual(self.test_graph.nodes.count(), 4) self.assertEqual(node_1.get_edge_count(), 2) self.assertEqual(node_1.get_edges(), { edge_1.get_name(): edge_1, @@ -1585,10 +1595,10 @@ class TestBasicGraph(unittest.TestCase): }) # Test disconnect with 2 connections. - disconnected_edge = self.test_graph.disconnect_nodes(edge_identifier=edge_2) + disconnected_edge = self.test_graph.nodes.disconnect(edge_identifier=edge_2) self.assertEqual(disconnected_edge, edge_2) - self.assertEqual(self.test_graph.get_edge_count(), 1) - self.assertEqual(self.test_graph.get_node_count(), 4) + self.assertEqual(self.test_graph.edges.count(), 1) + self.assertEqual(self.test_graph.nodes.count(), 4) self.assertEqual(node_1.get_edge_count(), 1) self.assertEqual(node_1.get_edges(), { edge_1.get_name(): edge_1, @@ -1599,10 +1609,10 @@ class TestBasicGraph(unittest.TestCase): }) # Test disconnect with 1 connections. - disconnected_edge = self.test_graph.disconnect_nodes(edge_identifier=edge_1) + disconnected_edge = self.test_graph.nodes.disconnect(edge_identifier=edge_1) self.assertEqual(disconnected_edge, edge_1) - self.assertEqual(self.test_graph.get_edge_count(), 0) - self.assertEqual(self.test_graph.get_node_count(), 4) + self.assertEqual(self.test_graph.edges.count(), 0) + self.assertEqual(self.test_graph.nodes.count(), 4) self.assertEqual(node_1.get_edge_count(), 0) self.assertEqual(node_1.get_edges(), {}) self.assertEqual(node_1.get_connected_node_count(), 0) @@ -1612,13 +1622,13 @@ class TestBasicGraph(unittest.TestCase): with self.subTest('Disconnect by edge names.'): # Create node connections. - edge_1 = self.test_graph.connect_nodes(node_1, node_2) - edge_2 = self.test_graph.connect_nodes(node_1, node_3) - edge_3 = self.test_graph.connect_nodes(node_1, node_4) + edge_1 = self.test_graph.nodes.connect(node_1, node_2) + edge_2 = self.test_graph.nodes.connect(node_1, node_3) + edge_3 = self.test_graph.nodes.connect(node_1, node_4) # Verify start state. - self.assertEqual(self.test_graph.get_edge_count(), 3) - self.assertEqual(self.test_graph.get_node_count(), 4) + self.assertEqual(self.test_graph.edges.count(), 3) + self.assertEqual(self.test_graph.nodes.count(), 4) self.assertEqual(node_1.get_edge_count(), 3) self.assertEqual(node_1.get_edges(), { edge_1.get_name(): edge_1, @@ -1633,10 +1643,10 @@ class TestBasicGraph(unittest.TestCase): }) # Test disconnect with 3 connections. - disconnected_edge = self.test_graph.disconnect_nodes(edge_identifier=edge_3.get_name()) + disconnected_edge = self.test_graph.nodes.disconnect(edge_identifier=edge_3.get_name()) self.assertEqual(disconnected_edge, edge_3) - self.assertEqual(self.test_graph.get_edge_count(), 2) - self.assertEqual(self.test_graph.get_node_count(), 4) + self.assertEqual(self.test_graph.edges.count(), 2) + self.assertEqual(self.test_graph.nodes.count(), 4) self.assertEqual(node_1.get_edge_count(), 2) self.assertEqual(node_1.get_edges(), { edge_1.get_name(): edge_1, @@ -1649,10 +1659,10 @@ class TestBasicGraph(unittest.TestCase): }) # Test disconnect with 2 connections. - disconnected_edge = self.test_graph.disconnect_nodes(edge_identifier=edge_2.get_name()) + disconnected_edge = self.test_graph.nodes.disconnect(edge_identifier=edge_2.get_name()) self.assertEqual(disconnected_edge, edge_2) - self.assertEqual(self.test_graph.get_edge_count(), 1) - self.assertEqual(self.test_graph.get_node_count(), 4) + self.assertEqual(self.test_graph.edges.count(), 1) + self.assertEqual(self.test_graph.nodes.count(), 4) self.assertEqual(node_1.get_edge_count(), 1) self.assertEqual(node_1.get_edges(), { edge_1.get_name(): edge_1, @@ -1663,10 +1673,10 @@ class TestBasicGraph(unittest.TestCase): }) # Test disconnect with 1 connections. - disconnected_edge = self.test_graph.disconnect_nodes(edge_identifier=edge_1.get_name()) + disconnected_edge = self.test_graph.nodes.disconnect(edge_identifier=edge_1.get_name()) self.assertEqual(disconnected_edge, edge_1) - self.assertEqual(self.test_graph.get_edge_count(), 0) - self.assertEqual(self.test_graph.get_node_count(), 4) + self.assertEqual(self.test_graph.edges.count(), 0) + self.assertEqual(self.test_graph.nodes.count(), 4) self.assertEqual(node_1.get_edge_count(), 0) self.assertEqual(node_1.get_edges(), {}) self.assertEqual(node_1.get_connected_node_count(), 0) @@ -1674,19 +1684,19 @@ class TestBasicGraph(unittest.TestCase): # Works with 1, 2, and 3 connections. Assuming works with all further n connections. - def test__disconnect_nodes__failure(self): + def test__disconnect__failure(self): with self.subTest('No args passed.'): with self.assertRaises(AttributeError): - self.test_graph.disconnect_nodes() + self.test_graph.nodes.disconnect() with self.subTest('Node and Edge identifiers passed at once.'): # Edge and node_1 passed. with self.assertRaises(AttributeError): - self.test_graph.disconnect_nodes(node_2_identifier='1', edge_identifier='2') + self.test_graph.nodes.disconnect(node_2_identifier='1', edge_identifier='2') # Edge and node_2 passed. with self.assertRaises(AttributeError): - self.test_graph.disconnect_nodes(node_1_identifier='1', edge_identifier='2') + self.test_graph.nodes.disconnect(node_1_identifier='1', edge_identifier='2') # Create nodes for following tests. node_1 = BasicNode(self.test_graph._get_node_auto_name()) @@ -1694,30 +1704,30 @@ class TestBasicGraph(unittest.TestCase): edge_1 = BasicEdge(self.test_graph._get_edge_auto_name()) # Add only one node to graph. - self.test_graph.add_node(node_1) + self.test_graph.nodes.add(node_1) with self.subTest('Node args passed but node 1 not in graph.'): with self.assertLogs(level='WARNING'): - self.assertIsNone(self.test_graph.disconnect_nodes(node_1_identifier=node_2, node_2_identifier=node_1)) + self.assertIsNone(self.test_graph.nodes.disconnect(node_1_identifier=node_2, node_2_identifier=node_1)) with self.subTest('Node args passed but node 2 not in graph.'): with self.assertLogs(level='WARNING'): - self.assertIsNone(self.test_graph.disconnect_nodes(node_1_identifier=node_1, node_2_identifier=node_2)) + self.assertIsNone(self.test_graph.nodes.disconnect(node_1_identifier=node_1, node_2_identifier=node_2)) with self.subTest('Node args passed but nodes aren\'t connected.'): # Add second node to graph. - self.test_graph.add_node(node_2) + self.test_graph.nodes.add(node_2) # Check for error. with self.assertLogs(level='WARNING'): - self.assertIsNone(self.test_graph.disconnect_nodes(edge_identifier=edge_1)) + self.assertIsNone(self.test_graph.nodes.disconnect(edge_identifier=edge_1)) with self.subTest('Edge arg passed but edge not in graph.'): # Connect two nodes in graph. - self.test_graph.connect_nodes(node_1, node_2) + self.test_graph.nodes.connect(node_1, node_2) # Check for error. with self.assertLogs(level='WARNING'): - self.assertIsNone(self.test_graph.disconnect_nodes(edge_identifier=edge_1)) + self.assertIsNone(self.test_graph.nodes.disconnect(edge_identifier=edge_1)) #endregion Edge Upkeep Function Tests diff --git a/tests/resources/graphs/directed_graph/graph.py b/tests/resources/graphs/directed_graph/graph.py index 0510cfb5f41f02bbacbf28d439bcf560799d37fa..2ccf8dfc391c70ec4e3ee76b864c857989ee874b 100644 --- a/tests/resources/graphs/directed_graph/graph.py +++ b/tests/resources/graphs/directed_graph/graph.py @@ -16,36 +16,36 @@ from resources import DirectedEdge, DirectedNode from resources import DirectedGraph -class TestDirectedGraph(unittest.TestCase): +class TestDirectedGraphNodes(unittest.TestCase): def setUp(self): self.test_graph = DirectedGraph() - def test__create_node(self): + def test__create(self): # We have pretty thorough testing of the parent function. # Thus, just test returned node is of "Directed" type. - node_1 = self.test_graph.create_node() + node_1 = self.test_graph.nodes.create() self.assertTrue(isinstance(node_1, DirectedNode)) - def test__remove_node(self): + def test__remove(self): # We have pretty thorough testing of the parent function. # Thus, just test returned node is of "Directed" type. - node_1 = self.test_graph.create_node() - node_1 = self.test_graph.remove_node(node_1) + node_1 = self.test_graph.nodes.create() + node_1 = self.test_graph.nodes.remove(node_1) self.assertTrue(isinstance(node_1, DirectedNode)) - def test__connect_node(self): + def test__connect(self): # We have pretty thorough testing of the parent function. # Thus, just test returned edge is of "Directed" type. - node_1 = self.test_graph.create_node() - node_2 = self.test_graph.create_node() - edge_1 = self.test_graph.connect_nodes(node_1, node_2) + node_1 = self.test_graph.nodes.create() + node_2 = self.test_graph.nodes.create() + edge_1 = self.test_graph.nodes.connect(node_1, node_2) self.assertTrue(isinstance(edge_1, DirectedEdge)) - def test__disconnect_node(self): + def test__disconnect(self): # We have pretty thorough testing of the parent function. # Thus, just test returned edge is of "Directed" type. - node_1 = self.test_graph.create_node() - node_2 = self.test_graph.create_node() - self.test_graph.connect_nodes(node_1, node_2) - edge_1 = self.test_graph.disconnect_nodes(node_1_identifier=node_1, node_2_identifier=node_2) + node_1 = self.test_graph.nodes.create() + node_2 = self.test_graph.nodes.create() + self.test_graph.nodes.connect(node_1, node_2) + edge_1 = self.test_graph.nodes.disconnect(node_1_identifier=node_1, node_2_identifier=node_2) self.assertTrue(isinstance(edge_1, DirectedEdge)) diff --git a/tests/resources/graphs/state_machine/graph.py b/tests/resources/graphs/state_machine/graph.py index fee94ca5708890ce9e6b19a398b21e3259d6f3f7..6352a3d7aadea1d5a8fd596450df25942d86ed6f 100644 --- a/tests/resources/graphs/state_machine/graph.py +++ b/tests/resources/graphs/state_machine/graph.py @@ -20,12 +20,12 @@ class TestDirectedGraph(unittest.TestCase): def setUp(self): self.test_graph = StateMachineGraph() - def test__connect_nodes(self): + def test__connect(self): # Create nodes to connect. - node_1 = self.test_graph.create_node() - node_2 = self.test_graph.create_node() - node_3 = self.test_graph.create_node() - node_4 = self.test_graph.create_node() + node_1 = self.test_graph.nodes.create() + node_2 = self.test_graph.nodes.create() + node_3 = self.test_graph.nodes.create() + node_4 = self.test_graph.nodes.create() # Check that all nodes start with 0 connections. self.assertEqual(node_1.get_edge_count(), 0) @@ -34,7 +34,7 @@ class TestDirectedGraph(unittest.TestCase): self.assertEqual(node_4.get_edge_count(), 0) # Test with 0 connections. - edge_1 = self.test_graph.connect_nodes(node_1, node_2, 'a') + edge_1 = self.test_graph.nodes.connect(node_1, node_2, 'a') # Check node connection count. self.assertEqual(node_1.get_edge_count(), 1) self.assertEqual(node_2.get_edge_count(), 1) @@ -48,7 +48,7 @@ class TestDirectedGraph(unittest.TestCase): self.assertEqual(edge_1.state_change_conditions, ['a']) # Test with 1 connection. - edge_2 = self.test_graph.connect_nodes(node_1, node_3, 'b') + edge_2 = self.test_graph.nodes.connect(node_1, node_3, 'b') # Check node connection count. self.assertEqual(node_1.get_edge_count(), 2) self.assertEqual(node_2.get_edge_count(), 1) @@ -62,7 +62,7 @@ class TestDirectedGraph(unittest.TestCase): self.assertEqual(edge_2.state_change_conditions, ['b']) # Test with 2 connections. - edge_3 = self.test_graph.connect_nodes(node_1, node_4, 'c') + edge_3 = self.test_graph.nodes.connect(node_1, node_4, 'c') # Check node connection count. self.assertEqual(node_1.get_edge_count(), 3) self.assertEqual(node_2.get_edge_count(), 1) @@ -79,9 +79,9 @@ class TestDirectedGraph(unittest.TestCase): def test__toggle_node_state_initial(self): # Create node to toggle. - node_1 = self.test_graph.create_node() - node_2 = self.test_graph.create_node() - node_3 = self.test_graph.create_node() + node_1 = self.test_graph.nodes.create() + node_2 = self.test_graph.nodes.create() + node_3 = self.test_graph.nodes.create() with self.subTest('Adding initial/start states.'): # Test initial values. @@ -153,9 +153,9 @@ class TestDirectedGraph(unittest.TestCase): def test__toggle_node_state_final(self): # Create node to toggle. - node_1 = self.test_graph.create_node() - node_2 = self.test_graph.create_node() - node_3 = self.test_graph.create_node() + node_1 = self.test_graph.nodes.create() + node_2 = self.test_graph.nodes.create() + node_3 = self.test_graph.nodes.create() with self.subTest('Adding final states.'): # Test initial values.