The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
test_mp_connect.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2013 - 2016 by Andrius Silinskas <[email protected]>
3  Part of thie Battle for Wesnoth Project http://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 "game_config_manager.hpp"
20 #include "game_display.hpp"
24 #include "mt_rng.hpp"
25 #include "saved_game.hpp"
27 
28 #include <boost/scoped_ptr.hpp>
29 #include <boost/assign.hpp>
30 
31 
32 /* Definitions */
33 
34 /*class test_mp_connect : public mp::connect {
35 public:
36  test_mp_connect(game_display& disp, const std::string& game_name,
37  const config& game_config, mp::chat& c, config& gamelist,
38  mp::connect_engine& engine) :
39  mp::connect(disp, game_name, game_config, c, gamelist, engine)
40  {}
41 };*/
42 
44 public:
46  ng::connect_engine(gamestate, true, nullptr)
47  {}
48 };
49 
50 
51 /* Variables */
52 
53 namespace {
54 
55 boost::scoped_ptr<saved_game> state;
56 boost::scoped_ptr<rand_rng::mt_rng> rng;
57 
58 }
59 
60 
61 /* Global fixture */
62 
65  dummy_args(boost::assign::list_of("wesnoth")("--noaddons").convert_to_container<std::vector<std::string> >()),
69  {
70 
71  config_manager.reset(new game_config_manager(cmdline_opts, test_utils::get_fake_display(1000,1000).video(), false));
73 
74  state.reset(new saved_game());
75  state->classification().campaign_type = game_classification::CAMPAIGN_TYPE::MULTIPLAYER;
76  config_manager->load_game_config_for_game(state->classification());
77 
78  state->mp_settings().mp_era = "era_default";
79  state->mp_settings().name = "multiplayer_The_Freelands";
80  state->mp_settings().use_map_settings = true;
81  state->mp_settings().saved_game = false;
82 
83  state->set_scenario(config_manager->
84  game_config().find_child("multiplayer", "id", state->mp_settings().name));
85 
86  state->mp_settings().num_turns = state->get_starting_pos()["turns"];
87 
88  rng.reset(new rand_rng::mt_rng());
89  }
91  {
92  }
93  std::vector<std::string> dummy_args;
96  boost::scoped_ptr<game_config_manager> config_manager;
97 };
98 
99 
100 /* Test classes creation utilities */
101 
103 {
104  test_connect_engine* connect_engine =
105  new test_connect_engine(*state);
106 
107  return connect_engine;
108 }
109 
110 static ng::side_engine* create_side_engine(const config& defaults,
111  test_connect_engine* connect_engine)
112 {
113  config side_cfg = connect_engine->current_config()->child("side");
114  side_cfg.remove_attributes("faction");
115  side_cfg.clear_children("default_faction");
116  side_cfg.append(defaults);
117 
118  return new ng::side_engine(side_cfg, *connect_engine, 0);
119 }
120 
121 
122 /* Tests */
123 
125 BOOST_AUTO_TEST_SUITE( mp_connect );
126 
127 
128 BOOST_AUTO_TEST_CASE( flg_map_settings )
129 {
130  // Set up side_engine and its dependencies.
131  state->mp_settings().use_map_settings = true;
132  state->mp_settings().saved_game = false;
133  boost::scoped_ptr<test_connect_engine>
134  connect_engine(create_test_connect_engine());
135  ng::side_engine_ptr side_engine;
136  config side;
137 
138  // Recruit list with no faction.
139  side.clear();
140  side["recruit"] = "Elvish Archer";
141  side_engine.reset(create_side_engine(side, connect_engine.get()));
142  //BOOST_CHECK_EQUAL( side_engine->flg().choosable_factions().size(), 1 );
143  //BOOST_CHECK_EQUAL( side_engine->flg().current_faction()["id"], "Custom" );
144  BOOST_CHECK_EQUAL( side_engine->new_config()["recruit"], "Elvish Archer" );
145 
146  // Custom faction, no recruits.
147  side.clear();
148  side["faction"] = "Custom";
149  side_engine.reset(create_side_engine(side, connect_engine.get()));
150  //BOOST_CHECK_EQUAL( side_engine->flg().choosable_factions().size(), 1 );
151  BOOST_CHECK_EQUAL( side_engine->flg().current_faction()["id"], "Custom" );
152  BOOST_CHECK_EQUAL( side_engine->new_config()["recruit"].empty(), true );
153 
154  // Random faction.
155  side.clear();
156  side["faction"] = "Random";
157  side_engine.reset(create_side_engine(side, connect_engine.get()));
158  //BOOST_CHECK_EQUAL( side_engine->flg().choosable_factions().size(), 1 );
159  BOOST_CHECK_EQUAL( side_engine->flg().current_faction()["id"], "Random" );
160 
161  // Valid faction.
162  side.clear();
163  side["faction"] = "Rebels";
164  side_engine.reset(create_side_engine(side, connect_engine.get()));
165  //BOOST_CHECK_EQUAL( side_engine->flg().choosable_factions().size(), 1 );
166  BOOST_CHECK_EQUAL( side_engine->flg().current_faction()["id"], "Rebels" );
167 
168  // Invalid faction.
169  side.clear();
170  side["faction"] = "ThisFactionDoesNotExist";
171  side_engine.reset(create_side_engine(side, connect_engine.get()));
172  BOOST_CHECK( side_engine->flg().choosable_factions().size() > 1 );
173  BOOST_CHECK_EQUAL( side_engine->flg().current_faction()["id"], "Random" );
174 
175  // Faction and recruit list.
176  side.clear();
177  side["recruit"] = "Elvish Archer";
178  side["faction"] = "Undead";
179  side_engine.reset(create_side_engine(side, connect_engine.get()));
180  //BOOST_CHECK_EQUAL( side_engine->flg().choosable_factions().size(), 1 );
181  //BOOST_CHECK_EQUAL( side_engine->flg().current_faction()["id"], "Custom" );
182  //BOOST_CHECK_EQUAL( side_engine->new_config()["recruit"], "Elvish Archer" );
183 
184  // Carried over recruits.
185  side.clear();
186  side["previous_recruits"] = "Elvish Archer";
187  side_engine.reset(create_side_engine(side, connect_engine.get()));
188  //BOOST_CHECK_EQUAL( side_engine->flg().choosable_factions().size(), 1 );
189  BOOST_CHECK_EQUAL( side_engine->flg().current_faction()["id"], "Custom" );
190  BOOST_CHECK_EQUAL( side_engine->new_config()["previous_recruits"],
191  "Elvish Archer" );
192 
193  // Valid leader unit.
194  side.clear();
195  side["type"] = "Shadow";
196  side_engine.reset(create_side_engine(side, connect_engine.get()));
197  BOOST_CHECK_EQUAL( side_engine->flg().choosable_leaders().size(), 1 );
198  BOOST_CHECK_EQUAL( side_engine->flg().current_leader(), "Shadow" );
199  BOOST_CHECK_EQUAL( side_engine->new_config()["type"], "Shadow" );
200 
201  // Invalid leader unit.
202  side.clear();
203  side["type"] = "ThisUnitDoesNotExist";
204  side_engine.reset(create_side_engine(side, connect_engine.get()));
205  BOOST_CHECK_EQUAL( side_engine->flg().choosable_leaders().size(), 1 );
206  BOOST_CHECK_EQUAL( side_engine->flg().current_leader(), "null" );
207 
208  // No leader, Custom faction.
209  side.clear();
210  side["faction"] = "Custom";
211  side_engine.reset(create_side_engine(side, connect_engine.get()));
212  BOOST_CHECK( side_engine->flg().choosable_leaders().size() > 1 );
213  BOOST_CHECK_EQUAL( side_engine->flg().current_leader(), "random" );
214 
215  // No leader, Random faction.
216  side.clear();
217  side["faction"] = "Random";
218  side_engine.reset(create_side_engine(side, connect_engine.get()));
219  BOOST_CHECK_EQUAL( side_engine->flg().choosable_leaders().size(), 1 );
220  BOOST_CHECK_EQUAL( side_engine->flg().current_leader(), "null" );
221 
222  // No leader, regular faction.
223  side.clear();
224  side["faction"] = "Undead";
225  side_engine.reset(create_side_engine(side, connect_engine.get()));
226  BOOST_CHECK( side_engine->flg().choosable_leaders().size() > 1 );
227  BOOST_CHECK_EQUAL( side_engine->flg().current_leader(), "random" );
228 
229  // Carried over leader.
230  side.clear();
231  side["id"] = "LeaderID";
232  side["type"] = "Elvish Archer";
233  config& unit = side.add_child("unit");
234  unit["id"] = "LeaderID";
235  unit["type"] = "Elvish Ranger";
236  side_engine.reset(create_side_engine(side, connect_engine.get()));
237  BOOST_CHECK_EQUAL( side_engine->flg().choosable_leaders().size(), 1 );
238  BOOST_CHECK_EQUAL( side_engine->flg().current_leader(), "Elvish Ranger" );
239 
240  // Random leader.
241  side.clear();
242  side["type"] = "random";
243  side_engine.reset(create_side_engine(side, connect_engine.get()));
244  BOOST_CHECK_EQUAL( side_engine->flg().choosable_leaders().size(), 1 );
245 
246  // Leader with both genders.
247  side.clear();
248  side["type"] = "Elvish Archer";
249  side_engine.reset(create_side_engine(side, connect_engine.get()));
250  BOOST_CHECK_EQUAL( side_engine->flg().choosable_genders().size(), 3 );
251  BOOST_CHECK_EQUAL( side_engine->flg().current_gender(), "random" );
252 
253  // Leader with only male gender.
254  side.clear();
255  side["type"] = "Swordsman";
256  side_engine.reset(create_side_engine(side, connect_engine.get()));
257  BOOST_CHECK_EQUAL( side_engine->flg().choosable_genders().size(), 1 );
258  BOOST_CHECK_EQUAL( side_engine->flg().current_gender(), "male" );
259 
260  // Leader with only female gender.
261  side.clear();
262  side["type"] = "Elvish Druid";
263  side_engine.reset(create_side_engine(side, connect_engine.get()));
264  BOOST_CHECK_EQUAL( side_engine->flg().choosable_genders().size(), 1 );
265  BOOST_CHECK_EQUAL( side_engine->flg().current_gender(), "female" );
266 
267  // Valid leader with valid gender.
268  side.clear();
269  side["type"] = "White Mage";
270  side["gender"] = "female";
271  side_engine.reset(create_side_engine(side, connect_engine.get()));
272  //BOOST_CHECK_EQUAL( side_engine->flg().choosable_genders().size(), 1 );
273  BOOST_CHECK_EQUAL( side_engine->flg().current_gender(), "female" );
274 
275  // Valid leader with invalid gender.
276  side.clear();
277  side["type"] = "Troll";
278  side["gender"] = "female";
279  side_engine.reset(create_side_engine(side, connect_engine.get()));
280  BOOST_CHECK_EQUAL( side_engine->flg().choosable_genders().size(), 1 );
281  BOOST_CHECK_EQUAL( side_engine->flg().current_gender(), "male" );
282 
283  // Leader with random gender.
284  side.clear();
285  side["type"] = "White Mage";
286  side["gender"] = "random";
287  side_engine.reset(create_side_engine(side, connect_engine.get()));
288  //BOOST_CHECK_EQUAL( side_engine->flg().choosable_genders().size(), 1 );
289  BOOST_CHECK_EQUAL( side_engine->flg().current_gender(), "random" );
290 
291  // No leader.
292  side.clear();
293  side["no_leader"] = true;
294  side_engine.reset(create_side_engine(side, connect_engine.get()));
295  BOOST_CHECK_EQUAL( side_engine->flg().choosable_leaders().size(), 1 );
296  BOOST_CHECK_EQUAL( side_engine->flg().current_leader(), "null" );
297 
298  // Resolve random faction.
299  side.clear();
300  side["faction"] = "Random";
301  side_engine.reset(create_side_engine(side, connect_engine.get()));
302  side_engine->resolve_random(*rng);
303  BOOST_CHECK( side_engine->flg().current_faction()["id"] != "Random" );
304  BOOST_CHECK( side_engine->flg().current_leader() != "random" &&
305  side_engine->flg().current_leader() != "null");
306  BOOST_CHECK( side_engine->flg().current_gender() != "random" &&
307  side_engine->flg().current_gender() != "null");
308 
309  // Resolve random faction with default leader.
310  side.clear();
311  side["faction"] = "Random";
312  side["type"] = "Troll";
313  side_engine.reset(create_side_engine(side, connect_engine.get()));
314  side_engine->resolve_random(*rng);
315  BOOST_CHECK( side_engine->flg().current_faction()["id"] != "Random" );
316  BOOST_CHECK_EQUAL( side_engine->flg().current_leader(), "Troll" );
317  BOOST_CHECK( side_engine->flg().current_gender() != "random" &&
318  side_engine->flg().current_gender() != "null" );
319 
320  // Resolve random faction with default leader and gender.
321  side.clear();
322  side["faction"] = "Random";
323  side["type"] = "White Mage";
324  side["gender"] = "male";
325  side_engine.reset(create_side_engine(side, connect_engine.get()));
326  side_engine->resolve_random(*rng);
327  BOOST_CHECK( side_engine->flg().current_faction()["id"] != "Random" );
328  BOOST_CHECK_EQUAL( side_engine->flg().current_leader(), "White Mage" );
329  BOOST_CHECK_EQUAL( side_engine->flg().current_gender(), "male" );
330 
331  // Resolve random leader.
332  side.clear();
333  side["type"] = "random";
334  side_engine.reset(create_side_engine(side, connect_engine.get()));
335  side_engine->resolve_random(*rng);
336  BOOST_CHECK( side_engine->flg().current_leader() != "random" );
337 }
338 
339 BOOST_AUTO_TEST_CASE( flg_no_map_settings )
340 {
341  // Set up side_engine and its dependencies.
342  state->mp_settings().use_map_settings = false;
343  state->mp_settings().saved_game = false;
344  boost::scoped_ptr<test_connect_engine>
345  connect_engine(create_test_connect_engine());
346  ng::side_engine_ptr side_engine;
347  config side;
348 
349  // Recruit list with no faction.
350  side.clear();
351  side["recruit"] = "Elvish Archer";
352  side_engine.reset(create_side_engine(side, connect_engine.get()));
353  BOOST_CHECK( side_engine->flg().choosable_factions().size() > 1 );
354  //BOOST_CHECK_EQUAL( side_engine->flg().current_faction()["id"], "Custom" );
355 
356  // Custom faction, no recruits.
357  side.clear();
358  side["faction"] = "Custom";
359  side_engine.reset(create_side_engine(side, connect_engine.get()));
360  BOOST_CHECK( side_engine->flg().choosable_factions().size() > 1 );
361  BOOST_CHECK_EQUAL( side_engine->flg().current_faction()["id"], "Custom" );
362  BOOST_CHECK_EQUAL( side_engine->new_config()["recruit"].empty(), true );
363 
364  // Carried over recruits.
365  side.clear();
366  side["previous_recruits"] = "Elvish Archer";
367  side_engine.reset(create_side_engine(side, connect_engine.get()));
368  BOOST_CHECK( side_engine->flg().choosable_factions().size() > 1 );
369  BOOST_CHECK_EQUAL( side_engine->flg().current_faction()["id"], "Custom" );
370  BOOST_CHECK_EQUAL( side_engine->new_config()["previous_recruits"],
371  "Elvish Archer" );
372 
373  // Explicit leader for faction with multiple leaders.
374  side.clear();
375  side["type"] = "Goblin Impaler";
376  side_engine.reset(create_side_engine(side, connect_engine.get()));
377  side_engine->flg().set_current_faction("Rebels");
378  BOOST_CHECK( side_engine->flg().choosable_leaders().size() > 1 );
379 
380  // Duplicate leaders.
381  side.clear();
382  side["faction"] = "Custom";
383  side["type"] = "Swordsman";
384  side_engine.reset(create_side_engine(side, connect_engine.get()));
385  BOOST_CHECK( side_engine->flg().choosable_leaders().size() > 1 );
386  const std::vector<std::string>& leaders =
387  side_engine->flg().choosable_leaders();
388  BOOST_CHECK_EQUAL( std::count(leaders.begin(), leaders.end(), "Swordsman"),
389  1 );
390 
391  // Explicit gender for unit with both genders available.
392  side.clear();
393  side["gender"] = "female";
394  side_engine.reset(create_side_engine(side, connect_engine.get()));
395  side_engine->flg().set_current_faction("Rebels");
396  side_engine->flg().set_current_leader("Elvish Ranger");
397  BOOST_CHECK_EQUAL( side_engine->flg().current_gender(), "random" );
398 }
399 
400 BOOST_AUTO_TEST_CASE( flg_saved_game )
401 {
402  // TODO
403 }
404 
405 BOOST_AUTO_TEST_SUITE_END()
406 
BOOST_AUTO_TEST_SUITE(mp_connect)
Definition: unit.hpp:95
void append(const config &cfg)
Append data from another config object to this one.
Definition: config.cpp:566
boost::scoped_ptr< game_config_manager > config_manager
this class is initialized once at game start put all initialization and wipe code in the methods here...
game_display & get_fake_display(const int width, const int height)
Gets a fake test display.
BOOST_GLOBAL_FIXTURE(mp_connect_fixture)
STL namespace.
Dont reload if the previous defines equal the new defines.
void clear()
Definition: config.cpp:1055
static ng::side_engine * create_side_engine(const config &defaults, test_connect_engine *connect_engine)
void clear_children(const std::string &key)
Definition: config.cpp:820
BOOST_AUTO_TEST_CASE(flg_map_settings)
config & add_child(const std::string &key)
Definition: config.cpp:743
GLuint GLuint GLsizei count
Definition: glew.h:1221
Game configuration data as global variables.
Definition: build_info.cpp:38
connect_engine(saved_game &state, const bool first_scenario, mp_campaign_info *campaign_info)
static test_connect_engine * create_test_connect_engine()
std::vector< std::string > dummy_args
const attribute_value * get(const std::string &key) const
Returns a pointer to the attribute with the given key or nullptr if it does not exist.
Definition: config.cpp:935
commandline_options cmdline_opts
hotkey::manager hotkey_manager
config & child(const std::string &key, int n=0)
Returns the nth child with the given key, or a reference to an invalid config if there is none...
Definition: config.cpp:658
void remove_attributes(T...keys)
Definition: config.hpp:571
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
test_connect_engine(saved_game &gamestate)
GLsizei const GLcharARB ** string
Definition: glew.h:4503