package cli import ( "bytes" "os" "path/filepath" "strconv" "strings" "testing" configkit "gitea.maximumdirect.net/eric/ConfigKit" ) func TestConfigLoadDiagnosticsIdentifyComposedSources(t *testing.T) { t.Parallel() for _, overlay := range []bool{false, true} { t.Run(strconv.FormatBool(overlay), func(t *testing.T) { root := t.TempDir() main := filepath.Join(root, "config.yml") fragment := filepath.Join(root, "pipeline\n\x1b.yml") args := []string{"config", "validate", "--config", main} if overlay { fragment = filepath.Join(root, "overlays", "development.yml") writeConfigKitFile(t, main, "version: 5\n") args = append(args, "--config-overlay", "development") } else { writeConfigKitFile(t, main, "version: 5\nconfigkit:\n imports:\n - path: "+strconv.Quote(filepath.Base(fragment))+"\n") } writeConfigKitFile(t, fragment, "concurrency: {total_llm: invalid-private-value}\n") var stdout, stderr bytes.Buffer if code := RunWithOptions(args, &stdout, &stderr, commandContractOptions(t)); code != 1 { t.Fatalf("status = %d; %s", code, stderr.String()) } got := stderr.String() if stdout.Len() != 0 || !strings.Contains(got, "decode.type") || !strings.Contains(got, "source-2:1:") || !strings.Contains(got, strconv.Quote(fragment)) || strings.Contains(got, "invalid-private-value") || strings.ContainsRune(got, '\x1b') { t.Fatalf("stdout = %q; stderr = %q", stdout.String(), got) } }) } } func TestLoadConfigKitUsesDiscoveryOverlayAndOverrides(t *testing.T) { t.Parallel() root := t.TempDir() path := filepath.Join(root, "notarius.yml") writeConfigKitFile(t, path, "version: 5\npipelines:\n base:\n input: {module: input}\n") overlays := filepath.Join(root, "overlays") writeConfigKitFile(t, filepath.Join(overlays, "development.yml"), "pipelines:\n overlaid:\n input: {module: input}\n") loaded, gotPath, err := loadConfigKit(path, "development", []configkit.Override{{Path: configkit.Keys("output", "directory"), Value: "generated", Flag: "--output"}}, commandContractOptions(t)) if err != nil { t.Fatalf("loadConfigKit() error = %v", err) } if gotPath != path || loaded.Config.Pipelines["overlaid"].Input.Module != "input" || loaded.Config.Output.Directory == "generated" { t.Fatalf("loaded = %#v, path=%q", loaded.Config, gotPath) } } func TestWriteConfigLoadErrorUsesSafeDiagnostics(t *testing.T) { t.Parallel() path := filepath.Join(t.TempDir(), "invalid.yml") writeConfigKitFile(t, path, "version: 4\n") _, _, err := loadConfigKit(path, "", nil, commandContractOptions(t)) if err == nil { t.Fatal("loadConfigKit() error = nil") } var output bytes.Buffer writeConfigLoadError(&output, err) if !strings.Contains(output.String(), "version") || strings.Contains(output.String(), "notarius: configkit") { t.Fatalf("diagnostics = %q", output.String()) } } func writeConfigKitFile(t *testing.T, path, contents string) { t.Helper() if err := os.MkdirAll(filepath.Dir(path), 0o700); err != nil { t.Fatal(err) } if err := os.WriteFile(path, []byte(contents), 0o600); err != nil { t.Fatal(err) } }