package cli import ( "context" "io" "os" "path/filepath" "slices" "strings" "testing" commandkit "go.maximumdirect.net/commandkit" ck "go.maximumdirect.net/configkit" ) func TestQuietDestinationCheckPrecedesInputAcquisition(t *testing.T) { _, err := loadProcessInputs(context.Background(), processInput{Transcript: "missing.json"}, commandkit.ReportingModeQuiet) if err == nil || !strings.Contains(err.Error(), "/dev/null") { t.Fatalf("error=%v", err) } } func TestProcessAcquisitionCapturesConsumedFiles(t *testing.T) { dir := t.TempDir() for name, contents := range map[string]string{ "config.yml": "version: 3\npipeline:\n stages: []\n", "transcript.json": `[{"speaker":"Alice","start":0,"end":1,"text":"hello"}]`, "prompts.yml": "prompts:\n - id: extra\n messages:\n - role: user\n content_file: text.txt\n output:\n format: text\n validation_mode: none\n", "text.txt": "example", } { if err := os.WriteFile(filepath.Join(dir, name), []byte(contents), 0644); err != nil { t.Fatal(err) } } input := processInput{Config: commandkit.Supplied[string]{Value: filepath.Join(dir, "config.yml"), Set: true}, Transcript: filepath.Join(dir, "transcript.json")} result, err := loadProcessInputs(context.Background(), input, commandkit.ReportingModeOrdinary) if err != nil { t.Fatal(err) } for _, name := range []string{"config.yml", "prompts.yml", "text.txt"} { if !slices.Contains(result.ProtectedPaths, filepath.Join(dir, name)) { t.Errorf("missing %s in %v", name, result.ProtectedPaths) } } } func TestPrepareProcessInitializesReportsAndToleratesDebugLoss(t *testing.T) { dir := t.TempDir() for name, contents := range map[string]string{ "config.yml": "version: 3\npipeline:\n stages: []\n", "transcript.json": `[{"speaker":"Alice","start":0,"end":1,"text":"hello"}]`, "blocked": "not a directory", } { if err := os.WriteFile(filepath.Join(dir, name), []byte(contents), 0644); err != nil { t.Fatal(err) } } input := processInput{Config: commandkit.Supplied[string]{Value: filepath.Join(dir, "config.yml"), Set: true}, Transcript: filepath.Join(dir, "transcript.json"), Output: commandkit.Supplied[string]{Value: filepath.Join(dir, "output.json"), Set: true}, Debug: commandkit.Supplied[bool]{Value: true, Set: true}, Overrides: []ck.Override{{Path: ck.Keys("diagnostics", "work_dir"), Value: filepath.Join(dir, "blocked"), Flag: "--work-dir"}}} loaded, err := loadProcessInputs(context.Background(), input, commandkit.ReportingModeOrdinary) if err != nil { t.Fatal(err) } prepared, err := prepareProcess(context.Background(), input, loaded, io.Discard) if err != nil { t.Fatal(err) } defer prepared.Prepared.Output.Close() if len(prepared.Prepared.Warnings) == 0 { t.Fatal("debug loss was not reported") } report, err := os.ReadFile(filepath.Join(dir, "errors.yml")) if err != nil || !strings.Contains(string(report), "in_progress") { t.Fatalf("report=%q err=%v", report, err) } if _, err := os.Stat(input.Output.Value); !os.IsNotExist(err) { t.Fatalf("output published early: %v", err) } } func TestCollectionFlagJSON(t *testing.T) { for _, tc := range []struct { raw string valid bool null bool size int }{ {`["party","spells"]`, true, false, 2}, {`[]`, true, false, 0}, {`null`, true, true, 0}, {`"party"`, false, false, 0}, {`[1]`, false, false, 0}, {`["x"] true`, false, false, 0}, } { result, err := parseCollectionNames(tc.raw) if (err == nil) != tc.valid { t.Fatalf("%s error=%v", tc.raw, err) } if !tc.valid { continue } if tc.null { if result != nil { t.Fatalf("null=%v", result) } continue } list, ok := result.([]any) if !ok || len(list) != tc.size { t.Fatalf("%s result=%v", tc.raw, result) } } }