-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain_test.go
More file actions
131 lines (117 loc) · 3.48 KB
/
main_test.go
File metadata and controls
131 lines (117 loc) · 3.48 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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package main
import (
"io"
"os"
"strings"
"testing"
)
// captureOutput redirects os.Stdout and os.Stderr, runs fn, then restores them.
// Returns captured stdout and stderr as strings.
func captureOutput(fn func()) (stdout, stderr string) {
oldStdout := os.Stdout
rOut, wOut, _ := os.Pipe()
os.Stdout = wOut
oldStderr := os.Stderr
rErr, wErr, _ := os.Pipe()
os.Stderr = wErr
fn()
wOut.Close()
wErr.Close()
outBytes, _ := io.ReadAll(rOut)
errBytes, _ := io.ReadAll(rErr)
os.Stdout = oldStdout
os.Stderr = oldStderr
return string(outBytes), string(errBytes)
}
func TestRoute_Version(t *testing.T) {
for _, flag := range []string{"--version", "-version", "-V"} {
t.Run(flag, func(t *testing.T) {
var code int
stdout, stderr := captureOutput(func() {
code = route([]string{flag}, "1.2.3", nil)
})
if code != 0 {
t.Errorf("expected exit 0, got %d", code)
}
if !strings.Contains(stdout, "lorah 1.2.3") {
t.Errorf("expected %q in stdout, got %q", "lorah 1.2.3", stdout)
}
if stderr != "" {
t.Errorf("expected empty stderr, got %q", stderr)
}
})
}
}
// TestRoute_Help verifies that --help prints usage to stdout per UNIX
// convention (an explicit documentation request is not an error).
func TestRoute_Help(t *testing.T) {
for _, flag := range []string{"--help", "-help", "-h"} {
t.Run(flag, func(t *testing.T) {
var code int
stdout, stderr := captureOutput(func() {
code = route([]string{flag}, "dev", nil)
})
if code != 0 {
t.Errorf("expected exit 0, got %d", code)
}
if !strings.Contains(stdout, "Usage:") {
t.Errorf("expected usage in stdout, got %q", stdout)
}
if stderr != "" {
t.Errorf("expected empty stderr, got %q", stderr)
}
})
}
}
// TestRoute_NoArgs verifies that no arguments prints usage to stderr and exits 1.
// This is distinct from --help which exits 0 (per loop.md §3).
func TestRoute_NoArgs(t *testing.T) {
var code int
_, stderr := captureOutput(func() {
code = route([]string{}, "dev", nil)
})
if code != 1 {
t.Errorf("expected exit 1, got %d", code)
}
if !strings.Contains(stderr, "Usage:") {
t.Errorf("expected usage in stderr, got %q", stderr)
}
}
// TestRoute_PromptFile verifies that a non-flag first argument is passed to
// runFn as the prompt file, with remaining args passed through as claude flags
// (loop.md §3 rule 5).
func TestRoute_PromptFile(t *testing.T) {
var calledFile string
var calledFlags []string
runFn := func(file string, flags []string) {
calledFile = file
calledFlags = flags
}
code := route([]string{"prompt.md", "--max-turns", "50"}, "dev", runFn)
if code != 0 {
t.Errorf("expected exit 0, got %d", code)
}
if calledFile != "prompt.md" {
t.Errorf("expected prompt file %q, got %q", "prompt.md", calledFile)
}
if len(calledFlags) != 2 || calledFlags[0] != "--max-turns" || calledFlags[1] != "50" {
t.Errorf("unexpected flags: %v", calledFlags)
}
}
// TestRoute_UnknownFlag verifies that a leading unknown flag is rejected with
// a helpful error rather than being treated as a prompt file (loop.md §3 rule 4).
func TestRoute_UnknownFlag(t *testing.T) {
var code int
_, stderr := captureOutput(func() {
code = route([]string{"--nope"}, "dev", nil)
})
if code != 1 {
t.Errorf("expected exit 1, got %d", code)
}
if !strings.Contains(stderr, "Unknown flag: --nope") {
t.Errorf("expected %q in stderr, got %q", "Unknown flag: --nope", stderr)
}
if !strings.Contains(stderr, "Usage:") {
t.Errorf("expected usage in stderr, got %q", stderr)
}
}