blob: bb93dfdfe888739047649ae1efcadf7fa7b7653e [file] [log] [blame]
package mapsets
import (
"strings"
"testing"
)
// TestOrderedMap exercises the basics of an OrderedMap.
func TestOrderedMap(t *testing.T) {
m := OrderedMap[string, string]{}
if want, got := 0, len(m.Keys()); want != got {
t.Errorf("empty map should have %d keys, got %d", want, got)
}
// Test insertion.
m.Insert("a", "foo")
if got, ok := m.Get("a"); !ok || got != "foo" {
t.Errorf("Wanted value 'foo', got %q", got)
}
// Test update.
m.Insert("a", "bar")
if got, ok := m.Get("a"); !ok || got != "bar" {
t.Errorf("Wanted value 'bar', got %q", got)
}
// Helper to ensure that the keys returned by the map are the same as keystring
// split by commas.
keysEq := func(m *OrderedMap[string, string], keystring string) {
t.Helper()
keys := strings.Split(keystring, ",")
if want, got := keys, m.Keys(); len(want) == len(got) {
for i, k := range want {
if got[i] != k {
t.Errorf("Wanted key %d %q, got %q", i, want[i], got[i])
}
}
} else {
t.Errorf("Wanted keys %v, got %v", want, got)
}
}
// Test keys. They should get sorted.
m.Insert("c", "baz")
m.Insert("b", "barfoo")
keysEq(&m, "a,b,c")
// Test deleting and re-inserting a key.
m.Delete("a")
keysEq(&m, "b,c")
m.Insert("a", "a")
keysEq(&m, "a,b,c")
// Test clone.
n := m.Clone()
// Inserting into the original OrderedMap shouldn't impact the clone.
m.Insert("z", "zz")
keysEq(&m, "a,b,c,z")
keysEq(&n, "a,b,c")
// Test replace.
n.Replace(&m)
keysEq(&n, "a,b,c,z")
// Test Values.
values := n.Values()
if want, got := 4, len(values); want != got {
t.Errorf("Expected %d values, got %d", want, got)
} else {
for i, k := range []string{"a", "b", "c", "z"} {
if want, got := k, values[i].Key; want != got {
t.Errorf("Key %d should've been %q, got %q", i, want, got)
}
}
for i, v := range []string{"a", "barfoo", "baz", "zz"} {
if want, got := v, values[i].Value; want != got {
t.Errorf("Value %d should've been %q, got %q", i, want, got)
}
}
}
}
// TestCycleIterator exercises the CycleIterator.
func TestCycleIterator(t *testing.T) {
m := OrderedMap[string, string]{}
it := m.Cycle()
// Helper to ensure that the iterator returns a list of (key, values) string
// pairs, as defined by keystring and valuestring, split by commas.
valuesEq := func(keystring, valuestring string) {
t.Helper()
wantKeys := strings.Split(keystring, ",")
if keystring == "" {
wantKeys = nil
}
wantValues := strings.Split(valuestring, ",")
if valuestring == "" {
wantValues = nil
}
if len(wantKeys) != len(wantValues) {
// Test programming error.
t.Fatalf("keystring length != valuestring length")
}
var ix int
for {
// Out of test elements? We're done.
if ix >= len(wantKeys) {
return
}
k, v, ok := it.Next()
if !ok {
// Iterator empty while test cases present? Fail.
if ix < len(wantKeys) {
t.Errorf("Iterator empty")
}
break
}
if want, got := wantKeys[ix], k; want != got {
t.Errorf("Iterator returned key %q at %d, wanted %q", got, ix, want)
}
if want, got := wantValues[ix], v; want != got {
t.Errorf("Iterator returned value %q at %d, wanted %q", got, ix, want)
}
ix++
}
}
// Empty iterator should fail immediately.
it.Reset()
valuesEq("", "")
// Expect keys/values in order.
m.Insert("z", "foo")
m.Insert("a", "bar")
m.Insert("c", "baz")
valuesEq("a,c,z", "bar,baz,foo")
// The iterator should cycle.
valuesEq("a,c,z,a,c,z,a,c,z", "bar,baz,foo,bar,baz,foo,bar,baz,foo")
// Reset iterator and read only first value.
it.Reset()
valuesEq("a", "bar")
// Now insert a new key, the iterator should handle that.
m.Insert("b", "hello")
valuesEq("b,c,z", "hello,baz,foo")
// Reset iterator and only read first value.
it.Reset()
valuesEq("a", "bar")
// Now update an existing key. The iterator should continue.
m.Insert("b", "goodbye")
valuesEq("b,c,z", "goodbye,baz,foo")
// Reset iterator and only read first value.
it.Reset()
valuesEq("a", "bar")
// Now remove all values. The iterator should fail immediately.
m.Replace(&OrderedMap[string, string]{})
valuesEq("", "")
}