package schema_test
import (
"errors"
"strings"
"testing"
"mercemay.top/src/lambdalog/internal/encoder"
"mercemay.top/src/lambdalog/internal/encoder/json/schema"
)
func newTestSchema(t *testing.T) *schema.Schema {
t.Helper()
s := schema.New()
s.Register("user", schema.Spec{Type: schema.TypeString, Required: true})
s.Register("count", schema.Spec{Type: schema.TypeInt})
s.Register("ok", schema.Spec{Type: schema.TypeBool})
return s
}
func TestValidate_Accepts(t *testing.T) {
s := newTestSchema(t)
rec := encoder.Record{
Fields: []encoder.Field{
{Key: "user", Value: "alice"},
{Key: "count", Value: int64(3)},
{Key: "ok", Value: true},
},
}
if err := s.Validate(rec); err != nil {
t.Fatalf("Validate: %v", err)
}
}
func TestValidate_RejectsMissingRequired(t *testing.T) {
s := newTestSchema(t)
err := s.Validate(encoder.Record{})
if err == nil {
t.Fatal("expected error")
}
if !errors.Is(err, &schema.ValidationError{}) {
t.Fatalf("not a ValidationError: %v", err)
}
if !strings.Contains(err.Error(), `missing required field "user"`) {
t.Fatalf("unexpected message: %v", err)
}
}
func TestValidate_RejectsTypeMismatch(t *testing.T) {
s := newTestSchema(t)
rec := encoder.Record{
Fields: []encoder.Field{
{Key: "user", Value: "x"},
{Key: "count", Value: "not-an-int"},
},
}
err := s.Validate(rec)
if err == nil {
t.Fatal("expected error")
}
if !strings.Contains(err.Error(), `field "count": expected int`) {
t.Fatalf("unexpected message: %v", err)
}
}
func TestValidate_RejectsUnknownField(t *testing.T) {
s := newTestSchema(t)
rec := encoder.Record{
Fields: []encoder.Field{
{Key: "user", Value: "x"},
{Key: "mystery", Value: 1},
},
}
err := s.Validate(rec)
if err == nil || !strings.Contains(err.Error(), `unknown field "mystery"`) {
t.Fatalf("unexpected error: %v", err)
}
}
func TestValidationError_IsOpaqueSentinel(t *testing.T) {
err := &schema.ValidationError{Problems: []string{"x"}}
if !errors.Is(err, &schema.ValidationError{}) {
t.Fatal("Is should match the zero value")
}
}
func TestValidate_ProblemsAreSorted(t *testing.T) {
s := schema.New()
s.Register("a", schema.Spec{Type: schema.TypeInt, Required: true})
s.Register("b", schema.Spec{Type: schema.TypeInt, Required: true})
err := s.Validate(encoder.Record{})
if err == nil {
t.Fatal("expected error")
}
ve, ok := err.(*schema.ValidationError)
if !ok {
t.Fatalf("wrong type: %T", err)
}
if len(ve.Problems) != 2 {
t.Fatalf("got %d problems, want 2", len(ve.Problems))
}
if ve.Problems[0] > ve.Problems[1] {
t.Fatalf("not sorted: %v", ve.Problems)
}
}