Files
trivy/pkg/set/unsafe_test.go
2024-12-24 04:47:21 +00:00

584 lines
10 KiB
Go

package set_test
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/aquasecurity/trivy/pkg/set"
)
func Test_New(t *testing.T) {
tests := []struct {
name string
values []int
wantSize int
wantAll bool
desc string
}{
{
name: "new empty set",
values: []int{},
wantSize: 0,
wantAll: true,
desc: "should create empty set when no values provided",
},
{
name: "new set with single value",
values: []int{1},
wantSize: 1,
wantAll: true,
desc: "should create set with single value",
},
{
name: "new set with multiple values",
values: []int{
1,
2,
3,
},
wantSize: 3,
wantAll: true,
desc: "should create set with multiple values",
},
{
name: "new set with duplicate values",
values: []int{
1,
2,
2,
3,
3,
3,
},
wantSize: 3,
wantAll: true,
desc: "should create set with unique values only",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := set.New(tt.values...)
assert.Equal(t, tt.wantSize, s.Size(), "unexpected set size")
})
}
}
func Test_unsafeSet_Add(t *testing.T) {
// Define custom type for struct test cases
type custom struct {
id int
name string
}
tests := []struct {
name string
prepare func(s set.Set[any])
input any
wantSize int
}{
{
name: "add integer",
prepare: nil,
input: 1,
wantSize: 1,
},
{
name: "add duplicate integer",
prepare: func(s set.Set[any]) {
s.Append(1)
},
input: 1,
wantSize: 1,
},
{
name: "add string",
prepare: nil,
input: "test",
wantSize: 1,
},
{
name: "add empty string",
prepare: nil,
input: "",
wantSize: 1,
},
{
name: "add custom struct",
prepare: nil,
input: custom{
id: 1,
name: "test1",
},
wantSize: 1,
},
{
name: "add nil pointer",
prepare: nil,
input: (*int)(nil),
wantSize: 1,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := set.New[any]()
if tt.prepare != nil {
tt.prepare(s)
}
s.Append(tt.input)
got := s.Size()
assert.Equal(t, tt.wantSize, got, "unexpected set size")
assert.True(t, s.Contains(tt.input), "unexpected contains result for value: %v", tt.input)
})
}
}
func Test_unsafeSet_Append(t *testing.T) {
tests := []struct {
name string
prepare func(s set.Set[int])
input []int
wantSize int
}{
{
name: "append to empty set",
prepare: nil,
input: []int{
1,
2,
3,
},
wantSize: 3,
},
{
name: "append with duplicates",
prepare: func(s set.Set[int]) {
s.Append(1)
},
input: []int{
1,
2,
1,
3,
2,
},
wantSize: 3,
},
{
name: "append empty slice",
prepare: func(s set.Set[int]) {
s.Append(1)
},
input: []int{},
wantSize: 1,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := set.New[int]()
if tt.prepare != nil {
tt.prepare(s)
}
got := s.Append(tt.input...)
assert.Equal(t, tt.wantSize, got, "unexpected returned size")
assert.Equal(t, tt.wantSize, s.Size(), "unexpected actual size")
for _, item := range tt.input {
assert.True(t, s.Contains(item), "set should contain appended item: %v", item)
}
})
}
}
func Test_unsafeSet_Remove(t *testing.T) {
tests := []struct {
name string
prepare func(s set.Set[int])
input int
wantSize int
}{
{
name: "remove existing element",
prepare: func(s set.Set[int]) {
s.Append(1)
},
input: 1,
wantSize: 0,
},
{
name: "remove non-existing element",
prepare: func(s set.Set[int]) {
s.Append(1)
},
input: 2,
wantSize: 1,
},
{
name: "remove from empty set",
prepare: nil,
input: 1,
wantSize: 0,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := set.New[int]()
if tt.prepare != nil {
tt.prepare(s)
}
s.Remove(tt.input)
got := s.Size()
assert.Equal(t, tt.wantSize, got, "unexpected set size")
assert.False(t, s.Contains(tt.input), "unexpected contains result for value: %v", tt.input)
})
}
}
func Test_unsafeSet_Clear(t *testing.T) {
tests := []struct {
name string
prepare func(s set.Set[int])
}{
{
name: "clear non-empty set",
prepare: func(s set.Set[int]) {
s.Append(1)
s.Append(2)
s.Append(3)
},
},
{
name: "clear empty set",
prepare: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := set.New[int]()
if tt.prepare != nil {
tt.prepare(s)
}
s.Clear()
got := s.Size()
assert.Zero(t, got, "unexpected set size")
assert.Empty(t, s.Items(), "items should be empty")
})
}
}
func Test_unsafeSet_Clone(t *testing.T) {
t.Run("empty set", func(t *testing.T) {
original := set.New[string]()
cloned := original.Clone()
assert.Equal(t, 0, cloned.Size(), "cloned set should be empty")
// Verify independence
original.Append("test")
assert.False(t, cloned.Contains("test"), "cloned set should not be affected by original")
})
t.Run("basic types", func(t *testing.T) {
original := set.New[any](1, "test", true)
cloned := original.Clone()
assert.Equal(t, original.Size(), cloned.Size(), "sizes should match")
assert.True(t, cloned.Contains(1), "should contain integer")
assert.True(t, cloned.Contains("test"), "should contain string")
assert.True(t, cloned.Contains(true), "should contain boolean")
// Verify independence
original.Append("new")
assert.False(t, cloned.Contains("new"), "cloned set should not be affected by original")
cloned.Append("another")
assert.False(t, original.Contains("another"), "original set should not be affected by clone")
})
// Test nil pointer
t.Run("nil pointer", func(t *testing.T) {
original := set.New[*int]()
original.Append(nil)
cloned := original.Clone()
assert.Equal(t, original.Size(), cloned.Size(), "sizes should match")
assert.True(t, cloned.Contains((*int)(nil)), "should contain nil pointer")
})
}
func Test_unsafeSet_Items(t *testing.T) {
tests := []struct {
name string
prepare func(s set.Set[int])
want []int
}{
{
name: "get items from non-empty set",
prepare: func(s set.Set[int]) {
s.Append(1)
s.Append(2)
s.Append(3)
},
want: []int{
1,
2,
3,
},
},
{
name: "get items from empty set",
prepare: nil,
want: []int{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := set.New[int]()
if tt.prepare != nil {
tt.prepare(s)
}
got := s.Items()
assert.ElementsMatch(t, tt.want, got, "unexpected items in set")
})
}
}
func Test_unsafeSet_Union(t *testing.T) {
tests := []struct {
name string
prepare1 func(s set.Set[int])
prepare2 func(s set.Set[int])
want []int
}{
{
name: "union of non-overlapping sets",
prepare1: func(s set.Set[int]) {
s.Append(1)
s.Append(2)
},
prepare2: func(s set.Set[int]) {
s.Append(3)
s.Append(4)
},
want: []int{
1,
2,
3,
4,
},
},
{
name: "union of overlapping sets",
prepare1: func(s set.Set[int]) {
s.Append(1)
s.Append(2)
s.Append(3)
},
prepare2: func(s set.Set[int]) {
s.Append(2)
s.Append(3)
s.Append(4)
},
want: []int{
1,
2,
3,
4,
},
},
{
name: "union with empty set",
prepare1: func(s set.Set[int]) {
s.Append(1)
s.Append(2)
},
prepare2: nil,
want: []int{
1,
2,
},
},
{
name: "union of empty sets",
prepare1: nil,
prepare2: nil,
want: []int{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s1 := set.New[int]()
s2 := set.New[int]()
if tt.prepare1 != nil {
tt.prepare1(s1)
}
if tt.prepare2 != nil {
tt.prepare2(s2)
}
result := s1.Union(s2)
got := result.Items()
assert.ElementsMatch(t, tt.want, got, "unexpected union result")
})
}
}
func Test_unsafeSet_Intersection(t *testing.T) {
tests := []struct {
name string
prepare1 func(s set.Set[int])
prepare2 func(s set.Set[int])
want []int
}{
{
name: "intersection of overlapping sets",
prepare1: func(s set.Set[int]) {
s.Append(1)
s.Append(2)
s.Append(3)
},
prepare2: func(s set.Set[int]) {
s.Append(2)
s.Append(3)
s.Append(4)
},
want: []int{
2,
3,
},
},
{
name: "intersection of non-overlapping sets",
prepare1: func(s set.Set[int]) {
s.Append(1)
s.Append(2)
},
prepare2: func(s set.Set[int]) {
s.Append(3)
s.Append(4)
},
want: []int{},
},
{
name: "intersection with empty set",
prepare1: func(s set.Set[int]) {
s.Append(1)
s.Append(2)
},
prepare2: nil,
want: []int{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s1 := set.New[int]()
s2 := set.New[int]()
if tt.prepare1 != nil {
tt.prepare1(s1)
}
if tt.prepare2 != nil {
tt.prepare2(s2)
}
result := s1.Intersection(s2)
got := result.Items()
assert.ElementsMatch(t, tt.want, got, "unexpected intersection result")
})
}
}
func Test_unsafeSet_Difference(t *testing.T) {
tests := []struct {
name string
prepare1 func(s set.Set[int])
prepare2 func(s set.Set[int])
want []int
}{
{
name: "difference of overlapping sets",
prepare1: func(s set.Set[int]) {
s.Append(1)
s.Append(2)
s.Append(3)
},
prepare2: func(s set.Set[int]) {
s.Append(2)
s.Append(3)
s.Append(4)
},
want: []int{1},
},
{
name: "difference with non-overlapping set",
prepare1: func(s set.Set[int]) {
s.Append(1)
s.Append(2)
},
prepare2: func(s set.Set[int]) {
s.Append(3)
s.Append(4)
},
want: []int{
1,
2,
},
},
{
name: "difference with empty set",
prepare1: func(s set.Set[int]) {
s.Append(1)
s.Append(2)
},
prepare2: nil,
want: []int{
1,
2,
},
},
{
name: "difference of empty set",
prepare1: nil,
prepare2: func(s set.Set[int]) {
s.Append(1)
s.Append(2)
},
want: []int{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s1 := set.New[int]()
s2 := set.New[int]()
if tt.prepare1 != nil {
tt.prepare1(s1)
}
if tt.prepare2 != nil {
tt.prepare2(s2)
}
result := s1.Difference(s2)
got := result.Items()
assert.ElementsMatch(t, tt.want, got, "unexpected difference result")
})
}
}