71 lines
2.7 KiB
Go
71 lines
2.7 KiB
Go
package pipeline
|
||
|
||
import (
|
||
"strings"
|
||
"testing"
|
||
|
||
"textmachine/backend/internal/store"
|
||
)
|
||
|
||
// snapshot_wave_test.go: WS1 §1в per-wave snapshot mechanics (R1 ADDITIVE sub-step — the wave executor
|
||
// itself is residual; this pins the snapshot machinery it will use, WITHOUT switching the driver). The
|
||
// book-global snapshotID() is byte-unchanged (TestGolden proves it); these tests exercise the new
|
||
// snapshotIDForWave.
|
||
func TestSnapshotIDForWave(t *testing.T) {
|
||
r := newRunner(t, setupProject(t, "http://127.0.0.1:1"))
|
||
defer r.Close()
|
||
|
||
seed := []store.GlossaryEntry{
|
||
{Src: "方源", Dst: "Фан Юань", Status: "approved", Source: "seed"},
|
||
{Src: "古月", Dst: "Гу Юэ", Status: "approved", Source: "ruby"},
|
||
}
|
||
r.memory = materializeMemory(seed, false)
|
||
|
||
w1id, w1p, err := r.snapshotIDForWave(waveW1)
|
||
if err != nil {
|
||
t.Fatal(err)
|
||
}
|
||
w2id, w2p, err := r.snapshotIDForWave(waveW2)
|
||
if err != nil {
|
||
t.Fatal(err)
|
||
}
|
||
// W1 and W2 differ (different stage subset AND different bank version).
|
||
if w1id == w2id {
|
||
t.Fatalf("snapshot_W1 must differ from snapshot_W2 (stage subset + bank version)")
|
||
}
|
||
// The stage PARTITION: W1 folds the draft (translator) stage, W2 folds the edit (editor) stage.
|
||
if !strings.Contains(w1p, `"name":"draft"`) || strings.Contains(w1p, `"name":"edit"`) {
|
||
t.Fatalf("snapshot_W1 must fold ONLY the draft stage, payload: %s", w1p)
|
||
}
|
||
if !strings.Contains(w2p, `"name":"edit"`) || strings.Contains(w2p, `"name":"draft"`) {
|
||
t.Fatalf("snapshot_W2 must fold ONLY the edit stage, payload: %s", w2p)
|
||
}
|
||
|
||
// «Переоплата ОДНА» at the snapshot level (§1в): a W1.5 mined-approved addition moves ONLY W2.
|
||
enriched := append(append([]store.GlossaryEntry{}, seed...), store.GlossaryEntry{
|
||
Src: "蛊", Dst: "гу", Status: "approved", Source: "mined",
|
||
})
|
||
r.memory = materializeMemory(enriched, false)
|
||
w1id2, _, _ := r.snapshotIDForWave(waveW1)
|
||
w2id2, _, _ := r.snapshotIDForWave(waveW2)
|
||
if w1id2 != w1id {
|
||
t.Fatalf("snapshot_W1 moved on a mined-approved addition — W1 checkpoints would re-bill («переоплата ОДНА» broken)")
|
||
}
|
||
if w2id2 == w2id {
|
||
t.Fatalf("snapshot_W2 did NOT move on a mined-approved addition — the edit wave would miss the mined canon")
|
||
}
|
||
}
|
||
|
||
// TestWaveStagesPartition pins the role partition independently of the runner.
|
||
func TestWaveStagesPartition(t *testing.T) {
|
||
r := newRunner(t, setupProject(t, "http://127.0.0.1:1"))
|
||
defer r.Close()
|
||
w1 := waveStages(r.Pipeline.Stages, waveW1)
|
||
w2 := waveStages(r.Pipeline.Stages, waveW2)
|
||
if len(w1) != 1 || w1[0].Role != roleTranslator {
|
||
t.Fatalf("W1 must be the translator stage(s), got %+v", w1)
|
||
}
|
||
if len(w2) != 1 || w2[0].Role != roleEditor {
|
||
t.Fatalf("W2 must be the editor stage(s), got %+v", w2)
|
||
}
|
||
}
|