The Battle for Wesnoth  1.15.1+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 "log.hpp"
20 #include "config.hpp"
21 #include "units/unit.hpp"
23 #include "units/map.hpp"
24 #include "units/id.hpp"
25 
26 #include "utils/functional.hpp"
27 
28 
29 /*
30 ./test --report_level=detailed --log_level=all --run_test=interpolate_suite
31 
32  */
33 
34 BOOST_AUTO_TEST_SUITE( unit_map_suite )
35 
38 
39  config orc_config;
40  orc_config["id"]="Orcish Grunt";
41  orc_config["random_traits"]=false;
42  orc_config["animate"]=false;
43  unit_type orc_type(orc_config);
44 
46 
47  unit_ptr orc1_side0_real = unit::create(orc_type, 0, false);
48  unit_ptr orc2_side0_fake = unit::create(orc_type, 0, false);
49 
51 
52  typedef std::pair<unit_map::unit_iterator, bool> t_uresult;
53  t_uresult uresult1 = unit_map.add(map_location(1,1), *orc1_side0_real);
54 
55  BOOST_CHECK_MESSAGE(uresult1.second == true, "Good Add");
56  BOOST_CHECK_EQUAL(unit_map.size(), 1);
57 
58  unit_map::unit_iterator ui = unit_map.find(map_location(1,1));
59  BOOST_CHECK_MESSAGE(uresult1.first == ui, "Good Add");
60  BOOST_CHECK_MESSAGE(ui->underlying_id() == orc1_side0_real->underlying_id(), "Found Orc1");
61 
62  unit_map::unit_iterator ui2 = unit_map.find(map_location(1,2));
63  BOOST_CHECK_MESSAGE(ui2 == unit_map.end(), "Not Found Orc1");
64  ui2 = unit_map.find(orc1_side0_real->underlying_id()+1);
65  BOOST_CHECK_MESSAGE(ui2 == unit_map.end(), "Not Found Orc1");
66 
67  // unit * orc1p = new unit(orc1_side0_real);
68 
69  lg::set_log_domain_severity("engine", lg::err().get_severity() - 1); // Don't log anything
71  uresult1 = unit_map.add(map_location(1,1), *orc1_side0_real);
74  BOOST_CHECK_EQUAL(unit_map.size(), 1);
75  BOOST_CHECK_MESSAGE(uresult1.second == false, "Didn't Add at occupied location.");
76  BOOST_CHECK_MESSAGE(uresult1.first == unit_map.end(), "Didn't Add at occupied location.");
77 
78  lg::set_log_domain_severity("engine", lg::err().get_severity() - 1); // Don't log anything
79  // If the location is invalid, the unit never needs to be cloned, so no warning is emitted in the unit domain
80  uresult1 = unit_map.add(map_location(-1,1), *orc1_side0_real);
82  BOOST_CHECK_EQUAL(unit_map.size(), 1);
83  BOOST_CHECK_MESSAGE(uresult1.second == false, "Didn't Add at invalid location.");
84  BOOST_CHECK_MESSAGE(uresult1.first == unit_map.end(), "Didn't Add at invalid location.");
85 
86 
87  // std::cerr<<"ID real ="<<orc1_side0_real.underlying_id()<<"\n";
88  // std::cerr<<"ID fake ="<<orc2_side0_fake.underlying_id()<<"\n";
89 
90  lg::set_log_domain_severity("engine", lg::err().get_severity() - 1); // Don't log anything
92  uresult1 = unit_map.add(map_location(1,2), *orc1_side0_real);
95  BOOST_CHECK_EQUAL(unit_map.size(), 2);
96  BOOST_CHECK_MESSAGE(uresult1.second == true, "Added in face of id collision.");
97  BOOST_CHECK_MESSAGE(uresult1.first != unit_map.end(), "Added in face of id collision.");
98  BOOST_CHECK_MESSAGE(uresult1.first->underlying_id() != orc1_side0_real->underlying_id(), "Found Orc1");
99 
100  BOOST_CHECK_MESSAGE(!unit_map.end().valid(), "Hmm, unit_map.end() is valid for dereference...");
101  //To check that the collisions will cut off change the cutoff in unit_map.cpp from 1e6 to less than the guard value below
102  // unit_map.add(map_location(1,3), orc2_side0_fake);
103  // unit_map.add(map_location(1,3), orc2_side0_fake);
104 
105  // unsigned long long guard =0;
106  // for(; guard< 2e2;++guard) {
107  // unit_map.add(map_location(2,guard), orc1_side0_real);
108  // };
109 
110  // std::cerr<<"BREAK\n;";
111  // unit_map.add(map_location(1,3), orc2_side0_fake);
112  // unit_map.add(map_location(1,4), orc2_side0_fake);
113  // try {
114  // unit_map.add(map_location(1,5), orc2_side0_fake);
115  // }catch (std::runtime_error e ){
116  // BOOST_CHECK_MESSAGE(std::string(e.what()) == std::string("One million collisions in unit_map")
117  // , "One million uid collision exception");
118  // }
119 
120 }
121 
122 BOOST_AUTO_TEST_CASE( track_real_unit_by_underlying_id ) {
124 
125  config orc_config;
126  orc_config["id"]="Orcish Grunt";
127  orc_config["random_traits"] = false;
128  orc_config["animate"]=false;
129  unit_type orc_type(orc_config);
130 
132 
133  unit_ptr orc1_side0_real = unit::create(orc_type, 0, true);
134 
135  std::size_t underlying_id = orc1_side0_real->underlying_id();
136  map_location hex = map_location(1,1);
137 
139 
140  typedef std::pair<unit_map::unit_iterator, bool> t_uresult;
141  t_uresult uresult1 = unit_map.add(hex, *orc1_side0_real);
142 
143  BOOST_CHECK(uresult1.second == true);
144 
145  {
146  unit_map::unit_iterator ui = unit_map.find(underlying_id);
147  BOOST_CHECK(uresult1.first == ui);
148  BOOST_CHECK(ui->underlying_id() == orc1_side0_real->underlying_id());
149  }
150 
151  unit_ptr extracted_unit = unit_map.extract(hex);
152 
153  {
154  unit_map::unit_iterator ui = unit_map.find(underlying_id);
155  BOOST_CHECK(ui == unit_map.end());
156  }
157 
158  unit_map.insert(extracted_unit);
159  extracted_unit.reset();
160 
161  {
162  unit_map::unit_iterator ui = unit_map.find(underlying_id);
163  BOOST_CHECK(uresult1.first == ui);
164  BOOST_CHECK(ui->underlying_id() == orc1_side0_real->underlying_id());
165  }
166 }
167 
168 BOOST_AUTO_TEST_CASE( track_fake_unit_by_underlying_id ) {
170 
171  config orc_config;
172  orc_config["id"]="Orcish Grunt";
173  orc_config["random_traits"] = false;
174  orc_config["animate"]=false;
175  unit_type orc_type(orc_config);
176 
178 
179  unit_ptr orc1_side0_fake = unit::create(orc_type, 0, false);
180 
181  std::size_t underlying_id = orc1_side0_fake->underlying_id();
182  map_location hex = map_location(1,1);
183 
185 
186  typedef std::pair<unit_map::unit_iterator, bool> t_uresult;
187  t_uresult uresult1 = unit_map.add(hex, *orc1_side0_fake);
188 
189  BOOST_CHECK(uresult1.second == true);
190 
191  {
192  unit_map::unit_iterator ui = unit_map.find(underlying_id);
193  BOOST_CHECK(uresult1.first == ui);
194  BOOST_CHECK(ui->underlying_id() == orc1_side0_fake->underlying_id());
195  }
196 
197  unit_ptr extracted_unit = unit_map.extract(hex);
198 
199  {
200  unit_map::unit_iterator ui = unit_map.find(underlying_id);
201  BOOST_CHECK(ui == unit_map.end());
202  }
203 
204  unit_map.insert(extracted_unit);
205  extracted_unit.reset();
206 
207  {
208  unit_map::unit_iterator ui = unit_map.find(underlying_id);
209  BOOST_CHECK(uresult1.first == ui);
210  BOOST_CHECK(ui->underlying_id() == orc1_side0_fake->underlying_id());
211  }
212 }
213 
214 BOOST_AUTO_TEST_CASE( track_real_unit_by_iterator ) {
216 
217  config orc_config;
218  orc_config["id"]="Orcish Grunt";
219  orc_config["random_traits"] = false;
220  orc_config["animate"]=false;
221  unit_type orc_type(orc_config);
222 
224 
225  unit_ptr orc1_side0_real = unit::create(orc_type, 0, true);
226 
227  map_location hex = map_location(1,1);
228 
230 
231  typedef std::pair<unit_map::unit_iterator, bool> t_uresult;
232  t_uresult uresult1 = unit_map.add(hex, *orc1_side0_real);
233 
234  unit_map::unit_iterator unit_iterator = uresult1.first;
235 
236  BOOST_CHECK(unit_iterator.valid());
237 
238  unit_ptr extracted_unit = unit_map.extract(hex);
239 
240  BOOST_CHECK_MESSAGE(unit_iterator.valid() == false, "Iterator should be invalid after extraction.");
241 
242  unit_map.insert(extracted_unit);
243 
244  BOOST_CHECK_MESSAGE(unit_iterator.valid(), "Iterator should be valid after extraction and reinsertion.");
245 
246  unit_map::unit_iterator unit_iterator2 = unit_map.find(hex);
247  BOOST_CHECK(unit_iterator2.valid());
248  BOOST_CHECK(unit_iterator == unit_iterator2);
249 }
250 
251 BOOST_AUTO_TEST_CASE( track_fake_unit_by_iterator ) {
253 
254  config orc_config;
255  orc_config["id"]="Orcish Grunt";
256  orc_config["random_traits"] = false;
257  orc_config["animate"]=false;
258  unit_type orc_type(orc_config);
259 
261 
262  unit_ptr orc1_side0_fake = unit::create(orc_type, 0, false);
263 
264  map_location hex = map_location(1,1);
265 
267 
268  typedef std::pair<unit_map::unit_iterator, bool> t_uresult;
269  t_uresult uresult1 = unit_map.add(hex, *orc1_side0_fake);
270 
271  unit_map::unit_iterator unit_iterator = uresult1.first;
272 
273  BOOST_CHECK(unit_iterator.valid());
274 
275  unit_ptr extracted_unit = unit_map.extract(hex);
276 
277  BOOST_CHECK_MESSAGE(unit_iterator.valid() == false, "Iterator should be invalid after extraction.");
278 
279  unit_map.insert(extracted_unit);
280 
281  BOOST_CHECK_MESSAGE(unit_iterator.valid(), "Iterator should be valid after extraction and reinsertion.");
282 
283  unit_map::unit_iterator unit_iterator2 = unit_map.find(hex);
284  BOOST_CHECK(unit_iterator2.valid());
285  BOOST_CHECK(unit_iterator == unit_iterator2);
286 }
287 
288 /* vim: set ts=4 sw=4: */
289 BOOST_AUTO_TEST_SUITE_END()
unit_iterator end()
Definition: map.hpp:415
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:1525
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:154
A single unit type that the player may recruit.
Definition: types.hpp:42
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.hpp:373
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:425
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:49
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:92
bool valid() const
Definition: map.hpp:276