1 /***************************************************************************
2 * Copyright (C) 2005-2019 by the FIFE team *
3 * http://www.fifengine.net *
4 * This file is part of FIFE. *
5 * *
6 * FIFE is free software; you can redistribute it and/or *
7 * modify it under the terms of the GNU Lesser General Public *
8 * License as published by the Free Software Foundation; either *
9 * version 2.1 of the License, or (at your option) any later version. *
10 * *
11 * This library is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14 * Lesser General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU Lesser General Public *
17 * License along with this library; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
20 ***************************************************************************/
21
22 // Standard C++ library includes
23 #include <iostream>
24 #include <iomanip>
25
26 // Platform specific includes
27 #include "fife_unittest.h"
28
29 // 3rd party library includes
30
31 // FIFE includes
32 // These includes are split up in two parts, separated by one empty line
33 // First block: files included from the FIFE root src directory
34 // Second block: files included from the same folder
35 #include "util/base/sharedptr.h"
36 #include "util/base/fife_stdint.h"
37
38 using namespace FIFE;
39
40 class Data {
41 public:
42 int32_t x,y;
43
Data()44 Data() : x(0), y(0) {}
Data(int32_t _x,int32_t _y)45 Data(int32_t _x, int32_t _y) : x(_x), y(_y) {}
46
~Data()47 virtual ~Data() {}
48
total()49 virtual int32_t total() { return x+y; }
50 };
51
52 class SubData : public Data {
53 public:
54 int32_t z;
55
SubData()56 SubData() : Data(0,0), z(0) {}
SubData(int32_t _x,int32_t _y,int32_t _z)57 SubData(int32_t _x, int32_t _y, int32_t _z) : Data(_x, _y), z(_z) {}
58
~SubData()59 virtual ~SubData() {}
60
total()61 virtual int32_t total() { return x+y+z; }
62 };
63
64 /**
65 * 1. Create a shared pointer to new data
66 * 2. Create another shared pointer by using the "=" operator to the first shared pointer
67 * 3. Call reset on the first shared pointer and make sure the data is still valid
68 * 4. Call reset on the second shared pointer and make sure the dynamic memory is deleted
69 **/
70
TEST(case1)71 TEST(case1) {
72 SharedPtr<Data> shptr(new Data(5,10));
73
74 SharedPtr<Data> copy = shptr;
75 CHECK(shptr.useCount() == 2);
76
77 shptr.reset();
78 CHECK(!shptr);
79
80 CHECK(copy.useCount() == 1);
81 CHECK(copy.unique());
82
83 CHECK(copy->x == 5);
84 CHECK(copy->y == 10);
85
86 copy.reset();
87 CHECK(!copy);
88 }
89
90 /**
91 * 1. Create a shared pointer to new data
92 * 2. Create another shared pointer by using the copy constructor passing the first shared pointer as the parameter
93 * 3. Call reset on the first shared pointer and make sure the data is still valid
94 * 4. Call reset on the second shared pointer and make sure the dynamic memory is deleted
95 **/
96
TEST(case2)97 TEST(case2) {
98 SharedPtr<Data> shptr(new Data(5,10));
99
100 SharedPtr<Data> copy(shptr);
101 CHECK(shptr.useCount() == 2);
102
103 shptr.reset();
104 CHECK(!shptr);
105
106 CHECK(copy.useCount() == 1);
107 CHECK(copy.unique());
108
109 CHECK(copy->x == 5);
110 CHECK(copy->y == 10);
111
112 copy.reset();
113 CHECK(!copy);
114 }
115
116 /**
117 * 1. Create a shared pointer to new data
118 * 2. Set data using the "->" operator of the shared pointer
119 * 3. Create another shared pointer either using "=" or copy constructor
120 * 4. Access underlying dynamic data using the "*" operator and make sure the value is the same as what was set in step 2.
121 */
TEST(case3)122 TEST(case3) {
123 SharedPtr<Data> shptr(new Data());
124
125 shptr->x = 5;
126 shptr->y = 10;
127
128 SharedPtr<Data> copy(shptr);
129 CHECK(shptr.useCount() == 2);
130
131 shptr.reset();
132 CHECK(!shptr);
133
134 Data d = *copy;
135
136 CHECK(copy.useCount() == 1);
137 CHECK(copy.unique());
138
139 CHECK(d.x == 5);
140 CHECK(d.y == 10);
141
142 copy.reset();
143 CHECK(!copy);
144 }
145
146 /**
147 * 1. Create a shared pointer to new data
148 * 2. Check to make sure unique returns true
149 * 3. Create another shared pointer to same shared data using "=" or copy constructor
150 * 4. Make sure unique on both shared pointers return false
151 */
TEST(case4)152 TEST(case4) {
153 SharedPtr<Data> shptr(new Data());
154 CHECK(shptr.unique());
155
156 SharedPtr<Data> copy(shptr);
157
158 CHECK(!shptr.unique());
159 CHECK(!copy.unique());
160 }
161
162 /**
163 * 1. Create empty shared pointer using default constructor
164 * 2. use shared pointer in condition such as an if statement to make sure it evaluates correctly
165 */
TEST(case5)166 TEST(case5) {
167 SharedPtr<Data> shptr;
168
169 CHECK(shptr == 0);
170 }
171
172 /**
173 * 1. Create a shared pointer of type base class to a dynamic object of the child class
174 * 2. Call a virtual function using the "->" of the shared pointer and make sure the proper function overload is called.
175 */
TEST(case6)176 TEST(case6) {
177 SharedPtr<Data> shptr(new SubData(2,4,6));
178
179 CHECK(shptr->total() == 12);
180 }
181
182 /**
183 * 1. Create a shared pointer to new data
184 * 2. Create another shared pointer by using the copy constructor passing the first shared pointer as the parameter
185 * 3. Create a third shared pointer to new data
186 * 4. Check for equality of the first 2 shared pointers.
187 * 5. Check for inequality of the first and 3rd shared pointers.
188 */
TEST(case7)189 TEST(case7) {
190 SharedPtr<Data> shptr(new Data(2,4));
191 SharedPtr<Data> copy(shptr);
192 SharedPtr<Data> shptr2(new Data(4,8));
193
194 CHECK(shptr == copy);
195 CHECK(shptr != shptr2);
196 }
197
198 /**
199 * 1. Create a shared pointer to new data
200 * 2. Create a copy of the shared pointer
201 * 3. Reset the first shared pointer with new data
202 * 4. Check the data values of the original shared pointer
203 * 5. Check the data values of the copied shared pointer
204 */
TEST(case8)205 TEST(case8) {
206 SharedPtr<Data> shptr(new Data(2,4));
207 SharedPtr<Data> copy(shptr);
208
209 CHECK(copy.useCount() == 2);
210 shptr.reset(new Data(6,8));
211 CHECK(copy.useCount() == 1);
212
213 //shptr holding values we expect?
214 CHECK(shptr->x == 6);
215 CHECK(shptr->y == 8);
216
217 CHECK(copy->x == 2);
218 CHECK(copy->y == 4);
219
220 shptr.reset();
221 CHECK(!shptr);
222 }
223
main()224 int32_t main() {
225 return UnitTest::RunAllTests();
226 }
227