function_ref.cpp (2817B)
1 #include "libshit/lua/function_ref.hpp" 2 3 #include "libshit/doctest.hpp" 4 #include "libshit/lua/dynamic_object.hpp" 5 #include "libshit/lua/type_traits.hpp" 6 #include "libshit/meta.hpp" 7 #include "libshit/shared_ptr.hpp" 8 9 #include <algorithm> 10 #include <vector> 11 12 namespace Libshit::Lua::Test 13 { 14 TEST_SUITE_BEGIN("Libshit::Lua::FunctionRef"); 15 16 TEST_CASE("FunctionRefs") 17 { 18 State vm; 19 vm.DoString("local i = 0 function f(j) i=i+1 return j or i end"); 20 REQUIRE(lua_getglobal(vm, "f") == LUA_TFUNCTION); 21 22 SUBCASE("FunctionRef") 23 { 24 FunctionRef<> fr{lua_absindex(vm, -1)}; 25 26 CHECK(fr.Call<int>(vm) == 1); 27 CHECK(fr.Call<int>(vm, 22) == 22); 28 CHECK(fr.Call<int>(vm) == 3); 29 CHECK(fr.Call<int>(vm, "10") == 10); // lua converts string to int 30 31 LIBSHIT_CHECK_LUA_THROWS(vm, 1, fr.Call<int>(vm, "xx"), ""); 32 } 33 34 SUBCASE("FunctionWrapGen") 35 { 36 FunctionWrapGen<int> fr{vm, lua_absindex(vm, -1)}; 37 38 CHECK(fr() == 1); 39 CHECK(fr(77) == 77); 40 41 LIBSHIT_CHECK_LUA_THROWS(vm, 1, fr("Hello"), ""); 42 } 43 44 SUBCASE("FunctionWrap") 45 { 46 FunctionWrap<int()> fr{vm, lua_absindex(vm, -1)}; 47 48 CHECK(fr() == 1); 49 static_assert(std::is_same_v< 50 decltype(&FunctionWrap<int()>::operator()), 51 int (FunctionWrap<int()>::*)()>); 52 } 53 } 54 55 TEST_CASE("FunctionWrap for stl algorithm") 56 { 57 State vm; 58 vm.DoString("function f(a, b) return math.abs(a) < math.abs(b) end"); 59 REQUIRE(lua_getglobal(vm, "f") == LUA_TFUNCTION); 60 61 std::vector<int> v{3, 9, -2, 7, -99, 13, -11}; 62 SUBCASE("FunctionWrap") 63 { 64 FunctionWrap<bool (int, int)> fr{vm, lua_absindex(vm, -1)}; 65 std::sort(v.begin(), v.end(), fr); 66 } 67 SUBCASE("FunctionWrapGen") 68 { 69 FunctionWrapGen<bool> fr{vm, lua_absindex(vm, -1)}; 70 std::sort(v.begin(), v.end(), fr); 71 } 72 73 std::vector<int> exp{-2, 3, 7, 9, -11, 13, -99}; 74 CHECK(v == exp); 75 } 76 77 namespace 78 { 79 struct FunctionRefTest : public SmartObject 80 { 81 template <typename Fun> 82 LIBSHIT_LUAGEN(template_params: %w(::Libshit::Lua::FunctionWrapGen<int>)) 83 void Cb(Fun f) { x = f(23, "hello"); } 84 85 template <typename Fun> 86 LIBSHIT_LUAGEN(template_params: %w(::Libshit::Lua::FunctionWrap<double(double)>)) 87 void Cb2(Fun f) { y = f(3.1415); } 88 89 int x = 0; 90 double y = 0; 91 92 LIBSHIT_LUA_CLASS; 93 }; 94 } 95 96 TEST_CASE("FunctionWrap parameters") 97 { 98 State vm; 99 auto x = MakeSmart<FunctionRefTest>(); 100 vm.Push(x); 101 lua_setglobal(vm, "foo"); 102 103 vm.DoString("foo:cb(function(n, str) return n + #str end)"); 104 CHECK(x->x == 23+5); 105 106 vm.DoString("foo:cb2(function(d) return d*2 end)"); 107 CHECK(x->y == doctest::Approx(2*3.1415)); 108 } 109 110 TEST_SUITE_END(); 111 } 112 113 #include "function_ref.binding.hpp"