"use strict"; const test = require('tape'); const tests = require("./tests.js"); const toByteCode = tests.toByteCode; const lauxlib = require("../src/lauxlib.js"); const lua = require('../src/lua.js'); test('luaL_newstate, lua_pushnil, luaL_typename', function (t) { let L; t.plan(2); t.doesNotThrow(function () { L = lauxlib.luaL_newstate(); lua.lua_pushnil(L); }, "JS Lua program ran without error"); t.deepEqual( lauxlib.luaL_typename(L, -1), "nil".split('').map(e => e.charCodeAt(0)), "Correct element(s) on the stack" ); }); test('lua_pushnumber', function (t) { let L; t.plan(3); t.doesNotThrow(function () { L = lauxlib.luaL_newstate(); lua.lua_pushnumber(L, 10.5); }, "JS Lua program ran without error"); t.deepEqual( lauxlib.luaL_typename(L, -1), "number".split('').map(e => e.charCodeAt(0)), "Correct element(s) on the stack" ); t.strictEqual( lua.lua_tonumber(L, -1), 10.5, "top is correct" ); }); test('lua_pushinteger', function (t) { let L; t.plan(3); t.doesNotThrow(function () { L = lauxlib.luaL_newstate(); lua.lua_pushinteger(L, 10); }, "JS Lua program ran without error"); t.deepEqual( lauxlib.luaL_typename(L, -1), "number".split('').map(e => e.charCodeAt(0)), "Correct element(s) on the stack" ); t.strictEqual( lua.lua_tointeger(L, -1), 10, "top is correct" ); }); test('lua_pushliteral', function (t) { let L; t.plan(3); t.doesNotThrow(function () { L = lauxlib.luaL_newstate(); lua.lua_pushliteral(L, "hello"); }, "JS Lua program ran without error"); t.deepEqual( lauxlib.luaL_typename(L, -1), "string".split('').map(e => e.charCodeAt(0)), "Correct element(s) on the stack" ); t.strictEqual( lua.lua_tojsstring(L, -1), "hello", "top is correct" ); }); test('lua_pushboolean', function (t) { let L; t.plan(3); t.doesNotThrow(function () { L = lauxlib.luaL_newstate(); lua.lua_pushboolean(L, true); }, "JS Lua program ran without error"); t.deepEqual( lauxlib.luaL_typename(L, -1), "boolean".split('').map(e => e.charCodeAt(0)), "Correct element(s) on the stack" ); t.strictEqual( lua.lua_toboolean(L, -1), true, "top is correct" ); }); test('lua_pushvalue', function (t) { let L; t.plan(5); t.doesNotThrow(function () { L = lauxlib.luaL_newstate(); lua.lua_pushliteral(L, "hello"); lua.lua_pushvalue(L, -1); }, "JS Lua program ran without error"); t.deepEqual( lauxlib.luaL_typename(L, -1), "string".split('').map(e => e.charCodeAt(0)), "Correct element(s) on the stack" ); t.deepEqual( lauxlib.luaL_typename(L, -2), "string".split('').map(e => e.charCodeAt(0)), "Correct element(s) on the stack" ); t.strictEqual( lua.lua_tojsstring(L, -1), "hello", "Correct element(s) on the stack" ); t.strictEqual( lua.lua_tojsstring(L, -2), "hello", "Correct element(s) on the stack" ); }); test('lua_pushjsclosure', function (t) { let L; t.plan(2); t.doesNotThrow(function () { let fn = function(L) { return 0; }; L = lauxlib.luaL_newstate(); lua.lua_pushliteral(L, "a value associated to the C closure"); lua.lua_pushjsclosure(L, fn, 1); }, "JS Lua program ran without error"); t.deepEqual( lauxlib.luaL_typename(L, -1), "function".split('').map(e => e.charCodeAt(0)), "Correct element(s) on the stack" ); }); test('lua_pushjsfunction', function (t) { let L; t.plan(2); t.doesNotThrow(function () { let fn = function(L) { return 0; }; L = lauxlib.luaL_newstate(); lua.lua_pushjsfunction(L, fn); }, "JS Lua program ran without error"); t.deepEqual( lauxlib.luaL_typename(L, -1), "function".split('').map(e => e.charCodeAt(0)), "Correct element(s) on the stack" ); }); test('lua_call (calling a light JS function)', function (t) { let L; t.plan(2); t.doesNotThrow(function () { let fn = function(L) { lua.lua_pushliteral(L, "hello"); return 1; }; L = lauxlib.luaL_newstate(); lua.lua_pushjsfunction(L, fn); lua.lua_call(L, 0, 1); }, "JS Lua program ran without error"); t.strictEqual( lua.lua_tojsstring(L, -1), "hello", "top is correct" ); }); test('lua_call (calling a JS closure)', function (t) { let L; t.plan(2); t.doesNotThrow(function () { let fn = function(L) { lua.lua_pushstring(L, lua.lua_tostring(L, lua.lua_upvalueindex(1))); return 1; }; L = lauxlib.luaL_newstate(); lua.lua_pushliteral(L, "upvalue hello !"); lua.lua_pushjsclosure(L, fn, 1); lua.lua_call(L, 0, 1); }, "JS Lua program ran without error"); t.strictEqual( lua.lua_tojsstring(L, -1), "upvalue hello !", "top is correct" ); }); test('lua_pcall (calling a light JS function)', function (t) { let L; t.plan(2); t.doesNotThrow(function () { let fn = function(L) { lua.lua_pushliteral(L, "hello"); return 1; }; L = lauxlib.luaL_newstate(); lua.lua_pushjsfunction(L, fn); lua.lua_pcall(L, 0, 1, 0); }, "JS Lua program ran without error"); t.strictEqual( lua.lua_tojsstring(L, -1), "hello", "top is correct" ); }); test('lua_pcall that breaks', function (t) { let L; t.plan(1); t.doesNotThrow(function () { let fn = function(L) { return "undefined_value"; }; L = lauxlib.luaL_newstate(); lua.lua_pushjsfunction(L, fn); lua.lua_pcall(L, 0, 1, 0); }, "JS Lua program ran without error"); console.log(L.stack[L.top - 1].value); }); test('lua_pop', function (t) { let L; t.plan(2); t.doesNotThrow(function () { L = lauxlib.luaL_newstate(); lua.lua_pushliteral(L, "hello"); lua.lua_pushliteral(L, "world"); lua.lua_pop(L, 1); }, "JS Lua program ran without error"); t.strictEqual( lua.lua_tojsstring(L, -1), "hello", "Correct element(s) on the stack" ); }); test('lua_load and lua_call it', function (t) { let luaCode = ` local a = "JS > Lua > JS \o/" return a `, L; t.plan(2); t.doesNotThrow(function () { let bc = toByteCode(luaCode); L = lauxlib.luaL_newstate(); lua.lua_load(L, null, bc, lua.to_luastring("test-lua_load"), lua.to_luastring("binary")); lua.lua_call(L, 0, 1); }, "JS Lua program ran without error"); t.strictEqual( lua.lua_tojsstring(L, -1), "JS > Lua > JS \o/", "Correct element(s) on the stack" ); }); test('lua script reads js upvalues', function (t) { let luaCode = ` return js .. " world" `, L; t.plan(2); t.doesNotThrow(function () { let bc = toByteCode(luaCode); L = lauxlib.luaL_newstate(); lua.lua_load(L, null, bc, lua.to_luastring("test-lua_load"), lua.to_luastring("binary")); lua.lua_pushliteral(L, "hello"); lua.lua_setglobal(L, lua.to_luastring("js")); lua.lua_call(L, 0, 1); }, "JS Lua program ran without error"); t.strictEqual( lua.lua_tojsstring(L, -1), "hello world", "Correct element(s) on the stack" ); }); test('lua_createtable', function (t) { let L; t.plan(2); t.doesNotThrow(function () { L = lauxlib.luaL_newstate(); lua.lua_createtable(L, 3, 3); }, "JS Lua program ran without error"); t.ok( lua.lua_istable(L, -1), "Correct element(s) on the stack" ); }); test('lua_newtable', function (t) { let L; t.plan(2); t.doesNotThrow(function () { L = lauxlib.luaL_newstate(); lua.lua_newtable(L); }, "JS Lua program ran without error"); t.ok( lua.lua_istable(L, -1), "Correct element(s) on the stack" ); }); test('lua_settable, lua_gettable', function (t) { let L; t.plan(2); t.doesNotThrow(function () { L = lauxlib.luaL_newstate(); lua.lua_newtable(L); lua.lua_pushliteral(L, "key"); lua.lua_pushliteral(L, "value"); lua.lua_settable(L, -3); lua.lua_pushliteral(L, "key"); lua.lua_gettable(L, -2); }, "JS Lua program ran without error"); t.strictEqual( lua.lua_tojsstring(L, -1), "value", "Correct element(s) on the stack" ); });