Add D&D spells extractor skeleton
This commit is contained in:
65
internal/modules/extract/dnd/spells/extractor.go
Normal file
65
internal/modules/extract/dnd/spells/extractor.go
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
package spells
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"gitea.maximumdirect.net/eric/notarius/internal/framework/contracts"
|
||||||
|
"gitea.maximumdirect.net/eric/notarius/internal/framework/pipeline"
|
||||||
|
)
|
||||||
|
|
||||||
|
const Key = "dnd/spells"
|
||||||
|
const ArtifactType = "dnd.spell_cast"
|
||||||
|
const SchemaVersion = "v1"
|
||||||
|
|
||||||
|
var requiredCapabilities = []string{
|
||||||
|
"chunks",
|
||||||
|
"source.transcript",
|
||||||
|
}
|
||||||
|
|
||||||
|
var providedCapabilities = []string{
|
||||||
|
"dnd.spell_casts",
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ contracts.Extractor = (*Extractor)(nil)
|
||||||
|
|
||||||
|
type Extractor struct{}
|
||||||
|
|
||||||
|
func New() *Extractor {
|
||||||
|
return &Extractor{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Extractor) Key() string {
|
||||||
|
return Key
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Extractor) ArtifactType() string {
|
||||||
|
return ArtifactType
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Extractor) SchemaVersion() string {
|
||||||
|
return SchemaVersion
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Extractor) Validators() []contracts.Validator {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Extractor) Extract(ctx context.Context, req contracts.ExtractionRequest) (contracts.ExtractionResult, error) {
|
||||||
|
return contracts.ExtractionResult{}, fmt.Errorf("dnd spells extractor: extraction is not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func ModuleSpec() pipeline.ModuleSpec {
|
||||||
|
return pipeline.ModuleSpec{
|
||||||
|
Key: Key,
|
||||||
|
Stage: pipeline.StageExtract,
|
||||||
|
Requires: append([]string(nil), requiredCapabilities...),
|
||||||
|
Provides: append([]string(nil), providedCapabilities...),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Register(registry *pipeline.ExtractorRegistry) error {
|
||||||
|
return registry.RegisterWithSpec(ModuleSpec(), func() (contracts.Extractor, error) {
|
||||||
|
return New(), nil
|
||||||
|
})
|
||||||
|
}
|
||||||
22
internal/modules/extract/dnd/spells/model.go
Normal file
22
internal/modules/extract/dnd/spells/model.go
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package spells
|
||||||
|
|
||||||
|
import "gitea.maximumdirect.net/eric/notarius/internal/core/source"
|
||||||
|
|
||||||
|
type SpellCast struct {
|
||||||
|
Caster string `json:"caster"`
|
||||||
|
Spell string `json:"spell"`
|
||||||
|
Effect string `json:"effect"`
|
||||||
|
NarrativeDescription string `json:"narrative_description"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type extractionResponse struct {
|
||||||
|
SpellCasts []spellCastResponse `json:"spell_casts"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type spellCastResponse struct {
|
||||||
|
Caster string `json:"caster"`
|
||||||
|
Spell string `json:"spell"`
|
||||||
|
Effect string `json:"effect"`
|
||||||
|
NarrativeDescription string `json:"narrative_description"`
|
||||||
|
SourceRefs []source.SourceRef `json:"source_refs"`
|
||||||
|
}
|
||||||
105
internal/modules/extract/dnd/spells/registry_test.go
Normal file
105
internal/modules/extract/dnd/spells/registry_test.go
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
package spells
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"gitea.maximumdirect.net/eric/notarius/internal/framework/contracts"
|
||||||
|
"gitea.maximumdirect.net/eric/notarius/internal/framework/pipeline"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewReturnsExtractorWithMetadata(t *testing.T) {
|
||||||
|
extractor := New()
|
||||||
|
if extractor == nil {
|
||||||
|
t.Fatal("New() = nil, want extractor")
|
||||||
|
}
|
||||||
|
if extractor.Key() != Key {
|
||||||
|
t.Fatalf("extractor.Key() = %q, want %q", extractor.Key(), Key)
|
||||||
|
}
|
||||||
|
if extractor.ArtifactType() != ArtifactType {
|
||||||
|
t.Fatalf("extractor.ArtifactType() = %q, want %q", extractor.ArtifactType(), ArtifactType)
|
||||||
|
}
|
||||||
|
if extractor.SchemaVersion() != SchemaVersion {
|
||||||
|
t.Fatalf("extractor.SchemaVersion() = %q, want %q", extractor.SchemaVersion(), SchemaVersion)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestModuleSpec(t *testing.T) {
|
||||||
|
got := ModuleSpec()
|
||||||
|
want := pipeline.ModuleSpec{
|
||||||
|
Key: Key,
|
||||||
|
Stage: pipeline.StageExtract,
|
||||||
|
Requires: []string{
|
||||||
|
"chunks",
|
||||||
|
"source.transcript",
|
||||||
|
},
|
||||||
|
Provides: []string{
|
||||||
|
"dnd.spell_casts",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(got, want) {
|
||||||
|
t.Fatalf("ModuleSpec() = %#v, want %#v", got, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
got.Requires[0] = "changed"
|
||||||
|
got.Provides[0] = "changed"
|
||||||
|
again := ModuleSpec()
|
||||||
|
if !reflect.DeepEqual(again, want) {
|
||||||
|
t.Fatalf("ModuleSpec() after caller mutation = %#v, want %#v", again, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRegisterMakesExtractorBuildable(t *testing.T) {
|
||||||
|
registry := pipeline.NewExtractorRegistry()
|
||||||
|
|
||||||
|
if err := Register(registry); err != nil {
|
||||||
|
t.Fatalf("Register() error = %v, want nil", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
extractor, err := registry.Build(Key)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Build() error = %v, want nil", err)
|
||||||
|
}
|
||||||
|
if extractor.Key() != Key {
|
||||||
|
t.Fatalf("extractor.Key() = %q, want %q", extractor.Key(), Key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRegisterStoresModuleSpec(t *testing.T) {
|
||||||
|
registry := pipeline.NewExtractorRegistry()
|
||||||
|
|
||||||
|
if err := Register(registry); err != nil {
|
||||||
|
t.Fatalf("Register() error = %v, want nil", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
got, ok := registry.Spec(Key)
|
||||||
|
if !ok {
|
||||||
|
t.Fatal("Spec() ok = false, want true")
|
||||||
|
}
|
||||||
|
want := ModuleSpec()
|
||||||
|
if !reflect.DeepEqual(got, want) {
|
||||||
|
t.Fatalf("Spec() = %#v, want %#v", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRegisterNilRegistryReturnsError(t *testing.T) {
|
||||||
|
err := Register(nil)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("Register(nil) error = nil, want error")
|
||||||
|
}
|
||||||
|
if !strings.Contains(err.Error(), "extractor registry") {
|
||||||
|
t.Fatalf("Register(nil) error = %q, want registry context", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExtractReportsNotImplemented(t *testing.T) {
|
||||||
|
_, err := New().Extract(context.Background(), contracts.ExtractionRequest{})
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("Extract() error = nil, want error")
|
||||||
|
}
|
||||||
|
if !strings.Contains(err.Error(), "dnd spells") || !strings.Contains(err.Error(), "not implemented") {
|
||||||
|
t.Fatalf("Extract() error = %q, want not implemented D&D spells context", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user