Say what a dot-prefixed data entry actually does

Two cases claimed to pin that a category or folder named with the reference
prefix is rejected. They passed for the wrong reason: the entry is skipped as
hidden, which left the directory empty, so New failed with "no .json data
found" instead. Beside a valid sibling both load fine and are simply absent.

Replaced with a test of the real rule — a leading dot means hidden, which is
what lets a data directory be a checkout — and that covers a ".." name too.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
M
2026-08-31 13:41:09 +02:00
committed by lilleman-tw
parent 258bce3b98
commit 25a3077925
+17 -3
View File
@@ -104,9 +104,7 @@ func TestReferenceErrors(t *testing.T) {
"mutual cycle across two folders": {"en_US/a": `{"format":"{..sv_SE.b}"}`, "sv_SE/b": `{"format":"{..en_US.a}"}`}, "mutual cycle across two folders": {"en_US/a": `{"format":"{..sv_SE.b}"}`, "sv_SE/b": `{"format":"{..en_US.a}"}`},
// ".." is reserved for bound references, so an authored key using it would // ".." is reserved for bound references, so an authored key using it would
// name a node nothing can reach and nothing would validate. // name a node nothing can reach and nothing would validate.
"field key using the reference prefix": {"cat": `{"format":"hi","..x":{"format":"{..nope}"}}`}, "field key using the reference prefix": {"cat": `{"format":"hi","..x":{"format":"{..nope}"}}`},
"category name using the reference prefix": {"sv_SE/..bad": `{"format":"{..nope}"}`},
"folder name using the reference prefix": {"sv_SE/..y/cat": `{"format":"{..nope}"}`},
} }
for name, files := range cases { for name, files := range cases {
if _, err := New([]string{writeData(t, files)}); err == nil { if _, err := New([]string{writeData(t, files)}); err == nil {
@@ -115,6 +113,22 @@ func TestReferenceErrors(t *testing.T) {
} }
} }
// TestDotPrefixedDataEntriesAreSkipped pins what a leading dot means on disk: the
// entry is hidden, not data, so a data directory can also be a checkout. A name
// starting with the reference prefix is covered by that same rule, since ".."
// starts with "." — it is skipped, not rejected.
func TestDotPrefixedDataEntriesAreSkipped(t *testing.T) {
f := newFakes(t, writeData(t, map[string]string{
"sv_SE/ok": `["fine"]`,
"sv_SE/..bad": `{"format":"{..nope}"}`,
"sv_SE/..y/ct": `{"format":"{..nope}"}`,
".git/config": `["not data"]`,
}), WithSeed(1))
if got := f.List(); len(got) != 1 || got[0] != "sv_SE.ok" {
t.Fatalf("List() = %v, want only sv_SE.ok", got)
}
}
// TestReferenceFromUnrenderedFieldTerminates guards the cycle check against // TestReferenceFromUnrenderedFieldTerminates guards the cycle check against
// over-rejecting: a field the format never renders may point back at its own // over-rejecting: a field the format never renders may point back at its own
// category, which terminates, and stays renderable by path. // category, which terminates, and stays renderable by path.