153 lines
4.8 KiB
Go
153 lines
4.8 KiB
Go
package app
|
|
|
|
import (
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
|
|
"gitea.maximumdirect.net/eric/narratio/internal/stage"
|
|
)
|
|
|
|
func TestBuildFullPlanOrder(t *testing.T) {
|
|
got := BuildFullPlan()
|
|
want := []string{"prepare", "transcribe", "merge", "polish", "normalize", "trim", "render", "extract", "analyze", "publish", "notify"}
|
|
if len(got) != len(want) {
|
|
t.Fatalf("len(plan) = %d, want %d", len(got), len(want))
|
|
}
|
|
for i := range want {
|
|
if got[i].Name() != want[i] {
|
|
t.Fatalf("plan[%d] = %q, want %q", i, got[i].Name(), want[i])
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestBuildSingleStagePlan(t *testing.T) {
|
|
stages, err := BuildSingleStagePlan("polish")
|
|
if err != nil {
|
|
t.Fatalf("BuildSingleStagePlan() error = %v", err)
|
|
}
|
|
if len(stages) != 1 {
|
|
t.Fatalf("len(plan) = %d, want 1", len(stages))
|
|
}
|
|
if stages[0].Name() != "polish" {
|
|
t.Fatalf("stage name = %q, want %q", stages[0].Name(), "polish")
|
|
}
|
|
}
|
|
|
|
func TestBuildSingleStagePlanUnknown(t *testing.T) {
|
|
_, err := BuildSingleStagePlan("unknown")
|
|
if err == nil {
|
|
t.Fatal("expected error for unknown stage, got nil")
|
|
}
|
|
}
|
|
|
|
func TestBuildBoundedPlanEndpoints(t *testing.T) {
|
|
canonical := stageNames(BuildFullPlan())
|
|
for index, name := range canonical {
|
|
t.Run(name, func(t *testing.T) {
|
|
one, err := BuildBoundedPlan(name, name)
|
|
if err != nil {
|
|
t.Fatalf("BuildBoundedPlan(%q, %q) error = %v", name, name, err)
|
|
}
|
|
if got := one.Names(); !reflect.DeepEqual(got, []string{name}) {
|
|
t.Fatalf("one-stage names = %#v, want %q", got, name)
|
|
}
|
|
if one.From() != name || one.Through() != name || !one.Contains(name) || !one.HasExplicitBounds() {
|
|
t.Fatalf("one-stage plan endpoints or membership = %#v", one)
|
|
}
|
|
|
|
from, err := BuildBoundedPlan(name, "")
|
|
if err != nil {
|
|
t.Fatalf("BuildBoundedPlan(%q, empty) error = %v", name, err)
|
|
}
|
|
if got := from.Names(); !reflect.DeepEqual(got, canonical[index:]) {
|
|
t.Fatalf("from names = %#v, want %#v", got, canonical[index:])
|
|
}
|
|
|
|
through, err := BuildBoundedPlan("", name)
|
|
if err != nil {
|
|
t.Fatalf("BuildBoundedPlan(empty, %q) error = %v", name, err)
|
|
}
|
|
if got := through.Names(); !reflect.DeepEqual(got, canonical[:index+1]) {
|
|
t.Fatalf("through names = %#v, want %#v", got, canonical[:index+1])
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestBuildBoundedPlanDefaultsToFullCanonicalPlan(t *testing.T) {
|
|
plan, err := BuildBoundedPlan("", "")
|
|
if err != nil {
|
|
t.Fatalf("BuildBoundedPlan() error = %v", err)
|
|
}
|
|
want := stageNames(BuildFullPlan())
|
|
if got := plan.Names(); !reflect.DeepEqual(got, want) {
|
|
t.Fatalf("bounded names = %#v, want %#v", got, want)
|
|
}
|
|
if plan.From() != want[0] || plan.Through() != want[len(want)-1] || plan.HasExplicitBounds() {
|
|
t.Fatalf("default endpoints = %q through %q explicit=%t", plan.From(), plan.Through(), plan.HasExplicitBounds())
|
|
}
|
|
if got := plan.PrefixNames(); len(got) != 0 {
|
|
t.Fatalf("default prefix = %#v, want empty", got)
|
|
}
|
|
}
|
|
|
|
func TestBuildBoundedPlanRejectsInvalidBounds(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
from string
|
|
through string
|
|
want []string
|
|
}{
|
|
{name: "unknown from", from: "missing", through: "analyze", want: []string{"unknown from stage", "missing", "prepare", "notify"}},
|
|
{name: "unknown through", from: "extract", through: "missing", want: []string{"unknown through stage", "missing", "prepare", "notify"}},
|
|
{name: "reversed", from: "publish", through: "render", want: []string{"publish", "occurs after", "render", "prepare", "notify"}},
|
|
}
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
_, err := BuildBoundedPlan(test.from, test.through)
|
|
if err == nil {
|
|
t.Fatal("BuildBoundedPlan() error = nil")
|
|
}
|
|
for _, fragment := range test.want {
|
|
if !strings.Contains(err.Error(), fragment) {
|
|
t.Fatalf("error = %q, want fragment %q", err, fragment)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestBoundedPlanIsContiguousAndCannotMutateRegistry(t *testing.T) {
|
|
before := stageNames(BuildFullPlan())
|
|
plan, err := BuildBoundedPlan("trim", "analyze")
|
|
if err != nil {
|
|
t.Fatalf("BuildBoundedPlan() error = %v", err)
|
|
}
|
|
want := []string{"trim", "render", "extract", "analyze"}
|
|
if got := plan.Names(); !reflect.DeepEqual(got, want) {
|
|
t.Fatalf("names = %#v, want contiguous %#v", got, want)
|
|
}
|
|
if got := plan.PrefixNames(); !reflect.DeepEqual(got, before[:5]) {
|
|
t.Fatalf("prefix = %#v, want %#v", got, before[:5])
|
|
}
|
|
stages := plan.Stages()
|
|
stages[0] = nil
|
|
names := plan.Names()
|
|
names[0] = "changed"
|
|
if got := plan.Names(); !reflect.DeepEqual(got, want) {
|
|
t.Fatalf("mutated plan names = %#v, want %#v", got, want)
|
|
}
|
|
if got := stageNames(BuildFullPlan()); !reflect.DeepEqual(got, before) {
|
|
t.Fatalf("canonical registry changed = %#v, want %#v", got, before)
|
|
}
|
|
}
|
|
|
|
func stageNames(stages []stage.Stage) []string {
|
|
names := make([]string, 0, len(stages))
|
|
for _, candidate := range stages {
|
|
names = append(names, candidate.Name())
|
|
}
|
|
return names
|
|
}
|