Mini Shell

Direktori : /opt/imh-python/lib/python3.9/site-packages/tests/
Upload File :
Current File : //opt/imh-python/lib/python3.9/site-packages/tests/test_biconnected_components.py

"""Provides unit tests to verify that the biconnected components algorithms are functioning correctly."""

import unittest

from ..pygraph import (UndirectedGraph, find_biconnected_components, find_articulation_vertices, merge_graphs,
                     build_triangle_graph, build_square_graph, build_diamond_graph,
                     build_tetrahedral_graph, build_5_cycle_graph, build_gem_graph)

from . import utility_functions


class BiconnectedComponentsTest(unittest.TestCase):
    def test_empty_graph(self):
        """Does the ''find_biconnected_components'' function return an empty set of edges for an empty graph?"""
        graph = UndirectedGraph()

        expected = []
        calculated = find_biconnected_components(graph)

        self.assertEqual(expected, calculated)

    def test_single_node_graph(self):
        """Does the ''find_biconnected_components'' function return an empty set of edges for a graph with 1 node?"""
        graph = utility_functions.build_single_node_graph()

        expected = []
        calculated = find_biconnected_components(graph)

        self.assertEqual(expected, calculated)

    def test_2_node_graph(self):
        """Does the ''find_biconnected_components'' function return a single edge list for a 2-node connected graph?"""
        graph = utility_functions.build_2_node_graph()

        expected = [[1]]
        calculated = find_biconnected_components(graph)

        self.assertEqual(expected, calculated)

    def test_triangle_graph(self):
        """Does the ''find_biconnected_components'' function return a single edge list for a triangle graph?"""
        graph = build_triangle_graph()

        expected = [[1, 2, 3]]
        calculated = find_biconnected_components(graph)
        calculated[0].sort()

        self.assertEqual(expected, calculated)

    def test_square_graph(self):
        """Does the ''find_biconnected_components'' function return a single edge list for a square graph?"""
        graph = build_square_graph()

        expected = [[1, 2, 3, 4]]
        calculated = find_biconnected_components(graph)
        calculated[0].sort()

        self.assertEqual(expected, calculated)

    def test_diamond_graph(self):
        """Does the ''find_biconnected_components'' function return a single edge list for a diamond graph?"""
        graph = build_diamond_graph()

        expected = [[1, 2, 3, 4, 5]]
        calculated = find_biconnected_components(graph)
        calculated[0].sort()

        self.assertEqual(expected, calculated)

    def test_tetrahedral_graph(self):
        """Does the ''find_biconnected_components'' function return a single edge list for a tetrahedral graph?"""
        graph = build_tetrahedral_graph()

        expected = [[1, 2, 3, 4, 5, 6]]
        calculated = find_biconnected_components(graph)
        calculated[0].sort()

        self.assertEqual(expected, calculated)

    def test_5_cycle_graph(self):
        """Does the ''find_biconnected_components'' function return a single edge list for a 5-cycle graph?"""
        graph = build_5_cycle_graph()

        expected = [[1, 2, 3, 4, 5]]
        calculated = find_biconnected_components(graph)
        calculated[0].sort()

        self.assertEqual(expected, calculated)

    def test_gem_graph(self):
        """Does the ''find_biconnected_components'' function return a single edge list for a gem graph?"""
        graph = build_gem_graph()

        expected = [[1, 2, 3, 4, 5, 6, 7]]
        calculated = find_biconnected_components(graph)
        calculated[0].sort()

        self.assertEqual(expected, calculated)

    def test_fully_biconnected_graph(self):
        """Does the ''find_biconnected_components'' function correctly return
        the entire graph for a fully biconnected graph?"""
        graph = utility_functions.build_fully_biconnected_test_graph()

        expected_edges = list(range(1, 20))  # There are 19 edges in the test graph, so their IDs go from 1-19
        calculated_edges = find_biconnected_components(graph)

        # Verify that there is only a single component in the calculated edge list
        self.assertEqual(1, len(calculated_edges))

        # Verify all edges exist within the calculated edge list
        component = calculated_edges[0]
        for edge_id in expected_edges:
            self.assertIn(edge_id, component)

        # Verify that there are precisely the number of edges expected in the calculated edge list
        self.assertEqual(19, len(component))

    def test_biconnected_graph(self):
        """Does the ''find_biconnected_components'' function correctly identify the
        components in a graph with multiple biconnected components?"""
        graph = utility_functions.build_biconnected_test_graph()

        component_a = [1, 2, 3]
        component_b = [4, 5, 6, 7, 8]
        component_c = [9, 10, 11, 12, 13, 14, 15, 16]
        known_components = [component_a, component_b, component_c]

        calculated_components = find_biconnected_components(graph)

        # Verify that there are the expected number of components
        self.assertEqual(3, len(calculated_components))

        # --Verify each known component exists and has the correct number of edges
        found_components_count = 0
        for kc in known_components:
            found_known_component = False
            for c in calculated_components:
                # --Determine if the current component is a superset of known component
                # --(it might have more edges than the known component)
                superset_match = True
                for e in kc:
                    if e not in c:
                        # --This is not the correct component, go to the next one
                        superset_match = False
                        break
                if superset_match:
                    # --Determine if the current component has precisely the same number of
                    # --edges in it as the known component
                    found_known_component = (len(kc) == len(c))
                if found_known_component:
                    found_components_count += 1
                    break
            if not found_known_component:
                # --We know the current component was not found in the connected components
                # --list, fail with an error message
                msg = 'Component {} not found in {}'.format(kc, calculated_components)
                self.fail(msg)

        # --This verifies that we found all three known components in the calculated components
        # --Prior tests should stop things before we get this far if there are errors,
        # --but it's a simple sanity check test
        self.assertEqual(3, found_components_count)

    def test_disconnected_graph(self):
        """Does the ''find_biconnected_components'' function return components for each connected component?"""
        graph = utility_functions.build_biconnected_test_graph()
        addition_graph = build_triangle_graph()

        node_map, edge_map = merge_graphs(graph, addition_graph)

        calculated_components = find_biconnected_components(graph)

        # Verify that there are the expected number of components
        self.assertEqual(4, len(calculated_components))


class ArticulationVerticesTest(unittest.TestCase):
    def test_articulation_vertices_empty_graph(self):
        """Does the ''find_articulation_vertices'' function return an empty list when run on an empty graph?"""
        graph = UndirectedGraph()

        expected = []
        calculated = find_articulation_vertices(graph)

        self.assertEqual(expected, calculated)

    def test_articulation_vertices_fully_biconnected_graph(self):
        """Does the ''find_articulation_vertices'' function return an empty list
        when run on a fully biconnected graph?"""
        graph = utility_functions.build_fully_biconnected_test_graph()

        expected = []
        calculated = find_articulation_vertices(graph)

        self.assertEqual(expected, calculated)

    def test_articulation_vertices_single_cut_vertex(self):
        """Does the ''find_articulation_vertices'' function return a single
        articulation vertex for a graph with a single cut vertex?"""
        graph = utility_functions.build_3_node_line_graph()

        expected = [2]
        calculated = find_articulation_vertices(graph)

        self.assertEqual(expected, calculated)

    def test_articulation_vertices_single_cut_vertex_is_root(self):
        """Does the ''find_articulation_vertices'' function return a single
        articulation vertex for a graph where the root node is the single cut vertex?"""
        graph = utility_functions.build_3_node_line_root_articulation_graph()

        expected = [1]
        calculated = find_articulation_vertices(graph)

        self.assertEqual(expected, calculated)

    def test_articulation_vertices_dual_cut_vertices(self):
        """Does the ''find_articulation_vertices'' function return a pair of
        articulation vertices for a graph where there are two?"""
        graph = utility_functions.build_simple_test_graph()

        expected = [1, 2]
        calculated = find_articulation_vertices(graph)
        calculated.sort()

        self.assertEqual(expected, calculated)

    def test_articulation_vertices_biconnected_graph(self):
        """Does the ''find_articulation_vertices'' function return the correct list
        of articulation vertices for a graph with multiple biconnected components?"""
        graph = utility_functions.build_biconnected_test_graph()

        expected = [2, 5, 7, 8]
        calculated = find_articulation_vertices(graph)
        calculated.sort()

        self.assertEqual(expected, calculated)


Zerion Mini Shell 1.0