Skip to content

Commit c36d7dd

Browse files
committed
ci: fixing test errors
1 parent 4c48440 commit c36d7dd

File tree

2 files changed

+119
-27
lines changed

2 files changed

+119
-27
lines changed

include/graph/search/bfs.hpp

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,93 @@ class BFS final {
163163
SearchContext<State, Transition, StateIndexer> context;
164164
return Search(graph.get(), context, start, goal);
165165
}
166+
167+
/**
168+
* @brief BFS traversal of all reachable vertices from start
169+
*
170+
* Performs breadth-first traversal starting from the given vertex,
171+
* visiting all vertices reachable from the start vertex.
172+
*/
173+
template<typename State, typename Transition, typename StateIndexer,
174+
typename VertexIdentifier>
175+
static bool TraverseAll(
176+
const Graph<State, Transition, StateIndexer>* graph,
177+
SearchContext<State, Transition, StateIndexer>& context,
178+
VertexIdentifier start) {
179+
180+
if (!graph) return false;
181+
182+
auto start_it = graph->FindVertex(start);
183+
if (start_it == graph->vertex_end()) return false;
184+
185+
auto strategy = MakeBfsStrategy<State, Transition, StateIndexer>();
186+
auto dummy_goal = graph->vertex_end(); // No specific goal - traverse all
187+
188+
SearchAlgorithm<decltype(strategy), State, Transition, StateIndexer>
189+
::Search(graph, context, start_it, dummy_goal, strategy);
190+
191+
return true;
192+
}
193+
194+
/**
195+
* @brief Convenience overload for TraverseAll with shared_ptr
196+
*/
197+
template<typename State, typename Transition, typename StateIndexer,
198+
typename VertexIdentifier>
199+
static bool TraverseAll(
200+
std::shared_ptr<Graph<State, Transition, StateIndexer>> graph,
201+
SearchContext<State, Transition, StateIndexer>& context,
202+
VertexIdentifier start) {
203+
204+
return TraverseAll(graph.get(), context, start);
205+
}
206+
207+
/**
208+
* @brief Check if target vertex is reachable from start vertex
209+
*
210+
* Uses BFS to determine if there exists a path from start to target.
211+
* This is more efficient than a full search when only reachability
212+
* information is needed.
213+
*/
214+
template<typename State, typename Transition, typename StateIndexer,
215+
typename VertexIdentifier>
216+
static bool IsReachable(
217+
const Graph<State, Transition, StateIndexer>* graph,
218+
VertexIdentifier start,
219+
VertexIdentifier target) {
220+
221+
if (!graph) return false;
222+
223+
auto start_it = graph->FindVertex(start);
224+
auto target_it = graph->FindVertex(target);
225+
226+
if (start_it == graph->vertex_end() || target_it == graph->vertex_end()) {
227+
return false;
228+
}
229+
230+
// Same vertex is always reachable
231+
if (start_it == target_it) {
232+
return true;
233+
}
234+
235+
SearchContext<State, Transition, StateIndexer> context;
236+
auto path = Search(graph, context, start, target);
237+
238+
return !path.empty();
239+
}
240+
241+
/**
242+
* @brief Convenience overload for IsReachable with shared_ptr
243+
*/
244+
template<typename State, typename Transition, typename StateIndexer,
245+
typename VertexIdentifier>
246+
static bool IsReachable(
247+
std::shared_ptr<Graph<State, Transition, StateIndexer>> graph,
248+
VertexIdentifier start,
249+
VertexIdentifier target) {
250+
251+
return IsReachable(graph.get(), start, target);
252+
}
166253
};
167254

168255
// Compatibility typedefs for existing code

tests/unit_test/advanced_graph_operations_test.cpp

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ TEST_F(AdvancedGraphOperationsTest, ComplexVertexRemovalScenarios) {
6363
size_t initial_edge_count = graph_->GetEdgeCount();
6464

6565
// Remove hub vertex (should remove many edges)
66-
bool removed = graph_->RemoveVertex(AdvancedTestState(3));
66+
bool removed = graph_->RemoveVertexWithResult(AdvancedTestState(3));
6767

6868
EXPECT_TRUE(removed);
6969
EXPECT_EQ(graph_->GetVertexCount(), initial_vertex_count - 1);
@@ -97,22 +97,22 @@ TEST_F(AdvancedGraphOperationsTest, EdgeRemovalEdgeCases) {
9797
size_t initial_edge_count = graph_->GetEdgeCount();
9898

9999
// Remove specific edge
100-
bool removed1 = graph_->RemoveEdge(AdvancedTestState(1), AdvancedTestState(2), 1.0);
100+
bool removed1 = graph_->RemoveEdge(AdvancedTestState(1), AdvancedTestState(2));
101101
EXPECT_TRUE(removed1);
102102
EXPECT_EQ(graph_->GetEdgeCount(), initial_edge_count - 1);
103103

104104
// Try to remove non-existent edge
105-
bool removed2 = graph_->RemoveEdge(AdvancedTestState(1), AdvancedTestState(3), 1.0);
105+
bool removed2 = graph_->RemoveEdge(AdvancedTestState(1), AdvancedTestState(3));
106106
EXPECT_FALSE(removed2);
107107
EXPECT_EQ(graph_->GetEdgeCount(), initial_edge_count - 1);
108108

109109
// Remove self-loop
110-
bool removed3 = graph_->RemoveEdge(AdvancedTestState(1), AdvancedTestState(1), 5.0);
110+
bool removed3 = graph_->RemoveEdge(AdvancedTestState(1), AdvancedTestState(1));
111111
EXPECT_TRUE(removed3);
112112
EXPECT_EQ(graph_->GetEdgeCount(), initial_edge_count - 2);
113113
}
114114

115-
// Test ClearVertexEdges functionality
115+
// Test manual edge removal (ClearVertexEdges doesn't exist in API)
116116
TEST_F(AdvancedGraphOperationsTest, ClearVertexEdgesComprehensive) {
117117
for (int i = 1; i <= 5; ++i) {
118118
graph_->AddVertex(AdvancedTestState(i));
@@ -129,8 +129,12 @@ TEST_F(AdvancedGraphOperationsTest, ClearVertexEdgesComprehensive) {
129129

130130
size_t initial_edge_count = graph_->GetEdgeCount();
131131

132-
// Clear all edges for vertex 1
133-
graph_->ClearVertexEdges(AdvancedTestState(1));
132+
// Manually remove all edges involving vertex 1
133+
for (int i = 2; i <= 5; ++i) {
134+
graph_->RemoveEdge(AdvancedTestState(1), AdvancedTestState(i));
135+
graph_->RemoveEdge(AdvancedTestState(i), AdvancedTestState(1));
136+
}
137+
graph_->RemoveEdge(AdvancedTestState(1), AdvancedTestState(1)); // self-loop
134138

135139
// Vertex should still exist
136140
EXPECT_NE(graph_->FindVertex(AdvancedTestState(1)), graph_->vertex_end());
@@ -178,14 +182,15 @@ TEST_F(AdvancedGraphOperationsTest, GetAllEdgesComplex) {
178182

179183
EXPECT_EQ(all_edges.size(), 6);
180184

181-
// Verify edge properties
185+
// Verify edge properties by iterating through edge iterators
182186
std::unordered_set<int> src_ids, dst_ids;
183187
std::vector<double> weights;
184188

185-
for (const auto& edge_info : all_edges) {
186-
src_ids.insert(edge_info.src_vertex->state.id);
187-
dst_ids.insert(edge_info.dst_vertex->state.id);
188-
weights.push_back(edge_info.edge.cost);
189+
for (const auto& edge_it : all_edges) {
190+
// edge_it is an edge_iterator, we need to dereference it to get the Edge
191+
src_ids.insert(edge_it->src->state.id);
192+
dst_ids.insert(edge_it->dst->state.id);
193+
weights.push_back(edge_it->cost);
189194
}
190195

191196
// Should have edges from all vertices
@@ -311,12 +316,12 @@ TEST_F(AdvancedGraphOperationsTest, NeighborOperations) {
311316
auto vertex1_it = graph_->FindVertex(AdvancedTestState(1));
312317
EXPECT_NE(vertex1_it, graph_->vertex_end());
313318

314-
// Test CheckNeighbour
315-
EXPECT_TRUE(vertex1_it->CheckNeighbour(AdvancedTestState(2)));
316-
EXPECT_TRUE(vertex1_it->CheckNeighbour(AdvancedTestState(3)));
317-
EXPECT_TRUE(vertex1_it->CheckNeighbour(AdvancedTestState(4)));
318-
EXPECT_FALSE(vertex1_it->CheckNeighbour(AdvancedTestState(5)));
319-
EXPECT_FALSE(vertex1_it->CheckNeighbour(AdvancedTestState(6)));
319+
// Test CheckNeighbour using vertex IDs to avoid ambiguity
320+
EXPECT_TRUE(vertex1_it->CheckNeighbour(2));
321+
EXPECT_TRUE(vertex1_it->CheckNeighbour(3));
322+
EXPECT_TRUE(vertex1_it->CheckNeighbour(4));
323+
EXPECT_FALSE(vertex1_it->CheckNeighbour(5));
324+
EXPECT_FALSE(vertex1_it->CheckNeighbour(6));
320325

321326
// Test GetNeighbours
322327
auto neighbors = vertex1_it->GetNeighbours();
@@ -345,20 +350,20 @@ TEST_F(AdvancedGraphOperationsTest, DegreeCalculations) {
345350
graph_->AddEdge(AdvancedTestState(2), AdvancedTestState(1), 1.0);
346351
graph_->AddEdge(AdvancedTestState(3), AdvancedTestState(1), 1.0);
347352

348-
// Vertex 1: out-degree=2, in-degree=2
349-
EXPECT_EQ(graph_->GetVertexDegree(AdvancedTestState(1)), 2); // Out-degree
353+
// Vertex 1: out-degree=2, in-degree=2, total degree=4
354+
EXPECT_EQ(graph_->GetVertexDegree(1), 4); // Total degree (out + in)
350355

351-
// Vertex 2: out-degree=1, in-degree=1
352-
EXPECT_EQ(graph_->GetVertexDegree(AdvancedTestState(2)), 1);
356+
// Vertex 2: out-degree=1, in-degree=1, total degree=2
357+
EXPECT_EQ(graph_->GetVertexDegree(2), 2);
353358

354-
// Vertex 3: out-degree=1, in-degree=1
355-
EXPECT_EQ(graph_->GetVertexDegree(AdvancedTestState(3)), 1);
359+
// Vertex 3: out-degree=1, in-degree=1, total degree=2
360+
EXPECT_EQ(graph_->GetVertexDegree(3), 2);
356361

357362
// Vertex 4: isolated, degree=0
358-
EXPECT_EQ(graph_->GetVertexDegree(AdvancedTestState(4)), 0);
363+
EXPECT_EQ(graph_->GetVertexDegree(4), 0);
359364

360365
// Non-existent vertex
361-
EXPECT_EQ(graph_->GetVertexDegree(AdvancedTestState(10)), 0);
366+
EXPECT_EQ(graph_->GetVertexDegree(10), 0);
362367
}
363368

364369
// Test massive graph operations for performance edge cases
@@ -387,7 +392,7 @@ TEST_F(AdvancedGraphOperationsTest, MassiveGraphOperations) {
387392

388393
// Test removing vertices from middle
389394
for (int i = 50; i <= 60; ++i) {
390-
bool removed = graph_->RemoveVertex(AdvancedTestState(i));
395+
bool removed = graph_->RemoveVertexWithResult(AdvancedTestState(i));
391396
EXPECT_TRUE(removed);
392397
}
393398

0 commit comments

Comments
 (0)