forked from coder/claudecode.nvim
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdiff_spec.lua
More file actions
280 lines (226 loc) · 7.98 KB
/
diff_spec.lua
File metadata and controls
280 lines (226 loc) · 7.98 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
272
273
274
275
276
277
278
279
280
-- luacheck: globals expect
require("tests.busted_setup")
describe("Diff Module", function()
local diff
local original_vim_functions = {}
local function setup()
package.loaded["claudecode.diff"] = nil
package.loaded["claudecode.config"] = nil
assert(_G.vim, "Global vim mock not initialized by busted_setup.lua")
assert(_G.vim.fn, "Global vim.fn mock not initialized")
-- For this spec, the global mock (which now includes stdpath) should be largely sufficient.
-- The local mock_vim that was missing stdpath is removed.
diff = require("claudecode.diff")
end
local function teardown()
for path, func in pairs(original_vim_functions) do
local parts = {}
for part in string.gmatch(path, "[^%.]+") do
table.insert(parts, part)
end
local obj = _G.vim
for i = 1, #parts - 1 do
obj = obj[parts[i]]
end
obj[parts[#parts]] = func
end
original_vim_functions = {}
if original_vim_functions["cmd"] then
_G.vim.cmd = original_vim_functions["cmd"]
original_vim_functions["cmd"] = nil
end
-- _G.vim itself is managed by busted_setup.lua
end
before_each(function()
setup()
end)
after_each(function()
teardown()
end)
describe("Temporary File Management (via Native Diff)", function()
it("should create temporary files with correct content through native diff", function()
local test_content = "This is test content\nLine 2\nLine 3"
local old_file_path = "/path/to/old.lua"
local new_file_path = "/path/to/new.lua"
local mock_file = {
write = function() end,
close = function() end,
}
local old_io_open = io.open
rawset(io, "open", function()
return mock_file
end)
local result = diff._open_native_diff(old_file_path, new_file_path, test_content, "Test Diff")
expect(result).to_be_table()
expect(result.success).to_be_true()
expect(result.temp_file).to_be_string()
expect(result.temp_file:find("claudecode_diff", 1, true)).not_to_be_nil()
local expected_suffix = vim.fn.fnamemodify(new_file_path, ":t") .. ".new"
expect(result.temp_file:find(expected_suffix, 1, true)).not_to_be_nil()
rawset(io, "open", old_io_open)
end)
it("should handle file creation errors in native diff", function()
local test_content = "test"
local old_file_path = "/path/to/old.lua"
local new_file_path = "/path/to/new.lua"
local old_io_open = io.open
rawset(io, "open", function()
return nil
end)
local result = diff._open_native_diff(old_file_path, new_file_path, test_content, "Test Diff")
expect(result).to_be_table()
expect(result.success).to_be_false()
expect(result.error).to_be_string()
expect(result.error:find("Failed to create temporary file", 1, true)).not_to_be_nil()
expect(result.temp_file).to_be_nil() -- Ensure no temp_file is created on failure
rawset(io, "open", old_io_open)
end)
end)
describe("Native Diff Implementation", function()
it("should create diff with correct parameters", function()
diff.setup({
diff_opts = {
vertical_split = true,
show_diff_stats = false,
auto_close_on_accept = true,
},
})
local commands = {}
if _G.vim and rawget(original_vim_functions, "cmd") == nil then
original_vim_functions["cmd"] = _G.vim.cmd
end
_G.vim.cmd = function(cmd)
table.insert(commands, cmd)
end
local mock_file = {
write = function() end,
close = function() end,
}
local old_io_open = io.open
rawset(io, "open", function()
return mock_file
end)
local result = diff._open_native_diff("/path/to/old.lua", "/path/to/new.lua", "new content here", "Test Diff")
expect(result.success).to_be_true()
expect(result.provider).to_be("native")
expect(result.tab_name).to_be("Test Diff")
local found_vsplit = false
local found_diffthis = false
local found_edit = false
for _, cmd in ipairs(commands) do
if cmd:find("vsplit", 1, true) then
found_vsplit = true
end
if cmd:find("diffthis", 1, true) then
found_diffthis = true
end
if cmd:find("edit", 1, true) then
found_edit = true
end
end
expect(found_vsplit).to_be_true()
expect(found_diffthis).to_be_true()
expect(found_edit).to_be_true()
rawset(io, "open", old_io_open)
end)
it("should use horizontal split when configured", function()
diff.setup({
diff_opts = {
vertical_split = false,
show_diff_stats = false,
auto_close_on_accept = true,
},
})
local commands = {}
if _G.vim and rawget(original_vim_functions, "cmd") == nil then
original_vim_functions["cmd"] = _G.vim.cmd
end
_G.vim.cmd = function(cmd)
table.insert(commands, cmd)
end
local mock_file = {
write = function() end,
close = function() end,
}
local old_io_open = io.open
rawset(io, "open", function()
return mock_file
end)
local result = diff._open_native_diff("/path/to/old.lua", "/path/to/new.lua", "new content here", "Test Diff")
expect(result.success).to_be_true()
local found_split = false
local found_vertical_split = false
for _, cmd in ipairs(commands) do
if cmd:find("split", 1, true) and not cmd:find("vertical split", 1, true) then
found_split = true
end
if cmd:find("vertical split", 1, true) then
found_vertical_split = true
end
end
expect(found_split).to_be_true()
expect(found_vertical_split).to_be_false()
rawset(io, "open", old_io_open)
end)
it("should handle temporary file creation errors", function()
diff.setup({})
local old_io_open = io.open
rawset(io, "open", function()
return nil
end)
local result = diff._open_native_diff("/path/to/old.lua", "/path/to/new.lua", "new content here", "Test Diff")
expect(result.success).to_be_false()
expect(result.error).to_be_string()
expect(result.error:find("Failed to create temporary file", 1, true)).not_to_be_nil()
rawset(io, "open", old_io_open)
end)
end)
describe("Filetype Propagation", function()
it("should propagate original filetype to proposed buffer", function()
diff.setup({})
-- Spy on nvim_set_option_value
spy.on(_G.vim.api, "nvim_set_option_value")
local mock_file = {
write = function() end,
close = function() end,
}
local old_io_open = io.open
rawset(io, "open", function()
return mock_file
end)
local result = diff._open_native_diff("/tmp/test.ts", "/tmp/test.ts", "-- new", "Propagate FT")
expect(result.success).to_be_true()
-- Verify spy called with filetype typescript
local calls = _G.vim.api.nvim_set_option_value.calls or {}
local found = false
for _, c in ipairs(calls) do
if c.vals[1] == "filetype" and c.vals[2] == "typescript" then
found = true
break
end
end
expect(found).to_be_true()
rawset(io, "open", old_io_open)
end)
end)
describe("Open Diff Function", function()
it("should use native provider", function()
diff.setup({})
local native_called = false
diff._open_native_diff = function(old_path, new_path, content, tab_name)
native_called = true
return {
success = true,
provider = "native",
tab_name = tab_name,
temp_file = "/mock/temp/file.new",
}
end
local result = diff.open_diff("/path/to/old.lua", "/path/to/new.lua", "new content", "Test Diff")
expect(native_called).to_be_true()
expect(result.provider).to_be("native")
expect(result.success).to_be_true()
end)
end)
teardown()
end)