The Battle for Wesnoth  1.17.10+dev
test_gui2.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2022
3  by Mark de Wever <koraq@xs4all.nl>
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 // In this domain since it compares a shared string from this domain.
17 #define GETTEXT_DOMAIN "wesnoth-lib"
18 
19 #include "addon/client.hpp"
20 #include "addon/info.hpp"
21 #include "config_cache.hpp"
22 #include "filesystem.hpp"
23 #include "formula/debugger.hpp"
24 #include "game_config.hpp"
25 #include "game_config_view.hpp"
26 #include "game_display.hpp"
27 #include "game_events/manager.hpp"
31 #include "game_launcher.hpp"
33 #include "gettext.hpp"
43 #include "gui/dialogs/chat_log.hpp"
76 #include "gui/dialogs/message.hpp"
90 #include "gui/dialogs/outro.hpp"
101 #include "gui/dialogs/tooltip.hpp"
106 #include "gui/dialogs/unit_list.hpp"
109 #include "gui/dialogs/wml_error.hpp"
111 #include "gui/widgets/settings.hpp"
112 #include "gui/widgets/window.hpp"
113 #include "language.hpp"
114 #include "map/map.hpp"
115 #include "replay.hpp"
116 #include "save_index.hpp"
117 #include "saved_game.hpp"
119 #include "terrain/type_data.hpp"
121 #include "utils/general.hpp"
122 #include "wesnothd_connection.hpp"
123 #include "wml_exception.hpp"
124 
125 #include <boost/test/unit_test.hpp>
126 
127 #include <functional>
128 #include <memory>
129 
130 using namespace gui2::dialogs;
131 
134  {
135  /** The main config, which contains the entire WML tree. */
136  game_config_view game_config_view_ = game_config_view::wrap(main_config);
137 
139 
140  cache.clear_defines();
141  cache.add_define("EDITOR");
142  cache.add_define("MULTIPLAYER");
143  cache.get_config(game_config::path +"/data", main_config);
144 
145  const filesystem::binary_paths_manager bin_paths_manager(game_config_view_);
146 
148  game_config::load_config(main_config.child("game_config"));
149  }
151  {
152  }
154  static const std::string widgets_file;
155 };
157 const std::string test_gui2_fixture::widgets_file = "widgets_tested.log";
158 
159 namespace gui2 {
160 
161 namespace dialogs {
162 
163 std::string get_modal_dialog_id(const modal_dialog& dialog)
164 {
165  return dialog.window_id();
166 }
167 
168 std::string get_modeless_dialog_id(const modeless_dialog& dialog)
169 {
170  return dialog.window_id();
171 }
172 
173 } // namespace dialogs
174 } // namespace gui2
175 
176 namespace {
177 
178  /**
179  * Helper class to generate a dialog.
180  *
181  * This class makes sure the dialog is properly created and initialized.
182  * The specialized versions are at the end of this file.
183  */
184  template<class T>
185  struct dialog_tester
186  {
187  T* create() { return new T(); }
188  };
189 
190  typedef std::pair<unsigned, unsigned> resolution;
191  typedef std::vector<std::pair<unsigned, unsigned>> resolution_list;
192 
193  template<class T>
194  void test_resolutions(const resolution_list& resolutions)
195  {
196  for(const resolution& resolution : resolutions) {
197  test_utils::get_fake_display(resolution.first, resolution.second);
198 
199  dialog_tester<T> ctor;
200  const std::unique_ptr<modal_dialog> dlg(ctor.create());
201  BOOST_REQUIRE_MESSAGE(dlg.get(), "Failed to create a dialog.");
202 
203  std::string id = get_modal_dialog_id(*dlg.get());
204  filesystem::write_file(test_gui2_fixture::widgets_file, ","+id, std::ios_base::app);
205 
206  std::string exception;
207  try {
208  dlg->show(1);
209  } catch(const gui2::layout_exception_width_modified&) {
210  exception = "gui2::layout_exception_width_modified";
212  exception = "gui2::layout_exception_width_resize_failed";
214  exception = "gui2::layout_exception_height_resize_failed";
215  } catch(const wml_exception& e) {
216  exception = e.dev_message;
217  } catch(const std::exception& e) {
218  exception = e.what();
219  } catch(...) {
220  exception = utils::get_unknown_exception_type();
221  }
222  BOOST_CHECK_MESSAGE(exception.empty(),
223  "Test for '" << id
224  << "' Failed\nnew widgets = " << gui2::new_widgets
225  << " resolution = " << resolution.first
226  << 'x' << resolution.second
227  << "\nException caught: " << exception << '.');
228  }
229  }
230 
231  template<class T>
232  void test_popup_resolutions(const resolution_list& resolutions)
233  {
234  bool interact = false;
235  for(int i = 0; i < 2; ++i) {
236  for(const resolution& resolution : resolutions) {
237  // debug clock doesn't work at 800x600
238  if(resolution.first == 800 && resolution.second == 600) {
239  continue;
240  }
241  test_utils::get_fake_display(resolution.first, resolution.second);
242 
243  dialog_tester<T> ctor;
244  const std::unique_ptr<modeless_dialog> dlg(ctor.create());
245  BOOST_REQUIRE_MESSAGE(dlg.get(), "Failed to create a dialog.");
246 
247  std::string id = get_modeless_dialog_id(*dlg.get());
248  filesystem::write_file(test_gui2_fixture::widgets_file, ","+id, std::ios_base::app);
249 
250  std::string exception;
251  try {
252  dlg->show(interact);
253  gui2::window* window = dlg.get();
254  BOOST_REQUIRE_NE(window, static_cast<void*>(nullptr));
255  window->draw();
256  } catch(const gui2::layout_exception_width_modified&) {
257  exception = "gui2::layout_exception_width_modified";
259  exception = "gui2::layout_exception_width_resize_failed";
261  exception = "gui2::layout_exception_height_resize_failed";
262  } catch(const wml_exception& e) {
263  exception = e.dev_message;
264  } catch(const std::exception& e) {
265  exception = e.what();
266  } catch(...) {
267  exception = utils::get_unknown_exception_type();
268  }
269  BOOST_CHECK_MESSAGE(exception.empty(),
270  "Test for '" << id
271  << "' Failed\nnew widgets = " << gui2::new_widgets
272  << " resolution = " << resolution.first
273  << 'x' << resolution.second
274  << "\nException caught: " << exception << '.');
275  }
276 
277  interact = true;
278  }
279  }
280 
281 #ifdef _MSC_VER
282 #pragma warning(push)
283 #pragma warning(disable: 4702)
284 #endif
285  void test_tip_resolutions(const resolution_list& resolutions
286  , const std::string& id)
287  {
288  for(const auto& resolution : resolutions) {
289  test_utils::get_fake_display(resolution.first, resolution.second);
290 
291  filesystem::write_file(test_gui2_fixture::widgets_file, ","+id, std::ios_base::app);
292 
293  std::string exception;
294  try {
295  tip::show(id
296  , "Test message for a tooltip."
297  , point(0, 0)
298  , {0,0,0,0});
299  tip::remove();
300  } catch(const gui2::layout_exception_width_modified&) {
301  exception = "gui2::layout_exception_width_modified";
303  exception = "gui2::layout_exception_width_resize_failed";
305  exception = "gui2::layout_exception_height_resize_failed";
306  } catch(const wml_exception& e) {
307  exception = e.dev_message;
308  } catch(const std::exception& e) {
309  exception = e.what();
310  } catch(...) {
311  exception = utils::get_unknown_exception_type();
312  }
313  BOOST_CHECK_MESSAGE(exception.empty(),
314  "Test for tip '" << id
315  << "' Failed\nnew widgets = " << gui2::new_widgets
316  << " resolution = " << resolution.first
317  << 'x' << resolution.second
318  << "\nException caught: " << exception << '.');
319  }
320  }
321 #ifdef _MSC_VER
322 #pragma warning(pop)
323 #endif
324 
325 const resolution_list& get_gui_resolutions()
326 {
327  static resolution_list result {
328  {800, 600},
329  {1024, 768},
330  {1280, 1024},
331  {1680, 1050},
332  };
333 
334  return result;
335 }
336 
337 template<class T>
338 void test()
339 {
340  gui2::new_widgets = false;
341 
342 // for(std::size_t i = 0; i < 2; ++i) {
343 
344  test_resolutions<T>(get_gui_resolutions());
345 
346 // break; // FIXME: New widgets break
347 // gui2::new_widgets = true;
348 // }
349 }
350 
351 template<class T>
352 void test_popup()
353 {
354  gui2::new_widgets = false;
355 
356  for(std::size_t i = 0; i < 2; ++i) {
357 
358  test_popup_resolutions<T>(get_gui_resolutions());
359 
360  gui2::new_widgets = true;
361  }
362 }
363 
364 void test_tip(const std::string& id)
365 {
366  gui2::new_widgets = false;
367 
368  for(std::size_t i = 0; i < 2; ++i) {
369 
370  test_tip_resolutions(get_gui_resolutions(), id);
371 
372  gui2::new_widgets = true;
373  }
374 }
375 
376 } // namespace
377 
379 
380 BOOST_AUTO_TEST_CASE(modal_dialog_test_addon_auth)
381 {
382  test<addon_auth>();
383 }
384 BOOST_AUTO_TEST_CASE(modal_dialog_test_addon_connect)
385 {
386  test<addon_connect>();
387 }
388 BOOST_AUTO_TEST_CASE(modal_dialog_test_addon_license_prompt)
389 {
390  test<addon_license_prompt>();
391 }
392 BOOST_AUTO_TEST_CASE(modal_dialog_test_campaign_difficulty)
393 {
394  test<campaign_difficulty>();
395 }
396 BOOST_AUTO_TEST_CASE(modal_dialog_test_chat_log)
397 {
398  test<chat_log>();
399 }
400 BOOST_AUTO_TEST_CASE(modal_dialog_test_core_selection)
401 {
402  test<core_selection>();
403 }
404 BOOST_AUTO_TEST_CASE(modal_dialog_test_custom_tod)
405 {
406  test<custom_tod>();
407 }
408 BOOST_AUTO_TEST_CASE(modal_dialog_test_depcheck_confirm_change)
409 {
410  test<depcheck_confirm_change>();
411 }
412 BOOST_AUTO_TEST_CASE(modal_dialog_test_depcheck_select_new)
413 {
414  test<depcheck_select_new>();
415 }
416 BOOST_AUTO_TEST_CASE(modal_dialog_test_edit_label)
417 {
418  test<edit_label>();
419 }
420 BOOST_AUTO_TEST_CASE(modal_dialog_test_edit_text)
421 {
422  test<edit_text>();
423 }
424 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_edit_label)
425 {
426  test<editor_edit_label>();
427 }
428 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_edit_side)
429 {
430  test<editor_edit_side>();
431 }
432 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_edit_scenario)
433 {
434  test<editor_edit_scenario>();
435 }
436 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_generate_map)
437 {
438  test<editor_generate_map>();
439 }
440 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_new_map)
441 {
442  test<editor_new_map>();
443 }
444 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_resize_map)
445 {
446  test<editor_resize_map>();
447 }
448 BOOST_AUTO_TEST_CASE(modal_dialog_test_faction_select)
449 {
450  test<faction_select>();
451 }
452 BOOST_AUTO_TEST_CASE(modal_dialog_test_file_dialog)
453 {
454  test<file_dialog>();
455 }
456 BOOST_AUTO_TEST_CASE(modal_dialog_test_folder_create)
457 {
458  test<folder_create>();
459 }
460 BOOST_AUTO_TEST_CASE(modal_dialog_test_formula_debugger)
461 {
462  test<formula_debugger>();
463 }
464 BOOST_AUTO_TEST_CASE(modal_dialog_test_game_cache_options)
465 {
466  test<game_cache_options>();
467 }
468 BOOST_AUTO_TEST_CASE(modal_dialog_test_game_delete)
469 {
470  test<game_delete>();
471 }
472 BOOST_AUTO_TEST_CASE(modal_dialog_test_game_version)
473 {
474  test<game_version>();
475 }
476 BOOST_AUTO_TEST_CASE(modal_dialog_test_game_save)
477 {
478  test<game_save>();
479 }
480 BOOST_AUTO_TEST_CASE(modal_dialog_test_game_save_message)
481 {
482  test<game_save_message>();
483 }
484 BOOST_AUTO_TEST_CASE(modal_dialog_test_game_save_oos)
485 {
486  test<game_save_oos>();
487 }
488 BOOST_AUTO_TEST_CASE(modal_dialog_test_generator_settings)
489 {
490  test<generator_settings>();
491 }
492 BOOST_AUTO_TEST_CASE(modal_dialog_test_hotkey_bind)
493 {
494  test<hotkey_bind>();
495 }
496 BOOST_AUTO_TEST_CASE(modal_dialog_test_install_dependencies)
497 {
498  test<install_dependencies>();
499 }
500 BOOST_AUTO_TEST_CASE(modal_dialog_test_language_selection)
501 {
502  test<language_selection>();
503 }
504 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_lobby)
505 {
506  test<mp_lobby>();
507 }
508 BOOST_AUTO_TEST_CASE(modal_dialog_test_lobby_player_info)
509 {
510  test<lobby_player_info>();
511 }
512 BOOST_AUTO_TEST_CASE(modal_dialog_test_log_settings)
513 {
514  test<log_settings>();
515 }
516 BOOST_AUTO_TEST_CASE(modal_dialog_test_message)
517 {
518  test<message>();
519 }
520 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_alerts_options)
521 {
522  test<mp_alerts_options>();
523 }
524 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_connect)
525 {
526  test<mp_connect>();
527 }
528 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_join_game_password_prompt)
529 {
530  test<mp_join_game_password_prompt>();
531 }
532 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_login)
533 {
534  test<mp_login>();
535 }
536 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_method_selection)
537 {
538  test<mp_method_selection>();
539 }
540 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_report)
541 {
542  test<mp_report>();
543 }
544 BOOST_AUTO_TEST_CASE(modal_dialog_test_simple_item_selector)
545 {
546  test<simple_item_selector>();
547 }
548 BOOST_AUTO_TEST_CASE(modal_dialog_test_screenshot_notification)
549 {
550  test<screenshot_notification>();
551 }
552 BOOST_AUTO_TEST_CASE(modal_dialog_test_select_orb_colors)
553 {
554  test<select_orb_colors>();
555 }
556 BOOST_AUTO_TEST_CASE(modal_dialog_test_statistics_dialog)
557 {
558  test<statistics_dialog>();
559 }
560 BOOST_AUTO_TEST_CASE(modal_dialog_test_surrender_quit)
561 {
562  test<surrender_quit>();
563 }
564 BOOST_AUTO_TEST_CASE(modal_dialog_test_theme_list)
565 {
566  test<theme_list>();
567 }
568 BOOST_AUTO_TEST_CASE(modal_dialog_test_transient_message)
569 {
570  test<transient_message>();
571 }
572 BOOST_AUTO_TEST_CASE(modal_dialog_test_unit_create)
573 {
574  test<unit_create>();
575 }
576 BOOST_AUTO_TEST_CASE(modal_dialog_test_wml_error)
577 {
578  test<wml_error>();
579 }
580 BOOST_AUTO_TEST_CASE(modal_dialog_test_wml_message_left)
581 {
582  test<wml_message_left>();
583 }
584 BOOST_AUTO_TEST_CASE(modal_dialog_test_wml_message_right)
585 {
586  test<wml_message_right>();
587 }
588 BOOST_AUTO_TEST_CASE(modal_dialog_test_wml_message_double)
589 {
590  test<wml_message_double>();
591 }
592 BOOST_AUTO_TEST_CASE(modeless_dialog_test_debug_clock)
593 {
594  test_popup<debug_clock>();
595 }
596 BOOST_AUTO_TEST_CASE(tooltip_test_tooltip_large)
597 {
598  test_tip("tooltip_large");
599 }
600 BOOST_AUTO_TEST_CASE(tooltip_test_tooltip)
601 {
602  test_tip("tooltip");
603 }
604 
605 // execute last - checks that there aren't any unaccounted for GUIs
607 {
608  std::set<std::string> widget_list = gui2::registered_window_types();
609  std::vector<std::string> widgets_tested = utils::split(filesystem::read_file(test_gui2_fixture::widgets_file));
610  std::set<std::string> omitted {
611  /*
612  * The unit attack unit test are disabled for now, they calling parameters
613  * don't allow 'nullptr's needs to be fixed.
614  */
615  "unit_attack",
616  // No test for this right now, not sure how to use the test system
617  // for dialog with no default constructor
618  "lua_interpreter",
619  /*
620  * Disable label settings dialog test because we need a display_context
621  * object, which we don't have, and it's a lot of work to produce a dummy
622  * one.
623  */
624  "label_settings",
625  "addon_uninstall_list",
626  "addon_manager",
627  "loading_screen",
628  "network_transmission",
629  "synched_choice_wait",
630  "drop_down_menu",
631  "preferences_dialog",
632  "unit_recruit",
633  "unit_recall",
634  "unit_list",
635  "unit_advance",
636  "mp_host_game_prompt",
637  "mp_create_game",
638  // The title screen appears to be throwing a bad_alloc on Travis, so disable it for now
639  "title_screen",
640  "end_credits",
641  "mp_staging",
642  "mp_join_game",
643  "terrain_layers",
644  "attack_predictions",
645  "help_browser",
646  "story_viewer",
647  "outro",
648  "mp_change_control", // Basically useless without a game_board object, so disabling
649  "game_stats", // segfault with LTO
650  "gamestate_inspector", // segfault with LTO
651  "server_info",
652  "sp_options_configure",// segfault with LTO
653  "campaign_selection",// segfault with LTO
654  "game_load",// segfault after disabling the above tests
655  "file_progress",
656  };
658 
659  for(const std::string& item : widgets_tested)
660  {
661  widget_list.erase(item);
662  PLAIN_LOG << "Checking widget " << item;
663  BOOST_CHECK_EQUAL(omitted.count(item), 0);
664  }
665  for(const std::string& item : omitted)
666  {
667  widget_list.erase(item);
668  }
669 
670  // Test size() instead of empty() to get the number of offenders
671  BOOST_CHECK_EQUAL(widget_list.size(), 0);
672  for(const std::string& id : widget_list) {
673  PLAIN_LOG << "Window '" << id << "' registered but not tested.";
674  }
675 }
676 
677 BOOST_AUTO_TEST_CASE(test_make_test_fake)
678 {
680 
681  try {
682  message dlg("title", "message", true, false, false);
683  dlg.show(1);
684  } catch(const wml_exception& e) {
685  BOOST_CHECK(e.user_message == _("Failed to show a dialog, which doesn't fit on the screen."));
686  return;
687  } catch(...) {
688  BOOST_ERROR("Didn't catch the wanted exception, instead caught " << utils::get_unknown_exception_type() << ".");
689  }
690  BOOST_ERROR("Didn't catch the wanted exception, instead caught nothing.");
691 }
692 
693 BOOST_AUTO_TEST_SUITE_END()
694 
695 namespace {
696 
697 template<>
698 struct dialog_tester<addon_auth>
699 {
700  config cfg;
701  addon_auth* create()
702  {
703  return new addon_auth(cfg);
704  }
705 };
706 
707 template<>
708 struct dialog_tester<addon_connect>
709 {
710  std::string host_name = "host_name";
711  addon_connect* create()
712  {
713  return new addon_connect(host_name, true);
714  }
715 };
716 
717 template<>
718 struct dialog_tester<addon_license_prompt>
719 {
720  std::string license_terms = R"""(Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis ante nibh, dignissim ullamcorper tristique eget, condimentum sit amet enim. Aenean dictum pulvinar lacinia. Etiam eleifend, leo sed efficitur consectetur, augue nulla ornare lectus, vitae molestie lacus risus vitae libero. Quisque odio nunc, porttitor eget fermentum sit amet, faucibus eu risus. Praesent sit amet lacus tortor. Suspendisse volutpat quam vitae ipsum fermentum, in vulputate metus egestas. Nulla id consequat ex. Nulla ac dignissim nisl, nec euismod lectus. Duis vitae dolor ornare, convallis justo in, porta dui.
721 
722 Sed faucibus nibh sit amet ligula porta, non malesuada nibh tristique. Maecenas aliquam diam non eros convallis mattis. Proin rhoncus condimentum leo, sed condimentum magna. Phasellus cursus condimentum lacus, sed sodales lacus. Sed pharetra dictum metus, eget dictum nibh lobortis imperdiet. Nunc tempus sollicitudin bibendum. In porttitor interdum orci. Curabitur vitae nibh vestibulum, condimentum lectus quis, condimentum dui. In quis cursus nisl. Maecenas semper neque eu ipsum aliquam, id porta ligula lacinia. Integer sed blandit ex, eu accumsan magna.)""";
723  addon_license_prompt* create()
724  {
725  return new addon_license_prompt(license_terms);
726  }
727 };
728 
729 template<>
730 struct dialog_tester<addon_manager>
731 {
732  dialog_tester()
733  {
735  }
736  addon_manager* create()
737  {
738  addons_client client("localhost:15999");
739  return new addon_manager(client);
740  }
741 };
742 
743 template<>
744 struct dialog_tester<campaign_difficulty>
745 {
746  campaign_difficulty* create()
747  {
748  const config items("difficulty");
749 
750  return new campaign_difficulty(items);
751  }
752 };
753 
754 template<>
755 struct dialog_tester<campaign_selection>
756 {
757  saved_game state;
759  dialog_tester() : state(config {"campaign_type", "scenario"}), ng(state)
760  {
761  }
762  campaign_selection* create()
763  {
764  return new campaign_selection(ng);
765  }
766 };
767 
768 template<>
769 struct dialog_tester<chat_log>
770 {
771  config cfg;
772  vconfig vcfg;
773  replay_recorder_base rbase;
774  replay r;
775  dialog_tester() : vcfg(cfg), r(rbase) {}
776  chat_log* create()
777  {
778  return new chat_log(vcfg, r);
779  }
780 };
781 
782 template<>
783 struct dialog_tester<core_selection>
784 {
785  std::vector<config> cores;
786  dialog_tester()
787  {
788  cores.resize(1);
789  }
790  core_selection* create()
791  {
792  return new core_selection(cores, 0);
793  }
794 };
795 
796 template<>
797 struct dialog_tester<custom_tod>
798 {
799  std::vector<time_of_day> times;
800  int current_tod = 0;
801  dialog_tester()
802  {
803  times.resize(1);
804  }
805  custom_tod* create()
806  {
807  return new custom_tod(times, current_tod);
808  }
809 };
810 
811 template<>
812 struct dialog_tester<edit_label>
813 {
814  std::string label = "Label text to modify";
815  bool team_only = false;
816  edit_label* create()
817  {
818  return new edit_label(label, team_only);
819  }
820 };
821 
822 template<>
823 struct dialog_tester<edit_text>
824 {
825  std::string text = "text to modify";
826  edit_text* create()
827  {
828  return new edit_text("title", "label", text);
829  }
830 };
831 
832 template<>
833 struct dialog_tester<editor_edit_label>
834 {
835  std::string label = "Label text to modify";
836  std::string category = "test";
837  bool immutable = false, fog = false, shroud = false;
838  color_t color;
839  editor_edit_label* create()
840  {
841  return new editor_edit_label(label, immutable, fog, shroud, color, category);
842  }
843 };
844 
845 template<>
846 struct dialog_tester<editor_edit_scenario>
847 {
848  std::string id, name, descr;
849  int turns = 0, xp_mod = 50;
850  bool defeat_enemies = false, random_start = false;
851  editor_edit_scenario* create()
852  {
853  return new editor_edit_scenario(id, name, descr, turns, xp_mod, defeat_enemies, random_start);
854  }
855 };
856 
857 template<>
858 struct dialog_tester<editor_edit_side>
859 {
860  team t;
862  dialog_tester() : info(t) {}
863  editor_edit_side* create()
864  {
865  return new editor_edit_side(info);
866  }
867 };
868 
869 template<>
870 struct dialog_tester<formula_debugger>
871 {
872  wfl::formula_debugger debugger;
873  formula_debugger* create()
874  {
875  return new formula_debugger(debugger);
876  }
877 };
878 
879 template<>
880 struct dialog_tester<game_load>
881 {
882  config cfg;
883  game_config_view view;
884  // It would be good to have a test directory instead of using the same directory as the player,
885  // however this code will support that - default_saves_dir() will respect --userdata-dir.
887  dialog_tester()
888  {
889  /** @todo Would be nice to add real data to the config. */
890  }
891  game_load* create()
892  {
893  view = game_config_view::wrap(cfg);
894  return new game_load(view, data);
895  }
896 
897 };
898 
899 template<>
900 struct dialog_tester<game_save>
901 {
902  std::string title = "Title";
903  std::string filename = "filename";
904  game_save* create()
905  {
906  return new game_save(title, filename);
907  }
908 
909 };
910 
911 template<>
912 struct dialog_tester<game_save_message>
913 {
914  std::string title = "Title";
915  std::string filename = "filename";
916  std::string message = "message";
917  game_save_message* create()
918  {
919  return new game_save_message(title, filename, message);
920  }
921 
922 };
923 
924 template<>
925 struct dialog_tester<game_save_oos>
926 {
927  bool ignore_all = false;
928  std::string title = "Title";
929  std::string filename = "filename";
930  std::string message = "message";
931  game_save_oos* create()
932  {
933  return new game_save_oos(ignore_all, title, filename, message);
934  }
935 
936 };
937 
938 template<>
939 struct dialog_tester<install_dependencies>
940 {
941  addons_list addons;
942  install_dependencies* create()
943  {
944  return new install_dependencies(addons);
945  }
946 };
947 
948 template<>
949 struct dialog_tester<hotkey_bind>
950 {
951  std::string id = "";
952 
953  hotkey_bind* create()
954  {
955  return new hotkey_bind(id);
956  }
957 };
958 
959 template<>
960 struct dialog_tester<mp_lobby>
961 {
963  wesnothd_connection connection;
964  mp::lobby_info li;
965  int selected_game;
966  dialog_tester() : connection("", ""), li()
967  {
968  }
969  mp_lobby* create()
970  {
971  return new mp_lobby(li, connection, selected_game);
972  }
973 };
974 
975 class fake_chat_handler : public events::chat_handler {
976  void add_chat_message(const std::time_t&,
977  const std::string&, int, const std::string&,
978  MESSAGE_TYPE) {}
979  void send_chat_message(const std::string&, bool) {}
980  void send_to_server(const config&) {}
981  void clear_messages() {}
982 };
983 
984 template<>
985 struct dialog_tester<lobby_player_info>
986 {
987  config c;
988  fake_chat_handler ch;
989  wesnothd_connection connection;
990  mp::user_info ui;
991  mp::lobby_info li;
992  dialog_tester()
993  : connection("", "")
994  , ui(c), li()
995  {
996  }
997  lobby_player_info* create()
998  {
999  return new lobby_player_info(ch, ui, li);
1000  }
1001 };
1002 
1003 template<>
1004 struct dialog_tester<log_settings>
1005 {
1006  log_settings* create()
1007  {
1008  return new log_settings();
1009  }
1010 };
1011 
1012 template<>
1013 struct dialog_tester<message>
1014 {
1015  message* create()
1016  {
1017  return new message("Title", "Message", false, false, false);
1018  }
1019 };
1020 
1021 template<>
1022 struct dialog_tester<mp_create_game>
1023 {
1024  saved_game state;
1025  dialog_tester() : state(config {"campaign_type", "multiplayer"})
1026  {
1027  }
1028  mp_create_game* create()
1029  {
1030  return new mp_create_game(state, true);
1031  }
1032 };
1033 
1034 template<>
1035 struct dialog_tester<mp_join_game_password_prompt>
1036 {
1037  std::string password;
1038  mp_join_game_password_prompt* create()
1039  {
1040  return new mp_join_game_password_prompt(password);
1041  }
1042 };
1043 
1044 template<>
1045 struct dialog_tester<mp_report>
1046 {
1047  std::string report_text;
1048  mp_report* create()
1049  {
1050  return new mp_report(report_text);
1051  }
1052 };
1053 
1054 static std::vector<std::string> depcheck_mods {"mod_one", "some other", "more"};
1055 
1056 template<>
1057 struct dialog_tester<depcheck_confirm_change>
1058 {
1059  depcheck_confirm_change* create()
1060  {
1061  return new depcheck_confirm_change(true, depcheck_mods, "requester");
1062  }
1063 };
1064 
1065 template<>
1066 struct dialog_tester<depcheck_select_new>
1067 {
1068  depcheck_select_new* create()
1069  {
1070  return new depcheck_select_new(ng::depcheck::MODIFICATION, depcheck_mods);
1071  }
1072 };
1073 
1074 template<>
1075 struct dialog_tester<mp_login>
1076 {
1077  mp_login* create()
1078  {
1079  return new mp_login("wesnoth.org", "label", true);
1080  }
1081 };
1082 
1083 template<>
1084 struct dialog_tester<simple_item_selector>
1085 {
1086  simple_item_selector* create()
1087  {
1088  return new simple_item_selector("title", "message", std::vector<std::string>(), false, false);
1089  }
1090 };
1091 
1092 template<>
1093 struct dialog_tester<screenshot_notification>
1094 {
1095  screenshot_notification* create()
1096  {
1097  return new screenshot_notification("path", nullptr);
1098  }
1099 };
1100 
1101 template<>
1102 struct dialog_tester<theme_list>
1103 {
1104  static theme_info make_theme(const std::string& name)
1105  {
1106  theme_info ti;
1107  ti.id = name;
1108  ti.name = name;
1109  ti.description = name + " this is a description";
1110  return ti;
1111  }
1112  static std::vector<theme_info> themes;
1113  theme_list* create()
1114  {
1115  return new theme_list(themes, 0);
1116  }
1117 };
1118 std::vector<theme_info> dialog_tester<theme_list>::themes {make_theme("classic"), make_theme("new"), make_theme("more"), make_theme("themes")};
1119 
1120 template<>
1121 struct dialog_tester<editor_generate_map>
1122 {
1123  std::vector<std::unique_ptr<map_generator>> map_generators;
1124  editor_generate_map* create()
1125  {
1126  for(const config &i : test_gui2_fixture::main_config.child_range("multiplayer")) {
1127  if(i["scenario_generation"] == "default") {
1128  const config &generator_cfg = i.child("generator");
1129  if (generator_cfg) {
1130  map_generators.emplace_back(create_map_generator("", generator_cfg));
1131  }
1132  }
1133  }
1134 
1135  editor_generate_map* result = new editor_generate_map(map_generators);
1136  BOOST_REQUIRE_MESSAGE(result, "Failed to create a dialog.");
1137 
1138  return result;
1139  }
1140 };
1141 
1142 template<>
1143 struct dialog_tester<editor_new_map>
1144 {
1145  int width = 10;
1146  int height = 10;
1147  editor_new_map* create()
1148  {
1149  return new editor_new_map("Test", width, height);
1150  }
1151 };
1152 
1153 template<>
1154 struct dialog_tester<editor_resize_map>
1155 {
1156  int width = 0;
1157  int height = 0;
1159  bool copy = false;
1160  editor_resize_map* create()
1161  {
1162  return new editor_resize_map(width, height, expand_direction, copy);
1163  }
1164 };
1165 
1166 template<>
1167 struct dialog_tester<file_dialog>
1168 {
1169  file_dialog* create()
1170  {
1171  return new file_dialog();
1172  }
1173 };
1174 
1175 template<>
1176 struct dialog_tester<folder_create>
1177 {
1178  std::string folder_name;
1179  folder_create* create()
1180  {
1181  return new folder_create(folder_name);
1182  }
1183 };
1184 
1185 template<>
1186 struct dialog_tester<transient_message>
1187 {
1188  transient_message* create()
1189  {
1190  return new transient_message("Title", false, "Message", false, "");
1191  }
1192 };
1193 
1194 template<>
1195 struct dialog_tester<title_screen>
1196 {
1197  std::vector<std::string> args;
1198  commandline_options opts;
1200  dialog_tester() : opts(args), game(opts) {}
1201  title_screen* create()
1202  {
1203  return new title_screen(game);
1204  }
1205 };
1206 
1207 template<>
1208 struct dialog_tester<wml_error>
1209 {
1210  static std::vector<std::string> files;
1211  wml_error* create()
1212  {
1213  return new wml_error("Summary", "Post summary", files, "Details");
1214  }
1215 };
1216 std::vector<std::string> dialog_tester<wml_error>::files {"some", "files", "here"};
1217 
1218 template<>
1219 struct dialog_tester<wml_message_left>
1220 {
1221  wml_message_left* create()
1222  {
1223  return new wml_message_left("Title", "Message", "", false);
1224  }
1225 };
1226 
1227 template<>
1228 struct dialog_tester<wml_message_right>
1229 {
1230  wml_message_right* create()
1231  {
1232  return new wml_message_right("Title", "Message", "", false);
1233  }
1234 };
1235 
1236 template<>
1237 struct dialog_tester<wml_message_double>
1238 {
1239  wml_message_double* create()
1240  {
1241  return new wml_message_double("Title", "Message", "", false, "", true);
1242  }
1243 };
1244 
1245 template<>
1246 struct dialog_tester<faction_select>
1247 {
1248  config era_cfg, side_cfg;
1249  std::vector<const config*> eras;
1250  ng::flg_manager flg;
1251  std::string color;
1252  dialog_tester()
1253  : era_cfg(), side_cfg(), eras(1, &era_cfg) // TODO: Add an actual era definition
1254  , flg(eras, side_cfg, false, false, false)
1255  , color("teal")
1256  {}
1257  faction_select* create() {
1258  return new faction_select(flg, color, 1);
1259  }
1260 };
1261 
1262 template<>
1263 struct dialog_tester<generator_settings>
1264 {
1265  config cfg;
1267  dialog_tester() : data(cfg) {}
1268  generator_settings* create()
1269  {
1270  return new generator_settings(data);
1271  }
1272 };
1273 
1274 template<>
1275 struct dialog_tester<sp_options_configure>
1276 {
1277  saved_game state;
1278  ng::create_engine create_eng;
1279  ng::configure_engine config_eng;
1280  dialog_tester() : create_eng(state)
1281  , config_eng(create_eng.get_state()) {}
1282  sp_options_configure* create()
1283  {
1284  return new sp_options_configure(create_eng, config_eng);
1285  }
1286 };
1287 
1288 template<>
1289 struct dialog_tester<statistics_dialog>
1290 {
1291  team t;
1292  dialog_tester() : t() {}
1293  statistics_dialog* create()
1294  {
1295  return new statistics_dialog(t);
1296  }
1297 };
1298 
1299 template<>
1300 struct dialog_tester<surrender_quit>
1301 {
1302  dialog_tester() {}
1303  surrender_quit* create()
1304  {
1305  return new surrender_quit();
1306  }
1307 };
1308 
1309 } // namespace
bool new_widgets
Do we wish to use the new library or not.
Definition: settings.cpp:23
t_string description
Definition: theme.hpp:39
void remove()
Removes a tip.
Definition: tooltip.cpp:111
Defines the exception classes for the layout algorithm.
#define PLAIN_LOG
Definition: log.hpp:258
static config_cache & instance()
Get reference to the singleton object.
configure_engine
saved_game & get_state()
static config main_config
Definition: test_gui2.cpp:153
std::string get_modeless_dialog_id(const modeless_dialog &dialog)
Definition: test_gui2.cpp:168
bool delete_file(const std::string &filename)
Add a special kind of assert to validate whether the input from WML doesn&#39;t contain any problems that...
Main class to show messages to the user.
Definition: message.hpp:35
static game_config_view wrap(const config &cfg)
Formula AI debugger.
logger & info()
Definition: log.cpp:182
static std::shared_ptr< save_index_class > default_saves_dir()
Returns an instance for managing saves in filesystem::get_saves_dir()
Definition: save_index.cpp:210
std::string id
Definition: theme.hpp:37
game_display & get_fake_display(const int width, const int height)
Gets a fake test display.
t_string name
Definition: theme.hpp:38
Exception thrown when the height resizing has failed.
This file contains the window object, this object is a top level container which has the event manage...
void draw()
Draws the window.
Definition: window.cpp:616
The paths manager is responsible for recording the various paths that binary files may be located at...
Definition: filesystem.hpp:402
This class represents the collective information the client has about the players and games on the se...
Definition: lobby_info.hpp:31
std::string_view data
Definition: picture.cpp:206
std::string user_message
The message for the user explaining what went wrong.
const std::vector< std::string > items
Replay control code.
std::string get_unknown_exception_type()
Utility function for finding the type of thing caught with catch(...).
Definition: general.cpp:23
static std::string _(const char *str)
Definition: gettext.hpp:93
FLG stands for faction, leader and gender.
Definition: flg_manager.hpp:29
bool show(const unsigned auto_close_time=0)
Shows the window.
void load_config(const config &v)
BOOST_FIXTURE_TEST_SUITE(test_map_location, MLFixture)
Generic file dialog.
bool fog()
Definition: game.cpp:526
This class stores all the data for a single &#39;side&#39; (in game nomenclature).
Definition: team.hpp:75
static const std::string widgets_file
Definition: test_gui2.cpp:154
Exception thrown when the width has been modified during resizing.
BOOST_AUTO_TEST_CASE(modal_dialog_test_addon_auth)
Definition: test_gui2.cpp:380
std::string label
What to show in the filter&#39;s drop-down list.
Definition: manager.cpp:217
This file contains the settings handling of the widget library.
virtual const std::string & window_id() const
The ID of the window to build.
A class that represents a TCP/IP connection to the wesnothd server.
The basic class for representing 8-bit RGB or RGBA colour values.
Definition: color.hpp:58
Exception thrown when the width resizing has failed.
std::string path
Definition: game_config.cpp:39
std::string read_file(const std::string &fname)
Basic disk I/O - read file.
Add-ons (campaignd) client class.
Definition: client.hpp:40
Various uncategorised dialogs.
Helper class, don&#39;t construct this directly.
void get_config(const std::string &path, config &cfg, abstract_validator *validator=nullptr)
Gets a config object from given path.
std::string dev_message
The message for developers telling which problem was triggered, this shouldn&#39;t be translated...
bool shroud()
Definition: game.cpp:536
std::string id
Text to match against addon_info.tags()
Definition: manager.cpp:215
void write_file(const std::string &fname, const std::string &data, std::ios_base::openmode mode)
Throws io_exception if an error occurs.
void clear_defines()
Clear stored defines map to default values.
map_generator * create_map_generator(const std::string &name, const config &cfg, const config *vars)
Definition: map_create.cpp:29
std::size_t i
Definition: function.cpp:967
Game configuration data as global variables.
Definition: build_info.cpp:60
std::string get_modal_dialog_id(const modal_dialog &dialog)
Definition: test_gui2.cpp:163
std::string password(const std::string &server, const std::string &login)
bool load_language_list()
Definition: language.cpp:104
Declarations for File-IO.
virtual const std::string & window_id() const =0
The ID of the window to build.
This class represents the information a client has about another player.
Definition: lobby_data.hpp:32
int turns()
Definition: game.cpp:546
double t
Definition: astarsearch.cpp:65
std::vector< std::string > split(const config_attribute_value &val)
The popup class shows windows that are shown non-modal.
A variable-expanding proxy for the config class.
Definition: variable.hpp:44
Abstract base class for all modal dialogs.
void point(int x, int y)
Draw a single point.
Definition: draw.cpp:193
point resolution()
Definition: general.cpp:395
#define e
void send_to_server(const config &data)
Attempts to send given data to server if a connection is open.
std::set< std::string > & registered_window_types()
Returns the list of registered windows.
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:60
mock_char c
std::map< std::string, addon_info > addons_list
Definition: info.hpp:28
base class of top level items, the only item which needs to store the final canvases to draw on...
Definition: window.hpp:66
void add_define(const std::string &define)
Add a entry to preproc defines map.
Networked add-ons (campaignd) client interface.
std::pair< std::string, unsigned > item
Definition: help_impl.hpp:414
void show(const std::string &window_id, const t_string &message, const point &mouse, const SDL_Rect &source_rect)
Shows a tip.
Definition: tooltip.cpp:81
Singleton class to manage game config file caching.