From b7d7dd936902f530aca88b0da6fd8da8836eb196 Mon Sep 17 00:00:00 2001 From: Brandon Rodriguez <brodriguez8774@gmail.com> Date: Sat, 16 Nov 2019 00:17:43 -0500 Subject: [PATCH] Combine files to remove circular import dependencies --- main.py | 17 +- .../basic_graph/{node.py => components.py} | 213 +++++++++++++++-- resources/basic_graph/edge.py | 215 ------------------ resources/basic_graph/graph.py | 32 +-- .../directed_graph/{edge.py => components.py} | 118 +++++++++- resources/directed_graph/graph.py | 18 +- resources/directed_graph/node.py | 131 ----------- .../state_machine/{edge.py => components.py} | 52 ++++- resources/state_machine/graph.py | 24 +- resources/state_machine/node.py | 65 ------ tests/resources/basic_graph/edge.py | 47 ++-- tests/resources/basic_graph/graph.py | 129 ++++++----- tests/resources/basic_graph/node.py | 77 ++++--- tests/resources/directed_graph/edge.py | 9 +- tests/resources/directed_graph/graph.py | 15 +- tests/resources/directed_graph/node.py | 33 ++- tests/resources/state_machine/edge.py | 9 +- tests/resources/state_machine/graph.py | 13 +- tests/resources/state_machine/node.py | 4 +- 19 files changed, 564 insertions(+), 657 deletions(-) rename resources/basic_graph/{node.py => components.py} (67%) delete mode 100644 resources/basic_graph/edge.py rename resources/directed_graph/{edge.py => components.py} (52%) delete mode 100644 resources/directed_graph/node.py rename resources/state_machine/{edge.py => components.py} (75%) delete mode 100644 resources/state_machine/node.py diff --git a/main.py b/main.py index 7486daa..ebb126b 100644 --- a/main.py +++ b/main.py @@ -14,13 +14,12 @@ Example usage and output for graph library. # User Class Imports. from random import randint from resources import logging as init_logging -from resources.basic_graph.edge import Edge as BasicEdge -from resources.basic_graph.graph import Graph as BasicGraph -from resources.basic_graph.node import Node as BasicNode -from resources.directed_graph.edge import Edge as DirectedEdge -from resources.directed_graph.graph import Graph as DirectedGraph -from resources.directed_graph.node import Node as DirectedNode -from resources.state_machine.graph import Graph as SmGraph +from resources.basic_graph.components import BasicEdge, BasicNode +from resources.basic_graph.graph import BasicGraph +from resources.directed_graph.components import DirectedEdge, DirectedNode +from resources.directed_graph.graph import DirectedGraph +from resources.state_machine.components import StateMachineEdge, StateMachineNode +from resources.state_machine.graph import StateMachineGraph # Initialize Logger. @@ -35,7 +34,7 @@ def test_graph(): logger.info('Creating and displaying Test Graph...') # Create graph. - graph = SmGraph() + graph = StateMachineGraph() # Create some nodes. node_1 = graph.create_node('A') @@ -366,7 +365,7 @@ def draw_state_machine(): logger.info('Creating and displaying State Machine Graph...') # Create graph. - graph = SmGraph() + graph = StateMachineGraph() # Create some nodes. node_1 = graph.create_node('A') diff --git a/resources/basic_graph/node.py b/resources/basic_graph/components.py similarity index 67% rename from resources/basic_graph/node.py rename to resources/basic_graph/components.py index a811174..3bdd064 100644 --- a/resources/basic_graph/node.py +++ b/resources/basic_graph/components.py @@ -5,18 +5,19 @@ Assignment: Graph Library Author: Brandon Rodriguez -Node class for a "basic graph" (No edge weights or edge directions). -Essentially the "vertex" in a Graph data structure. +Edge and Node classes for a "basic graph" (No edge weights or edge directions). +Essentially the "vertex" and "vertex connection" classes in a Graph data structure. + +These classes are combined into one single file to avoid circular import dependencies. """ # System Imports. - # User Class Imports. -import resources.basic_graph.edge as basic_edge -# Initialize logging. +#region Logging Initialization + # Since this is a library, we specifically only modify logging if the library is being run alone. try: # First, try to import the variable specific to our library logging. @@ -32,8 +33,192 @@ except ModuleNotFoundError: import logging as init_logging logger = init_logging.getLogger('graph_library') +#endregion Logging Initialization + + +class BasicEdge(): + def __init__(self, name, *args, **kwargs): + # Check for passed arg types. + if name is None: + raise TypeError('Edge must be passed a string-convertable name.') + + # Define basic class vars. + self._name = str(name) + self._nodes = [] + self._nodes_can_self_connect = False + + # Define expected class types (should all be of "Basic" type). + # This is necessary for inheritance, or else child classes will only have access to parent functions. + self._edge_type = BasicEdge + self._node_type = BasicNode + + def __str__(self): + """ + String representation of object. + """ + return self.get_name() + + #region Information Functions + + def get_name(self): + """ + Returns edge name. + :return: Edge's name. + """ + return str(self._name) + + def get_node_count(self): + """ + Counts all nodes connected to edge. + :return: Count of connected nodes. + """ + return len(self._nodes) + + def get_nodes(self): + """ + Return all connected nodes. + :return: Connected nodes. + """ + # Check number of connected nodes. + if len(self._nodes) == 0: + return () + + elif len(self._nodes) == 2: + return (self._nodes[0], self._nodes[1]) + + else: + raise AttributeError('This edge connects {0} nodes. Should only connect 0 or 2.'.format( + self.get_node_count() + )) + + def get_node(self, node_identifier): + """ + Returns single node connected to edge. + :param node_identifier: Connected node to return. + :return: A single Node connected to this edge. + """ + # Check for passed arg types. + if node_identifier is None: + # Arg is empty. + raise AttributeError('Node Identifier arg cannot be empty.') + elif isinstance(node_identifier, self._node_type): + # Arg is 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: + # Assume arg is for node name. + node_name = str(node_identifier) + + # Attempt to return node. + for connected_node in self._nodes: + if connected_node.get_name() == node_name: + # Node found. Return. + return connected_node + + # If we made it this far, then node is not connected to edge. + logger.warning('Could not find node "{0}" in list of connected nodes.'.format(node_name)) + return None + + def get_partner_node(self, passed_node): + """ + Get passed node's partner in edge connection. + :param passed_node: Node to check partner of. + :return: Partner of passed node, in edge connection. + """ + # Check for passed arg types. + if not isinstance(passed_node, self._node_type): + raise TypeError('Passed node must be of type Node.') + + # Check number of connected nodes. + node_count = self.get_node_count() + if node_count == 0: + raise AttributeError('No nodes connected. Cannot get partner node.') + + elif node_count == 2: + if self._nodes[0] == passed_node: + return self._nodes[1] + else: + return self._nodes[0] + + else: + raise AttributeError('This edge connects {0} nodes. Should only connect 0 or 2.'.format( + self.get_node_count() + )) + + #endregion Information Functions + + #region Upkeep Functions + + def connect_nodes(self, node_1, node_2): + """ + Connects two nodes to edge. + :param node_1: First node to connect. + :param node_2: Second node to connect. + """ + # Check node_1 is of type node. + if not isinstance(node_1, self._node_type): + raise TypeError('Arg 1 must be of type Node.') + # Check node_2 is of type node. + if not isinstance(node_2, self._node_type): + raise TypeError('Arg 2 must be of type Node.') + # Check that nodes do not have the same name value (only if self-connecting is illegal). + if not self._nodes_can_self_connect: + if node_1.get_name() == node_2.get_name(): + raise ValueError('Nodes to connect must not have identical names.') + + # Check existing node count. + node_count = self.get_node_count() + if node_count == 0: + # No nodes connected yet. Proceed. + + # Add node references to this edge. + self._nodes.append(node_1) + self._nodes.append(node_2) + + # Add edge reference to first node. + node_1._edges[self.get_name()] = self + node_1._connected_nodes[node_2.get_name()] = node_2 + + # Add edge reference to second node. + node_2._edges[self.get_name()] = self + node_2._connected_nodes[node_1.get_name()] = node_1 + + else: + # One or more nodes already connected. Handle accordingly. + if node_count == 2: + raise AttributeError( + 'An edge can only connect zero or two nodes. This edge already connects {0} to {1}'.format( + self._nodes[0], + self._nodes[1] + ) + ) + else: + raise AttributeError( + 'An edge can only connect zero or two nodes. This edge already connects {0} nodes.'.format( + self.get_node_count() + ) + ) + + def disconnect_nodes(self): + """ + Disconnect nodes attached to edge. + """ + # Get connected nodes. + try: + node_1, node_2 = self.get_nodes() + except ValueError: + # No nodes connected. Return None. + return None + + # Call node function to disconnect. + node_1.disconnect_node(node_identifier=node_2) + + # Return disconnected edge. + return self + + #endregion Upkeep Functions + -class Node(): +class BasicNode(): def __init__(self, name, *args, **kwargs): # Check for passed arg types. if name is None: @@ -46,8 +231,8 @@ class Node(): # Define expected class types (should all be of "Basic" type). # This is necessary for inheritance, or else child classes will only have access to parent functions. - self._edge_type = basic_edge.Edge - self._node_type = Node + self._edge_type = BasicEdge + self._node_type = BasicNode def __str__(self): """ @@ -147,7 +332,7 @@ class Node(): if edge_identifier is None: # Arg is empty. raise AttributeError('Edge Identifier arg cannot be empty.') - elif isinstance(edge_identifier, basic_edge.Edge): + elif isinstance(edge_identifier, self._edge_type): # Arg is 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: @@ -171,7 +356,7 @@ class Node(): if node_identifier is None: # Arg is empty. raise AttributeError('Node identifier arg cannot be empty.') - elif isinstance(node_identifier, Node): + elif isinstance(node_identifier, self._edge_type): # Arg is of Node object instance. connected_node_name = node_identifier.get_name() else: @@ -209,7 +394,7 @@ class Node(): if node_identifier is None: # Arg is empty. raise AttributeError('Node identifier arg cannot be empty.') - elif isinstance(node_identifier, Node): + elif isinstance(node_identifier, self._node_type): # Arg is of Node object instance. node_name = node_identifier.get_name() else: @@ -237,7 +422,7 @@ class Node(): :param edge_name: Name of edge connection to create. """ # Raise error if neighbor_node arg is not of Node type. - if not isinstance(neighbor_node, Node): + if not isinstance(neighbor_node, self._node_type): raise TypeError('Arg must be of type Node.') # Set edge_name arg if none is provided. @@ -273,7 +458,7 @@ class Node(): # Handle if node arg passed. if node_identifier is not None: # Check type of passed arg. - if isinstance(node_identifier, Node): + if isinstance(node_identifier, self._node_type): # Passed arg of type node. node_name = node_identifier.get_name() else: @@ -340,7 +525,7 @@ class Node(): # Handle if edge arg passed. if edge_identifier is not None: # Check type of passed arg. - if isinstance(edge_identifier, basic_edge.Edge): + if isinstance(edge_identifier, self._edge_type): # Passed arg of type edge. edge_name = edge_identifier.get_name() else: diff --git a/resources/basic_graph/edge.py b/resources/basic_graph/edge.py deleted file mode 100644 index 57de3be..0000000 --- a/resources/basic_graph/edge.py +++ /dev/null @@ -1,215 +0,0 @@ -""" -Date: 09-12-19 -Class: CS5310 -Assignment: Graph Library -Author: Brandon Rodriguez - - -Edge class for a "basic graph" (No edge weights or edge directions). -Essentially the "node connection" in a Graph data structure. -""" - -# System Imports. - - -# User Class Imports. -import resources.basic_graph.node as basic_node - - -# Initialize logging. -# Since this is a library, we specifically only modify logging if the library is being run alone. -try: - # First, try to import the variable specific to our library logging. - from resources.logging import graph_library_logger - - # It worked, so we know the project is being run stand alone, probably as a unittest. - # Proceed to configure logging. - from resources.logging import get_logger as init_logging - logger = init_logging(__name__) -except ModuleNotFoundError: - # Above import failed. Project is being run as a library. - # Just import existing logger and do not modify. - import logging as init_logging - logger = init_logging.getLogger('graph_library') - - -class Edge(): - def __init__(self, name, *args, **kwargs): - # Check for passed arg types. - if name is None: - raise TypeError('Edge must be passed a string-convertable name.') - - # Define basic class vars. - self._name = str(name) - self._nodes = [] - self._nodes_can_self_connect = False - - # Define expected class types (should all be of "Basic" type). - # This is necessary for inheritance, or else child classes will only have access to parent functions. - self._edge_type = Edge - self._node_type = basic_node.Node - - def __str__(self): - """ - String representation of object. - """ - return self.get_name() - - #region Information Functions - - def get_name(self): - """ - Returns edge name. - :return: Edge's name. - """ - return str(self._name) - - def get_node_count(self): - """ - Counts all nodes connected to edge. - :return: Count of connected nodes. - """ - return len(self._nodes) - - def get_nodes(self): - """ - Return all connected nodes. - :return: Connected nodes. - """ - # Check number of connected nodes. - if len(self._nodes) == 0: - return () - - elif len(self._nodes) == 2: - return (self._nodes[0], self._nodes[1]) - - else: - raise AttributeError('This edge connects {0} nodes. Should only connect 0 or 2.'.format( - self.get_node_count() - )) - - def get_node(self, node_identifier): - """ - Returns single node connected to edge. - :param node_identifier: Connected node to return. - :return: A single Node connected to this edge. - """ - # Check for passed arg types. - if node_identifier is None: - # Arg is empty. - raise AttributeError('Node Identifier arg cannot be empty.') - elif isinstance(node_identifier, basic_node.Node): - # Arg is 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: - # Assume arg is for node name. - node_name = str(node_identifier) - - # Attempt to return node. - for connected_node in self._nodes: - if connected_node.get_name() == node_name: - # Node found. Return. - return connected_node - - # If we made it this far, then node is not connected to edge. - logger.warning('Could not find node "{0}" in list of connected nodes.'.format(node_name)) - return None - - def get_partner_node(self, passed_node): - """ - Get passed node's partner in edge connection. - :param passed_node: Node to check partner of. - :return: Partner of passed node, in edge connection. - """ - # Check for passed arg types. - if not isinstance(passed_node, basic_node.Node): - raise TypeError('Passed node must be of type Node.') - - # Check number of connected nodes. - node_count = self.get_node_count() - if node_count == 0: - raise AttributeError('No nodes connected. Cannot get partner node.') - - elif node_count == 2: - if self._nodes[0] == passed_node: - return self._nodes[1] - else: - return self._nodes[0] - - else: - raise AttributeError('This edge connects {0} nodes. Should only connect 0 or 2.'.format( - self.get_node_count() - )) - - #endregion Information Functions - - #region Upkeep Functions - - def connect_nodes(self, node_1, node_2): - """ - Connects two nodes to edge. - :param node_1: First node to connect. - :param node_2: Second node to connect. - """ - # Check node_1 is of type node. - if not isinstance(node_1, basic_node.Node): - raise TypeError('Arg 1 must be of type Node.') - # Check node_2 is of type node. - if not isinstance(node_2, basic_node.Node): - raise TypeError('Arg 2 must be of type Node.') - # Check that nodes do not have the same name value (only if self-connecting is illegal). - if not self._nodes_can_self_connect: - if node_1.get_name() == node_2.get_name(): - raise ValueError('Nodes to connect must not have identical names.') - - # Check existing node count. - node_count = self.get_node_count() - if node_count == 0: - # No nodes connected yet. Proceed. - - # Add node references to this edge. - self._nodes.append(node_1) - self._nodes.append(node_2) - - # Add edge reference to first node. - node_1._edges[self.get_name()] = self - node_1._connected_nodes[node_2.get_name()] = node_2 - - # Add edge reference to second node. - node_2._edges[self.get_name()] = self - node_2._connected_nodes[node_1.get_name()] = node_1 - - else: - # One or more nodes already connected. Handle accordingly. - if node_count == 2: - raise AttributeError( - 'An edge can only connect zero or two nodes. This edge already connects {0} to {1}'.format( - self._nodes[0], - self._nodes[1] - ) - ) - else: - raise AttributeError( - 'An edge can only connect zero or two nodes. This edge already connects {0} nodes.'.format( - self.get_node_count() - ) - ) - - def disconnect_nodes(self): - """ - Disconnect nodes attached to edge. - """ - # Get connected nodes. - try: - node_1, node_2 = self.get_nodes() - except ValueError: - # No nodes connected. Return None. - return None - - # Call node function to disconnect. - node_1.disconnect_node(node_identifier=node_2) - - # Return disconnected edge. - return self - - #endregion Upkeep Functions diff --git a/resources/basic_graph/graph.py b/resources/basic_graph/graph.py index 34a7a32..81479e5 100644 --- a/resources/basic_graph/graph.py +++ b/resources/basic_graph/graph.py @@ -13,11 +13,11 @@ Parent structure containing various Nodes and Edges. from random import randint # User Class Imports. -import resources.basic_graph.edge as basic_edge -import resources.basic_graph.node as basic_node +from .components import BasicEdge, BasicNode -# Initialize logging. +#region Logging Initialization + # Since this is a library, we specifically only modify logging if the library is being run alone. try: # First, try to import the variable specific to our library logging. @@ -33,8 +33,10 @@ except ModuleNotFoundError: import logging as init_logging logger = init_logging.getLogger('graph_library') +#endregion Logging Initialization + -class Graph(): +class BasicGraph(): def __init__(self, *args, **kwargs): # Lists of nodes and edges in graph. self._edges = {} @@ -46,9 +48,9 @@ class Graph(): # Define expected class types (should all be of "Basic" type). # This is necessary for inheritance, or else child classes will only have access to parent functions. - self._edge_type = basic_edge.Edge - self._graph_type = Graph - self._node_type = basic_node.Node + self._edge_type = BasicEdge + self._graph_type = BasicGraph + self._node_type = BasicNode #region Private Information Functions @@ -530,7 +532,7 @@ class Graph(): # Check for passed arg types. if node_identifier is None: raise AttributeError('Node identifier arg cannot be empty.') - elif isinstance(node_identifier, basic_node.Node): + elif isinstance(node_identifier, self._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: @@ -556,7 +558,7 @@ class Graph(): # Check for passed arg types. if node_identifier is None: raise AttributeError('Node identifier arg cannot be empty.') - elif isinstance(node_identifier, basic_node.Node): + elif isinstance(node_identifier, self._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: @@ -677,7 +679,7 @@ class Graph(): # Check for passed arg types. if edge_identifier is None: raise AttributeError('Edge identifier arg cannot be empty.') - elif isinstance(edge_identifier, basic_edge.Edge): + 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: @@ -703,7 +705,7 @@ class Graph(): # Check for passed arg types. if edge_identifier is None: raise AttributeError('Edge identifier arg cannot be empty.') - elif isinstance(edge_identifier, basic_edge.Edge): + 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: @@ -767,7 +769,7 @@ class Graph(): :param new_node: Node to add to graph. """ # Check for passed arg types. - if not isinstance(new_node, basic_node.Node): + if not isinstance(new_node, self._node_type): raise TypeError('Passed arg is not of type Node.') # Check that node does not already exist within graph. @@ -816,7 +818,7 @@ class Graph(): if potential_node is None: # Item was empty. raise AttributeError('Item in list is of type None.') - elif isinstance(potential_node, basic_node.Node): + elif isinstance(potential_node, self._node_type): # Arg was of Node object instance. node_name = potential_node.get_name() else: @@ -872,9 +874,9 @@ class Graph(): :return: Newly created edge to connect nodes. """ # Check if node_1 is type Node. - if not isinstance(node_1, basic_node.Node): + if not isinstance(node_1, self._node_type): raise TypeError('Arg "node_1" must be of type node.') - if not isinstance(node_2, basic_node.Node): + if not isinstance(node_2, self._node_type): raise TypeError('Arg "node_2" must be of type node.') # Check edge_name arg. diff --git a/resources/directed_graph/edge.py b/resources/directed_graph/components.py similarity index 52% rename from resources/directed_graph/edge.py rename to resources/directed_graph/components.py index 0f1efef..65e74a7 100644 --- a/resources/directed_graph/edge.py +++ b/resources/directed_graph/components.py @@ -5,19 +5,20 @@ Assignment: Graph Library Author: Brandon Rodriguez -Edge class for a "directed graph" (Has edge directions, but no edge weights). -Essentially the "node connection" in a Graph data structure. +Edge and Node classes for a "directed graph" (Has edge directions, but no edge weights). +Essentially the "vertex" and "vertex connection" classes in a Graph data structure. + +These classes are combined into one single file to avoid circular import dependencies. """ # System Imports. - # User Class Imports. -import resources.basic_graph.edge as basic_edge -import resources.directed_graph.node as directed_node +from ..basic_graph.components import BasicEdge, BasicNode + +#region Logging Initialization -# Initialize logging. # Since this is a library, we specifically only modify logging if the library is being run alone. try: # First, try to import the variable specific to our library logging. @@ -33,15 +34,17 @@ except ModuleNotFoundError: import logging as init_logging logger = init_logging.getLogger('graph_library') +#endregion Logging Initialization -class Edge(basic_edge.Edge): + +class DirectedEdge(BasicEdge): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # Define expected class types (should all be of "Directed" type). # This is necessary for inheritance, or else child classes will only have access to parent functions. - self._edge_type = Edge - self._node_type = directed_node.Node + self._edge_type = DirectedEdge + self._node_type = DirectedNode #region Information Functions @@ -136,3 +139,100 @@ class Edge(basic_edge.Edge): pass #endregion Upkeep Functions + + +class DirectedNode(BasicNode): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + # Define expected class types (should all be of "Directed" type). + # This is necessary for inheritance, or else child classes will only have access to parent functions. + self._edge_type = DirectedEdge + self._node_type = DirectedNode + + #region Information Functions + + def get_outgoing_edges(self): + """ + Gets a list of all directly connected, outgoing edges. + :return: List of all directly connected, outgoing edges. + """ + outgoing_edge_list = [] + + # Loop through all existing edges. + for connecting_edge in self.get_edges().values(): + if connecting_edge.get_nodes()['tail_node'] == self: + outgoing_edge_list.append(connecting_edge) + + # Return outgoing edges. + return outgoing_edge_list + + def get_incoming_edges(self): + """ + Gets a list of all directly connected, incoming edges. + :return: List of all directly connected, incoming edges. + """ + incoming_edge_list = [] + + # Loop through all existing edges. + for connecting_edge in self.get_edges().values(): + if connecting_edge.get_nodes()['head_node'] == self: + incoming_edge_list.append(connecting_edge) + + # Return incoming edges. + return incoming_edge_list + + def get_outgoing_nodes(self): + """ + Gets a list of all directly connected, outgoing nodes. + :return: List of all directly connected, outgoing nodes. + """ + outgoing_node_list = [] + + # Loop through all existing edges. + for connecting_edge in self.get_edges().values(): + if connecting_edge.get_nodes()['tail_node'] == self: + outgoing_node_list.append(connecting_edge.get_nodes()['head_node']) + + # Return outgoing nodes. + return outgoing_node_list + + def get_incoming_nodes(self): + """ + Gets a list of all directly connected, incoming nodes. + :return: List of all directly connected, incoming nodes. + """ + incoming_node_lst = [] + + # Loop through all existing edges. + for connecting_edge in self.get_edges().values(): + if connecting_edge.get_nodes()['head_node'] == self: + incoming_node_lst.append(connecting_edge.get_nodes()['tail_node']) + + # Return incoming nodes. + return incoming_node_lst + + #endregion Information Functions + + #region Upkeep Functions + + def connect_node(self, neighbor_node, direct_towards_neighbor=True, edge_name=None): + """ + Connects current node to passed node. + :param neighbor_node: Node to connect with. + :param direct_towards_neighbor: Bool indicating if edge direction should lead towards neighbor. + :param edge_name: Name of edge connection to create. + """ + # Raise error if neighbor_node arg is not of Node type. + if not isinstance(neighbor_node, self._node_type): + raise TypeError('Arg must be of type Node.') + + # Check which way edge direction should lead. + if direct_towards_neighbor: + # Neighbor should be the Head Node. Call parent implementation. + return super().connect_node(neighbor_node, edge_name=edge_name) + else: + # Neighbor should be the Tail Node. Re-call this function accordingly, so we can call the correct super(). + return neighbor_node.connect_node(self, direct_towards_neighbor=True, edge_name=edge_name) + + #endregion Upkeep Functions diff --git a/resources/directed_graph/graph.py b/resources/directed_graph/graph.py index 20753a8..e0cb2b6 100644 --- a/resources/directed_graph/graph.py +++ b/resources/directed_graph/graph.py @@ -13,12 +13,12 @@ Parent structure containing various Nodes and Edges. import math # User Class Imports. -import resources.basic_graph.graph as basic_graph -import resources.directed_graph.edge as directed_edge -import resources.directed_graph.node as directed_node +from .components import DirectedEdge, DirectedNode +from ..basic_graph.graph import BasicGraph -# Initialize logging. +#region Logging Initialization + # Since this is a library, we specifically only modify logging if the library is being run alone. try: # First, try to import the variable specific to our library logging. @@ -34,16 +34,18 @@ except ModuleNotFoundError: import logging as init_logging logger = init_logging.getLogger('graph_library') +#endregion Logging Initialization + -class Graph(basic_graph.Graph): +class DirectedGraph(BasicGraph): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # Define expected class types (should all be of "Directed" type). # This is necessary for inheritance, or else child classes will only have access to parent functions. - self._edge_type = directed_edge.Edge - self._graph_type = Graph - self._node_type = directed_node.Node + self._edge_type = DirectedEdge + self._graph_type = DirectedGraph + self._node_type = DirectedNode def _create_additional_edge_mappings(self): """ diff --git a/resources/directed_graph/node.py b/resources/directed_graph/node.py deleted file mode 100644 index 801c751..0000000 --- a/resources/directed_graph/node.py +++ /dev/null @@ -1,131 +0,0 @@ -""" -Date: 09-12-19 -Class: CS5310 -Assignment: Graph Library -Author: Brandon Rodriguez - - -Node class for a "directed graph" (Has edge directions, but no edge weights). -Essentially the "vertex" in a Graph data structure. -""" - -# System Imports. - - -# User Class Imports. -import resources.basic_graph.node as basic_node -import resources.directed_graph.edge as directed_edge - - -# Initialize logging. -# Since this is a library, we specifically only modify logging if the library is being run alone. -try: - # First, try to import the variable specific to our library logging. - from resources.logging import graph_library_logger - - # It worked, so we know the project is being run stand alone, probably as a unittest. - # Proceed to configure logging. - from resources.logging import get_logger as init_logging - logger = init_logging(__name__) -except ModuleNotFoundError: - # Above import failed. Project is being run as a library. - # Just import existing logger and do not modify. - import logging as init_logging - logger = init_logging.getLogger('graph_library') - - -class Node(basic_node.Node): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - - # Define expected class types (should all be of "Directed" type). - # This is necessary for inheritance, or else child classes will only have access to parent functions. - self._edge_type = directed_edge.Edge - self._node_type = Node - - #region Information Functions - - def get_outgoing_edges(self): - """ - Gets a list of all directly connected, outgoing edges. - :return: List of all directly connected, outgoing edges. - """ - outgoing_edge_list = [] - - # Loop through all existing edges. - for connecting_edge in self.get_edges().values(): - if connecting_edge.get_nodes()['tail_node'] == self: - outgoing_edge_list.append(connecting_edge) - - # Return outgoing edges. - return outgoing_edge_list - - def get_incoming_edges(self): - """ - Gets a list of all directly connected, incoming edges. - :return: List of all directly connected, incoming edges. - """ - incoming_edge_list = [] - - # Loop through all existing edges. - for connecting_edge in self.get_edges().values(): - if connecting_edge.get_nodes()['head_node'] == self: - incoming_edge_list.append(connecting_edge) - - # Return incoming edges. - return incoming_edge_list - - def get_outgoing_nodes(self): - """ - Gets a list of all directly connected, outgoing nodes. - :return: List of all directly connected, outgoing nodes. - """ - outgoing_node_list = [] - - # Loop through all existing edges. - for connecting_edge in self.get_edges().values(): - if connecting_edge.get_nodes()['tail_node'] == self: - outgoing_node_list.append(connecting_edge.get_nodes()['head_node']) - - # Return outgoing nodes. - return outgoing_node_list - - def get_incoming_nodes(self): - """ - Gets a list of all directly connected, incoming nodes. - :return: List of all directly connected, incoming nodes. - """ - incoming_node_lst = [] - - # Loop through all existing edges. - for connecting_edge in self.get_edges().values(): - if connecting_edge.get_nodes()['head_node'] == self: - incoming_node_lst.append(connecting_edge.get_nodes()['tail_node']) - - # Return incoming nodes. - return incoming_node_lst - - #endregion Information Functions - - #region Upkeep Functions - - def connect_node(self, neighbor_node, direct_towards_neighbor=True, edge_name=None): - """ - Connects current node to passed node. - :param neighbor_node: Node to connect with. - :param direct_towards_neighbor: Bool indicating if edge direction should lead towards neighbor. - :param edge_name: Name of edge connection to create. - """ - # Raise error if neighbor_node arg is not of Node type. - if not isinstance(neighbor_node, Node): - raise TypeError('Arg must be of type Node.') - - # Check which way edge direction should lead. - if direct_towards_neighbor: - # Neighbor should be the Head Node. Call parent implementation. - return super().connect_node(neighbor_node, edge_name=edge_name) - else: - # Neighbor should be the Tail Node. Re-call this function accordingly, so we can call the correct super(). - return neighbor_node.connect_node(self, direct_towards_neighbor=True, edge_name=edge_name) - - #endregion Upkeep Functions diff --git a/resources/state_machine/edge.py b/resources/state_machine/components.py similarity index 75% rename from resources/state_machine/edge.py rename to resources/state_machine/components.py index 36a9310..7fca598 100644 --- a/resources/state_machine/edge.py +++ b/resources/state_machine/components.py @@ -5,18 +5,20 @@ Assignment: Graph Library Author: Brandon Rodriguez -Edge class for a "state machine graph". -Essentially the "node connection" in a Graph data structure. +Edge and Node classes for a "state machine graph". +Essentially the "vertex" and "vertex connection" classes in a Graph data structure. + +These classes are combined into one single file to avoid circular import dependencies. """ # System Imports. # User Class Imports. -import resources.directed_graph.edge as directed_edge -import resources.state_machine.node as sm_node +from ..directed_graph.components import DirectedEdge, DirectedNode + +#region Logging Initialization -# Initialize logging. # Since this is a library, we specifically only modify logging if the library is being run alone. try: # First, try to import the variable specific to our library logging. @@ -32,8 +34,10 @@ except ModuleNotFoundError: import logging as init_logging logger = init_logging.getLogger('graph_library') +#endregion Logging Initialization + -class Edge(directed_edge.Edge): +class StateMachineEdge(DirectedEdge): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -42,8 +46,8 @@ class Edge(directed_edge.Edge): # Define expected class types (should all be of "State Machine" type). # This is necessary for inheritance, or else child classes will only have access to parent functions. - self._edge_type = Edge - self._node_type = sm_node.Node + self._edge_type = StateMachineEdge + self._node_type = StateMachineNode # List of values which allow a state change through this edge. self.state_change_conditions = [] @@ -113,3 +117,35 @@ class Edge(directed_edge.Edge): # Return original parent value. return parent_return + + +class StateMachineNode(DirectedNode): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + # Define expected class types (should all be of "State Machine" type). + # This is necessary for inheritance, or else child classes will only have access to parent functions. + self._edge_type = StateMachineEdge + self._node_type = StateMachineNode + + # Add values for state machine states. + self.is_initial = False + self.is_final = False + + def toggle_node_state_initial(self): + """ + Toggles node "initial" state. + """ + if not self.is_initial: + self.is_initial = True + else: + self.is_initial = False + + def toggle_node_state_final(self): + """ + Toggles node "final" state. + """ + if not self.is_final: + self.is_final = True + else: + self.is_final = False diff --git a/resources/state_machine/graph.py b/resources/state_machine/graph.py index fe5430f..9e69f8d 100644 --- a/resources/state_machine/graph.py +++ b/resources/state_machine/graph.py @@ -12,12 +12,12 @@ Parent structure containing various Nodes and Edges. # System Imports. # User Class Imports. -import resources.directed_graph.graph as directed_graph -import resources.state_machine.edge as sm_edge -import resources.state_machine.node as sm_node +from .components import StateMachineEdge, StateMachineNode +from ..directed_graph.graph import DirectedGraph -# Initialize logging. +#region Logging Initialization + # Since this is a library, we specifically only modify logging if the library is being run alone. try: # First, try to import the variable specific to our library logging. @@ -33,16 +33,18 @@ except ModuleNotFoundError: import logging as init_logging logger = init_logging.getLogger('graph_library') +#endregion Logging Initialization + -class Graph(directed_graph.Graph): +class StateMachineGraph(DirectedGraph): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # Define expected class types (should all be of "State Machine" type). # This is necessary for inheritance, or else child classes will only have access to parent functions. - self._edge_type = sm_edge.Edge - self._graph_type = Graph - self._node_type = sm_node.Node + self._edge_type = StateMachineEdge + self._graph_type = StateMachineGraph + self._node_type = StateMachineNode def _create_node_hover_text(self): """ @@ -201,15 +203,15 @@ class Graph(directed_graph.Graph): raise ValueError('State change condition cannot be none.') # Check if node_1 is type Node. - if not isinstance(node_1, sm_node.Node): + if not isinstance(node_1, self._node_type): raise TypeError('Arg "node_1" must be of type node.') - if not isinstance(node_2, sm_node.Node): + if not isinstance(node_2, self._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() - # Check that node name does not already exist in graph. + # Check that edge name does not already exist in graph. try: self._nodes[edge_name] diff --git a/resources/state_machine/node.py b/resources/state_machine/node.py deleted file mode 100644 index 3be00b6..0000000 --- a/resources/state_machine/node.py +++ /dev/null @@ -1,65 +0,0 @@ -""" -Date: 10-02-19 -Class: CS5310 -Assignment: Graph Library -Author: Brandon Rodriguez - - -Node class for a "state machine graph". -Essentially the "vertex" in a Graph data structure. -""" - -# System Imports. - -# User Class Imports. -import resources.directed_graph.node as directed_node -import resources.state_machine.edge as sm_edge - - -# Initialize logging. -# Since this is a library, we specifically only modify logging if the library is being run alone. -try: - # First, try to import the variable specific to our library logging. - from resources.logging import graph_library_logger - - # It worked, so we know the project is being run stand alone, probably as a unittest. - # Proceed to configure logging. - from resources.logging import get_logger as init_logging - logger = init_logging(__name__) -except ModuleNotFoundError: - # Above import failed. Project is being run as a library. - # Just import existing logger and do not modify. - import logging as init_logging - logger = init_logging.getLogger('graph_library') - - -class Node(directed_node.Node): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - - # Define expected class types (should all be of "State Machine" type). - # This is necessary for inheritance, or else child classes will only have access to parent functions. - self._edge_type = sm_edge.Edge - self._node_type = Node - - # Add values for state machine states. - self.is_initial = False - self.is_final = False - - def toggle_node_state_initial(self): - """ - Toggles node "initial" state. - """ - if not self.is_initial: - self.is_initial = True - else: - self.is_initial = False - - def toggle_node_state_final(self): - """ - Toggles node "final" state. - """ - if not self.is_final: - self.is_final = True - else: - self.is_final = False diff --git a/tests/resources/basic_graph/edge.py b/tests/resources/basic_graph/edge.py index 652d681..0f19d66 100644 --- a/tests/resources/basic_graph/edge.py +++ b/tests/resources/basic_graph/edge.py @@ -12,15 +12,14 @@ Tests for "Basic Edge" class. import unittest # User Class Imports. -from resources.basic_graph.edge import Edge -from resources.basic_graph.node import Node +from resources.basic_graph.components import BasicEdge, BasicNode class TestBasicEdge(unittest.TestCase): def setUp(self): self.edge_name = 'Test Edge Name' self.node_name = 'Test Node Name' - self.test_edge = Edge(self.edge_name) + self.test_edge = BasicEdge(self.edge_name) def test__edge_initialization(self): self.assertEqual(self.test_edge.get_name(), self.edge_name) @@ -35,8 +34,8 @@ class TestBasicEdge(unittest.TestCase): def test__get_node_count(self): # Create nodes to connect. - node_1 = Node('Node 1') - node_2 = Node('Node 2') + node_1 = BasicNode('Node 1') + node_2 = BasicNode('Node 2') # Test with no nodes. self.assertEqual(self.test_edge.get_node_count(), 0) @@ -48,8 +47,8 @@ class TestBasicEdge(unittest.TestCase): def test__get_nodes__success(self): # Create nodes to connect. - node_1 = Node('Node 1') - node_2 = Node('Node 2') + node_1 = BasicNode('Node 1') + node_2 = BasicNode('Node 2') # Test with no nodes. self.assertEqual(self.test_edge.get_nodes(), ()) @@ -61,8 +60,8 @@ class TestBasicEdge(unittest.TestCase): def test__get_nodes__failure(self): # Create nodes to connect. - node_1 = Node('Node 1') - node_2 = Node('Node 2') + node_1 = BasicNode('Node 1') + node_2 = BasicNode('Node 2') with self.subTest('Failure - Only one node.'): with self.assertRaises(AttributeError): @@ -77,8 +76,8 @@ class TestBasicEdge(unittest.TestCase): def test__get_node__success(self): # Create and connect nodes. - node_1 = Node('Node 1') - node_2 = Node('Node 2') + node_1 = BasicNode('Node 1') + node_2 = BasicNode('Node 2') self.test_edge.connect_nodes(node_1, node_2) with self.subTest('Get node by Node class.'): @@ -105,7 +104,7 @@ class TestBasicEdge(unittest.TestCase): self.test_edge.get_node(None) with self.subTest('Node not connected to edge - by Node class.'): - node_1 = Node('Node 1') + node_1 = BasicNode('Node 1') with self.assertLogs(level='WARNING'): self.assertIsNone(self.test_edge.get_node(node_1)) @@ -115,8 +114,8 @@ class TestBasicEdge(unittest.TestCase): def test__get_connected_node__success(self): # Create nodes to connect. - node_1 = Node('Node 1') - node_2 = Node('Node 2') + node_1 = BasicNode('Node 1') + node_2 = BasicNode('Node 2') # Connect nodes. self.test_edge.connect_nodes(node_1, node_2) @@ -127,8 +126,8 @@ class TestBasicEdge(unittest.TestCase): def test__get_connected_node__failure(self): # Create nodes to connect. - node_1 = Node('Node 1') - node_2 = Node('Node 2') + node_1 = BasicNode('Node 1') + node_2 = BasicNode('Node 2') with self.subTest('Arg is not of type Node.'): with self.assertRaises(TypeError): @@ -174,8 +173,8 @@ class TestBasicEdge(unittest.TestCase): def test__connect_nodes__success(self): # Create nodes to connect. - node_1 = Node('Node 1') - node_2 = Node('Node 2') + node_1 = BasicNode('Node 1') + node_2 = BasicNode('Node 2') # Verify initial state. self.assertEqual(self.test_edge.get_node_count(), 0) @@ -191,8 +190,8 @@ class TestBasicEdge(unittest.TestCase): def test__connect_nodes__failure(self): # Create nodes to connect. - node_1 = Node('Node 1') - node_2 = Node('Node 2') + node_1 = BasicNode('Node 1') + node_2 = BasicNode('Node 2') with self.subTest('Arg 1 is not of type Node.'): # Should have 0 connected node from above subtests. @@ -221,7 +220,7 @@ class TestBasicEdge(unittest.TestCase): self.assertEqual(self.test_edge.get_node_count(), 0) # Test with duplicate Node names. - node_1_duplicate = Node(node_1.get_name()) + node_1_duplicate = BasicNode(node_1.get_name()) with self.assertRaises(ValueError): self.test_edge.connect_nodes(node_1, node_1_duplicate) @@ -262,14 +261,14 @@ class TestBasicEdge(unittest.TestCase): def test__connect_node_to_self(self): self.test_edge._nodes_can_self_connect = True - test_node = Node('Test Node') + test_node = BasicNode('Test Node') self.test_edge.connect_nodes(test_node, test_node) self.assertEqual(self.test_edge.get_nodes(), (test_node, test_node)) def test__disconnect_nodes__success(self): # Create and connect nodes. - node_1 = Node('Node 1') - node_2 = Node('Node 2') + node_1 = BasicNode('Node 1') + node_2 = BasicNode('Node 2') self.test_edge.connect_nodes(node_1, node_2) # Verify initial state. diff --git a/tests/resources/basic_graph/graph.py b/tests/resources/basic_graph/graph.py index 4748c4a..e3611fd 100644 --- a/tests/resources/basic_graph/graph.py +++ b/tests/resources/basic_graph/graph.py @@ -12,14 +12,13 @@ Tests for "Basic Graph" class. import unittest # User Class Imports. -from resources.basic_graph.edge import Edge -from resources.basic_graph.graph import Graph -from resources.basic_graph.node import Node +from resources.basic_graph.components import BasicEdge, BasicNode +from resources.basic_graph.graph import BasicGraph class TestBasicGraph(unittest.TestCase): def setUp(self): - self.test_graph = Graph() + self.test_graph = BasicGraph() def test__graph_initialization(self): self.assertEqual(self.test_graph.get_all_edges(), {}) @@ -48,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(Node(5)) - self.test_graph.add_node(Node(6)) - self.test_graph.add_node(Node(7)) + self.test_graph.add_node(BasicNode(5)) + self.test_graph.add_node(BasicNode(6)) + self.test_graph.add_node(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(Node(9)) + self.test_graph.add_node(BasicNode(9)) # Test that auto_name now provides 10. self.assertEqual(self.test_graph._get_node_auto_name(), 10) @@ -82,9 +81,9 @@ class TestBasicGraph(unittest.TestCase): self.assertEqual(4, self.test_graph._get_edge_auto_name()) # Manually add entries 5, 6, and 7 to graph. - edge_5 = Edge(5) - edge_6 = Edge(6) - edge_7 = Edge(7) + edge_5 = BasicEdge(5) + edge_6 = BasicEdge(6) + edge_7 = BasicEdge(7) self.test_graph._edges[edge_5.get_name()] = edge_5 self.test_graph._edges[edge_6.get_name()] = edge_6 self.test_graph._edges[edge_7.get_name()] = edge_7 @@ -93,7 +92,7 @@ class TestBasicGraph(unittest.TestCase): self.assertEqual(self.test_graph._get_edge_auto_name(), 8) # Manually add one more. - edge_9 = Edge(9) + edge_9 = BasicEdge(9) self.test_graph._edges[edge_9.get_name()] = edge_9 # Test that auto_name now provides 10. @@ -120,8 +119,8 @@ class TestBasicGraph(unittest.TestCase): # Works with 0, 1, and 2 nodes. Assuming works with all further n nodes. def test__get_all_nodes(self): - node_1 = Node(self.test_graph._get_node_auto_name()) - node_2 = Node(self.test_graph._get_node_auto_name()) + 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) @@ -148,7 +147,7 @@ class TestBasicGraph(unittest.TestCase): # Create nodes. node_1 = self.test_graph.create_node() node_2 = self.test_graph.create_node() - node_3 = Node('Node 3') + node_3 = BasicNode('Node 3') with self.subTest('Check by Node class.'): # Test node 1. @@ -200,7 +199,7 @@ class TestBasicGraph(unittest.TestCase): self.test_graph.get_node(None) with self.subTest('Node is not in graph - by Node class.'): - node_1 = Node(self.test_graph._get_node_auto_name()) + node_1 = BasicNode(self.test_graph._get_node_auto_name()) with self.assertLogs(level='WARNING'): self.assertIsNone(self.test_graph.get_node(node_1)) @@ -254,7 +253,7 @@ class TestBasicGraph(unittest.TestCase): self.test_graph.get_node_degree(None) with self.subTest('Node is not in graph - by Node Class.'): - node_1 = Node(self.test_graph._get_node_auto_name()) + 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)) @@ -317,7 +316,7 @@ class TestBasicGraph(unittest.TestCase): self.test_graph.get_edges_connected_to_node(None) with self.subTest('Node is not in graph - by Node Class.'): - node_1 = Node(self.test_graph._get_node_auto_name()) + 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)) @@ -393,7 +392,7 @@ class TestBasicGraph(unittest.TestCase): self.test_graph.get_connected_nodes(None) with self.subTest('Node is not in graph - by Node Class.'): - node_1 = Node(self.test_graph._get_node_auto_name()) + 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)) @@ -461,8 +460,8 @@ class TestBasicGraph(unittest.TestCase): def test__get_edge_count(self): # Create edges to add to graph. - edge_1 = Edge(self.test_graph._get_node_auto_name()) - edge_2 = Edge(self.test_graph._get_node_auto_name()) + 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) @@ -479,8 +478,8 @@ class TestBasicGraph(unittest.TestCase): def test__get_all_edges(self): # Create edges to add to graph. - edge_1 = Edge(self.test_graph._get_node_auto_name()) - edge_2 = Edge(self.test_graph._get_node_auto_name()) + 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(), {}) @@ -505,8 +504,8 @@ class TestBasicGraph(unittest.TestCase): node_1 = self.test_graph.create_node() node_2 = self.test_graph.create_node() node_3 = self.test_graph.create_node() - node_4 = Node('Node 4') - node_5 = Node('Node 5') + node_4 = BasicNode('Node 4') + node_5 = BasicNode('Node 5') # Create connections. edge_1 = self.test_graph.connect_nodes(node_1, node_2) @@ -566,7 +565,7 @@ class TestBasicGraph(unittest.TestCase): self.test_graph.get_edge(None) with self.subTest('Edge is not in graph - By Edge class.'): - edge_1 = Edge(self.test_graph._get_edge_auto_name()) + edge_1 = BasicEdge(self.test_graph._get_edge_auto_name()) with self.assertLogs(level='WARNING'): self.assertIsNone(self.test_graph.get_edge(edge_1)) @@ -598,7 +597,7 @@ class TestBasicGraph(unittest.TestCase): self.test_graph.get_nodes_connected_to_edge(None) with self.subTest('Edge is not in graph - By edge class.'): - edge_1 = Edge(self.test_graph._get_edge_auto_name()) + 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)) @@ -619,7 +618,7 @@ class TestBasicGraph(unittest.TestCase): # Test with no nodes. node_1 = self.test_graph.create_node() - self.assertTrue(isinstance(node_1, Node)) + self.assertTrue(isinstance(node_1, BasicNode)) self.assertEqual(self.test_graph.get_node_count(), 1) self.assertEqual(self.test_graph.get_all_nodes(), { node_1.get_name(): node_1, @@ -628,7 +627,7 @@ class TestBasicGraph(unittest.TestCase): # Test with one node. node_2 = self.test_graph.create_node() - self.assertTrue(isinstance(node_2, Node)) + self.assertTrue(isinstance(node_2, BasicNode)) self.assertEqual(self.test_graph.get_node_count(), 2) self.assertEqual(self.test_graph.get_all_nodes(), { node_1.get_name(): node_1, @@ -638,7 +637,7 @@ class TestBasicGraph(unittest.TestCase): # Test with two nodes. node_3 = self.test_graph.create_node() - self.assertTrue(isinstance(node_3, Node)) + self.assertTrue(isinstance(node_3, BasicNode)) self.assertEqual(self.test_graph.get_node_count(), 3) self.assertEqual(self.test_graph.get_all_nodes(), { node_1.get_name(): node_1, @@ -664,7 +663,7 @@ class TestBasicGraph(unittest.TestCase): # Test with no nodes. node_1 = self.test_graph.create_node(node_name='Node 1') - self.assertTrue(isinstance(node_1, Node)) + self.assertTrue(isinstance(node_1, BasicNode)) self.assertEqual(self.test_graph.get_node_count(), 1) self.assertEqual(self.test_graph.get_all_nodes(), { node_1.get_name(): node_1, @@ -673,7 +672,7 @@ class TestBasicGraph(unittest.TestCase): # Test with one node. node_2 = self.test_graph.create_node(node_name='Node 2') - self.assertTrue(isinstance(node_2, Node)) + self.assertTrue(isinstance(node_2, BasicNode)) self.assertEqual(self.test_graph.get_node_count(), 2) self.assertEqual(self.test_graph.get_all_nodes(), { node_1.get_name(): node_1, @@ -683,7 +682,7 @@ class TestBasicGraph(unittest.TestCase): # Test with two nodes. node_3 = self.test_graph.create_node(node_name='Node 3') - self.assertTrue(isinstance(node_3, Node)) + self.assertTrue(isinstance(node_3, BasicNode)) self.assertEqual(self.test_graph.get_node_count(), 3) self.assertEqual(self.test_graph.get_all_nodes(), { node_1.get_name(): node_1, @@ -697,9 +696,9 @@ class TestBasicGraph(unittest.TestCase): def test__add_node__success(self): with self.subTest('With basic, unconnected nodes.'): # Create nodes to connect. - node_1 = Node(self.test_graph._get_node_auto_name()) - node_2 = Node(self.test_graph._get_node_auto_name()) - node_3 = Node(self.test_graph._get_node_auto_name()) + node_1 = BasicNode(self.test_graph._get_node_auto_name()) + node_2 = BasicNode(self.test_graph._get_node_auto_name()) + node_3 = BasicNode(self.test_graph._get_node_auto_name()) # Verify start state. self.assertEqual(self.test_graph.get_node_count(), 0) @@ -738,15 +737,15 @@ class TestBasicGraph(unittest.TestCase): with self.subTest('With interconnected nodes - None in graph.'): # Create nodes to connect. - node_1 = Node(self.test_graph._get_node_auto_name()) - node_2 = Node(self.test_graph._get_node_auto_name()) - node_3 = Node(self.test_graph._get_node_auto_name()) - node_4 = Node(self.test_graph._get_node_auto_name()) - node_5 = Node(self.test_graph._get_node_auto_name()) - node_6 = Node(self.test_graph._get_node_auto_name()) - node_7 = Node(self.test_graph._get_node_auto_name()) - node_8 = Node(self.test_graph._get_node_auto_name()) - node_9 = Node(self.test_graph._get_node_auto_name()) + node_1 = BasicNode(self.test_graph._get_node_auto_name()) + node_2 = BasicNode(self.test_graph._get_node_auto_name()) + node_3 = BasicNode(self.test_graph._get_node_auto_name()) + node_4 = BasicNode(self.test_graph._get_node_auto_name()) + node_5 = BasicNode(self.test_graph._get_node_auto_name()) + node_6 = BasicNode(self.test_graph._get_node_auto_name()) + node_7 = BasicNode(self.test_graph._get_node_auto_name()) + node_8 = BasicNode(self.test_graph._get_node_auto_name()) + node_9 = BasicNode(self.test_graph._get_node_auto_name()) # Connect nodes. edge_1 = node_1.connect_node(node_2) @@ -834,14 +833,14 @@ class TestBasicGraph(unittest.TestCase): # Still accounting for it anyways to try to be flexible. # Create nodes to connect. - node_1 = Node(self.test_graph._get_node_auto_name()) + node_1 = BasicNode(self.test_graph._get_node_auto_name()) node_2 = self.test_graph.create_node() - node_3 = Node(self.test_graph._get_node_auto_name()) + node_3 = BasicNode(self.test_graph._get_node_auto_name()) node_4 = self.test_graph.create_node() - node_5 = Node(self.test_graph._get_node_auto_name()) - node_6 = Node(self.test_graph._get_node_auto_name()) + 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_8 = Node(self.test_graph._get_node_auto_name()) + node_8 = BasicNode(self.test_graph._get_node_auto_name()) node_9 = self.test_graph.create_node() # Connect nodes. @@ -927,7 +926,7 @@ class TestBasicGraph(unittest.TestCase): self.test_graph.add_node(1234) # Add node to graph for following subtests. - new_node = Node(self.test_graph._get_node_auto_name()) + new_node = BasicNode(self.test_graph._get_node_auto_name()) self.assertEqual(self.test_graph.get_node_count(), 0) # Add initial node. @@ -944,12 +943,12 @@ class TestBasicGraph(unittest.TestCase): def test__add_node_list__success(self): # Create nodes to add. - node_1 = Node(self.test_graph._get_node_auto_name()) - node_2 = Node(self.test_graph._get_node_auto_name()) - node_3 = Node(self.test_graph._get_node_auto_name()) - node_4 = Node(self.test_graph._get_node_auto_name()) - node_5 = Node(self.test_graph._get_node_auto_name()) - node_6 = Node(self.test_graph._get_node_auto_name()) + node_1 = BasicNode(self.test_graph._get_node_auto_name()) + node_2 = BasicNode(self.test_graph._get_node_auto_name()) + node_3 = BasicNode(self.test_graph._get_node_auto_name()) + node_4 = BasicNode(self.test_graph._get_node_auto_name()) + node_5 = BasicNode(self.test_graph._get_node_auto_name()) + node_6 = BasicNode(self.test_graph._get_node_auto_name()) with self.subTest('List is type list.'): # Create lists. @@ -1096,7 +1095,7 @@ class TestBasicGraph(unittest.TestCase): self.test_graph.remove_node(node_6) def test__add_node_list__failure(self): - node_1 = Node(self.test_graph._get_node_auto_name()) + 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): @@ -1325,7 +1324,7 @@ class TestBasicGraph(unittest.TestCase): self.test_graph.remove_node(None) with self.subTest('Node is not in graph - by Node class.'): - node_1 = Node(self.test_graph._get_node_auto_name()) + node_1 = BasicNode(self.test_graph._get_node_auto_name()) with self.assertLogs(level='WARNING'): self.assertIsNone(self.test_graph.get_node(node_1)) @@ -1358,7 +1357,7 @@ class TestBasicGraph(unittest.TestCase): self.assertEqual(node_3.get_edge_count(), 0) self.assertEqual(node_4.get_edge_count(), 0) # Check connection that was made. - self.assertTrue(isinstance(edge_1, Edge)) + self.assertTrue(isinstance(edge_1, BasicEdge)) connected_node_1, connected_node_2 = edge_1.get_nodes() self.assertEqual(connected_node_1, node_1) self.assertEqual(connected_node_2, node_2) @@ -1371,7 +1370,7 @@ class TestBasicGraph(unittest.TestCase): self.assertEqual(node_3.get_edge_count(), 1) self.assertEqual(node_4.get_edge_count(), 0) # Check connection that was made. - self.assertTrue(isinstance(edge_2, Edge)) + self.assertTrue(isinstance(edge_2, BasicEdge)) connected_node_1, connected_node_3 = edge_2.get_nodes() self.assertEqual(connected_node_1, node_1) self.assertEqual(connected_node_3, node_3) @@ -1384,7 +1383,7 @@ class TestBasicGraph(unittest.TestCase): self.assertEqual(node_3.get_edge_count(), 1) self.assertEqual(node_4.get_edge_count(), 1) # Check connection that was made. - self.assertTrue(isinstance(edge_3, Edge)) + self.assertTrue(isinstance(edge_3, BasicEdge)) connected_node_1, connected_node_4 = edge_3.get_nodes() self.assertEqual(connected_node_1, node_1) self.assertEqual(connected_node_4, node_4) @@ -1678,9 +1677,9 @@ class TestBasicGraph(unittest.TestCase): self.test_graph.disconnect_nodes(node_1_identifier='1', edge_identifier='2') # Create nodes for following tests. - node_1 = Node(self.test_graph._get_node_auto_name()) - node_2 = Node(self.test_graph._get_node_auto_name()) - edge_1 = Edge(self.test_graph._get_edge_auto_name()) + node_1 = BasicNode(self.test_graph._get_node_auto_name()) + node_2 = BasicNode(self.test_graph._get_node_auto_name()) + edge_1 = BasicEdge(self.test_graph._get_edge_auto_name()) # Add only one node to graph. self.test_graph.add_node(node_1) diff --git a/tests/resources/basic_graph/node.py b/tests/resources/basic_graph/node.py index 3de9d1a..b91e1b2 100644 --- a/tests/resources/basic_graph/node.py +++ b/tests/resources/basic_graph/node.py @@ -12,15 +12,14 @@ Tests for "Basic Node" class. import unittest # User Class Imports. -from resources.basic_graph.edge import Edge -from resources.basic_graph.node import Node +from resources.basic_graph.components import BasicEdge, BasicNode class TestBasicNode(unittest.TestCase): def setUp(self): self.edge_name = 'Test Edge Name' self.node_name = 'Test Node Name' - self.test_node = Node(self.node_name) + self.test_node = BasicNode(self.node_name) def test__node_initialization(self): self.assertEqual(self.test_node.get_name(), self.node_name) @@ -36,8 +35,8 @@ class TestBasicNode(unittest.TestCase): def test__get_edge_count(self): # Create nodes to connect. - node_1 = Node('Node 1') - node_2 = Node('Node 2') + node_1 = BasicNode('Node 1') + node_2 = BasicNode('Node 2') # Test with no connections. self.assertEqual(self.test_node.get_edge_count(), 0) @@ -54,8 +53,8 @@ class TestBasicNode(unittest.TestCase): def test__get_connected_node_count(self): # Create nodes to connect. - node_1 = Node('Node 1') - node_2 = Node('Node 2') + node_1 = BasicNode('Node 1') + node_2 = BasicNode('Node 2') # Test with no connections. self.assertEqual(self.test_node.get_connected_node_count(), 0) @@ -72,8 +71,8 @@ class TestBasicNode(unittest.TestCase): def test__get_edges(self): # Create nodes to connect. - node_1 = Node('Node 1') - node_2 = Node('Node 2') + node_1 = BasicNode('Node 1') + node_2 = BasicNode('Node 2') # Test with no connections. self.assertEqual(self.test_node.get_edges(), {}) @@ -95,8 +94,8 @@ class TestBasicNode(unittest.TestCase): def test__get_connected_nodes(self): # Create nodes to connect. - node_1 = Node('Node 1') - node_2 = Node('Node 2') + node_1 = BasicNode('Node 1') + node_2 = BasicNode('Node 2') # Test with no connections. self.assertEqual(self.test_node.get_edges(), {}) @@ -118,8 +117,8 @@ class TestBasicNode(unittest.TestCase): def test__get_edge__success(self): # Create and connect nodes. - node_1 = Node('Node 1') - node_2 = Node('Node 2') + node_1 = BasicNode('Node 1') + node_2 = BasicNode('Node 2') edge_1 = self.test_node.connect_node(node_1) edge_2 = self.test_node.connect_node(node_2) @@ -147,7 +146,7 @@ class TestBasicNode(unittest.TestCase): self.test_node.get_edge(None) with self.subTest('Edge not connected to node - by Edge class.'): - edge_1 = Edge('Edge 1') + edge_1 = BasicEdge('Edge 1') with self.assertLogs(level='WARNING'): self.assertIsNone(self.test_node.get_edge(edge_1)) @@ -157,8 +156,8 @@ class TestBasicNode(unittest.TestCase): def test__get_edge_by_connected_node__success(self): # Create and connect nodes. - node_1 = Node('Node 1') - node_2 = Node('Node 2') + node_1 = BasicNode('Node 1') + node_2 = BasicNode('Node 2') edge_1 = self.test_node.connect_node(node_1) edge_2 = self.test_node.connect_node(node_2) @@ -186,7 +185,7 @@ class TestBasicNode(unittest.TestCase): self.test_node.get_edge_by_connected_node(None) with self.subTest('Node not found in connections - by Node class.'): - node_1 = Node('Node 1') + node_1 = BasicNode('Node 1') with self.assertLogs(level='WARNING'): self.assertIsNone(self.test_node.get_edge_by_connected_node(node_1)) @@ -196,9 +195,9 @@ class TestBasicNode(unittest.TestCase): def test__determine_node_adjacency__success(self): # Create nodes to connect. - node_1 = Node('Node 1') - node_2 = Node('Node 2') - node_3 = Node('Node 3') + node_1 = BasicNode('Node 1') + node_2 = BasicNode('Node 2') + node_3 = BasicNode('Node 3') # Connect nodes 1 and 3. self.test_node.connect_node(node_1) @@ -242,9 +241,9 @@ class TestBasicNode(unittest.TestCase): def test__connect_node__success(self): with self.subTest('With automatic edge names.'): # Create nodes to connect. - node_1 = Node('Node 1') - node_2 = Node('Node 2') - node_3 = Node('Node 3') + node_1 = BasicNode('Node 1') + node_2 = BasicNode('Node 2') + node_3 = BasicNode('Node 3') # Test with no connections. edge_1 = self.test_node.connect_node(node_1) @@ -254,7 +253,7 @@ class TestBasicNode(unittest.TestCase): edge_1.get_name(): edge_1, }) # Check new edge values. - self.assertTrue(isinstance(edge_1, Edge)) + self.assertTrue(isinstance(edge_1, BasicEdge)) self.assertEqual(edge_1.get_name(), '{0} to Node 1'.format(self.node_name)) # Test with one connection. @@ -266,7 +265,7 @@ class TestBasicNode(unittest.TestCase): edge_2.get_name(): edge_2, }) # Check new edge values. - self.assertTrue(isinstance(edge_2, Edge)) + self.assertTrue(isinstance(edge_2, BasicEdge)) self.assertEqual(edge_2.get_name(), '{0} to Node 2'.format(self.node_name)) # Test with one connections. @@ -279,19 +278,19 @@ class TestBasicNode(unittest.TestCase): edge_3.get_name(): edge_3, }) # Check new edge values. - self.assertTrue(isinstance(edge_3, Edge)) + self.assertTrue(isinstance(edge_3, BasicEdge)) self.assertEqual(edge_3.get_name(), '{0} to Node 3'.format(self.node_name)) # Works with 0, 1, and 2 connections. Assuming works with all further n connections. with self.subTest('With manual edge names.'): # Reset node cuz subtests. - self.test_node = Node(self.node_name) + self.test_node = BasicNode(self.node_name) # Create nodes to connect. - node_1 = Node('Node 1') - node_2 = Node('Node 1') - node_3 = Node('Node 1') + node_1 = BasicNode('Node 1') + node_2 = BasicNode('Node 1') + node_3 = BasicNode('Node 1') # Test with no connections. edge_1 = self.test_node.connect_node(node_1, edge_name='Test Edge 1') @@ -301,7 +300,7 @@ class TestBasicNode(unittest.TestCase): edge_1.get_name(): edge_1, }) # Check new edge values. - self.assertTrue(isinstance(edge_1, Edge)) + self.assertTrue(isinstance(edge_1, BasicEdge)) self.assertEqual(edge_1.get_name(), 'Test Edge 1') # Test with one connection. @@ -313,7 +312,7 @@ class TestBasicNode(unittest.TestCase): edge_2.get_name(): edge_2, }) # Check new edge values. - self.assertTrue(isinstance(edge_2, Edge)) + self.assertTrue(isinstance(edge_2, BasicEdge)) self.assertEqual(edge_2.get_name(), 'Test Edge 2') # Test with one connections. @@ -326,7 +325,7 @@ class TestBasicNode(unittest.TestCase): edge_3.get_name(): edge_3, }) # Check new edge values. - self.assertTrue(isinstance(edge_3, Edge)) + self.assertTrue(isinstance(edge_3, BasicEdge)) self.assertEqual(edge_3.get_name(), 'Test Edge 3') # Works with 0, 1, and 2 connections. Assuming works with all further n connections. @@ -338,9 +337,9 @@ class TestBasicNode(unittest.TestCase): def test__disconnect_node__success(self): # Create nodes to connect. - node_1 = Node('Node 1') - node_2 = Node('Node 2') - node_3 = Node('Node 3') + node_1 = BasicNode('Node 1') + node_2 = BasicNode('Node 2') + node_3 = BasicNode('Node 3') with self.subTest('Disconnect by Node class'): # Connect nodes. @@ -715,10 +714,10 @@ class TestBasicNode(unittest.TestCase): # Create at least one connection to avoid accidentally replicating above "no connections present" subtest. self.assertEqual(self.test_node.get_edge_count(), 0) - node_1 = Node('Node 1') - node_2 = Node('Node 2') + node_1 = BasicNode('Node 1') + node_2 = BasicNode('Node 2') edge_1 = self.test_node.connect_node(node_1) - edge_2 = Edge('Edge 2') + edge_2 = BasicEdge('Edge 2') with self.subTest('No args provided.'): # Should have one connection, from above subtests. diff --git a/tests/resources/directed_graph/edge.py b/tests/resources/directed_graph/edge.py index 74d6a00..63b4202 100644 --- a/tests/resources/directed_graph/edge.py +++ b/tests/resources/directed_graph/edge.py @@ -12,15 +12,14 @@ Tests for "Directed Edge" class. import unittest # User Class Imports. -from resources.directed_graph.edge import Edge -from resources.directed_graph.node import Node +from resources.directed_graph.components import DirectedEdge, DirectedNode class TestDirectedEdge(unittest.TestCase): def setUp(self): - self.test_edge = Edge('Test Edge') - self.head_node = Node('Head Node') - self.tail_node = Node('Tail Node') + self.test_edge = DirectedEdge('Test Edge') + self.head_node = DirectedNode('Head Node') + self.tail_node = DirectedNode('Tail Node') #region Information Functions diff --git a/tests/resources/directed_graph/graph.py b/tests/resources/directed_graph/graph.py index 9ffba73..815deac 100644 --- a/tests/resources/directed_graph/graph.py +++ b/tests/resources/directed_graph/graph.py @@ -12,27 +12,26 @@ Tests for "Directed Graph" class. import unittest # User Class Imports. -from resources.directed_graph.edge import Edge -from resources.directed_graph.graph import Graph -from resources.directed_graph.node import Node +from resources.directed_graph.components import DirectedEdge, DirectedNode +from resources.directed_graph.graph import DirectedGraph class TestDirectedGraph(unittest.TestCase): def setUp(self): - self.test_graph = Graph() + self.test_graph = DirectedGraph() def test__create_node(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() - self.assertTrue(isinstance(node_1, Node)) + self.assertTrue(isinstance(node_1, DirectedNode)) def test__remove_node(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) - self.assertTrue(isinstance(node_1, Node)) + self.assertTrue(isinstance(node_1, DirectedNode)) def test__connect_node(self): # We have pretty thorough testing of the parent function. @@ -40,7 +39,7 @@ class TestDirectedGraph(unittest.TestCase): 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) - self.assertTrue(isinstance(edge_1, Edge)) + self.assertTrue(isinstance(edge_1, DirectedEdge)) def test__disconnect_node(self): # We have pretty thorough testing of the parent function. @@ -49,4 +48,4 @@ class TestDirectedGraph(unittest.TestCase): 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) - self.assertTrue(isinstance(edge_1, Edge)) + self.assertTrue(isinstance(edge_1, DirectedEdge)) diff --git a/tests/resources/directed_graph/node.py b/tests/resources/directed_graph/node.py index 193ad3c..b3d0644 100644 --- a/tests/resources/directed_graph/node.py +++ b/tests/resources/directed_graph/node.py @@ -12,20 +12,19 @@ Tests for "Directed Node" class. import unittest # User Class Imports. -from resources.directed_graph.edge import Edge -from resources.directed_graph.node import Node +from resources.directed_graph.components import DirectedEdge, DirectedNode class TestDirectedNode(unittest.TestCase): def setUp(self): - self.test_node = Node('Test Node') + self.test_node = DirectedNode('Test Node') #region Information Functions def test__get_outgoing_edges(self): # Create nodes to connect. - node_1 = Node('Node 1') - node_2 = Node('Node 2') + node_1 = DirectedNode('Node 1') + node_2 = DirectedNode('Node 2') # Test getting outgoing edges with 0 connections. self.assertEqual(self.test_node.get_outgoing_edges(), []) @@ -42,8 +41,8 @@ class TestDirectedNode(unittest.TestCase): def test__get_incoming_edges(self): # Create nodes to connect. - node_1 = Node('Node 1') - node_2 = Node('Node 2') + node_1 = DirectedNode('Node 1') + node_2 = DirectedNode('Node 2') # Test getting outgoing edges with 0 connections. self.assertEqual(self.test_node.get_incoming_edges(), []) @@ -60,8 +59,8 @@ class TestDirectedNode(unittest.TestCase): def test__get_outgoing_nodes(self): # Create nodes to connect. - node_1 = Node('Node 1') - node_2 = Node('Node 2') + node_1 = DirectedNode('Node 1') + node_2 = DirectedNode('Node 2') # Test getting outgoing edges with 0 connections. self.assertEqual(self.test_node.get_outgoing_nodes(), []) @@ -78,8 +77,8 @@ class TestDirectedNode(unittest.TestCase): def test__get_incoming_nodes(self): # Create nodes to connect. - node_1 = Node('Node 1') - node_2 = Node('Node 2') + node_1 = DirectedNode('Node 1') + node_2 = DirectedNode('Node 2') # Test getting outgoing edges with 0 connections. self.assertEqual(self.test_node.get_incoming_nodes(), []) @@ -103,18 +102,18 @@ class TestDirectedNode(unittest.TestCase): # Thus, just test that neighboring order (head/tail) is properly observed. # Create nodes to connect. - node_1 = Node('Node 1') - node_2 = Node('Node 2') + node_1 = DirectedNode('Node 1') + node_2 = DirectedNode('Node 2') # Test connection where neighbor node is head. edge_1 = self.test_node.connect_node(node_1, direct_towards_neighbor=True) - self.assertTrue(isinstance(edge_1, Edge)) + self.assertTrue(isinstance(edge_1, DirectedEdge)) self.assertEqual(self.test_node.get_edge_by_connected_node(node_1).get_tail_node(), self.test_node) self.assertEqual(self.test_node.get_edge_by_connected_node(node_1).get_head_node(), node_1) # Test connection where neighbor node is tail. edge_2 = self.test_node.connect_node(node_2, direct_towards_neighbor=False) - self.assertTrue(isinstance(edge_2, Edge)) + self.assertTrue(isinstance(edge_2, DirectedEdge)) self.assertEqual(self.test_node.get_edge_by_connected_node(node_2).get_tail_node(), node_2) self.assertEqual(self.test_node.get_edge_by_connected_node(node_2).get_head_node(), self.test_node) @@ -126,9 +125,9 @@ class TestDirectedNode(unittest.TestCase): def test__disconnect_node(self): # We have pretty thorough testing of the parent function. # Thus, just test returned edge is of "Directed" type. - node_1 = Node('Node 1') + node_1 = DirectedNode('Node 1') self.test_node.connect_node(node_1) edge_1 = self.test_node.disconnect_node(node_identifier=node_1) - self.assertTrue(isinstance(edge_1, Edge)) + self.assertTrue(isinstance(edge_1, DirectedEdge)) #endregion Upkeep Functions diff --git a/tests/resources/state_machine/edge.py b/tests/resources/state_machine/edge.py index 390b81b..f3b092c 100644 --- a/tests/resources/state_machine/edge.py +++ b/tests/resources/state_machine/edge.py @@ -12,15 +12,14 @@ Tests for "State Machine Edge" class. import unittest # User Class Imports. -from resources.state_machine.edge import Edge -from resources.state_machine.node import Node +from resources.state_machine.components import StateMachineEdge, StateMachineNode class TestStateMachineEdge(unittest.TestCase): def setUp(self): - self.test_edge = Edge('Test Edge') - self.head_node = Node('Head Node') - self.tail_node = Node('Tail Node') + self.test_edge = StateMachineEdge('Test Edge') + self.head_node = StateMachineNode('Head Node') + self.tail_node = StateMachineNode('Tail Node') def test__edge_initialization(self): self.assertEqual(self.test_edge.state_change_conditions, []) diff --git a/tests/resources/state_machine/graph.py b/tests/resources/state_machine/graph.py index 50b86d6..af35200 100644 --- a/tests/resources/state_machine/graph.py +++ b/tests/resources/state_machine/graph.py @@ -12,14 +12,13 @@ Tests for "State Machine Graph" class. import unittest # User Class Imports. -from resources.state_machine.edge import Edge -from resources.state_machine.graph import Graph -from resources.state_machine.node import Node +from resources.state_machine.components import StateMachineEdge, StateMachineNode +from resources.state_machine.graph import StateMachineGraph class TestDirectedGraph(unittest.TestCase): def setUp(self): - self.test_graph = Graph() + self.test_graph = StateMachineGraph() def test__connect_nodes(self): # Create nodes to connect. @@ -42,7 +41,7 @@ class TestDirectedGraph(unittest.TestCase): self.assertEqual(node_3.get_edge_count(), 0) self.assertEqual(node_4.get_edge_count(), 0) # Check connection that was made. - self.assertTrue(isinstance(edge_1, Edge)) + self.assertTrue(isinstance(edge_1, StateMachineEdge)) connected_node_1, connected_node_2 = edge_1.get_nodes().values() self.assertEqual(connected_node_1, node_1) self.assertEqual(connected_node_2, node_2) @@ -56,7 +55,7 @@ class TestDirectedGraph(unittest.TestCase): self.assertEqual(node_3.get_edge_count(), 1) self.assertEqual(node_4.get_edge_count(), 0) # Check connection that was made. - self.assertTrue(isinstance(edge_2, Edge)) + self.assertTrue(isinstance(edge_2, StateMachineEdge)) connected_node_1, connected_node_3 = edge_2.get_nodes().values() self.assertEqual(connected_node_1, node_1) self.assertEqual(connected_node_3, node_3) @@ -70,7 +69,7 @@ class TestDirectedGraph(unittest.TestCase): self.assertEqual(node_3.get_edge_count(), 1) self.assertEqual(node_4.get_edge_count(), 1) # Check connection that was made. - self.assertTrue(isinstance(edge_3, Edge)) + self.assertTrue(isinstance(edge_3, StateMachineEdge)) connected_node_1, connected_node_4 = edge_3.get_nodes().values() self.assertEqual(connected_node_1, node_1) self.assertEqual(connected_node_4, node_4) diff --git a/tests/resources/state_machine/node.py b/tests/resources/state_machine/node.py index d745c64..8bccf7a 100644 --- a/tests/resources/state_machine/node.py +++ b/tests/resources/state_machine/node.py @@ -12,12 +12,12 @@ Tests for "State Machine Node" class. import unittest # User Class Imports. -from resources.state_machine.node import Node +from resources.state_machine.components import StateMachineEdge, StateMachineNode class TestStateMachineNode(unittest.TestCase): def setUp(self): - self.test_node = Node('Test Node') + self.test_node = StateMachineNode('Test Node') def test__node_initialization(self): self.assertFalse(self.test_node.is_initial) -- GitLab