82 lines
3.4 KiB
Go
82 lines
3.4 KiB
Go
package cli
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"strings"
|
|
"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"
|
|
)
|
|
|
|
const invalidEnemyEventExtractorKey = "test/dnd/invalid-enemy-events"
|
|
|
|
func TestAssembledEnemyEventLaneRejectsInvalidFinalArtifactDespiteValidatorOverrides(t *testing.T) {
|
|
components := productionTestComponents(t)
|
|
if err := pipeline.RegisterExtractor[dnd.EnemyEventList](components.registries.Extractors, pipeline.ModuleSpec{
|
|
Key: invalidEnemyEventExtractorKey,
|
|
Stage: pipeline.StageExtract,
|
|
ExecutionClass: contracts.ExecutionClassDeterministic,
|
|
Requires: []string{"chunks", "source.transcript"},
|
|
Provides: []string{"dnd.enemy_events"},
|
|
ArtifactKind: dnd.EnemyEventListKind,
|
|
}, func() (contracts.Extractor[dnd.EnemyEventList], error) {
|
|
return invalidEnemyEventExtractor{}, nil
|
|
}); err != nil {
|
|
t.Fatalf("register extractor: %v", err)
|
|
}
|
|
|
|
accept := pipeline.ValidatorOverride{Set: true, Validators: []pipeline.ModuleBinding{pipeline.Binding("generic/always_accept")}}
|
|
resolved, err := pipeline.ResolvePipeline(pipeline.PipelineProfile{
|
|
ID: "assembled-invalid-enemy-events",
|
|
Input: pipeline.Binding("seriatim"),
|
|
Chunk: pipeline.ModuleBinding{Module: "generic", Options: map[string]any{"max_units": 1}},
|
|
Artifacts: map[string]pipeline.ArtifactLaneProfile{
|
|
"enemy-events": {
|
|
Extract: pipeline.ModuleBinding{Module: invalidEnemyEventExtractorKey, Validators: accept},
|
|
Normalize: pipeline.ModuleBinding{Module: pipeline.DefaultNormalizeModule, Validators: accept},
|
|
},
|
|
},
|
|
Output: pipeline.Binding("json"),
|
|
}, pipeline.ResolveOptions{}, catalogFromRegistries(components.registries))
|
|
if err != nil {
|
|
t.Fatalf("ResolvePipeline() error = %v", err)
|
|
}
|
|
|
|
prepared, err := pipeline.Prepare(resolved, components.registries, pipeline.ModuleDependencies{})
|
|
if err != nil {
|
|
t.Fatalf("Prepare() error = %v", err)
|
|
}
|
|
_, err = pipeline.New().Run(context.Background(), pipeline.RunInput{
|
|
Prepared: prepared,
|
|
RawInput: readRepositoryFile(t, "examples", "seriatim-minimal-transcript.json"),
|
|
ChunkCacheMode: pipeline.ChunkCacheBypass,
|
|
})
|
|
if err == nil || !strings.Contains(err.Error(), "serialize accepted extract output") || !strings.Contains(err.Error(), "must not exceed") {
|
|
t.Fatalf("Run() error = %v, want final durable range rejection", err)
|
|
}
|
|
}
|
|
|
|
type invalidEnemyEventExtractor struct{}
|
|
|
|
func (invalidEnemyEventExtractor) Key() string { return invalidEnemyEventExtractorKey }
|
|
|
|
func (invalidEnemyEventExtractor) ReferenceSlots() []contracts.ReferenceSlot { return nil }
|
|
|
|
func (invalidEnemyEventExtractor) Extract(ctx context.Context, req contracts.TypedExtractionRequest) (contracts.TypedExtractionResult[dnd.EnemyEventList], error) {
|
|
if err := ctx.Err(); err != nil {
|
|
return contracts.TypedExtractionResult[dnd.EnemyEventList]{}, err
|
|
}
|
|
if req.Source == nil {
|
|
return contracts.TypedExtractionResult[dnd.EnemyEventList]{}, errors.New("assembled extractor requires source")
|
|
}
|
|
return contracts.TypedExtractionResult[dnd.EnemyEventList]{Value: dnd.EnemyEventList{Events: []dnd.EnemyEvent{{
|
|
Name: "Ashfang",
|
|
Kind: dnd.EnemyEventKindEngaged,
|
|
SourceRefs: []source.SourceRef{{SourceID: req.Source.ID, StartUnitID: 2, EndUnitID: 1}},
|
|
}}}}, nil
|
|
}
|