//go:build windows package engine import ( "errors" "path/filepath" "strings" "testing" ) func TestWindowsSearchRejectsReservedComponentsBeforeAcquisition(t *testing.T) { t.Parallel() root := t.TempDir() first := writeImportFile(t, root, "first.yml", "value: first\n") for _, name := range []string{"CONIN$", "CONOUT$"} { for _, source := range []Source{ SearchConfig(name, Searches(Paths(first), WorkingDirectory())), SearchConfig("", Searches(Paths(first), SearchDirectory(root, DirectorySearchOptions{ Filenames: []FilenameGroup{CustomFilenames(name)}, }))), } { result, err := testLoad[discoveryLoadConfig](source, Options[discoveryLoadConfig]{}) var failure *LoadError if result != nil || !errors.As(err, &failure) || len(failure.Diagnostics()) != 1 || failure.Diagnostics()[0].Code != CodeOptionsInvalid { t.Fatalf("reserved component %q accepted: %#v, %v", name, result, err) } if len(failure.Sources()) != 0 { t.Fatalf("reserved component %q was checked after acquisition: %#v", name, failure.Sources()) } } } } func TestWindowsSearchPathsMatchHostAbsoluteResolution(t *testing.T) { root := t.TempDir() file := writeImportFile(t, root, "settings/config.yml", "value: selected\n") working := t.TempDir() t.Chdir(working) relative, err := filepath.Rel(working, file) if err != nil { t.Fatal(err) } volume := filepath.VolumeName(file) rooted := strings.TrimPrefix(file, volume) for _, entry := range []struct { name string path string }{ {"relative", relative}, {"drive root relative", rooted}, {"slash root relative", filepath.ToSlash(rooted)}, {"drive relative", volume + relative}, {"absolute", file}, } { t.Run(entry.name, func(t *testing.T) { want, err := filepath.Abs(entry.path) if err != nil { t.Fatal(err) } explicit, err := testLoad[discoveryLoadConfig](File(entry.path)) if err != nil { t.Fatal(err) } for _, search := range []Search{ Paths(entry.path), SearchDirectory(filepath.Dir(entry.path), DirectorySearchOptions{ Filenames: []FilenameGroup{CustomFilenames(filepath.Base(entry.path))}, }), } { iterator, diagnostics := newSearchCandidateIterator(search, "", discoveryDirectoryHelpers{}) if len(diagnostics) != 0 { t.Fatal(diagnostics) } candidate, ok, err := iterator.next() if err != nil || !ok || candidate != want { t.Fatalf("candidate = %q, %v, %v; want %q", candidate, ok, err, want) } result, err := testLoad[discoveryLoadConfig](SearchConfig("", search)) if err != nil || result.Config.Value != explicit.Config.Value { t.Fatalf("searched path = %#v, %v; explicit value %q", result, err, explicit.Config.Value) } sources := result.Sources() if len(sources) != 1 || sources[0].Path != explicit.Sources()[0].Path { t.Fatalf("searched source = %#v; explicit source %#v", sources, explicit.Sources()) } } }) } }