202 lines
4.4 KiB
Go
202 lines
4.4 KiB
Go
package utils
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
type TestUser struct {
|
|
ID string
|
|
Name string
|
|
Email string
|
|
}
|
|
|
|
func TestMultiIndex_AddAndFind(t *testing.T) {
|
|
idx := NewMultiIndex[TestUser](2)
|
|
|
|
user := TestUser{"1", "John Doe", "john@example.com"}
|
|
idx.AddItem(user, [][]string{
|
|
{"john@example.com"},
|
|
{"john", "doe"},
|
|
})
|
|
|
|
found, ok := idx.FindItem(0, []string{"john@example.com"})
|
|
if !ok {
|
|
t.Fatal("expected to find user by email")
|
|
}
|
|
if found.ID != "1" {
|
|
t.Errorf("got ID %s, want 1", found.ID)
|
|
}
|
|
|
|
found, ok = idx.FindItem(1, []string{"john", "doe"})
|
|
if !ok {
|
|
t.Fatal("expected to find user by name")
|
|
}
|
|
if found.Name != "John Doe" {
|
|
t.Errorf("got Name %s, want John Doe", found.Name)
|
|
}
|
|
}
|
|
|
|
func TestMultiIndex_NotFound(t *testing.T) {
|
|
idx := NewMultiIndex[TestUser](1)
|
|
|
|
idx.AddItem(TestUser{"1", "John", "john@example.com"}, [][]string{
|
|
{"john@example.com"},
|
|
})
|
|
|
|
_, ok := idx.FindItem(0, []string{"jane@example.com"})
|
|
if ok {
|
|
t.Error("expected not found")
|
|
}
|
|
}
|
|
|
|
func TestMultiIndex_WrongCompositeKey(t *testing.T) {
|
|
idx := NewMultiIndex[TestUser](1)
|
|
|
|
idx.AddItem(TestUser{"1", "John Doe", "john@example.com"}, [][]string{
|
|
{"john", "doe"},
|
|
})
|
|
|
|
_, ok := idx.FindItem(0, []string{"john", "smith"})
|
|
if ok {
|
|
t.Error("expected not found with wrong composite key")
|
|
}
|
|
|
|
_, ok = idx.FindItem(0, []string{"john"})
|
|
if ok {
|
|
t.Error("expected not found with partial key")
|
|
}
|
|
}
|
|
|
|
func TestMultiIndex_KeyCollisionHandling(t *testing.T) {
|
|
idx := NewMultiIndex[TestUser](1)
|
|
|
|
idx.AddItem(TestUser{"1", "User1", "user1@example.com"}, [][]string{
|
|
{"ab", "cd"},
|
|
})
|
|
|
|
idx.AddItem(TestUser{"2", "User2", "user2@example.com"}, [][]string{
|
|
{"abc", "d"},
|
|
})
|
|
|
|
found, ok := idx.FindItem(0, []string{"ab", "cd"})
|
|
if !ok || found.ID != "1" {
|
|
t.Error("collision: wrong user for ['ab', 'cd']")
|
|
}
|
|
|
|
found, ok = idx.FindItem(0, []string{"abc", "d"})
|
|
if !ok || found.ID != "2" {
|
|
t.Error("collision: wrong user for ['abc', 'd']")
|
|
}
|
|
}
|
|
|
|
func TestMultiIndex_InvalidIndex(t *testing.T) {
|
|
idx := NewMultiIndex[TestUser](2)
|
|
|
|
idx.AddItem(TestUser{"1", "John", "john@example.com"}, [][]string{
|
|
{"john@example.com"},
|
|
{"john"},
|
|
})
|
|
|
|
_, ok := idx.FindItem(-1, []string{"john@example.com"})
|
|
if ok {
|
|
t.Error("expected not found for negative index")
|
|
}
|
|
|
|
_, ok = idx.FindItem(5, []string{"john@example.com"})
|
|
if ok {
|
|
t.Error("expected not found for out of range index")
|
|
}
|
|
}
|
|
|
|
func TestMultiIndex_Items(t *testing.T) {
|
|
idx := NewMultiIndex[TestUser](1)
|
|
|
|
users := []TestUser{
|
|
{"1", "John", "john@example.com"},
|
|
{"2", "Jane", "jane@example.com"},
|
|
{"3", "Bob", "bob@example.com"},
|
|
}
|
|
|
|
for _, u := range users {
|
|
idx.AddItem(u, [][]string{{u.Email}})
|
|
}
|
|
|
|
items := idx.Items()
|
|
if len(items) != 3 {
|
|
t.Fatalf("got %d items, want 3", len(items))
|
|
}
|
|
|
|
for i, u := range users {
|
|
if items[i].ID != u.ID {
|
|
t.Errorf("item %d: got ID %s, want %s", i, items[i].ID, u.ID)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestMultiIndex_ItemsIsCopy(t *testing.T) {
|
|
idx := NewMultiIndex[TestUser](1)
|
|
|
|
idx.AddItem(TestUser{"1", "John", "john@example.com"}, [][]string{
|
|
{"john@example.com"},
|
|
})
|
|
|
|
items := idx.Items()
|
|
items[0].Name = "Modified"
|
|
|
|
original, _ := idx.FindItem(0, []string{"john@example.com"})
|
|
if original.Name != "John" {
|
|
t.Error("Items() should return a copy, not affect internal state")
|
|
}
|
|
}
|
|
|
|
func TestMultiIndex_PanicOnWrongKeysLength(t *testing.T) {
|
|
defer func() {
|
|
if r := recover(); r == nil {
|
|
t.Error("expected panic on wrong searchKeys length")
|
|
}
|
|
}()
|
|
|
|
idx := NewMultiIndex[TestUser](2)
|
|
idx.AddItem(TestUser{"1", "John", "john@example.com"}, [][]string{
|
|
{"john@example.com"},
|
|
// missing second index key
|
|
})
|
|
}
|
|
|
|
func TestMultiIndex_MultipleItemsSameIndex(t *testing.T) {
|
|
idx := NewMultiIndex[TestUser](2)
|
|
|
|
idx.AddItem(TestUser{"1", "John Doe", "john@example.com"}, [][]string{
|
|
{"john@example.com"},
|
|
{"john", "doe"},
|
|
})
|
|
|
|
idx.AddItem(TestUser{"2", "Jane Doe", "jane@example.com"}, [][]string{
|
|
{"jane@example.com"},
|
|
{"jane", "doe"},
|
|
})
|
|
|
|
john, ok := idx.FindItem(1, []string{"john", "doe"})
|
|
if !ok || john.ID != "1" {
|
|
t.Error("failed to find John by name")
|
|
}
|
|
|
|
jane, ok := idx.FindItem(1, []string{"jane", "doe"})
|
|
if !ok || jane.ID != "2" {
|
|
t.Error("failed to find Jane by name")
|
|
}
|
|
}
|
|
|
|
func TestMultiIndex_EmptyIndex(t *testing.T) {
|
|
idx := NewMultiIndex[TestUser](1)
|
|
|
|
_, ok := idx.FindItem(0, []string{"anything"})
|
|
if ok {
|
|
t.Error("expected not found in empty index")
|
|
}
|
|
|
|
items := idx.Items()
|
|
if len(items) != 0 {
|
|
t.Errorf("expected 0 items, got %d", len(items))
|
|
}
|
|
}
|