The Battle for Wesnoth  1.15.5+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 
104 }
105 
106 BOOST_AUTO_TEST_CASE( track_real_unit_by_underlying_id ) {
108 
109  config orc_config;
110  orc_config["id"]="Orcish Grunt";
111  orc_config["random_traits"] = false;
112  orc_config["animate"]=false;
113  unit_type orc_type(orc_config);
114 
116 
117  unit_ptr orc1_side0_real = unit::create(orc_type, 0, true);
118 
119  std::size_t underlying_id = orc1_side0_real->underlying_id();
120  map_location hex = map_location(1,1);
121 
123 
124  typedef std::pair<unit_map::unit_iterator, bool> t_uresult;
125  t_uresult uresult1 = unit_map.add(hex, *orc1_side0_real);
126 
127  BOOST_CHECK(uresult1.second == true);
128 
129  {
130  unit_map::unit_iterator ui = unit_map.find(underlying_id);
131  BOOST_CHECK(uresult1.first == ui);
132  BOOST_CHECK(ui->underlying_id() == orc1_side0_real->underlying_id());
133  }
134 
135  unit_ptr extracted_unit = unit_map.extract(hex);
136 
137  {
138  unit_map::unit_iterator ui = unit_map.find(underlying_id);
139  BOOST_CHECK(ui == unit_map.end());
140  }
141 
142  unit_map.insert(extracted_unit);
143  extracted_unit.reset();
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 
152 BOOST_AUTO_TEST_CASE( track_fake_unit_by_underlying_id ) {
154 
155  config orc_config;
156  orc_config["id"]="Orcish Grunt";
157  orc_config["random_traits"] = false;
158  orc_config["animate"]=false;
159  unit_type orc_type(orc_config);
160 
162 
163  unit_ptr orc1_side0_fake = unit::create(orc_type, 0, false);
164 
165  std::size_t underlying_id = orc1_side0_fake->underlying_id();
166  map_location hex = map_location(1,1);
167 
169 
170  typedef std::pair<unit_map::unit_iterator, bool> t_uresult;
171  t_uresult uresult1 = unit_map.add(hex, *orc1_side0_fake);
172 
173  BOOST_CHECK(uresult1.second == true);
174 
175  {
176  unit_map::unit_iterator ui = unit_map.find(underlying_id);
177  BOOST_CHECK(uresult1.first == ui);
178  BOOST_CHECK(ui->underlying_id() == orc1_side0_fake->underlying_id());
179  }
180 
181  unit_ptr extracted_unit = unit_map.extract(hex);
182 
183  {
184  unit_map::unit_iterator ui = unit_map.find(underlying_id);
185  BOOST_CHECK(ui == unit_map.end());
186  }
187 
188  unit_map.insert(extracted_unit);
189  extracted_unit.reset();
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 
198 BOOST_AUTO_TEST_CASE( track_real_unit_by_iterator ) {
200 
201  config orc_config;
202  orc_config["id"]="Orcish Grunt";
203  orc_config["random_traits"] = false;
204  orc_config["animate"]=false;
205  unit_type orc_type(orc_config);
206 
208 
209  unit_ptr orc1_side0_real = unit::create(orc_type, 0, true);
210 
211  map_location hex = map_location(1,1);
212 
214 
215  typedef std::pair<unit_map::unit_iterator, bool> t_uresult;
216  t_uresult uresult1 = unit_map.add(hex, *orc1_side0_real);
217 
218  unit_map::unit_iterator unit_iterator = uresult1.first;
219 
220  BOOST_CHECK(unit_iterator.valid());
221 
222  unit_ptr extracted_unit = unit_map.extract(hex);
223 
224  BOOST_CHECK_MESSAGE(unit_iterator.valid() == false, "Iterator should be invalid after extraction.");
225 
226  unit_map.insert(extracted_unit);
227 
228  BOOST_CHECK_MESSAGE(unit_iterator.valid(), "Iterator should be valid after extraction and reinsertion.");
229 
230  unit_map::unit_iterator unit_iterator2 = unit_map.find(hex);
231  BOOST_CHECK(unit_iterator2.valid());
232  BOOST_CHECK(unit_iterator == unit_iterator2);
233 }
234 
235 BOOST_AUTO_TEST_CASE( track_fake_unit_by_iterator ) {
237 
238  config orc_config;
239  orc_config["id"]="Orcish Grunt";
240  orc_config["random_traits"] = false;
241  orc_config["animate"]=false;
242  unit_type orc_type(orc_config);
243 
245 
246  unit_ptr orc1_side0_fake = unit::create(orc_type, 0, false);
247 
248  map_location hex = map_location(1,1);
249 
251 
252  typedef std::pair<unit_map::unit_iterator, bool> t_uresult;
253  t_uresult uresult1 = unit_map.add(hex, *orc1_side0_fake);
254 
255  unit_map::unit_iterator unit_iterator = uresult1.first;
256 
257  BOOST_CHECK(unit_iterator.valid());
258 
259  unit_ptr extracted_unit = unit_map.extract(hex);
260 
261  BOOST_CHECK_MESSAGE(unit_iterator.valid() == false, "Iterator should be invalid after extraction.");
262 
263  unit_map.insert(extracted_unit);
264 
265  BOOST_CHECK_MESSAGE(unit_iterator.valid(), "Iterator should be valid after extraction and reinsertion.");
266 
267  unit_map::unit_iterator unit_iterator2 = unit_map.find(hex);
268  BOOST_CHECK(unit_iterator2.valid());
269  BOOST_CHECK(unit_iterator == unit_iterator2);
270 }
271 
272 /* vim: set ts=4 sw=4: */
273 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:1378
BOOST_AUTO_TEST_CASE(test_1)
Definitions for the interface to Wesnoth Markup Language (WML).
std::shared_ptr< unit > unit_ptr
Definition: ptr.hpp:28
static unit_ptr create(const config &cfg, bool use_traits=false, const vconfig *vcfg=nullptr)
Initializes a unit from a config.
Definition: unit.hpp:191
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:1151
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
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