textmachine/backend/internal/pipeline/export_pairs_test.go

61 lines
1.8 KiB
Go

package pipeline
import (
"context"
"testing"
)
// export_pairs_test.go: WS5 `tmctl export --pairs` — the src↔target column the polygon needs for the
// DC1/DC2 false-positive measure (§5(д)). Default export is target-only (Source omitted); --pairs adds
// the $0 manifest source per chunk, matching what the runner chunked.
func TestExportPairsIncludesSource(t *testing.T) {
rec := &reqRec{}
srv := newJSONProvider(rec, draftEdit)
defer srv.Close()
bookPath := setupProjectOpts(t, srv.URL, projectOpts{source: "静かな図書館の朝。"})
ctx := context.Background()
r := newRunner(t, bookPath)
defer r.Close()
if _, err := r.TranslateBook(ctx); err != nil {
t.Fatal(err)
}
// Recover the manifest source the runner chunked, to compare against the --pairs column.
manifest, err := r.bookChunks()
if err != nil {
t.Fatal(err)
}
bySource := map[[2]int]string{}
for _, ch := range manifest {
bySource[[2]int{ch.Chapter, ch.ChunkIdx}] = ch.Text
}
// Default export: Source omitted (target-only contract).
plain, err := r.Export(false)
if err != nil {
t.Fatal(err)
}
for _, ce := range plain.Chunks {
if ce.Source != "" {
t.Fatalf("default export must omit Source, got %q for ch%d/%d", ce.Source, ce.Chapter, ce.ChunkIdx)
}
}
// --pairs export: Source populated with the exact manifest source per chunk.
pairs, err := r.Export(true)
if err != nil {
t.Fatal(err)
}
if len(pairs.Chunks) == 0 {
t.Fatal("export produced no chunks")
}
for _, ce := range pairs.Chunks {
want := bySource[[2]int{ce.Chapter, ce.ChunkIdx}]
if ce.Source != want {
t.Fatalf("--pairs ch%d/%d Source = %q, want the manifest source %q", ce.Chapter, ce.ChunkIdx, ce.Source, want)
}
if ce.Source == "" {
t.Fatalf("--pairs must populate a non-empty Source for a real chunk (ch%d/%d)", ce.Chapter, ce.ChunkIdx)
}
}
}