libshit

Just some random shit
git clone https://git.neptards.moe/neptards/libshit.git
Log | Files | Refs | Submodules | README | LICENSE

user_type.cpp (4620B)


      1 #include "libshit/lua/user_type.hpp"
      2 
      3 #include "libshit/doctest.hpp"
      4 #include "libshit/lua/dynamic_object.hpp"
      5 #include "libshit/meta.hpp"
      6 #include "libshit/shared_ptr.hpp"
      7 
      8 namespace Libshit::Lua::Test
      9 {
     10   TEST_SUITE_BEGIN("Libshit::Lua::UserType");
     11   static int global;
     12 
     13   namespace
     14   {
     15     struct Smart final : public SmartObject
     16     {
     17       int x = 0;
     18 
     19       LIBSHIT_LUA_CLASS;
     20     };
     21 
     22     struct Foo final : public RefCounted, public DynamicObject
     23     {
     24       int local_var = 0;
     25       LIBSHIT_LUAGEN(get: "::Libshit::Lua::GetRefCountedOwnedMember")
     26       Smart smart;
     27       void DoIt(int x) { local_var = x; }
     28 
     29       Foo() = default; // no ctor generated otherwise.. (bug?)
     30       ~Foo() noexcept override { global += 13; }
     31 
     32       LIBSHIT_DYNAMIC_OBJECT;
     33     };
     34 
     35     namespace Bar::Baz
     36     {
     37       struct Asdfgh final : public DynamicObject
     38       {
     39         Asdfgh() = default;
     40         LIBSHIT_DYNAMIC_OBJECT;
     41       };
     42     }
     43 
     44     struct Baz : public DynamicObject
     45     {
     46       Baz() = default;
     47       void SetGlobal(int val) { global = val; }
     48       int GetRandom() { return 4; }
     49 
     50       LIBSHIT_DYNAMIC_OBJECT;
     51     };
     52   }
     53 
     54   TEST_CASE("shared check memory")
     55   {
     56     {
     57       State vm;
     58 
     59       global = 0;
     60       const char* str;
     61       SUBCASE("normal") str = "local x = libshit.lua.test.foo.new()";
     62       SUBCASE("short-cut") str = "local x = libshit.lua.test.foo()";
     63       SUBCASE("explicit call") str = "local x = libshit.lua.test.foo():__gc()";
     64 
     65       vm.DoString(str);
     66     }
     67     CHECK(global == 13);
     68   }
     69 
     70   TEST_CASE("resurrect shared object")
     71   {
     72     global = 0;
     73 
     74     {
     75       State vm;
     76       vm.TranslateException([&]()
     77       {
     78         auto ptr = MakeSmart<Foo>();
     79         vm.Push(ptr);
     80         lua_setglobal(vm, "fooobj");
     81 
     82         vm.DoString("fooobj:__gc() assert(getmetatable(fooobj) == nil)");
     83         REQUIRE(global == 0);
     84 
     85         vm.Push(ptr);
     86         lua_setglobal(vm, "fooobj");
     87         vm.DoString("fooobj:do_it(123)");
     88         CHECK(global == 0);
     89         CHECK(ptr->local_var == 123);
     90       });
     91     }
     92     CHECK(global == 13);
     93   }
     94 
     95   TEST_CASE("member function without helpers")
     96   {
     97     State vm;
     98 
     99     vm.DoString("local x = libshit.lua.test.foo() x:do_it(77) return x");
    100     CHECK(vm.TranslateException([&]() { return vm.Get<Foo>().local_var; }) == 77);
    101   }
    102 
    103   TEST_CASE("member function with helpers")
    104   {
    105     State vm;
    106 
    107     const char* str;
    108     int val;
    109     SUBCASE("normal call")
    110     { str = "libshit.lua.test.baz():set_global(42)"; val = 42; }
    111     SUBCASE("sugar")
    112     { str = "libshit.lua.test.baz().global = 43"; val = 43; }
    113     SUBCASE("read")
    114     { str = "local x = libshit.lua.test.baz() x.global = x.random"; val = 4; }
    115 
    116     vm.DoString(str);
    117     CHECK(global == val);
    118   }
    119 
    120   TEST_CASE("field access")
    121   {
    122     State vm;
    123     auto ptr = MakeSmart<Foo>();
    124     vm.TranslateException([&]()
    125     {
    126       vm.Push(ptr);
    127       lua_setglobal(vm, "foo");
    128       ptr->local_var = 13;
    129     });
    130 
    131     SUBCASE("get")
    132     {
    133       const char* str;
    134       SUBCASE("plain") { str = "return foo:get_local_var()"; }
    135       SUBCASE("sugar") { str = "return foo.local_var"; }
    136       vm.DoString(str);
    137       CHECK(vm.Get<int>() == 13);
    138     }
    139 
    140     SUBCASE("set")
    141     {
    142       const char* str;
    143       SUBCASE("plain") { str = "foo:set_local_var(42)"; }
    144       SUBCASE("sugar") { str = "foo.local_var = 42"; }
    145       vm.DoString(str);
    146       CHECK(ptr->local_var == 42);
    147     }
    148   }
    149 
    150   TEST_CASE("invalid field access yields nil")
    151   {
    152     State vm;
    153     vm.DoString("return libshit.lua.test.foo().bar");
    154     CHECK(lua_isnil(vm, -1));
    155   }
    156 
    157   TEST_CASE("dotted type name")
    158   {
    159     State vm;
    160     vm.DoString("local x = libshit.lua.test.bar.baz.asdfgh()");
    161   }
    162 
    163   TEST_CASE("aliased objects")
    164   {
    165     State vm;
    166     vm.DoString(R"(
    167 local f = libshit.lua.test.foo()
    168 assert(f ~= f.smart and f.smart == f.smart)
    169 f.smart.x = 7
    170 assert(f.smart.x == 7)
    171 )");
    172   }
    173 
    174   namespace
    175   {
    176     struct A : public DynamicObject
    177     {
    178       int x = 0;
    179 
    180       LIBSHIT_DYNAMIC_OBJECT;
    181     };
    182 
    183     struct B : public DynamicObject
    184     {
    185       int y = 1;
    186 
    187       LIBSHIT_DYNAMIC_OBJECT;
    188     };
    189 
    190     struct Multi : public A, public B
    191     {
    192       Multi() = default;
    193       SharedPtr<B> ptr;
    194 
    195       LIBSHIT_DYNAMIC_OBJECT;
    196     };
    197 
    198     static DynamicObject& GetDynamicObject(Multi& m) { return static_cast<A&>(m); }
    199   }
    200 
    201   TEST_CASE("multiple inheritance")
    202   {
    203     State vm;
    204     vm.DoString(R"(
    205 local m = libshit.lua.test.multi()
    206 m.ptr = libshit.lua.test.multi()
    207 m.y = 7
    208 m.ptr.x = 5
    209 m.ptr.y = 13
    210 assert(m.x == 0, "m.x")
    211 assert(m.y == 7, "m.y")
    212 assert(m.ptr.x == 5, "m.ptr.x")
    213 assert(m.ptr.y == 13, "m.ptr.y")
    214 )");
    215   }
    216 
    217   TEST_SUITE_END();
    218 }
    219 
    220 #include "user_type.binding.hpp"