137 lines
4.4 KiB
Go
137 lines
4.4 KiB
Go
package modules
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
|
|
"gitea.maximumdirect.net/eric/audita/internal/framework/contracts"
|
|
"gitea.maximumdirect.net/eric/audita/internal/framework/proposals"
|
|
)
|
|
|
|
type noopModule struct {
|
|
key string
|
|
}
|
|
|
|
func (m noopModule) Key() string { return m.key }
|
|
func (m noopModule) ReplacementPolicy() proposals.ReplacementPolicy {
|
|
return proposals.ReplacementPolicyRequireUnique
|
|
}
|
|
func (m noopModule) Validators() []contracts.Validator { return nil }
|
|
func (m noopModule) Propose(ctx context.Context, req contracts.ProposalRequest) ([]proposals.CorrectionProposal, error) {
|
|
_ = ctx
|
|
_ = req
|
|
return nil, nil
|
|
}
|
|
|
|
func TestKnownModuleKeyRecognition(t *testing.T) {
|
|
for _, key := range []string{ModuleKeyGlossary, ModuleKeyHomophones, ModuleKeySpokenWord, ModuleKeyGrammar} {
|
|
if !IsKnownModuleKey(key) {
|
|
t.Fatalf("expected key %q to be recognized", key)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestUnknownModuleKeyNotRecognized(t *testing.T) {
|
|
if IsKnownModuleKey("made_up") {
|
|
t.Fatal("expected unknown key to be unrecognized")
|
|
}
|
|
}
|
|
|
|
func TestRepeatedRunSpecNamingRemainsDeterministic(t *testing.T) {
|
|
specs, err := contracts.ResolveModuleRunSpecs([]string{"glossary", "glossary", "grammar"})
|
|
if err != nil {
|
|
t.Fatalf("ResolveModuleRunSpecs error: %v", err)
|
|
}
|
|
if specs[0].InstanceName != "glossary_1" || specs[1].InstanceName != "glossary_2" || specs[2].InstanceName != "grammar" {
|
|
t.Fatalf("unexpected instance names: %+v", specs)
|
|
}
|
|
}
|
|
|
|
func TestUnsupportedUnknownModuleKeyFailsCleanly(t *testing.T) {
|
|
factory := NewFactory(Dependencies{})
|
|
_, err := factory.ModuleForSpec(contracts.ModuleRunSpec{ModuleKey: "unknown", InstanceName: "unknown"})
|
|
if err == nil {
|
|
t.Fatal("expected unsupported-module error")
|
|
}
|
|
|
|
var unsupported *UnsupportedModuleError
|
|
if !errors.As(err, &unsupported) {
|
|
t.Fatalf("expected UnsupportedModuleError, got %T (%v)", err, err)
|
|
}
|
|
if unsupported.ReasonCode() != ReasonUnsupportedModule {
|
|
t.Fatalf("unexpected reason code: %q", unsupported.ReasonCode())
|
|
}
|
|
}
|
|
|
|
func TestRecognizedButUnimplementedModuleKeyFailsCleanly(t *testing.T) {
|
|
factory := NewFactory(Dependencies{})
|
|
for _, key := range []string{ModuleKeyGlossary, ModuleKeyHomophones, ModuleKeySpokenWord} {
|
|
t.Run(key, func(t *testing.T) {
|
|
_, err := factory.ModuleForSpec(contracts.ModuleRunSpec{ModuleKey: key, InstanceName: key})
|
|
if err == nil {
|
|
t.Fatal("expected unimplemented-module error")
|
|
}
|
|
|
|
var unimplemented *UnimplementedModuleError
|
|
if !errors.As(err, &unimplemented) {
|
|
t.Fatalf("expected UnimplementedModuleError, got %T (%v)", err, err)
|
|
}
|
|
if unimplemented.ReasonCode() != ReasonUnimplementedModule {
|
|
t.Fatalf("unexpected reason code: %q", unimplemented.ReasonCode())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGrammarIsRegisteredAndConstructibleByDefault(t *testing.T) {
|
|
factory := NewFactory(Dependencies{})
|
|
module, err := factory.ModuleForSpec(contracts.ModuleRunSpec{ModuleKey: ModuleKeyGrammar, InstanceName: ModuleKeyGrammar})
|
|
if err != nil {
|
|
t.Fatalf("ModuleForSpec error: %v", err)
|
|
}
|
|
if module.Key() != ModuleKeyGrammar {
|
|
t.Fatalf("expected grammar module key, got %q", module.Key())
|
|
}
|
|
}
|
|
|
|
func TestRegisterConstructorAndConstruct(t *testing.T) {
|
|
factory := NewFactory(Dependencies{})
|
|
if err := factory.RegisterConstructor(ModuleKeyGlossary, func(ctx context.Context, req ConstructRequest) (contracts.TranscriptModule, error) {
|
|
_ = ctx
|
|
if req.RunSpec.InstanceName != "glossary_1" {
|
|
t.Fatalf("expected run spec instance name, got %q", req.RunSpec.InstanceName)
|
|
}
|
|
return noopModule{key: req.RunSpec.ModuleKey}, nil
|
|
}); err != nil {
|
|
t.Fatalf("RegisterConstructor error: %v", err)
|
|
}
|
|
|
|
module, err := factory.ModuleForSpec(contracts.ModuleRunSpec{
|
|
ModuleKey: ModuleKeyGlossary,
|
|
InstanceName: "glossary_1",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("ModuleForSpec error: %v", err)
|
|
}
|
|
if module.Key() != ModuleKeyGlossary {
|
|
t.Fatalf("unexpected module key %q", module.Key())
|
|
}
|
|
}
|
|
|
|
func TestRegisterConstructorRejectsUnknownModuleKey(t *testing.T) {
|
|
factory := NewFactory(Dependencies{})
|
|
err := factory.RegisterConstructor("unknown", func(ctx context.Context, req ConstructRequest) (contracts.TranscriptModule, error) {
|
|
_ = ctx
|
|
_ = req
|
|
return noopModule{key: "unknown"}, nil
|
|
})
|
|
if err == nil {
|
|
t.Fatal("expected register failure for unknown key")
|
|
}
|
|
var unsupported *UnsupportedModuleError
|
|
if !errors.As(err, &unsupported) {
|
|
t.Fatalf("expected UnsupportedModuleError, got %T (%v)", err, err)
|
|
}
|
|
}
|