1 /**
2  * @file
3  */
4 
5 /*
6 Copyright (C) 2002-2013 UFO: Alien Invasion.
7 
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 
17 See the GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22 
23 */
24 
25 
26 #include "test_inventory.h"
27 #include "test_shared.h"
28 #include "../common/common.h"
29 #include "../game/inventory.h"
30 
31 static InventoryInterface i;
32 static const int TAG_INVENTORY = 5546;
33 
FreeInventory(void * data)34 static void FreeInventory (void* data)
35 {
36 	Mem_Free(data);
37 }
38 
AllocInventoryMemory(size_t size)39 static void* AllocInventoryMemory (size_t size)
40 {
41 	return Mem_PoolAlloc(size, com_genericPool, TAG_INVENTORY);
42 }
43 
FreeAllInventory(void)44 static void FreeAllInventory (void)
45 {
46 	Mem_FreeTag(com_genericPool, TAG_INVENTORY);
47 }
48 
49 static const inventoryImport_t inventoryImport = { FreeInventory, FreeAllInventory, AllocInventoryMemory };
50 
ResetInventoryList(void)51 static inline void ResetInventoryList (void)
52 {
53 	i.destroyInventoryInterface();
54 	i.initInventory("test", &csi, &inventoryImport);
55 }
56 
57 /**
58  * The suite initialization function.
59  * Returns zero on success, non-zero otherwise.
60  */
UFO_InitSuiteInventory(void)61 static int UFO_InitSuiteInventory (void)
62 {
63 	TEST_Init();
64 	Com_ParseScripts(true);
65 
66 	return 0;
67 }
68 
69 /**
70  * The suite cleanup function.
71  * Returns zero on success, non-zero otherwise.
72  */
UFO_CleanSuiteInventory(void)73 static int UFO_CleanSuiteInventory (void)
74 {
75 	TEST_Shutdown();
76 	return 0;
77 }
78 
testItemAdd(void)79 static void testItemAdd (void)
80 {
81 	Inventory inv;
82 	const objDef_t* od;
83 	const invDef_t* container;
84 
85 	ResetInventoryList();
86 
87 	od = INVSH_GetItemByIDSilent("assault");
88 	CU_ASSERT_PTR_NOT_NULL(od);
89 
90 	container = INVSH_GetInventoryDefinitionByID("right");
91 	CU_ASSERT_PTR_NOT_NULL(container);
92 
93 	Item item(od);
94 
95 	CU_ASSERT(inv.containsItem(container->id, &item) == false);
96 
97 	CU_ASSERT_PTR_NOT_NULL(i.addToInventory(&inv, &item, container, NONE, NONE, 1));
98 
99 	CU_ASSERT(inv.containsItem(container->id, &item) == true);
100 }
101 
testItemDel(void)102 static void testItemDel (void)
103 {
104 	Inventory inv;
105 	const objDef_t* od;
106 	const invDef_t* container;
107 	Item *addedItem;
108 
109 	ResetInventoryList();
110 
111 	od = INVSH_GetItemByIDSilent("assault");
112 	CU_ASSERT_PTR_NOT_NULL(od);
113 
114 	container = INVSH_GetInventoryDefinitionByID("right");
115 	CU_ASSERT_PTR_NOT_NULL(container);
116 
117 	Item item(od);
118 
119 	CU_ASSERT(inv.containsItem(container->id, &item) == false);
120 
121 	addedItem = i.addToInventory(&inv, &item, container, NONE, NONE, 1);
122 
123 	CU_ASSERT(inv.containsItem(container->id, &item) == true);
124 
125 	CU_ASSERT(i.removeFromInventory(&inv, container, addedItem));
126 
127 	CU_ASSERT(inv.containsItem(container->id, &item) == false);
128 }
129 
testItemMove(void)130 static void testItemMove (void)
131 {
132 	Inventory inv;
133 	const objDef_t* od;
134 	const invDef_t* container, *containerTo;
135 	Item *addedItem;
136 
137 	ResetInventoryList();
138 
139 	od = INVSH_GetItemByIDSilent("assault");
140 	CU_ASSERT_PTR_NOT_NULL(od);
141 
142 	container = INVSH_GetInventoryDefinitionByID("right");
143 	CU_ASSERT_PTR_NOT_NULL(container);
144 
145 	Item item(od);
146 
147 	CU_ASSERT(inv.containsItem(container->id, &item) == false);
148 
149 	addedItem = i.addToInventory(&inv, &item, container, NONE, NONE, 1);
150 	CU_ASSERT_PTR_NOT_NULL(addedItem);
151 
152 	CU_ASSERT(inv.containsItem(container->id, &item) == true);
153 
154 	containerTo = INVSH_GetInventoryDefinitionByID("backpack");
155 	CU_ASSERT_PTR_NOT_NULL(containerTo);
156 
157 	CU_ASSERT_EQUAL(IA_MOVE, i.moveInInventory(&inv, container, addedItem, containerTo, NONE, NONE, nullptr, nullptr));
158 
159 	CU_ASSERT(inv.containsItem(container->id, &item) == false);
160 	CU_ASSERT(inv.containsItem(containerTo->id, &item) == true);
161 }
162 
testItemReload(void)163 static void testItemReload (void)
164 {
165 	Inventory inv;
166 	const objDef_t* od, *ad;
167 	const invDef_t* container, *containerFrom;
168 	Item *addedItem;
169 
170 	ResetInventoryList();
171 
172 	od = INVSH_GetItemByIDSilent("rpg");
173 	CU_ASSERT_PTR_NOT_NULL(od);
174 
175 	container = INVSH_GetInventoryDefinitionByID("right");
176 	CU_ASSERT_PTR_NOT_NULL(container);
177 
178 	Item item(od);
179 
180 	CU_ASSERT(inv.containsItem(container->id, &item) == false);
181 
182 	addedItem = i.addToInventory(&inv, &item, container, NONE, NONE, 1);
183 	CU_ASSERT_PTR_NOT_NULL(addedItem);
184 
185 	CU_ASSERT(inv.containsItem(container->id, &item) == true);
186 
187 	ad = INVSH_GetItemByIDSilent("rpg_ammo");
188 	CU_ASSERT_PTR_NOT_NULL(ad);
189 
190 	Item ammo(ad);
191 
192 	containerFrom = INVSH_GetInventoryDefinitionByID("backpack");
193 	CU_ASSERT_PTR_NOT_NULL(containerFrom);
194 
195 	CU_ASSERT(inv.containsItem(containerFrom->id, &ammo) == false);
196 
197 	addedItem = i.addToInventory(&inv, &ammo, containerFrom, NONE, NONE, 1);
198 	CU_ASSERT_PTR_NOT_NULL(addedItem);
199 
200 	CU_ASSERT(inv.containsItem(containerFrom->id, &ammo) == true);
201 
202 	CU_ASSERT_EQUAL(IA_RELOAD, i.moveInInventory(&inv, containerFrom, addedItem, container, NONE, NONE, nullptr, nullptr));
203 
204 	CU_ASSERT(inv.containsItem(containerFrom->id, &ammo) == false);
205 
206 	item.setAmmoDef(ad);
207 	item.setAmmoLeft(1);
208 
209 	CU_ASSERT(inv.containsItem(container->id, &item) == true);
210 
211 	ad = INVSH_GetItemByIDSilent("rpg_incendiary_ammo");
212 	CU_ASSERT_PTR_NOT_NULL(ad);
213 
214 	Item ammoFrom(ad);
215 
216 	CU_ASSERT(inv.containsItem(containerFrom->id, &ammoFrom) == false);
217 
218 	addedItem = i.addToInventory(&inv, &ammoFrom, containerFrom, NONE, NONE, 1);
219 	CU_ASSERT_PTR_NOT_NULL(addedItem);
220 
221 	CU_ASSERT(inv.containsItem(containerFrom->id, &ammoFrom) == true);
222 
223 	CU_ASSERT_EQUAL(IA_RELOAD_SWAP, i.moveInInventory(&inv, containerFrom, addedItem, container, NONE, NONE, nullptr, nullptr));
224 
225 	CU_ASSERT(inv.containsItem(containerFrom->id, &ammoFrom) == false);
226 	CU_ASSERT(inv.containsItem(containerFrom->id, &ammo) == true);
227 
228 	item.setAmmoDef(ad);
229 
230 	CU_ASSERT(inv.containsItem(container->id, &item) == true);
231 }
232 
testAddSingle(Inventory * inv,const objDef_t * od,const invDef_t * container)233 static bool testAddSingle (Inventory* inv, const objDef_t* od, const invDef_t* container)
234 {
235 	Item item(od);
236 
237 	return i.tryAddToInventory(inv, &item, container);
238 }
239 
testItemMassActions(void)240 static void testItemMassActions (void)
241 {
242 	Inventory inv;
243 	const objDef_t* od;
244 	const invDef_t* container;
245 	bool addedItem;
246 	int i;
247 
248 	ResetInventoryList();
249 
250 	od = INVSH_GetItemByIDSilent("assault");
251 	CU_ASSERT_PTR_NOT_NULL_FATAL(od);
252 
253 	container = INVSH_GetInventoryDefinitionByID("right");
254 	CU_ASSERT_PTR_NOT_NULL_FATAL(container);
255 
256 	addedItem = testAddSingle(&inv, od, container);
257 	CU_ASSERT(addedItem == true);
258 
259 	/* second try should fail as the right container is a single container */
260 	addedItem = testAddSingle(&inv, od, container);
261 	CU_ASSERT(addedItem == false);
262 
263 	container = INVSH_GetInventoryDefinitionByID("left");
264 	CU_ASSERT_PTR_NOT_NULL_FATAL(container);
265 
266 	od = INVSH_GetItemByIDSilent("fraggrenade");
267 	CU_ASSERT_PTR_NOT_NULL_FATAL(od);
268 
269 	addedItem = testAddSingle(&inv, od, container);
270 	CU_ASSERT(addedItem == true);
271 
272 	container = INVSH_GetInventoryDefinitionByID("equip");
273 	CU_ASSERT_PTR_NOT_NULL_FATAL(container);
274 
275 	for (i = 0; i < csi.numODs; i++) {
276 		int j;
277 		od = INVSH_GetItemByIDX(i);
278 		/* every item should be placable on the ground container and there should really be enough space */
279 		addedItem = testAddSingle(&inv, od, container);
280 		CU_ASSERT(addedItem == true);
281 		addedItem = testAddSingle(&inv, od, container);
282 		CU_ASSERT(addedItem == true);
283 		addedItem = testAddSingle(&inv, od, container);
284 		CU_ASSERT(addedItem == true);
285 		for (j = 0; j < od->numAmmos; j++) {
286 			addedItem = testAddSingle(&inv, od->ammos[j], container);
287 			CU_ASSERT(addedItem == true);
288 			addedItem = testAddSingle(&inv, od->ammos[j], container);
289 			CU_ASSERT(addedItem == true);
290 			addedItem = testAddSingle(&inv, od->ammos[j], container);
291 			CU_ASSERT(addedItem == true);
292 			addedItem = testAddSingle(&inv, od->ammos[j], container);
293 			CU_ASSERT(addedItem == true);
294 			addedItem = testAddSingle(&inv, od->ammos[j], container);
295 			CU_ASSERT(addedItem == true);
296 			addedItem = testAddSingle(&inv, od->ammos[j], container);
297 			CU_ASSERT(addedItem == true);
298 		}
299 	}
300 }
301 
testItemToHeadgear(void)302 static void testItemToHeadgear (void)
303 {
304 	Inventory inv;
305 	const objDef_t* od;
306 	const invDef_t* container;
307 
308 	ResetInventoryList();
309 
310 	od = INVSH_GetItemByIDSilent("irgoggles");
311 	CU_ASSERT_PTR_NOT_NULL_FATAL(od);
312 
313 	container = INVSH_GetInventoryDefinitionByID("headgear");
314 	CU_ASSERT_PTR_NOT_NULL_FATAL(container);
315 
316 	Item item(od);
317 
318 	CU_ASSERT_FALSE(inv.containsItem(container->id, &item));
319 
320 	CU_ASSERT_PTR_NOT_NULL(i.addToInventory(&inv, &item, container, NONE, NONE, 1));
321 
322 	CU_ASSERT_TRUE(inv.containsItem(container->id, &item));
323 
324 	CU_ASSERT_PTR_NULL(i.addToInventory(&inv, &item, container, NONE, NONE, 1));
325 }
326 
UFO_AddInventoryTests(void)327 int UFO_AddInventoryTests (void)
328 {
329 	/* add a suite to the registry */
330 	CU_pSuite InventorySuite = CU_add_suite("InventoryTests", UFO_InitSuiteInventory, UFO_CleanSuiteInventory);
331 	if (InventorySuite == nullptr)
332 		return CU_get_error();
333 
334 	/* add the tests to the suite */
335 	if (CU_ADD_TEST(InventorySuite, testItemAdd) == nullptr)
336 		return CU_get_error();
337 	if (CU_ADD_TEST(InventorySuite, testItemDel) == nullptr)
338 		return CU_get_error();
339 	if (CU_ADD_TEST(InventorySuite, testItemMove) == nullptr)
340 		return CU_get_error();
341 	if (CU_ADD_TEST(InventorySuite, testItemMassActions) == nullptr)
342 		return CU_get_error();
343 	if (CU_ADD_TEST(InventorySuite, testItemReload) == nullptr)
344 		return CU_get_error();
345 	if (CU_ADD_TEST(InventorySuite, testItemToHeadgear) == nullptr)
346 		return CU_get_error();
347 
348 	return CUE_SUCCESS;
349 }
350