-
Notifications
You must be signed in to change notification settings - Fork 368
Expand file tree
/
Copy pathcodemod_serena_import_test.go
More file actions
223 lines (199 loc) · 7.09 KB
/
codemod_serena_import_test.go
File metadata and controls
223 lines (199 loc) · 7.09 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
//go:build !integration
package cli
import (
"strings"
"testing"
"github.com/github/gh-aw/pkg/parser"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestSerenaToSharedImportCodemod(t *testing.T) {
codemod := getSerenaToSharedImportCodemod()
t.Run("migrates tools.serena short syntax to imports", func(t *testing.T) {
content := `---
engine: copilot
tools:
serena: ["go", "typescript"]
strict: false
---
# Test Workflow
`
frontmatter := map[string]any{
"engine": "copilot",
"tools": map[string]any{
"serena": []any{"go", "typescript"},
},
"strict": false,
}
result, applied, err := codemod.Apply(content, frontmatter)
require.NoError(t, err, "Codemod should not return an error")
assert.True(t, applied, "Codemod should be applied when tools.serena is present")
assert.NotContains(t, result, "serena:", "Codemod should remove tools.serena configuration")
assert.Contains(t, result, "imports:", "Codemod should add imports block")
assert.Contains(t, result, "- uses: shared/mcp/serena.md", "Codemod should add Serena shared import")
assert.Contains(t, result, "languages: [\"go\", \"typescript\"]", "Codemod should preserve short syntax languages")
parsed, parseErr := parser.ExtractFrontmatterFromContent(result)
require.NoError(t, parseErr, "Result should contain valid frontmatter")
_, hasTools := parsed.Frontmatter["tools"]
assert.False(t, hasTools, "Codemod should remove empty tools key from frontmatter")
})
t.Run("migrates tools.serena long syntax languages object to imports", func(t *testing.T) {
content := `---
engine: copilot
tools:
serena:
languages:
go:
version: "1.21"
typescript:
strict: false
---
# Test Workflow
`
frontmatter := map[string]any{
"engine": "copilot",
"tools": map[string]any{
"serena": map[string]any{
"languages": map[string]any{
"go": map[string]any{
"version": "1.21",
},
"typescript": nil,
},
},
},
"strict": false,
}
result, applied, err := codemod.Apply(content, frontmatter)
require.NoError(t, err, "Codemod should not return an error")
assert.True(t, applied, "Codemod should be applied for long syntax tools.serena")
assert.NotContains(t, result, "serena:", "Codemod should remove tools.serena block")
assert.Contains(t, result, "- uses: shared/mcp/serena.md", "Codemod should add Serena shared import")
assert.Contains(t, result, "languages: [\"go\", \"typescript\"]", "Codemod should convert language object keys to array")
})
t.Run("removes tools.serena when shared import already exists without adding duplicate", func(t *testing.T) {
content := `---
engine: copilot
imports:
- uses: shared/mcp/serena.md
with:
languages: ["go", "typescript"]
tools:
serena: ["go", "typescript"]
github:
toolsets: [default]
---
# Test Workflow
`
frontmatter := map[string]any{
"engine": "copilot",
"imports": []any{
map[string]any{
"uses": "shared/mcp/serena.md",
"with": map[string]any{
"languages": []any{"go", "typescript"},
},
},
},
"tools": map[string]any{
"serena": []any{"go", "typescript"},
"github": map[string]any{
"toolsets": []any{"default"},
},
},
}
result, applied, err := codemod.Apply(content, frontmatter)
require.NoError(t, err, "Codemod should not return an error")
assert.True(t, applied, "Codemod should be applied when tools.serena is present")
assert.NotContains(t, result, "\n serena:", "Codemod should remove tools.serena field")
assert.Contains(t, result, "github:", "Codemod should preserve other tools.* entries")
assert.Equal(t, 1, strings.Count(result, "shared/mcp/serena.md"), "Codemod should not add a duplicate Serena import")
})
t.Run("does not modify workflows without tools.serena", func(t *testing.T) {
content := `---
engine: copilot
imports:
- uses: shared/mcp/serena.md
with:
languages: ["go"]
---
# Test Workflow
`
frontmatter := map[string]any{
"engine": "copilot",
"imports": []any{
map[string]any{
"uses": "shared/mcp/serena.md",
"with": map[string]any{
"languages": []any{"go"},
},
},
},
}
result, applied, err := codemod.Apply(content, frontmatter)
require.NoError(t, err, "Codemod should not return an error")
assert.False(t, applied, "Codemod should not be applied when tools.serena is absent")
assert.Equal(t, content, result, "Content should remain unchanged when no migration is needed")
})
t.Run("migrates engine.tools.serena and preserves engine sibling fields", func(t *testing.T) {
content := `---
engine:
tools:
serena:
languages: ["typescript"]
model: gpt-5.2
id: copilot
---
# Test Workflow
`
frontmatter := map[string]any{
"engine": map[string]any{
"tools": map[string]any{
"serena": map[string]any{
"languages": []any{"typescript"},
},
},
"model": "gpt-5.2",
"id": "copilot",
},
}
result, applied, err := codemod.Apply(content, frontmatter)
require.NoError(t, err, "Codemod should not return an error")
assert.True(t, applied, "Codemod should be applied when engine.tools.serena is present")
assert.Contains(t, result, "imports:", "Codemod should add imports block")
assert.Contains(t, result, "languages: [\"typescript\"]", "Codemod should preserve engine.tools.serena languages")
assert.NotContains(t, result, "\n tools:", "Codemod should remove now-empty engine.tools block")
parsed, parseErr := parser.ExtractFrontmatterFromContent(result)
require.NoError(t, parseErr, "Result should contain valid frontmatter")
engineAny, hasEngine := parsed.Frontmatter["engine"]
require.True(t, hasEngine, "Result should preserve engine block")
engine, ok := engineAny.(map[string]any)
require.True(t, ok, "Engine should remain an object when sibling fields remain")
assert.Equal(t, "gpt-5.2", engine["model"], "Engine model should remain under engine block")
assert.Equal(t, "copilot", engine["id"], "Engine id should remain under engine block")
_, hasEngineTools := engine["tools"]
assert.False(t, hasEngineTools, "Engine tools should be removed after migration")
})
t.Run("updates github/gh-aw source pin from commit SHA to main when migrating serena", func(t *testing.T) {
content := `---
source: github/gh-aw/.github/workflows/duplicate-code-detector.md@852cb06ad52958b402ed982b69957ffc57ca0619
engine: copilot
tools:
serena: ["typescript"]
---
# Test Workflow
`
frontmatter := map[string]any{
"source": "github/gh-aw/.github/workflows/duplicate-code-detector.md@852cb06ad52958b402ed982b69957ffc57ca0619",
"engine": "copilot",
"tools": map[string]any{
"serena": []any{"typescript"},
},
}
result, applied, err := codemod.Apply(content, frontmatter)
require.NoError(t, err, "Codemod should not return an error")
assert.True(t, applied, "Codemod should be applied when tools.serena is present")
assert.Contains(t, result, "source: github/gh-aw/.github/workflows/duplicate-code-detector.md@main", "Codemod should update pinned gh-aw source to main")
assert.Contains(t, result, "- uses: shared/mcp/serena.md", "Codemod should still add shared Serena import")
})
}