2023-10-11 20:00:01 +00:00
|
|
|
// Copyright (c) Tailscale Inc & AUTHORS
|
|
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
|
|
|
|
package nocasemaps
|
|
|
|
|
|
|
|
import (
|
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
qt "github.com/frankban/quicktest"
|
|
|
|
xmaps "golang.org/x/exp/maps"
|
|
|
|
)
|
|
|
|
|
|
|
|
func pair[A, B any](a A, b B) (out struct {
|
|
|
|
A A
|
|
|
|
B B
|
|
|
|
}) {
|
|
|
|
out.A = a
|
|
|
|
out.B = b
|
|
|
|
return out
|
|
|
|
}
|
|
|
|
|
|
|
|
func Test(t *testing.T) {
|
|
|
|
c := qt.New(t)
|
|
|
|
m := make(map[string]int)
|
|
|
|
Set(m, "hello", 1)
|
|
|
|
c.Assert(m, qt.DeepEquals, map[string]int{"hello": 1})
|
|
|
|
Set(m, "HeLlO", 2)
|
|
|
|
c.Assert(m, qt.DeepEquals, map[string]int{"hello": 2})
|
|
|
|
c.Assert(Get(m, "hello"), qt.Equals, 2)
|
|
|
|
c.Assert(pair(GetOk(m, "hello")), qt.Equals, pair(2, true))
|
|
|
|
c.Assert(Get(m, "HeLlO"), qt.Equals, 2)
|
|
|
|
c.Assert(pair(GetOk(m, "HeLlO")), qt.Equals, pair(2, true))
|
|
|
|
c.Assert(Get(m, "HELLO"), qt.Equals, 2)
|
|
|
|
c.Assert(pair(GetOk(m, "HELLO")), qt.Equals, pair(2, true))
|
|
|
|
c.Assert(Get(m, "missing"), qt.Equals, 0)
|
|
|
|
c.Assert(pair(GetOk(m, "missing")), qt.Equals, pair(0, false))
|
|
|
|
Set(m, "foo", 3)
|
|
|
|
Set(m, "BAR", 4)
|
|
|
|
Set(m, "bAz", 5)
|
|
|
|
c.Assert(m, qt.DeepEquals, map[string]int{"hello": 2, "foo": 3, "bar": 4, "baz": 5})
|
|
|
|
Delete(m, "foo")
|
|
|
|
c.Assert(m, qt.DeepEquals, map[string]int{"hello": 2, "bar": 4, "baz": 5})
|
|
|
|
Delete(m, "bar")
|
|
|
|
c.Assert(m, qt.DeepEquals, map[string]int{"hello": 2, "baz": 5})
|
|
|
|
Delete(m, "BAZ")
|
|
|
|
c.Assert(m, qt.DeepEquals, map[string]int{"hello": 2})
|
2024-01-19 23:30:12 +00:00
|
|
|
// test cases for AppendSliceElem with int slices
|
|
|
|
appendTestInt := make(map[string][]int)
|
|
|
|
Set(appendTestInt, "firsT", []int{7})
|
|
|
|
c.Assert(appendTestInt, qt.DeepEquals, map[string][]int{"first": {7}})
|
|
|
|
AppendSliceElem(appendTestInt, "firsT", 77)
|
|
|
|
c.Assert(appendTestInt, qt.DeepEquals, map[string][]int{"first": {7, 77}})
|
|
|
|
Set(appendTestInt, "SeCOnd", []int{56})
|
|
|
|
c.Assert(appendTestInt, qt.DeepEquals, map[string][]int{"first": {7, 77}, "second": {56}})
|
|
|
|
AppendSliceElem(appendTestInt, "seCOnd", 563, 23)
|
|
|
|
c.Assert(appendTestInt, qt.DeepEquals, map[string][]int{"first": {7, 77}, "second": {56, 563, 23}})
|
|
|
|
// test cases for AppendSliceElem with string slices
|
|
|
|
appendTestString := make(map[string][]string)
|
|
|
|
Set(appendTestString, "firsTSTRING", []string{"hi"})
|
|
|
|
c.Assert(appendTestString, qt.DeepEquals, map[string][]string{"firststring": {"hi"}})
|
|
|
|
AppendSliceElem(appendTestString, "firsTSTRING", "hello", "bye")
|
|
|
|
c.Assert(appendTestString, qt.DeepEquals, map[string][]string{"firststring": {"hi", "hello", "bye"}})
|
|
|
|
|
2023-10-11 20:00:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var lowerTests = []struct{ in, want string }{
|
|
|
|
{"", ""},
|
|
|
|
{"abc", "abc"},
|
|
|
|
{"AbC123", "abc123"},
|
|
|
|
{"azAZ09_", "azaz09_"},
|
|
|
|
{"longStrinGwitHmixofsmaLLandcAps", "longstringwithmixofsmallandcaps"},
|
|
|
|
{"renan bastos 93 AOSDAJDJAIDJAIDAJIaidsjjaidijadsjiadjiOOKKO", "renan bastos 93 aosdajdjaidjaidajiaidsjjaidijadsjiadjiookko"},
|
|
|
|
{"LONG\u2C6FSTRING\u2C6FWITH\u2C6FNONASCII\u2C6FCHARS", "long\u0250string\u0250with\u0250nonascii\u0250chars"},
|
|
|
|
{"\u2C6D\u2C6D\u2C6D\u2C6D\u2C6D", "\u0251\u0251\u0251\u0251\u0251"}, // shrinks one byte per char
|
|
|
|
{"A\u0080\U0010FFFF", "a\u0080\U0010FFFF"}, // test utf8.RuneSelf and utf8.MaxRune
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestAppendToLower(t *testing.T) {
|
|
|
|
for _, tt := range lowerTests {
|
|
|
|
got := string(appendToLower(nil, tt.in))
|
|
|
|
if got != tt.want {
|
|
|
|
t.Errorf("appendToLower(%q) = %q, want %q", tt.in, got, tt.want)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func FuzzAppendToLower(f *testing.F) {
|
|
|
|
for _, tt := range lowerTests {
|
|
|
|
f.Add(tt.in)
|
|
|
|
}
|
|
|
|
f.Fuzz(func(t *testing.T, in string) {
|
|
|
|
got := string(appendToLower(nil, in))
|
|
|
|
want := strings.ToLower(in)
|
|
|
|
if got != want {
|
|
|
|
t.Errorf("appendToLower(%q) = %q, want %q", in, got, want)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
testLower = "production-server"
|
|
|
|
testUpper = "PRODUCTION-SERVER"
|
|
|
|
testMap = make(map[string]int)
|
|
|
|
testValue = 5
|
|
|
|
testSink int
|
|
|
|
)
|
|
|
|
|
|
|
|
func Benchmark(b *testing.B) {
|
|
|
|
for i, key := range []string{testLower, testUpper} {
|
|
|
|
b.Run([]string{"Lower", "Upper"}[i], func(b *testing.B) {
|
|
|
|
b.Run("Get", func(b *testing.B) {
|
|
|
|
b.Run("Naive", func(b *testing.B) {
|
|
|
|
b.ReportAllocs()
|
2024-04-16 20:15:13 +00:00
|
|
|
for range b.N {
|
2023-10-11 20:00:01 +00:00
|
|
|
testSink = testMap[strings.ToLower(key)]
|
|
|
|
}
|
|
|
|
})
|
|
|
|
b.Run("NoCase", func(b *testing.B) {
|
|
|
|
b.ReportAllocs()
|
2024-04-16 20:15:13 +00:00
|
|
|
for range b.N {
|
2023-10-11 20:00:01 +00:00
|
|
|
testSink = Get(testMap, key)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
b.Run("Set", func(b *testing.B) {
|
|
|
|
b.Run("Naive", func(b *testing.B) {
|
|
|
|
b.ReportAllocs()
|
|
|
|
testMap[strings.ToLower(key)] = testValue
|
2024-04-16 20:15:13 +00:00
|
|
|
for range b.N {
|
2023-10-11 20:00:01 +00:00
|
|
|
testMap[strings.ToLower(key)] = testValue
|
|
|
|
}
|
|
|
|
xmaps.Clear(testMap)
|
|
|
|
})
|
|
|
|
b.Run("NoCase", func(b *testing.B) {
|
|
|
|
b.ReportAllocs()
|
|
|
|
Set(testMap, key, testValue)
|
2024-04-16 20:15:13 +00:00
|
|
|
for range b.N {
|
2023-10-11 20:00:01 +00:00
|
|
|
Set(testMap, key, testValue)
|
|
|
|
}
|
|
|
|
xmaps.Clear(testMap)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
b.Run("Delete", func(b *testing.B) {
|
|
|
|
b.Run("Naive", func(b *testing.B) {
|
|
|
|
b.ReportAllocs()
|
2024-04-16 20:15:13 +00:00
|
|
|
for range b.N {
|
2023-10-11 20:00:01 +00:00
|
|
|
delete(testMap, strings.ToLower(key))
|
|
|
|
}
|
|
|
|
})
|
|
|
|
b.Run("NoCase", func(b *testing.B) {
|
|
|
|
b.ReportAllocs()
|
2024-04-16 20:15:13 +00:00
|
|
|
for range b.N {
|
2023-10-11 20:00:01 +00:00
|
|
|
Delete(testMap, key)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|