2013-12-11 21:32:27 +08:00
|
|
|
#define CATCH_CONFIG_MAIN
|
|
|
|
#include <catch.hpp>
|
2013-12-11 19:34:18 +08:00
|
|
|
#include <sol.hpp>
|
|
|
|
|
2013-12-11 21:32:27 +08:00
|
|
|
std::string free_function() {
|
|
|
|
std::cout << "free_function()" << std::endl;
|
2013-12-11 19:34:18 +08:00
|
|
|
return "test";
|
|
|
|
}
|
|
|
|
|
2013-12-11 21:32:27 +08:00
|
|
|
struct object {
|
2013-12-11 19:34:18 +08:00
|
|
|
|
|
|
|
std::string operator() () {
|
|
|
|
std::cout << "member_test()" << std::endl;
|
|
|
|
return "test";
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2013-12-12 00:18:13 +08:00
|
|
|
int plop_xyz(int x, int y, std::string z) {
|
|
|
|
std::cout << x << " " << y << " " << z << std::endl;
|
|
|
|
return 11;
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_CASE("simple/set_global", "Check if the set_global works properly.") {
|
|
|
|
sol::state lua;
|
|
|
|
|
|
|
|
lua.set("a", 9);
|
|
|
|
REQUIRE_NOTHROW(lua.script("if a ~= 9 then error('wrong value') end"));
|
|
|
|
|
|
|
|
lua.set("d", "hello");
|
|
|
|
REQUIRE_NOTHROW(lua.script("if d ~= 'hello' then error('expected \\'hello\\', got '.. tostring(d)) end"));
|
|
|
|
|
|
|
|
lua.set("e", std::string("hello"));
|
|
|
|
REQUIRE_NOTHROW(lua.script("if d ~= 'hello' then error('expected \\'hello\\', got '.. tostring(d)) end"));
|
|
|
|
|
|
|
|
lua.set("f", true);
|
|
|
|
REQUIRE_NOTHROW(lua.script("if f ~= true then error('wrong value') end"));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_CASE("simple/get", "Tests if the get function works properly.") {
|
|
|
|
sol::state lua;
|
|
|
|
|
|
|
|
lua.script("a = 9");
|
|
|
|
auto a = lua.get<int>("a");
|
|
|
|
REQUIRE(a == 9.0);
|
|
|
|
|
|
|
|
lua.script("b = nil");
|
2013-12-12 00:56:34 +08:00
|
|
|
REQUIRE_NOTHROW(lua.get<sol::nil_t>("b"));
|
2013-12-12 00:18:13 +08:00
|
|
|
|
|
|
|
lua.script("d = 'hello'");
|
|
|
|
auto d = lua.get<std::string>("d");
|
|
|
|
REQUIRE(d == "hello");
|
|
|
|
|
|
|
|
lua.script("e = true");
|
|
|
|
auto e = lua.get<bool>("e");
|
|
|
|
REQUIRE(e == true);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_CASE("simple/addition", "") {
|
|
|
|
sol::state lua;
|
|
|
|
|
|
|
|
lua.set("b", 0.2);
|
|
|
|
lua.script("c = 9 + b");
|
|
|
|
auto c = lua.get<double>("c");
|
|
|
|
|
|
|
|
REQUIRE(c == 9.2);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_CASE("simple/if", "") {
|
|
|
|
sol::state lua;
|
|
|
|
|
|
|
|
std::string program = "if true then f = 0.1 else f = 'test' end";
|
|
|
|
lua.script(program);
|
|
|
|
auto f = lua.get<double>("f");
|
|
|
|
|
|
|
|
REQUIRE(f == 0.1);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_CASE("simple/callWithParameters", "Lua function is called with a few parameters from C++") {
|
|
|
|
sol::state lua;
|
2013-12-11 21:32:27 +08:00
|
|
|
|
2013-12-12 00:18:13 +08:00
|
|
|
REQUIRE_NOTHROW(lua.script("function my_add(i, j, k) return i + j + k end"));
|
|
|
|
auto f = lua.get<sol::function>("my_add");
|
2013-12-14 09:09:51 +08:00
|
|
|
REQUIRE_NOTHROW(lua.script("function my_nothing(i, j, k) end"));
|
|
|
|
auto fvoid = lua.get<sol::function>("my_nothing");
|
2013-12-12 01:42:00 +08:00
|
|
|
int a;
|
2013-12-14 09:09:51 +08:00
|
|
|
REQUIRE_NOTHROW(fvoid(1, 2, 3));
|
2013-12-12 01:42:00 +08:00
|
|
|
REQUIRE_NOTHROW(a = f.call<int>(1, 2, 3));
|
|
|
|
REQUIRE(a == 6);
|
|
|
|
REQUIRE_THROWS(a = f.call<int>(1, 2, "arf"));
|
2013-12-12 00:18:13 +08:00
|
|
|
}
|
2013-12-11 21:32:27 +08:00
|
|
|
|
2013-12-12 00:18:13 +08:00
|
|
|
TEST_CASE("simple/callCppFunction", "C++ function is called from lua") {
|
|
|
|
sol::state lua;
|
2013-12-11 21:32:27 +08:00
|
|
|
|
2013-12-12 00:18:13 +08:00
|
|
|
lua.set_function("plop_xyz", plop_xyz);
|
|
|
|
lua.script("x = plop_xyz(2, 6, 'hello')");
|
|
|
|
|
|
|
|
REQUIRE(lua.get<int>("x") == 11);
|
2013-12-11 21:32:27 +08:00
|
|
|
}
|
|
|
|
|
2013-12-12 00:18:13 +08:00
|
|
|
TEST_CASE("simple/callLambda", "A C++ lambda is exposed to lua and called") {
|
|
|
|
sol::state lua;
|
|
|
|
|
|
|
|
int x = 0;
|
2013-12-11 21:32:27 +08:00
|
|
|
|
2013-12-12 00:18:13 +08:00
|
|
|
lua.set_function("foo", [ &x ] { x = 1; });
|
2013-12-11 21:32:27 +08:00
|
|
|
|
2013-12-12 00:18:13 +08:00
|
|
|
lua.script("foo()");
|
2013-12-11 21:32:27 +08:00
|
|
|
|
2013-12-12 00:18:13 +08:00
|
|
|
REQUIRE(x == 1);
|
2013-12-11 21:32:27 +08:00
|
|
|
}
|
|
|
|
|
2013-12-12 00:18:13 +08:00
|
|
|
TEST_CASE("advanced/callLambdaReturns", "Checks for lambdas returning values") {
|
2013-12-14 13:15:14 +08:00
|
|
|
const static std::string lol = "lol", str = "str";
|
|
|
|
const static std::tuple<int, float, double, std::string> heh_tuple = std::make_tuple(1, 6.28f, 3.14, std::string("heh"));
|
2013-12-12 00:18:13 +08:00
|
|
|
sol::state lua;
|
|
|
|
|
2013-12-14 12:33:06 +08:00
|
|
|
REQUIRE_NOTHROW(lua.set_function("a", [ ] { return 42; }));
|
2013-12-17 00:07:10 +08:00
|
|
|
REQUIRE(lua.get<sol::function>("a").call<int>() == 42);
|
2013-12-14 13:15:14 +08:00
|
|
|
|
2013-12-14 12:33:06 +08:00
|
|
|
REQUIRE_NOTHROW(lua.set_function("b", [ ] { return 42u; }));
|
2013-12-17 00:07:10 +08:00
|
|
|
REQUIRE(lua.get<sol::function>("b").call<unsigned int>() == 42u);
|
2013-12-14 13:15:14 +08:00
|
|
|
|
2013-12-14 12:33:06 +08:00
|
|
|
REQUIRE_NOTHROW(lua.set_function("c", [ ] { return 3.14; }));
|
2013-12-17 00:07:10 +08:00
|
|
|
REQUIRE(lua.get<sol::function>("c").call<double>() == 3.14);
|
2013-12-14 13:15:14 +08:00
|
|
|
|
2013-12-14 12:33:06 +08:00
|
|
|
REQUIRE_NOTHROW(lua.set_function("d", [ ] { return 6.28f; }));
|
2013-12-17 00:07:10 +08:00
|
|
|
REQUIRE(lua.get<sol::function>("d").call<float>() == 6.28f);
|
2013-12-14 13:15:14 +08:00
|
|
|
|
2013-12-14 12:33:06 +08:00
|
|
|
REQUIRE_NOTHROW(lua.set_function("e", [ ] { return "lol"; }));
|
2013-12-17 00:07:10 +08:00
|
|
|
REQUIRE(lua.get<sol::function>("e").call<std::string>() == lol);
|
2013-12-14 13:15:14 +08:00
|
|
|
|
2013-12-14 12:33:06 +08:00
|
|
|
REQUIRE_NOTHROW(lua.set_function("f", [ ] { return true; }));
|
2013-12-17 00:07:10 +08:00
|
|
|
REQUIRE(lua.get<sol::function>("f").call<bool>());
|
2013-12-14 13:15:14 +08:00
|
|
|
|
2013-12-14 12:33:06 +08:00
|
|
|
REQUIRE_NOTHROW(lua.set_function("g", [ ] { return std::string("str"); }));
|
2013-12-17 00:07:10 +08:00
|
|
|
REQUIRE(lua.get<sol::function>("g").call<std::string>() == str);
|
2013-12-14 13:15:14 +08:00
|
|
|
|
2013-12-14 12:33:06 +08:00
|
|
|
REQUIRE_NOTHROW(lua.set_function("h", [ ] { }));
|
2013-12-17 00:07:10 +08:00
|
|
|
REQUIRE_NOTHROW(lua.get<sol::function>("h").call());
|
2013-12-14 13:15:14 +08:00
|
|
|
|
2013-12-14 12:33:06 +08:00
|
|
|
REQUIRE_NOTHROW(lua.set_function("i", [ ] { return sol::nil; }));
|
2013-12-17 00:07:10 +08:00
|
|
|
REQUIRE(lua.get<sol::function>("i").call<sol::nil_t>() == sol::nil);
|
2013-12-15 12:25:44 +08:00
|
|
|
REQUIRE_NOTHROW(lua.set_function("j", [ ] { return std::make_tuple(1, 6.28f, 3.14, std::string("heh")); }));
|
2013-12-17 00:07:10 +08:00
|
|
|
REQUIRE((lua.get<sol::function>("j").call<int, float, double, std::string>() == heh_tuple));
|
2013-12-12 00:18:13 +08:00
|
|
|
}
|
2013-12-11 21:32:27 +08:00
|
|
|
|
2013-12-12 00:18:13 +08:00
|
|
|
TEST_CASE("advanced/callLambda2", "A C++ lambda is exposed to lua and called") {
|
|
|
|
sol::state lua;
|
2013-12-11 21:32:27 +08:00
|
|
|
|
2013-12-12 00:18:13 +08:00
|
|
|
int x = 0;
|
|
|
|
lua.set_function("set_x", [ &] (int new_x) {
|
|
|
|
x = new_x;
|
|
|
|
return 0;
|
|
|
|
});
|
|
|
|
|
|
|
|
lua.script("set_x(9)");
|
|
|
|
REQUIRE(x == 9);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_CASE("negative/basicError", "Check if error handling works correctly") {
|
|
|
|
sol::state lua;
|
|
|
|
|
|
|
|
REQUIRE_THROWS(lua.script("nil[5]"));
|
2013-12-11 21:32:27 +08:00
|
|
|
}
|
|
|
|
|
2013-12-12 07:14:12 +08:00
|
|
|
TEST_CASE("libraries", "Check if we can open libraries through sol") {
|
|
|
|
sol::state lua;
|
|
|
|
REQUIRE_NOTHROW(lua.open_libraries(sol::lib::base, sol::lib::os));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_CASE("tables/variables", "Check if tables and variables work as intended") {
|
|
|
|
sol::state lua;
|
|
|
|
lua.open_libraries(sol::lib::base, sol::lib::os);
|
2013-12-12 00:18:13 +08:00
|
|
|
lua.get<sol::table>("os").set("name", "windows");
|
2013-12-12 07:14:12 +08:00
|
|
|
REQUIRE_NOTHROW(lua.script("assert(os.name == \"windows\")"));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_CASE("tables/functions_variables", "Check if tables and function calls work as intended") {
|
|
|
|
sol::state lua;
|
|
|
|
lua.open_libraries(sol::lib::base, sol::lib::os);
|
|
|
|
auto run_script = [ ] (sol::state& lua) -> void {
|
|
|
|
lua.script("assert(os.fun() == \"test\")");
|
|
|
|
};
|
2013-12-12 00:18:13 +08:00
|
|
|
|
|
|
|
lua.get<sol::table>("os").set_function("fun",
|
|
|
|
[ ] () {
|
2013-12-12 07:14:12 +08:00
|
|
|
std::cout << "stateless lambda()" << std::endl;
|
|
|
|
return "test";
|
|
|
|
}
|
2013-12-14 09:09:51 +08:00
|
|
|
);
|
2013-12-12 07:14:12 +08:00
|
|
|
REQUIRE_NOTHROW(run_script(lua));
|
2013-12-12 00:18:13 +08:00
|
|
|
|
|
|
|
lua.get<sol::table>("os").set_function("fun", &free_function);
|
2013-12-12 07:14:12 +08:00
|
|
|
REQUIRE_NOTHROW(run_script(lua));
|
2013-12-12 00:18:13 +08:00
|
|
|
|
|
|
|
// l-value, can optomize
|
|
|
|
auto lval = object();
|
|
|
|
lua.get<sol::table>("os").set_function("fun", &object::operator(), lval);
|
2013-12-14 13:32:45 +08:00
|
|
|
REQUIRE_NOTHROW(run_script(lua));
|
2013-12-12 00:18:13 +08:00
|
|
|
|
|
|
|
// stateful lambda: non-convertible, unoptomizable
|
|
|
|
int breakit = 50;
|
|
|
|
lua.get<sol::table>("os").set_function("fun",
|
|
|
|
[ &breakit ] () {
|
|
|
|
std::cout << "stateless lambda()" << std::endl;
|
|
|
|
return "test";
|
|
|
|
}
|
2013-12-14 09:09:51 +08:00
|
|
|
);
|
2013-12-12 07:14:12 +08:00
|
|
|
REQUIRE_NOTHROW(run_script(lua));
|
2013-12-12 00:18:13 +08:00
|
|
|
|
|
|
|
// r-value, cannot optomize
|
|
|
|
lua.get<sol::table>("os").set_function("fun", &object::operator(), object());
|
2013-12-12 07:14:12 +08:00
|
|
|
REQUIRE_NOTHROW(run_script(lua));
|
2013-12-12 00:18:13 +08:00
|
|
|
|
|
|
|
// r-value, cannot optomize
|
|
|
|
auto rval = object();
|
|
|
|
lua.get<sol::table>("os").set_function("fun", &object::operator(), std::move(rval));
|
2013-12-12 07:14:12 +08:00
|
|
|
REQUIRE_NOTHROW(run_script(lua));
|
2013-12-13 09:20:11 +08:00
|
|
|
}
|
|
|
|
|
2013-12-16 11:14:56 +08:00
|
|
|
TEST_CASE("functions/return_order_and_multi_get", "Check if return order is in the same reading order specified in Lua" ) {
|
2013-12-16 05:27:20 +08:00
|
|
|
const static std::tuple<int, int, int> triple = std::make_tuple(10, 11, 12);
|
|
|
|
sol::state lua;
|
|
|
|
lua.set_function( "f", [ ] {
|
2013-12-16 11:09:06 +08:00
|
|
|
return std::make_tuple( 10, 11, 12 );
|
2013-12-16 05:27:20 +08:00
|
|
|
} );
|
2013-12-16 11:09:06 +08:00
|
|
|
lua.script("function g() return 10, 11, 12 end\nx,y,z = g()");
|
|
|
|
auto tcpp = lua.get<sol::function>("f").call<int, int, int>();
|
|
|
|
auto tlua = lua.get<sol::function>("g").call<int, int, int>();
|
|
|
|
auto tluaget = lua.get<int, int, int>("x", "y", "z");
|
|
|
|
std::cout << "cpp: " << std::get<0>(tcpp) << ',' << std::get<1>(tcpp) << ',' << std::get<2>(tcpp) << std::endl;
|
|
|
|
std::cout << "lua: " << std::get<0>(tlua) << ',' << std::get<1>(tlua) << ',' << std::get<2>(tlua) << std::endl;
|
|
|
|
std::cout << "lua.xyz: " << lua.get<int>("x") << ',' << lua.get<int>("y") << ',' << lua.get<int>("z") << std::endl;
|
|
|
|
REQUIRE(tcpp == triple);
|
|
|
|
REQUIRE(tlua == triple);
|
|
|
|
REQUIRE(tluaget == triple);
|
2013-12-12 07:14:12 +08:00
|
|
|
}
|