From cc76d300e7b5fd93fc89ff0d72d7f6f08f0888ad Mon Sep 17 00:00:00 2001 From: M Date: Sun, 30 Aug 2026 23:04:31 +0200 Subject: [PATCH] Tests for a repeated alternation arm {a|a|b} skews an alternation three to one, an undocumented third way to weight beside a choice's weight and a repeated choice entry. These pin its rejection, and one accepted case fixes the boundary: {x}{x} is two tokens, so it stays two independent draws. Co-Authored-By: Claude Opus 5 --- edge_test.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/edge_test.go b/edge_test.go index a5564f5..da5ed4c 100644 --- a/edge_test.go +++ b/edge_test.go @@ -124,6 +124,19 @@ func TestNewErrors(t *testing.T) { map[string]string{"a(b/cat": `["1"]`}, `folder "a(b" contains "("`, }, + // A repeated arm skews an alternation, which weight is the spelling for. + "repeated alternation arm": { + map[string]string{"a": `{"format":"{x|x}","x":["1"]}`}, + `arm "x" is repeated`, + }, + "repeated arm among others": { + map[string]string{"a": `{"format":"{x|y|x}","x":["1"],"y":["2"]}`}, + `arm "x" is repeated`, + }, + "repeated path arm": { + map[string]string{"a": `{"format":"{p.v|p.v}","p":{"format":"{v}","v":["1"]}}`}, + `arm "p.v" is repeated`, + }, } for name, c := range rejected { _, err := New([]string{writeData(t, c.files)}) @@ -148,6 +161,9 @@ func TestNewErrors(t *testing.T) { "folder named Repeat": {map[string]string{"Repeat/cat": `["1"]`}, "Repeat.cat", "1"}, "field with a closing paren": {map[string]string{"a": `{"format":"{b)c}","b)c":["2"]}`}, "a", "2"}, "repeat without a separator": {map[string]string{"a": `{"format":"{x}","repeat":3,"x":["1"]}`}, "a", "111"}, + // One name in two separate tokens is two independent draws, not a repeated + // arm; only a repeat within one alternation is rejected. + "one name in two tokens": {map[string]string{"a": `{"format":"{x}{x}","x":["1"]}`}, "a", "11"}, } for name, c := range accepted { f, err := New([]string{writeData(t, c.files)})