From 3479f9cf98c442de823b469acd6138a9b037ff32 Mon Sep 17 00:00:00 2001 From: Lilleman auf Larv Date: Mon, 5 Oct 2026 12:25:22 +0200 Subject: [PATCH] Test a calc's operand list, one empty-segment check, and an empty segment after a step up --- calc_test.go | 8 ++++---- internal/grammar/calc_test.go | 12 ++++++------ internal/grammar/format_test.go | 10 ++++------ internal/grammar/path_test.go | 11 +++++++++++ table_test.go | 1 + 5 files changed, 26 insertions(+), 16 deletions(-) diff --git a/calc_test.go b/calc_test.go index e535177..80d9473 100644 --- a/calc_test.go +++ b/calc_test.go @@ -101,12 +101,12 @@ func TestCalcReproducible(t *testing.T) { // call that is not a calc, and for one whose expression does not parse: none, either way. func TestParsedCallReadsOnlyAnOperandBuiltin(t *testing.T) { for _, format := range []string{"{luhn()}", "{calc()}", "{calc(1 +)}", "{calc(()}"} { - if toks, err := grammar.ParseFormat(format, builtinOperands); err != nil || len(toks) != 1 || toks[0].Names != nil { - t.Errorf("ParseFormat(%q) = %+v, %v, want one call reading no operand", format, toks, err) + if toks, err := grammar.ParseFormat(format); err != nil || len(toks) != 1 || tokenReads(toks[0]) != nil { + t.Errorf("tokenReads(%q) = %+v, %v, want one call reading no operand", format, toks, err) } } - if toks, err := grammar.ParseFormat("{calc(net * qty)}", builtinOperands); err != nil || len(toks) != 1 || len(toks[0].Names) != 2 { - t.Errorf("ParseFormat({calc(net * qty)}) = %+v, %v, want both operands", toks, err) + if toks, err := grammar.ParseFormat("{calc(net * qty)}"); err != nil || len(toks) != 1 || len(tokenReads(toks[0])) != 2 { + t.Errorf("tokenReads({calc(net * qty)}) = %+v, %v, want both operands", toks, err) } } diff --git a/internal/grammar/calc_test.go b/internal/grammar/calc_test.go index 191a20c..222d73e 100644 --- a/internal/grammar/calc_test.go +++ b/internal/grammar/calc_test.go @@ -6,18 +6,18 @@ import ( ) func TestParseCalcPlacesEachOperandAtItsFirstReading(t *testing.T) { - n, err := ParseCalc("b * (a - b) / -2") + c, err := ParseCalc("b * (a - b) / -2") if err != nil { t.Fatal(err) } want := CalcBin{'/', CalcBin{'*', CalcVar{"b", 0}, CalcBin{'-', CalcVar{"a", 1}, CalcVar{"b", 0}}}, CalcNeg{CalcNum(2)}} - if !reflect.DeepEqual(n, want) { - t.Errorf("ParseCalc = %#v, want %#v", n, want) + if !reflect.DeepEqual(c.Expr, want) { + t.Errorf("ParseCalc = %#v, want %#v", c.Expr, want) } - if got := CalcVars(n); !reflect.DeepEqual(got, []string{"b", "a"}) { - t.Errorf("CalcVars = %q, want [b a]", got) + if !reflect.DeepEqual(c.Operands, []string{"b", "a"}) { + t.Errorf("Operands = %q, want [b a]", c.Operands) } - if got := CalcText(n); got != "((b * (a - b)) / -2)" { + if got := CalcText(c.Expr); got != "((b * (a - b)) / -2)" { t.Errorf("CalcText = %q", got) } } diff --git a/internal/grammar/format_test.go b/internal/grammar/format_test.go index 4223797..2c6a97b 100644 --- a/internal/grammar/format_test.go +++ b/internal/grammar/format_test.go @@ -21,17 +21,15 @@ func TestSplitArgsQuotesOutsideSelectors(t *testing.T) { } func TestParseFormatReadsEachTokenKind(t *testing.T) { - toks, err := ParseFormat("a{{{x|/y.z[a.b]}{/p as q}{f(1, n)}", func(fn string, args []string) []string { - return args[1:] - }) + toks, err := ParseFormat("a{{{x|/y.z[a.b]}{/p as q}{f(1, n)}") if err != nil { t.Fatal(err) } want := []Token{ {Kind: LiteralRun, Lit: "a{"}, - {Kind: NameRead, Body: "x|/y.z[a.b]", Names: []string{"x", "/y.z[a.b]"}}, + {Kind: NameRead, Body: "x|/y.z[a.b]", Arms: []string{"x", "/y.z[a.b]"}}, {Kind: NameBind, Body: "/p as q", BoundRef: "/p", Bound: "q"}, - {Kind: BuiltinCall, Body: "f(1, n)", Fn: "f", Args: []string{"1", "n"}, Names: []string{"n"}}, + {Kind: BuiltinCall, Body: "f(1, n)", Fn: "f", Args: []string{"1", "n"}}, } if !reflect.DeepEqual(toks, want) { t.Errorf("ParseFormat = %+v, want %+v", toks, want) @@ -40,7 +38,7 @@ func TestParseFormatReadsEachTokenKind(t *testing.T) { func TestParseFormatRefusesUnbalancedBraces(t *testing.T) { for _, format := range []string{"{a", "a}", "{a{b}}", "{f(}"} { - if _, err := ParseFormat(format, nil); err == nil { + if _, err := ParseFormat(format); err == nil { t.Errorf("ParseFormat(%q) = nil error, want one", format) } } diff --git a/internal/grammar/path_test.go b/internal/grammar/path_test.go index 5ea21ae..6dad65e 100644 --- a/internal/grammar/path_test.go +++ b/internal/grammar/path_test.go @@ -38,3 +38,14 @@ func TestNameSegmentsDropSelectorsAndStepsUp(t *testing.T) { t.Errorf("NameSegments = %q, want [a c]", got) } } + +func TestCheckSegmentsRefusesAnEmptySegment(t *testing.T) { + for _, segs := range [][]string{{""}, {"a", ""}, {"", "a"}, {"a", "", "b"}} { + if CheckSegments(segs) == nil { + t.Errorf("CheckSegments(%q) = nil, want an error", segs) + } + } + if err := CheckSegments([]string{"a", "[b]", "..", "c"}); err != nil { + t.Errorf("CheckSegments = %v, want nil", err) + } +} diff --git a/table_test.go b/table_test.go index 09b6c8d..6f850bc 100644 --- a/table_test.go +++ b/table_test.go @@ -318,6 +318,7 @@ func TestTableStepUpRefusals(t *testing.T) { "locality[L4]..municipality[0180]": "municipality[0180]", "locality[L4]..region": "..municipality..region", "locality[L4]...municipality": "empty segment", + "locality[L4]..municipality.": "empty segment", "locality[L4].municipality.name": "..municipality.name", "locality[L4].name..municipality": "column", "x..y": "only from a table's row",