This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
package dataext
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSyncMap_SetGet(t *testing.T) {
|
||||
m := NewSyncMap[string, int]()
|
||||
m.Set("a", 1)
|
||||
v, ok := m.Get("a")
|
||||
if !ok || v != 1 {
|
||||
t.Fatalf("got (%d,%v)", v, ok)
|
||||
}
|
||||
if _, ok := m.Get("missing"); ok {
|
||||
t.Fatal("expected missing")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncMap_SetIfNotContains(t *testing.T) {
|
||||
m := NewSyncMap[string, int]()
|
||||
if !m.SetIfNotContains("a", 1) {
|
||||
t.Fatal("first set should succeed")
|
||||
}
|
||||
if m.SetIfNotContains("a", 2) {
|
||||
t.Fatal("second set should fail")
|
||||
}
|
||||
v, _ := m.Get("a")
|
||||
if v != 1 {
|
||||
t.Fatalf("expected unchanged got %d", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncMap_SetIfNotContainsFunc(t *testing.T) {
|
||||
m := NewSyncMap[string, int]()
|
||||
calls := 0
|
||||
if !m.SetIfNotContainsFunc("a", func() int { calls++; return 5 }) {
|
||||
t.Fatal("first should succeed")
|
||||
}
|
||||
if m.SetIfNotContainsFunc("a", func() int { calls++; return 6 }) {
|
||||
t.Fatal("second should fail")
|
||||
}
|
||||
if calls != 1 {
|
||||
t.Fatalf("calls=%d want 1", calls)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncMap_GetAndSetIfNotContains(t *testing.T) {
|
||||
m := NewSyncMap[string, int]()
|
||||
if v := m.GetAndSetIfNotContains("a", 10); v != 10 {
|
||||
t.Fatalf("got %d", v)
|
||||
}
|
||||
if v := m.GetAndSetIfNotContains("a", 99); v != 10 {
|
||||
t.Fatalf("got %d", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncMap_GetAndSetIfNotContainsFunc(t *testing.T) {
|
||||
m := NewSyncMap[string, int]()
|
||||
calls := 0
|
||||
if v := m.GetAndSetIfNotContainsFunc("a", func() int { calls++; return 1 }); v != 1 {
|
||||
t.Fatalf("got %d", v)
|
||||
}
|
||||
if v := m.GetAndSetIfNotContainsFunc("a", func() int { calls++; return 2 }); v != 1 {
|
||||
t.Fatalf("got %d", v)
|
||||
}
|
||||
if calls != 1 {
|
||||
t.Fatalf("calls=%d", calls)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncMap_Delete(t *testing.T) {
|
||||
m := NewSyncMap[string, int]()
|
||||
m.Set("a", 1)
|
||||
if !m.Delete("a") {
|
||||
t.Fatal("delete existing returned false")
|
||||
}
|
||||
if m.Delete("a") {
|
||||
t.Fatal("delete missing returned true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncMap_DeleteIf(t *testing.T) {
|
||||
m := NewSyncMap[string, int]()
|
||||
m.Set("a", 1)
|
||||
m.Set("b", 2)
|
||||
m.Set("c", 3)
|
||||
rm := m.DeleteIf(func(k string, v int) bool { return v%2 == 1 })
|
||||
if rm != 2 {
|
||||
t.Fatalf("removed=%d", rm)
|
||||
}
|
||||
if m.Count() != 1 {
|
||||
t.Fatalf("count=%d", m.Count())
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncMap_UpdateIfExists(t *testing.T) {
|
||||
m := NewSyncMap[string, int]()
|
||||
if m.UpdateIfExists("a", func(v int) int { return v + 1 }) {
|
||||
t.Fatal("should be false on missing key")
|
||||
}
|
||||
m.Set("a", 5)
|
||||
if !m.UpdateIfExists("a", func(v int) int { return v + 1 }) {
|
||||
t.Fatal("should be true on existing")
|
||||
}
|
||||
v, _ := m.Get("a")
|
||||
if v != 6 {
|
||||
t.Fatalf("v=%d", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncMap_UpdateOrInsert(t *testing.T) {
|
||||
m := NewSyncMap[string, int]()
|
||||
if m.UpdateOrInsert("a", func(v int) int { return v + 1 }, 100) {
|
||||
t.Fatal("should return false on insert")
|
||||
}
|
||||
if v, _ := m.Get("a"); v != 100 {
|
||||
t.Fatalf("v=%d", v)
|
||||
}
|
||||
if !m.UpdateOrInsert("a", func(v int) int { return v + 1 }, 100) {
|
||||
t.Fatal("should return true on update")
|
||||
}
|
||||
if v, _ := m.Get("a"); v != 101 {
|
||||
t.Fatalf("v=%d", v)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncMap_ClearContains(t *testing.T) {
|
||||
m := NewSyncMap[string, int]()
|
||||
m.Set("a", 1)
|
||||
if !m.Contains("a") {
|
||||
t.Fatal("Contains should be true")
|
||||
}
|
||||
m.Clear()
|
||||
if m.Contains("a") {
|
||||
t.Fatal("after Clear should be false")
|
||||
}
|
||||
if m.Count() != 0 {
|
||||
t.Fatalf("count=%d", m.Count())
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncMap_GetAllKeysValues(t *testing.T) {
|
||||
m := NewSyncMap[string, int]()
|
||||
m.Set("a", 1)
|
||||
m.Set("b", 2)
|
||||
m.Set("c", 3)
|
||||
keys := m.GetAllKeys()
|
||||
sort.Strings(keys)
|
||||
if len(keys) != 3 || keys[0] != "a" || keys[2] != "c" {
|
||||
t.Fatalf("keys=%v", keys)
|
||||
}
|
||||
vals := m.GetAllValues()
|
||||
sort.Ints(vals)
|
||||
if len(vals) != 3 || vals[0] != 1 || vals[2] != 3 {
|
||||
t.Fatalf("vals=%v", vals)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncMap_Concurrent(t *testing.T) {
|
||||
m := NewSyncMap[int, int]()
|
||||
var wg sync.WaitGroup
|
||||
const n = 200
|
||||
wg.Add(n)
|
||||
for i := 0; i < n; i++ {
|
||||
go func(k int) {
|
||||
defer wg.Done()
|
||||
m.Set(k, k*2)
|
||||
}(i)
|
||||
}
|
||||
wg.Wait()
|
||||
if m.Count() != n {
|
||||
t.Fatalf("count=%d want %d", m.Count(), n)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user