Add inline templates to the CLI and library #4
+33
-12
@@ -301,21 +301,34 @@ func TestRunShippedDataByDefault(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIsTemplate(t *testing.T) {
|
func TestClassify(t *testing.T) {
|
||||||
for arg, want := range map[string]bool{
|
for arg, want := range map[string]argKind{
|
||||||
"sv_SE.person": false,
|
"sv_SE.person": argPath,
|
||||||
"person.last": false,
|
"person.last": argPath,
|
||||||
"[abc]": false, // a [ that is not valid JSON is not a template
|
`"abc`: argPath, // a quote opening no JSON string is part of a name
|
||||||
"[abc].field": false,
|
"name: {x}": argTemplate, // a { token: a path can never carry a brace
|
||||||
"name: {x}": true, // a { token: a path can never carry a brace
|
`{"format":"x"}`: argTemplate,
|
||||||
`{"format":"x"}`: true,
|
`["a","b"]`: argTemplate, // a JSON array carries no brace
|
||||||
`["a","b"]`: true, // a JSON array carries no brace
|
`[1, 2]`: argTemplate,
|
||||||
`[1, 2]`: true,
|
`"hello"`: argTemplate, // a JSON string, the spelling a format-only object names
|
||||||
} {
|
} {
|
||||||
if got := isTemplate(arg); got != want {
|
got, err := classify(arg)
|
||||||
t.Errorf("isTemplate(%q) = %v, want %v", arg, got, want)
|
if err != nil || got != want {
|
||||||
|
t.Errorf("classify(%q) = %v, %v; want %v", arg, got, err, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for _, arg := range []string{"[abc]", "[abc].field", "x[1]", "a]b"} {
|
||||||
|
if _, err := classify(arg); err == nil {
|
||||||
|
t.Errorf("classify(%q) = no error; want the bracket rejected", arg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRunShapeMisuseBeforeLoad(t *testing.T) {
|
||||||
|
code, _, errb := runOut("--no-shipped-data", "[abc]")
|
||||||
|
if code != 2 || !strings.Contains(errb, "[abc]") || strings.Contains(errb, "--data-path") {
|
||||||
|
t.Fatalf("shape misuse with no data = %d, %q; want the shape error before any load", code, errb)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRunInlineTemplate(t *testing.T) {
|
func TestRunInlineTemplate(t *testing.T) {
|
||||||
@@ -327,6 +340,10 @@ func TestRunInlineTemplate(t *testing.T) {
|
|||||||
if code != 0 || (out != "name: bosse\n" && out != "name: lina\n") {
|
if code != 0 || (out != "name: bosse\n" && out != "name: lina\n") {
|
||||||
t.Fatalf("inline JSON template = %d, %q, want one name, stderr %q", code, out, errb)
|
t.Fatalf("inline JSON template = %d, %q, want one name, stderr %q", code, out, errb)
|
||||||
}
|
}
|
||||||
|
code, out, errb = runOut("--seed", "1", `"name: {/sv_SE.person.last}"`)
|
||||||
|
if code != 0 || !strings.HasPrefix(out, "name: ") || strings.Contains(out, "{") {
|
||||||
|
t.Fatalf("inline JSON string = %d, %q, stderr %q", code, out, errb)
|
||||||
|
}
|
||||||
code, out, errb = runOut("--seed", "1", "-n", "2", `{digits(1)}`)
|
code, out, errb = runOut("--seed", "1", "-n", "2", `{digits(1)}`)
|
||||||
if code != 0 || len(strings.Split(strings.TrimRight(out, "\n"), "\n")) != 2 {
|
if code != 0 || len(strings.Split(strings.TrimRight(out, "\n"), "\n")) != 2 {
|
||||||
t.Fatalf("inline template with --repeat = %d, %q, stderr %q", code, out, errb)
|
t.Fatalf("inline template with --repeat = %d, %q, stderr %q", code, out, errb)
|
||||||
@@ -339,11 +356,15 @@ func TestRunTemplateMisuse(t *testing.T) {
|
|||||||
"[red,green]", // a near-miss JSON array (unquoted strings)
|
"[red,green]", // a near-miss JSON array (unquoted strings)
|
||||||
`{"format":"x"}`, // an object holding only a format
|
`{"format":"x"}`, // an object holding only a format
|
||||||
"{/no.such.path}", // a reference into nothing
|
"{/no.such.path}", // a reference into nothing
|
||||||
|
"x[1]", // a bracket no path may hold
|
||||||
} {
|
} {
|
||||||
code, out, errb := runOut("--seed", "1", arg)
|
code, out, errb := runOut("--seed", "1", arg)
|
||||||
if code != 2 || out != "" || !strings.Contains(errb, "try 'fejkdata --help'") {
|
if code != 2 || out != "" || !strings.Contains(errb, "try 'fejkdata --help'") {
|
||||||
t.Errorf("run(%q) = %d, %q, %q; want misuse naming --help", arg, code, out, errb)
|
t.Errorf("run(%q) = %d, %q, %q; want misuse naming --help", arg, code, out, errb)
|
||||||
}
|
}
|
||||||
|
if strings.Contains(errb, "fejkdata: fejkdata:") {
|
||||||
|
t.Errorf("run(%q) doubled the program prefix: %q", arg, errb)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ func TestFakeTemplateErrors(t *testing.T) {
|
|||||||
{`"{x}"`, `no field "x"`},
|
{`"{x}"`, `no field "x"`},
|
||||||
{`"{digits(0)}"`, "must be positive"},
|
{`"{digits(0)}"`, "must be positive"},
|
||||||
{`name: {/no.such.path}`, "no entry"},
|
{`name: {/no.such.path}`, "no entry"},
|
||||||
{`name: {..nope}`, "no folder above"},
|
{`name: {..nope}`, "write {/nope}"},
|
||||||
{`{"format":"x"}`, "is a string"},
|
{`{"format":"x"}`, "is a string"},
|
||||||
{`{/misc.country} {/misc.country.alpha2}`, "renders a level"},
|
{`{/misc.country} {/misc.country.alpha2}`, "renders a level"},
|
||||||
} {
|
} {
|
||||||
@@ -105,6 +105,23 @@ func TestFakeTemplateErrors(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFakeTemplateJSONString(t *testing.T) {
|
||||||
|
f := shipped(t)
|
||||||
|
got := tmpl(t, f, `"name: {/sv_SE.person.last}"`)
|
||||||
|
if !strings.HasPrefix(got, "name: ") || strings.Contains(got, "{") {
|
||||||
|
t.Fatalf("FakeTemplate(JSON string) = %q, want a rendered last name after the prefix", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPaddedJSONIsRejected(t *testing.T) {
|
||||||
|
f := shipped(t)
|
||||||
|
in := `{"format":"{x}","x":["a","b"]}`
|
||||||
|
_, err := f.NewTemplate(" " + in + " ")
|
||||||
|
if err == nil || !strings.Contains(err.Error(), "write "+in) {
|
||||||
|
t.Fatalf("NewTemplate(padded JSON) = %v, want an error naming the unpadded spelling", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestNewTemplateReusable(t *testing.T) {
|
func TestNewTemplateReusable(t *testing.T) {
|
||||||
f := shipped(t)
|
f := shipped(t)
|
||||||
tmpl, err := f.NewTemplate(`{digits(2)}`)
|
tmpl, err := f.NewTemplate(`{digits(2)}`)
|
||||||
+4
-2
@@ -275,8 +275,6 @@ func TestNewErrors(t *testing.T) {
|
|||||||
map[string]string{"a|b": `"1"`},
|
map[string]string{"a|b": `"1"`},
|
||||||
`category "a|b" contains "|"`,
|
`category "a|b" contains "|"`,
|
||||||
},
|
},
|
||||||
// A bracket is not a token-grammar character, but the CLI reads an argument
|
|
||||||
// starting with [ as a JSON array, so a name carrying one would be misread.
|
|
||||||
"field name with a bracket": {
|
"field name with a bracket": {
|
||||||
map[string]string{"a": `{"format":"{x}","x":"1","b[c":"2"}`},
|
map[string]string{"a": `{"format":"{x}","x":"1","b[c":"2"}`},
|
||||||
`field "b[c" contains "["`,
|
`field "b[c" contains "["`,
|
||||||
@@ -285,6 +283,10 @@ func TestNewErrors(t *testing.T) {
|
|||||||
map[string]string{"[abc]": `"1"`},
|
map[string]string{"[abc]": `"1"`},
|
||||||
`category "[abc]" contains "["`,
|
`category "[abc]" contains "["`,
|
||||||
},
|
},
|
||||||
|
"field name with a quote": {
|
||||||
|
map[string]string{"a": `{"format":"{x}","x":"1","b\"c":"2"}`},
|
||||||
|
`field "b\"c" contains "\""`,
|
||||||
|
},
|
||||||
// An empty name is not a path segment, so List never offered it — while a
|
// An empty name is not a path segment, so List never offered it — while a
|
||||||
// bare {}, a trailing dot in Fake("a.") and a {/a.} reference all reached
|
// bare {}, a trailing dot in Fake("a.") and a {/a.} reference all reached
|
||||||
// it. The engine accepted spellings it would never advertise.
|
// it. The engine accepted spellings it would never advertise.
|
||||||
|
|||||||
@@ -47,3 +47,13 @@ func TestInertObjectIsRejected(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestInlineFolderSigilsAreRejected(t *testing.T) {
|
||||||
|
f := shipped(t)
|
||||||
|
for _, input := range []string{"{.sv_SE.person.last}", "{..sv_SE.person.last}"} {
|
||||||
|
_, err := f.NewTemplate(input)
|
||||||
|
if err == nil || !strings.Contains(err.Error(), "write {/sv_SE.person.last}") {
|
||||||
|
t.Errorf("NewTemplate(%q) = %v, want an error naming the root spelling", input, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user