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