Skip to content

Commit 3dde532

Browse files
Add TopologicalSortDFSTest with JUnit 5 tests
1 parent bceeb16 commit 3dde532

File tree

1 file changed

+148
-0
lines changed

1 file changed

+148
-0
lines changed
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
package com.thealgorithms.datastructures.graphs;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertThrows;
5+
import static org.junit.jupiter.api.Assertions.assertTrue;
6+
7+
import java.util.List;
8+
import org.junit.jupiter.api.Test;
9+
10+
/**
11+
* JUnit 5 tests for {@link TopologicalSortDFS}.
12+
*
13+
* Test cases cover:
14+
* - Standard DAG with a clear expected topological order
15+
* - Multiple valid orderings (validated by constraint checking)
16+
* - Graphs with cycles (must throw IllegalStateException)
17+
* - Single-node graph
18+
* - Disconnected graph
19+
*/
20+
class TopologicalSortDFSTest {
21+
22+
/**
23+
* Checks that every edge u → v satisfies: u appears before v in the result.
24+
*/
25+
private static void assertValidTopologicalOrder(List<Integer> order, int[][] edges) {
26+
for (int[] edge : edges) {
27+
int u = edge[0];
28+
int v = edge[1];
29+
assertTrue(
30+
order.indexOf(u) < order.indexOf(v),
31+
"Expected " + u + " to appear before " + v + " in topological order. Got: " + order);
32+
}
33+
}
34+
35+
@Test
36+
void testSimpleLinearGraph() {
37+
// 0 → 1 → 2 → 3
38+
TopologicalSortDFS graph = new TopologicalSortDFS();
39+
graph.addEdge(0, 1);
40+
graph.addEdge(1, 2);
41+
graph.addEdge(2, 3);
42+
43+
List<Integer> result = graph.topologicalSort();
44+
assertEquals(List.of(0, 1, 2, 3), result);
45+
}
46+
47+
@Test
48+
void testDAGWithMultiplePaths() {
49+
// Graph:
50+
// 5 → 2
51+
// 5 → 0
52+
// 4 → 0
53+
// 4 → 1
54+
// 2 → 3
55+
// 3 → 1
56+
TopologicalSortDFS graph = new TopologicalSortDFS();
57+
int[][] edges = { { 5, 2 }, { 5, 0 }, { 4, 0 }, { 4, 1 }, { 2, 3 }, { 3, 1 } };
58+
for (int[] edge : edges) {
59+
graph.addEdge(edge[0], edge[1]);
60+
}
61+
62+
List<Integer> result = graph.topologicalSort();
63+
assertEquals(6, result.size());
64+
assertValidTopologicalOrder(result, edges);
65+
}
66+
67+
@Test
68+
void testBuildOrderDAG() {
69+
// Simulates build dependency: A depends on nothing, B depends on A, C depends
70+
// on A and B
71+
// A=0, B=1, C=2, D=3
72+
// 0 → 1, 0 → 2, 1 → 3, 2 → 3
73+
TopologicalSortDFS graph = new TopologicalSortDFS();
74+
int[][] edges = { { 0, 1 }, { 0, 2 }, { 1, 3 }, { 2, 3 } };
75+
for (int[] edge : edges) {
76+
graph.addEdge(edge[0], edge[1]);
77+
}
78+
79+
List<Integer> result = graph.topologicalSort();
80+
assertEquals(4, result.size());
81+
assertValidTopologicalOrder(result, edges);
82+
}
83+
84+
@Test
85+
void testSingleVertex() {
86+
TopologicalSortDFS graph = new TopologicalSortDFS();
87+
graph.addVertex(42);
88+
89+
List<Integer> result = graph.topologicalSort();
90+
assertEquals(List.of(42), result);
91+
}
92+
93+
@Test
94+
void testDisconnectedGraph() {
95+
// Two disconnected components: 0 → 1 and 2 → 3
96+
TopologicalSortDFS graph = new TopologicalSortDFS();
97+
int[][] edges = { { 0, 1 }, { 2, 3 } };
98+
for (int[] edge : edges) {
99+
graph.addEdge(edge[0], edge[1]);
100+
}
101+
102+
List<Integer> result = graph.topologicalSort();
103+
assertEquals(4, result.size());
104+
assertValidTopologicalOrder(result, edges);
105+
}
106+
107+
@Test
108+
void testSimpleCycleThrowsException() {
109+
// 0 → 1 → 2 → 0 (cycle)
110+
TopologicalSortDFS graph = new TopologicalSortDFS();
111+
graph.addEdge(0, 1);
112+
graph.addEdge(1, 2);
113+
graph.addEdge(2, 0);
114+
115+
assertThrows(
116+
IllegalStateException.class,
117+
graph::topologicalSort,
118+
"Expected IllegalStateException for cyclic graph");
119+
}
120+
121+
@Test
122+
void testSelfLoopThrowsException() {
123+
// A self-loop is a trivial cycle: 0 → 0
124+
TopologicalSortDFS graph = new TopologicalSortDFS();
125+
graph.addEdge(0, 0);
126+
127+
assertThrows(
128+
IllegalStateException.class,
129+
graph::topologicalSort,
130+
"Expected IllegalStateException for self-loop");
131+
}
132+
133+
@Test
134+
void testLargerCycleThrowsException() {
135+
// 0 → 1 → 2 → 3 → 4 → 2 (cycle at 2 → 3 → 4 → 2)
136+
TopologicalSortDFS graph = new TopologicalSortDFS();
137+
graph.addEdge(0, 1);
138+
graph.addEdge(1, 2);
139+
graph.addEdge(2, 3);
140+
graph.addEdge(3, 4);
141+
graph.addEdge(4, 2);
142+
143+
assertThrows(
144+
IllegalStateException.class,
145+
graph::topologicalSort,
146+
"Expected IllegalStateException for graph with cycle");
147+
}
148+
}

0 commit comments

Comments
 (0)