Centralize effective config loading and path resolution

This commit is contained in:
2026-05-23 17:43:27 +00:00
parent 938bfe88c1
commit 13029dbb33
4 changed files with 341 additions and 138 deletions

View File

@@ -98,66 +98,6 @@ func TestRunProcessHelpListsExpectedFlags(t *testing.T) {
}
}
func TestResolveConfigPathDefaultIgnoredWhenMissing(t *testing.T) {
lookup := func(string) (string, bool) { return "", false }
path, source, err := resolveConfigPath("", false, lookup)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if path != "" || source != "" {
t.Fatalf("expected no config path/source, got path=%q source=%q", path, source)
}
}
func TestResolveConfigPathDefaultPrefersUsrLocalOverEtc(t *testing.T) {
oldStat := statConfigPath
statConfigPath = func(path string) (os.FileInfo, error) {
if path == config.DefaultConfigPathUsrLocal || path == config.DefaultConfigPath {
return nil, nil
}
return nil, os.ErrNotExist
}
t.Cleanup(func() { statConfigPath = oldStat })
lookup := func(string) (string, bool) { return "", false }
path, source, err := resolveConfigPath("", false, lookup)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if source != "default" {
t.Fatalf("expected default source, got %q", source)
}
if path != config.DefaultConfigPathUsrLocal {
t.Fatalf("expected %q, got %q", config.DefaultConfigPathUsrLocal, path)
}
}
func TestResolveConfigPathDefaultFallsBackToEtc(t *testing.T) {
oldStat := statConfigPath
statConfigPath = func(path string) (os.FileInfo, error) {
if path == config.DefaultConfigPathUsrLocal {
return nil, os.ErrNotExist
}
if path == config.DefaultConfigPath {
return nil, nil
}
return nil, os.ErrNotExist
}
t.Cleanup(func() { statConfigPath = oldStat })
lookup := func(string) (string, bool) { return "", false }
path, source, err := resolveConfigPath("", false, lookup)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if source != "default" {
t.Fatalf("expected default source, got %q", source)
}
if path != config.DefaultConfigPath {
t.Fatalf("expected %q, got %q", config.DefaultConfigPath, path)
}
}
func TestRunConfigValidateSuccess(t *testing.T) {
var stdout bytes.Buffer
var stderr bytes.Buffer
@@ -258,6 +198,45 @@ func TestRunConfigPrintEffectiveOutputsRedactedJSON(t *testing.T) {
}
}
func TestRunConfigPrintEffectiveAppliesFileThenEnvironment(t *testing.T) {
var stdout bytes.Buffer
var stderr bytes.Buffer
cfgPath := writeFile(t, "config.yml", "version: 1\nllm:\n proposal:\n model: file-model\n")
t.Setenv("AUDITA_MODEL", "env-model")
exitCode := Run([]string{"config", "print-effective", "--config", cfgPath}, &stdout, &stderr)
if exitCode != 0 {
t.Fatalf("expected success, got %d stderr=%q", exitCode, stderr.String())
}
var out struct {
PrimaryLLM struct {
Model string `json:"Model"`
} `json:"PrimaryLLM"`
}
if err := json.Unmarshal(stdout.Bytes(), &out); err != nil {
t.Fatalf("expected valid JSON output, got error: %v output=%q", err, stdout.String())
}
if out.PrimaryLLM.Model != "env-model" {
t.Fatalf("expected env model override in print-effective output, got %q", out.PrimaryLLM.Model)
}
}
func TestRunConfigValidateIgnoresEnvironmentOverrides(t *testing.T) {
var stdout bytes.Buffer
var stderr bytes.Buffer
cfgPath := writeFile(t, "config.yml", "version: 1\n")
t.Setenv("AUDITA_MODULES", "made_up")
exitCode := Run([]string{"config", "validate", "--config", cfgPath}, &stdout, &stderr)
if exitCode != 0 {
t.Fatalf("expected success because config validate is file-only, got %d stderr=%q", exitCode, stderr.String())
}
if !strings.Contains(stdout.String(), "config is valid") {
t.Fatalf("expected success message, got %q", stdout.String())
}
}
func TestRunConfigCommandDoesNotRequireTranscriptOrGlossary(t *testing.T) {
var stdout bytes.Buffer
var stderr bytes.Buffer