1
0
Fork 0
mirror of https://github.com/Reuh/candran.git synced 2026-02-04 02:08:40 +00:00

feat: add tests for Lua 5.4 & Lua 5.5 syntax additions

This commit is contained in:
Étienne Fildadut 2025-12-26 15:13:28 +01:00
parent c13a7df27b
commit f5d6a101ed
2 changed files with 132 additions and 45 deletions

View file

@ -199,7 +199,7 @@ return function(code, ast, options, macros={functions={}, variables={}})
local CONTINUE_STOP = () -- at the start of loops using continue local CONTINUE_STOP = () -- at the start of loops using continue
return unindent().."end"..newline().."::"..var"continue".."::" return unindent().."end"..newline().."::"..var"continue".."::"
end end
local DESTRUCTURING_ASSIGN = (destructured, newlineAfter=false, noLocal=false) -- to define values from a destructuring assignement local DESTRUCTURING_ASSIGN = (destructured, newlineAfter=false, noLocal=false) -- to define values from a destructuring assignment
local vars = {} local vars = {}
local values = {} local values = {}
for _, list in ipairs(destructured) do for _, list in ipairs(destructured) do
@ -870,7 +870,7 @@ return function(code, ast, options, macros={functions={}, variables={}})
if t.id then -- destructing already done before, use parent variable as id if t.id then -- destructing already done before, use parent variable as id
return t.id return t.id
else else
local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignement") local d = assert(peek("destructuring"), "DestructuringId not in a destructurable assignment")
local vars = { id = tmp() } local vars = { id = tmp() }
for j=1, #t, 1 do for j=1, #t, 1 do
table.insert(vars, t[j]) table.insert(vars, t[j])

View file

@ -41,6 +41,11 @@ local function test(name, candranCode, expectedResult, options)
results[name] = { result = "not finished", message = "no info" } results[name] = { result = "not finished", message = "no info" }
local self = results[name] local self = results[name]
-- result
if type(expectedResult) ~= "table" then
expectedResult = { "return", expectedResult }
end
-- options -- options
options = options or {} options = options or {}
options.chunkname = name options.chunkname = name
@ -56,25 +61,33 @@ local function test(name, candranCode, expectedResult, options)
-- load code -- load code
local env = {} local env = {}
for k, v in pairs(_G) do env[k] = v end for k, v in pairs(_G) do env[k] = v end
local success, func = pcall(load, code, nil, env) local func, err = load(code, name, env)
if not success then if err then
if expectedResult[1] == "loadError" and err:match(expectedResult[2] or "") then
self.result = "success"
return
end
self.result = "error" self.result = "error"
self.message = c("/!\\ error while loading code:\n"..func.."\ngenerated code:\n", "bold", "red")..c(code, "red") self.message = c("/!\\ error while loading code:\n"..err.."\ngenerated code:\n", "bold", "red")..c(code, "red")
return return
end end
-- run code -- run code
local success, output = pcall(func) local success, output = pcall(func)
if not success then if not success then
if expectedResult[1] == "runtimeError" and output:match(expectedResult[2] or "") then
self.result = "success"
return
end
self.result = "error" self.result = "error"
self.message = c("/!\\ error while running code:\n"..output.."\ngenerated code:\n", "bold", "red")..c(code, "red") self.message = c("/!\\ error while running code:\n"..output.."\ngenerated code:\n", "bold", "red")..c(code, "red")
return return
end end
-- check result -- check result
if output ~= expectedResult then if expectedResult[1] == "return" and output ~= expectedResult[2] then
self.result = "fail" self.result = "fail"
self.message = c("/!\\ invalid result from the code; it returned "..tostring(output).." instead of "..tostring(expectedResult).."; generated code:\n", "bold", "purple")..c(code, "purple") self.message = c("/!\\ invalid result from the code; it returned "..tostring(output).." instead of "..tostring(expectedResult[2]).."; generated code:\n", "bold", "purple")..c(code, "purple")
return return
else else
self.result = "success" self.result = "success"
@ -214,7 +227,7 @@ return hello
-- SYNTAX ADDITIONS -- -- SYNTAX ADDITIONS --
---------------------- ----------------------
-- Assignement operators -- Assignment operators
test("+=", [[ test("+=", [[
local a = 5 local a = 5
a += 2 a += 2
@ -286,7 +299,7 @@ test(">>=", [[
return a return a
]], 5) ]], 5)
test("right assigments operators", [[ test("right assignments operators", [[
local a = 5 local a = 5
a =+ 2 assert(a == 7, "=+") a =+ 2 assert(a == 7, "=+")
a =- 2 assert(a == -5, "=-") a =- 2 assert(a == -5, "=-")
@ -312,7 +325,7 @@ test("right assigments operators", [[
a =>> 23 assert(a == 5, "=>>") a =>> 23 assert(a == 5, "=>>")
]], nil) ]], nil)
test("some left+right assigments operators", [[ test("some left+right assignments operators", [[
local a = 5 local a = 5
a -=+ 2 assert(a == 8, "-=+") a -=+ 2 assert(a == 8, "-=+")
@ -320,17 +333,17 @@ test("some left+right assigments operators", [[
a ..=.. " world " assert(a == "hello world hello", "..=..") a ..=.. " world " assert(a == "hello world hello", "..=..")
]], nil) ]], nil)
test("left assigments operators priority", [[ test("left assignments operators priority", [[
local a = 5 local a = 5
a *= 2 + 3 a *= 2 + 3
return a return a
]], 25) ]], 25)
test("right assigments operators priority", [[ test("right assignments operators priority", [[
local a = 5 local a = 5
a =/ 2 + 3 a =/ 2 + 3
return a return a
]], 1) ]], 1)
test("left+right assigments operators priority", [[ test("left+right assignments operators priority", [[
local a = 5 local a = 5
a *=/ 2 + 3 a *=/ 2 + 3
return a return a
@ -915,63 +928,63 @@ test("safe prefixes, random chaining", [[
assert(f.l?:o?() == nil) assert(f.l?:o?() == nil)
]]) ]])
-- Destructuring assigments -- Destructuring assignments
test("destructuring assignement with an expression", [[ test("destructuring assignment with an expression", [[
local {x, y} = { x = 5, y = 1 } local {x, y} = { x = 5, y = 1 }
return x + y return x + y
]], 6) ]], 6)
test("destructuring assignement with local", [[ test("destructuring assignment with local", [[
t = { x = 5, y = 1 } t = { x = 5, y = 1 }
local {x, y} = t local {x, y} = t
return x + y return x + y
]], 6) ]], 6)
test("destructuring assignement", [[ test("destructuring assignment", [[
t = { x = 5, y = 1 } t = { x = 5, y = 1 }
{x, y} = t {x, y} = t
return x + y return x + y
]], 6) ]], 6)
test("destructuring assignement with +=", [[ test("destructuring assignment with +=", [[
t = { x = 5, y = 1 } t = { x = 5, y = 1 }
local x, y = 5, 9 local x, y = 5, 9
{x, y} += t {x, y} += t
return x + y return x + y
]], 20) ]], 20)
test("destructuring assignement with =-", [[ test("destructuring assignment with =-", [[
t = { x = 5, y = 1 } t = { x = 5, y = 1 }
local x, y = 5, 9 local x, y = 5, 9
{x, y} =- t {x, y} =- t
return x + y return x + y
]], -8) ]], -8)
test("destructuring assignement with +=-", [[ test("destructuring assignment with +=-", [[
t = { x = 5, y = 1 } t = { x = 5, y = 1 }
local x, y = 5, 9 local x, y = 5, 9
{x, y} +=- t {x, y} +=- t
return x + y return x + y
]], 6) ]], 6)
test("destructuring assignement with =-", [[ test("destructuring assignment with =-", [[
t = { x = 5, y = 1 } t = { x = 5, y = 1 }
local x, y = 5, 9 local x, y = 5, 9
{x, y} =- t {x, y} =- t
return x + y return x + y
]], -8) ]], -8)
test("destructuring assignement with let", [[ test("destructuring assignment with let", [[
t = { x = 5, y = 1 } t = { x = 5, y = 1 }
let {x, y} = t let {x, y} = t
return x + y return x + y
]], 6) ]], 6)
test("destructuring assignement with for in", [[ test("destructuring assignment with for in", [[
t = {{ x = 5, y = 1 }} t = {{ x = 5, y = 1 }}
for k, {x, y} in pairs(t) do for k, {x, y} in pairs(t) do
return x + y return x + y
end end
]], 6) ]], 6)
test("destructuring assignement with if with assignement", [[ test("destructuring assignment with if with assignment", [[
t = { x = 5, y = 1 } t = { x = 5, y = 1 }
if {x, y} = t then if {x, y} = t then
return x + y return x + y
end end
]], 6) ]], 6)
test("destructuring assignement with if-elseif with assignement", [[ test("destructuring assignment with if-elseif with assignment", [[
t = { x = 5, y = 1 } t = { x = 5, y = 1 }
if ({u} = t) and u then if ({u} = t) and u then
return 0 return 0
@ -980,56 +993,56 @@ test("destructuring assignement with if-elseif with assignement", [[
end end
]], 6) ]], 6)
test("destructuring assignement with an expression with custom name", [[ test("destructuring assignment with an expression with custom name", [[
local {o = x, y} = { o = 5, y = 1 } local {o = x, y} = { o = 5, y = 1 }
return x + y return x + y
]], 6) ]], 6)
test("destructuring assignement with local with custom name", [[ test("destructuring assignment with local with custom name", [[
t = { o = 5, y = 1 } t = { o = 5, y = 1 }
local {o = x, y} = t local {o = x, y} = t
return x + y return x + y
]], 6) ]], 6)
test("destructuring assignement with custom name", [[ test("destructuring assignment with custom name", [[
t = { o = 5, y = 1 } t = { o = 5, y = 1 }
{o = x, y} = t {o = x, y} = t
return x + y return x + y
]], 6) ]], 6)
test("destructuring assignement with += with custom name", [[ test("destructuring assignment with += with custom name", [[
t = { o = 5, y = 1 } t = { o = 5, y = 1 }
local x, y = 5, 9 local x, y = 5, 9
{o = x, y} += t {o = x, y} += t
return x + y return x + y
]], 20) ]], 20)
test("destructuring assignement with =- with custom name", [[ test("destructuring assignment with =- with custom name", [[
t = { o = 5, y = 1 } t = { o = 5, y = 1 }
local x, y = 5, 9 local x, y = 5, 9
{o = x, y} =- t {o = x, y} =- t
return x + y return x + y
]], -8) ]], -8)
test("destructuring assignement with +=- with custom name", [[ test("destructuring assignment with +=- with custom name", [[
t = { o = 5, y = 1 } t = { o = 5, y = 1 }
local x, y = 5, 9 local x, y = 5, 9
{o = x, y} +=- t {o = x, y} +=- t
return x + y return x + y
]], 6) ]], 6)
test("destructuring assignement with let with custom name", [[ test("destructuring assignment with let with custom name", [[
t = { o = 5, y = 1 } t = { o = 5, y = 1 }
let {o = x, y} = t let {o = x, y} = t
return x + y return x + y
]], 6) ]], 6)
test("destructuring assignement with for in with custom name", [[ test("destructuring assignment with for in with custom name", [[
t = {{ o = 5, y = 1 }} t = {{ o = 5, y = 1 }}
for k, {o = x, y} in pairs(t) do for k, {o = x, y} in pairs(t) do
return x + y return x + y
end end
]], 6) ]], 6)
test("destructuring assignement with if with assignement with custom name", [[ test("destructuring assignment with if with assignment with custom name", [[
t = { o = 5, y = 1 } t = { o = 5, y = 1 }
if {o = x, y} = t then if {o = x, y} = t then
return x + y return x + y
end end
]], 6) ]], 6)
test("destructuring assignement with if-elseif with assignement with custom name", [[ test("destructuring assignment with if-elseif with assignment with custom name", [[
t = { o = 5, y = 1 } t = { o = 5, y = 1 }
if ({x} = t) and x then if ({x} = t) and x then
return 0 return 0
@ -1038,56 +1051,56 @@ test("destructuring assignement with if-elseif with assignement with custom name
end end
]], 6) ]], 6)
test("destructuring assignement with an expression with expression as key", [[ test("destructuring assignment with an expression with expression as key", [[
local {[1] = x, y} = { 5, y = 1 } local {[1] = x, y} = { 5, y = 1 }
return x + y return x + y
]], 6) ]], 6)
test("destructuring assignement with local with expression as key", [[ test("destructuring assignment with local with expression as key", [[
t = { 5, y = 1 } t = { 5, y = 1 }
local {[1] = x, y} = t local {[1] = x, y} = t
return x + y return x + y
]], 6) ]], 6)
test("destructuring assignement with expression as key", [[ test("destructuring assignment with expression as key", [[
t = { 5, y = 1 } t = { 5, y = 1 }
{[1] = x, y} = t {[1] = x, y} = t
return x + y return x + y
]], 6) ]], 6)
test("destructuring assignement with += with expression as key", [[ test("destructuring assignment with += with expression as key", [[
t = { 5, y = 1 } t = { 5, y = 1 }
local x, y = 5, 9 local x, y = 5, 9
{[1] = x, y} += t {[1] = x, y} += t
return x + y return x + y
]], 20) ]], 20)
test("destructuring assignement with =- with expression as key", [[ test("destructuring assignment with =- with expression as key", [[
t = { 5, y = 1 } t = { 5, y = 1 }
local x, y = 5, 9 local x, y = 5, 9
{[1] = x, y} =- t {[1] = x, y} =- t
return x + y return x + y
]], -8) ]], -8)
test("destructuring assignement with +=- with expression as key", [[ test("destructuring assignment with +=- with expression as key", [[
t = { 5, y = 1 } t = { 5, y = 1 }
local x, y = 5, 9 local x, y = 5, 9
{[1] = x, y} +=- t {[1] = x, y} +=- t
return x + y return x + y
]], 6) ]], 6)
test("destructuring assignement with let with expression as key", [[ test("destructuring assignment with let with expression as key", [[
t = { 5, y = 1 } t = { 5, y = 1 }
let {[1] = x, y} = t let {[1] = x, y} = t
return x + y return x + y
]], 6) ]], 6)
test("destructuring assignement with for in with expression as key", [[ test("destructuring assignment with for in with expression as key", [[
t = {{ 5, y = 1 }} t = {{ 5, y = 1 }}
for k, {[1] = x, y} in pairs(t) do for k, {[1] = x, y} in pairs(t) do
return x + y return x + y
end end
]], 6) ]], 6)
test("destructuring assignement with if with assignement with expression as key", [[ test("destructuring assignment with if with assignment with expression as key", [[
t = { 5, y = 1 } t = { 5, y = 1 }
if {[1] = x, y} = t then if {[1] = x, y} = t then
return x + y return x + y
end end
]], 6) ]], 6)
test("destructuring assignement with if-elseif with assignement with expression as key", [[ test("destructuring assignment with if-elseif with assignment with expression as key", [[
t = { 5, y = 1 } t = { 5, y = 1 }
if ({x} = t) and x then if ({x} = t) and x then
return 0 return 0
@ -1096,6 +1109,80 @@ test("destructuring assignement with if-elseif with assignement with expression
end end
]], 6) ]], 6)
-- named varargs
test("named varargs", [[
function fn(...x)
return table.concat(x, "-")
end
return fn("hello", "world")
]], "hello-world")
test("named varargs with preceding arguments", [[
function fn(a, ...x)
return a..table.concat(x, "-")
end
return fn("hey! ", "hello", "world")
]], "hey! hello-world")
-- variable attributes
if _VERSION >= "Lua 5.4" then
test("variable attributes", [[
local a <const>, b, c <close>
b = 42
]])
test("variable attributes: const violation", [[
local a <const>, b, c <close>
b = 42
a = 42
]], { "loadError", "attempt to assign to const variable 'a'" })
test("variable attributes: const violation 2", [[
local <const> d, e, f
e = 42
]], { "loadError", "attempt to assign to const variable 'e'" })
test("variable attributes shortcut", [[
const a
a = 42
]], { "loadError", "attempt to assign to const variable 'a'" })
end
-- global keyword
test("collective global variable declaration", [[
foo = 42
do
global *
end
foo = 12
]])
if _VERSION >= "Lua 5.5" then
test("global variable declaration", [[
do
global foo
global <const> bar
end
foo = 42
assert(not pcall(function() foo = 42 end))
]])
test("collective global variable declaration with attribute", [[
foo = 42
do
global<const> *
end
assert(not pcall(function() foo = 12 end))
]])
end
-- bitwise operators
if _VERSION >= "Lua 5.2" or bit then
test("bitwise operators: &", "return 0xDEAD & 0xBEEF", 40621)
test("bitwise operators: |", "return 0xDEAD | 0xBEEF", 65263)
test("bitwise operators: ~", "return 0xDEAD ~ 0xBEEF", 24642)
test("bitwise operators: >>", "return 0xDEAD >> 2", 14251)
test("bitwise operators: <<", "return 0xDEAD << 2", 228020)
test("bitwise operators: unary ~", "return ~0xDEAD", -57006)
end
-- results -- results
local resultCounter = {} local resultCounter = {}
local testCounter = 0 local testCounter = 0