fengari
Version:
A Lua VM written in JS ES6 targeting the browser
311 lines (246 loc) • 8.5 kB
JavaScript
"use strict";
const lua = require('../src/lua.js');
const lauxlib = require('../src/lauxlib.js');
const lualib = require('../src/lualib.js');
const {to_luastring} = require("../src/fengaricore.js");
test('debug.sethook', () => {
let L = lauxlib.luaL_newstate();
if (!L) throw Error("failed to create lua state");
let luaCode = `
local result = ""
debug.sethook(function (event)
result = result .. event .. " "
end, "crl", 1)
local l = function() end
l()
l()
l()
return result
`;
{
lualib.luaL_openlibs(L);
expect(lauxlib.luaL_loadstring(L, to_luastring(luaCode))).toBe(lua.LUA_OK);
lua.lua_call(L, 0, -1);
}
expect(lua.lua_tojsstring(L, -1))
.toBe("return count line count line count line call count line return count line count line call count line return count line count line call count line return count line ");
});
test('debug.gethook', () => {
let L = lauxlib.luaL_newstate();
if (!L) throw Error("failed to create lua state");
let luaCode = `
local result = ""
debug.sethook(function (event)
result = result .. event .. " "
end, "crl", 1)
local l = function() end
l()
l()
l()
return debug.gethook()
`;
{
lualib.luaL_openlibs(L);
expect(lauxlib.luaL_loadstring(L, to_luastring(luaCode))).toBe(lua.LUA_OK);
lua.lua_call(L, 0, -1);
}
expect(lua.lua_typename(L, lua.lua_type(L, -3)))
.toEqual(to_luastring("function"));
expect(lua.lua_tojsstring(L, -2)).toBe("crl");
expect(lua.lua_tointeger(L, -1)).toBe(1);
});
test('debug.getlocal', () => {
let L = lauxlib.luaL_newstate();
if (!L) throw Error("failed to create lua state");
let luaCode = `
local alocal = "alocal"
local another = "another"
local result = ""
local l = function()
local infunction = "infunction"
local anotherin = "anotherin"
result = table.concat(table.pack(debug.getlocal(2, 1)), " ")
.. table.concat(table.pack(debug.getlocal(2, 2)), " ")
.. table.concat(table.pack(debug.getlocal(1, 1)), " ")
.. table.concat(table.pack(debug.getlocal(1, 2)), " ")
end
l()
return result
`;
{
lualib.luaL_openlibs(L);
expect(lauxlib.luaL_loadstring(L, to_luastring(luaCode))).toBe(lua.LUA_OK);
lua.lua_call(L, 0, -1);
}
expect(lua.lua_tojsstring(L, -1))
.toBe("alocal alocalanother anotherinfunction infunctionanotherin anotherin");
});
test('debug.setlocal', () => {
let L = lauxlib.luaL_newstate();
if (!L) throw Error("failed to create lua state");
let luaCode = `
local alocal = "alocal"
local another = "another"
local l = function()
local infunction = "infunction"
local anotherin = "anotherin"
debug.setlocal(2, 1, 1)
debug.setlocal(2, 2, 2)
debug.setlocal(1, 1, 3)
debug.setlocal(1, 2, 4)
return infunction, anotherin
end
local a, b = l()
return alocal, another, a, b
`;
{
lualib.luaL_openlibs(L);
expect(lauxlib.luaL_loadstring(L, to_luastring(luaCode))).toBe(lua.LUA_OK);
lua.lua_call(L, 0, -1);
}
expect(lua.lua_tointeger(L, -4)).toBe(1);
expect(lua.lua_tointeger(L, -3)).toBe(2);
expect(lua.lua_tointeger(L, -2)).toBe(3);
expect(lua.lua_tointeger(L, -1)).toBe(4);
});
test('debug.upvalueid', () => {
let L = lauxlib.luaL_newstate();
if (!L) throw Error("failed to create lua state");
let luaCode = `
local upvalue = "upvalue"
local l = function()
return upvalue
end
return debug.upvalueid(l, 1)
`;
{
lualib.luaL_openlibs(L);
expect(lauxlib.luaL_loadstring(L, to_luastring(luaCode))).toBe(lua.LUA_OK);
lua.lua_call(L, 0, -1);
}
expect(lua.lua_touserdata(L, -1)).toBeTruthy();
});
test('debug.upvaluejoin', () => {
let L = lauxlib.luaL_newstate();
if (!L) throw Error("failed to create lua state");
let luaCode = `
local upvalue1 = "upvalue1"
local upvalue2 = "upvalue2"
local l1 = function()
return upvalue1
end
local l2 = function()
return upvalue2
end
debug.upvaluejoin(l1, 1, l2, 1)
return l1()
`;
{
lualib.luaL_openlibs(L);
expect(lauxlib.luaL_loadstring(L, to_luastring(luaCode))).toBe(lua.LUA_OK);
lua.lua_call(L, 0, -1);
}
expect(lua.lua_tojsstring(L, -1))
.toBe("upvalue2");
});
test('debug.traceback (with a global)', () => {
let L = lauxlib.luaL_newstate();
if (!L) throw Error("failed to create lua state");
let luaCode = `
local trace
rec = function(n)
n = n or 0
if n < 10 then
rec(n + 1)
else
trace = debug.traceback()
end
end
rec()
return trace
`;
{
lualib.luaL_openlibs(L);
luaCode = to_luastring(luaCode);
lauxlib.luaL_loadbuffer(L, luaCode, luaCode.length, to_luastring("traceback-test"));
lua.lua_call(L, 0, -1);
}
expect(lua.lua_tojsstring(L, -1))
.toBe(`stack traceback:
\t[string "traceback-test"]:9: in function 'rec'
\t[string "traceback-test"]:7: in function 'rec'
\t[string "traceback-test"]:7: in function 'rec'
\t[string "traceback-test"]:7: in function 'rec'
\t[string "traceback-test"]:7: in function 'rec'
\t[string "traceback-test"]:7: in function 'rec'
\t[string "traceback-test"]:7: in function 'rec'
\t[string "traceback-test"]:7: in function 'rec'
\t[string "traceback-test"]:7: in function 'rec'
\t[string "traceback-test"]:7: in function 'rec'
\t[string "traceback-test"]:7: in function 'rec'
\t[string "traceback-test"]:13: in main chunk`);
});
test('debug.traceback (with a upvalue)', () => {
let L = lauxlib.luaL_newstate();
if (!L) throw Error("failed to create lua state");
let luaCode = `
local trace
local rec
rec = function(n)
n = n or 0
if n < 10 then
rec(n + 1)
else
trace = debug.traceback()
end
end
rec()
return trace
`;
{
lualib.luaL_openlibs(L);
luaCode = to_luastring(luaCode);
lauxlib.luaL_loadbuffer(L, luaCode, luaCode.length, to_luastring("traceback-test"));
lua.lua_call(L, 0, -1);
}
expect(lua.lua_tojsstring(L, -1))
.toBe(`stack traceback:
\t[string "traceback-test"]:10: in upvalue 'rec'
\t[string "traceback-test"]:8: in upvalue 'rec'
\t[string "traceback-test"]:8: in upvalue 'rec'
\t[string "traceback-test"]:8: in upvalue 'rec'
\t[string "traceback-test"]:8: in upvalue 'rec'
\t[string "traceback-test"]:8: in upvalue 'rec'
\t[string "traceback-test"]:8: in upvalue 'rec'
\t[string "traceback-test"]:8: in upvalue 'rec'
\t[string "traceback-test"]:8: in upvalue 'rec'
\t[string "traceback-test"]:8: in upvalue 'rec'
\t[string "traceback-test"]:8: in local 'rec'
\t[string "traceback-test"]:14: in main chunk`);
});
test('debug.getinfo', () => {
let L = lauxlib.luaL_newstate();
if (!L) throw Error("failed to create lua state");
let luaCode = `
local alocal = function(p1, p2) end
global = function() return alocal end
local d1 = debug.getinfo(alocal)
local d2 = debug.getinfo(global)
return d1.short_src, d1.nups, d1.what, d1.nparams,
d2.short_src, d2.nups, d2.what, d2.nparams
`;
{
lualib.luaL_openlibs(L);
luaCode = to_luastring(luaCode);
lauxlib.luaL_loadbuffer(L, luaCode, luaCode.length, to_luastring("getinfo-test"));
lua.lua_call(L, 0, -1);
}
expect(lua.lua_tojsstring(L, -8)).toBe(`[string "getinfo-test"]`);
expect(lua.lua_tointeger(L, -7)).toBe(0);
expect(lua.lua_tojsstring(L, -6)).toBe(`Lua`);
expect(lua.lua_tointeger(L, -5)).toBe(2);
expect(lua.lua_tojsstring(L, -4)).toBe(`[string "getinfo-test"]`);
expect(lua.lua_tointeger(L, -3)).toBe(1);
expect(lua.lua_tojsstring(L, -2)).toBe(`Lua`);
expect(lua.lua_tointeger(L, -1)).toBe(0);
});