118 lines
3.9 KiB
Go
118 lines
3.9 KiB
Go
package pipeline
|
|
|
|
import (
|
|
"context"
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
|
|
"gitea.maximumdirect.net/eric/notarius/internal/framework/contracts"
|
|
)
|
|
|
|
func TestValidatorRegistryBehavior(t *testing.T) {
|
|
registry := NewValidatorRegistry()
|
|
if err := registry.Register(" generic-validator ", validatorConstructor("generic-validator", contracts.ExecutionClassDeterministic)); err != nil {
|
|
t.Fatalf("Register() error = %v, want nil", err)
|
|
}
|
|
|
|
validator, err := registry.Build("generic-validator")
|
|
if err != nil {
|
|
t.Fatalf("Build() error = %v, want nil", err)
|
|
}
|
|
if validator.Name() != "generic-validator" {
|
|
t.Fatalf("validator name = %q, want generic-validator", validator.Name())
|
|
}
|
|
|
|
spec, ok := registry.Spec(" generic-validator ")
|
|
if !ok {
|
|
t.Fatal("Spec() ok = false, want true")
|
|
}
|
|
want := ValidatorSpec{Key: "generic-validator", ExecutionClass: contracts.ExecutionClassDeterministic}
|
|
if !reflect.DeepEqual(spec, want) {
|
|
t.Fatalf("Spec() = %#v, want %#v", spec, want)
|
|
}
|
|
}
|
|
|
|
func TestValidatorRegistryRegistersSpecs(t *testing.T) {
|
|
registry := NewValidatorRegistry()
|
|
spec := ValidatorSpec{Key: " llm-validator ", ExecutionClass: contracts.ExecutionClassLLMBacked}
|
|
if err := registry.RegisterWithSpec(spec, validatorConstructor("llm-validator", contracts.ExecutionClassLLMBacked)); err != nil {
|
|
t.Fatalf("RegisterWithSpec() error = %v, want nil", err)
|
|
}
|
|
|
|
got, ok := registry.Spec("llm-validator")
|
|
if !ok {
|
|
t.Fatal("Spec() ok = false, want true")
|
|
}
|
|
want := ValidatorSpec{Key: "llm-validator", ExecutionClass: contracts.ExecutionClassLLMBacked}
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Fatalf("Spec() = %#v, want %#v", got, want)
|
|
}
|
|
}
|
|
|
|
func TestValidatorRegistryRegisteredSpecsAreSorted(t *testing.T) {
|
|
registry := NewValidatorRegistry()
|
|
for _, key := range []string{"zeta", "alpha"} {
|
|
if err := registry.Register(key, validatorConstructor(key, contracts.ExecutionClassDeterministic)); err != nil {
|
|
t.Fatalf("Register(%q) error = %v", key, err)
|
|
}
|
|
}
|
|
|
|
specs := registry.RegisteredSpecs()
|
|
if len(specs) != 2 || specs[0].Key != "alpha" || specs[1].Key != "zeta" {
|
|
t.Fatalf("RegisteredSpecs() = %#v, want sorted specs", specs)
|
|
}
|
|
}
|
|
|
|
func TestValidatorRegistryRejectsUnsupportedExecutionClass(t *testing.T) {
|
|
registry := NewValidatorRegistry()
|
|
err := registry.RegisterWithSpec(
|
|
ValidatorSpec{Key: "invalid-validator", ExecutionClass: contracts.ExecutionClass("unsupported")},
|
|
validatorConstructor("invalid-validator", contracts.ExecutionClass("unsupported")),
|
|
)
|
|
if err == nil {
|
|
t.Fatal("RegisterWithSpec() error = nil, want unsupported execution class error")
|
|
}
|
|
}
|
|
|
|
func TestValidatorRegistryRejectsConstructorExecutionClassMismatch(t *testing.T) {
|
|
registry := NewValidatorRegistry()
|
|
if err := registry.RegisterWithSpec(
|
|
ValidatorSpec{Key: "validator", ExecutionClass: contracts.ExecutionClassDeterministic},
|
|
validatorConstructor("validator", contracts.ExecutionClassLLMBacked),
|
|
); err != nil {
|
|
t.Fatalf("RegisterWithSpec() error = %v, want nil", err)
|
|
}
|
|
|
|
_, err := registry.Build("validator")
|
|
if err == nil {
|
|
t.Fatal("Build() error = nil, want execution class mismatch")
|
|
}
|
|
if !strings.Contains(err.Error(), "execution class") {
|
|
t.Fatalf("Build() error = %q, want execution class context", err.Error())
|
|
}
|
|
}
|
|
|
|
type testValidator struct {
|
|
name string
|
|
executionClass contracts.ExecutionClass
|
|
}
|
|
|
|
func validatorConstructor(name string, executionClass contracts.ExecutionClass) ValidatorConstructor {
|
|
return func() (contracts.Validator, error) {
|
|
return testValidator{name: name, executionClass: executionClass}, nil
|
|
}
|
|
}
|
|
|
|
func (validator testValidator) Name() string {
|
|
return validator.name
|
|
}
|
|
|
|
func (validator testValidator) ExecutionClass() contracts.ExecutionClass {
|
|
return validator.executionClass
|
|
}
|
|
|
|
func (validator testValidator) Validate(ctx context.Context, req contracts.ValidationRequest) (contracts.ValidationResult, error) {
|
|
return contracts.ValidationResult{Approved: true}, nil
|
|
}
|