You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
322 lines
7.0 KiB
322 lines
7.0 KiB
|
1 day ago
|
#include <fmt/core.h>
|
||
|
|
#include <deque>
|
||
|
|
#include <string>
|
||
|
|
#include <fuc2/testing.hpp>
|
||
|
|
#define SOL_ALL_SAFETIES_ON 1
|
||
|
|
#include <sol/sol.hpp>
|
||
|
|
|
||
|
|
using namespace fuc2;
|
||
|
|
|
||
|
|
namespace sol2_tests {
|
||
|
|
|
||
|
|
void test_basic_lua_run() {
|
||
|
|
sol::state lua;
|
||
|
|
|
||
|
|
int x = 0;
|
||
|
|
|
||
|
|
lua.set_function("beep", [&x]{++x; });
|
||
|
|
lua.script("beep()");
|
||
|
|
|
||
|
|
EQUAL(x, 1, "Lua failed to set x");
|
||
|
|
}
|
||
|
|
|
||
|
|
struct vars {
|
||
|
|
int boop = 0;
|
||
|
|
};
|
||
|
|
|
||
|
|
void test_big_ass_vector() {
|
||
|
|
std::vector<vars> variables;
|
||
|
|
for(int i = 0; i < 100; i++) {
|
||
|
|
variables.emplace_back(i);
|
||
|
|
}
|
||
|
|
|
||
|
|
sol::state lua;
|
||
|
|
lua.open_libraries(sol::lib::base);
|
||
|
|
|
||
|
|
lua.new_usertype<vars>("vars", "boop", &vars::boop);
|
||
|
|
lua.script(R"(
|
||
|
|
function handler(v)
|
||
|
|
v.boop = v.boop + 1
|
||
|
|
end
|
||
|
|
)");
|
||
|
|
|
||
|
|
sol::function handler = lua["handler"];
|
||
|
|
|
||
|
|
for(auto& v : variables) {
|
||
|
|
int boop_before = v.boop;
|
||
|
|
|
||
|
|
handler(v);
|
||
|
|
|
||
|
|
CHECK(boop_before == v.boop - 1);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void test_usertype_vars() {
|
||
|
|
sol::state lua;
|
||
|
|
lua.new_usertype<vars>("vars", "boop", &vars::boop);
|
||
|
|
lua.script("beep = vars.new()\n"
|
||
|
|
"beep.boop = 1");
|
||
|
|
|
||
|
|
EQUAL(lua.get<vars>("beep").boop, 1);
|
||
|
|
}
|
||
|
|
|
||
|
|
void test_base_libraries() {
|
||
|
|
using L = sol::lib;
|
||
|
|
|
||
|
|
sol::state lua;
|
||
|
|
lua.open_libraries(
|
||
|
|
L::base,
|
||
|
|
L::package,
|
||
|
|
L::coroutine,
|
||
|
|
L::string,
|
||
|
|
L::os,
|
||
|
|
L::math,
|
||
|
|
L::table,
|
||
|
|
L::debug,
|
||
|
|
L::bit32,
|
||
|
|
L::io,
|
||
|
|
L::ffi,
|
||
|
|
L::jit);
|
||
|
|
|
||
|
|
lua.script("print('bark bark bark!')");
|
||
|
|
fmt::println("");
|
||
|
|
}
|
||
|
|
|
||
|
|
void test_sol_lua_error() {
|
||
|
|
BLOWS_UP([]() {
|
||
|
|
sol::state lua;
|
||
|
|
auto result1 = lua.safe_script("bad.code");
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
void test_variables_from_file() {
|
||
|
|
sol::state lua;
|
||
|
|
lua.script_file("tests/variables.lua");
|
||
|
|
|
||
|
|
CHECK(lua["config"]["fullscreen"] == false);
|
||
|
|
|
||
|
|
sol::table config = lua["config"];
|
||
|
|
CHECK(config["fullscreen"] == false);
|
||
|
|
}
|
||
|
|
|
||
|
|
void test_passing_args_to_scripts() {
|
||
|
|
sol::state lua;
|
||
|
|
lua.open_libraries(sol::lib::base);
|
||
|
|
|
||
|
|
const auto& my_script = R"(
|
||
|
|
local a,b,c = ...
|
||
|
|
print(a, b, c)
|
||
|
|
)";
|
||
|
|
|
||
|
|
sol::load_result fx = lua.load(my_script);
|
||
|
|
if(!fx.valid()) {
|
||
|
|
sol::error err = fx;
|
||
|
|
throw err;
|
||
|
|
}
|
||
|
|
|
||
|
|
fx("your", "arguments", "here");
|
||
|
|
}
|
||
|
|
|
||
|
|
void test_transfer_func() {
|
||
|
|
sol::state lua;
|
||
|
|
sol::state lua2;
|
||
|
|
|
||
|
|
lua2.open_libraries(sol::lib::base);
|
||
|
|
sol::load_result lr = lua.load("a = function(v) print(v) return v end");
|
||
|
|
CHECK(lr.valid());
|
||
|
|
|
||
|
|
sol::protected_function target = lr.get<sol::protected_function>();
|
||
|
|
sol::bytecode target_bc = target.dump();
|
||
|
|
|
||
|
|
auto result2 = lua2.safe_script(target_bc.as_string_view(), sol::script_pass_on_error);
|
||
|
|
CHECK(result2.valid());
|
||
|
|
|
||
|
|
sol::protected_function pf = lua2["a"];
|
||
|
|
int v = pf(25557);
|
||
|
|
CHECK(v == 25557);
|
||
|
|
}
|
||
|
|
|
||
|
|
void test_get_variables() {
|
||
|
|
sol::state lua;
|
||
|
|
lua.open_libraries(sol::lib::base);
|
||
|
|
|
||
|
|
lua.set("number", 24);
|
||
|
|
CHECK(lua["number"] == 24);
|
||
|
|
|
||
|
|
lua["number"] = 24.5;
|
||
|
|
CHECK(lua["number"] == 24.5);
|
||
|
|
|
||
|
|
// how to compare a string?
|
||
|
|
lua["important_string"] = "test";
|
||
|
|
std::string a_string = "test";
|
||
|
|
CHECK(lua["important_string"] == a_string);
|
||
|
|
|
||
|
|
lua["a_function"] = []() { return 100; };
|
||
|
|
auto result = lua["a_function"]();
|
||
|
|
CHECK(result.valid());
|
||
|
|
|
||
|
|
int as_int = result;
|
||
|
|
CHECK(as_int == 100);
|
||
|
|
|
||
|
|
lua["some_table"] = lua.create_table_with("value", 24);
|
||
|
|
CHECK(lua["some_table"]["value"] == 24);
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void test_this_has_a_bug_in_sol2() {
|
||
|
|
sol::state lua;
|
||
|
|
|
||
|
|
lua.script(R"(
|
||
|
|
function handler (message)
|
||
|
|
return "Handled this message: " .. message
|
||
|
|
end
|
||
|
|
|
||
|
|
function f (a)
|
||
|
|
if a < 0 then
|
||
|
|
error("negative number detected")
|
||
|
|
end
|
||
|
|
return a + 5
|
||
|
|
end
|
||
|
|
)");
|
||
|
|
|
||
|
|
sol::protected_function f = lua["f"];
|
||
|
|
// this fails, error_handler is private
|
||
|
|
// f.error_handler = lua["handler"];
|
||
|
|
|
||
|
|
sol::protected_function_result result = f(-500);
|
||
|
|
if (result.valid()) {
|
||
|
|
// Call succeeded
|
||
|
|
int x = result;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
// Call failed
|
||
|
|
sol::error err = result;
|
||
|
|
std::string what = err.what();
|
||
|
|
// 'what' Should read
|
||
|
|
// "Handled this message: negative number detected"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void test_multiple_returns() {
|
||
|
|
sol::state lua;
|
||
|
|
|
||
|
|
lua.script("function f(a,b,c) return a, b, c end");
|
||
|
|
|
||
|
|
std::tuple<int, int, int> result;
|
||
|
|
result = lua["f"](1, 2, 3);
|
||
|
|
|
||
|
|
CHECK(std::get<0>(result) == 1);
|
||
|
|
CHECK(std::get<1>(result) == 2);
|
||
|
|
CHECK(std::get<2>(result) == 3);
|
||
|
|
|
||
|
|
int a;
|
||
|
|
int b;
|
||
|
|
std::string c;
|
||
|
|
sol::tie(a, b, c) = lua["f"](1, 2, "bar");
|
||
|
|
|
||
|
|
CHECK(a == 1);
|
||
|
|
CHECK(b == 2);
|
||
|
|
CHECK(c == "bar");
|
||
|
|
}
|
||
|
|
|
||
|
|
sol::object fancy_func(sol::object a, sol::object b, sol::this_state s) {
|
||
|
|
sol::state_view lua(s);
|
||
|
|
if(a.is<int>() && b.is<int>()) {
|
||
|
|
return sol::make_object(lua, a.as<int>() + b.as<int>());
|
||
|
|
} else if(a.is<bool>()) {
|
||
|
|
bool do_triple = a.as<bool>();
|
||
|
|
return sol::make_object(lua, b.as<double>() * (do_triple ? 3 : 1));
|
||
|
|
} else {
|
||
|
|
return sol::make_object(lua, sol::lua_nil);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void test_any_object_types() {
|
||
|
|
sol::state lua;
|
||
|
|
|
||
|
|
lua["f"] = fancy_func;
|
||
|
|
|
||
|
|
int result = lua["f"](1, 2);
|
||
|
|
CHECK(result == 3);
|
||
|
|
|
||
|
|
double result2 = lua["f"](false, 2.5);
|
||
|
|
CHECK(result2 == 2.5);
|
||
|
|
|
||
|
|
lua.script("result3 = f(true, 5.5)");
|
||
|
|
double result3 = lua["result3"];
|
||
|
|
CHECK(result3 == 16.5);
|
||
|
|
}
|
||
|
|
|
||
|
|
struct player {
|
||
|
|
int bullets;
|
||
|
|
int speed;
|
||
|
|
|
||
|
|
player() : player(3, 100) {}
|
||
|
|
player(int ammo) : player(ammo, 100) {}
|
||
|
|
player(int ammo, int hitpoints) :
|
||
|
|
bullets(ammo), hp(hitpoints) {}
|
||
|
|
|
||
|
|
void boost() { speed += 10; }
|
||
|
|
bool shoot() {
|
||
|
|
if(bullets < 1) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
--bullets;
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
void set_hp(int value) {
|
||
|
|
hp = value;
|
||
|
|
}
|
||
|
|
|
||
|
|
int get_hp() const {
|
||
|
|
return hp;
|
||
|
|
}
|
||
|
|
private:
|
||
|
|
int hp;
|
||
|
|
};
|
||
|
|
|
||
|
|
void test_udt_operations() {
|
||
|
|
sol::state lua;
|
||
|
|
|
||
|
|
lua.open_libraries(sol::lib::base);
|
||
|
|
|
||
|
|
lua["p2"] = player(0);
|
||
|
|
|
||
|
|
sol::usertype<player> player_type = lua.new_usertype<player>("player",
|
||
|
|
sol::constructors<
|
||
|
|
player(),
|
||
|
|
player(int),
|
||
|
|
player(int, int)>());
|
||
|
|
|
||
|
|
player_type["shoot"] = &player::shoot;
|
||
|
|
player_type["boost"] = &player::boost;
|
||
|
|
player_type["hp"] = sol::property(&player::get_hp, &player::set_hp);
|
||
|
|
|
||
|
|
player_type["speed"] = &player::speed;
|
||
|
|
player_type.set("bullets", sol::readonly(&player::bullets));
|
||
|
|
|
||
|
|
lua.script_file("tests/prelude_script.lua");
|
||
|
|
lua.script_file("tests/player_script.lua");
|
||
|
|
}
|
||
|
|
|
||
|
|
fuc2::Set TESTS{
|
||
|
|
.name="sol2",
|
||
|
|
.options={ .fail_fast=false },
|
||
|
|
.tests={
|
||
|
|
TEST(test_basic_lua_run),
|
||
|
|
TEST(test_usertype_vars),
|
||
|
|
TEST(test_base_libraries),
|
||
|
|
TEST(test_sol_lua_error),
|
||
|
|
TEST(test_variables_from_file),
|
||
|
|
TEST(test_big_ass_vector),
|
||
|
|
TEST(test_passing_args_to_scripts),
|
||
|
|
TEST(test_get_variables),
|
||
|
|
TEST(test_this_has_a_bug_in_sol2),
|
||
|
|
TEST(test_multiple_returns),
|
||
|
|
TEST(test_any_object_types),
|
||
|
|
TEST(test_udt_operations),
|
||
|
|
}
|
||
|
|
};
|
||
|
|
}
|