Skip to content

Commit 5f4d6e4

Browse files
committed
WIP: refactor E2E test
1 parent 3d49d4b commit 5f4d6e4

File tree

7 files changed

+174
-168
lines changed

7 files changed

+174
-168
lines changed

tools/generate-module-dependencies/e2e_test.go

Lines changed: 102 additions & 168 deletions
Original file line numberDiff line numberDiff line change
@@ -68,89 +68,66 @@ type testEnv struct {
6868
goModPath string
6969
}
7070

71-
// setupTestEnv sets up the test environment with all necessary files and directories.
71+
// setupTestEnvFromTestdata sets up the test environment by copying testdata and tool source.
7272
// It returns a testEnv struct with all the paths needed for the test.
73-
func setupTestEnv(t *testing.T, yamlContent, goModContent string) *testEnv {
73+
func setupTestEnvFromTestdata(t *testing.T, testdataDir string) *testEnv {
7474
t.Helper()
7575

76-
tmpDir := t.TempDir()
77-
scriptDir := filepath.Join(tmpDir, "tools", "generate-module-dependencies")
78-
if err := os.MkdirAll(scriptDir, 0755); err != nil {
79-
t.Fatalf("Failed to create script directory: %v", err)
80-
}
81-
82-
projectRoot := tmpDir
83-
84-
// Create dependency-replacements.yaml
85-
yamlPath := filepath.Join(projectRoot, "dependency-replacements.yaml")
86-
if err := os.WriteFile(yamlPath, []byte(yamlContent), 0644); err != nil {
87-
t.Fatalf("Failed to write dependency-replacements.yaml: %v", err)
88-
}
89-
90-
// Create replaces-mod.tpl template
91-
templateContent := `// BEGIN GENERATED REPLACES - DO NOT EDIT
92-
// Generated by go generate - DO NOT EDIT MANUALLY
93-
{{- range . }}
94-
{{- if .Comment }}
95-
// {{ .Comment }}
96-
{{- end }}
97-
replace {{ .Dependency }} => {{ .Replacement }}
98-
{{ end -}}
99-
// END GENERATED REPLACES
100-
101-
`
102-
templatePath := filepath.Join(scriptDir, "replaces-mod.tpl")
103-
if err := os.WriteFile(templatePath, []byte(templateContent), 0644); err != nil {
104-
t.Fatalf("Failed to write replaces-mod.tpl: %v", err)
105-
}
106-
107-
// Create go.mod file (this is the target file we'll modify)
108-
goModPath := filepath.Join(projectRoot, "go.mod")
109-
if err := os.WriteFile(goModPath, []byte(goModContent), 0644); err != nil {
110-
t.Fatalf("Failed to write go.mod: %v", err)
111-
}
112-
113-
// Get the original working directory before changing
11476
originalWd, err := os.Getwd()
11577
if err != nil {
11678
t.Fatalf("Failed to get current working directory: %v", err)
11779
}
11880

119-
// Copy go.mod and go.sum to the test script directory so go generate can resolve dependencies
120-
originalGoMod := filepath.Join(originalWd, "go.mod")
121-
originalGoSum := filepath.Join(originalWd, "go.sum")
81+
// Get the testdata directory path
82+
testdataPath := filepath.Join(originalWd, "testdata", testdataDir)
83+
if _, err := os.Stat(testdataPath); os.IsNotExist(err) {
84+
t.Fatalf("Testdata directory not found: %s", testdataPath)
85+
}
12286

123-
testGoMod := filepath.Join(scriptDir, "go.mod")
124-
testGoSum := filepath.Join(scriptDir, "go.sum")
87+
tmpDir := t.TempDir()
88+
projectRoot := tmpDir
89+
scriptDir := filepath.Join(tmpDir, "tools", "generate-module-dependencies")
12590

126-
// Copy go.mod and go.sum
127-
goModData, err := os.ReadFile(originalGoMod)
128-
if err != nil {
129-
t.Fatalf("Failed to read original go.mod: %v", err)
130-
}
131-
if err := os.WriteFile(testGoMod, goModData, 0644); err != nil {
132-
t.Fatalf("Failed to copy go.mod to test directory: %v", err)
91+
// Copy testdata files to project root
92+
testdataYaml := filepath.Join(testdataPath, "dependency-replacements.yaml")
93+
projectYaml := filepath.Join(projectRoot, "dependency-replacements.yaml")
94+
if err := copyFile(testdataYaml, projectYaml); err != nil {
95+
t.Fatalf("Failed to copy dependency-replacements.yaml: %v", err)
13396
}
13497

135-
if goSumData, err := os.ReadFile(originalGoSum); err == nil {
136-
if err := os.WriteFile(testGoSum, goSumData, 0644); err != nil {
137-
t.Fatalf("Failed to copy go.sum to test directory: %v", err)
138-
}
98+
testdataGoMod := filepath.Join(testdataPath, "go.mod")
99+
goModPath := filepath.Join(projectRoot, "go.mod")
100+
if err := copyFile(testdataGoMod, goModPath); err != nil {
101+
t.Fatalf("Failed to copy go.mod: %v", err)
139102
}
140103

141-
// Copy the internal directory structure so imports can be resolved
142-
originalInternal := filepath.Join(originalWd, "internal")
143-
testInternal := filepath.Join(scriptDir, "internal")
104+
// Copy tool source code to script directory
105+
if err := os.MkdirAll(scriptDir, 0755); err != nil {
106+
t.Fatalf("Failed to create script directory: %v", err)
107+
}
144108

145-
if err := copyDir(originalInternal, testInternal); err != nil {
146-
t.Fatalf("Failed to copy internal directory: %v", err)
109+
// Copy all necessary tool files
110+
toolFiles := []string{"replaces-mod.tpl", "main.go", "generate.go", "go.mod", "go.sum"}
111+
for _, file := range toolFiles {
112+
src := filepath.Join(originalWd, file)
113+
dst := filepath.Join(scriptDir, file)
114+
if _, err := os.Stat(src); err == nil {
115+
if err := copyFile(src, dst); err != nil {
116+
t.Fatalf("Failed to copy %s: %v", file, err)
117+
}
118+
}
147119
}
148120

149-
// Copy generate.go
150-
originalGenerateGo := filepath.Join(originalWd, "generate.go")
151-
testGenerateGo := filepath.Join(scriptDir, "generate.go")
152-
if err := copyFile(originalGenerateGo, testGenerateGo); err != nil {
153-
t.Fatalf("Failed to copy generate.go: %v", err)
121+
// Copy tool directories
122+
toolDirs := []string{"internal", "cmd"}
123+
for _, dir := range toolDirs {
124+
src := filepath.Join(originalWd, dir)
125+
dst := filepath.Join(scriptDir, dir)
126+
if _, err := os.Stat(src); err == nil {
127+
if err := copyDir(src, dst); err != nil {
128+
t.Fatalf("Failed to copy %s directory: %v", dir, err)
129+
}
130+
}
154131
}
155132

156133
return &testEnv{
@@ -159,8 +136,8 @@ replace {{ .Dependency }} => {{ .Replacement }}
159136
}
160137
}
161138

162-
// runGoGenerate runs `go generate` in the test environment
163-
func runGoGenerate(t *testing.T, env *testEnv) {
139+
// runCommand runs the generate command in the test environment
140+
func runCommand(t *testing.T, env *testEnv) {
164141
t.Helper()
165142

166143
// Change to script directory to simulate running from there
@@ -174,59 +151,67 @@ func runGoGenerate(t *testing.T, env *testEnv) {
174151
t.Fatalf("Failed to change to script directory: %v", err)
175152
}
176153

177-
// Run go generate
178-
cmd := exec.Command("go", "generate")
154+
// Calculate the project root relative to scriptDir
155+
// scriptDir is tmpDir/tools/generate-module-dependencies
156+
// project root should be tmpDir (two levels up)
157+
projectRoot := filepath.Join(env.scriptDir, "..", "..")
158+
projectRoot, err = filepath.Abs(projectRoot)
159+
if err != nil {
160+
t.Fatalf("Failed to resolve project root: %v", err)
161+
}
162+
163+
// Calculate the yaml path relative to scriptDir
164+
// dependency-replacements.yaml is at projectRoot/dependency-replacements.yaml
165+
yamlPath := filepath.Join(projectRoot, "dependency-replacements.yaml")
166+
relYamlPath, err := filepath.Rel(env.scriptDir, yamlPath)
167+
if err != nil {
168+
t.Fatalf("Failed to calculate relative yaml path: %v", err)
169+
}
170+
171+
// Calculate relative project root path
172+
relProjectRoot, err := filepath.Rel(env.scriptDir, projectRoot)
173+
if err != nil {
174+
t.Fatalf("Failed to calculate relative project root: %v", err)
175+
}
176+
177+
// Run the command directly
178+
cmd := exec.Command("go", "run", "main.go", "generate",
179+
"--dependency-yaml", relYamlPath,
180+
"--project-root", relProjectRoot)
179181
cmd.Dir = env.scriptDir
180182
output, err := cmd.CombinedOutput()
181183
if err != nil {
182-
t.Logf("go generate output: %s", string(output))
183-
t.Fatalf("Failed to run go generate: %v", err)
184+
t.Logf("Command output: %s", string(output))
185+
t.Fatalf("Failed to run command: %v", err)
184186
}
185187
}
186188

187189
// ##################################################################################
188190
// ################################### E2E TESTS ####################################
189191
// ##################################################################################
190192

191-
// TestE2E tests the full pipeline: generating replaces from YAML and applying them to go.mod
192-
func TestE2E(t *testing.T) {
193+
// TestE2E_Basic tests the full pipeline: generating replaces from YAML and applying them to go.mod
194+
// This test uses the testdata/basic directory which contains a simple example project.
195+
func TestE2E_Basic(t *testing.T) {
193196
originalWd, err := os.Getwd()
194197
if err != nil {
195198
t.Fatalf("Failed to get current working directory: %v", err)
196199
}
197200
defer os.Chdir(originalWd)
198201

199-
// Test-specific setup: YAML and go.mod content
200-
yamlContent := `modules:
201-
- name: test-module
202-
path: go.mod
203-
file_type: mod
204-
205-
replaces:
206-
- comment: Test replace for example.com/package
207-
dependency: example.com/package
208-
replacement: example.com/fork v1.0.0
209-
210-
- comment: Another test replace
211-
dependency: github.com/test/dependency
212-
replacement: github.com/test/fork v1.0.0
213-
`
214-
215-
goModContent := `module test.example.com
202+
// Set up test environment from testdata
203+
env := setupTestEnvFromTestdata(t, "basic")
216204

217-
go 1.21
205+
// Run the generate command
206+
runCommand(t, env)
218207

219-
require (
220-
example.com/package v0.1.0
221-
github.com/test/dependency v1.0.0
222-
)
223-
`
224-
225-
// Set up test environment
226-
env := setupTestEnv(t, yamlContent, goModContent)
227-
228-
// Run go generate
229-
runGoGenerate(t, env)
208+
// Read expected output from testdata
209+
expectedPath := filepath.Join("testdata", "basic", "go.mod.expected")
210+
expectedContent, err := os.ReadFile(expectedPath)
211+
if err != nil {
212+
t.Fatalf("Failed to read expected go.mod: %v", err)
213+
}
214+
expectedGoMod := strings.TrimSpace(string(expectedContent))
230215

231216
// Verify go.mod was updated
232217
updatedGoModContent, err := os.ReadFile(env.goModPath)
@@ -236,69 +221,34 @@ require (
236221

237222
actualGoMod := strings.TrimSpace(string(updatedGoModContent))
238223

239-
// Define expected go.mod content
240-
// Note: go mod tidy removes unused dependencies, so the require block is removed
241-
expectedGoMod := `module test.example.com
242-
243-
go 1.21
244-
245-
// BEGIN GENERATED REPLACES - DO NOT EDIT
246-
// Generated by go generate - DO NOT EDIT MANUALLY
247-
// Test replace for example.com/package
248-
replace example.com/package => example.com/fork v1.0.0
249-
250-
// Another test replace
251-
replace github.com/test/dependency => github.com/test/fork v1.0.0
252-
253-
// END GENERATED REPLACES`
254-
255-
expectedGoMod = strings.TrimSpace(expectedGoMod)
256-
257224
if actualGoMod != expectedGoMod {
258225
t.Errorf("go.mod content mismatch.\nExpected:\n%s\n\nActual:\n%s", expectedGoMod, actualGoMod)
259226
}
260227
}
261228

262-
// TestE2E_UpdateExisting tests updating an existing generated block
229+
// TestE2E_UpdateExisting tests updating an existing generated block.
230+
// This test uses the testdata/update-existing directory which contains a go.mod
231+
// with an existing generated block that should be updated.
263232
func TestE2E_UpdateExisting(t *testing.T) {
264233
originalWd, err := os.Getwd()
265234
if err != nil {
266235
t.Fatalf("Failed to get current working directory: %v", err)
267236
}
268237
defer os.Chdir(originalWd)
269238

270-
// Test-specific setup: YAML and go.mod content with existing generated block
271-
yamlContent := `modules:
272-
- name: test-module
273-
path: go.mod
274-
file_type: mod
275-
276-
replaces:
277-
- comment: Updated replace
278-
dependency: example.com/package
279-
replacement: example.com/fork v1.1.0
280-
`
281-
282-
goModContent := `module test.example.com
283-
284-
go 1.21
285-
286-
require (
287-
example.com/package v0.1.0
288-
)
289-
290-
// BEGIN GENERATED REPLACES - DO NOT EDIT
291-
// Generated by go generate - DO NOT EDIT MANUALLY
292-
// Old comment
293-
replace example.com/package => example.com/fork v1.0.0
294-
// END GENERATED REPLACES
295-
`
239+
// Set up test environment from testdata
240+
env := setupTestEnvFromTestdata(t, "update-existing")
296241

297-
// Set up test environment
298-
env := setupTestEnv(t, yamlContent, goModContent)
242+
// Run the generate command
243+
runCommand(t, env)
299244

300-
// Run go generate
301-
runGoGenerate(t, env)
245+
// Read expected output from testdata
246+
expectedPath := filepath.Join("testdata", "update-existing", "go.mod.expected")
247+
expectedContent, err := os.ReadFile(expectedPath)
248+
if err != nil {
249+
t.Fatalf("Failed to read expected go.mod: %v", err)
250+
}
251+
expectedGoMod := strings.TrimSpace(string(expectedContent))
302252

303253
// Verify go.mod was updated
304254
updatedGoModContent, err := os.ReadFile(env.goModPath)
@@ -308,22 +258,6 @@ replace example.com/package => example.com/fork v1.0.0
308258

309259
actualGoMod := strings.TrimSpace(string(updatedGoModContent))
310260

311-
// Define expected go.mod content
312-
// Note: go mod tidy removes unused dependencies, so the require block is removed
313-
// The old replace should be replaced with the new one
314-
expectedGoMod := `module test.example.com
315-
316-
go 1.21
317-
318-
// BEGIN GENERATED REPLACES - DO NOT EDIT
319-
// Generated by go generate - DO NOT EDIT MANUALLY
320-
// Updated replace
321-
replace example.com/package => example.com/fork v1.1.0
322-
323-
// END GENERATED REPLACES`
324-
325-
expectedGoMod = strings.TrimSpace(expectedGoMod)
326-
327261
if actualGoMod != expectedGoMod {
328262
t.Errorf("go.mod content mismatch.\nExpected:\n%s\n\nActual:\n%s", expectedGoMod, actualGoMod)
329263
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
modules:
2+
- name: test-module
3+
path: go.mod
4+
file_type: mod
5+
6+
replaces:
7+
- comment: Test replace for example.com/package
8+
dependency: example.com/package
9+
replacement: example.com/fork v1.0.0
10+
11+
- comment: Another test replace
12+
dependency: github.com/test/dependency
13+
replacement: github.com/test/fork v1.0.0
14+
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module test.example.com
2+
3+
go 1.21
4+
5+
require (
6+
example.com/package v0.1.0
7+
github.com/test/dependency v1.0.0
8+
)
9+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module test.example.com
2+
3+
go 1.21
4+
5+
// BEGIN GENERATED REPLACES - DO NOT EDIT
6+
// Generated by go generate - DO NOT EDIT MANUALLY
7+
// Test replace for example.com/package
8+
replace example.com/package => example.com/fork v1.0.0
9+
10+
// Another test replace
11+
replace github.com/test/dependency => github.com/test/fork v1.0.0
12+
13+
// END GENERATED REPLACES
14+

0 commit comments

Comments
 (0)