-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathmain_test.go
More file actions
94 lines (84 loc) · 2.65 KB
/
Copy pathmain_test.go
File metadata and controls
94 lines (84 loc) · 2.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package main
import (
"io"
"os"
"strings"
"testing"
)
func TestRunMainExitCodes(t *testing.T) {
t.Setenv("HOME", t.TempDir()) // no user config, no user chroma path
tests := []struct {
name string
args []string
want int
}{
{"usage error", []string{"--bogus-flag"}, exitUsage},
{"missing query", []string{"search"}, exitUsage}, // missing query is a usage error
{"missing vault", []string{"ingest"}, exitUsage}, // missing --vault-path is a usage error
{"bad log level", []string{"search", "q", "--log-level=verbose"}, exitUsage},
{"version subcommand", []string{"version"}, exitOK},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := runMain(tt.args); got != tt.want {
t.Errorf("runMain(%v) = %d, want %d", tt.args, got, tt.want)
}
})
}
}
func TestPanicRecovery(t *testing.T) {
code := 0
func() {
defer recoverMain(&code)
panic("boom")
}()
if code != exitError {
t.Errorf("panic recovery exit code = %d, want %d", code, exitError)
}
}
// captureRunMain runs runMain while capturing stdout and stderr.
func captureRunMain(t *testing.T, args []string) (code int, stdout, stderr string) {
t.Helper()
oldOut, oldErr := os.Stdout, os.Stderr
or, ow, err := os.Pipe()
if err != nil {
t.Fatal(err)
}
er, ew, err := os.Pipe()
if err != nil {
t.Fatal(err)
}
os.Stdout, os.Stderr = ow, ew
code = runMain(args)
os.Stdout, os.Stderr = oldOut, oldErr
_ = ow.Close()
_ = ew.Close()
out, _ := io.ReadAll(or)
errd, _ := io.ReadAll(er)
return code, string(out), string(errd)
}
// TestRunMainJSONModeSingleErrorLine verifies that --format json failures
// emit exactly one error representation: the {"error": ...} envelope on
// stdout, with no duplicate "Error:" line on stderr. A temp chroma path is
// used so the run fails fast on an empty database (the chroma-go shim cache
// in the real HOME is still resolved).
func TestRunMainJSONModeSingleErrorLine(t *testing.T) {
args := []string{"get", "nonexistent-note", "--chroma-path", t.TempDir(), "--format", "json"}
code, stdout, stderr := captureRunMain(t, args)
if code != exitError {
t.Errorf("exit code = %d, want %d", code, exitError)
}
if !strings.Contains(stdout, `{"error":`) {
t.Errorf("expected JSON error envelope on stdout, got: %s", stdout)
}
if strings.Contains(stderr, "Error:") {
t.Errorf("JSON mode must not duplicate the error on stderr, got: %s", stderr)
}
}
func TestRunMainTextModeStderrError(t *testing.T) {
args := []string{"get", "nonexistent-note", "--chroma-path", t.TempDir()}
_, _, stderr := captureRunMain(t, args)
if !strings.Contains(stderr, "Error:") {
t.Errorf("text mode must print the error on stderr, got: %s", stderr)
}
}