From c755d085a90fc7190bf17ec44b2deedfcc952f38 Mon Sep 17 00:00:00 2001 From: M Date: Sun, 30 Aug 2026 21:22:11 +0200 Subject: [PATCH] Tests for a reference reaching a bound level from anywhere, and a literal that merely matches --- bound_test.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/bound_test.go b/bound_test.go index 682d4d1..0a528a5 100644 --- a/bound_test.go +++ b/bound_test.go @@ -96,6 +96,11 @@ func TestReferenceNamingABoundLevelIsRejected(t *testing.T) { rejected := map[string]string{ "reference names the head": `{"format":"{p.first}|{..cat.p}","p":[{"format":"{first}","first":["Anna","Bo"]}]}`, "reference names the leaf": `{"format":"{p.addr}|{..cat.p.addr}","p":{"format":"x","addr":["A","B","C","D"]}}`, + // The reference need not sit in the format that binds: any field it renders + // reaches the level just the same, however deep. + "reference from a sibling field": `{"format":"{p.first}|{inner}","p":[` + + `{"format":"{first}-{last}","first":"A","last":"1"},{"format":"{first}-{last}","first":"B","last":"2"}],` + + `"inner":{"format":"{..cat.p}"}}`, } for name, file := range rejected { _, err := New([]string{writeData(t, map[string]string{"cat": file})}) @@ -112,6 +117,18 @@ func TestReferenceNamingABoundLevelIsRejected(t *testing.T) { } } +func TestReferenceToAMatchingStringIsAccepted(t *testing.T) { + // A literal renders one fixed string, so no draw of it can disagree with a + // held one. Two unrelated literals that merely spell the same text must not + // read as the same node — the trap when comparing a value type. + if _, err := New([]string{writeData(t, map[string]string{ + "cat": `{"format":"{p.city} {..other.tag}","p":{"format":"{city}","city":"Stockholm"}}`, + "other": `{"format":"x","tag":"Stockholm"}`, + })}); err != nil { + t.Fatalf("New = %v, want a reference to a matching string accepted", err) + } +} + func TestNestedChoiceDrawsOneVariant(t *testing.T) { // A choice item may itself be a choice, so drawing a bound head unwraps until // it reaches a value. Stopping at one level leaves a choice where the walk