153 lines
6.0 KiB
Go
153 lines
6.0 KiB
Go
package engine
|
|
|
|
import (
|
|
"runtime"
|
|
"testing"
|
|
)
|
|
|
|
func TestSearchDescriptionEmptyAndSlugRequirements(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
if diagnostics := validateSearch(Search{}, ""); len(diagnostics) != 0 {
|
|
t.Fatalf("zero search diagnostics = %#v", diagnostics)
|
|
}
|
|
if diagnostics := validateSearch(Searches(), ""); len(diagnostics) != 0 {
|
|
t.Fatalf("empty concatenation diagnostics = %#v", diagnostics)
|
|
}
|
|
if diagnostics := validateSearch(Paths(), ""); len(diagnostics) != 0 {
|
|
t.Fatalf("empty path list diagnostics = %#v", diagnostics)
|
|
}
|
|
if diagnostics := validateSearch(Paths("relative/config.yml"), ""); len(diagnostics) != 0 {
|
|
t.Fatalf("literal path unexpectedly requires a slug: %#v", diagnostics)
|
|
}
|
|
generic := SearchDirectory("configs", DirectorySearchOptions{Filenames: []FilenameGroup{GenericFilenames()}})
|
|
if diagnostics := validateSearch(generic, ""); len(diagnostics) != 0 {
|
|
t.Fatalf("generic-only directory unexpectedly requires a slug: %#v", diagnostics)
|
|
}
|
|
if diagnostics := validateSearch(SearchDirectory("configs"), ""); len(diagnostics) == 0 || diagnostics[0].Code != CodeOptionsInvalid {
|
|
t.Fatalf("default named directory accepted an empty slug: %#v", diagnostics)
|
|
}
|
|
if diagnostics := validateSearch(UnixSystemDirectories(), "myapp"); len(diagnostics) != 0 {
|
|
t.Fatalf("valid preset slug diagnostics = %#v", diagnostics)
|
|
}
|
|
}
|
|
|
|
func TestSearchDescriptionSnapshotsInputs(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
paths := []string{"first.yml", "second.yml"}
|
|
pathSearch := Paths(paths...)
|
|
paths[0] = "changed.yml"
|
|
|
|
customNames := []string{"one.yml", "two.yml"}
|
|
group := CustomFilenames(customNames...)
|
|
customNames[0] = "changed.yml"
|
|
groups := []FilenameGroup{group}
|
|
options := DirectorySearchOptions{Filenames: groups}
|
|
directorySearch := SearchDirectory("configs", options)
|
|
groups[0] = GenericFilenames()
|
|
options.Filenames[0] = NamedFilenames()
|
|
|
|
searches := []Search{pathSearch, directorySearch}
|
|
combined := Searches(searches...)
|
|
searches[0] = Search{}
|
|
|
|
if got := combined.entries[0].path; got != "first.yml" {
|
|
t.Fatalf("snapshotted path = %q", got)
|
|
}
|
|
gotNames := combined.entries[2].filenames[0].names
|
|
if len(gotNames) != 2 || gotNames[0] != "one.yml" || gotNames[1] != "two.yml" {
|
|
t.Fatalf("snapshotted custom names = %#v", gotNames)
|
|
}
|
|
if diagnostics := validateSearch(combined, ""); len(diagnostics) != 0 {
|
|
t.Fatalf("snapshot description diagnostics = %#v", diagnostics)
|
|
}
|
|
}
|
|
|
|
func TestDirectoryFilenameDefaultsAndExplicitEmpty(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
omitted := SearchDirectory("configs")
|
|
if len(omitted.entries) != 1 || len(omitted.entries[0].filenames) != 2 || omitted.entries[0].filenames[0].kind != filenameGroupNamed || omitted.entries[0].filenames[1].kind != filenameGroupGeneric {
|
|
t.Fatalf("omitted groups = %#v", omitted.entries)
|
|
}
|
|
explicitNil := SearchDirectory("configs", DirectorySearchOptions{})
|
|
if len(explicitNil.entries[0].filenames) != 2 {
|
|
t.Fatalf("nil filename selection did not use defaults: %#v", explicitNil.entries[0].filenames)
|
|
}
|
|
explicitEmpty := SearchDirectory("configs", DirectorySearchOptions{Filenames: []FilenameGroup{}})
|
|
if explicitEmpty.entries[0].filenames == nil || len(explicitEmpty.entries[0].filenames) != 0 {
|
|
t.Fatalf("explicit empty selection lost its distinction: %#v", explicitEmpty.entries[0].filenames)
|
|
}
|
|
if len(validateSearch(explicitEmpty, "")) != 0 {
|
|
t.Fatal("explicit empty filename selection should need no slug")
|
|
}
|
|
}
|
|
|
|
func TestSearchDescriptionArityAndErrorConcatenation(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tooMany := SearchDirectory("configs", DirectorySearchOptions{}, DirectorySearchOptions{})
|
|
if diagnostics := validateSearch(tooMany, "app"); len(diagnostics) == 0 {
|
|
t.Fatal("multiple option values should be invalid")
|
|
}
|
|
invalid := Paths("")
|
|
combined := Searches(Paths("good.yml"), invalid)
|
|
if diagnostics := validateSearch(combined, ""); len(diagnostics) == 0 {
|
|
t.Fatal("concatenation lost a constructor error")
|
|
}
|
|
if diagnostics := validateSearch(Paths("good.yml", ""), ""); len(diagnostics) == 0 {
|
|
t.Fatal("later invalid path was hidden by an earlier component")
|
|
}
|
|
}
|
|
|
|
func TestSearchDescriptionPreservesFilenameGroupOrder(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
groups := []FilenameGroup{GenericFilenames(), NamedFilenames(), CustomFilenames("override.yml")}
|
|
search := SearchDirectory("configs", DirectorySearchOptions{Filenames: groups})
|
|
got := search.entries[0].filenames
|
|
if len(got) != 3 || got[0].kind != filenameGroupGeneric || got[1].kind != filenameGroupNamed || got[2].names[0] != "override.yml" {
|
|
t.Fatalf("filename group order = %#v", got)
|
|
}
|
|
if got := SearchDirectory("configs", DirectorySearchOptions{Filenames: []FilenameGroup{CustomFilenames()}}).entries[0].filenames[0].names; len(got) != 0 {
|
|
t.Fatalf("empty custom group = %#v", got)
|
|
}
|
|
}
|
|
|
|
func TestFilenameComponentValidation(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
for _, value := range []string{"", ".", "..", "nested/name", "bad\x00name"} {
|
|
if validFilenameComponent(value) {
|
|
t.Errorf("validFilenameComponent(%q) = true", value)
|
|
}
|
|
}
|
|
if runtime.GOOS == "windows" {
|
|
for _, value := range []string{"CON", "nul.txt", "name.", "bad:name"} {
|
|
if validFilenameComponent(value) {
|
|
t.Errorf("Windows component %q unexpectedly accepted", value)
|
|
}
|
|
}
|
|
} else {
|
|
for _, value := range []string{"name with spaces", "naïve"} {
|
|
if !validFilenameComponent(value) {
|
|
t.Errorf("host-valid component %q rejected", value)
|
|
}
|
|
}
|
|
}
|
|
if diagnostics := validateSearch(SearchDirectory("configs", DirectorySearchOptions{Filenames: []FilenameGroup{CustomFilenames("bad/name")}}), ""); len(diagnostics) == 0 {
|
|
t.Fatal("invalid custom filename was not retained for validation")
|
|
}
|
|
for _, value := range []string{"CON", "nul.txt", "COM¹.log", "LPT³.txt", "name.", "bad:name", "bad\x01name"} {
|
|
if validWindowsFilenameComponent(value) {
|
|
t.Errorf("Windows component %q unexpectedly accepted", value)
|
|
}
|
|
}
|
|
for _, value := range []string{"name with spaces", "naïve"} {
|
|
if !validWindowsFilenameComponent(value) {
|
|
t.Errorf("valid Windows component %q rejected", value)
|
|
}
|
|
}
|
|
}
|