Tests for options that cannot take effect, and entries that are not data
This commit is contained in:
@@ -63,6 +63,72 @@ func TestNewErrors(t *testing.T) {
|
||||
if _, err := New([]string{writeData(t, map[string]string{"broken": `{ not json`})}); err == nil {
|
||||
t.Error("New(invalid JSON) = nil error")
|
||||
}
|
||||
// An option that cannot take effect, and a category or folder no dot path can
|
||||
// reach, are mistakes New must name rather than accept and ignore.
|
||||
rejected := map[string]struct {
|
||||
files map[string]string
|
||||
want string
|
||||
}{
|
||||
"separator without repeat": {
|
||||
map[string]string{"a": `{"format":"{x}","x":["1"],"separator":","}`},
|
||||
"has no effect without a repeat above 1",
|
||||
},
|
||||
"separator with an explicit repeat of 1": {
|
||||
map[string]string{"a": `{"format":"{x}","x":["1"],"repeat":1,"separator":","}`},
|
||||
"has no effect without a repeat above 1",
|
||||
},
|
||||
"weight outside a choice": {
|
||||
map[string]string{"a": `{"format":"x","weight":5}`},
|
||||
"weight only skews a choice's items",
|
||||
},
|
||||
"an option name used as a token": {
|
||||
map[string]string{"a": `{"format":"{weight}"}`},
|
||||
`"weight" is an option, never a field`,
|
||||
},
|
||||
"category name with a dot": {
|
||||
map[string]string{"a.b": `["1"]`},
|
||||
`category "a.b" contains a dot`,
|
||||
},
|
||||
"folder name with a dot": {
|
||||
map[string]string{"a.b/cat": `["1"]`},
|
||||
`/a.b: folder "a.b" contains a dot`,
|
||||
},
|
||||
}
|
||||
for name, c := range rejected {
|
||||
_, err := New([]string{writeData(t, c.files)})
|
||||
if err == nil {
|
||||
t.Errorf("%s: New = nil error, want it rejected at load", name)
|
||||
continue
|
||||
}
|
||||
if !strings.Contains(err.Error(), c.want) {
|
||||
t.Errorf("%s: New = %v, want it to mention %q", name, err, c.want)
|
||||
}
|
||||
}
|
||||
// Data that works today must keep working, and stay reachable.
|
||||
accepted := map[string]struct {
|
||||
files map[string]string
|
||||
path string
|
||||
want string
|
||||
}{
|
||||
"option name as a field": {map[string]string{"a": `{"format":"{name} {Weight}kg","name":["Anvil"],"Weight":["7"]}`}, "a", "Anvil 7kg"},
|
||||
"format spelling as a field": {map[string]string{"a": `{"format":"{Format}","Format":["PDF"]}`}, "a", "PDF"},
|
||||
"dotted field via its token": {map[string]string{"a": `{"format":"[{a.b}]","a.b":["V"]}`}, "a", "[V]"},
|
||||
"hyphenated field": {map[string]string{"a": `{"format":"{x-y}","x-y":["1"]}`}, "a.x-y", "1"},
|
||||
"category named Format": {map[string]string{"Format": `["1"]`}, "Format", "1"},
|
||||
"folder named Repeat": {map[string]string{"Repeat/cat": `["1"]`}, "Repeat.cat", "1"},
|
||||
"field with a paren": {map[string]string{"a": `{"format":"{x}","x":["1"],"b(c":["2"]}`}, "a.b(c", "2"},
|
||||
"repeat without a separator": {map[string]string{"a": `{"format":"{x}","repeat":3,"x":["1"]}`}, "a", "111"},
|
||||
}
|
||||
for name, c := range accepted {
|
||||
f, err := New([]string{writeData(t, c.files)})
|
||||
if err != nil {
|
||||
t.Errorf("%s: New = %v, want it accepted", name, err)
|
||||
continue
|
||||
}
|
||||
if got, err := f.Fake(c.path); err != nil || got != c.want {
|
||||
t.Errorf("%s: Fake(%q) = %q, %v, want %q", name, c.path, got, err, c.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- deep path navigation ---
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"slices"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -156,3 +157,27 @@ func TestListedPathsAllRender(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestHiddenEntriesAreSkipped keeps a data directory usable when it is also a
|
||||
// checkout or an editor workspace: a dot-prefixed entry is not data, and a folder
|
||||
// carrying no JSON never contributed a namespace, so neither may fail the load.
|
||||
func TestHiddenEntriesAreSkipped(t *testing.T) {
|
||||
dir := writeData(t, map[string]string{
|
||||
"cat": `["V"]`,
|
||||
".git/HEAD": `["ignored"]`,
|
||||
".hidden": `["ignored"]`,
|
||||
"empty.folder/doc": `["ignored"]`,
|
||||
})
|
||||
if err := os.Rename(filepath.Join(dir, "empty.folder", "doc.json"), filepath.Join(dir, "empty.folder", "doc.txt")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
f := newFakes(t, dir, WithSeed(1))
|
||||
if got := fake(t, f, "cat"); got != "V" {
|
||||
t.Fatalf("cat = %q, want V", got)
|
||||
}
|
||||
for _, p := range f.List() {
|
||||
if strings.HasPrefix(p, ".") || strings.Contains(p, "empty.folder") {
|
||||
t.Errorf("List() advertises %q, which is not data", p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user