aboutsummaryrefslogtreecommitdiff
path: root/unit_tests/deep_tests.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--unit_tests/deep_tests.cpp101
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
11class 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
27TEST_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
44TEST_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
80TEST_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