feat(env): add nestedUnderJQPath for extracting nested subtrees by jq-style paths

Introduce `nestedUnderJQPath`, enabling subtree extraction using jq-style path parsing. Add associated utility functions (`splitJQPath`, `peelRedundantPathLeaf`, `buildNestedTreeAtPath`) and test coverage. Extend `.env Codec` to support path-specific subtree merges. Update `WithFile` to accept an optional jqPath for targeted merges.
This commit is contained in:
2026-05-12 13:54:27 +01:00
parent 4beb769a2b
commit 719fccf712
5 changed files with 258 additions and 20 deletions
+69
View File
@@ -0,0 +1,69 @@
package env
import (
"reflect"
"testing"
)
func TestNestedUnderJQPath(t *testing.T) {
nested := map[string]any{
"noise": map[string]any{"x": "ignore"},
"service": map[string]any{
"name": "my-service",
"database": map[string]any{
"url": "postgres://db",
},
},
}
got := nestedUnderJQPath(nested, ".service")
want := map[string]any{
"name": "my-service",
"database": map[string]any{
"url": "postgres://db",
},
}
if !reflect.DeepEqual(got, want) {
t.Fatalf("got %#v want %#v", got, want)
}
}
func TestNestedUnderJQPath_EmptyPathNoop(t *testing.T) {
n := map[string]any{"a": "1"}
if got := nestedUnderJQPath(n, ""); !reflect.DeepEqual(got, n) {
t.Fatalf("%#v", got)
}
if got := nestedUnderJQPath(n, "."); !reflect.DeepEqual(got, n) {
t.Fatalf("%#v", got)
}
}
func TestNestedUnderJQPath_MissingPath(t *testing.T) {
got := nestedUnderJQPath(map[string]any{"other": "v"}, ".service")
if len(got) != 0 {
t.Fatalf("got %#v", got)
}
}
func TestNestedUnderJQPath_PeelsRedundantServiceWrapper(t *testing.T) {
nested := map[string]any{
"service": map[string]any{
"service": map[string]any{
"name": "inner",
},
},
}
got := nestedUnderJQPath(nested, ".service")
want := map[string]any{
"name": "inner",
}
if !reflect.DeepEqual(got, want) {
t.Fatalf("got %#v want %#v", got, want)
}
}
func TestNestedUnderJQPath_ScalarAtServiceIgnored(t *testing.T) {
got := nestedUnderJQPath(map[string]any{"service": "x"}, ".service")
if len(got) != 0 {
t.Fatalf("got %#v", got)
}
}