Files
dataStructures/tests/treeTests/priorityQueue_test.go
T
2026-07-14 17:54:25 -04:00

137 lines
2.8 KiB
Go

package tests
import (
"math/rand"
"slices"
"testing"
"datastructures/trees/heap"
)
func TestPQPopEmpty(t *testing.T) {
q := heap.NewPriorityQueue[int]()
if v, ok := q.Pop(); ok {
t.Fatalf("Pop on empty queue = (%d, true), want (0, false)", v)
}
}
func TestPQPeekEmpty(t *testing.T) {
q := heap.NewPriorityQueue[int]()
if v, ok := q.Peek(); ok {
t.Fatalf("Peek on empty queue = (%d, true), want (0, false)", v)
}
}
func TestPQSizeTracksPushPop(t *testing.T) {
q := heap.NewPriorityQueue[int]()
if q.Size() != 0 {
t.Fatalf("new queue Size = %d, want 0", q.Size())
}
for i, v := range []int{9, 4, 7, 1} {
q.Push(v)
if q.Size() != i+1 {
t.Fatalf("after %d pushes Size = %d, want %d", i+1, q.Size(), i+1)
}
}
for want := 3; want >= 0; want-- {
q.Pop()
if q.Size() != want {
t.Fatalf("Size = %d, want %d", q.Size(), want)
}
}
}
func TestPQPeekReturnsMinWithoutRemoving(t *testing.T) {
q := heap.NewPriorityQueue[int]()
for _, v := range []int{8, 3, 5, 1, 9} {
q.Push(v)
}
v, ok := q.Peek()
if !ok || v != 1 {
t.Fatalf("Peek = (%d, %v), want (1, true)", v, ok)
}
// Peek must not mutate the queue.
if q.Size() != 5 {
t.Fatalf("Size after Peek = %d, want 5", q.Size())
}
v2, _ := q.Peek()
if v2 != v {
t.Fatalf("second Peek = %d, want same %d", v2, v)
}
}
func TestPQPopsInPriorityOrder(t *testing.T) {
in := []int{5, 3, 8, 1, 9, 2, 7, 0, 4, 6}
q := heap.NewPriorityQueue[int]()
for _, v := range in {
q.Push(v)
}
got := []int{}
for q.Size() > 0 {
// Peek must always agree with the next Pop.
p, ok := q.Peek()
if !ok {
t.Fatal("Peek returned ok=false while Size > 0")
}
v, ok := q.Pop()
if !ok {
t.Fatal("Pop returned ok=false while Size > 0")
}
if p != v {
t.Fatalf("Peek returned %d but Pop returned %d", p, v)
}
got = append(got, v)
}
want := slices.Clone(in)
slices.Sort(want)
if !slices.Equal(got, want) {
t.Fatalf("pop order = %v, want ascending %v", got, want)
}
}
func TestPQStrings(t *testing.T) {
q := heap.NewPriorityQueue[string]()
for _, s := range []string{"pear", "apple", "cherry", "banana"} {
q.Push(s)
}
got := []string{}
for q.Size() > 0 {
v, _ := q.Pop()
got = append(got, v)
}
want := []string{"apple", "banana", "cherry", "pear"}
if !slices.Equal(got, want) {
t.Fatalf("pop order = %v, want %v", got, want)
}
}
func TestPQFuzzAgainstSort(t *testing.T) {
rng := rand.New(rand.NewSource(7))
for trial := 0; trial < 200; trial++ {
n := rng.Intn(50)
in := make([]int, n)
for i := range in {
in[i] = rng.Intn(100)
}
q := heap.NewPriorityQueue[int]()
for _, v := range in {
q.Push(v)
}
got := []int{}
for q.Size() > 0 {
v, _ := q.Pop()
got = append(got, v)
}
want := slices.Clone(in)
slices.Sort(want)
if !slices.Equal(got, want) {
t.Fatalf("trial %d: got %v, want %v (input %v)", trial, got, want, in)
}
}
}