diff options
Diffstat (limited to '')
-rw-r--r-- | unit_tests/deep_tests.cpp | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/unit_tests/deep_tests.cpp b/unit_tests/deep_tests.cpp new file mode 100644 index 0000000..c1708e1 --- /dev/null +++ b/unit_tests/deep_tests.cpp | |||
@@ -0,0 +1,101 @@ | |||
1 | #include "_pch.hpp" | ||
2 | #include "shared.h" | ||
3 | |||
4 | // yeah it's dirty, I will do better someday | ||
5 | #include "../deep_test/deep_test.cpp" | ||
6 | |||
7 | |||
8 | // ################################################################################################# | ||
9 | // ################################################################################################# | ||
10 | |||
11 | class DeepTests : public ::testing::Test | ||
12 | { | ||
13 | protected: | ||
14 | LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ true } }; | ||
15 | |||
16 | void SetUp() override | ||
17 | { | ||
18 | std::ignore = S.doString("lanes = require 'lanes'.configure()"); | ||
19 | std::ignore = S.doString("fixture = require 'fixture'"); | ||
20 | std::ignore = S.doString("deep_test = require 'deep_test'"); | ||
21 | } | ||
22 | }; | ||
23 | |||
24 | // ################################################################################################# | ||
25 | // ################################################################################################# | ||
26 | |||
27 | TEST_F(DeepTests, DeepIsCollected) | ||
28 | { | ||
29 | ASSERT_EQ(S.doString("assert(true)"), LuaError::OK) << S; | ||
30 | ASSERT_NE(S.doString("assert(false)"), LuaError::OK) << S; | ||
31 | if constexpr (LUA_VERSION_NUM >= 503) { // Lua < 5.3 only supports a table uservalue | ||
32 | ASSERT_EQ(S.doString( | ||
33 | // create a deep userdata object without referencing it. First uservalue is a function, and should be called on __gc | ||
34 | " deep_test.new_deep(1):setuv(1, function() collected = collected and collected + 1 or 1 end)" | ||
35 | " deep_test.new_deep(1):setuv(1, function() collected = collected and collected + 1 or 1 end)" | ||
36 | " collectgarbage()" // and collect it | ||
37 | " assert(collected == 2)" | ||
38 | ), LuaError::OK) << S; | ||
39 | } | ||
40 | } | ||
41 | |||
42 | // ################################################################################################# | ||
43 | |||
44 | TEST_F(DeepTests, DeepRefcounting) | ||
45 | { | ||
46 | ASSERT_EQ(S.doString( | ||
47 | " d = deep_test.new_deep(1)" // create a deep userdata object | ||
48 | " d:set(42)" // set some value | ||
49 | " assert(d:refcount() == 1)" | ||
50 | ), LuaError::OK) << S; | ||
51 | ASSERT_EQ(S.doString( | ||
52 | " l = lanes.linda()" | ||
53 | " b, s = l:set('k', d, d)" // store it twice in the linda | ||
54 | " assert(b == false and s == 'under')" // no waking, under capacity | ||
55 | " assert(d:refcount() == 2)" // 1 ref here, 1 in the keeper (even if we sent it twice) | ||
56 | ), LuaError::OK) << S; | ||
57 | ASSERT_EQ(S.doString( | ||
58 | " n, d = l:get('k')" // pull it out of the linda | ||
59 | " assert(n == 1 and type(d) == 'userdata')" // got 1 item out of the linda | ||
60 | " assert(d:get() == 42 and d:refcount() == 2)" // 1 ref here, 1 in the keeper (even if we sent it twice) | ||
61 | ), LuaError::OK) << S; | ||
62 | ASSERT_EQ(S.doString( | ||
63 | " l = nil" | ||
64 | " collectgarbage()" // clears the linda, removes its storage from the keeper | ||
65 | " lanes.collectgarbage()" // collect garbage inside the keepers too, to finish cleanup | ||
66 | " assert(d:refcount() == 1)" // 1 ref here | ||
67 | ), LuaError::OK) << S; | ||
68 | if constexpr (LUA_VERSION_NUM >= 503) { // Lua < 5.3 only supports a table uservalue | ||
69 | ASSERT_EQ(S.doString( | ||
70 | " d:setuv(1, function() collected = collected and collected + 1 or 1 end)" | ||
71 | " d = nil" // clear last reference | ||
72 | " collectgarbage()" // force collection | ||
73 | " assert(collected == 1)" // we should see it | ||
74 | ), LuaError::OK) << S; | ||
75 | } | ||
76 | } | ||
77 | |||
78 | // ################################################################################################# | ||
79 | |||
80 | TEST_F(DeepTests, DeepCollectedFromInsideLinda) | ||
81 | { | ||
82 | ASSERT_EQ(S.doString( | ||
83 | " d = deep_test.new_deep(1)" // create a deep userdata object | ||
84 | " d:set(42)" // set some value | ||
85 | " assert(d:refcount() == 1)" | ||
86 | ), LuaError::OK) << S; | ||
87 | ASSERT_EQ(S.doString( | ||
88 | " l = lanes.linda()" | ||
89 | " b, s = l:set('k', d, d)" // store it twice in the linda | ||
90 | " assert(b == false and s == 'under')" // no waking, under capacity | ||
91 | " assert(d:refcount() == 2)" // 1 ref here, 1 in the keeper (even if we sent it twice) | ||
92 | ), LuaError::OK) << S; | ||
93 | ASSERT_EQ(S.doString( | ||
94 | " d = nil" | ||
95 | " collectgarbage()" // force collection | ||
96 | " l = nil" | ||
97 | " collectgarbage()" // clears the linda, removes its storage from the keeper | ||
98 | " lanes.collectgarbage()" // collect garbage inside the keepers too, to finish cleanup | ||
99 | " assert(deep_test.get_deep_count() == 0)" | ||
100 | ), LuaError::OK) << S; | ||
101 | } \ No newline at end of file | ||