-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathintegration_test.go
More file actions
271 lines (218 loc) · 8.19 KB
/
integration_test.go
File metadata and controls
271 lines (218 loc) · 8.19 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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
package main
import (
"os"
"os/exec"
"path/filepath"
"strings"
"testing"
)
// setupIntegrationTest creates a temporary directory and builds the CLI binary
func setupIntegrationTest(t *testing.T) (string, string) {
// Create temp directory
testDir, err := os.MkdirTemp("", "todo-integration-*")
if err != nil {
t.Fatalf("Failed to create temp dir: %v", err)
}
// Build the CLI binary
binaryPath := filepath.Join(testDir, "todo")
cmd := exec.Command("go", "build", "-o", binaryPath, ".")
if err := cmd.Run(); err != nil {
t.Fatalf("Failed to build CLI binary: %v", err)
}
// Change to test directory
originalDir, err := os.Getwd()
if err != nil {
t.Fatalf("Failed to get working directory: %v", err)
}
err = os.Chdir(testDir)
if err != nil {
t.Fatalf("Failed to change to test directory: %v", err)
}
// Initialize git repo for testing
exec.Command("git", "init").Run()
exec.Command("git", "config", "user.name", "Test User").Run()
exec.Command("git", "config", "user.email", "test@example.com").Run()
// Create initial commit
os.WriteFile("README.md", []byte("# Test repo"), 0644)
exec.Command("git", "add", "README.md").Run()
exec.Command("git", "commit", "-m", "Initial commit").Run()
// Setup cleanup
t.Cleanup(func() {
os.Chdir(originalDir)
os.RemoveAll(testDir)
})
return testDir, binaryPath
}
// runCLI executes the CLI binary with given arguments and returns stdout, stderr, and exit code
func runCLI(t *testing.T, binaryPath string, args ...string) (string, string, int) {
cmd := exec.Command(binaryPath, args...)
stdout, err := cmd.Output()
var stderr []byte
if exitError, ok := err.(*exec.ExitError); ok {
stderr = exitError.Stderr
return string(stdout), string(stderr), exitError.ExitCode()
} else if err != nil {
t.Fatalf("Failed to run CLI command: %v", err)
}
return string(stdout), "", 0
}
// runCLIWithInput executes the CLI binary with stdin input
func runCLIWithInput(t *testing.T, binaryPath string, input string, args ...string) (string, string, int) {
cmd := exec.Command(binaryPath, args...)
cmd.Stdin = strings.NewReader(input)
stdout, err := cmd.Output()
var stderr []byte
if exitError, ok := err.(*exec.ExitError); ok {
stderr = exitError.Stderr
return string(stdout), string(stderr), exitError.ExitCode()
} else if err != nil {
t.Fatalf("Failed to run CLI command with input: %v", err)
}
return string(stdout), "", 0
}
func TestListCommand(t *testing.T) {
_, binaryPath := setupIntegrationTest(t)
// Test creating a new list
stdout, stderr, exitCode := runCLIWithInput(t, binaryPath, "y\n", "list", "authentication")
if exitCode != 0 {
t.Fatalf("list command failed with exit code %d, stderr: %s", exitCode, stderr)
}
// Check that list was created and switched
if !strings.Contains(stdout, "Created and switched to list 'authentication'") {
t.Errorf("Expected list creation message, got: %s", stdout)
}
// Check that todo file was created
if !strings.Contains(stdout, "Initialized todo file: .todo/authentication.md") {
t.Errorf("Expected todo file creation message, got: %s", stdout)
}
// Verify the todo file exists
todoFile := ".todo/authentication.md"
if _, err := os.Stat(todoFile); os.IsNotExist(err) {
t.Error("Todo file was not created")
}
// Test switching to existing list
stdout, stderr, exitCode = runCLIWithInput(t, binaryPath, "y\n", "list", "authentication")
if exitCode != 0 {
t.Fatalf("list command failed for existing list with exit code %d, stderr: %s", exitCode, stderr)
}
if !strings.Contains(stdout, "Switched to existing list 'authentication'") {
t.Errorf("Expected list switch message, got: %s", stdout)
}
// Test showing all lists
stdout, stderr, exitCode = runCLI(t, binaryPath, "list")
if exitCode != 0 {
t.Fatalf("list command failed to show all lists with exit code %d, stderr: %s", exitCode, stderr)
}
if !strings.Contains(stdout, "Lists:") {
t.Errorf("Expected lists header, got: %s", stdout)
}
}
func TestAddCheckUncheckWorkflow(t *testing.T) {
_, binaryPath := setupIntegrationTest(t)
// Create a list
runCLIWithInput(t, binaryPath, "y\n", "list", "testing")
// Add some todo items
stdout, stderr, exitCode := runCLI(t, binaryPath, "add", "First todo item")
if exitCode != 0 {
t.Fatalf("add command failed with exit code %d, stderr: %s", exitCode, stderr)
}
if !strings.Contains(stdout, "Added todo item to feature 'testing': First todo item") {
t.Errorf("Expected add confirmation, got: %s", stdout)
}
runCLI(t, binaryPath, "add", "Second todo item")
// Check progress
stdout, stderr, exitCode = runCLI(t, binaryPath, "progress")
if exitCode != 0 {
t.Fatalf("progress command failed with exit code %d, stderr: %s", exitCode, stderr)
}
if !strings.Contains(stdout, "Progress: 0/2 completed") {
t.Errorf("Expected 0/2 progress, got: %s", stdout)
}
// Check off first item
stdout, stderr, exitCode = runCLI(t, binaryPath, "check", "1")
if exitCode != 0 {
t.Fatalf("check command failed with exit code %d, stderr: %s", exitCode, stderr)
}
if !strings.Contains(stdout, "Marked item 1 as completed") {
t.Errorf("Expected check confirmation, got: %s", stdout)
}
// Check progress again
stdout, stderr, exitCode = runCLI(t, binaryPath, "progress")
if exitCode != 0 {
t.Fatalf("progress command failed with exit code %d, stderr: %s", exitCode, stderr)
}
if !strings.Contains(stdout, "Progress: 1/2 completed") {
t.Errorf("Expected 1/2 progress, got: %s", stdout)
}
// Uncheck the item
stdout, stderr, exitCode = runCLI(t, binaryPath, "uncheck", "1")
if exitCode != 0 {
t.Fatalf("uncheck command failed with exit code %d, stderr: %s", exitCode, stderr)
}
if !strings.Contains(stdout, "Marked item 1 as not completed") {
t.Errorf("Expected uncheck confirmation, got: %s", stdout)
}
// Check progress is back to 0/2
stdout, stderr, exitCode = runCLI(t, binaryPath, "progress")
if exitCode != 0 {
t.Fatalf("progress command failed with exit code %d, stderr: %s", exitCode, stderr)
}
if !strings.Contains(stdout, "Progress: 0/2 completed") {
t.Errorf("Expected 0/2 progress after uncheck, got: %s", stdout)
}
}
func TestProgressCommandWithAll(t *testing.T) {
_, binaryPath := setupIntegrationTest(t)
// Create multiple lists with different progress
runCLIWithInput(t, binaryPath, "y\n", "list", "feature1")
runCLI(t, binaryPath, "add", "Feature 1 todo")
runCLI(t, binaryPath, "check", "1")
runCLIWithInput(t, binaryPath, "y\n", "list", "feature2")
runCLI(t, binaryPath, "add", "Feature 2 todo 1")
runCLI(t, binaryPath, "add", "Feature 2 todo 2")
// Leave both unchecked
// Test progress --all
stdout, stderr, exitCode := runCLI(t, binaryPath, "progress", "--all")
if exitCode != 0 {
t.Fatalf("progress --all command failed with exit code %d, stderr: %s", exitCode, stderr)
}
// Should show both features
if !strings.Contains(stdout, "feature1 - 1/1 completed (100%)") {
t.Errorf("Expected feature1 100%% complete, got: %s", stdout)
}
if !strings.Contains(stdout, "feature2 - 0/2 completed (0%)") {
t.Errorf("Expected feature2 0%% complete, got: %s", stdout)
}
// Test short flag
stdout, stderr, exitCode = runCLI(t, binaryPath, "progress", "-a")
if exitCode != 0 {
t.Fatalf("progress -a command failed with exit code %d, stderr: %s", exitCode, stderr)
}
if !strings.Contains(stdout, "Lists:") {
t.Errorf("Expected lists header, got: %s", stdout)
}
}
func TestVersionCommand(t *testing.T) {
_, binaryPath := setupIntegrationTest(t)
stdout, stderr, exitCode := runCLI(t, binaryPath, "version")
if exitCode != 0 {
t.Fatalf("version command failed with exit code %d, stderr: %s", exitCode, stderr)
}
if !strings.Contains(stdout, "todo CLI v0.1.0") {
t.Errorf("Expected version string, got: %s", stdout)
}
}
func TestHelpCommand(t *testing.T) {
_, binaryPath := setupIntegrationTest(t)
stdout, stderr, exitCode := runCLI(t, binaryPath, "--help")
if exitCode != 0 {
t.Fatalf("help command failed with exit code %d, stderr: %s", exitCode, stderr)
}
// Check for key commands
expectedCommands := []string{"list", "add", "check", "uncheck", "progress", "version"}
for _, cmd := range expectedCommands {
if !strings.Contains(stdout, cmd) {
t.Errorf("Expected to find command %s in help output, got: %s", cmd, stdout)
}
}
}