Files

451 lines
9.1 KiB
Go

// Copyright (C) 2019-2025, Lux Industries, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package setmap
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/luxfi/math/set"
)
func TestSetMapPut(t *testing.T) {
tests := []struct {
name string
state *SetMap[int, int]
key int
value set.Set[int]
expectedRemoved []Entry[int, int]
expectedState *SetMap[int, int]
}{
{
name: "none removed",
state: New[int, int](),
key: 1,
value: set.Of(2),
expectedRemoved: nil,
expectedState: &SetMap[int, int]{
keyToSet: map[int]set.Set[int]{
1: set.Of(2),
},
valueToKey: map[int]int{
2: 1,
},
},
},
{
name: "key removed",
state: &SetMap[int, int]{
keyToSet: map[int]set.Set[int]{
1: set.Of(2),
},
valueToKey: map[int]int{
2: 1,
},
},
key: 1,
value: set.Of(3),
expectedRemoved: []Entry[int, int]{
{
Key: 1,
Set: set.Of(2),
},
},
expectedState: &SetMap[int, int]{
keyToSet: map[int]set.Set[int]{
1: set.Of(3),
},
valueToKey: map[int]int{
3: 1,
},
},
},
{
name: "value removed",
state: &SetMap[int, int]{
keyToSet: map[int]set.Set[int]{
1: set.Of(2),
},
valueToKey: map[int]int{
2: 1,
},
},
key: 3,
value: set.Of(2),
expectedRemoved: []Entry[int, int]{
{
Key: 1,
Set: set.Of(2),
},
},
expectedState: &SetMap[int, int]{
keyToSet: map[int]set.Set[int]{
3: set.Of(2),
},
valueToKey: map[int]int{
2: 3,
},
},
},
{
name: "key and value removed",
state: &SetMap[int, int]{
keyToSet: map[int]set.Set[int]{
1: set.Of(2),
3: set.Of(4),
},
valueToKey: map[int]int{
2: 1,
4: 3,
},
},
key: 1,
value: set.Of(4),
expectedRemoved: []Entry[int, int]{
{
Key: 1,
Set: set.Of(2),
},
{
Key: 3,
Set: set.Of(4),
},
},
expectedState: &SetMap[int, int]{
keyToSet: map[int]set.Set[int]{
1: set.Of(4),
},
valueToKey: map[int]int{
4: 1,
},
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
require := require.New(t)
removed := test.state.Put(test.key, test.value)
require.ElementsMatch(test.expectedRemoved, removed)
require.Equal(test.expectedState, test.state)
})
}
}
func TestSetMapHasValueAndGetKeyAndSetOverlaps(t *testing.T) {
m := New[int, int]()
require.Empty(t, m.Put(1, set.Of(2)))
tests := []struct {
name string
value int
expectedKey int
expectedExists bool
}{
{
name: "fetch unknown",
value: 3,
expectedKey: 0,
expectedExists: false,
},
{
name: "fetch known value",
value: 2,
expectedKey: 1,
expectedExists: true,
},
{
name: "fetch known key",
value: 1,
expectedKey: 0,
expectedExists: false,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
require := require.New(t)
exists := m.HasValue(test.value)
require.Equal(test.expectedExists, exists)
key, exists := m.GetKey(test.value)
require.Equal(test.expectedKey, key)
require.Equal(test.expectedExists, exists)
})
}
}
func TestSetMapHasOverlap(t *testing.T) {
m := New[int, int]()
require.Empty(t, m.Put(1, set.Of(2)))
require.Empty(t, m.Put(2, set.Of(3, 4)))
tests := []struct {
name string
set set.Set[int]
expectedOverlaps bool
}{
{
name: "small fetch unknown",
set: set.Of(5),
expectedOverlaps: false,
},
{
name: "large fetch unknown",
set: set.Of(5, 6, 7, 8),
expectedOverlaps: false,
},
{
name: "small fetch known",
set: set.Of(3),
expectedOverlaps: true,
},
{
name: "large fetch known",
set: set.Of(3, 5, 6, 7, 8),
expectedOverlaps: true,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
overlaps := m.HasOverlap(test.set)
require.Equal(t, test.expectedOverlaps, overlaps)
})
}
}
func TestSetMapHasKeyAndGetSet(t *testing.T) {
m := New[int, int]()
require.Empty(t, m.Put(1, set.Of(2)))
tests := []struct {
name string
key int
expectedValue set.Set[int]
expectedExists bool
}{
{
name: "fetch unknown",
key: 3,
expectedValue: nil,
expectedExists: false,
},
{
name: "fetch known key",
key: 1,
expectedValue: set.Of(2),
expectedExists: true,
},
{
name: "fetch known value",
key: 2,
expectedValue: nil,
expectedExists: false,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
require := require.New(t)
exists := m.HasKey(test.key)
require.Equal(test.expectedExists, exists)
value, exists := m.GetSet(test.key)
require.Equal(test.expectedValue, value)
require.Equal(test.expectedExists, exists)
})
}
}
func TestSetMapDeleteKey(t *testing.T) {
tests := []struct {
name string
state *SetMap[int, int]
key int
expectedValue set.Set[int]
expectedRemoved bool
expectedState *SetMap[int, int]
}{
{
name: "none removed",
state: New[int, int](),
key: 1,
expectedValue: nil,
expectedRemoved: false,
expectedState: New[int, int](),
},
{
name: "key removed",
state: &SetMap[int, int]{
keyToSet: map[int]set.Set[int]{
1: set.Of(2),
},
valueToKey: map[int]int{
2: 1,
},
},
key: 1,
expectedValue: set.Of(2),
expectedRemoved: true,
expectedState: New[int, int](),
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
require := require.New(t)
value, removed := test.state.DeleteKey(test.key)
require.Equal(test.expectedValue, value)
require.Equal(test.expectedRemoved, removed)
require.Equal(test.expectedState, test.state)
})
}
}
func TestSetMapDeleteValue(t *testing.T) {
tests := []struct {
name string
state *SetMap[int, int]
value int
expectedKey int
expectedSet set.Set[int]
expectedRemoved bool
expectedState *SetMap[int, int]
}{
{
name: "none removed",
state: New[int, int](),
value: 1,
expectedKey: 0,
expectedSet: nil,
expectedRemoved: false,
expectedState: New[int, int](),
},
{
name: "key removed",
state: &SetMap[int, int]{
keyToSet: map[int]set.Set[int]{
1: set.Of(2),
},
valueToKey: map[int]int{
2: 1,
},
},
value: 2,
expectedKey: 1,
expectedSet: set.Of(2),
expectedRemoved: true,
expectedState: New[int, int](),
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
require := require.New(t)
key, set, removed := test.state.DeleteValue(test.value)
require.Equal(test.expectedKey, key)
require.Equal(test.expectedSet, set)
require.Equal(test.expectedRemoved, removed)
require.Equal(test.expectedState, test.state)
})
}
}
func TestSetMapDeleteOverlapping(t *testing.T) {
tests := []struct {
name string
state *SetMap[int, int]
set set.Set[int]
expectedRemoved []Entry[int, int]
expectedState *SetMap[int, int]
}{
{
name: "none removed",
state: New[int, int](),
set: set.Of(1),
expectedRemoved: nil,
expectedState: New[int, int](),
},
{
name: "key removed",
state: &SetMap[int, int]{
keyToSet: map[int]set.Set[int]{
1: set.Of(2),
},
valueToKey: map[int]int{
2: 1,
},
},
set: set.Of(2),
expectedRemoved: []Entry[int, int]{
{
Key: 1,
Set: set.Of(2),
},
},
expectedState: New[int, int](),
},
{
name: "multiple keys removed",
state: &SetMap[int, int]{
keyToSet: map[int]set.Set[int]{
1: set.Of(2, 3),
2: set.Of(4),
},
valueToKey: map[int]int{
2: 1,
3: 1,
4: 2,
},
},
set: set.Of(2, 4),
expectedRemoved: []Entry[int, int]{
{
Key: 1,
Set: set.Of(2, 3),
},
{
Key: 2,
Set: set.Of(4),
},
},
expectedState: New[int, int](),
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
require := require.New(t)
removed := test.state.DeleteOverlapping(test.set)
require.ElementsMatch(test.expectedRemoved, removed)
require.Equal(test.expectedState, test.state)
})
}
}
func TestSetMapLen(t *testing.T) {
require := require.New(t)
m := New[int, int]()
require.Zero(m.Len())
require.Zero(m.LenValues())
m.Put(1, set.Of(2))
require.Equal(1, m.Len())
require.Equal(1, m.LenValues())
m.Put(2, set.Of(3, 4))
require.Equal(2, m.Len())
require.Equal(3, m.LenValues())
m.Put(1, set.Of(4, 5))
require.Equal(1, m.Len())
require.Equal(2, m.LenValues())
m.DeleteKey(1)
require.Zero(m.Len())
require.Zero(m.LenValues())
}