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