]> git.lizzy.rs Git - dragonfireclient.git/blob - src/unittest/test_irrptr.cpp
Require 'basic_debug' priv to view gameplay-relevant debug info, require 'debug'...
[dragonfireclient.git] / src / unittest / test_irrptr.cpp
1 /*
2 Minetest
3 Copyright (C) 2018 numzero, Lobachevskiy Vitaliy <numzer0@yandex.ru>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "test.h"
21
22 #include "exceptions.h"
23 #include "irr_ptr.h"
24
25 class TestIrrPtr : public TestBase
26 {
27 public:
28         TestIrrPtr() { TestManager::registerTestModule(this); }
29         const char *getName() { return "TestIrrPtr"; }
30
31         void runTests(IGameDef *gamedef);
32
33         void testRefCounting();
34         void testSelfAssignment();
35         void testNullHandling();
36 };
37
38 static TestIrrPtr g_test_instance;
39
40 void TestIrrPtr::runTests(IGameDef *gamedef)
41 {
42         TEST(testRefCounting);
43         TEST(testSelfAssignment);
44         TEST(testNullHandling);
45 }
46
47 ////////////////////////////////////////////////////////////////////////////////
48
49 #define UASSERT_REFERENCE_COUNT(object, value, info)                                     \
50         UTEST((object)->getReferenceCount() == value,                                    \
51                         info "Reference count is %d instead of " #value,                 \
52                         (object)->getReferenceCount())
53
54 void TestIrrPtr::testRefCounting()
55 {
56         IReferenceCounted *obj = new IReferenceCounted(); // RC=1
57         obj->grab();
58         UASSERT_REFERENCE_COUNT(obj, 2, "Pre-condition failed: ");
59         {
60                 irr_ptr<IReferenceCounted> p1{obj}; // move semantics
61                 UASSERT(p1.get() == obj);
62                 UASSERT_REFERENCE_COUNT(obj, 2, );
63
64                 irr_ptr<IReferenceCounted> p2{p1}; // copy ctor
65                 UASSERT(p1.get() == obj);
66                 UASSERT(p2.get() == obj);
67                 UASSERT_REFERENCE_COUNT(obj, 3, );
68
69                 irr_ptr<IReferenceCounted> p3{std::move(p1)}; // move ctor
70                 UASSERT(p1.get() == nullptr);
71                 UASSERT(p3.get() == obj);
72                 UASSERT_REFERENCE_COUNT(obj, 3, );
73
74                 p1 = std::move(p2); // move assignment
75                 UASSERT(p1.get() == obj);
76                 UASSERT(p2.get() == nullptr);
77                 UASSERT_REFERENCE_COUNT(obj, 3, );
78
79                 p2 = p3; // copy assignment
80                 UASSERT(p2.get() == obj);
81                 UASSERT(p3.get() == obj);
82                 UASSERT_REFERENCE_COUNT(obj, 4, );
83
84                 p1.release();
85                 UASSERT(p1.get() == nullptr);
86                 UASSERT_REFERENCE_COUNT(obj, 4, );
87         }
88         UASSERT_REFERENCE_COUNT(obj, 2, );
89         obj->drop();
90         UTEST(obj->drop(), "Dropping failed: reference count is %d",
91                         obj->getReferenceCount());
92 }
93
94 void TestIrrPtr::testSelfAssignment()
95 {
96         irr_ptr<IReferenceCounted> p1{new IReferenceCounted()};
97         UASSERT(p1);
98         UASSERT_REFERENCE_COUNT(p1, 1, );
99         p1 = p1;
100         UASSERT(p1);
101         UASSERT_REFERENCE_COUNT(p1, 1, );
102         p1 = std::move(p1);
103         UASSERT(p1);
104         UASSERT_REFERENCE_COUNT(p1, 1, );
105 }
106
107 void TestIrrPtr::testNullHandling()
108 {
109         // In the case of an error, it will probably crash with SEGV.
110         // Nevertheless, UASSERTs are used to catch possible corner cases.
111         irr_ptr<IReferenceCounted> p1{new IReferenceCounted()};
112         UASSERT(p1);
113         irr_ptr<IReferenceCounted> p2;
114         UASSERT(!p2);
115         irr_ptr<IReferenceCounted> p3{p2};
116         UASSERT(!p2);
117         UASSERT(!p3);
118         irr_ptr<IReferenceCounted> p4{std::move(p2)};
119         UASSERT(!p2);
120         UASSERT(!p4);
121         p2 = p2;
122         UASSERT(!p2);
123         p2 = std::move(p2);
124         UASSERT(!p2);
125         p3 = p2;
126         UASSERT(!p2);
127         UASSERT(!p3);
128         p3 = std::move(p2);
129         UASSERT(!p2);
130         UASSERT(!p3);
131 }