188 lines
3.9 KiB
Go
188 lines
3.9 KiB
Go
package collections_test
|
|
|
|
import (
|
|
"fmt"
|
|
"slices"
|
|
"testing"
|
|
|
|
"efprojects.com/kitten-ipc/kitcom/internal/tsgo/collections"
|
|
"github.com/go-json-experiment/json"
|
|
"gotest.tools/v3/assert"
|
|
)
|
|
|
|
func TestOrderedMap(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
var m collections.OrderedMap[int, string]
|
|
|
|
assert.Assert(t, !m.Has(1))
|
|
|
|
const (
|
|
N = 1000
|
|
start = 1
|
|
end = start + N
|
|
)
|
|
|
|
// Seed the map with ascending keys and values for easier testing.
|
|
for i := start; i < end; i++ {
|
|
m.Set(i, padInt(i))
|
|
}
|
|
|
|
assert.Equal(t, m.Size(), N)
|
|
|
|
// Attempt to overwrite existing keys in reverse order.
|
|
for i := end - 1; i >= start; i-- {
|
|
m.Set(i, padInt(i))
|
|
}
|
|
|
|
assert.Equal(t, m.Size(), N)
|
|
|
|
for i := start; i < end; i++ {
|
|
v, ok := m.Get(i)
|
|
assert.Assert(t, ok)
|
|
assert.Equal(t, v, padInt(i))
|
|
}
|
|
|
|
for k, v := range m.Entries() {
|
|
assert.Equal(t, v, padInt(k))
|
|
}
|
|
|
|
keys := slices.Collect(m.Keys())
|
|
assert.Equal(t, len(keys), N)
|
|
assert.Assert(t, slices.IsSorted(keys))
|
|
|
|
values := slices.Collect(m.Values())
|
|
assert.Equal(t, len(values), N)
|
|
assert.Assert(t, slices.IsSorted(values))
|
|
|
|
var firstKey int
|
|
for k := range m.Keys() {
|
|
firstKey = k
|
|
break
|
|
}
|
|
assert.Equal(t, firstKey, start)
|
|
|
|
var firstValue string
|
|
for v := range m.Values() {
|
|
firstValue = v
|
|
break
|
|
}
|
|
assert.Equal(t, firstValue, padInt(start))
|
|
|
|
for k, v := range m.Entries() {
|
|
firstKey = k
|
|
firstValue = v
|
|
break
|
|
}
|
|
|
|
assert.Equal(t, firstKey, start)
|
|
assert.Equal(t, firstValue, padInt(start))
|
|
|
|
for i := start + 1; i < end; i++ {
|
|
v, ok := m.Delete(i)
|
|
assert.Assert(t, ok)
|
|
assert.Equal(t, v, padInt(i))
|
|
assert.Assert(t, !m.Has(i))
|
|
|
|
v, ok = m.Get(i)
|
|
assert.Assert(t, !ok)
|
|
assert.Equal(t, v, "")
|
|
|
|
v, ok = m.Delete(i)
|
|
assert.Assert(t, !ok)
|
|
assert.Equal(t, v, "")
|
|
}
|
|
|
|
assert.Equal(t, m.Size(), 1)
|
|
assert.Assert(t, m.Has(start))
|
|
|
|
v, ok := m.Delete(start)
|
|
assert.Assert(t, ok)
|
|
assert.Equal(t, v, padInt(start))
|
|
|
|
assert.Equal(t, m.Size(), 0)
|
|
}
|
|
|
|
func TestOrderedMapClone(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
m := &collections.OrderedMap[int, string]{}
|
|
m.Set(1, "one")
|
|
m.Set(2, "two")
|
|
|
|
clone := m.Clone()
|
|
|
|
assert.Assert(t, clone != m)
|
|
assert.Equal(t, clone.Size(), 2)
|
|
assert.DeepEqual(t, slices.Collect(clone.Keys()), []int{1, 2})
|
|
assert.DeepEqual(t, slices.Collect(clone.Values()), []string{"one", "two"})
|
|
|
|
v, ok := clone.Get(1)
|
|
assert.Assert(t, ok)
|
|
assert.Equal(t, v, "one")
|
|
|
|
m.Delete(1)
|
|
|
|
assert.Equal(t, m.Size(), 1)
|
|
assert.Equal(t, clone.Size(), 2)
|
|
assert.DeepEqual(t, slices.Collect(clone.Keys()), []int{1, 2})
|
|
assert.DeepEqual(t, slices.Collect(clone.Values()), []string{"one", "two"})
|
|
}
|
|
|
|
func TestOrderedMapClear(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
var m collections.OrderedMap[int, string]
|
|
m.Set(1, "one")
|
|
m.Set(2, "two")
|
|
|
|
m.Clear()
|
|
|
|
assert.Equal(t, m.Size(), 0)
|
|
}
|
|
|
|
func padInt(n int) string {
|
|
return fmt.Sprintf("%10d", n)
|
|
}
|
|
|
|
func TestOrderedMapWithSizeHint(t *testing.T) { //nolint:paralleltest
|
|
const N = 1024
|
|
|
|
allocs := testing.AllocsPerRun(10, func() {
|
|
m := collections.NewOrderedMapWithSizeHint[int, int](N)
|
|
for i := range N {
|
|
m.Set(i, i)
|
|
}
|
|
})
|
|
|
|
assert.Assert(t, allocs < 10, "allocs = %v", allocs)
|
|
}
|
|
|
|
func TestOrderedMapUnmarshalJSON(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("UnmarshalJSONV2", func(t *testing.T) {
|
|
t.Parallel()
|
|
testOrderedMapUnmarshalJSON(t, func(in []byte, out any) error { return json.Unmarshal(in, out) })
|
|
})
|
|
}
|
|
|
|
func testOrderedMapUnmarshalJSON(t *testing.T, unmarshal func([]byte, any) error) {
|
|
var m collections.OrderedMap[string, any]
|
|
err := unmarshal([]byte(`{"a": 1, "b": "two", "c": { "d": 4 } }`), &m)
|
|
assert.NilError(t, err)
|
|
|
|
assert.Equal(t, m.Size(), 3)
|
|
assert.Equal(t, m.GetOrZero("a"), float64(1))
|
|
|
|
err = unmarshal([]byte(`null`), &m)
|
|
assert.NilError(t, err)
|
|
|
|
err = unmarshal([]byte(`"foo"`), &m)
|
|
assert.ErrorContains(t, err, "cannot unmarshal non-object JSON value into Map")
|
|
|
|
var invalidMap collections.OrderedMap[int, any]
|
|
err = unmarshal([]byte(`{"a": 1, "b": "two"}`), &invalidMap)
|
|
assert.ErrorContains(t, err, "unmarshal")
|
|
}
|