Add typed spell validation strategies

This commit is contained in:
2026-07-17 07:02:30 +00:00
parent 142ba36695
commit 52e6b31408
25 changed files with 708 additions and 410 deletions

View File

@@ -84,6 +84,19 @@ func TestNormalizeDefensivelyCopiesRawPayload(t *testing.T) {
}
}
func TestTypedNormalizePassesThroughReusableValueType(t *testing.T) {
type score struct{ Value int }
result, err := NewTyped[score]().Normalize(context.Background(), contracts.TypedNormalizeRequest[score]{
MergeOutput: contracts.MergeArtifact[score]{Value: score{Value: 7}},
})
if err != nil {
t.Fatalf("Normalize() error = %v", err)
}
if result.Value.Value != 7 {
t.Fatalf("Value = %d, want 7", result.Value.Value)
}
}
func mergeOutput(content string) contracts.MergeOutput {
return contracts.MergeOutput{
LaneID: "events",

View File

@@ -0,0 +1,44 @@
package noop
import (
"context"
"gitea.maximumdirect.net/eric/notarius/internal/framework/contracts"
"gitea.maximumdirect.net/eric/notarius/internal/framework/pipeline"
)
type TypedNormalizer[T any] struct{}
func NewTyped[T any]() *TypedNormalizer[T] { return &TypedNormalizer[T]{} }
func (n *TypedNormalizer[T]) Key() string { return Key }
func (n *TypedNormalizer[T]) ReferenceSlots() []contracts.ReferenceSlot { return nil }
func (n *TypedNormalizer[T]) Normalize(ctx context.Context, req contracts.TypedNormalizeRequest[T]) (contracts.TypedNormalizeResult[T], error) {
if n == nil {
return contracts.TypedNormalizeResult[T]{}, normalizerErrorf("normalizer must not be nil")
}
if ctx == nil {
return contracts.TypedNormalizeResult[T]{}, normalizerErrorf("context must not be nil")
}
if err := ctx.Err(); err != nil {
return contracts.TypedNormalizeResult[T]{}, normalizerErrorf("context error before normalize: %w", err)
}
return contracts.TypedNormalizeResult[T]{Value: req.MergeOutput.Value}, nil
}
func TypedModuleSpec(kind contracts.ArtifactKind) pipeline.ModuleSpec {
spec := ModuleSpec()
spec.ArtifactKind = kind
return spec
}
func RegisterTyped[T any](registry *pipeline.NormalizerRegistry, kind contracts.ArtifactKind) error {
validateOptions := func(options map[string]any) error { return pipeline.RejectUnknownOptions(options) }
return pipeline.RegisterNormalizerBuilder(registry, TypedModuleSpec(kind), validateOptions, func(request pipeline.BuildRequest) (contracts.Normalizer[T], error) {
if err := pipeline.RejectUnknownOptions(request.Options); err != nil {
return nil, err
}
return NewTyped[T](), nil
})
}