diff options
Diffstat (limited to '')
-rw-r--r-- | unit_tests/init_and_shutdown.cpp | 1091 |
1 files changed, 553 insertions, 538 deletions
diff --git a/unit_tests/init_and_shutdown.cpp b/unit_tests/init_and_shutdown.cpp index d45b52f..83c0350 100644 --- a/unit_tests/init_and_shutdown.cpp +++ b/unit_tests/init_and_shutdown.cpp | |||
@@ -3,14 +3,12 @@ | |||
3 | 3 | ||
4 | // ################################################################################################# | 4 | // ################################################################################################# |
5 | 5 | ||
6 | TEST(Require, MissingBaseLibraries) | 6 | TEST_CASE("require 'lanes'") |
7 | { | 7 | { |
8 | LuaState L{ LuaState::WithBaseLibs{ false }, LuaState::WithFixture{ false } }; | 8 | LuaState L{ LuaState::WithBaseLibs{ false }, LuaState::WithFixture{ false } }; |
9 | 9 | ||
10 | // no base library loaded means no print() | 10 | // no base library loaded means no print() |
11 | EXPECT_NE(L.doString("print('hello')"), LuaError::OK); | 11 | L.requireFailure("print('hello')"); |
12 | L.stackCheck(1); | ||
13 | lua_pop(L, 1); | ||
14 | 12 | ||
15 | // need require() to require lanes | 13 | // need require() to require lanes |
16 | luaL_requiref(L, LUA_LOADLIBNAME, luaopen_package, 0); | 14 | luaL_requiref(L, LUA_LOADLIBNAME, luaopen_package, 0); |
@@ -18,9 +16,7 @@ TEST(Require, MissingBaseLibraries) | |||
18 | L.stackCheck(0); | 16 | L.stackCheck(0); |
19 | 17 | ||
20 | // no base library loaded means lanes should issue an error | 18 | // no base library loaded means lanes should issue an error |
21 | EXPECT_NE(L.doString("require 'lanes'"), LuaError::OK); | 19 | L.requireFailure("require 'lanes'"); |
22 | lua_pop(L, 1); | ||
23 | L.stackCheck(0); | ||
24 | 20 | ||
25 | // need base to make lanes happy | 21 | // need base to make lanes happy |
26 | luaL_requiref(L, LUA_GNAME, luaopen_base, 1); | 22 | luaL_requiref(L, LUA_GNAME, luaopen_base, 1); |
@@ -28,9 +24,7 @@ TEST(Require, MissingBaseLibraries) | |||
28 | L.stackCheck(0); | 24 | L.stackCheck(0); |
29 | 25 | ||
30 | // no table library loaded means lanes should issue an error | 26 | // no table library loaded means lanes should issue an error |
31 | EXPECT_NE(L.doString("require 'lanes'"), LuaError::OK); | 27 | L.requireFailure("require 'lanes'"); |
32 | L.stackCheck(1); | ||
33 | lua_pop(L, 1); | ||
34 | 28 | ||
35 | // need table to make lanes happy | 29 | // need table to make lanes happy |
36 | luaL_requiref(L, LUA_TABLIBNAME, luaopen_table, 1); | 30 | luaL_requiref(L, LUA_TABLIBNAME, luaopen_table, 1); |
@@ -38,9 +32,7 @@ TEST(Require, MissingBaseLibraries) | |||
38 | L.stackCheck(0); | 32 | L.stackCheck(0); |
39 | 33 | ||
40 | // no string library loaded means lanes should issue an error | 34 | // no string library loaded means lanes should issue an error |
41 | EXPECT_NE(L.doString("require 'lanes'"), LuaError::OK); | 35 | L.requireFailure("require 'lanes'"); |
42 | lua_pop(L, 1); | ||
43 | L.stackCheck(0); | ||
44 | 36 | ||
45 | // need string to make lanes happy | 37 | // need string to make lanes happy |
46 | luaL_requiref(L, LUA_STRLIBNAME, luaopen_string, 1); | 38 | luaL_requiref(L, LUA_STRLIBNAME, luaopen_string, 1); |
@@ -50,7 +42,7 @@ TEST(Require, MissingBaseLibraries) | |||
50 | // all required libraries are here: we should be happy | 42 | // all required libraries are here: we should be happy |
51 | // that's only the case for Lua > 5.1 though, because the latter can't require() a module after a previously failed attempt (like we just did) | 43 | // that's only the case for Lua > 5.1 though, because the latter can't require() a module after a previously failed attempt (like we just did) |
52 | if constexpr (LUA_VERSION_NUM > 501) { | 44 | if constexpr (LUA_VERSION_NUM > 501) { |
53 | ASSERT_EQ(L.doString("require 'lanes'"), LuaError::OK); | 45 | L.requireSuccess("require 'lanes'"); |
54 | } else { | 46 | } else { |
55 | // so let's do a fresh attempt in a virgin state where we have the 3 base libraries we need (plus 'package' to be able to require it of course) | 47 | // so let's do a fresh attempt in a virgin state where we have the 3 base libraries we need (plus 'package' to be able to require it of course) |
56 | LuaState L51{ LuaState::WithBaseLibs{ false }, LuaState::WithFixture{ false } }; | 48 | LuaState L51{ LuaState::WithBaseLibs{ false }, LuaState::WithFixture{ false } }; |
@@ -59,625 +51,653 @@ TEST(Require, MissingBaseLibraries) | |||
59 | luaL_requiref(L51, LUA_TABLIBNAME, luaopen_table, 1); | 51 | luaL_requiref(L51, LUA_TABLIBNAME, luaopen_table, 1); |
60 | luaL_requiref(L51, LUA_STRLIBNAME, luaopen_string, 1); | 52 | luaL_requiref(L51, LUA_STRLIBNAME, luaopen_string, 1); |
61 | lua_settop(L51, 0); | 53 | lua_settop(L51, 0); |
62 | ASSERT_EQ(L51.doString("require 'lanes'"), LuaError::OK); | 54 | L51.requireSuccess("require 'lanes'"); |
63 | } | 55 | } |
64 | } | 56 | } |
65 | 57 | ||
66 | class Configure : public ::testing::Test | ||
67 | { | ||
68 | protected: | ||
69 | LuaState L{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } }; | ||
70 | }; | ||
71 | |||
72 | // ################################################################################################# | 58 | // ################################################################################################# |
73 | // ################################################################################################# | 59 | // ################################################################################################# |
74 | // allocator should be "protected", a C function returning a suitable userdata, or nil | 60 | // allocator should be "protected", a C function returning a suitable userdata, or nil |
75 | 61 | ||
76 | TEST_F(Configure, AllocatorFalse) | 62 | TEST_CASE("lanes.configure") |
77 | { | 63 | { |
78 | EXPECT_NE(L.doString("require 'lanes'.configure{allocator = false}"), LuaError::OK); | 64 | LuaState L{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } }; |
79 | } | ||
80 | 65 | ||
81 | // ################################################################################################# | 66 | // --------------------------------------------------------------------------------------------- |
82 | 67 | ||
83 | TEST_F(Configure, AllocatorTrue) | 68 | SECTION("allocator", "[allocator]") |
84 | { | 69 | { |
85 | EXPECT_NE(L.doString("require 'lanes'.configure{allocator = true}"), LuaError::OK); | 70 | SECTION("allocator = false") |
86 | } | 71 | { |
72 | L.requireFailure("require 'lanes'.configure{allocator = false}"); | ||
73 | } | ||
87 | 74 | ||
88 | // ################################################################################################# | 75 | // ----------------------------------------------------------------------------------------- |
89 | 76 | ||
90 | TEST_F(Configure, AllocatorNumber) | 77 | SECTION("allocator = true") |
91 | { | 78 | { |
92 | EXPECT_NE(L.doString("require 'lanes'.configure{allocator = 33}"), LuaError::OK); | 79 | L.requireFailure("require 'lanes'.configure{allocator = true}"); |
93 | } | 80 | } |
94 | 81 | ||
95 | // ################################################################################################# | 82 | // ----------------------------------------------------------------------------------------- |
96 | 83 | ||
97 | TEST_F(Configure, AllocatorTable) | 84 | SECTION("allocator = <number>") |
98 | { | 85 | { |
99 | EXPECT_NE(L.doString("require 'lanes'.configure{allocator = {}}"), LuaError::OK); | 86 | L.requireFailure("require 'lanes'.configure{allocator = 33}"); |
100 | } | 87 | } |
101 | 88 | ||
102 | // ################################################################################################# | 89 | // ----------------------------------------------------------------------------------------- |
103 | 90 | ||
104 | TEST_F(Configure, AllocatorLuaFunction) | 91 | SECTION("allocator = <table>") |
105 | { | 92 | { |
106 | EXPECT_NE(L.doString("require 'lanes'.configure{allocator = function() return {}, 12, 'yoy' end}"), LuaError::OK); | 93 | L.requireFailure("require 'lanes'.configure{allocator = {}}"); |
107 | } | 94 | } |
108 | 95 | ||
109 | // ################################################################################################# | 96 | // ----------------------------------------------------------------------------------------- |
110 | 97 | ||
111 | TEST_F(Configure, AllocatorBadCFunction) | 98 | SECTION("allocator = <Lua function>") |
112 | { | 99 | { |
113 | // a C function that doesn't return what we expect should cause an error too | 100 | L.requireFailure("require 'lanes'.configure{allocator = function() return {}, 12, 'yoy' end}"); |
114 | EXPECT_NE(L.doString("require 'lanes'.configure{allocator = print}"), LuaError::OK); | 101 | } |
115 | } | ||
116 | 102 | ||
117 | // ################################################################################################# | 103 | // ----------------------------------------------------------------------------------------- |
118 | 104 | ||
119 | TEST_F(Configure, AllocatorTypo) | 105 | SECTION("allocator = <bad C function>") |
120 | { | 106 | { |
121 | // oops, a typo | 107 | // a C function that doesn't return what we expect should cause an error too |
122 | EXPECT_NE(L.doString("require 'lanes'.configure{allocator = 'Protected'}"), LuaError::OK); | 108 | L.requireFailure("require 'lanes'.configure{allocator = print}"); |
123 | } | 109 | } |
124 | 110 | ||
125 | // ################################################################################################# | 111 | // ----------------------------------------------------------------------------------------- |
126 | 112 | ||
127 | TEST_F(Configure, AllocatorProtected) | 113 | SECTION("allocator = <string with a typo>") |
128 | { | 114 | { |
129 | // no typo, should work | 115 | // oops, a typo |
130 | EXPECT_EQ(L.doString("require 'lanes'.configure{allocator = 'protected'}"), LuaError::OK); | 116 | L.requireFailure("require 'lanes'.configure{allocator = 'Protected'}"); |
131 | } | 117 | } |
132 | 118 | ||
133 | // ################################################################################################# | 119 | // ----------------------------------------------------------------------------------------- |
134 | 120 | ||
135 | TEST_F(Configure, AllocatorCustomOk) | 121 | SECTION("allocator = 'protected'") |
136 | { | 122 | { |
137 | // a function that provides what we expect is fine | 123 | // no typo, should work |
138 | static constexpr lua_CFunction _provideAllocator = +[](lua_State* const L_) { | 124 | L.requireSuccess("require 'lanes'.configure{allocator = 'protected'}"); |
139 | lanes::AllocatorDefinition* const _def{ new (L_) lanes::AllocatorDefinition{} }; | 125 | } |
140 | _def->initFrom(L_); | ||
141 | return 1; | ||
142 | }; | ||
143 | lua_pushcfunction(L, _provideAllocator); | ||
144 | lua_setglobal(L, "ProvideAllocator"); | ||
145 | EXPECT_EQ(L.doString("require 'lanes'.configure{allocator = ProvideAllocator}"), LuaError::OK); | ||
146 | } | ||
147 | 126 | ||
148 | // ################################################################################################# | 127 | // ----------------------------------------------------------------------------------------- |
149 | 128 | ||
150 | TEST_F(Configure, AllocatorCustomWrongResultType) | 129 | SECTION("allocator = <good custom C allocator>") |
151 | { | 130 | { |
152 | // a function that provides something that is definitely not an AllocatorDefinition, should cause an error | 131 | // a function that provides what we expect is fine |
153 | static constexpr lua_CFunction _provideAllocator = +[](lua_State* const L_) { | 132 | static constexpr lua_CFunction _provideAllocator = +[](lua_State* const L_) { |
154 | lua_newtable(L_); | 133 | lanes::AllocatorDefinition* const _def{ new (L_) lanes::AllocatorDefinition{} }; |
155 | return 1; | 134 | _def->initFrom(L_); |
156 | }; | 135 | return 1; |
157 | lua_pushcfunction(L, _provideAllocator); | 136 | }; |
158 | lua_setglobal(L, "ProvideAllocator"); | 137 | lua_pushcfunction(L, _provideAllocator); |
159 | EXPECT_NE(L.doString("require 'lanes'.configure{allocator = ProvideAllocator}"), LuaError::OK); | 138 | lua_setglobal(L, "ProvideAllocator"); |
160 | } | 139 | L.requireSuccess("require 'lanes'.configure{allocator = ProvideAllocator}"); |
140 | } | ||
161 | 141 | ||
162 | // ################################################################################################# | 142 | // ----------------------------------------------------------------------------------------- |
163 | 143 | ||
164 | TEST_F(Configure, AllocatorCustomSignatureMismatch) | 144 | SECTION("allocator not returning an AllocatorDefinition") |
165 | { | 145 | { |
166 | // a function that provides something that is too small to contain an AllocatorDefinition, should cause an error | 146 | // a function that provides something that is definitely not an AllocatorDefinition, should cause an error |
167 | static constexpr lua_CFunction _provideAllocator = +[](lua_State* const L_) { | 147 | static constexpr lua_CFunction _provideAllocator = +[](lua_State* const L_) { |
168 | // create a full userdata that is too small (it only contains enough to store a version tag, but not the rest | 148 | lua_newtable(L_); |
169 | auto* const _duck{ static_cast<lanes::AllocatorDefinition::version_t*>(lua_newuserdata(L_, sizeof(lanes::AllocatorDefinition::version_t))) }; | 149 | return 1; |
170 | *_duck = 666777; | 150 | }; |
171 | return 1; | 151 | lua_pushcfunction(L, _provideAllocator); |
172 | }; | 152 | lua_setglobal(L, "ProvideAllocator"); |
173 | lua_pushcfunction(L, _provideAllocator); | 153 | L.requireFailure("require 'lanes'.configure{allocator = ProvideAllocator}"); |
174 | lua_setglobal(L, "ProvideAllocator"); | 154 | } |
175 | EXPECT_NE(L.doString("require 'lanes'.configure{allocator = ProvideAllocator}"), LuaError::OK); | ||
176 | } | ||
177 | 155 | ||
178 | // ################################################################################################# | 156 | // ----------------------------------------------------------------------------------------- |
179 | 157 | ||
180 | TEST_F(Configure, AllocatorCustomSizeMismatch) | 158 | SECTION("allocator returning an AllocatorDefinition with the wrong signature") |
181 | { | 159 | { |
182 | // a function that provides something that attempts to pass as an AllocatorDefinition, but is not, should cause an error | 160 | // a function that provides something that is too small to contain an AllocatorDefinition, should cause an error |
183 | static constexpr lua_CFunction _provideAllocator = +[](lua_State* const L_) { | 161 | static constexpr lua_CFunction _provideAllocator = +[](lua_State* const L_) { |
184 | // create a full userdata of the correct size, but of course the contents don't match | 162 | // create a full userdata that is too small (it only contains enough to store a version tag, but not the rest |
185 | int* const _duck{ static_cast<int*>(lua_newuserdata(L_, sizeof(lanes::AllocatorDefinition))) }; | 163 | auto* const _duck{ static_cast<lanes::AllocatorDefinition::version_t*>(lua_newuserdata(L_, sizeof(lanes::AllocatorDefinition::version_t))) }; |
186 | _duck[0] = 666; | 164 | *_duck = 666777; |
187 | _duck[1] = 777; | 165 | return 1; |
188 | return 1; | 166 | }; |
189 | }; | 167 | lua_pushcfunction(L, _provideAllocator); |
190 | lua_pushcfunction(L, _provideAllocator); | 168 | lua_setglobal(L, "ProvideAllocator"); |
191 | lua_setglobal(L, "ProvideAllocator"); | 169 | L.requireFailure("require 'lanes'.configure{allocator = ProvideAllocator}"); |
192 | EXPECT_NE(L.doString("require 'lanes'.configure{allocator = ProvideAllocator}"), LuaError::OK); | 170 | } |
193 | } | ||
194 | 171 | ||
195 | // ################################################################################################# | 172 | // ----------------------------------------------------------------------------------------- |
196 | // ################################################################################################# | ||
197 | // internal_allocator should be a string, "libc"/"allocator" | ||
198 | 173 | ||
199 | TEST_F(Configure, InternalAllocatorFalse) | 174 | SECTION("allocator returning something too small to be a valid AllocatorDefinition") |
200 | { | 175 | { |
201 | EXPECT_NE(L.doString("require 'lanes'.configure{internal_allocator = false}"), LuaError::OK); | 176 | // a function that provides something that attempts to pass as an AllocatorDefinition, but is not, should cause an error |
202 | } | 177 | static constexpr lua_CFunction _provideAllocator = +[](lua_State* const L_) { |
178 | // create a full userdata of the correct size, but of course the contents don't match | ||
179 | int* const _duck{ static_cast<int*>(lua_newuserdata(L_, sizeof(lanes::AllocatorDefinition))) }; | ||
180 | _duck[0] = 666; | ||
181 | _duck[1] = 777; | ||
182 | return 1; | ||
183 | }; | ||
184 | lua_pushcfunction(L, _provideAllocator); | ||
185 | lua_setglobal(L, "ProvideAllocator"); | ||
186 | L.requireFailure("require 'lanes'.configure{allocator = ProvideAllocator}"); | ||
187 | } | ||
188 | } | ||
203 | 189 | ||
204 | // ################################################################################################# | 190 | // --------------------------------------------------------------------------------------------- |
191 | // internal_allocator should be a string, "libc"/"allocator" | ||
205 | 192 | ||
206 | TEST_F(Configure, InternalAllocatorTrue) | 193 | SECTION("[internal_allocator") |
207 | { | 194 | { |
208 | EXPECT_NE(L.doString("require 'lanes'.configure{internal_allocator = true}"), LuaError::OK); | 195 | SECTION("internal_allocator = false") |
209 | } | 196 | { |
197 | L.requireFailure("require 'lanes'.configure{internal_allocator = false}"); | ||
198 | } | ||
210 | 199 | ||
211 | // ################################################################################################# | 200 | // ----------------------------------------------------------------------------------------- |
212 | 201 | ||
213 | TEST_F(Configure, InternalAllocatorTable) | 202 | SECTION("internal_allocator = true") |
214 | { | 203 | { |
215 | EXPECT_NE(L.doString("require 'lanes'.configure{internal_allocator = {}}"), LuaError::OK); | 204 | L.requireFailure("require 'lanes'.configure{internal_allocator = true}"); |
216 | } | 205 | } |
217 | 206 | ||
218 | // ################################################################################################# | 207 | // ----------------------------------------------------------------------------------------- |
219 | 208 | ||
220 | TEST_F(Configure, InternalAllocatorFunction) | 209 | SECTION("internal_allocator = <table>") |
221 | { | 210 | { |
222 | EXPECT_NE(L.doString("require 'lanes'.configure{internal_allocator = function() end}"), LuaError::OK); | 211 | L.requireFailure("require 'lanes'.configure{internal_allocator = {}}"); |
223 | } | 212 | } |
224 | 213 | ||
225 | // ################################################################################################# | 214 | // ----------------------------------------------------------------------------------------- |
226 | 215 | ||
227 | TEST_F(Configure, InternalAllocatorString) | 216 | SECTION("internal_allocator = <Lua function>") |
228 | { | 217 | { |
229 | EXPECT_NE(L.doString("require 'lanes'.configure{internal_allocator = 'gluh'}"), LuaError::OK); | 218 | L.requireFailure("require 'lanes'.configure{internal_allocator = function() end}"); |
230 | } | 219 | } |
231 | 220 | ||
232 | // ################################################################################################# | 221 | // ----------------------------------------------------------------------------------------- |
233 | 222 | ||
234 | TEST_F(Configure, InternalAllocatorLibc) | 223 | SECTION("internal_allocator = <bad string>") |
235 | { | 224 | { |
236 | EXPECT_EQ(L.doString("require 'lanes'.configure{internal_allocator = 'libc'}"), LuaError::OK); | 225 | L.requireFailure("require 'lanes'.configure{internal_allocator = 'gluh'}"); |
237 | } | 226 | } |
238 | 227 | ||
239 | // ################################################################################################# | 228 | // ----------------------------------------------------------------------------------------- |
240 | 229 | ||
241 | TEST_F(Configure, InternalAllocatorAllocator) | 230 | SECTION("internal_allocator = 'libc'") |
242 | { | 231 | { |
243 | EXPECT_EQ(L.doString("require 'lanes'.configure{internal_allocator = 'allocator'}"), LuaError::OK); | 232 | L.requireSuccess("require 'lanes'.configure{internal_allocator = 'libc'}"); |
244 | } | 233 | } |
245 | 234 | ||
246 | // ################################################################################################# | 235 | // ----------------------------------------------------------------------------------------- |
247 | // ################################################################################################# | ||
248 | // keepers_gc_threshold should be a number in [0, 100] | ||
249 | 236 | ||
250 | TEST_F(Configure, KeepersGcThresholdTable) | 237 | SECTION("internal_allocator = 'allocator'") |
251 | { | 238 | { |
252 | EXPECT_NE(L.doString("require 'lanes'.configure{keepers_gc_threshold = {}}"), LuaError::OK); | 239 | L.requireSuccess("require 'lanes'.configure{internal_allocator = 'allocator'}"); |
253 | } | 240 | } |
241 | } | ||
254 | 242 | ||
255 | // ################################################################################################# | 243 | // --------------------------------------------------------------------------------------------- |
244 | // keepers_gc_threshold should be a number in [0, 100] | ||
256 | 245 | ||
257 | TEST_F(Configure, KeepersGcThresholdString) | 246 | SECTION("keepers_gc_threshold") |
258 | { | 247 | { |
259 | EXPECT_NE(L.doString("require 'lanes'.configure{keepers_gc_threshold = 'gluh'}"), LuaError::OK); | 248 | SECTION("keepers_gc_threshold = <table>") |
260 | } | 249 | { |
250 | L.requireFailure("require 'lanes'.configure{keepers_gc_threshold = {}}"); | ||
251 | } | ||
261 | 252 | ||
262 | // ################################################################################################# | 253 | // ----------------------------------------------------------------------------------------- |
263 | 254 | ||
264 | TEST_F(Configure, KeepersGcThresholdNegative) | 255 | SECTION("keepers_gc_threshold = <string>") |
265 | { | 256 | { |
266 | EXPECT_EQ(L.doString("require 'lanes'.configure{keepers_gc_threshold = -1}"), LuaError::OK); | 257 | L.requireFailure("require 'lanes'.configure{keepers_gc_threshold = 'gluh'}"); |
267 | } | 258 | } |
268 | 259 | ||
269 | // ################################################################################################# | 260 | // ----------------------------------------------------------------------------------------- |
270 | 261 | ||
271 | TEST_F(Configure, KeepersGcThresholdZero) | 262 | SECTION("keepers_gc_threshold = -1") |
272 | { | 263 | { |
273 | EXPECT_EQ(L.doString("require 'lanes'.configure{keepers_gc_threshold = 0}"), LuaError::OK); | 264 | L.requireSuccess("require 'lanes'.configure{keepers_gc_threshold = -1}"); |
274 | } | 265 | } |
275 | 266 | ||
276 | // ################################################################################################# | 267 | // ----------------------------------------------------------------------------------------- |
277 | 268 | ||
278 | TEST_F(Configure, KeepersGcThresholdHundred) | 269 | SECTION("keepers_gc_threshold = 0") |
279 | { | 270 | { |
280 | EXPECT_EQ(L.doString("require 'lanes'.configure{keepers_gc_threshold = 100}"), LuaError::OK); | 271 | L.requireSuccess("require 'lanes'.configure{keepers_gc_threshold = 0}"); |
281 | } | 272 | } |
282 | 273 | ||
283 | // ################################################################################################# | 274 | // ----------------------------------------------------------------------------------------- |
284 | // ################################################################################################# | ||
285 | // nb_user_keepers should be a number in [0, 100] | ||
286 | 275 | ||
287 | TEST_F(Configure, NbUserKeepersTable) | 276 | SECTION("keepers_gc_threshold = 100") |
288 | { | 277 | { |
289 | EXPECT_NE(L.doString("require 'lanes'.configure{nb_user_keepers = {}}"), LuaError::OK); | 278 | L.requireSuccess("require 'lanes'.configure{keepers_gc_threshold = 100}"); |
290 | } | 279 | } |
280 | } | ||
291 | 281 | ||
292 | // ################################################################################################# | 282 | // --------------------------------------------------------------------------------------------- |
283 | // nb_user_keepers should be a number in [0, 100] | ||
293 | 284 | ||
294 | TEST_F(Configure, NbUserKeepersString) | 285 | SECTION("nb_user_keepers") |
295 | { | 286 | { |
296 | EXPECT_NE(L.doString("require 'lanes'.configure{nb_user_keepers = 'gluh'}"), LuaError::OK); | 287 | SECTION("nb_user_keepers = <table>") |
297 | } | 288 | { |
289 | L.requireFailure("require 'lanes'.configure{nb_user_keepers = {}}"); | ||
290 | } | ||
298 | 291 | ||
299 | // ################################################################################################# | 292 | // ----------------------------------------------------------------------------------------- |
300 | 293 | ||
301 | TEST_F(Configure, NbUserKeepersNegative) | 294 | SECTION("nb_user_keepers = <string>") |
302 | { | 295 | { |
303 | EXPECT_NE(L.doString("require 'lanes'.configure{nb_user_keepers = -1}"), LuaError::OK); | 296 | L.requireFailure("require 'lanes'.configure{nb_user_keepers = 'gluh'}"); |
304 | } | 297 | } |
305 | 298 | ||
306 | // ################################################################################################# | 299 | // ----------------------------------------------------------------------------------------- |
307 | 300 | ||
308 | TEST_F(Configure, NbUserKeepersZero) | 301 | SECTION("nb_user_keepers = -1") |
309 | { | 302 | { |
310 | EXPECT_EQ(L.doString("require 'lanes'.configure{nb_user_keepers = 0}"), LuaError::OK); | 303 | L.requireFailure("require 'lanes'.configure{nb_user_keepers = -1}"); |
311 | } | 304 | } |
312 | 305 | ||
313 | // ################################################################################################# | 306 | // ----------------------------------------------------------------------------------------- |
314 | 307 | ||
315 | TEST_F(Configure, NbUserKeepersHundred) | 308 | SECTION("nb_user_keepers = 0") |
316 | { | 309 | { |
317 | EXPECT_EQ(L.doString("require 'lanes'.configure{nb_user_keepers = 100}"), LuaError::OK); | 310 | L.requireSuccess("require 'lanes'.configure{nb_user_keepers = 0}"); |
318 | } | 311 | } |
319 | 312 | ||
320 | // ################################################################################################# | 313 | // ----------------------------------------------------------------------------------------- |
321 | 314 | ||
322 | TEST_F(Configure, NbUserKeepersHundredAndOne) | 315 | SECTION("nb_user_keepers = 100") |
323 | { | 316 | { |
324 | EXPECT_NE(L.doString("require 'lanes'.configure{nb_user_keepers = 101}"), LuaError::OK); | 317 | L.requireSuccess("require 'lanes'.configure{nb_user_keepers = 100}"); |
325 | } | 318 | } |
326 | 319 | ||
327 | // ################################################################################################# | 320 | // ----------------------------------------------------------------------------------------- |
328 | // ################################################################################################# | ||
329 | // on_state_create should be a function, either C or Lua, without upvalues | ||
330 | 321 | ||
331 | TEST_F(Configure, OnStateCreateTable) | 322 | SECTION("nb_user_keepers = 101") |
332 | { | 323 | { |
333 | EXPECT_NE(L.doString("require 'lanes'.configure{on_state_create = {}}"), LuaError::OK); | 324 | L.requireFailure("require 'lanes'.configure{nb_user_keepers = 101}"); |
334 | } | 325 | } |
326 | } | ||
335 | 327 | ||
336 | // ################################################################################################# | 328 | // --------------------------------------------------------------------------------------------- |
329 | // on_state_create should be a function, either C or Lua, without upvalues | ||
337 | 330 | ||
338 | TEST_F(Configure, OnStateCreateString) | 331 | SECTION("on_state_create") |
339 | { | 332 | { |
340 | EXPECT_NE(L.doString("require 'lanes'.configure{on_state_create = 'gluh'}"), LuaError::OK); | 333 | SECTION("on_state_create = <table>") |
341 | } | 334 | { |
335 | L.requireFailure("require 'lanes'.configure{on_state_create = {}}"); | ||
336 | } | ||
342 | 337 | ||
343 | // ################################################################################################# | 338 | // ----------------------------------------------------------------------------------------- |
344 | 339 | ||
345 | TEST_F(Configure, OnStateCreateNumber) | 340 | SECTION("on_state_create = <string>") |
346 | { | 341 | { |
347 | EXPECT_NE(L.doString("require 'lanes'.configure{on_state_create = 1}"), LuaError::OK); | 342 | L.requireFailure("require 'lanes'.configure{on_state_create = 'gluh'}"); |
348 | } | 343 | } |
349 | 344 | ||
350 | // ################################################################################################# | 345 | // ----------------------------------------------------------------------------------------- |
351 | 346 | ||
352 | TEST_F(Configure, OnStateCreateFalse) | 347 | SECTION("on_state_create = <number>") |
353 | { | 348 | { |
354 | EXPECT_NE(L.doString("require 'lanes'.configure{on_state_create = false}"), LuaError::OK); | 349 | L.requireFailure("require 'lanes'.configure{on_state_create = 1}"); |
355 | } | 350 | } |
356 | 351 | ||
357 | // ################################################################################################# | 352 | // ----------------------------------------------------------------------------------------- |
358 | 353 | ||
359 | TEST_F(Configure, OnStateCreateTrue) | 354 | SECTION("on_state_create = false") |
360 | { | 355 | { |
361 | EXPECT_NE(L.doString("require 'lanes'.configure{on_state_create = true}"), LuaError::OK); | 356 | L.requireFailure("require 'lanes'.configure{on_state_create = false}"); |
362 | } | 357 | } |
363 | 358 | ||
364 | // ################################################################################################# | 359 | // ----------------------------------------------------------------------------------------- |
365 | 360 | ||
366 | TEST_F(Configure, OnStateCreateUpvaluedFunction) | 361 | SECTION("on_state_create = true") |
367 | { | 362 | { |
368 | // on_state_create isn't called inside a Keeper state if it's a Lua function (which is good as print() doesn't exist there!) | 363 | L.requireFailure("require 'lanes'.configure{on_state_create = true}"); |
369 | EXPECT_EQ(L.doString("local print = print; require 'lanes'.configure{on_state_create = function() print 'hello' end}"), LuaError::OK); | 364 | } |
370 | } | ||
371 | 365 | ||
372 | // ################################################################################################# | 366 | // ----------------------------------------------------------------------------------------- |
373 | 367 | ||
374 | TEST_F(Configure, OnStateCreateCFunction) | 368 | SECTION("on_state_create = <Lua function>") |
375 | { | 369 | { |
376 | // funnily enough, in Lua 5.3, print() uses global tostring(), that doesn't exist in a keeper since we didn't open libs -> "attempt to call a nil value" | 370 | // on_state_create isn't called inside a Keeper state if it's a Lua function (which is good as print() doesn't exist there!) |
377 | // conclusion, don't use print() as a fake on_state_create() callback! | 371 | L.requireSuccess("local print = print; require 'lanes'.configure{on_state_create = function() print 'hello' end}"); |
378 | // assert() should be fine since we pass a non-false argument to on_state_create | 372 | } |
379 | EXPECT_EQ(L.doString("require 'lanes'.configure{on_state_create = assert}"), LuaError::OK); | ||
380 | } | ||
381 | 373 | ||
382 | // ################################################################################################# | 374 | // ----------------------------------------------------------------------------------------- |
383 | // ################################################################################################# | ||
384 | // shutdown_timeout should be a number in [0,3600] | ||
385 | 375 | ||
386 | TEST_F(Configure, ShutdownTimeoutTable) | 376 | SECTION("on_state_create = <C function>") |
387 | { | 377 | { |
388 | EXPECT_NE(L.doString("require 'lanes'.configure{shutdown_timeout = {}}"), LuaError::OK); | 378 | // funnily enough, in Lua 5.3, print() uses global tostring(), that doesn't exist in a keeper since we didn't open libs -> "attempt to call a nil value" |
389 | } | 379 | // conclusion, don't use print() as a fake on_state_create() callback! |
380 | // assert() should be fine since we pass a non-false argument to on_state_create | ||
381 | L.requireSuccess("require 'lanes'.configure{on_state_create = assert}"); | ||
382 | } | ||
383 | } | ||
390 | 384 | ||
391 | // ################################################################################################# | 385 | // --------------------------------------------------------------------------------------------- |
386 | // shutdown_timeout should be a number in [0,3600] | ||
392 | 387 | ||
393 | TEST_F(Configure, ShutdownTimeoutString) | 388 | SECTION("shutdown_timeout") |
394 | { | 389 | { |
395 | EXPECT_NE(L.doString("require 'lanes'.configure{shutdown_timeout = 'gluh'}"), LuaError::OK); | 390 | SECTION("shutdown_timeout = <table>") |
396 | } | 391 | { |
392 | L.requireFailure("require 'lanes'.configure{shutdown_timeout = {}}"); | ||
393 | } | ||
397 | 394 | ||
398 | // ################################################################################################# | 395 | // ----------------------------------------------------------------------------------------- |
399 | 396 | ||
400 | TEST_F(Configure, ShutdownTimeoutNegative) | 397 | SECTION("shutdown_timeout = <string>") |
401 | { | 398 | { |
402 | EXPECT_NE(L.doString("require 'lanes'.configure{shutdown_timeout = -0.001}"), LuaError::OK); | 399 | L.requireFailure("require 'lanes'.configure{shutdown_timeout = 'gluh'}"); |
403 | } | 400 | } |
404 | 401 | ||
405 | // ################################################################################################# | 402 | // ----------------------------------------------------------------------------------------- |
406 | 403 | ||
407 | TEST_F(Configure, ShutdownTimeoutZero) | 404 | SECTION("shutdown_timeout = <negative number>") |
408 | { | 405 | { |
409 | EXPECT_EQ(L.doString("require 'lanes'.configure{shutdown_timeout = 0}"), LuaError::OK); | 406 | L.requireFailure("require 'lanes'.configure{shutdown_timeout = -0.001}"); |
410 | } | 407 | } |
411 | 408 | ||
412 | // ################################################################################################# | 409 | // ----------------------------------------------------------------------------------------- |
413 | 410 | ||
414 | TEST_F(Configure, ShutdownTimeoutOne) | 411 | SECTION("shutdown_timeout = 0") |
415 | { | 412 | { |
416 | EXPECT_EQ(L.doString("require 'lanes'.configure{shutdown_timeout = 1}"), LuaError::OK); | 413 | L.requireSuccess("require 'lanes'.configure{shutdown_timeout = 0}"); |
417 | } | 414 | } |
418 | 415 | ||
419 | // ################################################################################################# | 416 | // ----------------------------------------------------------------------------------------- |
420 | 417 | ||
421 | TEST_F(Configure, ShutdownTimeoutHour) | 418 | SECTION("shutdown_timeout = 1s") |
422 | { | 419 | { |
423 | EXPECT_EQ(L.doString("require 'lanes'.configure{shutdown_timeout = 3600}"), LuaError::OK); | 420 | L.requireSuccess("require 'lanes'.configure{shutdown_timeout = 1}"); |
424 | } | 421 | } |
425 | 422 | ||
426 | // ################################################################################################# | 423 | // ----------------------------------------------------------------------------------------- |
427 | 424 | ||
428 | TEST_F(Configure, ShutdownTimeoutTooLong) | 425 | SECTION("shutdown_timeout = 3600s") |
429 | { | 426 | { |
430 | EXPECT_NE(L.doString("require 'lanes'.configure{shutdown_timeout = 3600.001}"), LuaError::OK); | 427 | L.requireSuccess("require 'lanes'.configure{shutdown_timeout = 3600}"); |
431 | } | 428 | } |
432 | 429 | ||
433 | // ################################################################################################# | 430 | // ----------------------------------------------------------------------------------------- |
434 | // ################################################################################################# | ||
435 | // strip_functions should be a boolean | ||
436 | 431 | ||
437 | TEST_F(Configure, StripFunctionsTable) | 432 | SECTION("shutdown_timeout = <too long>") |
438 | { | 433 | { |
439 | EXPECT_NE(L.doString("require 'lanes'.configure{strip_functions = {}}"), LuaError::OK); | 434 | L.requireFailure("require 'lanes'.configure{shutdown_timeout = 3600.001}"); |
440 | } | 435 | } |
436 | } | ||
441 | 437 | ||
442 | // ################################################################################################# | 438 | // --------------------------------------------------------------------------------------------- |
439 | // strip_functions should be a boolean | ||
443 | 440 | ||
444 | TEST_F(Configure, StripFunctionsString) | 441 | SECTION("strip_functions") |
445 | { | 442 | { |
446 | EXPECT_NE(L.doString("require 'lanes'.configure{strip_functions = 'gluh'}"), LuaError::OK); | 443 | SECTION("strip_functions = <table>") |
447 | } | 444 | { |
445 | L.requireFailure("require 'lanes'.configure{strip_functions = {}}"); | ||
446 | } | ||
448 | 447 | ||
449 | // ################################################################################################# | 448 | // ----------------------------------------------------------------------------------------- |
450 | 449 | ||
451 | TEST_F(Configure, StripFunctionsNumber) | 450 | SECTION("strip_functions = <string>") |
452 | { | 451 | { |
453 | EXPECT_NE(L.doString("require 'lanes'.configure{strip_functions = 1}"), LuaError::OK); | 452 | L.requireFailure("require 'lanes'.configure{strip_functions = 'gluh'}"); |
454 | } | 453 | } |
455 | 454 | ||
456 | // ################################################################################################# | 455 | // ----------------------------------------------------------------------------------------- |
457 | 456 | ||
458 | TEST_F(Configure, StripFunctionsFunction) | 457 | SECTION("strip_functions = <number>") |
459 | { | 458 | { |
460 | EXPECT_NE(L.doString("require 'lanes'.configure{strip_functions = print}"), LuaError::OK); | 459 | L.requireFailure("require 'lanes'.configure{strip_functions = 1}"); |
461 | } | 460 | } |
462 | 461 | ||
463 | // ################################################################################################# | 462 | // ----------------------------------------------------------------------------------------- |
464 | 463 | ||
465 | TEST_F(Configure, StripFunctionsFalse) | 464 | SECTION("strip_functions = <C function>") |
466 | { | 465 | { |
467 | EXPECT_EQ(L.doString("require 'lanes'.configure{strip_functions = false}"), LuaError::OK); | 466 | L.requireFailure("require 'lanes'.configure{strip_functions = print}"); |
468 | } | 467 | } |
469 | 468 | ||
470 | // ################################################################################################# | 469 | // ----------------------------------------------------------------------------------------- |
471 | 470 | ||
472 | TEST_F(Configure, StripFunctionsTrue) | 471 | SECTION("strip_functions = false") |
473 | { | 472 | { |
474 | EXPECT_EQ(L.doString("require 'lanes'.configure{strip_functions = true}"), LuaError::OK); | 473 | L.requireSuccess("require 'lanes'.configure{strip_functions = false}"); |
475 | } | 474 | } |
476 | 475 | ||
477 | // ################################################################################################# | 476 | // ----------------------------------------------------------------------------------------- |
478 | // ################################################################################################# | ||
479 | // track_lanes should be a boolean | ||
480 | 477 | ||
481 | TEST_F(Configure, TrackLanesTable) | 478 | SECTION("strip_functions = true") |
482 | { | 479 | { |
483 | EXPECT_NE(L.doString("require 'lanes'.configure{track_lanes = {}}"), LuaError::OK); | 480 | L.requireSuccess("require 'lanes'.configure{strip_functions = true}"); |
484 | } | 481 | } |
482 | } | ||
485 | 483 | ||
486 | // ################################################################################################# | 484 | // --------------------------------------------------------------------------------------------- |
485 | // track_lanes should be a boolean | ||
487 | 486 | ||
488 | TEST_F(Configure, TrackLanesString) | 487 | SECTION("track_lanes") |
489 | { | 488 | { |
490 | EXPECT_NE(L.doString("require 'lanes'.configure{track_lanes = 'gluh'}"), LuaError::OK); | 489 | SECTION("track_lanes = <table>") |
491 | } | 490 | { |
491 | L.requireFailure("require 'lanes'.configure{track_lanes = {}}"); | ||
492 | } | ||
492 | 493 | ||
493 | // ################################################################################################# | 494 | // ----------------------------------------------------------------------------------------- |
494 | 495 | ||
495 | TEST_F(Configure, TrackLanesNumber) | 496 | SECTION("track_lanes = <string>") |
496 | { | 497 | { |
497 | EXPECT_NE(L.doString("require 'lanes'.configure{track_lanes = 1}"), LuaError::OK); | 498 | L.requireFailure("require 'lanes'.configure{track_lanes = 'gluh'}"); |
498 | } | 499 | } |
499 | 500 | ||
500 | // ################################################################################################# | 501 | // ----------------------------------------------------------------------------------------- |
501 | 502 | ||
502 | TEST_F(Configure, TrackLanesFunction) | 503 | SECTION("track_lanes = <number>") |
503 | { | 504 | { |
504 | EXPECT_NE(L.doString("require 'lanes'.configure{track_lanes = print}"), LuaError::OK); | 505 | L.requireFailure("require 'lanes'.configure{track_lanes = 1}"); |
505 | } | 506 | } |
506 | 507 | ||
507 | // ################################################################################################# | 508 | // ----------------------------------------------------------------------------------------- |
508 | 509 | ||
509 | TEST_F(Configure, TrackLanesFalse) | 510 | SECTION("track_lanes = <C function>") |
510 | { | 511 | { |
511 | EXPECT_EQ(L.doString("require 'lanes'.configure{track_lanes = false}"), LuaError::OK); | 512 | L.requireFailure("require 'lanes'.configure{track_lanes = print}"); |
512 | } | 513 | } |
513 | 514 | ||
514 | // ################################################################################################# | 515 | // ----------------------------------------------------------------------------------------- |
515 | 516 | ||
516 | TEST_F(Configure, TrackLanesTrue) | 517 | SECTION("track_lanes = false") |
517 | { | 518 | { |
518 | EXPECT_EQ(L.doString("require 'lanes'.configure{track_lanes = true}"), LuaError::OK); | 519 | L.requireSuccess("require 'lanes'.configure{track_lanes = false}"); |
519 | } | 520 | } |
520 | 521 | ||
521 | // ################################################################################################# | 522 | // ----------------------------------------------------------------------------------------- |
522 | // ################################################################################################# | ||
523 | // verbose_errors should be a boolean | ||
524 | 523 | ||
525 | TEST_F(Configure, VerboseErrorsTable) | 524 | SECTION("track_lanes = true") |
526 | { | 525 | { |
527 | EXPECT_NE(L.doString("require 'lanes'.configure{verbose_errors = {}}"), LuaError::OK); | 526 | L.requireSuccess("require 'lanes'.configure{track_lanes = true}"); |
528 | } | 527 | } |
528 | } | ||
529 | 529 | ||
530 | // ################################################################################################# | 530 | // --------------------------------------------------------------------------------------------- |
531 | // verbose_errors should be a boolean | ||
531 | 532 | ||
532 | TEST_F(Configure, VerboseErrorsString) | 533 | SECTION("verbose_errors") |
533 | { | 534 | { |
534 | EXPECT_NE(L.doString("require 'lanes'.configure{verbose_errors = 'gluh'}"), LuaError::OK); | 535 | SECTION("verbose_errors = <table>") |
535 | } | 536 | { |
537 | L.requireFailure("require 'lanes'.configure{verbose_errors = {}}"); | ||
538 | } | ||
536 | 539 | ||
537 | // ################################################################################################# | 540 | // ----------------------------------------------------------------------------------------- |
538 | 541 | ||
539 | TEST_F(Configure, VerboseErrorsNumber) | 542 | SECTION("verbose_errors = <string>") |
540 | { | 543 | { |
541 | EXPECT_NE(L.doString("require 'lanes'.configure{verbose_errors = 1}"), LuaError::OK); | 544 | L.requireFailure("require 'lanes'.configure{verbose_errors = 'gluh'}"); |
542 | } | 545 | } |
543 | 546 | ||
544 | // ################################################################################################# | 547 | // ----------------------------------------------------------------------------------------- |
545 | 548 | ||
546 | TEST_F(Configure, VerboseErrorsFunction) | 549 | SECTION("verbose_errors = <number>") |
547 | { | 550 | { |
548 | EXPECT_NE(L.doString("require 'lanes'.configure{verbose_errors = print}"), LuaError::OK); | 551 | L.requireFailure("require 'lanes'.configure{verbose_errors = 1}"); |
549 | } | 552 | } |
550 | 553 | ||
551 | // ################################################################################################# | 554 | // ----------------------------------------------------------------------------------------- |
552 | 555 | ||
553 | TEST_F(Configure, VerboseErrorsFalse) | 556 | SECTION("verbose_errors = <C function>") |
554 | { | 557 | { |
555 | EXPECT_EQ(L.doString("require 'lanes'.configure{verbose_errors = false}"), LuaError::OK); | 558 | L.requireFailure("require 'lanes'.configure{verbose_errors = print}"); |
556 | } | 559 | } |
557 | 560 | ||
558 | // ################################################################################################# | 561 | // ----------------------------------------------------------------------------------------- |
559 | 562 | ||
560 | TEST_F(Configure, VerboseErrorsTrue) | 563 | SECTION("verbose_errors = false") |
561 | { | 564 | { |
562 | EXPECT_EQ(L.doString("require 'lanes'.configure{verbose_errors = true}"), LuaError::OK); | 565 | L.requireSuccess("require 'lanes'.configure{verbose_errors = false}"); |
563 | } | 566 | } |
564 | 567 | ||
565 | // ################################################################################################# | 568 | // ----------------------------------------------------------------------------------------- |
566 | // ################################################################################################# | ||
567 | // with_timers should be a boolean | ||
568 | 569 | ||
569 | TEST_F(Configure, WithTimersTable) | 570 | SECTION("verbose_errors = true") |
570 | { | 571 | { |
571 | EXPECT_NE(L.doString("require 'lanes'.configure{with_timers = {}}"), LuaError::OK); | 572 | L.requireSuccess("require 'lanes'.configure{verbose_errors = true}"); |
572 | } | 573 | } |
574 | } | ||
573 | 575 | ||
574 | // ################################################################################################# | 576 | // --------------------------------------------------------------------------------------------- |
577 | // with_timers should be a boolean | ||
575 | 578 | ||
576 | TEST_F(Configure, WithTimersString) | 579 | SECTION("with_timers") |
577 | { | 580 | { |
578 | EXPECT_NE(L.doString("require 'lanes'.configure{with_timers = 'gluh'}"), LuaError::OK); | 581 | SECTION("with_timers = <table>") |
579 | } | 582 | { |
583 | L.requireFailure("require 'lanes'.configure{with_timers = {}}"); | ||
584 | } | ||
580 | 585 | ||
581 | // ################################################################################################# | 586 | // ----------------------------------------------------------------------------------------- |
582 | 587 | ||
583 | TEST_F(Configure, WithTimersNumber) | 588 | SECTION("with_timers = <string>") |
584 | { | 589 | { |
585 | EXPECT_NE(L.doString("require 'lanes'.configure{with_timers = 1}"), LuaError::OK); | 590 | L.requireFailure("require 'lanes'.configure{with_timers = 'gluh'}"); |
586 | } | 591 | } |
587 | 592 | ||
588 | // ################################################################################################# | 593 | // ----------------------------------------------------------------------------------------- |
589 | 594 | ||
590 | TEST_F(Configure, WithTimersFunction) | 595 | SECTION("with_timers = <number>") |
591 | { | 596 | { |
592 | EXPECT_NE(L.doString("require 'lanes'.configure{with_timers = print}"), LuaError::OK); | 597 | L.requireFailure("require 'lanes'.configure{with_timers = 1}"); |
593 | } | 598 | } |
594 | 599 | ||
595 | // ################################################################################################# | 600 | // ----------------------------------------------------------------------------------------- |
596 | 601 | ||
597 | TEST_F(Configure, WithTimersFalse) | 602 | SECTION("with_timers = <C function>") |
598 | { | 603 | { |
599 | EXPECT_EQ(L.doString("require 'lanes'.configure{with_timers = false}"), LuaError::OK); | 604 | L.requireFailure("require 'lanes'.configure{with_timers = print}"); |
600 | } | 605 | } |
601 | 606 | ||
602 | // ################################################################################################# | 607 | // ----------------------------------------------------------------------------------------- |
603 | 608 | ||
604 | TEST_F(Configure, WithTimersTrue) | 609 | SECTION("with_timers = false") |
605 | { | 610 | { |
606 | EXPECT_EQ(L.doString("require 'lanes'.configure{with_timers = true}"), LuaError::OK); | 611 | L.requireSuccess("require 'lanes'.configure{with_timers = false}"); |
607 | } | 612 | } |
608 | 613 | ||
609 | // ################################################################################################# | 614 | // ----------------------------------------------------------------------------------------- |
610 | // ################################################################################################# | ||
611 | // any unknown setting should be rejected | ||
612 | 615 | ||
613 | TEST_F(Configure, UnknownSettingTable) | 616 | SECTION("with_timers = true") |
614 | { | 617 | { |
615 | EXPECT_NE(L.doString("require 'lanes'.configure{[{}] = {}}"), LuaError::OK); | 618 | L.requireSuccess("require 'lanes'.configure{with_timers = true}"); |
616 | } | 619 | } |
620 | } | ||
617 | 621 | ||
618 | // ################################################################################################# | 622 | // --------------------------------------------------------------------------------------------- |
623 | // any unknown setting should be rejected | ||
619 | 624 | ||
620 | TEST_F(Configure, UnknownSettingBool) | 625 | SECTION("unknown_setting") |
621 | { | 626 | { |
622 | EXPECT_NE(L.doString("require 'lanes'.configure{[true] = 'gluh'}"), LuaError::OK); | 627 | SECTION("table setting") |
623 | } | 628 | { |
629 | L.requireFailure("require 'lanes'.configure{[{}] = {}}"); | ||
630 | } | ||
624 | 631 | ||
625 | // ################################################################################################# | 632 | // ----------------------------------------------------------------------------------------- |
626 | 633 | ||
627 | TEST_F(Configure, UnknownSettingFunction) | 634 | SECTION("boolean setting") |
628 | { | 635 | { |
629 | EXPECT_NE(L.doString("require 'lanes'.configure{[function() end] = 1}"), LuaError::OK); | 636 | L.requireFailure("require 'lanes'.configure{[true] = 'gluh'}"); |
630 | } | 637 | } |
631 | 638 | ||
632 | // ################################################################################################# | 639 | // ----------------------------------------------------------------------------------------- |
633 | 640 | ||
634 | TEST_F(Configure, UnknownSettingNumber) | 641 | SECTION("function setting") |
635 | { | 642 | { |
636 | EXPECT_NE(L.doString("require 'lanes'.configure{[1] = function() end}"), LuaError::OK); | 643 | L.requireFailure("require 'lanes'.configure{[function() end] = 1}"); |
637 | } | 644 | } |
638 | 645 | ||
639 | // ################################################################################################# | 646 | // ----------------------------------------------------------------------------------------- |
640 | 647 | ||
641 | TEST_F(Configure, UnknownSettingString) | 648 | SECTION("number setting") |
642 | { | 649 | { |
643 | EXPECT_NE(L.doString("require 'lanes'.configure{['gluh'] = false}"), LuaError::OK); | 650 | L.requireFailure("require 'lanes'.configure{[1] = function() end}"); |
651 | } | ||
652 | |||
653 | // ----------------------------------------------------------------------------------------- | ||
654 | |||
655 | SECTION("unknown string setting") | ||
656 | { | ||
657 | L.requireFailure("require 'lanes'.configure{['gluh'] = false}"); | ||
658 | } | ||
659 | } | ||
644 | } | 660 | } |
645 | 661 | ||
646 | // ################################################################################################# | 662 | // ################################################################################################# |
647 | // ################################################################################################# | 663 | // ################################################################################################# |
648 | 664 | ||
649 | TEST(Lanes, Finally) | 665 | TEST_CASE("lanes.finally") |
650 | { | 666 | { |
667 | SECTION("no fixture") | ||
651 | { | 668 | { |
652 | LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } }; | 669 | LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } }; |
653 | // we need Lanes to be up. Since we run several 'scripts', we store it as a global | 670 | // we need Lanes to be up. Since we run several 'scripts', we store it as a global |
654 | EXPECT_EQ(S.doString("lanes = require 'lanes'"), LuaError::OK) << S; | 671 | S.requireSuccess("lanes = require 'lanes'"); |
655 | // we can set a function | 672 | // we can set a function |
656 | EXPECT_EQ(S.doString("lanes.finally(function() end)"), LuaError::OK) << S; | 673 | S.requireSuccess("lanes.finally(function() end)"); |
657 | // we can clear it | 674 | // we can clear it |
658 | EXPECT_EQ(S.doString("lanes.finally(nil)"), LuaError::OK) << S; | 675 | S.requireSuccess("lanes.finally(nil)"); |
659 | // we can set a new one | 676 | // we can set a new one |
660 | EXPECT_EQ(S.doString("lanes.finally(function() end)"), LuaError::OK) << S; | 677 | S.requireSuccess("lanes.finally(function() end)"); |
661 | // we can replace an existing function | 678 | // we can replace an existing function |
662 | EXPECT_EQ(S.doString("lanes.finally(error)"), LuaError::OK) << S; | 679 | S.requireSuccess("lanes.finally(error)"); |
663 | // even if the finalizer throws a Lua error, it shouldn't crash anything | 680 | // even if the finalizer throws a Lua error, it shouldn't crash anything |
664 | ASSERT_NO_FATAL_FAILURE(S.close()); | 681 | REQUIRE_NOTHROW(S.close()); // TODO: use lua_atpanic to catch errors during close() |
665 | ASSERT_EQ(S.finalizerWasCalled, false); | 682 | REQUIRE_FALSE(S.finalizerWasCalled); |
666 | } | 683 | } |
667 | 684 | ||
685 | // --------------------------------------------------------------------------------------------- | ||
686 | |||
687 | SECTION("with fixture") | ||
668 | { | 688 | { |
669 | LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } }; | 689 | LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } }; |
670 | 690 | ||
671 | // we need Lanes to be up. Since we run several 'scripts', we store it as a global | 691 | // we need Lanes to be up. Since we run several 'scripts', we store it as a global |
672 | EXPECT_EQ(S.doString("lanes = require 'lanes'"), LuaError::OK) << S; | 692 | S.requireSuccess("lanes = require 'lanes'"); |
673 | // works because we have package.preload.fixture = luaopen_fixture | 693 | // works because we have package.preload.fixture = luaopen_fixture |
674 | EXPECT_EQ(S.doString("fixture = require 'fixture'"), LuaError::OK) << S; | 694 | S.requireSuccess("fixture = require 'fixture'"); |
675 | // set our detectable finalizer | 695 | // set our detectable finalizer |
676 | EXPECT_EQ(S.doString("lanes.finally(fixture.throwing_finalizer)"), LuaError::OK) << S; | 696 | S.requireSuccess("lanes.finally(fixture.throwing_finalizer)"); |
677 | // even if the finalizer can request a C++ exception, it shouldn't do it just now since we have no dangling lane | 697 | // even if the finalizer can request a C++ exception, it shouldn't do it just now since we have no dangling lane |
678 | ASSERT_NO_THROW(S.close()) << S; | 698 | REQUIRE_NOTHROW(S.close()); |
679 | // the finalizer should be called | 699 | // the finalizer should be called |
680 | ASSERT_EQ(S.finalizerWasCalled, true); | 700 | REQUIRE(S.finalizerWasCalled); |
681 | } | 701 | } |
682 | } | 702 | } |
683 | 703 | ||
@@ -697,97 +717,92 @@ namespace | |||
697 | } // namespace local | 717 | } // namespace local |
698 | } | 718 | } |
699 | 719 | ||
700 | class OnStateCreate : public ::testing::Test | ||
701 | { | ||
702 | protected: | ||
703 | LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } }; | ||
704 | |||
705 | void SetUp() override | ||
706 | { | ||
707 | local::OnStateCreateCallsCount.store(0, std::memory_order_relaxed); | ||
708 | } | ||
709 | |||
710 | void TearDown() override | ||
711 | { | ||
712 | local::OnStateCreateCallsCount.store(0, std::memory_order_relaxed); | ||
713 | } | ||
714 | }; | ||
715 | |||
716 | // ################################################################################################# | 720 | // ################################################################################################# |
717 | 721 | ||
718 | TEST_F(OnStateCreate, CalledInKeepers) | 722 | TEST_CASE("on_state_create setting") |
719 | { | 723 | { |
720 | // _G.on_state_create = on_state_create; | 724 | LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } }; |
721 | lua_pushcfunction(S, local::on_state_create); | ||
722 | lua_setglobal(S, "on_state_create"); | ||
723 | ASSERT_EQ(S.doString("lanes = require 'lanes'.configure{on_state_create = on_state_create, nb_user_keepers = 3}"), LuaError::OK) << S; | ||
724 | ASSERT_EQ(local::OnStateCreateCallsCount.load(std::memory_order_relaxed), 4) << "on_state_create should have been called once in each Keeper state"; | ||
725 | } | ||
726 | 725 | ||
727 | // ################################################################################################# | 726 | local::OnStateCreateCallsCount.store(0, std::memory_order_relaxed); |
727 | auto on_state_create = +[](lua_State* const L_) { | ||
728 | local::OnStateCreateCallsCount.fetch_add(1, std::memory_order_relaxed); | ||
729 | return 0; | ||
730 | }; | ||
728 | 731 | ||
729 | TEST_F(OnStateCreate, CalledInLane) | ||
730 | { | ||
731 | // _G.on_state_create = on_state_create; | ||
732 | lua_pushcfunction(S, local::on_state_create); | ||
733 | lua_setglobal(S, "on_state_create"); | ||
734 | ASSERT_EQ(S.doString("lanes = require 'lanes'.configure{on_state_create = on_state_create, with_timers = true}"), LuaError::OK) << S; | ||
735 | ASSERT_EQ(local::OnStateCreateCallsCount.load(std::memory_order_relaxed), 2) << "on_state_create should have been called in the Keeper state and the timer lane"; | ||
736 | } | ||
737 | 732 | ||
738 | // ################################################################################################# | 733 | SECTION("on_state_create called in Keeper states") |
734 | { | ||
735 | // _G.on_state_create = on_state_create; | ||
736 | lua_pushcfunction(S, local::on_state_create); | ||
737 | lua_setglobal(S, "on_state_create"); | ||
738 | S.requireSuccess("lanes = require 'lanes'.configure{on_state_create = on_state_create, nb_user_keepers = 3}"); | ||
739 | REQUIRE(local::OnStateCreateCallsCount.load(std::memory_order_relaxed) == 4); | ||
740 | } | ||
739 | 741 | ||
740 | TEST_F(OnStateCreate, CanPackagePreload) | 742 | // --------------------------------------------------------------------------------------------- |
741 | { | ||
742 | // a C function for which we can test it was called | ||
743 | static bool _doStuffWasCalled{}; | ||
744 | static auto _doStuff = +[](lua_State* const L_) { | ||
745 | _doStuffWasCalled = true; | ||
746 | return 0; | ||
747 | }; | ||
748 | 743 | ||
749 | // a module that exports the above function | 744 | SECTION("on_state_create called in lane") |
750 | static auto _luaopen_Stuff = +[](lua_State* const L_) { | 745 | { |
751 | lua_newtable(L_); // t | 746 | // _G.on_state_create = on_state_create; |
752 | lua_pushstring(L_, "DoStuffInC"); // t "DoStuffInC" | 747 | lua_pushcfunction(S, local::on_state_create); |
753 | lua_pushcfunction(L_, _doStuff); // t "DoStuffInC" _doStuff | 748 | lua_setglobal(S, "on_state_create"); |
754 | lua_settable(L_, -3); // t | 749 | S.requireSuccess("lanes = require 'lanes'.configure{on_state_create = on_state_create, with_timers = true}"); |
755 | return 1; | 750 | REQUIRE(local::OnStateCreateCallsCount.load(std::memory_order_relaxed) == 2); |
756 | }; | 751 | } |
757 | 752 | ||
758 | // a function that installs the module loader function in package.preload | 753 | // --------------------------------------------------------------------------------------------- |
759 | auto _on_state_create = [](lua_State* const L_) { | ||
760 | 754 | ||
761 | lua_getglobal(L_, "package"); // package | 755 | SECTION("on_state_create changes package.preload") |
762 | if (lua_istable(L_, -1)) { | 756 | { |
763 | lua_getfield(L_, -1, "preload"); // package package.preload | 757 | // a C function for which we can test it was called |
758 | static bool _doStuffWasCalled{}; | ||
759 | static auto _doStuff = +[](lua_State* const L_) { | ||
760 | _doStuffWasCalled = true; | ||
761 | return 0; | ||
762 | }; | ||
763 | |||
764 | // a module that exports the above function | ||
765 | static auto _luaopen_Stuff = +[](lua_State* const L_) { | ||
766 | lua_newtable(L_); // t | ||
767 | lua_pushstring(L_, "DoStuffInC"); // t "DoStuffInC" | ||
768 | lua_pushcfunction(L_, _doStuff); // t "DoStuffInC" _doStuff | ||
769 | lua_settable(L_, -3); // t | ||
770 | return 1; | ||
771 | }; | ||
772 | |||
773 | // a function that installs the module loader function in package.preload | ||
774 | auto _on_state_create = [](lua_State* const L_) { | ||
775 | lua_getglobal(L_, "package"); // package | ||
764 | if (lua_istable(L_, -1)) { | 776 | if (lua_istable(L_, -1)) { |
765 | lua_pushcfunction(L_, _luaopen_Stuff); // package package.preload luaopen_Stuff | 777 | lua_getfield(L_, -1, "preload"); // package package.preload |
766 | lua_setfield(L_, -2, "Stuff"); // package package.preload | 778 | if (lua_istable(L_, -1)) { |
779 | lua_pushcfunction(L_, _luaopen_Stuff); // package package.preload luaopen_Stuff | ||
780 | lua_setfield(L_, -2, "Stuff"); // package package.preload | ||
781 | } | ||
782 | lua_pop(L_, 1); // package | ||
767 | } | 783 | } |
768 | lua_pop(L_, 1); // package | 784 | lua_pop(L_, 1); // |
769 | } | ||
770 | lua_pop(L_, 1); // | ||
771 | 785 | ||
772 | return 0; | 786 | return 0; |
773 | }; | 787 | }; |
774 | 788 | ||
775 | // _G.on_state_create = on_state_create; | 789 | // _G.on_state_create = on_state_create; |
776 | lua_pushcfunction(S, _on_state_create); | 790 | lua_pushcfunction(S, _on_state_create); |
777 | lua_setglobal(S, "on_state_create"); | 791 | lua_setglobal(S, "on_state_create"); |
778 | 792 | ||
779 | ASSERT_EQ(S.doString("lanes = require 'lanes'.configure{on_state_create = on_state_create}"), LuaError::OK) << S; | 793 | S.requireSuccess("lanes = require 'lanes'.configure{on_state_create = on_state_create}"); |
780 | 794 | ||
781 | // launch a Lane that requires the module. It should succeed because _on_state_create was called and made it possible | 795 | // launch a Lane that requires the module. It should succeed because _on_state_create was called and made it possible |
782 | std::string_view const _script{ | 796 | std::string_view const _script{ |
783 | " f = lanes.gen('*'," | 797 | " f = lanes.gen('*'," |
784 | " function()" | 798 | " function()" |
785 | " local Stuff = require ('Stuff')" | 799 | " local Stuff = require ('Stuff')" |
786 | " Stuff.DoStuffInC()" | 800 | " Stuff.DoStuffInC()" |
787 | " return true" | 801 | " return true" |
788 | " end)" | 802 | " end)" |
789 | " f():join()" // start the lane and block until it terminates | 803 | " f():join()" // start the lane and block until it terminates |
790 | }; | 804 | }; |
791 | ASSERT_EQ(S.doString(_script), LuaError::OK) << S; | 805 | S.requireSuccess(_script); |
792 | ASSERT_TRUE(_doStuffWasCalled); | 806 | REQUIRE(_doStuffWasCalled); |
793 | } | 807 | } |
808 | } \ No newline at end of file | ||