The Battle for Wesnoth  1.15.3+dev
test_unit_map.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2018 by Pauli Nieminen <paniemin@cc.hut.fi>
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #define GETTEXT_DOMAIN "wesnoth-test"
16 
17 #include <boost/test/unit_test.hpp>
18 
19 #include "config.hpp"
20 #include "log.hpp"
22 #include "units/id.hpp"
23 #include "units/map.hpp"
24 #include "units/types.hpp"
25 #include "units/unit.hpp"
26 
27 #include "utils/functional.hpp"
28 
29 
30 /*
31 ./test --report_level=detailed --log_level=all --run_test=interpolate_suite
32 
33  */
34 
35 BOOST_AUTO_TEST_SUITE( unit_map_suite )
36 
39 
40  config orc_config;
41  orc_config["id"]="Orcish Grunt";
42  orc_config["random_traits"]=false;
43  orc_config["animate"]=false;
44  unit_type orc_type(orc_config);
45 
47 
48  unit_ptr orc1_side0_real = unit::create(orc_type, 0, false);
49  unit_ptr orc2_side0_fake = unit::create(orc_type, 0, false);
50 
52 
53  typedef std::pair<unit_map::unit_iterator, bool> t_uresult;
54  t_uresult uresult1 = unit_map.add(map_location(1,1), *orc1_side0_real);
55 
56  BOOST_CHECK_MESSAGE(uresult1.second == true, "Good Add");
57  BOOST_CHECK_EQUAL(unit_map.size(), 1);
58 
59  unit_map::unit_iterator ui = unit_map.find(map_location(1,1));
60  BOOST_CHECK_MESSAGE(uresult1.first == ui, "Good Add");
61  BOOST_CHECK_MESSAGE(ui->underlying_id() == orc1_side0_real->underlying_id(), "Found Orc1");
62 
63  unit_map::unit_iterator ui2 = unit_map.find(map_location(1,2));
64  BOOST_CHECK_MESSAGE(ui2 == unit_map.end(), "Not Found Orc1");
65  ui2 = unit_map.find(orc1_side0_real->underlying_id()+1);
66  BOOST_CHECK_MESSAGE(ui2 == unit_map.end(), "Not Found Orc1");
67 
68  // unit * orc1p = new unit(orc1_side0_real);
69 
70  lg::set_log_domain_severity("engine", lg::err().get_severity() - 1); // Don't log anything
72  uresult1 = unit_map.add(map_location(1,1), *orc1_side0_real);
75  BOOST_CHECK_EQUAL(unit_map.size(), 1);
76  BOOST_CHECK_MESSAGE(uresult1.second == false, "Didn't Add at occupied location.");
77  BOOST_CHECK_MESSAGE(uresult1.first == unit_map.end(), "Didn't Add at occupied location.");
78 
79  lg::set_log_domain_severity("engine", lg::err().get_severity() - 1); // Don't log anything
80  // If the location is invalid, the unit never needs to be cloned, so no warning is emitted in the unit domain
81  uresult1 = unit_map.add(map_location(-1,1), *orc1_side0_real);
83  BOOST_CHECK_EQUAL(unit_map.size(), 1);
84  BOOST_CHECK_MESSAGE(uresult1.second == false, "Didn't Add at invalid location.");
85  BOOST_CHECK_MESSAGE(uresult1.first == unit_map.end(), "Didn't Add at invalid location.");
86 
87 
88  // std::cerr<<"ID real ="<<orc1_side0_real.underlying_id()<<"\n";
89  // std::cerr<<"ID fake ="<<orc2_side0_fake.underlying_id()<<"\n";
90 
91  lg::set_log_domain_severity("engine", lg::err().get_severity() - 1); // Don't log anything
93  uresult1 = unit_map.add(map_location(1,2), *orc1_side0_real);
96  BOOST_CHECK_EQUAL(unit_map.size(), 2);
97  BOOST_CHECK_MESSAGE(uresult1.second == true, "Added in face of id collision.");
98  BOOST_CHECK_MESSAGE(uresult1.first != unit_map.end(), "Added in face of id collision.");
99  BOOST_CHECK_MESSAGE(uresult1.first->underlying_id() != orc1_side0_real->underlying_id(), "Found Orc1");
100 
101  BOOST_CHECK_MESSAGE(!unit_map.end().valid(), "Hmm, unit_map.end() is valid for dereference...");
102  //To check that the collisions will cut off change the cutoff in unit_map.cpp from 1e6 to less than the guard value below
103  // unit_map.add(map_location(1,3), orc2_side0_fake);
104  // unit_map.add(map_location(1,3), orc2_side0_fake);
105 
106  // unsigned long long guard =0;
107  // for(; guard< 2e2;++guard) {
108  // unit_map.add(map_location(2,guard), orc1_side0_real);
109  // };
110 
111  // std::cerr<<"BREAK\n;";
112  // unit_map.add(map_location(1,3), orc2_side0_fake);
113  // unit_map.add(map_location(1,4), orc2_side0_fake);
114  // try {
115  // unit_map.add(map_location(1,5), orc2_side0_fake);
116  // }catch (std::runtime_error e ){
117  // BOOST_CHECK_MESSAGE(std::string(e.what()) == std::string("One million collisions in unit_map")
118  // , "One million uid collision exception");
119  // }
120 
121 }
122 
123 BOOST_AUTO_TEST_CASE( track_real_unit_by_underlying_id ) {
125 
126  config orc_config;
127  orc_config["id"]="Orcish Grunt";
128  orc_config["random_traits"] = false;
129  orc_config["animate"]=false;
130  unit_type orc_type(orc_config);
131 
133 
134  unit_ptr orc1_side0_real = unit::create(orc_type, 0, true);
135 
136  std::size_t underlying_id = orc1_side0_real->underlying_id();
137  map_location hex = map_location(1,1);
138 
140 
141  typedef std::pair<unit_map::unit_iterator, bool> t_uresult;
142  t_uresult uresult1 = unit_map.add(hex, *orc1_side0_real);
143 
144  BOOST_CHECK(uresult1.second == true);
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  unit_ptr extracted_unit = unit_map.extract(hex);
153 
154  {
155  unit_map::unit_iterator ui = unit_map.find(underlying_id);
156  BOOST_CHECK(ui == unit_map.end());
157  }
158 
159  unit_map.insert(extracted_unit);
160  extracted_unit.reset();
161 
162  {
163  unit_map::unit_iterator ui = unit_map.find(underlying_id);
164  BOOST_CHECK(uresult1.first == ui);
165  BOOST_CHECK(ui->underlying_id() == orc1_side0_real->underlying_id());
166  }
167 }
168 
169 BOOST_AUTO_TEST_CASE( track_fake_unit_by_underlying_id ) {
171 
172  config orc_config;
173  orc_config["id"]="Orcish Grunt";
174  orc_config["random_traits"] = false;
175  orc_config["animate"]=false;
176  unit_type orc_type(orc_config);
177 
179 
180  unit_ptr orc1_side0_fake = unit::create(orc_type, 0, false);
181 
182  std::size_t underlying_id = orc1_side0_fake->underlying_id();
183  map_location hex = map_location(1,1);
184 
186 
187  typedef std::pair<unit_map::unit_iterator, bool> t_uresult;
188  t_uresult uresult1 = unit_map.add(hex, *orc1_side0_fake);
189 
190  BOOST_CHECK(uresult1.second == true);
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  unit_ptr extracted_unit = unit_map.extract(hex);
199 
200  {
201  unit_map::unit_iterator ui = unit_map.find(underlying_id);
202  BOOST_CHECK(ui == unit_map.end());
203  }
204 
205  unit_map.insert(extracted_unit);
206  extracted_unit.reset();
207 
208  {
209  unit_map::unit_iterator ui = unit_map.find(underlying_id);
210  BOOST_CHECK(uresult1.first == ui);
211  BOOST_CHECK(ui->underlying_id() == orc1_side0_fake->underlying_id());
212  }
213 }
214 
215 BOOST_AUTO_TEST_CASE( track_real_unit_by_iterator ) {
217 
218  config orc_config;
219  orc_config["id"]="Orcish Grunt";
220  orc_config["random_traits"] = false;
221  orc_config["animate"]=false;
222  unit_type orc_type(orc_config);
223 
225 
226  unit_ptr orc1_side0_real = unit::create(orc_type, 0, true);
227 
228  map_location hex = map_location(1,1);
229 
231 
232  typedef std::pair<unit_map::unit_iterator, bool> t_uresult;
233  t_uresult uresult1 = unit_map.add(hex, *orc1_side0_real);
234 
235  unit_map::unit_iterator unit_iterator = uresult1.first;
236 
237  BOOST_CHECK(unit_iterator.valid());
238 
239  unit_ptr extracted_unit = unit_map.extract(hex);
240 
241  BOOST_CHECK_MESSAGE(unit_iterator.valid() == false, "Iterator should be invalid after extraction.");
242 
243  unit_map.insert(extracted_unit);
244 
245  BOOST_CHECK_MESSAGE(unit_iterator.valid(), "Iterator should be valid after extraction and reinsertion.");
246 
247  unit_map::unit_iterator unit_iterator2 = unit_map.find(hex);
248  BOOST_CHECK(unit_iterator2.valid());
249  BOOST_CHECK(unit_iterator == unit_iterator2);
250 }
251 
252 BOOST_AUTO_TEST_CASE( track_fake_unit_by_iterator ) {
254 
255  config orc_config;
256  orc_config["id"]="Orcish Grunt";
257  orc_config["random_traits"] = false;
258  orc_config["animate"]=false;
259  unit_type orc_type(orc_config);
260 
262 
263  unit_ptr orc1_side0_fake = unit::create(orc_type, 0, false);
264 
265  map_location hex = map_location(1,1);
266 
268 
269  typedef std::pair<unit_map::unit_iterator, bool> t_uresult;
270  t_uresult uresult1 = unit_map.add(hex, *orc1_side0_fake);
271 
272  unit_map::unit_iterator unit_iterator = uresult1.first;
273 
274  BOOST_CHECK(unit_iterator.valid());
275 
276  unit_ptr extracted_unit = unit_map.extract(hex);
277 
278  BOOST_CHECK_MESSAGE(unit_iterator.valid() == false, "Iterator should be invalid after extraction.");
279 
280  unit_map.insert(extracted_unit);
281 
282  BOOST_CHECK_MESSAGE(unit_iterator.valid(), "Iterator should be valid after extraction and reinsertion.");
283 
284  unit_map::unit_iterator unit_iterator2 = unit_map.find(hex);
285  BOOST_CHECK(unit_iterator2.valid());
286  BOOST_CHECK(unit_iterator == unit_iterator2);
287 }
288 
289 /* vim: set ts=4 sw=4: */
290 BOOST_AUTO_TEST_SUITE_END()
unit_iterator end()
Definition: map.hpp:429
umap_retval_pair_t insert(unit_ptr p)
Inserts the unit pointed to by p into the map.
Definition: map.cpp:135
logger & info()
Definition: log.cpp:90
unit_type_data unit_types
Definition: types.cpp:1376
BOOST_AUTO_TEST_CASE(test_1)
Definitions for the interface to Wesnoth Markup Language (WML).
static unit_ptr create(const config &cfg, bool use_traits=false, const vconfig *vcfg=nullptr)
Initializes a unit from a config.
Definition: unit.hpp:185
A single unit type that the player may recruit.
Definition: types.hpp:44
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:1149
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:78
std::size_t size() const
Definition: map.hpp:439
Encapsulates the map of the game.
Definition: location.hpp:42
unit_iterator find(std::size_t id)
Definition: map.cpp:311
logger & err()
Definition: log.cpp:78
Game configuration data as global variables.
Definition: build_info.cpp:55
bool set_log_domain_severity(const std::string &name, int severity)
Definition: log.cpp:118
boost::intrusive_ptr< unit > unit_ptr
Definition: ptr.hpp:29
logger & warn()
Definition: log.cpp:84
unit_ptr extract(const map_location &loc)
Extracts a unit from the map.
Definition: map.cpp:268
Standard logging facilities (interface).
Container associating units to locations.
Definition: map.hpp:99
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:68
bool valid() const
Definition: map.hpp:276