The Battle for Wesnoth  1.19.8+dev
test_mp_connect.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2013 - 2024
3  by Andrius Silinskas <silinskas.andrius@gmail.com>
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 "game_config_manager.hpp"
21 #include "game_display.hpp"
24 #include "mt_rng.hpp"
25 #include "saved_game.hpp"
27 
28 /* Definitions */
29 
31 public:
33  ng::connect_engine(gamestate, true, nullptr)
34  {}
35 };
36 
37 /* Variables */
38 
39 namespace {
40 
41 std::unique_ptr<saved_game> state;
42 std::unique_ptr<randomness::mt_rng> rng;
43 
44 }
45 
46 /* Global fixture */
47 
50  dummy_args({"wesnoth", "--noaddons"}),
54  {
58 
59  state.reset(new saved_game());
60  state->classification().type = campaign_type::type::multiplayer;
61  state->classification().era_id = "era_default";
62  config_manager->load_game_config_for_game(state->classification(), state->get_scenario_id());
63 
64  state->mp_settings().name = "multiplayer_The_Freelands";
65  state->mp_settings().use_map_settings = true;
66  state->mp_settings().saved_game = saved_game_mode::type::no;
67 
68  state->set_scenario(config_manager->game_config().find_mandatory_child("multiplayer", "id", state->mp_settings().name));
69 
70  state->mp_settings().num_turns = state->get_starting_point()["turns"].to_int();
71 
72  rng.reset(new randomness::mt_rng());
73  }
75  {
76  }
77  std::vector<std::string> dummy_args;
80  std::unique_ptr<game_config_manager> config_manager;
81 };
82 
83 
84 /* Test classes creation utilities */
85 
87 {
88  test_connect_engine* connect_engine =
89  new test_connect_engine(*state);
90 
91  return connect_engine;
92 }
93 
94 static ng::side_engine* create_side_engine(const config& defaults,
95  test_connect_engine* connect_engine)
96 {
97  config side_cfg = connect_engine->current_config()->mandatory_child("side");
98  side_cfg.remove_attributes("faction");
99  side_cfg.clear_children("default_faction");
100  side_cfg.clear_children("leader");
101  side_cfg.append(defaults);
102 
103  return new ng::side_engine(side_cfg, *connect_engine, 0);
104 }
105 
106 
107 /* Tests */
108 
110 
111 
112 BOOST_AUTO_TEST_CASE( flg_map_settings2 )
113 {
114  // Set up side_engine and its dependencies.
115  state->mp_settings().use_map_settings = true;
116  state->mp_settings().saved_game = saved_game_mode::type::no;
117  std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
118  ng::side_engine_ptr side_engine;
119  config side;
120 
121  // Recruit list with no faction.
122  side.clear();
123  side["recruit"] = "Elvish Archer";
124  side_engine.reset(create_side_engine(side, connect_engine.get()));
125  BOOST_CHECK_EQUAL( side_engine->new_config()["recruit"], "Elvish Archer" );
126 }
127 
128 BOOST_AUTO_TEST_CASE( flg_map_settings3 )
129 {
130  // Set up side_engine and its dependencies.
131  state->mp_settings().use_map_settings = true;
132  state->mp_settings().saved_game = saved_game_mode::type::no;
133  std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
134  ng::side_engine_ptr side_engine;
135  config side;
136 
137  // Custom faction, no recruits.
138  side.clear();
139  side["faction"] = "Custom";
140  side_engine.reset(create_side_engine(side, connect_engine.get()));
141  BOOST_CHECK_EQUAL( side_engine->flg().current_faction()["id"], "Custom" );
142  BOOST_CHECK_EQUAL( side_engine->new_config()["recruit"].empty(), true );
143 }
144 
145 BOOST_AUTO_TEST_CASE( flg_map_settings4 )
146 {
147  // Set up side_engine and its dependencies.
148  state->mp_settings().use_map_settings = true;
149  state->mp_settings().saved_game = saved_game_mode::type::no;
150  std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
151  ng::side_engine_ptr side_engine;
152  config side;
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().current_faction()["id"], "Random" );
159 }
160 
161 BOOST_AUTO_TEST_CASE( flg_map_settings5 )
162 {
163  // Set up side_engine and its dependencies.
164  state->mp_settings().use_map_settings = true;
165  state->mp_settings().saved_game = saved_game_mode::type::no;
166  std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
167  ng::side_engine_ptr side_engine;
168  config side;
169 
170  // Valid faction.
171  side.clear();
172  side["faction"] = "Rebels";
173  side_engine.reset(create_side_engine(side, connect_engine.get()));
174  BOOST_CHECK_EQUAL( side_engine->flg().current_faction()["id"], "Rebels" );
175 }
176 
177 BOOST_AUTO_TEST_CASE( flg_map_settings6 )
178 {
179  // Set up side_engine and its dependencies.
180  state->mp_settings().use_map_settings = true;
181  state->mp_settings().saved_game = saved_game_mode::type::no;
182  std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
183  ng::side_engine_ptr side_engine;
184  config side;
185 
186  // Invalid faction.
187  side.clear();
188  side["faction"] = "ThisFactionDoesNotExist";
189  side_engine.reset(create_side_engine(side, connect_engine.get()));
190  BOOST_CHECK( side_engine->flg().choosable_factions().size() > 1 );
191  BOOST_CHECK_EQUAL( side_engine->flg().current_faction()["id"], "Random" );
192 }
193 
194 BOOST_AUTO_TEST_CASE( flg_map_settings7 )
195 {
196  // Set up side_engine and its dependencies.
197  state->mp_settings().use_map_settings = true;
198  state->mp_settings().saved_game = saved_game_mode::type::no;
199  std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
200  ng::side_engine_ptr side_engine;
201  config side;
202 
203  // Faction and recruit list.
204  side.clear();
205  side["recruit"] = "Elvish Archer";
206  side["faction"] = "Undead";
207  side_engine.reset(create_side_engine(side, connect_engine.get()));
208 }
209 
210 BOOST_AUTO_TEST_CASE( flg_map_settings8 )
211 {
212  // Set up side_engine and its dependencies.
213  state->mp_settings().use_map_settings = true;
214  state->mp_settings().saved_game = saved_game_mode::type::no;
215  std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
216  ng::side_engine_ptr side_engine;
217  config side;
218 
219  // Carried over recruits.
220  side.clear();
221  side["previous_recruits"] = "Elvish Archer";
222  side_engine.reset(create_side_engine(side, connect_engine.get()));
223  BOOST_CHECK_EQUAL( side_engine->new_config()["previous_recruits"], "Elvish Archer" );
224 }
225 
226 BOOST_AUTO_TEST_CASE( flg_map_settings9 )
227 {
228  // Set up side_engine and its dependencies.
229  state->mp_settings().use_map_settings = true;
230  state->mp_settings().saved_game = saved_game_mode::type::no;
231  std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
232  ng::side_engine_ptr side_engine;
233  config side;
234 
235  // Valid leader unit.
236  side = config {
237  "leader", config {
238  "type", "Shadow",
239  },
240  };
241 
242  side_engine.reset(create_side_engine(side, connect_engine.get()));
243  BOOST_CHECK_EQUAL( side_engine->flg().choosable_leaders().size(), 1 );
244  BOOST_CHECK_EQUAL( side_engine->flg().current_leader(), "Shadow" );
245  BOOST_CHECK_EQUAL( side_engine->new_config().mandatory_child("leader")["type"], "Shadow" );
246 }
247 
248 BOOST_AUTO_TEST_CASE( flg_map_settings10 )
249 {
250  // Set up side_engine and its dependencies.
251  state->mp_settings().use_map_settings = true;
252  state->mp_settings().saved_game = saved_game_mode::type::no;
253  std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
254  ng::side_engine_ptr side_engine;
255  config side;
256 
257  // Invalid leader unit.
258  side = config {
259  "leader", config {
260  "type", "ThisUnitDoesNotExist",
261  },
262  };
263 
264  side_engine.reset(create_side_engine(side, connect_engine.get()));
265  BOOST_CHECK_EQUAL( side_engine->flg().choosable_leaders().size(), 1 );
266  BOOST_CHECK_EQUAL( side_engine->flg().current_leader(), "null" );
267 }
268 
269 BOOST_AUTO_TEST_CASE( flg_map_settings11 )
270 {
271  // Set up side_engine and its dependencies.
272  state->mp_settings().use_map_settings = true;
273  state->mp_settings().saved_game = saved_game_mode::type::no;
274  std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
275  ng::side_engine_ptr side_engine;
276  config side;
277 
278  // No leader, Custom faction.
279  side.clear();
280  side["faction"] = "Custom";
281  side_engine.reset(create_side_engine(side, connect_engine.get()));
282  BOOST_CHECK( side_engine->flg().choosable_leaders().size() > 1 );
283  BOOST_CHECK_EQUAL( side_engine->flg().current_leader(), "random" );
284 }
285 
286 BOOST_AUTO_TEST_CASE( flg_map_settings12 )
287 {
288  // Set up side_engine and its dependencies.
289  state->mp_settings().use_map_settings = true;
290  state->mp_settings().saved_game = saved_game_mode::type::no;
291  std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
292  ng::side_engine_ptr side_engine;
293  config side;
294 
295  // No leader, Random faction.
296  side.clear();
297  side["faction"] = "Random";
298  side_engine.reset(create_side_engine(side, connect_engine.get()));
299  BOOST_CHECK_EQUAL( side_engine->flg().choosable_leaders().size(), 1 );
300  BOOST_CHECK_EQUAL( side_engine->flg().current_leader(), "null" );
301 }
302 
303 BOOST_AUTO_TEST_CASE( flg_map_settings13 )
304 {
305  // Set up side_engine and its dependencies.
306  state->mp_settings().use_map_settings = true;
307  state->mp_settings().saved_game = saved_game_mode::type::no;
308  std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
309  ng::side_engine_ptr side_engine;
310  config side;
311 
312 
313 }
314 
315 BOOST_AUTO_TEST_CASE( flg_map_settings14 )
316 {
317  // Set up side_engine and its dependencies.
318  state->mp_settings().use_map_settings = true;
319  state->mp_settings().saved_game = saved_game_mode::type::no;
320  std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
321  ng::side_engine_ptr side_engine;
322  config side;
323 
324  // No leader, regular faction.
325  side.clear();
326  side["faction"] = "Undead";
327  side_engine.reset(create_side_engine(side, connect_engine.get()));
328  BOOST_CHECK( side_engine->flg().choosable_leaders().size() > 1 );
329  BOOST_CHECK_EQUAL( side_engine->flg().current_leader(), "random" );
330 }
331 
332 BOOST_AUTO_TEST_CASE( flg_map_settings15 )
333 {
334  // Set up side_engine and its dependencies.
335  state->mp_settings().use_map_settings = true;
336  state->mp_settings().saved_game = saved_game_mode::type::no;
337  std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
338  ng::side_engine_ptr side_engine;
339  config side;
340 
341  // Carried over leader.
342  side = config {
343  "leader", config {
344  "type", "Elvish Archer",
345  "id", "LeaderID",
346  },
347  "unit", config {
348  "type", "Elvish Ranger",
349  "id", "LeaderID",
350  },
351  };
352 
353  side_engine.reset(create_side_engine(side, connect_engine.get()));
354  BOOST_CHECK_EQUAL( side_engine->flg().choosable_leaders().size(), 1 );
355  BOOST_CHECK_EQUAL( side_engine->flg().current_leader(), "Elvish Ranger" );
356 }
357 
358 BOOST_AUTO_TEST_CASE( flg_map_settings16 )
359 {
360  // Set up side_engine and its dependencies.
361  state->mp_settings().use_map_settings = true;
362  state->mp_settings().saved_game = saved_game_mode::type::no;
363  std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
364  ng::side_engine_ptr side_engine;
365  config side;
366 
367 
368 }
369 
370 BOOST_AUTO_TEST_CASE( flg_map_settings17 )
371 {
372  // Set up side_engine and its dependencies.
373  state->mp_settings().use_map_settings = true;
374  state->mp_settings().saved_game = saved_game_mode::type::no;
375  std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
376  ng::side_engine_ptr side_engine;
377  config side;
378 
379  // Random leader.
380  side = config {
381  "leader", config {
382  "type", "random",
383  },
384  };
385  side_engine.reset(create_side_engine(side, connect_engine.get()));
386  BOOST_CHECK_EQUAL( side_engine->flg().choosable_leaders().size(), 1 );
387 }
388 
389 BOOST_AUTO_TEST_CASE( flg_map_settings18 )
390 {
391  // Set up side_engine and its dependencies.
392  state->mp_settings().use_map_settings = true;
393  state->mp_settings().saved_game = saved_game_mode::type::no;
394  std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
395  ng::side_engine_ptr side_engine;
396  config side;
397 
398  // Leader with both genders.
399  side = config {
400  "leader", config {
401  "type", "Elvish Archer",
402  },
403  };
404  side_engine.reset(create_side_engine(side, connect_engine.get()));
405  BOOST_CHECK_EQUAL( side_engine->flg().choosable_genders().size(), 3 );
406  BOOST_CHECK_EQUAL( side_engine->flg().current_gender(), "random" );
407 }
408 
409 BOOST_AUTO_TEST_CASE( flg_map_settings19 )
410 {
411  // Set up side_engine and its dependencies.
412  state->mp_settings().use_map_settings = true;
413  state->mp_settings().saved_game = saved_game_mode::type::no;
414  std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
415  ng::side_engine_ptr side_engine;
416  config side;
417 
418  // Leader with only male gender.
419  side = config {
420  "leader", config {
421  "type", "Swordsman",
422  },
423  };
424  side_engine.reset(create_side_engine(side, connect_engine.get()));
425  BOOST_CHECK_EQUAL( side_engine->flg().choosable_genders().size(), 1 );
426  BOOST_CHECK_EQUAL( side_engine->flg().current_gender(), "male" );
427 }
428 
429 BOOST_AUTO_TEST_CASE( flg_map_settings20 )
430 {
431  // Set up side_engine and its dependencies.
432  state->mp_settings().use_map_settings = true;
433  state->mp_settings().saved_game = saved_game_mode::type::no;
434  std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
435  ng::side_engine_ptr side_engine;
436  config side;
437 
438  // Leader with only female gender.
439  side = config {
440  "leader", config {
441  "type", "Elvish Druid",
442  },
443  };
444  side_engine.reset(create_side_engine(side, connect_engine.get()));
445  BOOST_CHECK_EQUAL( side_engine->flg().choosable_genders().size(), 1 );
446  BOOST_CHECK_EQUAL( side_engine->flg().current_gender(), "female" );
447 }
448 
449 BOOST_AUTO_TEST_CASE( flg_map_settings21 )
450 {
451  // Set up side_engine and its dependencies.
452  state->mp_settings().use_map_settings = true;
453  state->mp_settings().saved_game = saved_game_mode::type::no;
454  std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
455  ng::side_engine_ptr side_engine;
456  config side;
457 
458  // Valid leader with valid gender.
459  side = config {
460  "leader", config {
461  "type", "White Mage",
462  "gender", "female",
463  },
464  };
465  side_engine.reset(create_side_engine(side, connect_engine.get()));
466  BOOST_CHECK_EQUAL( side_engine->flg().current_gender(), "female" );
467 }
468 
469 BOOST_AUTO_TEST_CASE( flg_map_settings22 )
470 {
471  // Set up side_engine and its dependencies.
472  state->mp_settings().use_map_settings = true;
473  state->mp_settings().saved_game = saved_game_mode::type::no;
474  std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
475  ng::side_engine_ptr side_engine;
476  config side;
477 
478  // Valid leader with invalid gender.
479  side = config {
480  "leader", config {
481  "type", "Troll",
482  "gender", "female",
483  },
484  };
485  side_engine.reset(create_side_engine(side, connect_engine.get()));
486  BOOST_CHECK_EQUAL( side_engine->flg().choosable_genders().size(), 1 );
487  BOOST_CHECK_EQUAL( side_engine->flg().current_gender(), "male" );
488 }
489 
490 BOOST_AUTO_TEST_CASE( flg_map_settings23 )
491 {
492  // Set up side_engine and its dependencies.
493  state->mp_settings().use_map_settings = true;
494  state->mp_settings().saved_game = saved_game_mode::type::no;
495  std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
496  ng::side_engine_ptr side_engine;
497  config side;
498 
499  // Leader with random gender.
500  side = config {
501  "leader", config {
502  "type", "White Mage",
503  "gender", "random",
504  },
505  };
506  side_engine.reset(create_side_engine(side, connect_engine.get()));
507  BOOST_CHECK_EQUAL( side_engine->flg().current_gender(), "random" );
508 }
509 
510 BOOST_AUTO_TEST_CASE( flg_map_settings24 )
511 {
512  // Set up side_engine and its dependencies.
513  state->mp_settings().use_map_settings = true;
514  state->mp_settings().saved_game = saved_game_mode::type::no;
515  std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
516  ng::side_engine_ptr side_engine;
517  config side;
518 
519 
520 }
521 
522 BOOST_AUTO_TEST_CASE( flg_map_settings25 )
523 {
524  // Set up side_engine and its dependencies.
525  state->mp_settings().use_map_settings = true;
526  state->mp_settings().saved_game = saved_game_mode::type::no;
527  std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
528  ng::side_engine_ptr side_engine;
529  config side;
530 
531  // No leader.
532  side.clear();
533  side["leader_lock"] = true;
534  side_engine.reset(create_side_engine(side, connect_engine.get()));
535  BOOST_CHECK_EQUAL( side_engine->flg().choosable_leaders().size(), 1 );
536  BOOST_CHECK_EQUAL( side_engine->flg().current_leader(), "null" );
537 }
538 
539 BOOST_AUTO_TEST_CASE( flg_map_settings26 )
540 {
541  // Set up side_engine and its dependencies.
542  state->mp_settings().use_map_settings = true;
543  state->mp_settings().saved_game = saved_game_mode::type::no;
544  std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
545  ng::side_engine_ptr side_engine;
546  config side;
547 
548  // Resolve random faction.
549  side.clear();
550  side["faction"] = "Random";
551  side_engine.reset(create_side_engine(side, connect_engine.get()));
552  side_engine->resolve_random(*rng);
553  BOOST_CHECK( side_engine->flg().current_faction()["id"] != "Random" );
554  BOOST_CHECK( side_engine->flg().current_leader() != "random" && side_engine->flg().current_leader() != "null");
555  BOOST_CHECK( side_engine->flg().current_gender() != "random" && side_engine->flg().current_gender() != "null");
556 }
557 
558 BOOST_AUTO_TEST_CASE( flg_map_settings27 )
559 {
560  // Set up side_engine and its dependencies.
561  state->mp_settings().use_map_settings = true;
562  state->mp_settings().saved_game = saved_game_mode::type::no;
563  std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
564  ng::side_engine_ptr side_engine;
565  config side;
566 
567  // Resolve random faction with default leader.
568  side = config {
569  "faction" , "Random",
570  "leader", config {
571  "type", "Troll",
572  },
573  };
574  side_engine.reset(create_side_engine(side, connect_engine.get()));
575  side_engine->resolve_random(*rng);
576  BOOST_CHECK( side_engine->flg().current_faction()["id"] != "Random" );
577  BOOST_CHECK_EQUAL( side_engine->flg().current_leader(), "Troll" );
578  BOOST_CHECK( side_engine->flg().current_gender() != "random" && side_engine->flg().current_gender() != "null" );
579 }
580 
581 BOOST_AUTO_TEST_CASE( flg_map_settings28 )
582 {
583  // Set up side_engine and its dependencies.
584  state->mp_settings().use_map_settings = true;
585  state->mp_settings().saved_game = saved_game_mode::type::no;
586  std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
587  ng::side_engine_ptr side_engine;
588  config side;
589 
590  // Resolve random faction with default leader and gender.
591  side = config {
592  "faction" , "Random",
593  "leader", config {
594  "type", "White Mage",
595  "gender", "male",
596  },
597  };
598  side_engine.reset(create_side_engine(side, connect_engine.get()));
599  side_engine->resolve_random(*rng);
600  BOOST_CHECK( side_engine->flg().current_faction()["id"] != "Random" );
601  BOOST_CHECK_EQUAL( side_engine->flg().current_leader(), "White Mage" );
602  BOOST_CHECK_EQUAL( side_engine->flg().current_gender(), "male" );
603 }
604 
605 BOOST_AUTO_TEST_CASE( flg_map_settings29 )
606 {
607  // Set up side_engine and its dependencies.
608  state->mp_settings().use_map_settings = true;
609  state->mp_settings().saved_game = saved_game_mode::type::no;
610  std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
611  ng::side_engine_ptr side_engine;
612  config side;
613 
614  // Resolve random leader.
615  side = config {
616  "leader", config {
617  "type", "random",
618  },
619  };
620  side_engine.reset(create_side_engine(side, connect_engine.get()));
621  side_engine->resolve_random(*rng);
622  BOOST_CHECK( side_engine->flg().current_leader() != "random" );
623 }
624 
625 
626 
627 
628 
629 BOOST_AUTO_TEST_CASE( flg_no_map_settings1 )
630 {
631  // Set up side_engine and its dependencies.
632  state->mp_settings().use_map_settings = false;
633  state->mp_settings().saved_game = saved_game_mode::type::no;
634  const std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
635  ng::side_engine_ptr side_engine;
636  config side;
637 
638  // Recruit list with no faction.
639  side.clear();
640  side["recruit"] = "Elvish Archer";
641  side_engine.reset(create_side_engine(side, connect_engine.get()));
642  BOOST_CHECK( side_engine->flg().choosable_factions().size() > 1 );
643 }
644 
645 BOOST_AUTO_TEST_CASE( flg_no_map_settings2 )
646 {
647  // Set up side_engine and its dependencies.
648  state->mp_settings().use_map_settings = false;
649  state->mp_settings().saved_game = saved_game_mode::type::no;
650  const std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
651  ng::side_engine_ptr side_engine;
652  config side;
653 
654  // Custom faction, no recruits.
655  side.clear();
656  side["faction"] = "Custom";
657  side_engine.reset(create_side_engine(side, connect_engine.get()));
658  BOOST_CHECK( side_engine->flg().choosable_factions().size() > 1 );
659  BOOST_CHECK_EQUAL( side_engine->flg().current_faction()["id"], "Custom" );
660  BOOST_CHECK_EQUAL( side_engine->new_config()["recruit"].empty(), true );
661 }
662 
663 BOOST_AUTO_TEST_CASE( flg_no_map_settings3 )
664 {
665  // Set up side_engine and its dependencies.
666  state->mp_settings().use_map_settings = false;
667  state->mp_settings().saved_game = saved_game_mode::type::no;
668  const std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
669  ng::side_engine_ptr side_engine;
670  config side;
671 
672  // Carried over recruits.
673  side.clear();
674  side["previous_recruits"] = "Elvish Archer";
675  side_engine.reset(create_side_engine(side, connect_engine.get()));
676  BOOST_CHECK( side_engine->flg().choosable_factions().size() > 1 );
677  BOOST_CHECK_EQUAL( side_engine->new_config()["previous_recruits"], "Elvish Archer" );
678 }
679 
680 BOOST_AUTO_TEST_CASE( flg_no_map_settings4 )
681 {
682  // Set up side_engine and its dependencies.
683  state->mp_settings().use_map_settings = false;
684  state->mp_settings().saved_game = saved_game_mode::type::no;
685  const std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
686  ng::side_engine_ptr side_engine;
687  config side;
688 
689  // Explicit leader for faction with multiple leaders.
690  side = config {
691  "leader", config {
692  "type", "Goblin Impaler",
693  },
694  };
695  side_engine.reset(create_side_engine(side, connect_engine.get()));
696  side_engine->flg().set_current_faction("Rebels");
697  BOOST_CHECK( side_engine->flg().choosable_leaders().size() > 1 );
698 }
699 
700 BOOST_AUTO_TEST_CASE( flg_no_map_settings5 )
701 {
702  // Set up side_engine and its dependencies.
703  state->mp_settings().use_map_settings = false;
704  state->mp_settings().saved_game = saved_game_mode::type::no;
705  const std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
706  ng::side_engine_ptr side_engine;
707  config side;
708 
709  // Duplicate leaders.
710  side = config {
711  "faction" , "Custom",
712  "leader", config {
713  "type", "Swordsman",
714  },
715  };
716  side_engine.reset(create_side_engine(side, connect_engine.get()));
717  BOOST_CHECK( side_engine->flg().choosable_leaders().size() > 1 );
718  const std::vector<std::string>& leaders = side_engine->flg().choosable_leaders();
719  BOOST_CHECK_EQUAL( std::count(leaders.begin(), leaders.end(), "Swordsman"), 1 );
720 }
721 
722 BOOST_AUTO_TEST_CASE( flg_no_map_settings6 )
723 {
724  // Set up side_engine and its dependencies.
725  state->mp_settings().use_map_settings = false;
726  state->mp_settings().saved_game = saved_game_mode::type::no;
727  const std::unique_ptr<test_connect_engine> connect_engine(create_test_connect_engine());
728  ng::side_engine_ptr side_engine;
729  config side;
730 
731  // Explicit gender for unit with both genders available.
732  side = config {
733  "leader", config {
734  "gender", "female",
735  },
736  };
737  side_engine.reset(create_side_engine(side, connect_engine.get()));
738  side_engine->flg().set_current_faction("Rebels");
739  side_engine->flg().set_current_leader("Elvish Ranger");
740  // TODO: this this really make sense? it would be nice to know the usecases for this.
741  //BOOST_CHECK_EQUAL( side_engine->flg().current_gender(), "random" );
742 }
743 
744 BOOST_AUTO_TEST_SUITE_END()
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:158
void append(const config &cfg)
Append data from another config object to this one.
Definition: config.cpp:188
void remove_attributes(T... keys)
Definition: config.hpp:537
config & mandatory_child(config_key_type key, int n=0)
Returns the nth child with the given key, or throws an error if there is none.
Definition: config.cpp:362
void clear_children(T... keys)
Definition: config.hpp:602
void clear()
Definition: config.cpp:824
const attribute_value * get(config_key_type key) const
Returns a pointer to the attribute with the given key or nullptr if it does not exist.
Definition: config.cpp:681
@ NO_FORCE_RELOAD
Don't reload if the previous defines equal the new defines.
this class is initialized once at game start put all initialization and wipe code in the methods here...
connect_engine(saved_game &state, const bool first_scenario, mp_game_metadata *metadata)
test_connect_engine(saved_game &gamestate)
std::shared_ptr< side_engine > side_engine_ptr
game_display & get_fake_display(const int width, const int height)
Gets a fake test display.
std::vector< std::string > dummy_args
hotkey::manager hotkey_manager
commandline_options cmdline_opts
std::unique_ptr< game_config_manager > config_manager
BOOST_FIXTURE_TEST_SUITE(test_map_location, MLFixture)
static ng::side_engine * create_side_engine(const config &defaults, test_connect_engine *connect_engine)
static test_connect_engine * create_test_connect_engine()
BOOST_AUTO_TEST_CASE(flg_map_settings2)