-
Notifications
You must be signed in to change notification settings - Fork 198
Expand file tree
/
Copy pathbusted_setup.lua
More file actions
349 lines (317 loc) · 8.89 KB
/
Copy pathbusted_setup.lua
File metadata and controls
349 lines (317 loc) · 8.89 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
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
-- Test setup for busted
-- Create mock vim API if we're running tests outside of Neovim
if not _G.vim then
_G.vim = require("tests.mocks.vim")
end
-- Ensure vim global is accessible
_G.vim = _G.vim or {}
-- Setup test globals
_G.assert = require("luassert")
-- Helper function to verify expectations
_G.expect = function(value)
return {
to_be = function(expected)
assert.are.equal(expected, value)
end,
to_be_nil = function()
assert.is_nil(value)
end,
to_be_true = function()
assert.is_true(value)
end,
to_be_false = function()
assert.is_false(value)
end,
to_be_table = function()
assert.is_table(value)
end,
to_be_string = function()
assert.is_string(value)
end,
to_be_function = function()
assert.is_function(value)
end,
to_be_boolean = function()
assert.is_boolean(value)
end,
to_be_at_least = function(expected)
assert.is_true(value >= expected)
end,
to_have_key = function(key)
assert.is_table(value)
assert.not_nil(value[key])
end,
-- to_contain was here, moved to _G.assert_contains
not_to_be_nil = function()
assert.is_not_nil(value)
end,
-- not_to_contain was here, moved to _G.assert_not_contains
to_be_truthy = function()
assert.is_truthy(value)
end,
to_match = function(pattern)
assert.is_string(value)
assert.is_true(
string.find(value, pattern, 1, true) ~= nil,
"Expected string '" .. value .. "' to match pattern '" .. pattern .. "'"
)
end,
}
end
_G.assert_contains = function(actual_value, expected_pattern)
if type(actual_value) == "string" then
if type(expected_pattern) ~= "string" then
error(
"assert_contains expected a string pattern for a string actual_value, but expected_pattern was type: "
.. type(expected_pattern)
)
end
assert.is_true(
string.find(actual_value, expected_pattern, 1, true) ~= nil,
"Expected string '" .. actual_value .. "' to contain '" .. expected_pattern .. "'"
)
elseif type(actual_value) == "table" then
local found = false
for _, v in ipairs(actual_value) do
if v == expected_pattern then
found = true
break
end
end
assert.is_true(found, "Expected table to contain value: " .. tostring(expected_pattern))
else
error("assert_contains can only be used with string or table actual_values, got type: " .. type(actual_value))
end
end
_G.assert_not_contains = function(actual_value, expected_pattern)
if type(actual_value) == "string" then
if type(expected_pattern) ~= "string" then
error(
"assert_not_contains expected a string pattern for a string actual_value, but expected_pattern was type: "
.. type(expected_pattern)
)
end
assert.is_true(
string.find(actual_value, expected_pattern, 1, true) == nil,
"Expected string '" .. actual_value .. "' NOT to contain '" .. expected_pattern .. "'"
)
elseif type(actual_value) == "table" then
local found = false
for _, v in ipairs(actual_value) do
if v == expected_pattern then
found = true
break
end
end
assert.is_false(found, "Expected table NOT to contain value: " .. tostring(expected_pattern))
else
error("assert_not_contains can only be used with string or table actual_values, got type: " .. type(actual_value))
end
end
-- JSON encoding/decoding helpers for tests
_G.json_encode = function(data)
if type(data) == "table" then
local parts = {}
local is_array = true
-- Check if it's an array (all numeric, positive keys) or an object
for k, _ in pairs(data) do
if type(k) ~= "number" or k <= 0 or math.floor(k) ~= k then
is_array = false
break
end
end
if is_array then
table.insert(parts, "[")
for i, v in ipairs(data) do
if i > 1 then
table.insert(parts, ",")
end
table.insert(parts, _G.json_encode(v))
end
table.insert(parts, "]")
else
table.insert(parts, "{")
local first = true
for k, v in pairs(data) do
if not first then
table.insert(parts, ",")
end
first = false
-- Handle special Lua keywords as object keys
local key_str = tostring(k)
if key_str == "end" then
table.insert(parts, '["end"]:')
else
table.insert(parts, '"' .. key_str .. '":')
end
table.insert(parts, _G.json_encode(v))
end
table.insert(parts, "}")
end
return table.concat(parts)
elseif type(data) == "string" then
-- Handle escape sequences properly
local escaped = data
:gsub("\\", "\\\\") -- Escape backslashes first
:gsub('"', '\\"') -- Escape quotes
:gsub("\n", "\\n") -- Escape newlines
:gsub("\r", "\\r") -- Escape carriage returns
:gsub("\t", "\\t") -- Escape tabs
return '"' .. escaped .. '"'
elseif type(data) == "boolean" then
return data and "true" or "false"
elseif type(data) == "number" then
return tostring(data)
else
return "null"
end
end
-- Simple JSON decoder for test purposes
_G.json_decode = function(str)
if not str or str == "" then
return nil
end
local pos = 1
local function skip_whitespace()
while pos <= #str and str:sub(pos, pos):match("%s") do
pos = pos + 1
end
end
local function parse_value()
skip_whitespace()
if pos > #str then
return nil
end
local char = str:sub(pos, pos)
if char == '"' then
-- Parse string
pos = pos + 1
local start = pos
while pos <= #str and str:sub(pos, pos) ~= '"' do
if str:sub(pos, pos) == "\\" then
pos = pos + 1
end
pos = pos + 1
end
local value = str
:sub(start, pos - 1)
:gsub('\\"', '"') -- Unescape quotes
:gsub("\\\\", "\\") -- Unescape backslashes
:gsub("\\n", "\n") -- Unescape newlines
:gsub("\\r", "\r") -- Unescape carriage returns
:gsub("\\t", "\t") -- Unescape tabs
pos = pos + 1
return value
elseif char == "{" then
-- Parse object
pos = pos + 1
local obj = {}
skip_whitespace()
if pos <= #str and str:sub(pos, pos) == "}" then
pos = pos + 1
return obj
end
while true do
skip_whitespace()
-- Parse key
if str:sub(pos, pos) ~= '"' and str:sub(pos, pos) ~= "[" then
break
end
local key
if str:sub(pos, pos) == '"' then
key = parse_value()
elseif str:sub(pos, pos) == "[" then
-- Handle bracket notation like ["end"]
pos = pos + 2 -- skip ["
local start = pos
while pos <= #str and str:sub(pos, pos) ~= '"' do
pos = pos + 1
end
key = str:sub(start, pos - 1)
pos = pos + 2 -- skip "]
else
break
end
skip_whitespace()
if pos > #str or str:sub(pos, pos) ~= ":" then
break
end
pos = pos + 1
-- Parse value
local value = parse_value()
obj[key] = value
skip_whitespace()
if pos > #str then
break
end
if str:sub(pos, pos) == "}" then
pos = pos + 1
break
elseif str:sub(pos, pos) == "," then
pos = pos + 1
else
break
end
end
return obj
elseif char == "[" then
-- Parse array
pos = pos + 1
local arr = {}
skip_whitespace()
if pos <= #str and str:sub(pos, pos) == "]" then
pos = pos + 1
return arr
end
while true do
table.insert(arr, parse_value())
skip_whitespace()
if pos > #str then
break
end
if str:sub(pos, pos) == "]" then
pos = pos + 1
break
elseif str:sub(pos, pos) == "," then
pos = pos + 1
else
break
end
end
return arr
elseif char:match("%d") or char == "-" then
-- Parse number
local start = pos
if char == "-" then
pos = pos + 1
end
while pos <= #str and str:sub(pos, pos):match("%d") do
pos = pos + 1
end
if pos <= #str and str:sub(pos, pos) == "." then
pos = pos + 1
while pos <= #str and str:sub(pos, pos):match("%d") do
pos = pos + 1
end
end
return tonumber(str:sub(start, pos - 1))
elseif str:sub(pos, pos + 3) == "true" then
pos = pos + 4
return true
elseif str:sub(pos, pos + 4) == "false" then
pos = pos + 5
return false
elseif str:sub(pos, pos + 3) == "null" then
pos = pos + 4
return nil
else
return nil
end
end
return parse_value()
end
-- Return true to indicate setup was successful
return {
json_encode = _G.json_encode,
json_decode = _G.json_decode,
}