79 lines
3 KiB
Go
79 lines
3 KiB
Go
package config
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
// genre_retired_test.go: `genre:` is retired (owner 16.08 «просто выкидываем», D39.138 п.2в). The field
|
|
// left the API contract and the intake form in batch 0.3.0; it now leaves the engine — no prompt renders
|
|
// it and the brief canon no longer folds it.
|
|
//
|
|
// TWO HALVES AND THEY PULL OPPOSITE WAYS, which is why both are pinned here. The key must still LOAD,
|
|
// because the platform writes a book's book.yaml once from an operator template it carries through unread
|
|
// and never rewrites — a strict decoder that refused the line would refuse books already on disk, mid-run.
|
|
// And the VALUE must reach nothing: a book that differs only in its genre is now the same brief, so the
|
|
// two books' hashes are equal and neither is re-billed for a word nobody reads.
|
|
|
|
func TestARetiredGenreKeyStillLoadsAndReachesNothing(t *testing.T) {
|
|
load := func(extra string) *Book {
|
|
t.Helper()
|
|
dir := t.TempDir()
|
|
b, err := LoadBook(writeBook(t, dir, extra))
|
|
if err != nil {
|
|
t.Fatalf("book with %q must load: %v", extra, err)
|
|
}
|
|
return b
|
|
}
|
|
withGenre := load("genre: ранобэ\n")
|
|
otherGenre := load("genre: производственный роман\n")
|
|
without := load("")
|
|
|
|
// The brief is what a re-purchase is priced against, so this equality IS the money statement: an
|
|
// operator template that still carries the line costs its book nothing, and neither does editing it.
|
|
if withGenre.BriefHash() != without.BriefHash() {
|
|
t.Errorf("a declared genre still moves the brief: %s vs %s", withGenre.BriefHash(), without.BriefHash())
|
|
}
|
|
if withGenre.BriefHash() != otherGenre.BriefHash() {
|
|
t.Errorf("two genres are still two briefs: %s vs %s", withGenre.BriefHash(), otherGenre.BriefHash())
|
|
}
|
|
}
|
|
|
|
// TestNoShippingPromptAsksForTheGenre is the other end of the same removal, and it is a repo gate rather
|
|
// than a runtime one for the reason the prompt-label ledger is: the renderer already refuses an unknown
|
|
// {{…}} marker loudly, but only for a pair whose prompts somebody actually runs. A pack authored later
|
|
// with the placeholder should be caught by the repository that retired it, not by a paid run.
|
|
func TestNoShippingPromptAsksForTheGenre(t *testing.T) {
|
|
root := filepath.Join("..", "..", "prompts")
|
|
var offenders []string
|
|
err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
|
|
if err != nil || info.IsDir() {
|
|
return err
|
|
}
|
|
body, rerr := os.ReadFile(path)
|
|
if rerr != nil {
|
|
return rerr
|
|
}
|
|
if len(body) > 0 && containsGenrePlaceholder(string(body)) {
|
|
offenders = append(offenders, path)
|
|
}
|
|
return nil
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("walk %s: %v", root, err)
|
|
}
|
|
if len(offenders) > 0 {
|
|
t.Fatalf("the genre placeholder is retired and the renderer no longer supplies it — these prompts would fail loud on their first render: %v", offenders)
|
|
}
|
|
}
|
|
|
|
func containsGenrePlaceholder(s string) bool {
|
|
const marker = "{{genre}}"
|
|
for i := 0; i+len(marker) <= len(s); i++ {
|
|
if s[i:i+len(marker)] == marker {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|