v0.2.1 remove testify dep
Test / test (push) Canceled after 0s

This commit is contained in:
lixen committed 2026-09-29 01:11:44 -04:00
1 parent e08467bf38
commit 2a47be454d
17 files changed
+849 -855

No files matched your search

+49 -113
View File
@@ -1,163 +1,99 @@
// FILE: lixenwraith/config/validator_test.go
package config
import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
)
// TestPortValidator tests the Port validator
func TestPortValidator(t *testing.T) {
tests := []struct {
name string
port int64
wantErr bool
}{
{"ValidLowPort", 1, false},
{"ValidCommonPort", 8080, false},
{"ValidHighPort", 65535, false},
{"InvalidZeroPort", 0, true},
{"InvalidNegativePort", -1, true},
{"InvalidTooHighPort", 65536, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := Port(tt.port)
if tt.wantErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
// Each value is a subtest, so one failure does not hide another boundary case.
func checkValidator[T any](t *testing.T, validate func(T) error, valid, invalid []T, errorText ...string) {
t.Helper()
for _, group := range []struct {
name string
values []T
wantError bool
}{{"valid", valid, false}, {"invalid", invalid, true}} {
t.Run(group.name, func(t *testing.T) {
for _, value := range group.values {
t.Run(fmt.Sprintf("%v", value), func(t *testing.T) {
err := validate(value)
if (err != nil) != group.wantError {
t.Fatalf("validate(%#v) = %v, want error: %v", value, err, group.wantError)
}
if group.wantError {
for _, fragment := range errorText {
checkErrorContains(t, err, fragment)
}
}
})
}
})
}
}
// TestPositiveValidator tests the Positive validator
func TestPortValidator(t *testing.T) {
checkValidator(t, Port, []int64{1, 8080, 65535}, []int64{0, -1, 65536})
}
func TestPositiveValidator(t *testing.T) {
t.Run("Int64", func(t *testing.T) {
assert.NoError(t, Positive(int64(1)))
assert.Error(t, Positive(int64(0)))
assert.Error(t, Positive(int64(-1)))
checkValidator(t, Positive[int64], []int64{1}, []int64{0, -1})
})
t.Run("Float64", func(t *testing.T) {
assert.NoError(t, Positive(0.001))
assert.Error(t, Positive(0.0))
assert.Error(t, Positive(-0.001))
checkValidator(t, Positive[float64], []float64{0.001}, []float64{0, -0.001})
})
}
// TestNonNegativeValidator tests the NonNegative validator
func TestNonNegativeValidator(t *testing.T) {
t.Run("Int64", func(t *testing.T) {
assert.NoError(t, NonNegative(int64(1)))
assert.NoError(t, NonNegative(int64(0)))
assert.Error(t, NonNegative(int64(-1)))
checkValidator(t, NonNegative[int64], []int64{1, 0}, []int64{-1})
})
t.Run("Float64", func(t *testing.T) {
assert.NoError(t, NonNegative(0.001))
assert.NoError(t, NonNegative(0.0))
assert.Error(t, NonNegative(-0.001))
checkValidator(t, NonNegative[float64], []float64{0.001, 0}, []float64{-0.001})
})
}
// TestIPAddressValidators tests all IP-related validators
func TestIPAddressValidators(t *testing.T) {
t.Run("IPAddress", func(t *testing.T) {
assert.NoError(t, IPAddress("192.168.1.1"))
assert.NoError(t, IPAddress("2001:0db8:85a3:0000:0000:8a2e:0370:7334"))
assert.NoError(t, IPAddress(""))
assert.NoError(t, IPAddress("0.0.0.0"))
assert.NoError(t, IPAddress("::"))
assert.Error(t, IPAddress("not-an-ip"))
assert.Error(t, IPAddress("192.168.1.256"))
})
t.Run("IPv4Address", func(t *testing.T) {
assert.NoError(t, IPv4Address("192.168.1.1"))
assert.NoError(t, IPv4Address(""))
assert.NoError(t, IPv4Address("0.0.0.0"))
assert.Error(t, IPv4Address("::1")) // Is not IPv4
assert.Error(t, IPv4Address("not-an-ip"))
})
t.Run("IPv6Address", func(t *testing.T) {
assert.NoError(t, IPv6Address("2001:db8::1"))
assert.NoError(t, IPv6Address(""))
assert.NoError(t, IPv6Address("::"))
assert.Error(t, IPv6Address("127.0.0.1")) // Is not IPv6
assert.Error(t, IPv6Address("not-an-ip"))
})
for _, tc := range []struct {
name string
validate func(string) error
valid, invalid []string
}{
{"IPAddress", IPAddress, []string{"192.168.1.1", "2001:0db8:85a3:0000:0000:8a2e:0370:7334", "", "0.0.0.0", "::"}, []string{"not-an-ip", "192.168.1.256"}},
{"IPv4Address", IPv4Address, []string{"192.168.1.1", "", "0.0.0.0"}, []string{"::1", "not-an-ip"}},
{"IPv6Address", IPv6Address, []string{"2001:db8::1", "", "::"}, []string{"127.0.0.1", "not-an-ip"}},
} {
t.Run(tc.name, func(t *testing.T) { checkValidator(t, tc.validate, tc.valid, tc.invalid) })
}
}
// TestURLPathValidator tests the URLPath validator
func TestURLPathValidator(t *testing.T) {
assert.NoError(t, URLPath("/api/v1"))
assert.NoError(t, URLPath("/"))
assert.NoError(t, URLPath(""))
assert.Error(t, URLPath("api/v1"))
assert.Error(t, URLPath("no-slash"))
checkValidator(t, URLPath, []string{"/api/v1", "/", ""}, []string{"api/v1", "no-slash"})
}
// TestOneOfValidator tests the OneOf validator
func TestOneOfValidator(t *testing.T) {
t.Run("String", func(t *testing.T) {
validator := OneOf("prod", "dev", "staging")
assert.NoError(t, validator("prod"))
assert.NoError(t, validator("dev"))
err := validator("test")
assert.Error(t, err)
assert.Contains(t, err.Error(), "must be one of")
checkValidator(t, OneOf("prod", "dev", "staging"), []string{"prod", "dev"}, []string{"test"}, "must be one of")
})
t.Run("Int", func(t *testing.T) {
validator := OneOf(200, 404, 500)
assert.NoError(t, validator(404))
err := validator(302)
assert.Error(t, err)
assert.Contains(t, err.Error(), "must be one of")
checkValidator(t, OneOf(200, 404, 500), []int{404}, []int{302}, "must be one of")
})
}
// TestRangeValidator tests the Range validator
func TestRangeValidator(t *testing.T) {
t.Run("Int64", func(t *testing.T) {
validator := Range[int64](10, 100)
assert.NoError(t, validator(10))
assert.NoError(t, validator(50))
assert.NoError(t, validator(100))
assert.Error(t, validator(9))
assert.Error(t, validator(101))
checkValidator(t, Range[int64](10, 100), []int64{10, 50, 100}, []int64{9, 101})
})
t.Run("Float64", func(t *testing.T) {
validator := Range[float64](-1.5, 1.5)
assert.NoError(t, validator(-1.5))
assert.NoError(t, validator(0.0))
assert.NoError(t, validator(1.5))
assert.Error(t, validator(-1.51))
assert.Error(t, validator(1.51))
checkValidator(t, Range[float64](-1.5, 1.5), []float64{-1.5, 0, 1.5}, []float64{-1.51, 1.51})
})
}
// TestPatternValidator tests the Pattern validator
func TestPatternValidator(t *testing.T) {
// Simple email regex
validator := Pattern(`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`)
assert.NoError(t, validator("test@example.com"))
assert.NoError(t, validator("user.name+alias@domain.co.uk"))
assert.Error(t, validator("not-an-email"))
assert.Error(t, validator("test@example"))
checkValidator(t, Pattern(`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`),
[]string{"test@example.com", "user.name+alias@domain.co.uk"}, []string{"not-an-email", "test@example"})
}
// TestNonEmptyValidator tests the NonEmpty validator
func TestNonEmptyValidator(t *testing.T) {
assert.NoError(t, NonEmpty("hello"))
assert.NoError(t, NonEmpty(" a "))
assert.Error(t, NonEmpty(""))
assert.Error(t, NonEmpty(" "))
assert.Error(t, NonEmpty(" \t\n "))
checkValidator(t, NonEmpty, []string{"hello", " a "}, []string{"", " ", " \t\n "})
}