def test_add_neighbors_at_init(self): """ Test for passing multiple neighbors at initialising a Node. This includes a 500k node stress test. The test involves passing a large number of nodes and making sure the contents returned by the get_neighbors method is the same as what was passed at init. """ # adding 5000 neighbors at init as a set neighbor_set = set() for _ in range(5000): neighbor_set.add(Node()) many_node = Node(neighbor_set) self.assertEqual(many_node.get_neighbors(), neighbor_set, "Passing a large Neighbor list at Node Init fails") # stress test with set neighbor_set = set() for _ in range(500000): neighbor_set.add(Node()) many_node = Node(neighbor_set) self.assertEqual( many_node.get_neighbors(), neighbor_set, "Passing a VERY large Neighbor list at Node Init fails") # adding neighbors at init as a list neighbor_list = [] for _ in range(50): neighbor_list.append(Node()) many_node = Node(neighbor_list) self.assertEqual(many_node.get_neighbors(), set(neighbor_list), "Passing a large Neighbor list at Node Init fails")
def test_neighbor_already_added(self): """ Tests situations where there is an attempt to add an existing neighbor. The expected handling of this is that there is no change to the neighbors as a Set is being used. """ neighbor_a = Node() neighbor_b = Node() neighbors = [neighbor_a, neighbor_b] neighbor_c = Node(neighbors) previous_size = len(neighbor_c.get_neighbors()) for each in neighbors: neighbor_c.add_neighbor(each) self.assertEqual(previous_size, len(neighbor_c.get_neighbors()), "Adding existing neighbors adds to the neighbor set")
def test_add_neighbor(self): """ Tests adding a neighbor using the add_neighbor method. The expected response is that an added node is returned via the get_neighbors() method. :return: """ neighbor = Node() neighbor.add_neighbor(self.node_a) # Make sure the added node is accessible through the get method self.assertIs(neighbor.get_neighbors().pop(), self.node_a, "Neighbor not added") # Make sure the neighbor is not automatically updated as well self.assertEqual( self.node_a.get_neighbors(), set(), 'Neighbor list should not be updated automatically @Directed')
def test_add_neighbor_at_init(self): """ Test for passing a one neighbor as an argument when initializing a node. Fails if added neighbor: - Is not returned in node.get_neighbors() - Has the new node added to its neighbor list automatically (i.e. non-directed edges) """ neighbor = Node([self.node_a ]) # initialise a new node to use for this test # Make sure the added node is accessible through the get method self.assertIs(neighbor.get_neighbors().pop(), self.node_a, "Neighbor not added") # Make sure the neighbor is not automatically updated self.assertEqual( self.node_a.get_neighbors(), set(), "Neighbor list should not be updated automatically @Directed") # Make sure passing a Node instead of a list is handled correctly with self.assertRaises(AssertionError): Node(neighbor)
class BasicGraphTest(unittest.TestCase): def setUp(self): """Call before every test case.""" self.graph_a = Graph(name="myGraph") # Simple graph with three nodes self.node1 = Node(label='node1') self.node2 = Node(label='node2') self.node3 = Node(label='node3') self.graph_a.add_node(self.node1) self.graph_a.add_node(self.node2, neighbors={self.node1}) self.graph_a.add_node(self.node3, neighbors={self.node1}) def tearDown(self): """Call after every test case.""" def test_init(self): """ Tests that everything done in the setUp method works correctly. This test includes - Confirming that the internal graph of form {<node1>:{<neighbor1>,<neighbor2>},...} is updated - Confirming that the internal weights of form {(<node1>,<node2>):weight),...} is updated - Confirming node.neighbors is updated. - Confirming that node.neighbors and node.weights always reflect each other. """ self.assertEqual(len(self.graph_a._graph), 3, "Node seems to be missing from _graph") self.assertEqual(len(self.graph_a._weights), 2, "Weight seems to be missing from _weights ") self.assertEqual( self.node2.get_neighbors(), {self.node1}, "Neighbor doesn't seem to be added at the node level") self.assertEqual( self.node3.get_neighbors(), {self.node1}, "Neighbor doesn't seem to be added at the node level") for node in self.graph_a._graph.keys(): neighbors = node.get_neighbors() if neighbors: for neighbor in neighbors: self.assertIn( (node, neighbor), self.graph_a._weights, "Weights don't seem to have updated correctly") def test_has_node(self): """ Test the has_node() method. The expectation is that passing any node that has been added to the graph returns True. :return: """ # hasNode successful cases self.assertTrue(self.graph_a.has_node(self.node1), "has_node() returning False when it should not") self.assertTrue(self.graph_a.has_node(self.node2), "has_node() returning False when it should not") self.assertTrue(self.graph_a.has_node(self.node3), "has_node() returning False when it should not") # hasNode failure cases fail_node1 = Node() # node that has been added as a neighbor outside of the graph fail_neighbor = Node() fail_node2 = Node(neighbors={fail_neighbor}) self.graph_a.add_node(fail_node2) # make sure node that has not been added returns false self.assertFalse( self.graph_a.has_node(fail_node1), "has_node() returns True for a node that has not been added") self.assertTrue(self.graph_a.has_node(fail_node2), "has_node() returning False when it should not") error_msg = "Returns True for node that has been added as a neighbor outside of the graph" self.assertFalse(self.graph_a.has_node(fail_neighbor), error_msg) def test_has_edge(self): """ Tests the has_edge method. The expectation is that passing any edge (directed) that has been added to the graph returns True. - Tests that the function returns True when expected - Tests that the function returns False when expected - Tests that the function raises an exception when either of the nodes are not in the graph :return: """ # hasEdge successful cases self.assertTrue(self.graph_a.has_edge(self.node2, self.node1), "has_edge() returning False when it should not") self.assertTrue(self.graph_a.has_edge(self.node3, self.node1), "has_edge() returning False when it should not") # hasEdge fail cases self.assertFalse(self.graph_a.has_edge(self.node1, self.node2), "has_edge() returning True when it should not") self.assertFalse(self.graph_a.has_edge(self.node1, self.node3), "has_edge() returning True when it should not") self.assertFalse(self.graph_a.has_edge(self.node3, self.node3), "has_edge() returning True for not-added self-edge") self.assertRaises(AssertionError, self.graph_a.has_edge, self.node1, Node()) self.assertRaises(AssertionError, self.graph_a.has_edge, Node(), self.node1) self.assertRaises(AssertionError, self.graph_a.has_edge, self.node2, Node({self.node2})) fail_node1 = Node() fail_neighbor = Node({fail_node1}) self.assertRaises(AssertionError, self.graph_a.has_edge, fail_node1, fail_neighbor) self.assertRaises(AssertionError, self.graph_a.has_edge, fail_neighbor, fail_node1) def test_add_node(self): """ Tests the add_node() method :return: """ # true cases self.assertIn(self.node1, self.graph_a._graph, "has_node failed to add nodes") self.assertIn(self.node2, self.graph_a._graph, "has_node failed to add nodes") self.assertIn(self.node3, self.graph_a._graph, "has_node failed to add nodes") # fail cases node4 = Node() node5 = Node() # incorrectly passed node #self.assertRaises(AssertionError,self.graph_a.add_node,(node4,node5)) self.assertRaises(AssertionError, self.graph_a.add_node, None) # incorrectly passed neighbors self.assertRaises(AssertionError, self.graph_a.add_node, node4, node5) self.assertRaises(AssertionError, self.graph_a.add_node, node5, node5) def test_add_edge(self): """ Tests adding edges between two existing nodes using the add_edge() method :return: """ # generic/correct use self.graph_a.add_edge(self.node2, self.node3) self.assertIn( (self.node2, self.node3), self.graph_a._weights) # tests that it was added to weights self.assertIn(self.node3, self.graph_a._graph[ self.node2]) # tests that it was added to _graph # adding multiple edges neighbor_list = [] for _ in range(400): temp_node = Node() neighbor_list.append(temp_node) self.graph_a.add_node(temp_node) self.graph_a.add_edge(self.node3, temp_node) for neighbor in neighbor_list: self.assertIn((self.node3, neighbor), self.graph_a._weights.keys() ) # tests that it was added to weights self.assertIn(neighbor, self.graph_a._graph[ self.node3]) # tests that it was added to _graph # add a -> b and b -> a for neighbor in neighbor_list: self.graph_a.add_edge(neighbor, self.node3) for neighbor in neighbor_list: self.assertIn((neighbor, self.node3), self.graph_a._weights.keys() ) # tests that it was added to weights self.assertIn(self.node3, self.graph_a._graph[neighbor] ) # tests that it was added to _graph def test_delete_node(self): """ test the delete_node method""" self.graph_a.add_edge(self.node1, self.node3) self.assertIn((self.node1, self.node3), self.graph_a._weights) self.assertIn((self.node3, self.node1), self.graph_a._weights) self.assertTrue(self.graph_a.has_node(self.node1)) self.graph_a.delete_node(self.node1) print(self.graph_a.get_all_edges(stringify=True)) self.assertFalse(self.graph_a.has_node(self.node1)) # confirm that the internal methods for clearing out the relationships were successful self.assertNotIn((self.node1, self.node3), self.graph_a._weights) self.assertNotIn((self.node3, self.node1), self.graph_a._weights) self.assertRaises(KeyError, self.graph_a._graph.__getitem__, self.node1) # confirm _graph neighbors have been deleted for node, neighbors in self.graph_a._graph.items(): print(self.node1, "|||", node) self.assertNotIn(self.node1, neighbors) self.assertNotIn(self.node1, self.graph_a._graph.keys()) def test_incoming_node_neighbors(self): self.assertEqual(self.graph_a.get_incoming_neighbors(self.node1), {self.node2, self.node3}) def test_thresholding(self): self.graph_a.add_edge(self.node1, self.node3, 4) self.graph_a.add_edge(self.node1, self.node2, 2) print(self.graph_a.get_threshold(25)) def test_save_graph(self): self.graph_a.load_save(self.graph_a.get_save())
def test_add_neighbors(self): """ Test adding multiple neighbors to the node via add_neighbor() Includes multiple stress tests and attempts adding different types of sequences. :return: """ neighbor_a = Node() neighbor_a.add_neighbor(*[self.node_a]) self.assertIs(neighbor_a.get_neighbors().pop(), self.node_a, "Neighbor not added") self.assertEqual( self.node_a.get_neighbors(), set(), "Neighbor list should not be updated automatically @Directed") # test passing a set assert len(self.node_a.get_neighbors()) == 0, "Test is incorrect" neighbor_set = set() for _ in range(500): neighbor_set.add(Node()) self.node_a.add_neighbor(*neighbor_set) self.assertEqual(len(self.node_a.get_neighbors() - neighbor_set), 0) for _ in range(500000): neighbor_set.add(Node()) self.node_a.add_neighbor(*neighbor_set) self.assertEqual(len(self.node_a.get_neighbors()), 500000 + 500) self.assertEqual(len(self.node_a.get_neighbors() - neighbor_set), 0) # test passing a list neighbor_list = [] node_b = Node() for _ in range(500): neighbor_list.append(Node()) node_b.add_neighbor(*neighbor_list) self.assertEqual(len(node_b.get_neighbors() - set(neighbor_list)), 0) for _ in range(500000): neighbor_list.append(Node()) node_b.add_neighbor(*neighbor_list) self.assertEqual(len(node_b.get_neighbors()), 500000 + 500) self.assertEqual(len(node_b.get_neighbors() - set(neighbor_list)), 0) # test passing a tuple neighbor_list = [] node_b = Node() for _ in range(500): neighbor_list.append(Node()) neighbor_list = tuple(neighbor_list) node_b.add_neighbor(*neighbor_list) self.assertEqual(len(node_b.get_neighbors() - set(neighbor_list)), 0) # failure cases neighbor_set = set() for i in range(500): neighbor_set.add(i) neighbor_list = [] for i in range(500): neighbor_list.append(i) with self.assertRaises(AssertionError): self.node_a.add_neighbor(*neighbor_set) with self.assertRaises(AssertionError): self.node_a.add_neighbor(*neighbor_list) node_c = Node([node_b]) self.node_a.add_neighbor(*[node_b, node_c]) neighbor_list = self.node_a.get_neighbors() self.assertIn(node_b, neighbor_list) self.assertIn(node_c, neighbor_list)
class NodeTest(unittest.TestCase): def setUp(self): """Call before every test case.""" self.node_a = Node() def tearDown(self): """Call after every test case.""" gc.collect() def test_add_neighbor_at_init(self): """ Test for passing a one neighbor as an argument when initializing a node. Fails if added neighbor: - Is not returned in node.get_neighbors() - Has the new node added to its neighbor list automatically (i.e. non-directed edges) """ neighbor = Node([self.node_a ]) # initialise a new node to use for this test # Make sure the added node is accessible through the get method self.assertIs(neighbor.get_neighbors().pop(), self.node_a, "Neighbor not added") # Make sure the neighbor is not automatically updated self.assertEqual( self.node_a.get_neighbors(), set(), "Neighbor list should not be updated automatically @Directed") # Make sure passing a Node instead of a list is handled correctly with self.assertRaises(AssertionError): Node(neighbor) def test_add_neighbors_at_init(self): """ Test for passing multiple neighbors at initialising a Node. This includes a 500k node stress test. The test involves passing a large number of nodes and making sure the contents returned by the get_neighbors method is the same as what was passed at init. """ # adding 5000 neighbors at init as a set neighbor_set = set() for _ in range(5000): neighbor_set.add(Node()) many_node = Node(neighbor_set) self.assertEqual(many_node.get_neighbors(), neighbor_set, "Passing a large Neighbor list at Node Init fails") # stress test with set neighbor_set = set() for _ in range(500000): neighbor_set.add(Node()) many_node = Node(neighbor_set) self.assertEqual( many_node.get_neighbors(), neighbor_set, "Passing a VERY large Neighbor list at Node Init fails") # adding neighbors at init as a list neighbor_list = [] for _ in range(50): neighbor_list.append(Node()) many_node = Node(neighbor_list) self.assertEqual(many_node.get_neighbors(), set(neighbor_list), "Passing a large Neighbor list at Node Init fails") def test_neighbor_already_added(self): """ Tests situations where there is an attempt to add an existing neighbor. The expected handling of this is that there is no change to the neighbors as a Set is being used. """ neighbor_a = Node() neighbor_b = Node() neighbors = [neighbor_a, neighbor_b] neighbor_c = Node(neighbors) previous_size = len(neighbor_c.get_neighbors()) for each in neighbors: neighbor_c.add_neighbor(each) self.assertEqual(previous_size, len(neighbor_c.get_neighbors()), "Adding existing neighbors adds to the neighbor set") def test_add_neighbor(self): """ Tests adding a neighbor using the add_neighbor method. The expected response is that an added node is returned via the get_neighbors() method. :return: """ neighbor = Node() neighbor.add_neighbor(self.node_a) # Make sure the added node is accessible through the get method self.assertIs(neighbor.get_neighbors().pop(), self.node_a, "Neighbor not added") # Make sure the neighbor is not automatically updated as well self.assertEqual( self.node_a.get_neighbors(), set(), 'Neighbor list should not be updated automatically @Directed') def test_add_neighbors(self): """ Test adding multiple neighbors to the node via add_neighbor() Includes multiple stress tests and attempts adding different types of sequences. :return: """ neighbor_a = Node() neighbor_a.add_neighbor(*[self.node_a]) self.assertIs(neighbor_a.get_neighbors().pop(), self.node_a, "Neighbor not added") self.assertEqual( self.node_a.get_neighbors(), set(), "Neighbor list should not be updated automatically @Directed") # test passing a set assert len(self.node_a.get_neighbors()) == 0, "Test is incorrect" neighbor_set = set() for _ in range(500): neighbor_set.add(Node()) self.node_a.add_neighbor(*neighbor_set) self.assertEqual(len(self.node_a.get_neighbors() - neighbor_set), 0) for _ in range(500000): neighbor_set.add(Node()) self.node_a.add_neighbor(*neighbor_set) self.assertEqual(len(self.node_a.get_neighbors()), 500000 + 500) self.assertEqual(len(self.node_a.get_neighbors() - neighbor_set), 0) # test passing a list neighbor_list = [] node_b = Node() for _ in range(500): neighbor_list.append(Node()) node_b.add_neighbor(*neighbor_list) self.assertEqual(len(node_b.get_neighbors() - set(neighbor_list)), 0) for _ in range(500000): neighbor_list.append(Node()) node_b.add_neighbor(*neighbor_list) self.assertEqual(len(node_b.get_neighbors()), 500000 + 500) self.assertEqual(len(node_b.get_neighbors() - set(neighbor_list)), 0) # test passing a tuple neighbor_list = [] node_b = Node() for _ in range(500): neighbor_list.append(Node()) neighbor_list = tuple(neighbor_list) node_b.add_neighbor(*neighbor_list) self.assertEqual(len(node_b.get_neighbors() - set(neighbor_list)), 0) # failure cases neighbor_set = set() for i in range(500): neighbor_set.add(i) neighbor_list = [] for i in range(500): neighbor_list.append(i) with self.assertRaises(AssertionError): self.node_a.add_neighbor(*neighbor_set) with self.assertRaises(AssertionError): self.node_a.add_neighbor(*neighbor_list) node_c = Node([node_b]) self.node_a.add_neighbor(*[node_b, node_c]) neighbor_list = self.node_a.get_neighbors() self.assertIn(node_b, neighbor_list) self.assertIn(node_c, neighbor_list) def test_remove_node(self): """ Tests the removal of nodes """ neighbor_set = set() other_node = Node() for _ in range(5000): neighbor_set.add(Node()) self.node_a.add_neighbor(*neighbor_set) self.node_a.add_neighbor(other_node) for each_node in neighbor_set: self.node_a.delete_neighbor(each_node) # Making sure the specified nodes are deleted self.assertEqual(self.node_a.get_neighbors(), {other_node}) # Making sure there are no issues emptying the neighbor set self.node_a.delete_neighbor(other_node) def test_remove_exceptions(self): neighbor = Node() self.node_a.add_neighbor(neighbor) # testing removing a node that is not a neighbor self.assertRaises(AssertionError, self.node_a.delete_neighbor, Node()) # testing again with non-empty neighbor list self.node_a.add_neighbor(neighbor) self.assertRaises(AssertionError, self.node_a.delete_neighbor, Node()) # test passing a sequence self.assertRaises(AssertionError, self.node_a.delete_neighbor, [neighbor]) self.assertRaises(AssertionError, self.node_a.delete_neighbor, {neighbor}) # make sure nothing is broken self.node_a.delete_neighbor(neighbor) self.assertEqual(self.node_a.get_neighbors(), set())