def test_adj_vertices(self) -> None: g = Graph() g.add_vertex(1) assert not g[1].adj_vertices( ), "vertex 1 should have no adjacent vertices" g.add_edge(1, 2) assert next(iter( g[1].adj_vertices())) == 2, "vertex 1 should adjacent to vertex 2" g.add_edge(1, 3) assert len(g[1].adj_vertices() ) == 2, "vertex 1 should be adjacent to vertices 2 and 3" assert next(iter(g[3].adj_vertices()) ) == g[1], "vertex 3 should be adjacent to vertex 1" g.add_edge(2, 4) assert g[4] not in g[1].adj_vertices( ), "vertex 1 should not be adjacent to vertex 4" assert g[2] not in g[2].adj_vertices( ), "vertex 2 should not be adjacent to itself" g.add_edge(4, 4) assert g[4] in g[4].adj_vertices( ), "vertex 4 should be adjacent to itself"
def test_from_vertex_obj(self) -> None: g = Graph() g.add_vertex(1, color="blue") vertex_data = pp_module.VertexData.from_vertex_obj(g[1]) assert vertex_data.label == "1", "label should be '1'" assert vertex_data.attr[ "color"] == "blue", "should have 'color' attribute set to 'blue'" assert vertex_data.vertex_object, "should have reference to vertex object"
def test_basic_operations(self) -> None: g = Graph([(1, 2), (2, 3), (3, 4), (4, 5)]) vertex_priority: VertexDict[float] = VertexDict() vertex_priority[1] = 100 vertex_priority[2] = 90 vertex_priority[3] = 80 vertex_priority[4] = 70 vertex_priority[5] = 70 priority_function = get_priority_function(vertex_priority) vpq: PriorityQueue[Vertex] = PriorityQueue(priority_function) vpq.add_or_update(g[5]) vpq.add_or_update(g[4]) vpq.add_or_update(g[1]) vpq.add_or_update(g[2]) vpq.add_or_update(g[3]) assert len(vpq) == 5, "Priority queue should contain 5 vertices." next_v = vpq.pop() assert next_v == g[ 5], "First lowest priority vertex should be vertex 5." next_v = vpq.pop() assert next_v == g[4], ( "Second lowest priority vertex should be vertex 4, since 4 " " was inserted after 5.") vertex_priority[1] = 0 vpq.add_or_update(g[1]) assert len(vpq) == 3, ( "Priority queue should contain 3 vertices after popping and " " updating.") next_v = vpq.pop() assert next_v == g[ 1], "Lowest priority vertex should be 1 after setting priority to 0." next_v = vpq.pop() assert next_v == g[3], "Lowest priority vertex should be 3." g.add_vertex(10) vertex_priority[10] = 200 vpq.add_or_update(g[10]) next_v = vpq.pop() assert next_v == g[2], "Lowest priority vertex should be 2." assert len(vpq) == 1, "Priority queue should contain 1 vertex." next_v = vpq.pop() assert next_v == g[10], "Lowest priority vertex should be 10." assert len(vpq) == 0, "Priority queue should be empty." # Attempting to pop an item from an empty priority queue should raise KeyError. with pytest.raises(KeyError): vpq.pop()
def test_repr_str_and_label(self) -> None: g = Graph() v1 = g.add_vertex("a") v2 = g.add_vertex(2) assert v1.label == "a", "v1 label should be 'a'" assert v2.label == "2", "v2 label should be '2'" assert v1.__repr__( ) == v1.label, "vertex __repr__() should be its label" assert v1.__str__() == v1.label, "vertex __str__() should be its label" assert v1.__repr__() == v1.__str__( ), "vertex __repr__() should match __str__()"
def test_incident_edges_and_loop_edge(self) -> None: g = Graph() g.add_vertex(0) assert not g[0].loop_edge, "vertex 0 should not have a loop edge" g.add_edge(1, 1) assert g[1].incident_edges() == {g.get_edge( 1, 1)}, "vertex 1 should have self loop as incident edge" assert g[1].loop_edge, "vertex 1 should have a self loop" g.add_edge(1, 2) assert len(g[1].incident_edges() ) == 2, "vertex 1 should have two incident edges"
def test_create_edge_label(self) -> None: g = Graph() v1 = g.add_vertex(1) v2 = g.add_vertex(2) assert (edge_module.create_edge_label( v1, v1, is_directed=g.is_directed()) == "(1, 1)" ), "loop edge label should be (1, 1)" assert (edge_module.create_edge_label( v1, v2, is_directed=g.is_directed()) == "(1, 2)" ), "edge label should be (1, 2)" assert (edge_module.create_edge_label( v2, v1, is_directed=g.is_directed()) == "(1, 2)" ), "edge label should be (1, 2)" assert (edge_module.create_edge_label( 5, 9, is_directed=g.is_directed()) == "(5, 9)" ), "edge label should be (5, 9)" assert (edge_module.create_edge_label( "t", "s", is_directed=g.is_directed()) == "(s, t)" ), "edge label should be (s, t)" g2 = DiGraph() v3 = g2.add_vertex(3) v4 = g2.add_vertex(4) assert (edge_module.create_edge_label( v3, v4, is_directed=g2.is_directed()) == "(3, 4)" ), "edge label should be (3, 4)" assert (edge_module.create_edge_label( v4, v3, is_directed=g2.is_directed()) == "(4, 3)" ), "edge label should be (4, 3)" assert (edge_module.create_edge_label( "t", "s", is_directed=g2.is_directed()) == "(t, s)" ), "edge label should be (t, s)"
def test_issubclass_and_isinstance(self) -> None: g = Graph() v1 = g.add_vertex(1) assert isinstance( v1, vertex_module.VertexBase ), "v1 should be an instance of superclass VertexBase" assert isinstance(v1, Vertex), "v1 should be a Vertex instance" assert issubclass( Vertex, vertex_module.VertexBase), "Vertex should be VertexBase subclass"
def test_degree(self) -> None: g = Graph() v0 = g.add_vertex(0) assert v0.degree == 0, "vertex 0 should have degree 0" g.add_edge(1, 1) assert g[1].degree == 2, "vertex 1 with self loop should have degree 2" g.add_edge(1, 2) assert g[1].degree == 3, "vertex 1 should have degree 3"
def test_parse_vertex_type(self) -> None: g = Graph() g.add_vertex(1, mass=5.5) vertex_data1 = pp_module.parse_vertex_type(g[1]) assert vertex_data1.label == "1" assert vertex_data1.attr["mass"] == 5.5 mg = MultiGraph([(3, 4), (3, 4)]) vertex_data2 = pp_module.parse_vertex_type(mg[4]) assert vertex_data2.label == "4" vertex_data3 = pp_module.parse_vertex_type(3) assert vertex_data3.label == "3" vertex_data4 = pp_module.parse_vertex_type("s") assert vertex_data4.label == "s" vertex_data5 = pp_module.parse_vertex_type(("t", {"mass": 42})) assert vertex_data5.label == "t" assert vertex_data5.attr["mass"] == 42.0
def test_get_vertex_label(self) -> None: g = Graph() v_obj: Vertex = g.add_vertex(1) assert vertex_module.get_vertex_label( v_obj) == "1", "vertex object label should be '1'" assert vertex_module.get_vertex_label( 10) == "10", "int vertex label should be '10'" assert vertex_module.get_vertex_label( "s") == "s", "str vertex label should be 's'" assert (vertex_module.get_vertex_label(("s", { "color": "blue" })) == "s"), "vertex tuple should have label 's'"
def test_remove_and_edge_removal(self) -> None: g = Graph() v1 = g.add_vertex("a") assert g.vertex_count == 1, "graph should have one vertex" v1.remove() assert g.vertex_count == 0, "graph should have zero vertices after vertex self removal" v2 = g.add_vertex("b") g.add_edge("b", "c") g.add_edge("b", "b") with pytest.raises(VertizeeException): v2.remove() assert len( v2.incident_edges()) == 2, "v2 should have two incident edges" v2.remove_loops() assert v2.loop_edge is None, "v2 should not have a loop edge after removal" assert len(v2.incident_edges() ) == 1, "v2 should have one incident after removing loop" v2.remove_incident_edges() assert len(v2.incident_edges( )) == 0, "v2 should not have any incident edges after removal"
def test_comparison_operators(self) -> None: g = Graph() v1 = g.add_vertex("a") v2 = g.add_vertex("b") assert v1 < v2, "v1 should be less than v2" assert v1 <= v2, "v1 should be less than or equal to v2" assert v2 > v1, "v2 should be greater than v1" assert v2 >= v1, "v2 should be greater than or equal to v1" assert v1 == "a", "v1 should be equal to a vertex represented by label 'a'" assert v1 < "b", "v1 should be less than a vertex represented by label 'b'" assert v1 > 1, "v1 should be great than a vertex represented by label 1" assert v1 < ("b", { "color": "blue" }), "v1 should be less than vertex tuple 'b'"
def test_attr_dictionary(self) -> None: g = Graph() v1 = g.add_vertex("a") assert v1._attr is None, "attr dictionary should be None by default" v1.attr["weight"] = 1000 assert v1.attr[ "weight"] == 1000, "v1 should have 'weight' attribute set to 1000" assert v1[ "weight"] == 1000, "'weight' attribute should be accessible with index getter" v1["color"] = "blue" assert v1[ "color"] == "blue", "v1 should have color attribute set to 'blue'" with pytest.raises(KeyError): _ = v1["unknown_key"]
def test_is_isolated(self) -> None: g = Graph() v1 = g.add_vertex(1) assert v1.is_isolated(), "v1 should be isolated" g.add_edge(v1, v1) assert v1.loop_edge, "v1 should have a self loop" assert not v1.is_isolated( ), "vertex with self-loop should not be considered isolated" assert v1.is_isolated( ignore_self_loops=True ), "vertex with self-loop should be considered semi-isolated" g.add_edge(v1, 2) assert not v1.is_isolated( ), "vertex connected to a different vertex should not be isolated" v1.remove_incident_edges() assert v1.is_isolated( ), "vertex should be isolated after removing incident edges"
def test_is_vertex_type(self) -> None: g = Graph() v: Vertex = g.add_vertex(1) assert vertex_module.is_vertex_type( v), "Vertex object should be a VertexType" g2 = DiGraph() di_v: DiVertex = g2.add_vertex(1) assert vertex_module.is_vertex_type( di_v), "DiVertex object should be a VertexType" g3 = MultiGraph() multi_v: MultiVertex = g3.add_vertex(1) assert vertex_module.is_vertex_type( multi_v), "MultiVertex object should be a VertexType" g4 = MultiDiGraph() multi_di_v: MultiDiVertex = g4.add_vertex(1) assert vertex_module.is_vertex_type( multi_di_v), "MultiDiVertex should be a VertexType" assert vertex_module.is_vertex_type( 10), "int vertex label should be a VertexType" assert vertex_module.is_vertex_type( "s"), "str vertex label should be a VertexType" assert vertex_module.is_vertex_type(("s", { "color": "blue" })), "vertex tuple should be a VertexType" assert not vertex_module.is_vertex_type( 10.99), "float should not be a VertexType" assert not vertex_module.is_vertex_type( ("s", "t")), "edge tuple should not be a VertexType" assert not vertex_module.is_vertex_type( ("s", "t", 4.5)), "edge tuple with edge weight should not be a VertexType" g.add_edge("s", "t") assert not vertex_module.is_vertex_type(g.get_edge( "s", "t")), "edge object should not be a VertexType"