The Battle for Wesnoth  1.19.0-dev
test_unit_map.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2024
3  by Pauli Nieminen <paniemin@cc.hut.fi>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #define GETTEXT_DOMAIN "wesnoth-test"
17 
18 #include <boost/test/unit_test.hpp>
19 
20 #include "config.hpp"
21 #include "log.hpp"
23 #include "units/id.hpp"
24 #include "units/map.hpp"
25 #include "units/types.hpp"
26 #include "units/unit.hpp"
27 
28 #include <functional>
29 
30 
31 /*
32 ./test --report_level=detailed --log_level=all --run_test=interpolate_suite
33 
34  */
35 
36 BOOST_AUTO_TEST_SUITE( unit_map_suite )
37 
40 
41  config orc_config;
42  orc_config["id"]="Orcish Grunt";
43  orc_config["random_traits"]=false;
44  orc_config["animate"]=false;
45  unit_type orc_type(orc_config);
46 
48 
49  unit_ptr orc1_side0_real = unit::create(orc_type, 0, false);
50  unit_ptr orc2_side0_fake = unit::create(orc_type, 0, false);
51 
53 
54  typedef std::pair<unit_map::unit_iterator, bool> t_uresult;
55  t_uresult uresult1 = unit_map.add(map_location(1,1), *orc1_side0_real);
56 
57  BOOST_CHECK_MESSAGE(uresult1.second == true, "Good Add");
58  BOOST_CHECK_EQUAL(unit_map.size(), 1);
59 
61  BOOST_CHECK_MESSAGE(uresult1.first == ui, "Good Add");
62  BOOST_CHECK_MESSAGE(ui->underlying_id() == orc1_side0_real->underlying_id(), "Found Orc1");
63 
65  BOOST_CHECK_MESSAGE(ui2 == unit_map.end(), "Not Found Orc1");
66  ui2 = unit_map.find(orc1_side0_real->underlying_id()+1);
67  BOOST_CHECK_MESSAGE(ui2 == unit_map.end(), "Not Found Orc1");
68 
69  // unit * orc1p = new unit(orc1_side0_real);
70 
71  lg::set_log_domain_severity("engine", lg::severity::LG_NONE); // Don't log anything
73  uresult1 = unit_map.add(map_location(1,1), *orc1_side0_real);
76  BOOST_CHECK_EQUAL(unit_map.size(), 1);
77  BOOST_CHECK_MESSAGE(uresult1.second == false, "Didn't Add at occupied location.");
78  BOOST_CHECK_MESSAGE(uresult1.first == unit_map.end(), "Didn't Add at occupied location.");
79 
80  lg::set_log_domain_severity("engine", lg::severity::LG_NONE); // Don't log anything
81  // If the location is invalid, the unit never needs to be cloned, so no warning is emitted in the unit domain
82  uresult1 = unit_map.add(map_location(-1,1), *orc1_side0_real);
84  BOOST_CHECK_EQUAL(unit_map.size(), 1);
85  BOOST_CHECK_MESSAGE(uresult1.second == false, "Didn't Add at invalid location.");
86  BOOST_CHECK_MESSAGE(uresult1.first == unit_map.end(), "Didn't Add at invalid location.");
87 
88 
89  // PLAIN_LOG<<"ID real ="<<orc1_side0_real.underlying_id();
90  // PLAIN_LOG<<"ID fake ="<<orc2_side0_fake.underlying_id();
91 
92  lg::set_log_domain_severity("engine", lg::severity::LG_NONE); // Don't log anything
94  uresult1 = unit_map.add(map_location(1,2), *orc1_side0_real);
97  BOOST_CHECK_EQUAL(unit_map.size(), 2);
98  BOOST_CHECK_MESSAGE(uresult1.second == true, "Added in face of id collision.");
99  BOOST_CHECK_MESSAGE(uresult1.first != unit_map.end(), "Added in face of id collision.");
100  BOOST_CHECK_MESSAGE(uresult1.first->underlying_id() != orc1_side0_real->underlying_id(), "Found Orc1");
101 
102  BOOST_CHECK_MESSAGE(!unit_map.end().valid(), "Hmm, unit_map.end() is valid for dereference...");
103 
105 }
106 
107 BOOST_AUTO_TEST_CASE( track_real_unit_by_underlying_id ) {
109 
110  config orc_config;
111  orc_config["id"]="Orcish Grunt";
112  orc_config["random_traits"] = false;
113  orc_config["animate"]=false;
114  unit_type orc_type(orc_config);
115 
117 
118  unit_ptr orc1_side0_real = unit::create(orc_type, 0, true);
119 
120  std::size_t underlying_id = orc1_side0_real->underlying_id();
121  map_location hex = map_location(1,1);
122 
124 
125  typedef std::pair<unit_map::unit_iterator, bool> t_uresult;
126  t_uresult uresult1 = unit_map.add(hex, *orc1_side0_real);
127 
128  BOOST_CHECK(uresult1.second == true);
129 
130  {
131  unit_map::unit_iterator ui = unit_map.find(underlying_id);
132  BOOST_CHECK(uresult1.first == ui);
133  BOOST_CHECK(ui->underlying_id() == orc1_side0_real->underlying_id());
134  }
135 
136  unit_ptr extracted_unit = unit_map.extract(hex);
137 
138  {
139  unit_map::unit_iterator ui = unit_map.find(underlying_id);
140  BOOST_CHECK(ui == unit_map.end());
141  }
142 
143  unit_map.insert(extracted_unit);
144  extracted_unit.reset();
145 
146  {
147  unit_map::unit_iterator ui = unit_map.find(underlying_id);
148  BOOST_CHECK(uresult1.first == ui);
149  BOOST_CHECK(ui->underlying_id() == orc1_side0_real->underlying_id());
150  }
151 }
152 
153 BOOST_AUTO_TEST_CASE( track_fake_unit_by_underlying_id ) {
155 
156  config orc_config;
157  orc_config["id"]="Orcish Grunt";
158  orc_config["random_traits"] = false;
159  orc_config["animate"]=false;
160  unit_type orc_type(orc_config);
161 
163 
164  unit_ptr orc1_side0_fake = unit::create(orc_type, 0, false);
165 
166  std::size_t underlying_id = orc1_side0_fake->underlying_id();
167  map_location hex = map_location(1,1);
168 
170 
171  typedef std::pair<unit_map::unit_iterator, bool> t_uresult;
172  t_uresult uresult1 = unit_map.add(hex, *orc1_side0_fake);
173 
174  BOOST_CHECK(uresult1.second == true);
175 
176  {
177  unit_map::unit_iterator ui = unit_map.find(underlying_id);
178  BOOST_CHECK(uresult1.first == ui);
179  BOOST_CHECK(ui->underlying_id() == orc1_side0_fake->underlying_id());
180  }
181 
182  unit_ptr extracted_unit = unit_map.extract(hex);
183 
184  {
185  unit_map::unit_iterator ui = unit_map.find(underlying_id);
186  BOOST_CHECK(ui == unit_map.end());
187  }
188 
189  unit_map.insert(extracted_unit);
190  extracted_unit.reset();
191 
192  {
193  unit_map::unit_iterator ui = unit_map.find(underlying_id);
194  BOOST_CHECK(uresult1.first == ui);
195  BOOST_CHECK(ui->underlying_id() == orc1_side0_fake->underlying_id());
196  }
197 }
198 
199 BOOST_AUTO_TEST_CASE( track_real_unit_by_iterator ) {
201 
202  config orc_config;
203  orc_config["id"]="Orcish Grunt";
204  orc_config["random_traits"] = false;
205  orc_config["animate"]=false;
206  unit_type orc_type(orc_config);
207 
209 
210  unit_ptr orc1_side0_real = unit::create(orc_type, 0, true);
211 
212  map_location hex = map_location(1,1);
213 
215 
216  typedef std::pair<unit_map::unit_iterator, bool> t_uresult;
217  t_uresult uresult1 = unit_map.add(hex, *orc1_side0_real);
218 
219  unit_map::unit_iterator unit_iterator = uresult1.first;
220 
221  BOOST_CHECK(unit_iterator.valid());
222 
223  unit_ptr extracted_unit = unit_map.extract(hex);
224 
225  BOOST_CHECK_MESSAGE(unit_iterator.valid() == false, "Iterator should be invalid after extraction.");
226 
227  unit_map.insert(extracted_unit);
228 
229  BOOST_CHECK_MESSAGE(unit_iterator.valid(), "Iterator should be valid after extraction and reinsertion.");
230 
231  unit_map::unit_iterator unit_iterator2 = unit_map.find(hex);
232  BOOST_CHECK(unit_iterator2.valid());
233  BOOST_CHECK(unit_iterator == unit_iterator2);
234 }
235 
236 BOOST_AUTO_TEST_CASE( track_fake_unit_by_iterator ) {
238 
239  config orc_config;
240  orc_config["id"]="Orcish Grunt";
241  orc_config["random_traits"] = false;
242  orc_config["animate"]=false;
243  unit_type orc_type(orc_config);
244 
246 
247  unit_ptr orc1_side0_fake = unit::create(orc_type, 0, false);
248 
249  map_location hex = map_location(1,1);
250 
252 
253  typedef std::pair<unit_map::unit_iterator, bool> t_uresult;
254  t_uresult uresult1 = unit_map.add(hex, *orc1_side0_fake);
255 
256  unit_map::unit_iterator unit_iterator = uresult1.first;
257 
258  BOOST_CHECK(unit_iterator.valid());
259 
260  unit_ptr extracted_unit = unit_map.extract(hex);
261 
262  BOOST_CHECK_MESSAGE(unit_iterator.valid() == false, "Iterator should be invalid after extraction.");
263 
264  unit_map.insert(extracted_unit);
265 
266  BOOST_CHECK_MESSAGE(unit_iterator.valid(), "Iterator should be valid after extraction and reinsertion.");
267 
268  unit_map::unit_iterator unit_iterator2 = unit_map.find(hex);
269  BOOST_CHECK(unit_iterator2.valid());
270  BOOST_CHECK(unit_iterator == unit_iterator2);
271 }
272 
273 /* vim: set ts=4 sw=4: */
274 BOOST_AUTO_TEST_SUITE_END()
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:159
Container associating units to locations.
Definition: map.hpp:98
unit_iterator end()
Definition: map.hpp:428
unit_ptr extract(const map_location &loc)
Extracts a unit from the map.
Definition: map.cpp:259
unit_iterator find(std::size_t id)
Definition: map.cpp:302
umap_retval_pair_t add(const map_location &l, const unit &u)
Adds a copy of unit u at location l of the map.
Definition: map.cpp:76
std::size_t size() const
Definition: map.hpp:438
umap_retval_pair_t insert(unit_ptr p)
Inserts the unit pointed to by p into the map.
Definition: map.cpp:135
void build_unit_type(const unit_type &ut, unit_type::BUILD_STATUS status) const
Makes sure the provided unit_type is built to the specified level.
Definition: types.cpp:1259
A single unit type that the player may recruit.
Definition: types.hpp:43
@ FULL
Definition: types.hpp:74
static unit_ptr create(const config &cfg, bool use_traits=false, const vconfig *vcfg=nullptr)
Initializes a unit from a config.
Definition: unit.hpp:201
Standard logging facilities (interface).
Game configuration data as global variables.
Definition: build_info.cpp:60
logger & err()
Definition: log.cpp:302
logger & warn()
Definition: log.cpp:308
logger & info()
Definition: log.cpp:314
bool set_log_domain_severity(const std::string &name, severity severity)
Definition: log.cpp:342
std::shared_ptr< unit > unit_ptr
Definition: ptr.hpp:26
Encapsulates the map of the game.
Definition: location.hpp:38
bool valid() const
Definition: map.hpp:273
BOOST_AUTO_TEST_SUITE(filesystem)
BOOST_AUTO_TEST_CASE(test_1)
unit_type_data unit_types
Definition: types.cpp:1486