package cmd import ( "bytes" "os" "path/filepath" "strings" "testing" ) func TestQualityPassthroughScanArgs(t *testing.T) { logFile := setupFakeDesloppify(t) stdout, stderr, err := runRootCommand(t, "quality", "scan", "--path", ".") if err != nil { t.Fatalf("quality scan returned error: %v\nstderr:\n%s", err, stderr) } logged := readFileTrimmed(t, logFile) if logged != "scan --path ." { t.Fatalf("forwarded args = %q, want %q", logged, "scan --path .") } if !strings.Contains(stderr, desloppifyAttribution) { t.Fatalf("stderr missing attribution, got:\n%s", stderr) } if !strings.Contains(stdout, "fake stdout") { t.Fatalf("stdout missing fake tool output, got:\n%s", stdout) } } func TestQualityNoArgsForwardsHelp(t *testing.T) { logFile := setupFakeDesloppify(t) _, stderr, err := runRootCommand(t, "quality") if err != nil { t.Fatalf("quality returned error: %v\nstderr:\n%s", err, stderr) } logged := readFileTrimmed(t, logFile) if logged != "--help" { t.Fatalf("forwarded args = %q, want %q", logged, "--help") } } func TestReviewNoArgsRunsDefaultBatchFlow(t *testing.T) { logFile := setupFakeDesloppify(t) _, stderr, err := runRootCommand(t, "review") if err != nil { t.Fatalf("review returned error: %v\nstderr:\n%s", err, stderr) } logged := readFileTrimmed(t, logFile) want := "review --run-batches --runner codex --parallel --scan-after-import" if logged != want { t.Fatalf("forwarded args = %q, want %q", logged, want) } } func TestReviewForwardsArgs(t *testing.T) { logFile := setupFakeDesloppify(t) _, stderr, err := runRootCommand(t, "review", "--prepare") if err != nil { t.Fatalf("review --prepare returned error: %v\nstderr:\n%s", err, stderr) } logged := readFileTrimmed(t, logFile) if logged != "review --prepare" { t.Fatalf("forwarded args = %q, want %q", logged, "review --prepare") } } func TestMissingDesloppifyShowsInstallGuidance(t *testing.T) { t.Setenv("PATH", t.TempDir()) _, stderr, err := runRootCommand(t, "quality", "scan", "--path", ".") if err == nil { t.Fatal("expected error when desloppify is missing") } if !strings.Contains(stderr, "desloppify was not found in PATH") { t.Fatalf("stderr missing missing-binary guidance, got:\n%s", stderr) } if !strings.Contains(stderr, "pip install --upgrade \"desloppify[full]\"") { t.Fatalf("stderr missing install command, got:\n%s", stderr) } } func setupFakeDesloppify(t *testing.T) string { t.Helper() tmpDir := t.TempDir() logFile := filepath.Join(tmpDir, "args.log") scriptPath := filepath.Join(tmpDir, "desloppify") script := "#!/bin/sh\n" + "printf '%s\\n' \"$*\" > \"$DEVOUR_TEST_LOG\"\n" + "echo fake stdout\n" + "echo fake stderr 1>&2\n" + "exit 0\n" if err := os.WriteFile(scriptPath, []byte(script), 0755); err != nil { t.Fatalf("failed to write fake desloppify script: %v", err) } oldPath := os.Getenv("PATH") t.Setenv("PATH", tmpDir+string(os.PathListSeparator)+oldPath) t.Setenv("DEVOUR_TEST_LOG", logFile) return logFile } func runRootCommand(t *testing.T, args ...string) (string, string, error) { t.Helper() var outBuf bytes.Buffer var errBuf bytes.Buffer rootCmd.SetOut(&outBuf) rootCmd.SetErr(&errBuf) rootCmd.SetArgs(args) _, err := rootCmd.ExecuteC() return outBuf.String(), errBuf.String(), err } func readFileTrimmed(t *testing.T, path string) string { t.Helper() data, err := os.ReadFile(path) if err != nil { t.Fatalf("failed to read %s: %v", path, err) } return strings.TrimSpace(string(data)) }