aboutsummaryrefslogtreecommitdiff
path: root/unit_tests/linda_tests.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'unit_tests/linda_tests.cpp')
-rw-r--r--unit_tests/linda_tests.cpp333
1 files changed, 199 insertions, 134 deletions
diff --git a/unit_tests/linda_tests.cpp b/unit_tests/linda_tests.cpp
index efdb8a5..90630a7 100644
--- a/unit_tests/linda_tests.cpp
+++ b/unit_tests/linda_tests.cpp
@@ -3,154 +3,216 @@
3 3
4// ################################################################################################# 4// #################################################################################################
5 5
6TEST_CASE("linda.single Keeper") 6TEST_CASE("linda.single_keeper.creation/no_argument")
7{ 7{
8 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } }; 8 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } };
9 S.requireSuccess("lanes = require 'lanes'"); 9 S.requireSuccess("lanes = require 'lanes'");
10 10
11 SECTION("Linda creation") 11 // no argument is ok
12 { 12 S.requireSuccess("lanes.linda()");
13 // no parameters is ok 13 S.requireNotReturnedString("return tostring(lanes.linda())", R"===(Linda: <not a string>)==="); // unspecified name should not result in <not a string>
14 S.requireSuccess("lanes.linda()"); 14}
15 S.requireNotReturnedString("return tostring(lanes.linda())", R"===(Linda: <not a string>)==="); // unspecified name should not result in <not a string>
16
17 // since we have only one keeper, only group 0 is authorized
18 S.requireFailure("lanes.linda(-1)");
19 S.requireSuccess("lanes.linda(0)");
20 S.requireFailure("lanes.linda(1)");
21
22 // any name is ok
23 S.requireSuccess("lanes.linda('')"); // an empty name results in a string conversion of the form "Linda: <some hex value>" that we can't test (but it works)
24 S.requireReturnedString("return tostring(lanes.linda('short name'))", R"===(Linda: short name)===");
25 S.requireReturnedString("return tostring(lanes.linda('very very very very very very long name'))", R"===(Linda: very very very very very very long name)===");
26 S.requireReturnedString("return tostring(lanes.linda('auto'))", R"===(Linda: [string "return tostring(lanes.linda('auto'))"]:1)===");
27
28 if constexpr (LUA_VERSION_NUM == 504) {
29 // a function is acceptable as a __close handler
30 S.requireSuccess("local l <close> = lanes.linda(function() end)");
31 // a callable table too (a callable full userdata as well, but I have none here)
32 S.requireSuccess("local l <close> = lanes.linda(setmetatable({}, {__call = function() end}))");
33 // if the function raises an error, we should get it
34 S.requireFailure("local l <close> = lanes.linda(function() error 'gluh' end)");
35 } else {
36 // no __close support before Lua 5.4
37 S.requireFailure("lanes.linda(function() end)");
38 S.requireFailure("lanes.linda(setmetatable({}, {__call = function() end}))");
39 }
40 15
41 // mixing parameters in any order is ok: 2 out of 3 16// #################################################################################################
42 S.requireSuccess("lanes.linda(0, 'name')");
43 S.requireSuccess("lanes.linda('name', 0)");
44 if constexpr (LUA_VERSION_NUM == 504) {
45 S.requireSuccess("lanes.linda(0, function() end)");
46 S.requireSuccess("lanes.linda(function() end, 0)");
47 S.requireSuccess("lanes.linda('name', function() end)");
48 S.requireSuccess("lanes.linda(function() end, 'name')");
49 }
50 17
51 // mixing parameters in any order is ok: 3 out of 3 18TEST_CASE("linda.single_keeper.creation/non_table_arguments")
52 if constexpr (LUA_VERSION_NUM == 504) { 19{
53 S.requireSuccess("lanes.linda(0, 'name', function() end)"); 20 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } };
54 S.requireSuccess("lanes.linda(0, function() end, 'name')"); 21 S.requireSuccess("lanes = require 'lanes'");
55 S.requireSuccess("lanes.linda('name', 0, function() end)"); 22
56 S.requireSuccess("lanes.linda('name', function() end, 0)"); 23 // any argument that is not a table is not ok
57 S.requireSuccess("lanes.linda(function() end, 0, 'name')"); 24 S.requireFailure("lanes.linda(0)");
58 S.requireSuccess("lanes.linda(function() end, 'name', 0)"); 25 S.requireFailure("lanes.linda('bob')");
59 } 26 S.requireFailure("lanes.linda(false)");
27 S.requireFailure("lanes.linda(function() end)");
28 S.requireFailure("lanes.linda(lanes.cancel_error)");
29}
30
31// #################################################################################################
60 32
61 // unsupported parameters should fail 33TEST_CASE("linda.single_keeper.creation/close_handler")
62 S.requireFailure("lanes.linda(true)"); 34{
63 S.requireFailure("lanes.linda(false)"); 35 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } };
64 // uncallable table or full userdata 36 S.requireSuccess("lanes = require 'lanes'");
65 S.requireFailure("lanes.linda({})"); 37
66 S.requireFailure("lanes.linda(lanes.linda())"); 38 if constexpr (LUA_VERSION_NUM >= 504) {
39 // a function is acceptable as a __close handler
40 S.requireSuccess("local l <close> = lanes.linda{close_handler = function() end}");
41 // a callable table too (a callable full userdata as well, but I have none here)
42 S.requireSuccess("local l <close> = lanes.linda{close_handler = setmetatable({}, {__call = function() end})}");
43 } else {
44 // no __close support before Lua 5.4, field is ignored (therefore invalid values are accepted too!)
45 S.requireSuccess("lanes.linda{close_handler = 'a string'}");
46 S.requireSuccess("lanes.linda{close_handler = function() end}");
47 S.requireSuccess("lanes.linda{close_handler = setmetatable({}, {__call = function() end})}");
67 } 48 }
49}
68 50
69 // --------------------------------------------------------------------------------------------- 51// #################################################################################################
52
53TEST_CASE("linda.single_keeper.creation/table_argument")
54{
55 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } };
56 S.requireSuccess("lanes = require 'lanes'");
57
58 // one table is fine
59 S.requireSuccess("lanes.linda{}");
60 // anything beyond that is not
61 S.requireFailure("lanes.linda({},{})");
62 S.requireFailure("lanes.linda({},'bob')");
63 S.requireFailure("lanes.linda({},42)");
64}
65
66// #################################################################################################
67
68TEST_CASE("linda.single_keeper.creation/group")
69{
70 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } };
71 S.requireSuccess("lanes = require 'lanes'");
72
73 // since we have only one keeper, only group 0 is authorized
74 S.requireFailure("lanes.linda{group = -1}");
75 S.requireSuccess("lanes.linda{group = 0}");
76 S.requireFailure("lanes.linda{group = 1}");
77}
78
79// #################################################################################################
80
81TEST_CASE("linda.single_keeper.creation/name")
82{
83 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } };
84 S.requireSuccess("lanes = require 'lanes'");
85
86 // any name is ok
87 S.requireSuccess("lanes.linda{name = ''}"); // an empty name results in a string conversion of the form "Linda: <some hex value>" that we can't test (but it works)
88 S.requireReturnedString("return tostring(lanes.linda{name = 'short name'})", R"===(Linda: short name)===");
89 S.requireReturnedString("return tostring(lanes.linda{name = 'very very very very very very long name'})", R"===(Linda: very very very very very very long name)===");
90 S.requireReturnedString("return tostring(lanes.linda{name = 'auto'})", R"===(Linda: [string "return tostring(lanes.linda{name = 'auto'})"]:1)===");
91}
92
93// #################################################################################################
94
95TEST_CASE("linda.single_keeper.creation/wake_period")
96{
97 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } };
98 S.requireSuccess("lanes = require 'lanes'");
99
100 // wake_period should be a number > 0
101 S.requireFailure("lanes.linda{wake_period = false}");
102 S.requireFailure("lanes.linda{wake_period = 'bob'}");
103 S.requireFailure("lanes.linda{wake_period = {}}");
104 S.requireFailure("lanes.linda{wake_period = -1}");
105 S.requireFailure("lanes.linda{wake_period = 0}");
106 S.requireSuccess("lanes.linda{wake_period = 0.0001}");
107 S.requireSuccess("lanes.linda{wake_period = 'never'}");
108}
109
110// #################################################################################################
70 111
71 SECTION("Linda indexing") 112TEST_CASE("linda.single_keeper.indexing")
113{
114 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } };
115 S.requireSuccess("lanes = require 'lanes'.configure()");
116
117 // indexing the linda with an unknown string key should fail
118 S.requireFailure("return lanes.linda().gouikra");
119 // indexing the linda with an unsupported key type should fail
120 S.requireFailure("return lanes.linda()[5]");
121 S.requireFailure("return lanes.linda()[false]");
122 S.requireFailure("return lanes.linda()[{}]");
123 S.requireFailure("return lanes.linda()[function() end]");
124}
125
126// #################################################################################################
127
128TEST_CASE("linda.single_keeper.send()")
129{
130 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } };
131 S.requireSuccess("lanes = require 'lanes'.configure()");
132
133 SECTION("timeout")
72 { 134 {
73 // indexing the linda with an unknown string key should fail 135 // timeout checks
74 S.requireFailure("return lanes.linda().gouikra"); 136 // linda:send() should fail if the timeout is bad
75 // indexing the linda with an unsupported key type should fail 137 S.requireFailure("lanes.linda():send(-1, 'k', 'v')");
76 S.requireFailure("return lanes.linda()[5]"); 138 // any positive value is ok
77 S.requireFailure("return lanes.linda()[false]"); 139 S.requireSuccess("lanes.linda():send(0, 'k', 'v')");
78 S.requireFailure("return lanes.linda()[{}]"); 140 S.requireSuccess("lanes.linda():send(1e20, 'k', 'v')");
79 S.requireFailure("return lanes.linda()[function() end]"); 141 // nil too (same as 'forever')
142 S.requireSuccess("lanes.linda():send(nil, 'k', 'v')");
80 } 143 }
81 144
82 // --------------------------------------------------------------------------------------------- 145 // -----------------------------------------------------------------------------------------
83 SECTION("linda:send()") 146
147 SECTION("fails on bad keys")
84 { 148 {
85 SECTION("timeout") 149 // key checks
86 { 150 // linda:send() should fail if the key is unsupported (nil, table, function, full userdata, reserved light userdata)
87 // timeout checks 151 S.requireFailure("lanes.linda():send(0, nil, 'v')");
88 // linda:send() should fail if the timeout is bad 152 S.requireFailure("lanes.linda():send(0, {}, 'v')");
89 S.requireFailure("lanes.linda():send(-1, 'k', 'v')"); 153 S.requireFailure("lanes.linda():send(0, function() end, 'v')");
90 // any positive value is ok 154 S.requireFailure("lanes.linda():send(0, io.stdin, 'v')");
91 S.requireSuccess("lanes.linda():send(0, 'k', 'v')"); 155 S.requireFailure("lanes.linda():send(0, lanes.null, 'v')");
92 S.requireSuccess("lanes.linda():send(1e20, 'k', 'v')"); 156 S.requireFailure("lanes.linda():send(0, lanes.cancel_error, 'v')");
93 // nil too (same as 'forever') 157 }
94 S.requireSuccess("lanes.linda():send(nil, 'k', 'v')");
95 }
96 158
97 // ----------------------------------------------------------------------------------------- 159 // -----------------------------------------------------------------------------------------
98 160
99 SECTION("fails on bad keys") 161 SECTION("succeeds on supported keys")
100 { 162 {
101 // key checks 163 // supported keys are ok: boolean, number, string, light userdata, deep userdata
102 // linda:send() should fail if the key is unsupported (nil, table, function, full userdata, reserved light userdata) 164 S.requireSuccess("lanes.linda():send(0, true, 'v')");
103 S.requireFailure("lanes.linda():send(0, nil, 'v')"); 165 S.requireSuccess("lanes.linda():send(0, false, 'v')");
104 S.requireFailure("lanes.linda():send(0, {}, 'v')"); 166 S.requireSuccess("lanes.linda():send(0, 99, 'v')");
105 S.requireFailure("lanes.linda():send(0, function() end, 'v')"); 167 S.requireSuccess("local l = lanes.linda(); l:send(0, l:deep(), 'v')");
106 S.requireFailure("lanes.linda():send(0, io.stdin, 'v')"); 168 }
107 S.requireFailure("lanes.linda():send(0, lanes.null, 'v')");
108 S.requireFailure("lanes.linda():send(0, lanes.cancel_error, 'v')");
109 S.requireFailure("local l = lanes.linda(); l:send(0, l.batched, 'v')");
110 }
111 169
112 // ----------------------------------------------------------------------------------------- 170 // -----------------------------------------------------------------------------------------
113 171
114 SECTION("succeeds on supported keys") 172 SECTION("succeeds on deep userdata key")
115 { 173 {
116 // supported keys are ok: boolean, number, string, light userdata, deep userdata 174 S.requireSuccess("local l = lanes.linda(); l:send(0, l, 'v')");
117 S.requireSuccess("lanes.linda():send(0, true, 'v')"); 175 }
118 S.requireSuccess("lanes.linda():send(0, false, 'v')");
119 S.requireSuccess("lanes.linda():send(0, 99, 'v')");
120 S.requireSuccess("local l = lanes.linda(); l:send(0, l:deep(), 'v')");
121 }
122 176
123 // ----------------------------------------------------------------------------------------- 177 // -----------------------------------------------------------------------------------------
124 178
125 SECTION("succeeds on deep userdata key") 179 SECTION(". fails")
126 { 180 {
127 S.requireSuccess("local l = lanes.linda(); l:send(0, l, 'v')"); 181 // misuse checks, . instead of :
128 } 182 S.requireFailure("lanes.linda().send(nil, 'k', 'v')");
183 }
129 184
130 // ----------------------------------------------------------------------------------------- 185 // -----------------------------------------------------------------------------------------
131 186
132 SECTION(". fails") 187 SECTION("unsupported values fail")
133 { 188 {
134 // misuse checks, . instead of : 189 // value checks
135 S.requireFailure("lanes.linda().send(nil, 'k', 'v')"); 190 // linda:send() should fail if we don't send anything
136 } 191 S.requireFailure("lanes.linda():send()");
192 S.requireFailure("lanes.linda():send(0)");
193 S.requireFailure("lanes.linda():send(0, 'k')");
194 // or non-deep userdata
195 S.requireFailure("lanes.linda():send(0, 'k', fixture.newuserdata())");
196 // or something with a converter that raises an error (maybe that should go to a dedicated __lanesconvert test!)
197 S.requireFailure("lanes.linda():send(0, 'k', setmetatable({}, {__lanesconvert = function(where_) error (where_ .. ': should not send me' end}))");
198 // but a registered non-deep userdata should work
199 S.requireSuccess("lanes.linda():send(0, 'k', io.stdin)");
200 }
201}
137 202
138 // ----------------------------------------------------------------------------------------- 203// #################################################################################################
139 204
140 SECTION("unsupported values fail") 205TEST_CASE("linda.single_keeper.the_rest")
141 { 206{
142 // value checks 207 LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } };
143 // linda:send() should fail if we don't send anything 208 S.requireSuccess("lanes = require 'lanes'");
144 S.requireFailure("lanes.linda():send()"); 209
145 S.requireFailure("lanes.linda():send(0)"); 210 // ---------------------------------------------------------------------------------------------
146 S.requireFailure("lanes.linda():send(0, 'k')"); 211
147 // or non-deep userdata 212 SECTION("error in close handler is propagated")
148 S.requireFailure("lanes.linda():send(0, 'k', fixture.newuserdata())"); 213 {
149 // or something with a converter that raises an error (maybe that should go to a dedicated __lanesconvert test!) 214 // if the function raises an error, we should get it
150 S.requireFailure("lanes.linda():send(0, 'k', setmetatable({}, {__lanesconvert = function(where_) error (where_ .. ': should not send me' end}))"); 215 S.requireFailure("local l <close> = lanes.linda{close_handler = function() error 'gluh' end}");
151 // but a registered non-deep userdata should work
152 S.requireSuccess("lanes.linda():send(0, 'k', io.stdin)");
153 }
154 } 216 }
155 217
156 // --------------------------------------------------------------------------------------------- 218 // ---------------------------------------------------------------------------------------------
@@ -312,12 +374,12 @@ TEST_CASE("linda.multi Keeper")
312 374
313 S.requireSuccess("lanes = require 'lanes'.configure{nb_user_keepers = 3}"); 375 S.requireSuccess("lanes = require 'lanes'.configure{nb_user_keepers = 3}");
314 376
315 S.requireFailure("lanes.linda(-1)"); 377 S.requireFailure("lanes.linda{group = -1}");
316 S.requireSuccess("lanes.linda(0)"); 378 S.requireSuccess("lanes.linda{group = 0}");
317 S.requireSuccess("lanes.linda(1)"); 379 S.requireSuccess("lanes.linda{group = 1}");
318 S.requireSuccess("lanes.linda(2)"); 380 S.requireSuccess("lanes.linda{group = 2}");
319 S.requireSuccess("lanes.linda(3)"); 381 S.requireSuccess("lanes.linda{group = 3}");
320 S.requireFailure("lanes.linda(4)"); 382 S.requireFailure("lanes.linda{group = 4}");
321} 383}
322 384
323// ################################################################################################# 385// #################################################################################################
@@ -327,23 +389,26 @@ TEST_CASE("linda.multi Keeper")
327// so let's create a separate test case for each file with an ugly macro... 389// so let's create a separate test case for each file with an ugly macro...
328 390
329#define MAKE_TEST_CASE(DIR, FILE) \ 391#define MAKE_TEST_CASE(DIR, FILE) \
330TEST_CASE("scripted tests." #DIR "." #FILE) \ 392TEST_CASE("scripted_tests." #DIR "." #FILE) \
331{ \ 393{ \
332 FileRunner _runner(R"(.\unit_tests\scripts)"); \ 394 FileRunner _runner(R"(.\unit_tests\scripts)"); \
333 _runner.performTest(FileRunnerParam{ #DIR "/" #FILE, TestType::AssertNoLuaError }); \ 395 _runner.performTest(FileRunnerParam{ #DIR "/" #FILE, TestType::AssertNoLuaError }); \
334} 396}
335 397
398MAKE_TEST_CASE(linda, multiple_keepers)
336MAKE_TEST_CASE(linda, send_receive) 399MAKE_TEST_CASE(linda, send_receive)
400MAKE_TEST_CASE(linda, send_receive_func_and_string)
337MAKE_TEST_CASE(linda, send_registered_userdata) 401MAKE_TEST_CASE(linda, send_registered_userdata)
338MAKE_TEST_CASE(linda, multiple_keepers) 402MAKE_TEST_CASE(linda, wake_period)
339 403
340/* 404/*
341TEST_CASE("linda.scripted tests") 405TEST_CASE("linda.scripted_tests")
342{ 406{
343 auto const& _testParam = GENERATE( 407 auto const& _testParam = GENERATE(
408 FileRunnerParam{ "linda/multiple_keepers", TestType::AssertNoLuaError },
344 FileRunnerParam{ "linda/send_receive", TestType::AssertNoLuaError }, 409 FileRunnerParam{ "linda/send_receive", TestType::AssertNoLuaError },
345 FileRunnerParam{ "linda/send_registered_userdata", TestType::AssertNoLuaError }, 410 FileRunnerParam{ "linda/send_registered_userdata", TestType::AssertNoLuaError },
346 FileRunnerParam{ "linda/multiple_keepers", TestType::AssertNoLuaError } 411 FileRunnerParam{ "linda/wake_period", TestType::AssertNoLuaError }
347 ); 412 );
348 413
349 FileRunner _runner(R"(.\unit_tests\scripts)"); 414 FileRunner _runner(R"(.\unit_tests\scripts)");