From c7a2ab8d02f98913a855ee408c3d726196e4eed4 Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Mon, 20 Apr 2026 16:05:07 +0200 Subject: [PATCH] test(kql): cover dotted keys in property restrictions Four cases covering the distinct grammar paths touched by the new Key rule: dotted key in a TextPropertyRestrictionNode, multi-level key (stressing the Kleene part), dotted key in a GroupNode (the k:Key? branch), and a dot on the value side that must stay a literal character. --- pkg/kql/dictionary_test.go | 55 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/pkg/kql/dictionary_test.go b/pkg/kql/dictionary_test.go index 169bd823d3..4736a5d3e3 100644 --- a/pkg/kql/dictionary_test.go +++ b/pkg/kql/dictionary_test.go @@ -916,6 +916,61 @@ func TestParse_Errors(t *testing.T) { } } +func TestParse_DottedKey(t *testing.T) { + tests := []testCase{ + // TextPropertyRestrictionNode with a dotted key. + { + name: `audio.artist:Motörhead`, + ast: &ast.Ast{ + Nodes: []ast.Node{ + &ast.StringNode{Key: "audio.artist", Value: "Motörhead"}, + }, + }, + }, + // Multi-level key exercises the ("." Char+)* kleene in the Key rule. + { + name: `foo.bar.baz:qux`, + ast: &ast.Ast{ + Nodes: []ast.Node{ + &ast.StringNode{Key: "foo.bar.baz", Value: "qux"}, + }, + }, + }, + // GroupNode also uses the Key rule via k:Key?. + { + name: `audio.artist:("Motörhead" OR Beatles)`, + ast: &ast.Ast{ + Nodes: []ast.Node{ + &ast.GroupNode{ + Key: "audio.artist", + Nodes: []ast.Node{ + &ast.StringNode{Value: "Motörhead"}, + &ast.OperatorNode{Value: kql.BoolOR}, + &ast.StringNode{Value: "Beatles"}, + }, + }, + }, + }, + }, + // A dot on the value side is still a literal character. + { + name: `name:foo.bar`, + ast: &ast.Ast{ + Nodes: []ast.Node{ + &ast.StringNode{Key: "name", Value: "foo.bar"}, + }, + }, + }, + } + + for _, tc := range tests { + tc := tc + t.Run(tc.name, func(t *testing.T) { + testKQL(t, tc) + }) + } +} + func TestParse_Stress(t *testing.T) { tests := []testCase{ {