1
0
Fork 0
mirror of https://github.com/anyproto/any-sync.git synced 2025-06-08 05:57:03 +09:00
any-sync/util/slice/slice_test.go
2025-02-05 20:18:17 +01:00

279 lines
6.6 KiB
Go

package slice
import (
"testing"
"github.com/stretchr/testify/require"
"golang.org/x/exp/slices"
)
func TestCompareMaps(t *testing.T) {
tests := []struct {
name string
map1, map2 map[string]struct{}
expectedBoth []string
expectedFirst []string
expectedSecond []string
}{
{
name: "Both maps empty",
map1: map[string]struct{}{},
map2: map[string]struct{}{},
expectedBoth: []string{},
expectedFirst: []string{},
expectedSecond: []string{},
},
{
name: "Disjoint maps",
map1: map[string]struct{}{
"a": {},
"b": {},
},
map2: map[string]struct{}{
"c": {},
"d": {},
},
expectedBoth: []string{},
expectedFirst: []string{"a", "b"},
expectedSecond: []string{"c", "d"},
},
{
name: "Identical maps",
map1: map[string]struct{}{
"a": {},
"b": {},
},
map2: map[string]struct{}{
"a": {},
"b": {},
},
expectedBoth: []string{"a", "b"},
expectedFirst: []string{},
expectedSecond: []string{},
},
{
name: "Partial overlap",
map1: map[string]struct{}{
"a": {},
"b": {},
"c": {},
},
map2: map[string]struct{}{
"b": {},
"c": {},
"d": {},
},
expectedBoth: []string{"b", "c"},
expectedFirst: []string{"a"},
expectedSecond: []string{"d"},
},
{
name: "First map empty",
map1: map[string]struct{}{},
map2: map[string]struct{}{
"a": {},
"b": {},
},
expectedBoth: []string{},
expectedFirst: []string{},
expectedSecond: []string{"a", "b"},
},
{
name: "Second map empty",
map1: map[string]struct{}{
"a": {},
"b": {},
},
map2: map[string]struct{}{},
expectedBoth: []string{},
expectedFirst: []string{"a", "b"},
expectedSecond: []string{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
both, onlyInFirst, onlyInSecond := CompareMaps(tt.map1, tt.map2)
slices.Sort(onlyInFirst)
slices.Sort(onlyInSecond)
slices.Sort(both)
require.Equal(t, tt.expectedBoth, both)
require.Equal(t, tt.expectedFirst, onlyInFirst)
require.Equal(t, tt.expectedSecond, onlyInSecond)
})
}
}
func TestContainsSorted(t *testing.T) {
tests := []struct {
name string
first []int
second []int
expected bool
}{
{"both empty", []int{}, []int{}, true},
{"first empty", []int{}, []int{1}, false},
{"equal length but different", []int{2}, []int{1}, false},
{"second empty", []int{1, 2, 3}, []int{}, true},
{"both non-empty and first contains second", []int{1, 2, 3, 4, 5}, []int{2, 3, 4}, true},
{"both non-empty and first does not contain second", []int{1, 2, 3, 4, 5}, []int{3, 4, 6}, false},
{"both non-empty and first shorter than second", []int{1, 2, 3}, []int{1, 2, 3, 4}, false},
{"both non-empty and first equals second", []int{1, 2, 3}, []int{1, 2, 3}, true},
{"both non-empty and first contains second at the beginning", []int{1, 2, 3, 4, 5}, []int{1, 2, 3}, true},
{"both non-empty and first contains second at the end", []int{1, 2, 3, 4, 5}, []int{3, 4, 5}, true},
{"non-consecutive elements", []int{1, 3, 5, 7, 9}, []int{3, 7}, true},
{"unsorted first contains sorted second", []int{5, 1, 3, 2, 4}, []int{2, 3, 4}, true},
{"unsorted first does not contain sorted second", []int{5, 1, 3, 2, 4}, []int{3, 4, 6}, false},
{"test previous bug", []int{1, 3}, []int{2}, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := ContainsSorted(tt.first, tt.second)
if result != tt.expected {
t.Errorf("ContainsSorted(%v, %v) = %v; want %v", tt.first, tt.second, result, tt.expected)
}
})
}
}
func TestRemoveRepeatedSorted(t *testing.T) {
tests := []struct {
name string
input []int
expected []int
}{
{
name: "empty slice",
input: []int{},
expected: []int{},
},
{
name: "single element",
input: []int{1},
expected: []int{1},
},
{
name: "all duplicates",
input: []int{2, 2, 2},
expected: []int{},
},
{
name: "mixed duplicates and unique",
input: []int{1, 2, 2, 3, 4, 4, 4},
expected: []int{1, 3},
},
{
name: "all unique elements",
input: []int{5, 6, 7},
expected: []int{5, 6, 7},
},
{
name: "duplicates at end",
input: []int{1, 1, 2},
expected: []int{2},
},
{
name: "multiple groups",
input: []int{1, 1, 2, 3, 3, 4},
expected: []int{2, 4},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
inputCopy := make([]int, len(tt.input))
copy(inputCopy, tt.input)
result := RemoveRepeatedSorted(inputCopy)
require.Equal(t, result, tt.expected)
})
}
// Test with strings
stringTest := struct {
name string
input []string
expected []string
}{
name: "string elements",
input: []string{"a", "a", "b", "c", "c", "c"},
expected: []string{"b"},
}
t.Run(stringTest.name, func(t *testing.T) {
inputCopy := make([]string, len(stringTest.input))
copy(inputCopy, stringTest.input)
result := RemoveRepeatedSorted(inputCopy)
require.Equal(t, result, stringTest.expected)
})
}
func TestRemoveUniqueElementsSorted(t *testing.T) {
tests := []struct {
name string
input []int
expected []int
}{
{
name: "empty slice",
input: []int{},
expected: []int{},
},
{
name: "single element",
input: []int{1},
expected: []int{},
},
{
name: "all duplicates",
input: []int{3, 3, 3},
expected: []int{3, 3, 3},
},
{
name: "mixed duplicates and unique",
input: []int{1, 2, 2, 3, 4, 4, 4, 5},
expected: []int{2, 2, 4, 4, 4},
},
{
name: "all unique elements",
input: []int{5, 6, 7},
expected: []int{},
},
{
name: "duplicates at beginning",
input: []int{1, 1, 2, 3},
expected: []int{1, 1},
},
{
name: "multiple duplicate groups",
input: []int{1, 1, 2, 2, 3, 4, 4},
expected: []int{1, 1, 2, 2, 4, 4},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
inputCopy := make([]int, len(tt.input))
copy(inputCopy, tt.input)
result := RemoveUniqueElementsSorted(inputCopy)
require.Equal(t, result, tt.expected)
})
}
stringTest := struct {
name string
input []string
expected []string
}{
name: "string elements",
input: []string{"a", "a", "b", "c", "c", "c"},
expected: []string{"a", "a", "c", "c", "c"},
}
t.Run(stringTest.name, func(t *testing.T) {
inputCopy := make([]string, len(stringTest.input))
copy(inputCopy, stringTest.input)
result := RemoveUniqueElementsSorted(inputCopy)
require.Equal(t, result, stringTest.expected)
})
}