From 031a3ec7d6151f9f48dfe63709e497c01967c490 Mon Sep 17 00:00:00 2001 From: Lilleman auf Larv Date: Thu, 3 Sep 2026 17:40:29 +0200 Subject: [PATCH] Resolve architect findings: gate [ on json.Valid, fix the root-relative README claim, test isTemplate --- README.md | 7 ++++--- cmd/fejkdata/main.go | 8 +++++--- cmd/fejkdata/main_test.go | 17 +++++++++++++++++ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index eee42af..b1b5537 100644 --- a/README.md +++ b/README.md @@ -42,9 +42,10 @@ A path names a category, or a field inside one: each dot segment descends one level — folders, then the category (a JSON file), then fields. An argument that is a JSON object or array, or that carries a `{` token, is instead an **inline template**: a format string or a JSON value compiled and rendered on the spot. Its -tokens reach the data by reference — `{/sv_SE.person.last}` from the root, `{.name}` -and `{..name}` relative to it — so `--data-path` categories are available too. A -path never contains a brace, so the two cannot collide (see +tokens reach the data by reference from the root — `{/sv_SE.person.last}` (or +`{.name}`, which means the same here), so shipped and `--data-path` categories are +available — and `{..name}` is rejected, an inline template having no folder to step +up from. A path never contains a brace, so the two cannot collide (see [Decisions](#decisions)). | Flag | | diff --git a/cmd/fejkdata/main.go b/cmd/fejkdata/main.go index 07b5308..db1d277 100644 --- a/cmd/fejkdata/main.go +++ b/cmd/fejkdata/main.go @@ -9,6 +9,7 @@ package main import ( "bufio" + "encoding/json" "errors" "fmt" "io" @@ -243,13 +244,14 @@ func (in invocation) write(f *fejkdata.Generator, w io.Writer) error { } // isTemplate reports whether an argument is an inline template rather than a -// path: a JSON object or array, or a format string carrying a { token. A path can -// never contain a brace, so the two never collide. +// path: a format string carrying a { token (a path can never contain a brace), +// or a JSON object or array. A [ can begin a real category name, so a [ +// counts as a template only when the whole argument is valid JSON. func isTemplate(arg string) bool { if strings.ContainsRune(arg, '{') { return true } - return strings.HasPrefix(arg, "[") + return strings.HasPrefix(arg, "[") && json.Valid([]byte(arg)) } // renderArg renders one positional argument: an inline template, or a path. diff --git a/cmd/fejkdata/main_test.go b/cmd/fejkdata/main_test.go index f9615b5..b1995a0 100644 --- a/cmd/fejkdata/main_test.go +++ b/cmd/fejkdata/main_test.go @@ -301,6 +301,23 @@ func TestRunShippedDataByDefault(t *testing.T) { } } +func TestIsTemplate(t *testing.T) { + for arg, want := range map[string]bool{ + "sv_SE.person": false, + "person.last": false, + "[abc]": false, // a [ can open a real category name; not JSON + "[abc].field": false, + "name: {x}": true, // a { token: a path can never carry a brace + `{"format":"x"}`: true, + `["a","b"]`: true, // a JSON array carries no brace + `[1, 2]`: true, + } { + if got := isTemplate(arg); got != want { + t.Errorf("isTemplate(%q) = %v, want %v", arg, got, want) + } + } +} + func TestRunInlineTemplate(t *testing.T) { code, out, errb := runOut("--seed", "1", "name: {/sv_SE.person.last}") if code != 0 || !strings.HasPrefix(out, "name: ") || strings.Contains(out, "{") {