diff options
Diffstat (limited to '')
-rw-r--r-- | unit_tests/embedded_tests.cpp | 192 |
1 files changed, 94 insertions, 98 deletions
diff --git a/unit_tests/embedded_tests.cpp b/unit_tests/embedded_tests.cpp index 03905d7..a6952b2 100644 --- a/unit_tests/embedded_tests.cpp +++ b/unit_tests/embedded_tests.cpp | |||
@@ -23,118 +23,114 @@ namespace | |||
23 | 23 | ||
24 | // ################################################################################################# | 24 | // ################################################################################################# |
25 | 25 | ||
26 | class EmbeddedTests : public ::testing::Test | 26 | TEST_CASE("embedding") |
27 | { | 27 | { |
28 | private: | ||
29 | HMODULE hCore{}; | ||
30 | |||
31 | protected: | ||
32 | LuaState S{ LuaState::WithBaseLibs{ false }, LuaState::WithFixture{ false } }; | 28 | LuaState S{ LuaState::WithBaseLibs{ false }, LuaState::WithFixture{ false } }; |
33 | lua_CFunction lanes_register{}; | ||
34 | 29 | ||
35 | void SetUp() override | 30 | HMODULE hCore = LoadLibraryW(L"lanes\\core"); |
36 | { | 31 | if (!hCore) { |
37 | hCore = LoadLibraryW(L"lanes\\core"); | 32 | throw std::logic_error("Could not load lanes.core"); |
38 | if (!hCore) { | 33 | } |
39 | throw std::logic_error("Could not load lanes.core"); | 34 | luaopen_lanes_embedded_t const _p_luaopen_lanes_embedded{ reinterpret_cast<luaopen_lanes_embedded_t>(GetProcAddress(hCore, "luaopen_lanes_embedded")) }; |
40 | } | 35 | if (!_p_luaopen_lanes_embedded) { |
41 | luaopen_lanes_embedded_t const _p_luaopen_lanes_embedded{ reinterpret_cast<luaopen_lanes_embedded_t>(GetProcAddress(hCore, "luaopen_lanes_embedded")) }; | 36 | throw std::logic_error("Could not bind luaopen_lanes_embedded"); |
42 | if (!_p_luaopen_lanes_embedded) { | 37 | } |
43 | throw std::logic_error("Could not bind luaopen_lanes_embedded"); | ||
44 | } | ||
45 | 38 | ||
46 | lanes_register = reinterpret_cast<lua_CFunction>(GetProcAddress(hCore, "lanes_register")); | 39 | lua_CFunction lanes_register = reinterpret_cast<lua_CFunction>(GetProcAddress(hCore, "lanes_register")); |
47 | if (!lanes_register) { | 40 | if (!lanes_register) { |
48 | throw std::logic_error("Could not bind lanes_register"); | 41 | throw std::logic_error("Could not bind lanes_register"); |
49 | } | 42 | } |
50 | // need base to make lanes happy | 43 | // need base to make lanes happy |
51 | luaL_requiref(S, LUA_GNAME, luaopen_base, 1); | 44 | luaL_requiref(S, LUA_GNAME, luaopen_base, 1); |
52 | lua_pop(S, 1); | 45 | lua_pop(S, 1); |
53 | S.stackCheck(0); | 46 | S.stackCheck(0); |
54 | 47 | ||
55 | // need package to be able to require lanes | 48 | // need package to be able to require lanes |
56 | luaL_requiref(S, LUA_LOADLIBNAME, luaopen_package, 1); | 49 | luaL_requiref(S, LUA_LOADLIBNAME, luaopen_package, 1); |
57 | lua_pop(S, 1); | 50 | lua_pop(S, 1); |
58 | S.stackCheck(0); | 51 | S.stackCheck(0); |
59 | 52 | ||
60 | // need table to make lanes happy | 53 | // need table to make lanes happy |
61 | luaL_requiref(S, LUA_TABLIBNAME, luaopen_table, 1); | 54 | luaL_requiref(S, LUA_TABLIBNAME, luaopen_table, 1); |
62 | lua_pop(S, 1); | 55 | lua_pop(S, 1); |
63 | S.stackCheck(0); | 56 | S.stackCheck(0); |
64 | 57 | ||
65 | // need string to make lanes happy | 58 | // need string to make lanes happy |
66 | luaL_requiref(S, LUA_STRLIBNAME, luaopen_string, 1); | 59 | luaL_requiref(S, LUA_STRLIBNAME, luaopen_string, 1); |
67 | lua_pop(S, 1); | 60 | lua_pop(S, 1); |
68 | S.stackCheck(0); | 61 | S.stackCheck(0); |
69 | 62 | ||
70 | _p_luaopen_lanes_embedded(S, local::load_lanes_lua); // S: lanes | 63 | auto load_lanes_lua = +[](lua_State* const L_) { |
71 | lua_pop(S, 1); | 64 | if (0 == luaL_dofile(L_, "lanes.lua")) { |
72 | S.stackCheck(0); | 65 | return 1; |
73 | } | 66 | } else { |
67 | return 0; | ||
68 | } | ||
69 | }; | ||
70 | |||
71 | _p_luaopen_lanes_embedded(S, local::load_lanes_lua); // S: lanes | ||
72 | lua_pop(S, 1); | ||
73 | S.stackCheck(0); | ||
74 | |||
75 | // --------------------------------------------------------------------------------------------- | ||
74 | 76 | ||
75 | void TearDown() override | 77 | SECTION("single state") |
76 | { | 78 | { |
77 | // close state manually before we unload lanes.core | 79 | // this sends data in a linda. current contents: |
78 | S.close(); | 80 | // key: short string |
79 | FreeLibrary(hCore); | 81 | // values: |
82 | // bool | ||
83 | // integer | ||
84 | // number | ||
85 | // long string | ||
86 | // table with array and hash parts | ||
87 | // function with an upvalue | ||
88 | std::string_view const _script{ | ||
89 | " local lanes = require 'lanes'.configure{with_timers = false}" | ||
90 | " local l = lanes.linda'gleh'" | ||
91 | " local upvalue = 'oeauaoeuoeuaoeuaoeujaoefubycfjbycfybcfjybcfjybcfjbcf'" | ||
92 | " local upvalued = function()" | ||
93 | " return upvalue" | ||
94 | " end" | ||
95 | " local t = setmetatable({ true, true, true, a = true}, {__index = rawget })" | ||
96 | " l:set('yo', true, 10, 100.0, upvalue, t, upvalued)" // put a breakpoint in linda_set to have some data to explore with the NATVIS | ||
97 | " return 'SUCCESS'" | ||
98 | }; | ||
99 | S.requireReturnedString(_script, "SUCCESS"); | ||
80 | } | 100 | } |
81 | }; | ||
82 | 101 | ||
83 | TEST_F(EmbeddedTests, SingleState) | 102 | // --------------------------------------------------------------------------------------------- |
84 | { | ||
85 | // this sends data in a linda. current contents: | ||
86 | // key: short string | ||
87 | // values: | ||
88 | // bool | ||
89 | // integer | ||
90 | // number | ||
91 | // long string | ||
92 | // table with array and hash parts | ||
93 | // function with an upvalue | ||
94 | std::string_view const script{ | ||
95 | " local lanes = require 'lanes'.configure{with_timers = false}" | ||
96 | " local l = lanes.linda'gleh'" | ||
97 | " local upvalue = 'oeauaoeuoeuaoeuaoeujaoefubycfjbycfybcfjybcfjybcfjbcf'" | ||
98 | " local upvalued = function()" | ||
99 | " return upvalue" | ||
100 | " end" | ||
101 | " local t = setmetatable({ true, true, true, a = true}, {__index = rawget })" | ||
102 | " l:set('yo', true, 10, 100.0, upvalue, t, upvalued)" // put a breakpoint in linda_set to have some data to explore with the NATVIS | ||
103 | " return 'SUCCESS'" | ||
104 | }; | ||
105 | std::string_view result = S.doStringAndRet(script); | ||
106 | ASSERT_EQ(result, "SUCCESS"); | ||
107 | } | ||
108 | 103 | ||
109 | // ################################################################################################# | 104 | SECTION("manual registration") |
105 | { | ||
106 | S.requireSuccess("require 'lanes'.configure{with_timers = false}"); | ||
110 | 107 | ||
111 | TEST_F(EmbeddedTests, ManualRegister) | 108 | // require 'io' library after Lanes is initialized: |
112 | { | 109 | luaL_requiref(S, LUA_IOLIBNAME, luaopen_io, 1); |
113 | ASSERT_EQ(S.doString("require 'lanes'.configure{with_timers = false}"), LuaError::OK) << S; | 110 | lua_pop(S, 1); |
114 | lua_pop(S, 1); | 111 | S.stackCheck(0); |
115 | 112 | ||
116 | // require 'io' library after Lanes is initialized: | 113 | // try to send io.open into a linda |
117 | luaL_requiref(S, LUA_IOLIBNAME, luaopen_io, 1); | 114 | std::string_view const _script{ |
118 | lua_pop(S, 1); | 115 | " local lanes = require 'lanes'.configure{with_timers = false}" |
119 | S.stackCheck(0); | 116 | " local l = lanes.linda'gleh'" |
117 | " l:set('yo', io.open)" | ||
118 | " return 'SUCCESS'" | ||
119 | }; | ||
120 | S.requireNotReturnedString(_script, "SUCCESS"); | ||
121 | |||
122 | // try again after manual registration | ||
123 | lua_pushcfunction(S, lanes_register); // S: lanes_register | ||
124 | luaG_pushstring(S, LUA_IOLIBNAME); // S: lanes_register "io" | ||
125 | luaL_requiref(S, LUA_IOLIBNAME, luaopen_io, 1); // S: lanes_register "io" io | ||
126 | lua_call(S, 2, 0); // S: | ||
127 | S.stackCheck(0); | ||
128 | S.requireReturnedString(_script, "SUCCESS"); | ||
129 | } | ||
120 | 130 | ||
121 | // try to send io.open into a linda | 131 | // --------------------------------------------------------------------------------------------- |
122 | std::string_view const script{ | 132 | |
123 | "local lanes = require 'lanes'.configure{with_timers = false}" | 133 | // close state manually before we unload lanes.core |
124 | "local l = lanes.linda'gleh'" | 134 | S.close(); |
125 | "l:set('yo', io.open)" | 135 | FreeLibrary(hCore); |
126 | "return 'SUCCESS'" | ||
127 | }; | ||
128 | std::string_view const result1{ S.doStringAndRet(script) }; | ||
129 | ASSERT_NE(result1, "SUCCESS") << S; // S: "msg" | ||
130 | lua_pop(S, 1); // S: | ||
131 | |||
132 | // try again after manual registration | ||
133 | lua_pushcfunction(S, lanes_register); // S: lanes_register | ||
134 | luaG_pushstring(S, LUA_IOLIBNAME); // S: lanes_register "io" | ||
135 | luaL_requiref(S, LUA_IOLIBNAME, luaopen_io, 1); // S: lanes_register "io" io | ||
136 | lua_call(S, 2, 0); // S: | ||
137 | S.stackCheck(0); | ||
138 | std::string_view const result2{ S.doStringAndRet(script) }; | ||
139 | ASSERT_EQ(result2, "SUCCESS") << S; | ||
140 | } | 136 | } |