forked from Snider/Poindexter
347 lines
7.9 KiB
Go
347 lines
7.9 KiB
Go
package poindexter
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
)
|
|
|
|
func TestSortInts(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input []int
|
|
expected []int
|
|
}{
|
|
{"empty slice", []int{}, []int{}},
|
|
{"single element", []int{5}, []int{5}},
|
|
{"already sorted", []int{1, 2, 3, 4, 5}, []int{1, 2, 3, 4, 5}},
|
|
{"reverse sorted", []int{5, 4, 3, 2, 1}, []int{1, 2, 3, 4, 5}},
|
|
{"unsorted", []int{3, 1, 4, 1, 5, 9, 2, 6}, []int{1, 1, 2, 3, 4, 5, 6, 9}},
|
|
{"with negatives", []int{-3, 5, -1, 0, 2}, []int{-3, -1, 0, 2, 5}},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
data := make([]int, len(tt.input))
|
|
copy(data, tt.input)
|
|
SortInts(data)
|
|
if !reflect.DeepEqual(data, tt.expected) {
|
|
t.Errorf("SortInts(%v) = %v, want %v", tt.input, data, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSortIntsDescending(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input []int
|
|
expected []int
|
|
}{
|
|
{"empty slice", []int{}, []int{}},
|
|
{"single element", []int{5}, []int{5}},
|
|
{"ascending order", []int{1, 2, 3, 4, 5}, []int{5, 4, 3, 2, 1}},
|
|
{"unsorted", []int{3, 1, 4, 1, 5, 9, 2, 6}, []int{9, 6, 5, 4, 3, 2, 1, 1}},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
data := make([]int, len(tt.input))
|
|
copy(data, tt.input)
|
|
SortIntsDescending(data)
|
|
if !reflect.DeepEqual(data, tt.expected) {
|
|
t.Errorf("SortIntsDescending(%v) = %v, want %v", tt.input, data, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSortStrings(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input []string
|
|
expected []string
|
|
}{
|
|
{"empty slice", []string{}, []string{}},
|
|
{"single element", []string{"hello"}, []string{"hello"}},
|
|
{"already sorted", []string{"a", "b", "c"}, []string{"a", "b", "c"}},
|
|
{"reverse sorted", []string{"z", "y", "x"}, []string{"x", "y", "z"}},
|
|
{"unsorted", []string{"banana", "apple", "cherry", "date"}, []string{"apple", "banana", "cherry", "date"}},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
data := make([]string, len(tt.input))
|
|
copy(data, tt.input)
|
|
SortStrings(data)
|
|
if !reflect.DeepEqual(data, tt.expected) {
|
|
t.Errorf("SortStrings(%v) = %v, want %v", tt.input, data, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSortStringsDescending(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input []string
|
|
expected []string
|
|
}{
|
|
{"empty slice", []string{}, []string{}},
|
|
{"ascending order", []string{"a", "b", "c"}, []string{"c", "b", "a"}},
|
|
{"unsorted", []string{"banana", "apple", "cherry"}, []string{"cherry", "banana", "apple"}},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
data := make([]string, len(tt.input))
|
|
copy(data, tt.input)
|
|
SortStringsDescending(data)
|
|
if !reflect.DeepEqual(data, tt.expected) {
|
|
t.Errorf("SortStringsDescending(%v) = %v, want %v", tt.input, data, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSortFloat64s(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input []float64
|
|
expected []float64
|
|
}{
|
|
{"empty slice", []float64{}, []float64{}},
|
|
{"single element", []float64{3.14}, []float64{3.14}},
|
|
{"unsorted", []float64{3.14, 1.41, 2.71, 1.73}, []float64{1.41, 1.73, 2.71, 3.14}},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
data := make([]float64, len(tt.input))
|
|
copy(data, tt.input)
|
|
SortFloat64s(data)
|
|
if !reflect.DeepEqual(data, tt.expected) {
|
|
t.Errorf("SortFloat64s(%v) = %v, want %v", tt.input, data, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSortFloat64sDescending(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input []float64
|
|
expected []float64
|
|
}{
|
|
{"empty slice", []float64{}, []float64{}},
|
|
{"unsorted", []float64{3.14, 1.41, 2.71}, []float64{3.14, 2.71, 1.41}},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
data := make([]float64, len(tt.input))
|
|
copy(data, tt.input)
|
|
SortFloat64sDescending(data)
|
|
if !reflect.DeepEqual(data, tt.expected) {
|
|
t.Errorf("SortFloat64sDescending(%v) = %v, want %v", tt.input, data, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSortBy(t *testing.T) {
|
|
type Person struct {
|
|
Name string
|
|
Age int
|
|
}
|
|
|
|
people := []Person{
|
|
{"Alice", 30},
|
|
{"Bob", 25},
|
|
{"Charlie", 35},
|
|
}
|
|
|
|
// Sort by age
|
|
SortBy(people, func(i, j int) bool {
|
|
return people[i].Age < people[j].Age
|
|
})
|
|
|
|
expected := []Person{
|
|
{"Bob", 25},
|
|
{"Alice", 30},
|
|
{"Charlie", 35},
|
|
}
|
|
|
|
if !reflect.DeepEqual(people, expected) {
|
|
t.Errorf("SortBy (by age) = %v, want %v", people, expected)
|
|
}
|
|
}
|
|
|
|
func TestSortByKey(t *testing.T) {
|
|
type Product struct {
|
|
Name string
|
|
Price float64
|
|
}
|
|
|
|
products := []Product{
|
|
{"Apple", 1.50},
|
|
{"Banana", 0.75},
|
|
{"Cherry", 3.00},
|
|
}
|
|
|
|
// Sort by price
|
|
SortByKey(products, func(p Product) float64 {
|
|
return p.Price
|
|
})
|
|
|
|
expected := []Product{
|
|
{"Banana", 0.75},
|
|
{"Apple", 1.50},
|
|
{"Cherry", 3.00},
|
|
}
|
|
|
|
if !reflect.DeepEqual(products, expected) {
|
|
t.Errorf("SortByKey (by price) = %v, want %v", products, expected)
|
|
}
|
|
}
|
|
|
|
func TestSortByKeyDescending(t *testing.T) {
|
|
type Student struct {
|
|
Name string
|
|
Score int
|
|
}
|
|
|
|
students := []Student{
|
|
{"Alice", 85},
|
|
{"Bob", 92},
|
|
{"Charlie", 78},
|
|
}
|
|
|
|
// Sort by score descending
|
|
SortByKeyDescending(students, func(s Student) int {
|
|
return s.Score
|
|
})
|
|
|
|
expected := []Student{
|
|
{"Bob", 92},
|
|
{"Alice", 85},
|
|
{"Charlie", 78},
|
|
}
|
|
|
|
if !reflect.DeepEqual(students, expected) {
|
|
t.Errorf("SortByKeyDescending (by score) = %v, want %v", students, expected)
|
|
}
|
|
}
|
|
|
|
func TestIsSorted(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input []int
|
|
expected bool
|
|
}{
|
|
{"empty slice", []int{}, true},
|
|
{"single element", []int{5}, true},
|
|
{"sorted ascending", []int{1, 2, 3, 4, 5}, true},
|
|
{"not sorted", []int{1, 3, 2, 4}, false},
|
|
{"sorted with duplicates", []int{1, 1, 2, 3}, true},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := IsSorted(tt.input)
|
|
if result != tt.expected {
|
|
t.Errorf("IsSorted(%v) = %v, want %v", tt.input, result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIsSortedStrings(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input []string
|
|
expected bool
|
|
}{
|
|
{"sorted", []string{"a", "b", "c"}, true},
|
|
{"not sorted", []string{"b", "a", "c"}, false},
|
|
{"empty", []string{}, true},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := IsSortedStrings(tt.input)
|
|
if result != tt.expected {
|
|
t.Errorf("IsSortedStrings(%v) = %v, want %v", tt.input, result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIsSortedFloat64s(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input []float64
|
|
expected bool
|
|
}{
|
|
{"sorted", []float64{1.1, 2.2, 3.3}, true},
|
|
{"not sorted", []float64{2.2, 1.1, 3.3}, false},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := IsSortedFloat64s(tt.input)
|
|
if result != tt.expected {
|
|
t.Errorf("IsSortedFloat64s(%v) = %v, want %v", tt.input, result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestBinarySearch(t *testing.T) {
|
|
data := []int{1, 3, 5, 7, 9, 11}
|
|
|
|
tests := []struct {
|
|
name string
|
|
target int
|
|
expected int
|
|
}{
|
|
{"found at start", 1, 0},
|
|
{"found in middle", 5, 2},
|
|
{"found at end", 11, 5},
|
|
{"not found", 4, -1},
|
|
{"not found - too small", 0, -1},
|
|
{"not found - too large", 12, -1},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := BinarySearch(data, tt.target)
|
|
if result != tt.expected {
|
|
t.Errorf("BinarySearch(%v, %d) = %d, want %d", data, tt.target, result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestBinarySearchStrings(t *testing.T) {
|
|
data := []string{"apple", "banana", "cherry", "date"}
|
|
|
|
tests := []struct {
|
|
name string
|
|
target string
|
|
expected int
|
|
}{
|
|
{"found at start", "apple", 0},
|
|
{"found in middle", "banana", 1},
|
|
{"found at end", "date", 3},
|
|
{"not found", "grape", -1},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := BinarySearchStrings(data, tt.target)
|
|
if result != tt.expected {
|
|
t.Errorf("BinarySearchStrings(%v, %q) = %d, want %d", data, tt.target, result, tt.expected)
|
|
}
|
|
})
|
|
}
|
|
}
|