To do so, a few dependencies have been imported: * external/bsd/lutok * external/mit/lua * external/public-domain/sqlite * external/public-domain/xz The Kyua framework is the new generation of ATF (Automated Test Framework), it is composed of: * external/bsd/atf * external/bsd/kyua-atf-compat * external/bsd/kyua-cli * external/bsd/kyua-tester * tests Kyua/ATF being written in C++, it depends on libstdc++ which is provided by GCC. As this is not part of the sources, Kyua is only compiled when the native GCC utils are installed. To install Kyua do the following: * In a cross-build enviromnent, add the following to the build.sh commandline: -V MKBINUTILS=yes -V MKGCCCMDS=yes WARNING: At this point the import is still experimental, and not supported on native builds (a.k.a make build). Change-Id: I26aee23c5bbd2d64adcb7c1beb98fe0d479d7ada
1404 lines
40 KiB
C++
1404 lines
40 KiB
C++
// Copyright 2011 Google Inc.
|
|
// All rights reserved.
|
|
//
|
|
// Redistribution and use in source and binary forms, with or without
|
|
// modification, are permitted provided that the following conditions are
|
|
// met:
|
|
//
|
|
// * Redistributions of source code must retain the above copyright
|
|
// notice, this list of conditions and the following disclaimer.
|
|
// * Redistributions in binary form must reproduce the above copyright
|
|
// notice, this list of conditions and the following disclaimer in the
|
|
// documentation and/or other materials provided with the distribution.
|
|
// * Neither the name of Google Inc. nor the names of its contributors
|
|
// may be used to endorse or promote products derived from this software
|
|
// without specific prior written permission.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
#include "state.ipp"
|
|
|
|
#include <cstring>
|
|
#include <fstream>
|
|
#include <iostream>
|
|
#include <stdexcept>
|
|
|
|
#include <atf-c++.hpp>
|
|
#include <lua.hpp>
|
|
|
|
#include "c_gate.hpp"
|
|
#include "exceptions.hpp"
|
|
#include "test_utils.hpp"
|
|
|
|
|
|
// A note about the lutok::state tests.
|
|
//
|
|
// The methods of lutok::state are, in general, thin wrappers around the
|
|
// corresponding Lua C API methods. The tests below are simple unit tests that
|
|
// ensure that these functions just delegate the calls to the Lua library. We
|
|
// do not intend to test the validity of the methods themselves (that's the
|
|
// job of the Lua authors). That said, we test those conditions we rely on,
|
|
// such as the reporting of errors and the default values to the API.
|
|
//
|
|
// Lastly, for every test case that stresses a single lutok::state method, we
|
|
// only call that method directly. All other Lua state manipulation operations
|
|
// are performed by means of direct calls to the Lua C API. This is to ensure
|
|
// that the wrapped methods are really talking to Lua.
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
/// Checks if a symbol is available.
|
|
///
|
|
/// \param state The Lua state.
|
|
/// \param symbol The symbol to check for.
|
|
///
|
|
/// \return True if the symbol is defined, false otherwise.
|
|
static bool
|
|
is_available(lutok::state& state, const char* symbol)
|
|
{
|
|
luaL_loadstring(raw(state), (std::string("return ") + symbol).c_str());
|
|
const bool ok = (lua_pcall(raw(state), 0, 1, 0) == 0 &&
|
|
!lua_isnil(raw(state), -1));
|
|
lua_pop(raw(state), 1);
|
|
std::cout << "Symbol " << symbol << (ok ? " found\n" : " not found\n");
|
|
return ok;
|
|
}
|
|
|
|
|
|
/// Checks that no modules are present or that only one has been loaded.
|
|
///
|
|
/// \post The test case terminates if there is any module present when expected
|
|
/// is empty or if there two modules loaded when expected is defined.
|
|
///
|
|
/// \param state The Lua state.
|
|
/// \param expected The module to expect. Empty if no modules are allowed.
|
|
static void
|
|
check_modules(lutok::state& state, const std::string& expected)
|
|
{
|
|
std::cout << "Checking loaded modules" <<
|
|
(expected.empty() ? "" : (" (" + expected + " expected)")) << "\n";
|
|
ATF_REQUIRE(!((expected == "base") ^ (is_available(state, "assert"))));
|
|
ATF_REQUIRE(!((expected == "string") ^
|
|
(is_available(state, "string.byte"))));
|
|
ATF_REQUIRE(!((expected == "table") ^
|
|
(is_available(state, "table.concat"))));
|
|
}
|
|
|
|
|
|
/// A C closure that returns its two integral upvalues.
|
|
///
|
|
/// \post stack(-2) contains the first upvalue.
|
|
/// \post stack(-1) contains the second upvalue.
|
|
///
|
|
/// \param raw_state The raw Lua state.
|
|
///
|
|
/// \return The number of result values, i.e. 2.
|
|
static int
|
|
c_get_upvalues(lua_State* raw_state)
|
|
{
|
|
lutok::state state = lutok::state_c_gate::connect(raw_state);
|
|
const int i1 = lua_tointeger(raw_state, state.upvalue_index(1));
|
|
const int i2 = lua_tointeger(raw_state, state.upvalue_index(2));
|
|
lua_pushinteger(raw_state, i1);
|
|
lua_pushinteger(raw_state, i2);
|
|
return 2;
|
|
}
|
|
|
|
|
|
/// A custom C++ multiply function with one of its factors on its closure.
|
|
///
|
|
/// \pre stack(-1) contains the second factor.
|
|
/// \post stack(-1) contains the product of the two input factors.
|
|
///
|
|
/// \param state The Lua state.
|
|
///
|
|
/// \return The number of result values, i.e. 1.
|
|
static int
|
|
cxx_multiply_closure(lutok::state& state)
|
|
{
|
|
const int f1 = lua_tointeger(raw(state), lua_upvalueindex(1));
|
|
const int f2 = lua_tointeger(raw(state), -1);
|
|
lua_pushinteger(raw(state), f1 * f2);
|
|
return 1;
|
|
}
|
|
|
|
|
|
/// A custom C++ integral division function for Lua.
|
|
///
|
|
/// \pre stack(-2) contains the dividend.
|
|
/// \pre stack(-1) contains the divisor.
|
|
/// \post stack(-2) contains the quotient of the division.
|
|
/// \post stack(-1) contains the remainder of the division.
|
|
///
|
|
/// \param state The Lua state.
|
|
///
|
|
/// \return The number of result values, i.e. 1.
|
|
///
|
|
/// \throw std::runtime_error If the divisor is zero.
|
|
/// \throw std::string If the dividend or the divisor are negative. This is an
|
|
/// exception not derived from std::exception on purpose to ensure that the
|
|
/// C++ wrapping correctly captures any exception regardless of its type.
|
|
static int
|
|
cxx_divide(lutok::state& state)
|
|
{
|
|
const int dividend = state.to_integer(-2);
|
|
const int divisor = state.to_integer(-1);
|
|
if (divisor == 0)
|
|
throw std::runtime_error("Divisor is 0");
|
|
if (dividend < 0 || divisor < 0)
|
|
throw std::string("Cannot divide negative numbers");
|
|
state.push_integer(dividend / divisor);
|
|
state.push_integer(dividend % divisor);
|
|
return 2;
|
|
}
|
|
|
|
|
|
/// A Lua function that raises a very long error message.
|
|
///
|
|
/// \pre stack(-1) contains the length of the message to construct.
|
|
///
|
|
/// \param state The Lua state.
|
|
///
|
|
/// \return Never returns.
|
|
///
|
|
/// \throw std::runtime_error Unconditionally, with an error message formed by
|
|
/// the repetition of 'A' as many times as requested.
|
|
static int
|
|
raise_long_error(lutok::state& state)
|
|
{
|
|
const int length = state.to_integer();
|
|
throw std::runtime_error(std::string(length, 'A').c_str());
|
|
}
|
|
|
|
|
|
} // anonymous namespace
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(close);
|
|
ATF_TEST_CASE_BODY(close)
|
|
{
|
|
lutok::state state;
|
|
state.close();
|
|
// The destructor for state will run now. If it does a second close, we may
|
|
// crash, so let's see if we don't.
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(get_global__ok);
|
|
ATF_TEST_CASE_BODY(get_global__ok)
|
|
{
|
|
lutok::state state;
|
|
ATF_REQUIRE(luaL_dostring(raw(state), "test_variable = 3") == 0);
|
|
state.get_global("test_variable");
|
|
ATF_REQUIRE(lua_isnumber(raw(state), -1));
|
|
lua_pop(raw(state), 1);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(get_global__fail);
|
|
ATF_TEST_CASE_BODY(get_global__fail)
|
|
{
|
|
lutok::state state;
|
|
lua_pushinteger(raw(state), 3);
|
|
lua_replace(raw(state), LUA_GLOBALSINDEX);
|
|
REQUIRE_API_ERROR("lua_getglobal", state.get_global("test_variable"));
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(get_global__undefined);
|
|
ATF_TEST_CASE_BODY(get_global__undefined)
|
|
{
|
|
lutok::state state;
|
|
state.get_global("test_variable");
|
|
ATF_REQUIRE(lua_isnil(raw(state), -1));
|
|
lua_pop(raw(state), 1);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(get_metafield__ok);
|
|
ATF_TEST_CASE_BODY(get_metafield__ok)
|
|
{
|
|
lutok::state state;
|
|
luaL_openlibs(raw(state));
|
|
ATF_REQUIRE(luaL_dostring(raw(state), "meta = { foo = 567 }; "
|
|
"t = {}; setmetatable(t, meta)") == 0);
|
|
lua_getglobal(raw(state), "t");
|
|
ATF_REQUIRE(state.get_metafield(-1, "foo"));
|
|
ATF_REQUIRE(lua_isnumber(raw(state), -1));
|
|
ATF_REQUIRE_EQ(567, lua_tointeger(raw(state), -1));
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(get_metafield__undefined);
|
|
ATF_TEST_CASE_BODY(get_metafield__undefined)
|
|
{
|
|
lutok::state state;
|
|
luaL_openlibs(raw(state));
|
|
ATF_REQUIRE(luaL_dostring(raw(state), "meta = { foo = 567 }; "
|
|
"t = {}; setmetatable(t, meta)") == 0);
|
|
lua_getglobal(raw(state), "t");
|
|
ATF_REQUIRE(!state.get_metafield(-1, "bar"));
|
|
lua_pop(raw(state), 1);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(get_metatable__top);
|
|
ATF_TEST_CASE_BODY(get_metatable__top)
|
|
{
|
|
lutok::state state;
|
|
luaL_openlibs(raw(state));
|
|
ATF_REQUIRE(luaL_dostring(raw(state), "meta = { foo = 567 }; "
|
|
"t = {}; setmetatable(t, meta)") == 0);
|
|
lua_getglobal(raw(state), "t");
|
|
ATF_REQUIRE(state.get_metatable());
|
|
ATF_REQUIRE(lua_istable(raw(state), -1));
|
|
lua_pushstring(raw(state), "foo");
|
|
lua_gettable(raw(state), -2);
|
|
ATF_REQUIRE(lua_isnumber(raw(state), -1));
|
|
ATF_REQUIRE_EQ(567, lua_tointeger(raw(state), -1));
|
|
lua_pop(raw(state), 3);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(get_metatable__explicit);
|
|
ATF_TEST_CASE_BODY(get_metatable__explicit)
|
|
{
|
|
lutok::state state;
|
|
luaL_openlibs(raw(state));
|
|
ATF_REQUIRE(luaL_dostring(raw(state), "meta = { foo = 567 }; "
|
|
"t = {}; setmetatable(t, meta)") == 0);
|
|
lua_getglobal(raw(state), "t");
|
|
lua_pushinteger(raw(state), 5555);
|
|
ATF_REQUIRE(state.get_metatable(-2));
|
|
ATF_REQUIRE(lua_istable(raw(state), -1));
|
|
lua_pushstring(raw(state), "foo");
|
|
lua_gettable(raw(state), -2);
|
|
ATF_REQUIRE(lua_isnumber(raw(state), -1));
|
|
ATF_REQUIRE_EQ(567, lua_tointeger(raw(state), -1));
|
|
lua_pop(raw(state), 4);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(get_metatable__undefined);
|
|
ATF_TEST_CASE_BODY(get_metatable__undefined)
|
|
{
|
|
lutok::state state;
|
|
ATF_REQUIRE(luaL_dostring(raw(state), "t = {}") == 0);
|
|
lua_getglobal(raw(state), "t");
|
|
ATF_REQUIRE(!state.get_metatable(-1));
|
|
lua_pop(raw(state), 1);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(get_table__ok);
|
|
ATF_TEST_CASE_BODY(get_table__ok)
|
|
{
|
|
lutok::state state;
|
|
ATF_REQUIRE(luaL_dostring(raw(state), "t = { a = 1, bar = 234 }") == 0);
|
|
lua_getglobal(raw(state), "t");
|
|
lua_pushstring(raw(state), "bar");
|
|
state.get_table();
|
|
ATF_REQUIRE(lua_isnumber(raw(state), -1));
|
|
ATF_REQUIRE_EQ(234, lua_tointeger(raw(state), -1));
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(get_table__nil);
|
|
ATF_TEST_CASE_BODY(get_table__nil)
|
|
{
|
|
lutok::state state;
|
|
lua_pushnil(raw(state));
|
|
lua_pushinteger(raw(state), 1);
|
|
REQUIRE_API_ERROR("lua_gettable", state.get_table());
|
|
ATF_REQUIRE_EQ(2, lua_gettop(raw(state)));
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(get_table__unknown_index);
|
|
ATF_TEST_CASE_BODY(get_table__unknown_index)
|
|
{
|
|
lutok::state state;
|
|
ATF_REQUIRE(luaL_dostring(raw(state),
|
|
"the_table = { foo = 1, bar = 2 }") == 0);
|
|
lua_getglobal(raw(state), "the_table");
|
|
lua_pushstring(raw(state), "baz");
|
|
state.get_table();
|
|
ATF_REQUIRE(lua_isnil(raw(state), -1));
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(get_top);
|
|
ATF_TEST_CASE_BODY(get_top)
|
|
{
|
|
lutok::state state;
|
|
ATF_REQUIRE_EQ(0, state.get_top());
|
|
lua_pushinteger(raw(state), 3);
|
|
ATF_REQUIRE_EQ(1, state.get_top());
|
|
lua_pushinteger(raw(state), 3);
|
|
ATF_REQUIRE_EQ(2, state.get_top());
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(globals_index);
|
|
ATF_TEST_CASE_BODY(globals_index)
|
|
{
|
|
lutok::state state;
|
|
ATF_REQUIRE(luaL_dostring(raw(state), "global_variable = 'hello'") == 0);
|
|
lua_pushvalue(raw(state), lutok::globals_index);
|
|
lua_pushstring(raw(state), "global_variable");
|
|
lua_gettable(raw(state), -2);
|
|
ATF_REQUIRE(lua_isstring(raw(state), -1));
|
|
ATF_REQUIRE(std::strcmp("hello", lua_tostring(raw(state), -1)) == 0);
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(insert);
|
|
ATF_TEST_CASE_BODY(insert)
|
|
{
|
|
lutok::state state;
|
|
lua_pushinteger(raw(state), 1);
|
|
lua_pushinteger(raw(state), 2);
|
|
lua_pushinteger(raw(state), 3);
|
|
lua_pushinteger(raw(state), 4);
|
|
state.insert(-3);
|
|
ATF_REQUIRE_EQ(3, lua_tointeger(raw(state), -1));
|
|
ATF_REQUIRE_EQ(2, lua_tointeger(raw(state), -2));
|
|
ATF_REQUIRE_EQ(4, lua_tointeger(raw(state), -3));
|
|
ATF_REQUIRE_EQ(1, lua_tointeger(raw(state), -4));
|
|
lua_pop(raw(state), 4);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(is_boolean__empty);
|
|
ATF_TEST_CASE_BODY(is_boolean__empty)
|
|
{
|
|
lutok::state state;
|
|
ATF_REQUIRE(!state.is_boolean());
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(is_boolean__top);
|
|
ATF_TEST_CASE_BODY(is_boolean__top)
|
|
{
|
|
lutok::state state;
|
|
lua_pushnil(raw(state));
|
|
ATF_REQUIRE(!state.is_boolean());
|
|
lua_pushboolean(raw(state), 1);
|
|
ATF_REQUIRE(state.is_boolean());
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(is_boolean__explicit);
|
|
ATF_TEST_CASE_BODY(is_boolean__explicit)
|
|
{
|
|
lutok::state state;
|
|
lua_pushboolean(raw(state), 1);
|
|
ATF_REQUIRE(state.is_boolean(-1));
|
|
lua_pushinteger(raw(state), 5);
|
|
ATF_REQUIRE(!state.is_boolean(-1));
|
|
ATF_REQUIRE(state.is_boolean(-2));
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(is_function__empty);
|
|
ATF_TEST_CASE_BODY(is_function__empty)
|
|
{
|
|
lutok::state state;
|
|
ATF_REQUIRE(!state.is_function());
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(is_function__top);
|
|
ATF_TEST_CASE_BODY(is_function__top)
|
|
{
|
|
lutok::state state;
|
|
luaL_dostring(raw(state), "function my_func(a, b) return a + b; end");
|
|
|
|
lua_pushnil(raw(state));
|
|
ATF_REQUIRE(!state.is_function());
|
|
lua_getglobal(raw(state), "my_func");
|
|
ATF_REQUIRE(state.is_function());
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(is_function__explicit);
|
|
ATF_TEST_CASE_BODY(is_function__explicit)
|
|
{
|
|
lutok::state state;
|
|
luaL_dostring(raw(state), "function my_func(a, b) return a + b; end");
|
|
|
|
lua_getglobal(raw(state), "my_func");
|
|
ATF_REQUIRE(state.is_function(-1));
|
|
lua_pushinteger(raw(state), 5);
|
|
ATF_REQUIRE(!state.is_function(-1));
|
|
ATF_REQUIRE(state.is_function(-2));
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(is_nil__empty);
|
|
ATF_TEST_CASE_BODY(is_nil__empty)
|
|
{
|
|
lutok::state state;
|
|
ATF_REQUIRE(state.is_nil());
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(is_nil__top);
|
|
ATF_TEST_CASE_BODY(is_nil__top)
|
|
{
|
|
lutok::state state;
|
|
lua_pushnil(raw(state));
|
|
ATF_REQUIRE(state.is_nil());
|
|
lua_pushinteger(raw(state), 5);
|
|
ATF_REQUIRE(!state.is_nil());
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(is_nil__explicit);
|
|
ATF_TEST_CASE_BODY(is_nil__explicit)
|
|
{
|
|
lutok::state state;
|
|
lua_pushnil(raw(state));
|
|
ATF_REQUIRE(state.is_nil(-1));
|
|
lua_pushinteger(raw(state), 5);
|
|
ATF_REQUIRE(!state.is_nil(-1));
|
|
ATF_REQUIRE(state.is_nil(-2));
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(is_number__empty);
|
|
ATF_TEST_CASE_BODY(is_number__empty)
|
|
{
|
|
lutok::state state;
|
|
ATF_REQUIRE(!state.is_number());
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(is_number__top);
|
|
ATF_TEST_CASE_BODY(is_number__top)
|
|
{
|
|
lutok::state state;
|
|
lua_pushnil(raw(state));
|
|
ATF_REQUIRE(!state.is_number());
|
|
lua_pushinteger(raw(state), 5);
|
|
ATF_REQUIRE(state.is_number());
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(is_number__explicit);
|
|
ATF_TEST_CASE_BODY(is_number__explicit)
|
|
{
|
|
lutok::state state;
|
|
lua_pushnil(raw(state));
|
|
ATF_REQUIRE(!state.is_number(-1));
|
|
lua_pushinteger(raw(state), 5);
|
|
ATF_REQUIRE(state.is_number(-1));
|
|
ATF_REQUIRE(!state.is_number(-2));
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(is_string__empty);
|
|
ATF_TEST_CASE_BODY(is_string__empty)
|
|
{
|
|
lutok::state state;
|
|
ATF_REQUIRE(!state.is_string());
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(is_string__top);
|
|
ATF_TEST_CASE_BODY(is_string__top)
|
|
{
|
|
lutok::state state;
|
|
lua_pushnil(raw(state));
|
|
ATF_REQUIRE(!state.is_string());
|
|
lua_pushinteger(raw(state), 3);
|
|
ATF_REQUIRE(state.is_string());
|
|
lua_pushstring(raw(state), "foo");
|
|
ATF_REQUIRE(state.is_string());
|
|
lua_pop(raw(state), 3);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(is_string__explicit);
|
|
ATF_TEST_CASE_BODY(is_string__explicit)
|
|
{
|
|
lutok::state state;
|
|
lua_pushinteger(raw(state), 3);
|
|
ATF_REQUIRE(state.is_string(-1));
|
|
lua_pushnil(raw(state));
|
|
ATF_REQUIRE(!state.is_string(-1));
|
|
ATF_REQUIRE(state.is_string(-2));
|
|
lua_pushstring(raw(state), "foo");
|
|
ATF_REQUIRE(state.is_string(-1));
|
|
ATF_REQUIRE(!state.is_string(-2));
|
|
ATF_REQUIRE(state.is_string(-3));
|
|
lua_pop(raw(state), 3);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(is_table__empty);
|
|
ATF_TEST_CASE_BODY(is_table__empty)
|
|
{
|
|
lutok::state state;
|
|
ATF_REQUIRE(!state.is_table());
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(is_table__top);
|
|
ATF_TEST_CASE_BODY(is_table__top)
|
|
{
|
|
lutok::state state;
|
|
luaL_dostring(raw(state), "t = {3, 4, 5}");
|
|
|
|
lua_pushstring(raw(state), "foo");
|
|
ATF_REQUIRE(!state.is_table());
|
|
lua_getglobal(raw(state), "t");
|
|
ATF_REQUIRE(state.is_table());
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(is_table__explicit);
|
|
ATF_TEST_CASE_BODY(is_table__explicit)
|
|
{
|
|
lutok::state state;
|
|
luaL_dostring(raw(state), "t = {3, 4, 5}");
|
|
|
|
lua_pushstring(raw(state), "foo");
|
|
ATF_REQUIRE(!state.is_table(-1));
|
|
lua_getglobal(raw(state), "t");
|
|
ATF_REQUIRE(state.is_table(-1));
|
|
ATF_REQUIRE(!state.is_table(-2));
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(is_userdata__empty);
|
|
ATF_TEST_CASE_BODY(is_userdata__empty)
|
|
{
|
|
lutok::state state;
|
|
ATF_REQUIRE(!state.is_userdata());
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(is_userdata__top);
|
|
ATF_TEST_CASE_BODY(is_userdata__top)
|
|
{
|
|
lutok::state state;
|
|
|
|
lua_pushstring(raw(state), "foo");
|
|
ATF_REQUIRE(!state.is_userdata());
|
|
lua_newuserdata(raw(state), 1234);
|
|
ATF_REQUIRE(state.is_userdata());
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(is_userdata__explicit);
|
|
ATF_TEST_CASE_BODY(is_userdata__explicit)
|
|
{
|
|
lutok::state state;
|
|
|
|
lua_pushstring(raw(state), "foo");
|
|
ATF_REQUIRE(!state.is_userdata(-1));
|
|
lua_newuserdata(raw(state), 543);
|
|
ATF_REQUIRE(state.is_userdata(-1));
|
|
ATF_REQUIRE(!state.is_userdata(-2));
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(load_file__ok);
|
|
ATF_TEST_CASE_BODY(load_file__ok)
|
|
{
|
|
std::ofstream output("test.lua");
|
|
output << "in_the_file = \"oh yes\"\n";
|
|
output.close();
|
|
|
|
lutok::state state;
|
|
state.load_file("test.lua");
|
|
ATF_REQUIRE(lua_pcall(raw(state), 0, 0, 0) == 0);
|
|
lua_getglobal(raw(state), "in_the_file");
|
|
ATF_REQUIRE(std::strcmp("oh yes", lua_tostring(raw(state), -1)) == 0);
|
|
lua_pop(raw(state), 1);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(load_file__api_error);
|
|
ATF_TEST_CASE_BODY(load_file__api_error)
|
|
{
|
|
std::ofstream output("test.lua");
|
|
output << "I have a bad syntax! Wohoo!\n";
|
|
output.close();
|
|
|
|
lutok::state state;
|
|
REQUIRE_API_ERROR("luaL_loadfile", state.load_file("test.lua"));
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(load_file__file_not_found_error);
|
|
ATF_TEST_CASE_BODY(load_file__file_not_found_error)
|
|
{
|
|
lutok::state state;
|
|
ATF_REQUIRE_THROW_RE(lutok::file_not_found_error, "missing.lua",
|
|
state.load_file("missing.lua"));
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(load_string__ok);
|
|
ATF_TEST_CASE_BODY(load_string__ok)
|
|
{
|
|
lutok::state state;
|
|
state.load_string("return 2 + 3");
|
|
ATF_REQUIRE(lua_pcall(raw(state), 0, 1, 0) == 0);
|
|
ATF_REQUIRE_EQ(5, lua_tointeger(raw(state), -1));
|
|
lua_pop(raw(state), 1);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(load_string__fail);
|
|
ATF_TEST_CASE_BODY(load_string__fail)
|
|
{
|
|
lutok::state state;
|
|
REQUIRE_API_ERROR("luaL_loadstring", state.load_string("-"));
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(new_table);
|
|
ATF_TEST_CASE_BODY(new_table)
|
|
{
|
|
lutok::state state;
|
|
state.new_table();
|
|
ATF_REQUIRE_EQ(1, lua_gettop(raw(state)));
|
|
ATF_REQUIRE(lua_istable(raw(state), -1));
|
|
lua_pop(raw(state), 1);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(new_userdata);
|
|
ATF_TEST_CASE_BODY(new_userdata)
|
|
{
|
|
lutok::state state;
|
|
int* pointer = state.new_userdata< int >();
|
|
*pointer = 1234;
|
|
ATF_REQUIRE_EQ(1, lua_gettop(raw(state)));
|
|
ATF_REQUIRE(lua_isuserdata(raw(state), -1));
|
|
lua_pop(raw(state), 1);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(next__empty);
|
|
ATF_TEST_CASE_BODY(next__empty)
|
|
{
|
|
lutok::state state;
|
|
luaL_dostring(raw(state), "t = {}");
|
|
|
|
lua_getglobal(raw(state), "t");
|
|
lua_pushstring(raw(state), "this is a dummy value");
|
|
lua_pushnil(raw(state));
|
|
ATF_REQUIRE(!state.next(-3));
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(next__many);
|
|
ATF_TEST_CASE_BODY(next__many)
|
|
{
|
|
lutok::state state;
|
|
luaL_dostring(raw(state), "t = {}; t[1] = 100; t[2] = 200");
|
|
|
|
lua_getglobal(raw(state), "t");
|
|
lua_pushnil(raw(state));
|
|
|
|
ATF_REQUIRE(state.next());
|
|
ATF_REQUIRE_EQ(3, lua_gettop(raw(state)));
|
|
ATF_REQUIRE(lua_isnumber(raw(state), -2));
|
|
ATF_REQUIRE_EQ(1, lua_tointeger(raw(state), -2));
|
|
ATF_REQUIRE(lua_isnumber(raw(state), -1));
|
|
ATF_REQUIRE_EQ(100, lua_tointeger(raw(state), -1));
|
|
lua_pop(raw(state), 1);
|
|
|
|
ATF_REQUIRE(state.next());
|
|
ATF_REQUIRE_EQ(3, lua_gettop(raw(state)));
|
|
ATF_REQUIRE(lua_isnumber(raw(state), -2));
|
|
ATF_REQUIRE_EQ(2, lua_tointeger(raw(state), -2));
|
|
ATF_REQUIRE(lua_isnumber(raw(state), -1));
|
|
ATF_REQUIRE_EQ(200, lua_tointeger(raw(state), -1));
|
|
lua_pop(raw(state), 1);
|
|
|
|
ATF_REQUIRE(!state.next());
|
|
lua_pop(raw(state), 1);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(open_base);
|
|
ATF_TEST_CASE_BODY(open_base)
|
|
{
|
|
lutok::state state;
|
|
check_modules(state, "");
|
|
state.open_base();
|
|
check_modules(state, "base");
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(open_string);
|
|
ATF_TEST_CASE_BODY(open_string)
|
|
{
|
|
lutok::state state;
|
|
check_modules(state, "");
|
|
state.open_string();
|
|
check_modules(state, "string");
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(open_table);
|
|
ATF_TEST_CASE_BODY(open_table)
|
|
{
|
|
lutok::state state;
|
|
check_modules(state, "");
|
|
state.open_table();
|
|
check_modules(state, "table");
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(pcall__ok);
|
|
ATF_TEST_CASE_BODY(pcall__ok)
|
|
{
|
|
lutok::state state;
|
|
luaL_loadstring(raw(state), "function mul(a, b) return a * b; end");
|
|
state.pcall(0, 0, 0);
|
|
lua_getfield(raw(state), LUA_GLOBALSINDEX, "mul");
|
|
lua_pushinteger(raw(state), 3);
|
|
lua_pushinteger(raw(state), 5);
|
|
state.pcall(2, 1, 0);
|
|
ATF_REQUIRE_EQ(15, lua_tointeger(raw(state), -1));
|
|
lua_pop(raw(state), 1);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(pcall__fail);
|
|
ATF_TEST_CASE_BODY(pcall__fail)
|
|
{
|
|
lutok::state state;
|
|
lua_pushnil(raw(state));
|
|
REQUIRE_API_ERROR("lua_pcall", state.pcall(0, 0, 0));
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(pop__one);
|
|
ATF_TEST_CASE_BODY(pop__one)
|
|
{
|
|
lutok::state state;
|
|
lua_pushinteger(raw(state), 10);
|
|
lua_pushinteger(raw(state), 20);
|
|
lua_pushinteger(raw(state), 30);
|
|
state.pop(1);
|
|
ATF_REQUIRE_EQ(2, lua_gettop(raw(state)));
|
|
ATF_REQUIRE_EQ(20, lua_tointeger(raw(state), -1));
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(pop__many);
|
|
ATF_TEST_CASE_BODY(pop__many)
|
|
{
|
|
lutok::state state;
|
|
lua_pushinteger(raw(state), 10);
|
|
lua_pushinteger(raw(state), 20);
|
|
lua_pushinteger(raw(state), 30);
|
|
state.pop(2);
|
|
ATF_REQUIRE_EQ(1, lua_gettop(raw(state)));
|
|
ATF_REQUIRE_EQ(10, lua_tointeger(raw(state), -1));
|
|
lua_pop(raw(state), 1);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(push_boolean);
|
|
ATF_TEST_CASE_BODY(push_boolean)
|
|
{
|
|
lutok::state state;
|
|
state.push_boolean(true);
|
|
ATF_REQUIRE_EQ(1, lua_gettop(raw(state)));
|
|
ATF_REQUIRE(lua_toboolean(raw(state), -1));
|
|
state.push_boolean(false);
|
|
ATF_REQUIRE_EQ(2, lua_gettop(raw(state)));
|
|
ATF_REQUIRE(!lua_toboolean(raw(state), -1));
|
|
ATF_REQUIRE(lua_toboolean(raw(state), -2));
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(push_cxx_closure);
|
|
ATF_TEST_CASE_BODY(push_cxx_closure)
|
|
{
|
|
lutok::state state;
|
|
state.push_integer(15);
|
|
state.push_cxx_closure(cxx_multiply_closure, 1);
|
|
lua_setglobal(raw(state), "cxx_multiply_closure");
|
|
|
|
ATF_REQUIRE(luaL_dostring(raw(state),
|
|
"return cxx_multiply_closure(10)") == 0);
|
|
ATF_REQUIRE_EQ(150, lua_tointeger(raw(state), -1));
|
|
lua_pop(raw(state), 1);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(push_cxx_function__ok);
|
|
ATF_TEST_CASE_BODY(push_cxx_function__ok)
|
|
{
|
|
lutok::state state;
|
|
state.push_cxx_function(cxx_divide);
|
|
lua_setglobal(raw(state), "cxx_divide");
|
|
|
|
ATF_REQUIRE(luaL_dostring(raw(state), "return cxx_divide(17, 3)") == 0);
|
|
ATF_REQUIRE_EQ(5, lua_tointeger(raw(state), -2));
|
|
ATF_REQUIRE_EQ(2, lua_tointeger(raw(state), -1));
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(push_cxx_function__fail_exception);
|
|
ATF_TEST_CASE_BODY(push_cxx_function__fail_exception)
|
|
{
|
|
lutok::state state;
|
|
state.push_cxx_function(cxx_divide);
|
|
lua_setglobal(raw(state), "cxx_divide");
|
|
|
|
ATF_REQUIRE(luaL_dostring(raw(state), "return cxx_divide(15, 0)") != 0);
|
|
ATF_REQUIRE_MATCH("Divisor is 0", lua_tostring(raw(state), -1));
|
|
lua_pop(raw(state), 1);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(push_cxx_function__fail_anything);
|
|
ATF_TEST_CASE_BODY(push_cxx_function__fail_anything)
|
|
{
|
|
lutok::state state;
|
|
state.push_cxx_function(cxx_divide);
|
|
lua_setglobal(raw(state), "cxx_divide");
|
|
|
|
ATF_REQUIRE(luaL_dostring(raw(state), "return cxx_divide(-3, -1)") != 0);
|
|
ATF_REQUIRE_MATCH("Unhandled exception", lua_tostring(raw(state), -1));
|
|
lua_pop(raw(state), 1);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(push_cxx_function__fail_overflow);
|
|
ATF_TEST_CASE_BODY(push_cxx_function__fail_overflow)
|
|
{
|
|
lutok::state state;
|
|
state.push_cxx_function(raise_long_error);
|
|
lua_setglobal(raw(state), "fail");
|
|
|
|
ATF_REQUIRE(luaL_dostring(raw(state), "return fail(900)") != 0);
|
|
ATF_REQUIRE_MATCH(std::string(900, 'A'), lua_tostring(raw(state), -1));
|
|
lua_pop(raw(state), 1);
|
|
|
|
ATF_REQUIRE(luaL_dostring(raw(state), "return fail(8192)") != 0);
|
|
ATF_REQUIRE_MATCH(std::string(900, 'A'), lua_tostring(raw(state), -1));
|
|
lua_pop(raw(state), 1);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(push_integer);
|
|
ATF_TEST_CASE_BODY(push_integer)
|
|
{
|
|
lutok::state state;
|
|
state.push_integer(12);
|
|
ATF_REQUIRE_EQ(1, lua_gettop(raw(state)));
|
|
ATF_REQUIRE_EQ(12, lua_tointeger(raw(state), -1));
|
|
state.push_integer(34);
|
|
ATF_REQUIRE_EQ(2, lua_gettop(raw(state)));
|
|
ATF_REQUIRE_EQ(34, lua_tointeger(raw(state), -1));
|
|
ATF_REQUIRE_EQ(12, lua_tointeger(raw(state), -2));
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(push_nil);
|
|
ATF_TEST_CASE_BODY(push_nil)
|
|
{
|
|
lutok::state state;
|
|
state.push_nil();
|
|
ATF_REQUIRE_EQ(1, lua_gettop(raw(state)));
|
|
ATF_REQUIRE(lua_isnil(raw(state), -1));
|
|
state.push_integer(34);
|
|
ATF_REQUIRE_EQ(2, lua_gettop(raw(state)));
|
|
ATF_REQUIRE(!lua_isnil(raw(state), -1));
|
|
ATF_REQUIRE(lua_isnil(raw(state), -2));
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(push_string);
|
|
ATF_TEST_CASE_BODY(push_string)
|
|
{
|
|
lutok::state state;
|
|
|
|
{
|
|
std::string str = "first";
|
|
state.push_string(str);
|
|
ATF_REQUIRE_EQ(1, lua_gettop(raw(state)));
|
|
ATF_REQUIRE_EQ(std::string("first"), lua_tostring(raw(state), -1));
|
|
str = "second";
|
|
state.push_string(str);
|
|
}
|
|
ATF_REQUIRE_EQ(2, lua_gettop(raw(state)));
|
|
ATF_REQUIRE_EQ(std::string("second"), lua_tostring(raw(state), -1));
|
|
ATF_REQUIRE_EQ(std::string("first"), lua_tostring(raw(state), -2));
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(push_value__top);
|
|
ATF_TEST_CASE_BODY(push_value__top)
|
|
{
|
|
lutok::state state;
|
|
|
|
lua_pushinteger(raw(state), 10);
|
|
lua_pushinteger(raw(state), 20);
|
|
state.push_value();
|
|
ATF_REQUIRE_EQ(3, lua_gettop(raw(state)));
|
|
ATF_REQUIRE_EQ(20, lua_tointeger(raw(state), -1));
|
|
ATF_REQUIRE_EQ(20, lua_tointeger(raw(state), -2));
|
|
ATF_REQUIRE_EQ(10, lua_tointeger(raw(state), -3));
|
|
lua_pop(raw(state), 3);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(push_value__explicit);
|
|
ATF_TEST_CASE_BODY(push_value__explicit)
|
|
{
|
|
lutok::state state;
|
|
|
|
lua_pushinteger(raw(state), 10);
|
|
lua_pushinteger(raw(state), 20);
|
|
state.push_value(-2);
|
|
ATF_REQUIRE_EQ(3, lua_gettop(raw(state)));
|
|
ATF_REQUIRE_EQ(10, lua_tointeger(raw(state), -1));
|
|
ATF_REQUIRE_EQ(20, lua_tointeger(raw(state), -2));
|
|
ATF_REQUIRE_EQ(10, lua_tointeger(raw(state), -3));
|
|
lua_pop(raw(state), 3);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(raw_get__top);
|
|
ATF_TEST_CASE_BODY(raw_get__top)
|
|
{
|
|
lutok::state state;
|
|
|
|
luaL_openlibs(raw(state));
|
|
ATF_REQUIRE(luaL_dostring(
|
|
raw(state), "t = {foo=123} ; setmetatable(t, {__index=1})") == 0);
|
|
lua_getglobal(raw(state), "t");
|
|
lua_pushstring(raw(state), "foo");
|
|
state.raw_get();
|
|
ATF_REQUIRE(lua_isnumber(raw(state), -1));
|
|
ATF_REQUIRE_EQ(123, lua_tointeger(raw(state), -1));
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(raw_get__explicit);
|
|
ATF_TEST_CASE_BODY(raw_get__explicit)
|
|
{
|
|
lutok::state state;
|
|
|
|
luaL_openlibs(raw(state));
|
|
ATF_REQUIRE(luaL_dostring(
|
|
raw(state), "t = {foo=123} ; setmetatable(t, {__index=1})") == 0);
|
|
lua_getglobal(raw(state), "t");
|
|
lua_pushinteger(raw(state), 9876);
|
|
lua_pushstring(raw(state), "foo");
|
|
state.raw_get(-3);
|
|
ATF_REQUIRE(lua_isnumber(raw(state), -1));
|
|
ATF_REQUIRE_EQ(123, lua_tointeger(raw(state), -1));
|
|
ATF_REQUIRE_EQ(9876, lua_tointeger(raw(state), -2));
|
|
lua_pop(raw(state), 3);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(raw_set__top);
|
|
ATF_TEST_CASE_BODY(raw_set__top)
|
|
{
|
|
lutok::state state;
|
|
|
|
luaL_openlibs(raw(state));
|
|
ATF_REQUIRE(luaL_dostring(
|
|
raw(state), "t = {} ; setmetatable(t, {__newindex=1})") == 0);
|
|
lua_getglobal(raw(state), "t");
|
|
lua_pushstring(raw(state), "foo");
|
|
lua_pushinteger(raw(state), 345);
|
|
state.raw_set();
|
|
ATF_REQUIRE(luaL_dostring(raw(state), "return t.foo") == 0);
|
|
ATF_REQUIRE(lua_isnumber(raw(state), -1));
|
|
ATF_REQUIRE_EQ(345, lua_tointeger(raw(state), -1));
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(raw_set__explicit);
|
|
ATF_TEST_CASE_BODY(raw_set__explicit)
|
|
{
|
|
lutok::state state;
|
|
|
|
luaL_openlibs(raw(state));
|
|
ATF_REQUIRE(luaL_dostring(
|
|
raw(state), "t = {} ; setmetatable(t, {__newindex=1})") == 0);
|
|
lua_getglobal(raw(state), "t");
|
|
lua_pushinteger(raw(state), 876);
|
|
lua_pushstring(raw(state), "foo");
|
|
lua_pushinteger(raw(state), 345);
|
|
state.raw_set(-4);
|
|
ATF_REQUIRE(luaL_dostring(raw(state), "return t.foo") == 0);
|
|
ATF_REQUIRE(lua_isnumber(raw(state), -1));
|
|
ATF_REQUIRE_EQ(345, lua_tointeger(raw(state), -1));
|
|
ATF_REQUIRE_EQ(876, lua_tointeger(raw(state), -2));
|
|
lua_pop(raw(state), 3);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(set_global__ok);
|
|
ATF_TEST_CASE_BODY(set_global__ok)
|
|
{
|
|
lutok::state state;
|
|
lua_pushinteger(raw(state), 3);
|
|
state.set_global("test_variable");
|
|
ATF_REQUIRE(luaL_dostring(raw(state), "return test_variable + 1") == 0);
|
|
ATF_REQUIRE(lua_isnumber(raw(state), -1));
|
|
ATF_REQUIRE_EQ(4, lua_tointeger(raw(state), -1));
|
|
lua_pop(raw(state), 1);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(set_global__fail);
|
|
ATF_TEST_CASE_BODY(set_global__fail)
|
|
{
|
|
lutok::state state;
|
|
lua_pushinteger(raw(state), 3);
|
|
lua_replace(raw(state), LUA_GLOBALSINDEX);
|
|
lua_pushinteger(raw(state), 4);
|
|
REQUIRE_API_ERROR("lua_setglobal", state.set_global("test_variable"));
|
|
lua_pop(raw(state), 1);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(set_metatable__top);
|
|
ATF_TEST_CASE_BODY(set_metatable__top)
|
|
{
|
|
lutok::state state;
|
|
ATF_REQUIRE(luaL_dostring(
|
|
raw(state),
|
|
"mt = {}\n"
|
|
"mt.__add = function(a, b) return a[1] + b end\n"
|
|
"numbers = {}\n"
|
|
"numbers[1] = 5\n") == 0);
|
|
|
|
lua_getglobal(raw(state), "numbers");
|
|
lua_getglobal(raw(state), "mt");
|
|
state.set_metatable();
|
|
lua_pop(raw(state), 1);
|
|
|
|
ATF_REQUIRE(luaL_dostring(raw(state), "return numbers + 2") == 0);
|
|
ATF_REQUIRE(lua_isnumber(raw(state), -1));
|
|
ATF_REQUIRE_EQ(7, lua_tointeger(raw(state), -1));
|
|
lua_pop(raw(state), 1);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(set_metatable__explicit);
|
|
ATF_TEST_CASE_BODY(set_metatable__explicit)
|
|
{
|
|
lutok::state state;
|
|
ATF_REQUIRE(luaL_dostring(
|
|
raw(state),
|
|
"mt = {}\n"
|
|
"mt.__add = function(a, b) return a[1] + b end\n"
|
|
"numbers = {}\n"
|
|
"numbers[1] = 5\n") == 0);
|
|
|
|
lua_getglobal(raw(state), "numbers");
|
|
lua_pushinteger(raw(state), 1234);
|
|
lua_getglobal(raw(state), "mt");
|
|
state.set_metatable(-3);
|
|
lua_pop(raw(state), 2);
|
|
|
|
ATF_REQUIRE(luaL_dostring(raw(state), "return numbers + 2") == 0);
|
|
ATF_REQUIRE(lua_isnumber(raw(state), -1));
|
|
ATF_REQUIRE_EQ(7, lua_tointeger(raw(state), -1));
|
|
lua_pop(raw(state), 1);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(set_table__ok);
|
|
ATF_TEST_CASE_BODY(set_table__ok)
|
|
{
|
|
lutok::state state;
|
|
ATF_REQUIRE(luaL_dostring(raw(state), "t = { a = 1, bar = 234 }") == 0);
|
|
lua_getglobal(raw(state), "t");
|
|
|
|
lua_pushstring(raw(state), "bar");
|
|
lua_pushstring(raw(state), "baz");
|
|
state.set_table();
|
|
ATF_REQUIRE_EQ(1, lua_gettop(raw(state)));
|
|
|
|
lua_pushstring(raw(state), "a");
|
|
lua_gettable(raw(state), -2);
|
|
ATF_REQUIRE(lua_isnumber(raw(state), -1));
|
|
ATF_REQUIRE_EQ(1, lua_tointeger(raw(state), -1));
|
|
lua_pop(raw(state), 1);
|
|
|
|
lua_pushstring(raw(state), "bar");
|
|
lua_gettable(raw(state), -2);
|
|
ATF_REQUIRE(lua_isstring(raw(state), -1));
|
|
ATF_REQUIRE_EQ(std::string("baz"), lua_tostring(raw(state), -1));
|
|
lua_pop(raw(state), 1);
|
|
|
|
lua_pop(raw(state), 1);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(set_table__nil);
|
|
ATF_TEST_CASE_BODY(set_table__nil)
|
|
{
|
|
lutok::state state;
|
|
lua_pushnil(raw(state));
|
|
lua_pushinteger(raw(state), 1);
|
|
lua_pushinteger(raw(state), 2);
|
|
REQUIRE_API_ERROR("lua_settable", state.set_table(-3));
|
|
lua_pop(raw(state), 3);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(to_boolean__top);
|
|
ATF_TEST_CASE_BODY(to_boolean__top)
|
|
{
|
|
lutok::state state;
|
|
lua_pushboolean(raw(state), 1);
|
|
ATF_REQUIRE(state.to_boolean());
|
|
lua_pushboolean(raw(state), 0);
|
|
ATF_REQUIRE(!state.to_boolean());
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(to_boolean__explicit);
|
|
ATF_TEST_CASE_BODY(to_boolean__explicit)
|
|
{
|
|
lutok::state state;
|
|
lua_pushboolean(raw(state), 0);
|
|
lua_pushboolean(raw(state), 1);
|
|
ATF_REQUIRE(!state.to_boolean(-2));
|
|
ATF_REQUIRE(state.to_boolean(-1));
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(to_integer__top);
|
|
ATF_TEST_CASE_BODY(to_integer__top)
|
|
{
|
|
lutok::state state;
|
|
lua_pushstring(raw(state), "34");
|
|
ATF_REQUIRE_EQ(34, state.to_integer());
|
|
lua_pushinteger(raw(state), 12);
|
|
ATF_REQUIRE_EQ(12, state.to_integer());
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(to_integer__explicit);
|
|
ATF_TEST_CASE_BODY(to_integer__explicit)
|
|
{
|
|
lutok::state state;
|
|
lua_pushinteger(raw(state), 12);
|
|
lua_pushstring(raw(state), "foobar");
|
|
ATF_REQUIRE_EQ(12, state.to_integer(-2));
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(to_string__top);
|
|
ATF_TEST_CASE_BODY(to_string__top)
|
|
{
|
|
lutok::state state;
|
|
lua_pushstring(raw(state), "foobar");
|
|
ATF_REQUIRE_EQ("foobar", state.to_string());
|
|
lua_pushinteger(raw(state), 12);
|
|
ATF_REQUIRE_EQ("12", state.to_string());
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(to_string__explicit);
|
|
ATF_TEST_CASE_BODY(to_string__explicit)
|
|
{
|
|
lutok::state state;
|
|
lua_pushstring(raw(state), "foobar");
|
|
lua_pushinteger(raw(state), 12);
|
|
ATF_REQUIRE_EQ("foobar", state.to_string(-2));
|
|
ATF_REQUIRE_EQ("12", state.to_string(-1));
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(to_userdata__top);
|
|
ATF_TEST_CASE_BODY(to_userdata__top)
|
|
{
|
|
lutok::state state;
|
|
{
|
|
int* pointer = static_cast< int* >(
|
|
lua_newuserdata(raw(state), sizeof(int)));
|
|
*pointer = 987;
|
|
}
|
|
|
|
int* pointer = state.to_userdata< int >();
|
|
ATF_REQUIRE_EQ(987, *pointer);
|
|
lua_pop(raw(state), 1);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(to_userdata__explicit);
|
|
ATF_TEST_CASE_BODY(to_userdata__explicit)
|
|
{
|
|
lutok::state state;
|
|
{
|
|
int* pointer = static_cast< int* >(
|
|
lua_newuserdata(raw(state), sizeof(int)));
|
|
*pointer = 987;
|
|
}
|
|
|
|
lua_pushinteger(raw(state), 3);
|
|
int* pointer = state.to_userdata< int >(-2);
|
|
ATF_REQUIRE_EQ(987, *pointer);
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_TEST_CASE_WITHOUT_HEAD(upvalue_index);
|
|
ATF_TEST_CASE_BODY(upvalue_index)
|
|
{
|
|
lutok::state state;
|
|
lua_pushinteger(raw(state), 25);
|
|
lua_pushinteger(raw(state), 30);
|
|
lua_pushcclosure(raw(state), c_get_upvalues, 2);
|
|
lua_setglobal(raw(state), "c_get_upvalues");
|
|
|
|
ATF_REQUIRE(luaL_dostring(raw(state),
|
|
"return c_get_upvalues()") == 0);
|
|
ATF_REQUIRE_EQ(25, lua_tointeger(raw(state), -2));
|
|
ATF_REQUIRE_EQ(30, lua_tointeger(raw(state), -1));
|
|
lua_pop(raw(state), 2);
|
|
}
|
|
|
|
|
|
ATF_INIT_TEST_CASES(tcs)
|
|
{
|
|
ATF_ADD_TEST_CASE(tcs, close);
|
|
ATF_ADD_TEST_CASE(tcs, get_global__ok);
|
|
ATF_ADD_TEST_CASE(tcs, get_global__fail);
|
|
ATF_ADD_TEST_CASE(tcs, get_global__undefined);
|
|
ATF_ADD_TEST_CASE(tcs, get_metafield__ok);
|
|
ATF_ADD_TEST_CASE(tcs, get_metafield__undefined);
|
|
ATF_ADD_TEST_CASE(tcs, get_metatable__top);
|
|
ATF_ADD_TEST_CASE(tcs, get_metatable__explicit);
|
|
ATF_ADD_TEST_CASE(tcs, get_metatable__undefined);
|
|
ATF_ADD_TEST_CASE(tcs, get_table__ok);
|
|
ATF_ADD_TEST_CASE(tcs, get_table__nil);
|
|
ATF_ADD_TEST_CASE(tcs, get_table__unknown_index);
|
|
ATF_ADD_TEST_CASE(tcs, get_top);
|
|
ATF_ADD_TEST_CASE(tcs, globals_index);
|
|
ATF_ADD_TEST_CASE(tcs, insert);
|
|
ATF_ADD_TEST_CASE(tcs, is_boolean__empty);
|
|
ATF_ADD_TEST_CASE(tcs, is_boolean__top);
|
|
ATF_ADD_TEST_CASE(tcs, is_boolean__explicit);
|
|
ATF_ADD_TEST_CASE(tcs, is_function__empty);
|
|
ATF_ADD_TEST_CASE(tcs, is_function__top);
|
|
ATF_ADD_TEST_CASE(tcs, is_function__explicit);
|
|
ATF_ADD_TEST_CASE(tcs, is_nil__empty);
|
|
ATF_ADD_TEST_CASE(tcs, is_nil__top);
|
|
ATF_ADD_TEST_CASE(tcs, is_nil__explicit);
|
|
ATF_ADD_TEST_CASE(tcs, is_number__empty);
|
|
ATF_ADD_TEST_CASE(tcs, is_number__top);
|
|
ATF_ADD_TEST_CASE(tcs, is_number__explicit);
|
|
ATF_ADD_TEST_CASE(tcs, is_string__empty);
|
|
ATF_ADD_TEST_CASE(tcs, is_string__top);
|
|
ATF_ADD_TEST_CASE(tcs, is_string__explicit);
|
|
ATF_ADD_TEST_CASE(tcs, is_table__empty);
|
|
ATF_ADD_TEST_CASE(tcs, is_table__top);
|
|
ATF_ADD_TEST_CASE(tcs, is_table__explicit);
|
|
ATF_ADD_TEST_CASE(tcs, is_userdata__empty);
|
|
ATF_ADD_TEST_CASE(tcs, is_userdata__top);
|
|
ATF_ADD_TEST_CASE(tcs, is_userdata__explicit);
|
|
ATF_ADD_TEST_CASE(tcs, load_file__ok);
|
|
ATF_ADD_TEST_CASE(tcs, load_file__api_error);
|
|
ATF_ADD_TEST_CASE(tcs, load_file__file_not_found_error);
|
|
ATF_ADD_TEST_CASE(tcs, load_string__ok);
|
|
ATF_ADD_TEST_CASE(tcs, load_string__fail);
|
|
ATF_ADD_TEST_CASE(tcs, new_table);
|
|
ATF_ADD_TEST_CASE(tcs, new_userdata);
|
|
ATF_ADD_TEST_CASE(tcs, next__empty);
|
|
ATF_ADD_TEST_CASE(tcs, next__many);
|
|
ATF_ADD_TEST_CASE(tcs, open_base);
|
|
ATF_ADD_TEST_CASE(tcs, open_string);
|
|
ATF_ADD_TEST_CASE(tcs, open_table);
|
|
ATF_ADD_TEST_CASE(tcs, pcall__ok);
|
|
ATF_ADD_TEST_CASE(tcs, pcall__fail);
|
|
ATF_ADD_TEST_CASE(tcs, pop__one);
|
|
ATF_ADD_TEST_CASE(tcs, pop__many);
|
|
ATF_ADD_TEST_CASE(tcs, push_boolean);
|
|
ATF_ADD_TEST_CASE(tcs, push_cxx_closure);
|
|
ATF_ADD_TEST_CASE(tcs, push_cxx_function__ok);
|
|
ATF_ADD_TEST_CASE(tcs, push_cxx_function__fail_exception);
|
|
ATF_ADD_TEST_CASE(tcs, push_cxx_function__fail_anything);
|
|
ATF_ADD_TEST_CASE(tcs, push_cxx_function__fail_overflow);
|
|
ATF_ADD_TEST_CASE(tcs, push_integer);
|
|
ATF_ADD_TEST_CASE(tcs, push_nil);
|
|
ATF_ADD_TEST_CASE(tcs, push_string);
|
|
ATF_ADD_TEST_CASE(tcs, push_value__top);
|
|
ATF_ADD_TEST_CASE(tcs, push_value__explicit);
|
|
ATF_ADD_TEST_CASE(tcs, raw_get__top);
|
|
ATF_ADD_TEST_CASE(tcs, raw_get__explicit);
|
|
ATF_ADD_TEST_CASE(tcs, raw_set__top);
|
|
ATF_ADD_TEST_CASE(tcs, raw_set__explicit);
|
|
ATF_ADD_TEST_CASE(tcs, set_global__ok);
|
|
ATF_ADD_TEST_CASE(tcs, set_global__fail);
|
|
ATF_ADD_TEST_CASE(tcs, set_metatable__top);
|
|
ATF_ADD_TEST_CASE(tcs, set_metatable__explicit);
|
|
ATF_ADD_TEST_CASE(tcs, set_table__ok);
|
|
ATF_ADD_TEST_CASE(tcs, set_table__nil);
|
|
ATF_ADD_TEST_CASE(tcs, to_boolean__top);
|
|
ATF_ADD_TEST_CASE(tcs, to_boolean__explicit);
|
|
ATF_ADD_TEST_CASE(tcs, to_integer__top);
|
|
ATF_ADD_TEST_CASE(tcs, to_integer__explicit);
|
|
ATF_ADD_TEST_CASE(tcs, to_string__top);
|
|
ATF_ADD_TEST_CASE(tcs, to_string__explicit);
|
|
ATF_ADD_TEST_CASE(tcs, to_userdata__top);
|
|
ATF_ADD_TEST_CASE(tcs, to_userdata__explicit);
|
|
ATF_ADD_TEST_CASE(tcs, upvalue_index);
|
|
}
|