Skip to content

Commit 541d71e

Browse files
committed
[+] add tests (WIP)
1 parent 47ed7c3 commit 541d71e

File tree

16 files changed

+1637
-282
lines changed

16 files changed

+1637
-282
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Execute tasks from the plan
2+
3+
Execute tasks from the plan.
4+
5+
This is the fourth step in the Spec-Driven Development lifecycle.
6+
7+
Given the context provided as an argument, do this:
8+
9+
1. Run `scripts/check-task-prerequisites.sh --json` from repo root and parse FEATURE_DIR and AVAILABLE_DOCS list. All paths must be absolute.
10+
2. Load and analyze available design documents:
11+
- Always read plan.md for tech stack and libraries
12+
- Read tasks.md for existing tasks
13+
- IF EXISTS: Read data-model.md for entities
14+
- IF EXISTS: Read contracts/ for API endpoints
15+
- IF EXISTS: Read research.md for technical decisions
16+
- IF EXISTS: Read quickstart.md for test scenarios
17+
18+
Note: Not all projects have all documents. For example:
19+
- CLI tools might not have contracts/
20+
- Simple libraries might not need data-model.md
21+
22+
3. Implement tasks according to tasks.md and the context provided as an argument.
23+
24+
4. If several tasks specified for implementing, order tasks by dependencies:
25+
- Setup before everything
26+
- Tests before implementation (TDD)
27+
- Models before services
28+
- Services before endpoints
29+
- Core before integration
30+
- Everything before polish
31+
32+
Context for task implementation: $ARGUMENTS

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ build:
2020
## Run tests
2121
test:
2222
@echo "Running tests..."
23-
@go test -v -race -coverprofile=coverage.out ./...
23+
@go test -v -coverprofile=coverage.out ./...
2424

2525
## Run integration tests (requires PostgreSQL and etcd)
2626
test-integration:

cmd/etcd_fdw/cli_test.go

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
// Package main provides CLI testing for etcd_fdw command-line interface.
2+
package main
3+
4+
import (
5+
"os"
6+
"testing"
7+
8+
"github.com/stretchr/testify/assert"
9+
"github.com/stretchr/testify/require"
10+
)
11+
12+
// TestCLIParsing tests DSN parsing and flag validation for etcd_fdw CLI
13+
// This test MUST FAIL until CLI implementation is complete (TDD approach)
14+
func TestCLIParsing(t *testing.T) {
15+
tests := []struct {
16+
name string
17+
args []string
18+
wantErr bool
19+
errMsg string
20+
expected Config
21+
}{
22+
{
23+
name: "valid DSN and etcd DSN",
24+
args: []string{
25+
"--postgres-dsn", "postgres://user:pass@localhost:5432/db",
26+
"--etcd-dsn", "etcd://localhost:2379/",
27+
},
28+
wantErr: false,
29+
expected: Config{
30+
PostgresDSN: "postgres://user:pass@localhost:5432/db",
31+
EtcdDSN: "etcd://localhost:2379/",
32+
LogLevel: "info", // default value
33+
},
34+
},
35+
{
36+
name: "multiple etcd endpoints in DSN",
37+
args: []string{
38+
"--postgres-dsn", "postgres://user:pass@localhost:5432/db",
39+
"--etcd-dsn", "etcd://localhost:2379,localhost:2380,localhost:2381/",
40+
},
41+
wantErr: false,
42+
expected: Config{
43+
PostgresDSN: "postgres://user:pass@localhost:5432/db",
44+
EtcdDSN: "etcd://localhost:2379,localhost:2380,localhost:2381/",
45+
LogLevel: "info", // default value
46+
},
47+
},
48+
{
49+
name: "help flag",
50+
args: []string{"--help"},
51+
wantErr: false,
52+
expected: Config{
53+
Help: true,
54+
LogLevel: "info", // default value
55+
},
56+
},
57+
{
58+
name: "version flag",
59+
args: []string{"--version"},
60+
wantErr: false,
61+
expected: Config{
62+
Version: true,
63+
LogLevel: "info", // default value
64+
},
65+
},
66+
{
67+
name: "with log level and dry run",
68+
args: []string{
69+
"--postgres-dsn", "postgres://user:pass@localhost:5432/db",
70+
"--etcd-dsn", "etcd://localhost:2379/",
71+
"--log-level", "debug",
72+
"--dry-run",
73+
},
74+
wantErr: false,
75+
expected: Config{
76+
PostgresDSN: "postgres://user:pass@localhost:5432/db",
77+
EtcdDSN: "etcd://localhost:2379/",
78+
LogLevel: "debug",
79+
DryRun: true,
80+
},
81+
},
82+
{
83+
name: "etcd DSN with prefix and TLS params",
84+
args: []string{
85+
"--postgres-dsn", "postgres://user:pass@localhost:5432/db",
86+
"--etcd-dsn", "etcd://localhost:2379/config/?tls=enabled&dial_timeout=5s",
87+
},
88+
wantErr: false,
89+
expected: Config{
90+
PostgresDSN: "postgres://user:pass@localhost:5432/db",
91+
EtcdDSN: "etcd://localhost:2379/config/?tls=enabled&dial_timeout=5s",
92+
LogLevel: "info", // default value
93+
},
94+
},
95+
{
96+
name: "short flag aliases",
97+
args: []string{
98+
"-p", "postgres://user:pass@localhost:5432/db",
99+
"-e", "etcd://localhost:2379/",
100+
"-l", "warn",
101+
},
102+
wantErr: false,
103+
expected: Config{
104+
PostgresDSN: "postgres://user:pass@localhost:5432/db",
105+
EtcdDSN: "etcd://localhost:2379/",
106+
LogLevel: "warn",
107+
},
108+
},
109+
}
110+
111+
for _, tt := range tests {
112+
t.Run(tt.name, func(t *testing.T) {
113+
config, err := ParseCLI(tt.args)
114+
115+
if tt.wantErr {
116+
require.Error(t, err, "Expected error for test case: %s", tt.name)
117+
if tt.errMsg != "" {
118+
assert.Contains(t, err.Error(), tt.errMsg, "Error message should contain expected text")
119+
}
120+
} else {
121+
require.NoError(t, err, "Expected no error for test case: %s", tt.name)
122+
require.NotNil(t, config, "Config should not be nil")
123+
assert.Equal(t, tt.expected, *config, "Parsed config should match expected")
124+
}
125+
})
126+
}
127+
}
128+
129+
// TestCLIEnvironmentVariables tests that CLI can read from environment variables
130+
func TestCLIEnvironmentVariables(t *testing.T) {
131+
// Set environment variables
132+
os.Setenv("ETCD_FDW_POSTGRES_DSN", "postgres://env:pass@localhost:5432/envdb")
133+
os.Setenv("ETCD_FDW_ETCD_DSN", "etcd://localhost:2379,localhost:2380/")
134+
defer func() {
135+
os.Unsetenv("ETCD_FDW_POSTGRES_DSN")
136+
os.Unsetenv("ETCD_FDW_ETCD_DSN")
137+
}()
138+
139+
// This will fail because ParseCLI function doesn't exist yet
140+
config, err := ParseCLI([]string{})
141+
142+
require.NoError(t, err, "Should parse from environment variables")
143+
require.NotNil(t, config, "Config should not be nil")
144+
assert.Equal(t, "postgres://env:pass@localhost:5432/envdb", config.PostgresDSN)
145+
assert.Equal(t, "etcd://localhost:2379,localhost:2380/", config.EtcdDSN)
146+
}
147+
148+
// TestCLIFlagPrecedence tests that command-line flags override environment variables
149+
func TestCLIFlagPrecedence(t *testing.T) {
150+
// Set environment variables
151+
os.Setenv("ETCD_FDW_POSTGRES_DSN", "postgres://env:pass@localhost:5432/envdb")
152+
os.Setenv("ETCD_FDW_ETCD_DSN", "etcd://localhost:2379/")
153+
defer func() {
154+
os.Unsetenv("ETCD_FDW_POSTGRES_DSN")
155+
os.Unsetenv("ETCD_FDW_ETCD_DSN")
156+
}()
157+
158+
// Command-line flags should override environment
159+
args := []string{
160+
"--postgres-dsn", "postgres://flag:pass@localhost:5432/flagdb",
161+
"--etcd-dsn", "etcd://localhost:2380/",
162+
}
163+
164+
// This will fail because ParseCLI function doesn't exist yet
165+
config, err := ParseCLI(args)
166+
167+
require.NoError(t, err, "Should parse with flag precedence")
168+
require.NotNil(t, config, "Config should not be nil")
169+
assert.Equal(t, "postgres://flag:pass@localhost:5432/flagdb", config.PostgresDSN)
170+
assert.Equal(t, "etcd://localhost:2380/", config.EtcdDSN)
171+
}

0 commit comments

Comments
 (0)