use super::*;
#[test]
fn parse_nesting_based_end_detection() {
parse_errors(r#"-- i am line 1
function BottomUpTree(item, depth)
if depth > 0 then
local i = item + item
depth = depth - 1
local left, right = BottomUpTree(i-1, depth), BottomUpTree(i, depth)
return { item, left, right }
else
return { item }
end
function ItemCheck(tree)
if tree[2] then
return tree[1] + ItemCheck(tree[2]) - ItemCheck(tree[3])
else
return tree[1]
end
end
"#).assert_first_message("Expected 'end' (to close 'function' at line 2), got <eof>; did you forget to close 'else' at line 8?");
}
#[test]
fn parse_nesting_based_end_detection_single_line() {
parse_errors(r#"-- i am line 1
function ItemCheck(tree)
if tree[2] then return tree[1] + ItemCheck(tree[2]) - ItemCheck(tree[3]) else return tree[1]
end
function BottomUpTree(item, depth)
if depth > 0 then
local i = item + item
depth = depth - 1
local left, right = BottomUpTree(i-1, depth), BottomUpTree(i, depth)
return { item, left, right }
else
return { item }
end
end
"#).assert_first_message("Expected 'end' (to close 'function' at line 2), got <eof>; did you forget to close 'else' at line 3?");
}
#[test]
fn parse_nesting_based_end_detection_local_repeat() {
parse_errors(r#"-- i am line 1
repeat
print(1)
repeat
print(2)
print(3)
until false
"#).assert_first_message("Expected 'until' (to close 'repeat' at line 2), got <eof>; did you forget to close 'repeat' at line 4?");
}
#[test]
fn parse_nesting_based_end_detection_local_function() {
parse_errors(r#"-- i am line 1
local function BottomUpTree(item, depth)
if depth > 0 then
local i = item + item
depth = depth - 1
local left, right = BottomUpTree(i-1, depth), BottomUpTree(i, depth)
return { item, left, right }
else
return { item }
end
local function ItemCheck(tree)
if tree[2] then
return tree[1] + ItemCheck(tree[2]) - ItemCheck(tree[3])
else
return tree[1]
end
end
"#).assert_first_message("Expected 'end' (to close 'function' at line 2), got <eof>; did you forget to close 'else' at line 8?");
}
#[test]
fn parse_nesting_based_end_detection_failsafe_earlier() {
parse_errors(
r#"-- i am line 1
local function ItemCheck(tree)
if tree[2] then
return tree[1] + ItemCheck(tree[2]) - ItemCheck(tree[3])
else
return tree[1]
end
end
local function BottomUpTree(item, depth)
if depth > 0 then
local i = item + item
depth = depth - 1
local left, right = BottomUpTree(i-1, depth), BottomUpTree(i, depth)
return { item, left, right }
else
return { item }
end
"#,
)
.assert_first_message("Expected 'end' (to close 'function' at line 10), got <eof>");
}
#[test]
fn parse_nesting_based_end_detection_nested() {
parse_errors(r#"-- i am line 1
function stringifyTable(t)
local entries = {}
for k, v in pairs(t) do
-- if we find a nested table, convert that recursively
if type(v) == "table" then
v = stringifyTable(v)
else
v = tostring(v)
k = tostring(k)
-- add another entry to our stringified table
entries[#entries + 1] = ("s = s"):format(k, v)
end
-- the memory location of the table
local id = tostring(t):sub(8)
return ("{s}@s"):format(table.concat(entries, ", "), id)
end
"#).assert_first_message("Expected 'end' (to close 'function' at line 2), got <eof>; did you forget to close 'else' at line 8?");
}