예제 #1
0
    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")
예제 #2
0
 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")
예제 #3
0
 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')
예제 #4
0
 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)
예제 #5
0
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())
예제 #6
0
    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)
예제 #7
0
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())