| // Copyright 2026 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package graph |
| |
| import ( |
| "slices" |
| "testing" |
| ) |
| |
| func assertPanic(t *testing.T, f func(), msg string) { |
| t.Helper() |
| defer func() { |
| if r := recover(); r == nil { |
| t.Error(msg) |
| } |
| }() |
| f() |
| } |
| |
| func TestIndex_Identity(t *testing.T) { |
| ix := NewIdentityIndex(5) |
| |
| // Valid inputs |
| for i := range 5 { |
| if got := ix.Value(i); got != i { |
| t.Errorf("Value(%d) = %d, want %d", i, got, i) |
| } |
| if got := ix.Index(i); got != i { |
| t.Errorf("Index(%d) = %d, want %d", i, got, i) |
| } |
| } |
| |
| // Panics |
| assertPanic(t, func() { ix.Value(-1) }, "Value(-1) should panic") |
| assertPanic(t, func() { ix.Value(5) }, "Value(5) should panic") |
| assertPanic(t, func() { ix.Index(-1) }, "Index(-1) should panic") |
| assertPanic(t, func() { ix.Index(5) }, "Index(5) should panic") |
| |
| assertPanic(t, func() { NewIdentityIndex(-1) }, "NewIndentityIndex(-1) should panic") |
| } |
| |
| func TestIndex_SortedInts(t *testing.T) { |
| vals := []int{2, 4, 6, 8, 10} |
| ix := NewIndex(slices.Values(vals)) |
| |
| // Verify representation |
| if ix.index != nil { |
| t.Errorf("Expected nil map for sorted ints") |
| } |
| |
| // Valid inputs |
| for i, v := range vals { |
| if got := ix.Value(i); got != v { |
| t.Errorf("Value(%d) = %d, want %d", i, got, v) |
| } |
| if got := ix.Index(v); got != i { |
| t.Errorf("Index(%d) = %d, want %d", v, got, i) |
| } |
| } |
| |
| // Panics |
| assertPanic(t, func() { ix.Value(-1) }, "Value(-1) should panic") |
| assertPanic(t, func() { ix.Value(5) }, "Value(5) should panic") |
| |
| assertPanic(t, func() { ix.Index(3) }, "Index(3) should panic") |
| assertPanic(t, func() { ix.Index(11) }, "Index(11) should panic") |
| } |
| |
| func TestIndex_Full(t *testing.T) { |
| vals := []string{"C", "A", "B"} |
| ix := NewIndex(slices.Values(vals)) |
| |
| // Verify representation |
| if ix.index == nil { |
| t.Errorf("Expected non-nil map for unsorted/non-int keys") |
| } |
| |
| // Valid inputs |
| for i, v := range vals { |
| if got := ix.Value(i); got != v { |
| t.Errorf("Value(%d) = %q, want %q", i, got, v) |
| } |
| if got := ix.Index(v); got != i { |
| t.Errorf("Index(%q) = %d, want %d", v, got, i) |
| } |
| } |
| |
| // Panics |
| assertPanic(t, func() { ix.Value(-1) }, "Value(-1) should panic") |
| assertPanic(t, func() { ix.Value(3) }, "Value(3) should panic") |
| |
| assertPanic(t, func() { ix.Index("D") }, "Index(\"D\") should panic") |
| } |
| |
| func TestIndex_UnsortedInts(t *testing.T) { |
| vals := []int{4, 2, 6} |
| ix := NewIndex(slices.Values(vals)) |
| |
| // Verify representation |
| if ix.index == nil { |
| t.Errorf("Expected non-nil map for unsorted ints") |
| } |
| |
| for i, v := range vals { |
| if got := ix.Value(i); got != v { |
| t.Errorf("Value(%d) = %d, want %d", i, got, v) |
| } |
| if got := ix.Index(v); got != i { |
| t.Errorf("Index(%d) = %d, want %d", v, got, i) |
| } |
| } |
| |
| assertPanic(t, func() { ix.Index(3) }, "Index(3) should panic") |
| } |
| |
| func TestIndex_Empty(t *testing.T) { |
| ix := NewIndex(slices.Values([]string{})) |
| assertPanic(t, func() { ix.Value(0) }, "Value(0) on empty index should panic") |
| assertPanic(t, func() { ix.Index("A") }, "Index on empty index should panic") |
| |
| ix2 := NewIdentityIndex(0) |
| assertPanic(t, func() { ix2.Value(0) }, "Value(0) on empty identity index should panic") |
| assertPanic(t, func() { ix2.Index(0) }, "Index(0) on empty identity index should panic") |
| } |