package slice

import (
	"slices"
	"testing"
)

func TestAny(t *testing.T) {
	t.Parallel()

	tests := []struct {
		name    string
		values  []int
		matches func(int) bool
		want    bool
	}{
		{
			name:    "matches an element",
			values:  []int{1, 2, 3},
			matches: func(value int) bool { return value%2 == 0 },
			want:    true,
		},
		{
			name:    "does not match any element",
			values:  []int{1, 3, 5},
			matches: func(value int) bool { return value%2 == 0 },
			want:    false,
		},
		{
			name:    "empty slice",
			matches: func(int) bool { return true },
			want:    false,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			t.Parallel()
			if got := Any(tt.values, tt.matches); got != tt.want {
				t.Errorf("Any() = %v, want %v", got, tt.want)
			}
		})
	}
}

func TestSliceFunctions(t *testing.T) {
	s := []int{1, 2, 3, 4, 5}

	// transform
	exp := []int{101, 102, 103, 104, 105}
	s1 := SliceIterTransform(slices.Values(s), func(e int) int { return e + 100 })
	if slices.Compare(exp, slices.Collect(s1)) != 0 {
		t.Fatalf("SliceTransform failed, expected %v, got %v", exp, slices.Collect(s1))
	}

	// filter
	exp = []int{1, 3, 5}
	s2 := SliceIterFilter(slices.Values(s), func(e int) bool { return e%2 == 0 })
	if slices.Compare(exp, slices.Collect(s2)) != 0 {
		t.Fatalf("SliceTransform failed, expected %v, got %v", exp, slices.Collect(s2))
	}

	// filter and transform
	exp = []int{101, 103, 105}
	s3 := SliceIterTransform(SliceIterFilter(slices.Values(s), func(e int) bool { return e%2 == 0 }), func(e int) int { return e + 100 })
	if slices.Compare(exp, slices.Collect(s3)) != 0 {
		t.Fatalf("SliceTransform failed, expected %v, got %v", exp, slices.Collect(s3))
	}
}
