The Battle for Wesnoth  1.19.9+dev
test_gui2.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2025
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_manager.hpp"
26 #include "game_config_view.hpp"
27 #include "game_display.hpp"
28 #include "game_events/manager.hpp"
32 #include "game_launcher.hpp"
34 #include "gettext.hpp"
46 #include "gui/dialogs/chat_log.hpp"
85 #include "gui/dialogs/message.hpp"
101 #include "gui/dialogs/outro.hpp"
102 #include "gui/dialogs/prompt.hpp"
114 #include "gui/dialogs/tooltip.hpp"
119 #include "gui/dialogs/wml_error.hpp"
121 #include "gui/widgets/settings.hpp"
122 #include "gui/widgets/window.hpp"
123 #include "language.hpp"
124 #include "map/map.hpp"
125 #include "replay.hpp"
126 #include "save_index.hpp"
127 #include "saved_game.hpp"
129 #include "terrain/type_data.hpp"
131 #include "utils/general.hpp"
132 #include "wesnothd_connection.hpp"
133 #include "wml_exception.hpp"
134 
135 #include <boost/test/unit_test.hpp>
136 
137 #include <functional>
138 #include <memory>
139 
140 using namespace gui2::dialogs;
141 
144  : config_manager()
145  , dummy_args({"wesnoth", "--noaddons"})
146  {
147  /** The main config, which contains the entire WML tree. */
148  game_config_view game_config_view_ = game_config_view::wrap(main_config);
149  config_manager.reset(new game_config_manager(dummy_args));
150 
152 
153  cache.clear_defines();
154  cache.add_define("EDITOR");
155  cache.add_define("MULTIPLAYER");
156  cache.get_config(game_config::path +"/data", main_config);
157 
158  const filesystem::binary_paths_manager bin_paths_manager(game_config_view_);
159 
161  game_config::load_config(main_config.mandatory_child("game_config"));
162  }
164  {
165  }
167  static const std::string widgets_file;
168  std::unique_ptr<game_config_manager> config_manager;
169  std::vector<std::string> dummy_args;
170 };
172 const std::string test_gui2_fixture::widgets_file = "widgets_tested.log";
173 
174 namespace gui2 {
175 
176 namespace dialogs {
177 
178 std::string get_modal_dialog_id(const modal_dialog& dialog)
179 {
180  return dialog.window_id();
181 }
182 
183 std::string get_modeless_dialog_id(const modeless_dialog& dialog)
184 {
185  return dialog.window_id();
186 }
187 
188 } // namespace dialogs
189 } // namespace gui2
190 
191 namespace {
192 
193  /**
194  * Helper class to generate a dialog.
195  *
196  * This class makes sure the dialog is properly created and initialized.
197  * The specialized versions are at the end of this file.
198  */
199  template<class T>
200  struct dialog_tester
201  {
202  T* create() { return new T(); }
203  };
204 
205  typedef std::pair<unsigned, unsigned> resolution;
206  typedef std::vector<std::pair<unsigned, unsigned>> resolution_list;
207 
208  template<class T>
209  void test_resolutions(const resolution_list& resolutions)
210  {
211  for(const resolution& resolution : resolutions) {
212  test_utils::get_fake_display(resolution.first, resolution.second);
213 
214  dialog_tester<T> ctor;
215  const std::unique_ptr<modal_dialog> dlg(ctor.create());
216  BOOST_REQUIRE_MESSAGE(dlg.get(), "Failed to create a dialog.");
217 
218  std::string id = get_modal_dialog_id(*dlg.get());
219  filesystem::write_file(test_gui2_fixture::widgets_file, ","+id, std::ios_base::app);
220 
221  std::string exception;
222  try {
223  dlg->show(1);
224  } catch(const gui2::layout_exception_width_modified&) {
225  exception = "gui2::layout_exception_width_modified";
227  exception = "gui2::layout_exception_width_resize_failed";
229  exception = "gui2::layout_exception_height_resize_failed";
230  } catch(const wml_exception& e) {
231  exception = e.dev_message;
232  } catch(const std::exception& e) {
233  exception = e.what();
234  } catch(...) {
235  exception = utils::get_unknown_exception_type();
236  }
237  BOOST_CHECK_MESSAGE(exception.empty(),
238  "Test for '" << id
239  << "' Failed\nnew widgets = " << gui2::new_widgets
240  << " resolution = " << resolution.first
241  << 'x' << resolution.second
242  << "\nException caught: " << exception << '.');
243  }
244  }
245 
246  template<class T>
247  void test_popup_resolutions(const resolution_list& resolutions)
248  {
249  bool interact = false;
250  for(int i = 0; i < 2; ++i) {
251  for(const resolution& resolution : resolutions) {
252  // debug clock doesn't work at 800x600
253  if(resolution.first == 800 && resolution.second == 600) {
254  continue;
255  }
256  test_utils::get_fake_display(resolution.first, resolution.second);
257 
258  dialog_tester<T> ctor;
259  const std::unique_ptr<modeless_dialog> dlg(ctor.create());
260  BOOST_REQUIRE_MESSAGE(dlg.get(), "Failed to create a dialog.");
261 
262  std::string id = get_modeless_dialog_id(*dlg.get());
263  filesystem::write_file(test_gui2_fixture::widgets_file, ","+id, std::ios_base::app);
264 
265  std::string exception;
266  try {
267  dlg->show(interact);
268  gui2::window* window = dlg.get();
269  BOOST_REQUIRE_NE(window, static_cast<void*>(nullptr));
270  window->draw();
271  } catch(const gui2::layout_exception_width_modified&) {
272  exception = "gui2::layout_exception_width_modified";
274  exception = "gui2::layout_exception_width_resize_failed";
276  exception = "gui2::layout_exception_height_resize_failed";
277  } catch(const wml_exception& e) {
278  exception = e.dev_message;
279  } catch(const std::exception& e) {
280  exception = e.what();
281  } catch(...) {
282  exception = utils::get_unknown_exception_type();
283  }
284  BOOST_CHECK_MESSAGE(exception.empty(),
285  "Test for '" << id
286  << "' Failed\nnew widgets = " << gui2::new_widgets
287  << " resolution = " << resolution.first
288  << 'x' << resolution.second
289  << "\nException caught: " << exception << '.');
290  }
291 
292  interact = true;
293  }
294  }
295 
296 #ifdef _MSC_VER
297 #pragma warning(push)
298 #pragma warning(disable: 4702)
299 #endif
300  void test_tip_resolutions(const resolution_list& resolutions
301  , const std::string& id)
302  {
303  for(const auto& resolution : resolutions) {
304  test_utils::get_fake_display(resolution.first, resolution.second);
305 
306  filesystem::write_file(test_gui2_fixture::widgets_file, ","+id, std::ios_base::app);
307 
308  std::string exception;
309  try {
310  tip::show(id
311  , "Test message for a tooltip."
312  , point(0, 0)
313  , {0,0,0,0});
314  tip::remove();
315  } catch(const gui2::layout_exception_width_modified&) {
316  exception = "gui2::layout_exception_width_modified";
318  exception = "gui2::layout_exception_width_resize_failed";
320  exception = "gui2::layout_exception_height_resize_failed";
321  } catch(const wml_exception& e) {
322  exception = e.dev_message;
323  } catch(const std::exception& e) {
324  exception = e.what();
325  } catch(...) {
326  exception = utils::get_unknown_exception_type();
327  }
328  BOOST_CHECK_MESSAGE(exception.empty(),
329  "Test for tip '" << id
330  << "' Failed\nnew widgets = " << gui2::new_widgets
331  << " resolution = " << resolution.first
332  << 'x' << resolution.second
333  << "\nException caught: " << exception << '.');
334  }
335  }
336 #ifdef _MSC_VER
337 #pragma warning(pop)
338 #endif
339 
340 const resolution_list& get_gui_resolutions()
341 {
342  static resolution_list result {
343  {800, 600},
344  {1024, 768},
345  {1280, 1024},
346  {1680, 1050},
347  };
348 
349  return result;
350 }
351 
352 template<class T>
353 void test()
354 {
355  gui2::new_widgets = false;
356 
357 // for(std::size_t i = 0; i < 2; ++i) {
358 
359  test_resolutions<T>(get_gui_resolutions());
360 
361 // break; // FIXME: New widgets break
362 // gui2::new_widgets = true;
363 // }
364 }
365 
366 template<class T>
367 void test_popup()
368 {
369  gui2::new_widgets = false;
370 
371  for(std::size_t i = 0; i < 2; ++i) {
372 
373  test_popup_resolutions<T>(get_gui_resolutions());
374 
375  gui2::new_widgets = true;
376  }
377 }
378 
379 void test_tip(const std::string& id)
380 {
381  gui2::new_widgets = false;
382 
383  for(std::size_t i = 0; i < 2; ++i) {
384 
385  test_tip_resolutions(get_gui_resolutions(), id);
386 
387  gui2::new_widgets = true;
388  }
389 }
390 
391 } // namespace
392 
394 
395 BOOST_AUTO_TEST_CASE(modal_dialog_test_addon_auth)
396 {
397  test<addon_auth>();
398 }
399 BOOST_AUTO_TEST_CASE(modal_dialog_test_addon_connect)
400 {
401  test<addon_connect>();
402 }
403 BOOST_AUTO_TEST_CASE(modal_dialog_test_addon_license_prompt)
404 {
405  test<addon_license_prompt>();
406 }
407 BOOST_AUTO_TEST_CASE(modal_dialog_test_campaign_difficulty)
408 {
409  test<campaign_difficulty>();
410 }
411 BOOST_AUTO_TEST_CASE(modal_dialog_test_chat_log)
412 {
413  test<chat_log>();
414 }
415 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_choose_addon)
416 {
417  test<editor_choose_addon>();
418 }
419 BOOST_AUTO_TEST_CASE(modal_dialog_test_prompt)
420 {
421  test<prompt>();
422 }
423 BOOST_AUTO_TEST_CASE(modal_dialog_test_core_selection)
424 {
425  test<core_selection>();
426 }
427 BOOST_AUTO_TEST_CASE(modal_dialog_test_custom_tod)
428 {
429  test<custom_tod>();
430 }
431 BOOST_AUTO_TEST_CASE(modal_dialog_test_depcheck_confirm_change)
432 {
433  test<depcheck_confirm_change>();
434 }
435 BOOST_AUTO_TEST_CASE(modal_dialog_test_depcheck_select_new)
436 {
437  test<depcheck_select_new>();
438 }
439 BOOST_AUTO_TEST_CASE(modal_dialog_test_edit_label)
440 {
441  test<edit_label>();
442 }
443 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_edit_pbl)
444 {
445  test<editor_edit_pbl>();
446 }
447 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_edit_pbl_translation)
448 {
449  test<editor_edit_pbl_translation>();
450 }
451 BOOST_AUTO_TEST_CASE(modal_dialog_test_edit_text)
452 {
453  test<edit_text>();
454 }
455 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_edit_label)
456 {
457  test<editor_edit_label>();
458 }
459 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_edit_side)
460 {
461  test<editor_edit_side>();
462 }
463 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_edit_scenario)
464 {
465  test<editor_edit_scenario>();
466 }
467 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_generate_map)
468 {
469  test<editor_generate_map>();
470 }
471 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_new_map)
472 {
473  test<editor_new_map>();
474 }
475 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_resize_map)
476 {
477  test<editor_resize_map>();
478 }
479 BOOST_AUTO_TEST_CASE(modal_dialog_test_faction_select)
480 {
481  test<faction_select>();
482 }
483 BOOST_AUTO_TEST_CASE(modal_dialog_test_file_dialog)
484 {
485  test<file_dialog>();
486 }
487 BOOST_AUTO_TEST_CASE(modal_dialog_test_folder_create)
488 {
489  test<folder_create>();
490 }
491 BOOST_AUTO_TEST_CASE(modal_dialog_test_formula_debugger)
492 {
493  test<formula_debugger>();
494 }
495 BOOST_AUTO_TEST_CASE(modal_dialog_test_game_cache_options)
496 {
497  test<game_cache_options>();
498 }
499 BOOST_AUTO_TEST_CASE(modal_dialog_test_game_delete)
500 {
501  test<game_delete>();
502 }
503 BOOST_AUTO_TEST_CASE(modal_dialog_test_game_version)
504 {
505  test<game_version>();
506 }
507 BOOST_AUTO_TEST_CASE(modal_dialog_test_game_save)
508 {
509  test<game_save>();
510 }
511 BOOST_AUTO_TEST_CASE(modal_dialog_test_game_save_message)
512 {
513  test<game_save_message>();
514 }
515 BOOST_AUTO_TEST_CASE(modal_dialog_test_game_save_oos)
516 {
517  test<game_save_oos>();
518 }
519 BOOST_AUTO_TEST_CASE(modal_dialog_test_generator_settings)
520 {
521  test<generator_settings>();
522 }
523 BOOST_AUTO_TEST_CASE(modal_dialog_test_gui_test_dialog)
524 {
525  test<gui_test_dialog>();
526 }
527 BOOST_AUTO_TEST_CASE(modal_dialog_test_hotkey_bind)
528 {
529  test<hotkey_bind>();
530 }
531 BOOST_AUTO_TEST_CASE(modal_dialog_test_install_dependencies)
532 {
533  test<install_dependencies>();
534 }
535 BOOST_AUTO_TEST_CASE(modal_dialog_test_language_selection)
536 {
537  test<language_selection>();
538 }
539 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_lobby)
540 {
541  test<mp_lobby>();
542 }
543 BOOST_AUTO_TEST_CASE(modal_dialog_test_lobby_player_info)
544 {
545  test<lobby_player_info>();
546 }
547 BOOST_AUTO_TEST_CASE(modal_dialog_test_log_settings)
548 {
549  test<log_settings>();
550 }
551 BOOST_AUTO_TEST_CASE(modal_dialog_test_message)
552 {
553  test<message>();
554 }
555 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_alerts_options)
556 {
557  test<mp_alerts_options>();
558 }
559 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_connect)
560 {
561  test<mp_connect>();
562 }
563 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_join_game_password_prompt)
564 {
565  test<mp_join_game_password_prompt>();
566 }
567 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_login)
568 {
569  test<mp_login>();
570 }
571 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_method_selection)
572 {
573  test<mp_method_selection>();
574 }
575 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_report)
576 {
577  test<mp_report>();
578 }
579 BOOST_AUTO_TEST_CASE(modal_dialog_test_simple_item_selector)
580 {
581  test<simple_item_selector>();
582 }
583 BOOST_AUTO_TEST_CASE(modal_dialog_test_screenshot_notification)
584 {
585  test<screenshot_notification>();
586 }
587 BOOST_AUTO_TEST_CASE(modal_dialog_test_select_orb_colors)
588 {
589  test<select_orb_colors>();
590 }
591 BOOST_AUTO_TEST_CASE(modal_dialog_test_reachmap_options)
592 {
593  test<reachmap_options>();
594 }
595 BOOST_AUTO_TEST_CASE(modal_dialog_test_statistics_dialog)
596 {
597  test<statistics_dialog>();
598 }
599 BOOST_AUTO_TEST_CASE(modal_dialog_test_surrender_quit)
600 {
601  test<surrender_quit>();
602 }
603 BOOST_AUTO_TEST_CASE(modal_dialog_test_theme_list)
604 {
605  test<theme_list>();
606 }
607 BOOST_AUTO_TEST_CASE(modal_dialog_test_transient_message)
608 {
609  test<transient_message>();
610 }
611 BOOST_AUTO_TEST_CASE(modal_dialog_test_wml_error)
612 {
613  test<wml_error>();
614 }
615 BOOST_AUTO_TEST_CASE(modal_dialog_test_wml_message_left)
616 {
617  test<wml_message_left>();
618 }
619 BOOST_AUTO_TEST_CASE(modal_dialog_test_wml_message_right)
620 {
621  test<wml_message_right>();
622 }
623 BOOST_AUTO_TEST_CASE(modal_dialog_test_wml_message_double)
624 {
625  test<wml_message_double>();
626 }
627 BOOST_AUTO_TEST_CASE(modal_dialog_test_achievements_dialog)
628 {
629  test<achievements_dialog>();
630 }
631 BOOST_AUTO_TEST_CASE(modal_dialog_test_addon_server_info)
632 {
633  test<addon_server_info>();
634 }
635 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_match_history_dialog)
636 {
637  test<mp_match_history>();
638 }
639 BOOST_AUTO_TEST_CASE(modal_dialog_test_migrate_version_selection_dialog)
640 {
641  test<gui2::dialogs::migrate_version_selection>();
642 }
643 BOOST_AUTO_TEST_CASE(modeless_dialog_test_debug_clock)
644 {
645  test_popup<debug_clock>();
646 }
647 BOOST_AUTO_TEST_CASE(tooltip_test_tooltip_large)
648 {
649  test_tip("tooltip_large");
650 }
651 BOOST_AUTO_TEST_CASE(tooltip_test_tooltip)
652 {
653  test_tip("tooltip");
654 }
655 BOOST_AUTO_TEST_CASE(modal_dialog_test_tod_new_schedule)
656 {
657  test<tod_new_schedule>();
658 }
659 
660 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_edit_unit)
661 {
662  test<editor_edit_unit>();
663 }
664 
665 // execute last - checks that there aren't any unaccounted for GUIs
667 {
668  std::set<std::string> widget_list = gui2::registered_window_types();
669  std::vector<std::string> widgets_tested = utils::split(filesystem::read_file(test_gui2_fixture::widgets_file));
670  std::set<std::string> omitted {
671  /*
672  * The unit attack unit test are disabled for now, they calling parameters
673  * don't allow 'nullptr's needs to be fixed.
674  */
675  "unit_attack",
676  // No test for this right now, not sure how to use the test system
677  // for dialog with no default constructor
678  "lua_interpreter",
679  /*
680  * Disable label settings dialog test because we need a display_context
681  * object, which we don't have, and it's a lot of work to produce a dummy
682  * one.
683  */
684  "label_settings",
685  "addon_uninstall_list",
686  "addon_manager",
687  "loading_screen",
688  "network_transmission",
689  "synched_choice_wait",
690  "drop_down_menu",
691  "preferences_dialog",
692  "units_dialog",
693  "unit_advance",
694  "mp_host_game_prompt",
695  "mp_create_game",
696  // The title screen appears to be throwing a bad_alloc on Travis, so disable it for now
697  "title_screen",
698  "end_credits",
699  "mp_staging",
700  "mp_join_game",
701  "terrain_layers",
702  "attack_predictions",
703  "help_browser",
704  "story_viewer",
705  "outro",
706  "mp_change_control", // Basically useless without a game_board object, so disabling
707  "game_stats", // segfault with LTO
708  "gamestate_inspector", // segfault with LTO
709  "server_info",
710  "sp_options_configure",// segfault with LTO
711  "campaign_selection",// segfault with LTO
712  "game_load",// segfault after disabling the above tests
713  "file_progress",
714  };
716 
717  for(const std::string& item : widgets_tested)
718  {
719  widget_list.erase(item);
720  PLAIN_LOG << "Checking widget " << item;
721  BOOST_CHECK_EQUAL(omitted.count(item), 0);
722  }
723  for(const std::string& item : omitted)
724  {
725  widget_list.erase(item);
726  }
727 
728  // Test size() instead of empty() to get the number of offenders
729  BOOST_CHECK_EQUAL(widget_list.size(), 0);
730  for(const std::string& id : widget_list) {
731  PLAIN_LOG << "Window '" << id << "' registered but not tested.";
732  }
733 }
734 
735 BOOST_AUTO_TEST_CASE(test_make_test_fake)
736 {
738 
739  try {
740  message dlg("title", "message", true, false, false);
741  dlg.show(1);
742  } catch(const wml_exception& e) {
743  BOOST_CHECK(e.user_message == _("Failed to show a dialog, which doesn’t fit on the screen."));
744  return;
745  } catch(...) {
746  BOOST_ERROR("Didn't catch the wanted exception, instead caught " << utils::get_unknown_exception_type() << ".");
747  }
748  BOOST_ERROR("Didn't catch the wanted exception, instead caught nothing.");
749 }
750 
751 BOOST_AUTO_TEST_SUITE_END()
752 
753 namespace {
754 
755 template<>
756 struct dialog_tester<addon_server_info>
757 {
758  std::string s = "";
759  bool b = false;
760  addon_server_info* create()
761  {
762  addons_client client("localhost:15999");
763  return new addon_server_info(client, s, b);
764  }
765 };
766 
767 template<>
768 struct dialog_tester<addon_auth>
769 {
770  config cfg;
771  addon_auth* create()
772  {
773  return new addon_auth(cfg);
774  }
775 };
776 
777 template<>
778 struct dialog_tester<addon_connect>
779 {
780  std::string host_name = "host_name";
781  addon_connect* create()
782  {
783  return new addon_connect(host_name, true);
784  }
785 };
786 
787 template<>
788 struct dialog_tester<addon_license_prompt>
789 {
790  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.
791 
792 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.)";
793  addon_license_prompt* create()
794  {
795  return new addon_license_prompt(license_terms);
796  }
797 };
798 
799 template<>
800 struct dialog_tester<addon_manager>
801 {
802  dialog_tester()
803  {
805  }
806  addon_manager* create()
807  {
808  addons_client client("localhost:15999");
809  return new addon_manager(client);
810  }
811 };
812 
813 template<>
814 struct dialog_tester<campaign_difficulty>
815 {
816  campaign_difficulty* create()
817  {
818  const config items("difficulty");
819 
820  return new campaign_difficulty(items);
821  }
822 };
823 
824 template<>
825 struct dialog_tester<campaign_selection>
826 {
827  saved_game state;
829  dialog_tester() : state(config {"campaign_type", "scenario"}), ng(state)
830  {
831  }
832  campaign_selection* create()
833  {
834  return new campaign_selection(ng);
835  }
836 };
837 
838 template<>
839 struct dialog_tester<chat_log>
840 {
841  config cfg;
842  vconfig vcfg;
843  replay_recorder_base rbase;
844  replay r;
845  dialog_tester() : vcfg(cfg), r(rbase) {}
846  chat_log* create()
847  {
848  return new chat_log(vcfg, r);
849  }
850 };
851 
852 template<>
853 struct dialog_tester<editor_choose_addon>
854 {
855  std::string temp;
856  editor_choose_addon* create()
857  {
858  return new editor_choose_addon(temp);
859  }
860 };
861 
862 template<>
863 struct dialog_tester<prompt>
864 {
865  std::string temp;
866  prompt* create()
867  {
868  return new prompt(temp);
869  }
870 };
871 
872 template<>
873 struct dialog_tester<core_selection>
874 {
875  std::vector<config> cores;
876  dialog_tester()
877  {
878  cores.resize(1);
879  }
880  core_selection* create()
881  {
882  return new core_selection(cores, 0);
883  }
884 };
885 
886 template<>
887 struct dialog_tester<custom_tod>
888 {
889  std::vector<time_of_day> times;
890  int current_tod = 0;
891  dialog_tester()
892  {
893  times.resize(1);
894  }
895  custom_tod* create()
896  {
897  return new custom_tod(times, current_tod);
898  }
899 };
900 
901 template<>
902 struct dialog_tester<edit_label>
903 {
904  std::string label = "Label text to modify";
905  bool team_only = false;
906  edit_label* create()
907  {
908  return new edit_label(label, team_only);
909  }
910 };
911 
912 template<>
913 struct dialog_tester<edit_text>
914 {
915  std::string text = "text to modify";
916  edit_text* create()
917  {
918  return new edit_text("title", "label", text);
919  }
920 };
921 
922 template<>
923 struct dialog_tester<editor_edit_label>
924 {
925  std::string label = "Label text to modify";
926  std::string category = "test";
927  bool immutable = false, fog = false, shroud = false;
928  color_t color;
929  editor_edit_label* create()
930  {
931  return new editor_edit_label(label, immutable, fog, shroud, color, category);
932  }
933 };
934 
935 template<>
936 struct dialog_tester<editor_edit_pbl>
937 {
938  std::string temp;
939  std::string temp1;
940  editor_edit_pbl* create()
941  {
942  return new editor_edit_pbl(temp, temp1);
943  }
944 };
945 
946 template<>
947 struct dialog_tester<editor_edit_pbl_translation>
948 {
949  std::string temp1;
950  std::string temp2;
951  std::string temp3;
953  {
954  return new editor_edit_pbl_translation(temp1, temp2, temp3);
955  }
956 };
957 
958 template<>
959 struct dialog_tester<editor_edit_scenario>
960 {
961  std::string id, name, descr;
962  int turns = 0, xp_mod = 50;
963  bool defeat_enemies = false, random_start = false;
964  editor_edit_scenario* create()
965  {
966  return new editor_edit_scenario(id, name, descr, turns, xp_mod, defeat_enemies, random_start);
967  }
968 };
969 
970 template<>
971 struct dialog_tester<editor_edit_side>
972 {
973  team t;
975  dialog_tester() : info(t) {}
976  editor_edit_side* create()
977  {
978  return new editor_edit_side(info);
979  }
980 };
981 
982 template<>
983 struct dialog_tester<formula_debugger>
984 {
985  wfl::formula_debugger debugger;
986  formula_debugger* create()
987  {
988  return new formula_debugger(debugger);
989  }
990 };
991 
992 template<>
993 struct dialog_tester<game_load>
994 {
995  config cfg;
996  game_config_view view;
997  // It would be good to have a test directory instead of using the same directory as the player,
998  // however this code will support that - default_saves_dir() will respect --userdata-dir.
1000  dialog_tester()
1001  {
1002  /** @todo Would be nice to add real data to the config. */
1003  }
1004  game_load* create()
1005  {
1006  view = game_config_view::wrap(cfg);
1007  return new game_load(view, data);
1008  }
1009 
1010 };
1011 
1012 template<>
1013 struct dialog_tester<game_save>
1014 {
1015  std::string title = "Title";
1016  std::string filename = "filename";
1017  game_save* create()
1018  {
1019  return new game_save(title, filename);
1020  }
1021 
1022 };
1023 
1024 template<>
1025 struct dialog_tester<game_save_message>
1026 {
1027  std::string title = "Title";
1028  std::string filename = "filename";
1029  std::string message = "message";
1030  game_save_message* create()
1031  {
1032  return new game_save_message(title, filename, message);
1033  }
1034 
1035 };
1036 
1037 template<>
1038 struct dialog_tester<game_save_oos>
1039 {
1040  bool ignore_all = false;
1041  std::string title = "Title";
1042  std::string filename = "filename";
1043  std::string message = "message";
1044  game_save_oos* create()
1045  {
1046  return new game_save_oos(ignore_all, title, filename, message);
1047  }
1048 
1049 };
1050 
1051 template<>
1052 struct dialog_tester<install_dependencies>
1053 {
1054  addons_list addons;
1055  install_dependencies* create()
1056  {
1057  return new install_dependencies(addons);
1058  }
1059 };
1060 
1061 template<>
1062 struct dialog_tester<hotkey_bind>
1063 {
1064  std::string id = "";
1065 
1066  hotkey_bind* create()
1067  {
1068  return new hotkey_bind(id);
1069  }
1070 };
1071 
1072 template<>
1073 struct dialog_tester<mp_lobby>
1074 {
1076  wesnothd_connection connection;
1077  mp::lobby_info li;
1078  int selected_game;
1079  dialog_tester() : connection("", ""), li()
1080  {
1081  }
1082  mp_lobby* create()
1083  {
1084  return new mp_lobby(li, connection, selected_game);
1085  }
1086 };
1087 
1088 template<>
1089 struct dialog_tester<mp_match_history>
1090 {
1091  wesnothd_connection connection;
1092  dialog_tester() : connection("", "")
1093  {
1094  }
1095  mp_match_history* create()
1096  {
1097  return new mp_match_history("", connection, false);
1098  }
1099 };
1100 
1101 template<>
1102 struct dialog_tester<gui2::dialogs::migrate_version_selection>
1103 {
1105  {
1107  }
1108 };
1109 
1110 class fake_chat_handler : public events::chat_handler {
1111  void add_chat_message(const std::time_t&,
1112  const std::string&, int, const std::string&,
1113  MESSAGE_TYPE) {}
1114  void send_chat_message(const std::string&, bool) {}
1115  void send_to_server(const config&) {}
1116  void clear_messages() {}
1117 };
1118 
1119 template<>
1120 struct dialog_tester<lobby_player_info>
1121 {
1122  config c;
1123  fake_chat_handler ch;
1124  wesnothd_connection connection;
1125  mp::user_info ui;
1126  mp::lobby_info li;
1127  dialog_tester()
1128  : connection("", "")
1129  , ui(c), li()
1130  {
1131  }
1132  lobby_player_info* create()
1133  {
1134  return new lobby_player_info(ch, ui, li);
1135  }
1136 };
1137 
1138 template<>
1139 struct dialog_tester<log_settings>
1140 {
1141  log_settings* create()
1142  {
1143  return new log_settings();
1144  }
1145 };
1146 
1147 template<>
1148 struct dialog_tester<message>
1149 {
1150  message* create()
1151  {
1152  return new message("Title", "Message", false, false, false);
1153  }
1154 };
1155 
1156 template<>
1157 struct dialog_tester<mp_create_game>
1158 {
1159  saved_game state;
1160  dialog_tester() : state(config {"campaign_type", "multiplayer"})
1161  {
1162  }
1163  mp_create_game* create()
1164  {
1165  return new mp_create_game(state, true);
1166  }
1167 };
1168 
1169 template<>
1170 struct dialog_tester<mp_join_game_password_prompt>
1171 {
1172  std::string password;
1174  {
1175  return new mp_join_game_password_prompt(password);
1176  }
1177 };
1178 
1179 template<>
1180 struct dialog_tester<mp_report>
1181 {
1182  std::string report_text;
1183  mp_report* create()
1184  {
1185  return new mp_report(report_text);
1186  }
1187 };
1188 
1189 static std::vector<std::string> depcheck_mods {"mod_one", "some other", "more"};
1190 
1191 template<>
1192 struct dialog_tester<depcheck_confirm_change>
1193 {
1194  depcheck_confirm_change* create()
1195  {
1196  return new depcheck_confirm_change(true, depcheck_mods, "requester");
1197  }
1198 };
1199 
1200 template<>
1201 struct dialog_tester<depcheck_select_new>
1202 {
1203  depcheck_select_new* create()
1204  {
1205  return new depcheck_select_new(ng::depcheck::MODIFICATION, depcheck_mods);
1206  }
1207 };
1208 
1209 template<>
1210 struct dialog_tester<mp_login>
1211 {
1212  mp_login* create()
1213  {
1214  return new mp_login("wesnoth.org", "label", true);
1215  }
1216 };
1217 
1218 template<>
1219 struct dialog_tester<simple_item_selector>
1220 {
1221  simple_item_selector* create()
1222  {
1223  return new simple_item_selector("title", "message", std::vector<std::string>(), false, false);
1224  }
1225 };
1226 
1227 template<>
1228 struct dialog_tester<screenshot_notification>
1229 {
1230  screenshot_notification* create()
1231  {
1232  return new screenshot_notification("path", nullptr);
1233  }
1234 };
1235 
1236 template<>
1237 struct dialog_tester<theme_list>
1238 {
1239  static theme_info make_theme(const std::string& name)
1240  {
1241  theme_info ti;
1242  ti.id = name;
1243  ti.name = name;
1244  ti.description = name + " this is a description";
1245  return ti;
1246  }
1247  static std::vector<theme_info> themes;
1248  theme_list* create()
1249  {
1250  return new theme_list(themes, 0);
1251  }
1252 };
1253 std::vector<theme_info> dialog_tester<theme_list>::themes {make_theme("classic"), make_theme("new"), make_theme("more"), make_theme("themes")};
1254 
1255 template<>
1256 struct dialog_tester<editor_generate_map>
1257 {
1258  std::vector<std::unique_ptr<map_generator>> map_generators;
1259  editor_generate_map* create()
1260  {
1261  for(const config &i : test_gui2_fixture::main_config.child_range("multiplayer")) {
1262  if(i["scenario_generation"] == "default") {
1263  auto generator_cfg = i.optional_child("generator");
1264  if (generator_cfg) {
1265  map_generators.emplace_back(create_map_generator("", *generator_cfg));
1266  }
1267  }
1268  }
1269 
1270  editor_generate_map* result = new editor_generate_map(map_generators);
1271  BOOST_REQUIRE_MESSAGE(result, "Failed to create a dialog.");
1272 
1273  return result;
1274  }
1275 };
1276 
1277 template<>
1278 struct dialog_tester<editor_new_map>
1279 {
1280  int width = 10;
1281  int height = 10;
1282  editor_new_map* create()
1283  {
1284  return new editor_new_map("Test", width, height);
1285  }
1286 };
1287 
1288 template<>
1289 struct dialog_tester<editor_resize_map>
1290 {
1291  int width = 0;
1292  int height = 0;
1294  bool copy = false;
1295  editor_resize_map* create()
1296  {
1297  return new editor_resize_map(width, height, expand_direction, copy);
1298  }
1299 };
1300 
1301 template<>
1302 struct dialog_tester<file_dialog>
1303 {
1304  file_dialog* create()
1305  {
1306  return new file_dialog();
1307  }
1308 };
1309 
1310 template<>
1311 struct dialog_tester<folder_create>
1312 {
1313  std::string folder_name;
1314  folder_create* create()
1315  {
1316  return new folder_create(folder_name);
1317  }
1318 };
1319 
1320 template<>
1321 struct dialog_tester<transient_message>
1322 {
1323  transient_message* create()
1324  {
1325  return new transient_message("Title", false, "Message", false, "");
1326  }
1327 };
1328 
1329 template<>
1330 struct dialog_tester<title_screen>
1331 {
1332  std::vector<std::string> args;
1333  commandline_options opts;
1335  dialog_tester() : opts(args), game(opts) {}
1336  title_screen* create()
1337  {
1338  return new title_screen(game);
1339  }
1340 };
1341 
1342 template<>
1343 struct dialog_tester<wml_error>
1344 {
1345  static std::vector<std::string> files;
1346  wml_error* create()
1347  {
1348  return new wml_error("Summary", "Post summary", files, "Details");
1349  }
1350 };
1351 std::vector<std::string> dialog_tester<wml_error>::files {"some", "files", "here"};
1352 
1353 template<>
1354 struct dialog_tester<wml_message_left>
1355 {
1356  wml_message_left* create()
1357  {
1358  return new wml_message_left("Title", "Message", "", false);
1359  }
1360 };
1361 
1362 template<>
1363 struct dialog_tester<wml_message_right>
1364 {
1365  wml_message_right* create()
1366  {
1367  return new wml_message_right("Title", "Message", "", false);
1368  }
1369 };
1370 
1371 template<>
1372 struct dialog_tester<wml_message_double>
1373 {
1374  wml_message_double* create()
1375  {
1376  return new wml_message_double("Title", "Message", "", false, "", true);
1377  }
1378 };
1379 
1380 template<>
1381 struct dialog_tester<faction_select>
1382 {
1383  config era_cfg, side_cfg;
1384  std::vector<const config*> eras;
1385  ng::flg_manager flg;
1386  std::string color;
1387  dialog_tester()
1388  : era_cfg(), side_cfg(), eras(1, &era_cfg) // TODO: Add an actual era definition
1389  , flg(eras, side_cfg, false, false, false)
1390  , color("teal")
1391  {}
1392  faction_select* create() {
1393  return new faction_select(flg, color, 1);
1394  }
1395 };
1396 
1397 template<>
1398 struct dialog_tester<generator_settings>
1399 {
1400  config cfg;
1402  dialog_tester() : data(cfg) {}
1403  generator_settings* create()
1404  {
1405  return new generator_settings(data);
1406  }
1407 };
1408 
1409 template<>
1410 struct dialog_tester<sp_options_configure>
1411 {
1412  saved_game state;
1413  ng::create_engine create_eng;
1414  dialog_tester() : create_eng(state) {}
1415  sp_options_configure* create()
1416  {
1417  return new sp_options_configure(create_eng);
1418  }
1419 };
1420 
1421 template<>
1422 struct dialog_tester<statistics_dialog>
1423 {
1424  team t;
1426  statistics_t stats;
1427  dialog_tester() : t() , stats_record(), stats(stats_record) {}
1428  statistics_dialog* create()
1429  {
1430  return new statistics_dialog(stats, t);
1431  }
1432 };
1433 
1434 template<>
1435 struct dialog_tester<surrender_quit>
1436 {
1437  dialog_tester() {}
1438  surrender_quit* create()
1439  {
1440  return new surrender_quit();
1441  }
1442 };
1443 
1444 template<>
1445 struct dialog_tester<tod_new_schedule>
1446 {
1447  std::string id = "id";
1448  t_string name = "name";
1449  dialog_tester() {}
1450  tod_new_schedule* create()
1451  {
1452  return new tod_new_schedule(id, name);
1453  }
1454 };
1455 
1456 template<>
1457 struct dialog_tester<editor_edit_unit>
1458 {
1459  config cfg;
1460  game_config_view view;
1461 
1462  dialog_tester() {}
1463  editor_edit_unit* create()
1464  {
1465  config& units = cfg.add_child("units");
1466  cfg.add_child("race");
1467  config& movetype = units.add_child("movetype");
1468  movetype["name"] = "Test Movetype";
1469  movetype.add_child("defense");
1470  movetype.add_child("resistance");
1471  movetype.add_child("movement_costs");
1472  view = game_config_view::wrap(cfg);
1473  return new editor_edit_unit(view, "test_addon");
1474  }
1475 };
1476 
1477 template<>
1478 struct dialog_tester<gui_test_dialog>
1479 {
1480  dialog_tester() {}
1481  gui_test_dialog* create()
1482  {
1483  return new gui_test_dialog();
1484  }
1485 };
1486 
1487 } // namespace
double t
Definition: astarsearch.cpp:63
Add-ons (campaignd) client class.
Definition: client.hpp:41
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:158
config & add_child(config_key_type key)
Definition: config.cpp:436
Singleton class to manage game config file caching.
void add_define(const std::string &define)
Add a entry to preproc defines map.
static config_cache & instance()
Get reference to the singleton object.
void clear_defines()
Clear stored defines map to default values.
void get_config(const std::string &path, config &cfg, abstract_validator *validator=nullptr)
Gets a config object from given path.
A class grating read only view to a vector of config objects, viewed as one config with all children ...
static game_config_view wrap(const config &cfg)
Dialog that allows user to create custom unit types.
Definition: edit_unit.hpp:33
A test dialog for testing various gui2 features.
Main class to show messages to the user.
Definition: message.hpp:36
This shows the dialog to select a previous version of Wesnoth to migrate preferences from and redownl...
Abstract base class for all modal dialogs.
virtual const std::string & window_id() const =0
The ID of the window to build.
bool show(const unsigned auto_close_time=0)
Shows the window.
The popup class shows windows that are shown non-modal.
virtual const std::string & window_id() const
The ID of the window to build.
This shows the dialog to confirm surrender and/or quitting the game.
This class implements the title screen.
Dialog that takes new schedule ID and name from the player.
Shows a transient message.
Shows a dialog with two portraits, one on each side.
Shows a dialog with the portrait on the left side.
Shows a dialog with the portrait on the right side.
base class of top level items, the only item which needs to store the final canvases to draw on.
Definition: window.hpp:61
void draw()
Draws the window.
Definition: window.cpp:591
The basic "size" of the unit - flying, small land, large land, etc.
Definition: movetype.hpp:44
This class represents the collective information the client has about the players and games on the se...
Definition: lobby_info.hpp:31
FLG stands for faction, leader and gender.
Definition: flg_manager.hpp:30
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:209
This class stores all the data for a single 'side' (in game nomenclature).
Definition: team.hpp:75
A variable-expanding proxy for the config class.
Definition: variable.hpp:45
A class that represents a TCP/IP connection to the wesnothd server.
Networked add-ons (campaignd) client interface.
Formula AI debugger.
Declarations for File-IO.
std::size_t i
Definition: function.cpp:1029
static std::string _(const char *str)
Definition: gettext.hpp:93
std::string label
What to show in the filter's drop-down list.
Definition: manager.cpp:201
std::string id
Text to match against addon_info.tags()
Definition: manager.cpp:199
This file contains the window object, this object is a top level container which has the event manage...
std::map< std::string, addon_info > addons_list
Definition: info.hpp:27
bool load_language_list()
Definition: language.cpp:103
Defines the exception classes for the layout algorithm.
#define PLAIN_LOG
Definition: log.hpp:297
map_generator * create_map_generator(const std::string &name, const config &cfg, const config *vars)
Definition: map_create.cpp:28
Various uncategorised dialogs.
void point(int x, int y)
Draw a single point.
Definition: draw.cpp:209
bool delete_file(const std::string &filename)
std::string read_file(const std::string &fname)
Basic disk I/O - read file.
void write_file(const std::string &fname, const std::string &data, std::ios_base::openmode mode)
Throws io_exception if an error occurs.
Game configuration data as global variables.
Definition: build_info.cpp:61
std::string path
Definition: filesystem.cpp:92
bool addon_server_info
Definition: game_config.cpp:79
void load_config(const config &v)
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:64
void remove()
Removes a tip.
Definition: tooltip.cpp:94
std::string get_modal_dialog_id(const modal_dialog &dialog)
Definition: test_gui2.cpp:178
std::string get_modeless_dialog_id(const modeless_dialog &dialog)
Definition: test_gui2.cpp:183
Generic file dialog.
std::set< std::string > & registered_window_types()
Returns the list of registered windows.
bool new_widgets
Do we wish to use the new library or not.
Definition: settings.cpp:23
logger & info()
Definition: log.cpp:319
void send_to_server(const config &data)
Attempts to send given data to server if a connection is open.
game_display & get_fake_display(const int width, const int height)
Gets a fake test display.
std::string get_unknown_exception_type()
Utility function for finding the type of thing caught with catch(...).
Definition: general.cpp:23
std::vector< std::string > split(const config_attribute_value &val)
std::string_view data
Definition: picture.cpp:178
Replay control code.
This file contains the settings handling of the widget library.
std::string filename
Filename.
The basic class for representing 8-bit RGB or RGBA colour values.
Definition: color.hpp:59
The paths manager is responsible for recording the various paths that binary files may be located at.
Definition: filesystem.hpp:440
Exception thrown when the height resizing has failed.
Exception thrown when the width has been modified during resizing.
Exception thrown when the width resizing has failed.
This class represents the information a client has about another player.
Definition: lobby_data.hpp:30
static config main_config
Definition: test_gui2.cpp:166
std::unique_ptr< game_config_manager > config_manager
Definition: test_gui2.cpp:168
std::vector< std::string > dummy_args
Definition: test_gui2.cpp:169
static const std::string widgets_file
Definition: test_gui2.cpp:167
t_string name
Definition: theme.hpp:39
t_string description
Definition: theme.hpp:40
std::string id
Definition: theme.hpp:38
Helper class, don't construct this directly.
mock_char c
BOOST_AUTO_TEST_CASE(modal_dialog_test_addon_auth)
Definition: test_gui2.cpp:395
BOOST_FIXTURE_TEST_SUITE(test_map_location, MLFixture)
static map_location::direction s
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...
#define e
#define b