106 lines
3.6 KiB
Go
106 lines
3.6 KiB
Go
package app
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
"time"
|
|
|
|
"gitea.maximumdirect.net/eric/narratio/internal/manifest"
|
|
)
|
|
|
|
func TestDecideStageActions(t *testing.T) {
|
|
stages := BuildFullPlan()[:2]
|
|
m := manifest.New("2026-05-03", time.Now().UTC())
|
|
m.MarkStageSucceeded("prepare", time.Now().UTC(), nil)
|
|
|
|
got := decideStageActions(stages, m, false)
|
|
if len(got) != 2 {
|
|
t.Fatalf("len(decisions) = %d, want 2", len(got))
|
|
}
|
|
if got[0].Action != stageActionSkip {
|
|
t.Fatalf("prepare action = %q, want %q", got[0].Action, stageActionSkip)
|
|
}
|
|
if got[1].Action != stageActionRun {
|
|
t.Fatalf("transcribe action = %q, want %q", got[1].Action, stageActionRun)
|
|
}
|
|
|
|
forced := decideStageActions(stages, m, true)
|
|
if forced[0].Action != stageActionRun {
|
|
t.Fatalf("forced prepare action = %q, want %q", forced[0].Action, stageActionRun)
|
|
}
|
|
}
|
|
|
|
func TestDownstreamStageNames(t *testing.T) {
|
|
got := downstreamStageNames("polish")
|
|
want := []string{"normalize", "trim", "extract", "render", "analyze", "publish", "notify"}
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Fatalf("downstreamStageNames(polish) = %#v, want %#v", got, want)
|
|
}
|
|
|
|
missing := downstreamStageNames("unknown")
|
|
if len(missing) != 0 {
|
|
t.Fatalf("downstreamStageNames(unknown) = %#v, want empty", missing)
|
|
}
|
|
}
|
|
|
|
func TestInvalidateDownstreamSucceededStagesWithReason(t *testing.T) {
|
|
now := time.Now().UTC()
|
|
m := manifest.New("2026-05-03", now)
|
|
m.MarkStageSucceeded("prepare", now, nil)
|
|
m.MarkStageSucceeded("transcribe", now, nil)
|
|
m.MarkStageSucceeded("merge", now, nil)
|
|
m.MarkStageSucceeded("polish", now, nil)
|
|
m.MarkStageSucceeded("normalize", now, nil)
|
|
m.MarkStageSucceeded("trim", now, nil)
|
|
m.MarkStageSucceeded("extract", now, nil)
|
|
m.MarkStageSucceeded("render", now, nil)
|
|
m.MarkStageFailed("analyze", now, "analysis failed")
|
|
m.MarkStageSucceeded("publish", now, nil)
|
|
m.MarkStageSucceeded("notify", now, nil)
|
|
|
|
got := invalidateDownstreamSucceededStagesWithReason(m, "polish", now.Add(1*time.Second), staleReasonChangedResult)
|
|
want := []string{"normalize", "trim", "extract", "render", "publish", "notify"}
|
|
if !reflect.DeepEqual(got, want) {
|
|
t.Fatalf("invalidateDownstreamSucceededStagesWithReason() = %#v, want %#v", got, want)
|
|
}
|
|
|
|
for _, stageName := range want {
|
|
if m.Stages[stageName].Status != manifest.StatusStale {
|
|
t.Fatalf("%s status = %q, want stale", stageName, m.Stages[stageName].Status)
|
|
}
|
|
}
|
|
if m.Stages["analyze"].Status != manifest.StatusFailed {
|
|
t.Fatalf("analyze status = %q, want failed", m.Stages["analyze"].Status)
|
|
}
|
|
if m.Stages["prepare"].Status != manifest.StatusSucceeded {
|
|
t.Fatalf("prepare status = %q, want succeeded", m.Stages["prepare"].Status)
|
|
}
|
|
}
|
|
|
|
func TestExtractionPositionControlsForceInvalidation(t *testing.T) {
|
|
now := time.Now().UTC()
|
|
tests := []struct {
|
|
upstream string
|
|
want []string
|
|
}{
|
|
{upstream: "trim", want: []string{"extract", "render", "analyze", "publish", "notify"}},
|
|
{upstream: "extract", want: []string{"render", "analyze", "publish", "notify"}},
|
|
{upstream: "render", want: []string{"analyze", "publish", "notify"}},
|
|
}
|
|
for _, test := range tests {
|
|
t.Run(test.upstream, func(t *testing.T) {
|
|
m := manifest.New("2026-05-03", now)
|
|
for _, name := range canonicalStageNames() {
|
|
m.MarkStageSucceeded(name, now, nil)
|
|
}
|
|
got := invalidateDownstreamSucceededStagesWithReason(m, test.upstream, now.Add(time.Second), staleReasonForcedReplacement)
|
|
if !reflect.DeepEqual(got, test.want) {
|
|
t.Fatalf("invalidated = %#v, want %#v", got, test.want)
|
|
}
|
|
if test.upstream == "render" && m.Stages["extract"].Status != manifest.StatusSucceeded {
|
|
t.Fatalf("forcing render changed extract: %#v", m.Stages["extract"])
|
|
}
|
|
})
|
|
}
|
|
}
|