Slice 1 of the filename-generator train (PRD 2026-06-01 §8). Pure refactor behind byte-equality — no user-visible change. pkg/nomen: the reusable engine. A Composition (ordered Segments, each with a trailing separator, optional wrap, and an omit/placeholder/literal missing-rule) renders against a VarResolver and a RenderTarget. Targets split into SanitiseValue (per-variable) + Finalise (whole-string + suffix) so a human title and a sanitised filename are two targets of one composition. VarCatalog + Validate guard stored compositions. internal/services/namegen.go: paliad-side wiring — the two seed system- default compositions that reproduce AutoSubmissionTitle (#155) and submissionFileName (354) as DATA, their variable catalogs, the resolvers (built from the existing submission_autoname helpers), and the artifact registry binding artifact -> catalog -> target -> default. Repointed call-sites: AutoSubmissionTitle and handlers.submissionFileName are now thin wrappers rendering through the registry; the assembly logic lives in the engine. Removed the hardcoded title/filename assembly and the handler's Az.-folgt const (now the case_number segment's placeholder). FLAG resolved (separators): the PRD sketched LEADING separators; that can't reproduce #155's client-absent case (date must join forum with a space while forum->opponent stays ' ./. '). Switched to TRAILING separators (owned by the left segment) — the minimal faithful fix. PRD §2.1 annotated. FLAG resolved (back-compat): the shipped composer_meta.filename_keyword override still flows through the engine — live round-trip test green. Acceptance: all existing #155/354 test matrices pass UNCHANGED (the byte-equality gate); new pkg/nomen unit tests cover trailing-sep, the three missing-rules, targets, and Validate; namegen_test validates the seeds against their catalogs. go vet + go test ./... + bun build all clean.
35 lines
1.1 KiB
Go
35 lines
1.1 KiB
Go
package services
|
|
|
|
import "testing"
|
|
|
|
// TestNameArtifactsValidate guards the seed system-default compositions
|
|
// against their own catalogs — a typo'd variable in a seed composition (a key
|
|
// the catalog doesn't declare) fails here rather than silently rendering
|
|
// nothing in production.
|
|
func TestNameArtifactsValidate(t *testing.T) {
|
|
for id, art := range nameArtifacts {
|
|
if art.ID != id {
|
|
t.Errorf("artifact %q has mismatched ID %q", id, art.ID)
|
|
}
|
|
if art.Target == nil {
|
|
t.Errorf("artifact %q has nil target", id)
|
|
}
|
|
if err := art.SystemDefault.Validate(art.Catalog); err != nil {
|
|
t.Errorf("artifact %q system default invalid: %v", id, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestNameArtifactLookup covers the registry accessor.
|
|
func TestNameArtifactLookup(t *testing.T) {
|
|
if _, ok := NameArtifact(ArtifactSubmissionDraftTitle); !ok {
|
|
t.Errorf("draft-title artifact not registered")
|
|
}
|
|
if _, ok := NameArtifact(ArtifactSubmissionDocxFilename); !ok {
|
|
t.Errorf("docx-filename artifact not registered")
|
|
}
|
|
if _, ok := NameArtifact("nonexistent"); ok {
|
|
t.Errorf("lookup of unknown artifact returned ok")
|
|
}
|
|
}
|