Add Notarius reference configuration vocabulary
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
@@ -108,6 +109,7 @@ func TestNotariusStrictYAML(t *testing.T) {
|
||||
{name: "unknown output field", yaml: "notarius:\n outputs:\n npc_registry:\n lane_id: npc-registry\n unknown: true\n"},
|
||||
{name: "unsupported session id", yaml: "notarius:\n session_id: forbidden\n"},
|
||||
{name: "unsupported model", yaml: "notarius:\n model: forbidden\n"},
|
||||
{name: "duplicate reference selector", yaml: "notarius:\n references:\n party: narratio.input.party\n party: narratio.input.players\n"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
@@ -122,6 +124,134 @@ func TestNotariusStrictYAML(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestNotariusReferenceValidationAndNormalization(t *testing.T) {
|
||||
cfg := validNotariusConfig()
|
||||
cfg.References = map[string]string{
|
||||
" party ": " narratio.input.party ",
|
||||
" chunk . players ": "narratio.input.players",
|
||||
" npc-registry . extract . glossary ": "narratio.input.glossary",
|
||||
"spells": "narratio.input.spell_catalog",
|
||||
}
|
||||
|
||||
if err := validateNotarius(cfg, nil); err != nil {
|
||||
t.Fatalf("validateNotarius() error = %v", err)
|
||||
}
|
||||
want := map[string]string{
|
||||
"party": "narratio.input.party",
|
||||
"chunk.players": "narratio.input.players",
|
||||
"npc-registry.extract.glossary": "narratio.input.glossary",
|
||||
"spells": "narratio.input.spell_catalog",
|
||||
}
|
||||
if len(cfg.References) != len(want) {
|
||||
t.Fatalf("normalized references = %#v, want %#v", cfg.References, want)
|
||||
}
|
||||
for selector, source := range want {
|
||||
if cfg.References[selector] != source {
|
||||
t.Fatalf("references[%q] = %q, want %q", selector, cfg.References[selector], source)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNotariusReferenceValidationRejectsInvalidBindings(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
references map[string]string
|
||||
wantErr string
|
||||
}{
|
||||
{name: "empty selector", references: map[string]string{" ": "narratio.input.party"}, wantErr: "selector is required"},
|
||||
{name: "equals in selector", references: map[string]string{"party=x": "narratio.input.party"}, wantErr: "must not contain"},
|
||||
{name: "invalid stage", references: map[string]string{"lane.prepare.party": "narratio.input.party"}, wantErr: "middle component"},
|
||||
{name: "empty source", references: map[string]string{"party": " "}, wantErr: "source is required"},
|
||||
{name: "unsupported source", references: map[string]string{"party": "narratio.input.unknown"}, wantErr: "not a supported prepared input source"},
|
||||
{
|
||||
name: "normalized collision",
|
||||
references: map[string]string{
|
||||
"chunk.party": "narratio.input.party",
|
||||
" chunk . party ": "narratio.input.players",
|
||||
},
|
||||
wantErr: "normalize to",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
cfg := validNotariusConfig()
|
||||
cfg.References = tt.references
|
||||
err := validateNotarius(cfg, nil)
|
||||
if err == nil || !strings.Contains(err.Error(), tt.wantErr) {
|
||||
t.Fatalf("validateNotarius() error = %v, want containing %q", err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNotariusReferenceLimit(t *testing.T) {
|
||||
for _, count := range []int{MaxNotariusReferenceBindings, MaxNotariusReferenceBindings + 1} {
|
||||
t.Run(fmt.Sprintf("count_%d", count), func(t *testing.T) {
|
||||
cfg := validNotariusConfig()
|
||||
cfg.References = make(map[string]string, count)
|
||||
for i := 0; i < count; i++ {
|
||||
cfg.References[fmt.Sprintf("lane-%03d.party", i)] = "narratio.input.party"
|
||||
}
|
||||
err := validateNotarius(cfg, nil)
|
||||
if count == MaxNotariusReferenceBindings {
|
||||
if err != nil {
|
||||
t.Fatalf("validateNotarius() at limit error = %v", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if err == nil || !strings.Contains(err.Error(), "at most 256 bindings") {
|
||||
t.Fatalf("validateNotarius() above limit error = %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNotariusNilAndEmptyReferencesAreValid(t *testing.T) {
|
||||
for _, references := range []map[string]string{nil, {}} {
|
||||
cfg := validNotariusConfig()
|
||||
cfg.References = references
|
||||
if err := validateNotarius(cfg, nil); err != nil {
|
||||
t.Fatalf("validateNotarius(%#v) error = %v", references, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNotariusSpellCatalogReferenceRequiresEffectiveInput(t *testing.T) {
|
||||
cfg := loadedValidConfig(t)
|
||||
cfg.Pipeline.Notarius = validNotariusConfig()
|
||||
cfg.Pipeline.Notarius.References = map[string]string{"spells": "narratio.input.spell_catalog"}
|
||||
|
||||
err := Validate(cfg)
|
||||
if err == nil || !strings.Contains(err.Error(), "requires campaign.inputs.spell_catalog_file or session.inputs.spell_catalog_file") {
|
||||
t.Fatalf("Validate() error = %v, want missing spell catalog input", err)
|
||||
}
|
||||
|
||||
cfg.StableInputs.SpellCatalogFile = ResolvedInputFile{Path: "./spells.json", Source: "campaign_config"}
|
||||
if err := Validate(cfg); err != nil {
|
||||
t.Fatalf("Validate() with spell catalog error = %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func validNotariusConfig() *NotariusConfig {
|
||||
return &NotariusConfig{
|
||||
Enabled: true,
|
||||
Binary: "notarius",
|
||||
ConfigPath: "./notarius.yml",
|
||||
PipelineID: "dnd-session",
|
||||
Timeout: "45m",
|
||||
WorkingDirectory: ".",
|
||||
Outputs: map[string]NotariusOutputConfig{
|
||||
"npc_registry": {
|
||||
LaneID: "npc-registry",
|
||||
MediaType: "application/json",
|
||||
SchemaID: "notarius.dnd.npc_registry",
|
||||
SchemaVersion: "v1",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestNotariusEnabledValidation(t *testing.T) {
|
||||
valid := `notarius:
|
||||
enabled: true
|
||||
|
||||
Reference in New Issue
Block a user