66 lines
3.0 KiB
Go
66 lines
3.0 KiB
Go
package shape
|
|
|
|
import (
|
|
"context"
|
|
"reflect"
|
|
"testing"
|
|
|
|
"gitea.maximumdirect.net/eric/notarius/internal/core/source"
|
|
"gitea.maximumdirect.net/eric/notarius/internal/framework/contracts"
|
|
"gitea.maximumdirect.net/eric/notarius/internal/framework/pipeline"
|
|
"gitea.maximumdirect.net/eric/notarius/internal/modules/dnd"
|
|
)
|
|
|
|
func TestValidatorRequiresSceneShapeAndExactlyOneExtractionRecord(t *testing.T) {
|
|
valid := list(scene("one", dnd.SceneKindNarrative, "Arrival", "The party arrives.", 1, 1))
|
|
validator := New(Options{})
|
|
for _, test := range []struct {
|
|
name string
|
|
value dnd.SceneDescriptionList
|
|
stage string
|
|
approved bool
|
|
}{
|
|
{name: "valid normalization", value: valid, approved: true},
|
|
{name: "valid extraction", value: valid, stage: string(pipeline.StageExtract), approved: true},
|
|
{name: "multiple extraction records", value: list(valid.Scenes[0], scene("two", dnd.SceneKindMeta, "Rules", "The table checks rules.", 2, 2)), stage: string(pipeline.StageExtract)},
|
|
{name: "nil list", value: dnd.SceneDescriptionList{}},
|
|
{name: "empty list", value: dnd.SceneDescriptionList{Scenes: []dnd.SceneDescription{}}},
|
|
{name: "blank ID", value: list(scene(" ", dnd.SceneKindNarrative, "Arrival", "The party arrives.", 1, 1))},
|
|
{name: "unsupported kind", value: list(scene("one", "other", "Arrival", "The party arrives.", 1, 1))},
|
|
{name: "untrimmed prose", value: list(scene("one", dnd.SceneKindNarrative, " Arrival ", "The party arrives.", 1, 1))},
|
|
{name: "empty source reference", value: dnd.SceneDescriptionList{Scenes: []dnd.SceneDescription{{ID: "one", Kind: dnd.SceneKindNarrative, Title: "Arrival", Summary: "The party arrives."}}}},
|
|
} {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
result, err := validator.Validate(context.Background(), contracts.TypedValidationRequest[dnd.SceneDescriptionList]{Stage: test.stage, Value: test.value})
|
|
if err != nil || result.Approved != test.approved {
|
|
t.Fatalf("Validate() = %#v, %v; want approved=%t", result, err, test.approved)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidatorContractAndRegistration(t *testing.T) {
|
|
registry := pipeline.NewValidatorRegistry()
|
|
if err := Register(registry); err != nil {
|
|
t.Fatalf("Register() error = %v", err)
|
|
}
|
|
if _, ok := registry.Spec(Key); !ok {
|
|
t.Fatalf("registry has no spec for %q", Key)
|
|
}
|
|
if _, err := DecodeOptions(map[string]any{"unexpected": true}); err == nil {
|
|
t.Fatal("DecodeOptions() accepted unknown options")
|
|
}
|
|
validator := New(Options{})
|
|
if got, want := validator.CheckpointFingerprints(), []pipeline.CheckpointFingerprint{{Name: "policy", Value: policy}}; !reflect.DeepEqual(got, want) {
|
|
t.Fatalf("fingerprints = %#v, want %#v", got, want)
|
|
}
|
|
}
|
|
|
|
func list(scenes ...dnd.SceneDescription) dnd.SceneDescriptionList {
|
|
return dnd.SceneDescriptionList{Scenes: scenes}
|
|
}
|
|
|
|
func scene(id string, kind dnd.SceneKind, title, summary string, start, end int) dnd.SceneDescription {
|
|
return dnd.SceneDescription{ID: id, Kind: kind, Title: title, Summary: summary, SourceRef: source.SourceRef{SourceID: "session", StartUnitID: start, EndUnitID: end}}
|
|
}
|