Files
dataStructures/tests/graphTests/bfs_test.go
T
Acid ba54411627
Go / build (push) Successful in 33s
added DFS AND BSF to graphs
2026-07-25 23:53:46 -04:00

204 lines
4.9 KiB
Go

package tests
import (
"slices"
"testing"
"datastructures/graphs"
)
func TestBFSUnknownStartReturnsNil(t *testing.T) {
graph := graphs.NewGraph[string]()
graph.AddVertex("a", "b")
if order := graph.BFS("zz"); order != nil {
t.Errorf("BFS from unknown vertex = %v, want nil", order)
}
}
func TestBFSEmptyGraphReturnsNil(t *testing.T) {
graph := graphs.NewGraph[int]()
if order := graph.BFS(1); order != nil {
t.Errorf("BFS on empty graph = %v, want nil", order)
}
}
func TestBFSIsolatedVertexVisitsOnlyItself(t *testing.T) {
graph := graphs.NewGraph[string]()
graph.AddIsolatedVertex("lonely")
order := graph.BFS("lonely")
if !slices.Equal(order, []string{"lonely"}) {
t.Errorf("BFS = %v, want [lonely]", order)
}
}
func TestBFSPathGraphVisitsInOrder(t *testing.T) {
graph := graphs.NewGraph[string]()
graph.AddVertex("a", "b")
graph.AddVertex("b", "c")
graph.AddVertex("c", "d")
order := graph.BFS("a")
if !slices.Equal(order, []string{"a", "b", "c", "d"}) {
t.Errorf("BFS = %v, want [a b c d]", order)
}
}
func TestBFSVisitsLevelByLevel(t *testing.T) {
// a
// / \
// b c
// | |
// d e
graph := graphs.NewGraph[string]()
graph.AddVertex("a", "b")
graph.AddVertex("a", "c")
graph.AddVertex("b", "d")
graph.AddVertex("c", "e")
order := graph.BFS("a")
if !slices.Equal(order, []string{"a", "b", "c", "d", "e"}) {
t.Errorf("BFS = %v, want [a b c d e]", order)
}
}
func TestBFSFromNonRootStart(t *testing.T) {
graph := graphs.NewGraph[string]()
graph.AddVertex("a", "b")
graph.AddVertex("a", "c")
graph.AddVertex("b", "d")
// b's adjacency is [a d], so a comes before d
order := graph.BFS("b")
if !slices.Equal(order, []string{"b", "a", "d", "c"}) {
t.Errorf("BFS from b = %v, want [b a d c]", order)
}
}
func TestBFSCycleTerminatesWithoutRepeats(t *testing.T) {
graph := graphs.NewGraph[string]()
graph.AddVertex("a", "b")
graph.AddVertex("b", "c")
graph.AddVertex("c", "a")
order := graph.BFS("a")
if len(order) != 3 {
t.Fatalf("BFS on triangle = %v, want 3 vertices", order)
}
assertNoDuplicates(t, order)
}
func TestBFSDenseGraphVisitsEachVertexOnce(t *testing.T) {
// K4: every vertex connected to every other
graph := graphs.NewGraph[int]()
for first := 1; first <= 4; first++ {
for second := first + 1; second <= 4; second++ {
graph.AddVertex(first, second)
}
}
order := graph.BFS(1)
if len(order) != graph.Order() {
t.Errorf("BFS visited %d vertices, want %d", len(order), graph.Order())
}
assertNoDuplicates(t, order)
}
func TestBFSSkipsDisconnectedComponent(t *testing.T) {
graph := graphs.NewGraph[string]()
graph.AddVertex("a", "b")
graph.AddVertex("x", "y")
order := graph.BFS("a")
if !slices.Equal(order, []string{"a", "b"}) {
t.Errorf("BFS = %v, want only the component of a: [a b]", order)
}
}
func TestBFSReachesEveryVertexInConnectedGraph(t *testing.T) {
graph := graphs.NewGraph[int]()
graph.AddVertex(1, 2)
graph.AddVertex(2, 3)
graph.AddVertex(3, 4)
graph.AddVertex(4, 1)
graph.AddVertex(2, 5)
order := graph.BFS(1)
if len(order) != graph.Order() {
t.Errorf("BFS visited %d vertices, want %d", len(order), graph.Order())
}
for vertex := range graph.Display() {
if !slices.Contains(order, vertex) {
t.Errorf("vertex %d was never visited, order = %v", vertex, order)
}
}
}
func TestBFSDistancesAreNonDecreasing(t *testing.T) {
graph := graphs.NewGraph[string]()
graph.AddVertex("a", "b")
graph.AddVertex("a", "c")
graph.AddVertex("b", "d")
graph.AddVertex("c", "d")
graph.AddVertex("d", "e")
graph.AddVertex("e", "f")
order := graph.BFS("a")
// hop count from a, derived from the graph itself
distances := map[string]int{"a": 0, "b": 1, "c": 1, "d": 2, "e": 3, "f": 4}
previous := 0
for _, vertex := range order {
current, ok := distances[vertex]
if !ok {
t.Fatalf("BFS returned unexpected vertex %q", vertex)
}
if current < previous {
t.Errorf("BFS = %v: %q at distance %d visited after distance %d", order, vertex, current, previous)
}
previous = current
}
}
func TestBFSDoesNotMutateGraph(t *testing.T) {
graph := graphs.NewGraph[string]()
graph.AddVertex("a", "b")
graph.AddVertex("b", "c")
orderBefore, sizeBefore := graph.Order(), graph.Size()
graph.BFS("a")
if graph.Order() != orderBefore || graph.Size() != sizeBefore {
t.Errorf("after BFS Order/Size = %d/%d, want %d/%d",
graph.Order(), graph.Size(), orderBefore, sizeBefore)
}
}
func TestBFSIsRepeatable(t *testing.T) {
graph := graphs.NewGraph[string]()
graph.AddVertex("a", "b")
graph.AddVertex("a", "c")
graph.AddVertex("b", "d")
first := graph.BFS("a")
second := graph.BFS("a")
if !slices.Equal(first, second) {
t.Errorf("BFS not repeatable: %v then %v", first, second)
}
}
func assertNoDuplicates[T comparable](t *testing.T, order []T) {
t.Helper()
seen := make(map[T]bool, len(order))
for _, vertex := range order {
if seen[vertex] {
t.Errorf("vertex %v visited more than once in %v", vertex, order)
}
seen[vertex] = true
}
}