The Battle for Wesnoth  1.19.0-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"
82 #include "gui/dialogs/message.hpp"
97 #include "gui/dialogs/outro.hpp"
98 #include "gui/dialogs/prompt.hpp"
109 #include "gui/dialogs/tooltip.hpp"
114 #include "gui/dialogs/unit_list.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) {
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  }
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) {
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_hotkey_bind)
522 {
523  test<hotkey_bind>();
524 }
525 BOOST_AUTO_TEST_CASE(modal_dialog_test_install_dependencies)
526 {
527  test<install_dependencies>();
528 }
529 BOOST_AUTO_TEST_CASE(modal_dialog_test_language_selection)
530 {
531  test<language_selection>();
532 }
533 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_lobby)
534 {
535  test<mp_lobby>();
536 }
537 BOOST_AUTO_TEST_CASE(modal_dialog_test_lobby_player_info)
538 {
539  test<lobby_player_info>();
540 }
541 BOOST_AUTO_TEST_CASE(modal_dialog_test_log_settings)
542 {
543  test<log_settings>();
544 }
545 BOOST_AUTO_TEST_CASE(modal_dialog_test_message)
546 {
547  test<message>();
548 }
549 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_alerts_options)
550 {
551  test<mp_alerts_options>();
552 }
553 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_connect)
554 {
555  test<mp_connect>();
556 }
557 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_join_game_password_prompt)
558 {
559  test<mp_join_game_password_prompt>();
560 }
561 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_login)
562 {
563  test<mp_login>();
564 }
565 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_method_selection)
566 {
567  test<mp_method_selection>();
568 }
569 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_report)
570 {
571  test<mp_report>();
572 }
573 BOOST_AUTO_TEST_CASE(modal_dialog_test_simple_item_selector)
574 {
575  test<simple_item_selector>();
576 }
577 BOOST_AUTO_TEST_CASE(modal_dialog_test_screenshot_notification)
578 {
579  test<screenshot_notification>();
580 }
581 BOOST_AUTO_TEST_CASE(modal_dialog_test_select_orb_colors)
582 {
583  test<select_orb_colors>();
584 }
585 BOOST_AUTO_TEST_CASE(modal_dialog_test_statistics_dialog)
586 {
587  test<statistics_dialog>();
588 }
589 BOOST_AUTO_TEST_CASE(modal_dialog_test_surrender_quit)
590 {
591  test<surrender_quit>();
592 }
593 BOOST_AUTO_TEST_CASE(modal_dialog_test_theme_list)
594 {
595  test<theme_list>();
596 }
597 BOOST_AUTO_TEST_CASE(modal_dialog_test_transient_message)
598 {
599  test<transient_message>();
600 }
601 BOOST_AUTO_TEST_CASE(modal_dialog_test_unit_create)
602 {
603  test<unit_create>();
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(modeless_dialog_test_debug_clock)
630 {
631  test_popup<debug_clock>();
632 }
633 BOOST_AUTO_TEST_CASE(tooltip_test_tooltip_large)
634 {
635  test_tip("tooltip_large");
636 }
637 BOOST_AUTO_TEST_CASE(tooltip_test_tooltip)
638 {
639  test_tip("tooltip");
640 }
641 BOOST_AUTO_TEST_CASE(modal_dialog_test_tod_new_schedule)
642 {
643  test<tod_new_schedule>();
644 }
645 
646 // execute last - checks that there aren't any unaccounted for GUIs
648 {
649  std::set<std::string> widget_list = gui2::registered_window_types();
650  std::vector<std::string> widgets_tested = utils::split(filesystem::read_file(test_gui2_fixture::widgets_file));
651  std::set<std::string> omitted {
652  /*
653  * The unit attack unit test are disabled for now, they calling parameters
654  * don't allow 'nullptr's needs to be fixed.
655  */
656  "unit_attack",
657  // No test for this right now, not sure how to use the test system
658  // for dialog with no default constructor
659  "lua_interpreter",
660  /*
661  * Disable label settings dialog test because we need a display_context
662  * object, which we don't have, and it's a lot of work to produce a dummy
663  * one.
664  */
665  "label_settings",
666  "addon_uninstall_list",
667  "addon_manager",
668  "loading_screen",
669  "network_transmission",
670  "synched_choice_wait",
671  "drop_down_menu",
672  "preferences_dialog",
673  "unit_recruit",
674  "unit_recall",
675  "unit_list",
676  "unit_advance",
677  "mp_host_game_prompt",
678  "mp_create_game",
679  // The title screen appears to be throwing a bad_alloc on Travis, so disable it for now
680  "title_screen",
681  "end_credits",
682  "mp_staging",
683  "mp_join_game",
684  "terrain_layers",
685  "attack_predictions",
686  "help_browser",
687  "story_viewer",
688  "outro",
689  "mp_change_control", // Basically useless without a game_board object, so disabling
690  "game_stats", // segfault with LTO
691  "gamestate_inspector", // segfault with LTO
692  "server_info",
693  "sp_options_configure",// segfault with LTO
694  "campaign_selection",// segfault with LTO
695  "game_load",// segfault after disabling the above tests
696  "file_progress",
697  };
699 
700  for(const std::string& item : widgets_tested)
701  {
702  widget_list.erase(item);
703  PLAIN_LOG << "Checking widget " << item;
704  BOOST_CHECK_EQUAL(omitted.count(item), 0);
705  }
706  for(const std::string& item : omitted)
707  {
708  widget_list.erase(item);
709  }
710 
711  // Test size() instead of empty() to get the number of offenders
712  BOOST_CHECK_EQUAL(widget_list.size(), 0);
713  for(const std::string& id : widget_list) {
714  PLAIN_LOG << "Window '" << id << "' registered but not tested.";
715  }
716 }
717 
718 BOOST_AUTO_TEST_CASE(test_make_test_fake)
719 {
721 
722  try {
723  message dlg("title", "message", true, false, false);
724  dlg.show(1);
725  } catch(const wml_exception& e) {
726  BOOST_CHECK(e.user_message == _("Failed to show a dialog, which doesn't fit on the screen."));
727  return;
728  } catch(...) {
729  BOOST_ERROR("Didn't catch the wanted exception, instead caught " << utils::get_unknown_exception_type() << ".");
730  }
731  BOOST_ERROR("Didn't catch the wanted exception, instead caught nothing.");
732 }
733 
734 BOOST_AUTO_TEST_SUITE_END()
735 
736 namespace {
737 
738 template<>
739 struct dialog_tester<addon_auth>
740 {
741  config cfg;
742  addon_auth* create()
743  {
744  return new addon_auth(cfg);
745  }
746 };
747 
748 template<>
749 struct dialog_tester<addon_connect>
750 {
751  std::string host_name = "host_name";
752  addon_connect* create()
753  {
754  return new addon_connect(host_name, true);
755  }
756 };
757 
758 template<>
759 struct dialog_tester<addon_license_prompt>
760 {
761  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.
762 
763 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.)";
764  addon_license_prompt* create()
765  {
766  return new addon_license_prompt(license_terms);
767  }
768 };
769 
770 template<>
771 struct dialog_tester<addon_manager>
772 {
773  dialog_tester()
774  {
776  }
777  addon_manager* create()
778  {
779  addons_client client("localhost:15999");
780  return new addon_manager(client);
781  }
782 };
783 
784 template<>
785 struct dialog_tester<campaign_difficulty>
786 {
787  campaign_difficulty* create()
788  {
789  const config items("difficulty");
790 
791  return new campaign_difficulty(items);
792  }
793 };
794 
795 template<>
796 struct dialog_tester<campaign_selection>
797 {
798  saved_game state;
800  dialog_tester() : state(config {"campaign_type", "scenario"}), ng(state)
801  {
802  }
803  campaign_selection* create()
804  {
805  return new campaign_selection(ng);
806  }
807 };
808 
809 template<>
810 struct dialog_tester<chat_log>
811 {
812  config cfg;
813  vconfig vcfg;
814  replay_recorder_base rbase;
815  replay r;
816  dialog_tester() : vcfg(cfg), r(rbase) {}
817  chat_log* create()
818  {
819  return new chat_log(vcfg, r);
820  }
821 };
822 
823 template<>
824 struct dialog_tester<editor_choose_addon>
825 {
826  std::string temp;
827  editor_choose_addon* create()
828  {
829  return new editor_choose_addon(temp);
830  }
831 };
832 
833 template<>
834 struct dialog_tester<prompt>
835 {
836  std::string temp;
837  prompt* create()
838  {
839  return new prompt(temp);
840  }
841 };
842 
843 template<>
844 struct dialog_tester<core_selection>
845 {
846  std::vector<config> cores;
847  dialog_tester()
848  {
849  cores.resize(1);
850  }
851  core_selection* create()
852  {
853  return new core_selection(cores, 0);
854  }
855 };
856 
857 template<>
858 struct dialog_tester<custom_tod>
859 {
860  std::vector<time_of_day> times;
861  int current_tod = 0;
862  dialog_tester()
863  {
864  times.resize(1);
865  }
866  custom_tod* create()
867  {
868  return new custom_tod(times, current_tod);
869  }
870 };
871 
872 template<>
873 struct dialog_tester<edit_label>
874 {
875  std::string label = "Label text to modify";
876  bool team_only = false;
877  edit_label* create()
878  {
879  return new edit_label(label, team_only);
880  }
881 };
882 
883 template<>
884 struct dialog_tester<edit_text>
885 {
886  std::string text = "text to modify";
887  edit_text* create()
888  {
889  return new edit_text("title", "label", text);
890  }
891 };
892 
893 template<>
894 struct dialog_tester<editor_edit_label>
895 {
896  std::string label = "Label text to modify";
897  std::string category = "test";
898  bool immutable = false, fog = false, shroud = false;
899  color_t color;
900  editor_edit_label* create()
901  {
902  return new editor_edit_label(label, immutable, fog, shroud, color, category);
903  }
904 };
905 
906 template<>
907 struct dialog_tester<editor_edit_pbl>
908 {
909  std::string temp;
910  std::string temp1;
911  editor_edit_pbl* create()
912  {
913  return new editor_edit_pbl(temp, temp1);
914  }
915 };
916 
917 template<>
918 struct dialog_tester<editor_edit_pbl_translation>
919 {
920  std::string temp1;
921  std::string temp2;
922  std::string temp3;
924  {
925  return new editor_edit_pbl_translation(temp1, temp2, temp3);
926  }
927 };
928 
929 template<>
930 struct dialog_tester<editor_edit_scenario>
931 {
932  std::string id, name, descr;
933  int turns = 0, xp_mod = 50;
934  bool defeat_enemies = false, random_start = false;
935  editor_edit_scenario* create()
936  {
937  return new editor_edit_scenario(id, name, descr, turns, xp_mod, defeat_enemies, random_start);
938  }
939 };
940 
941 template<>
942 struct dialog_tester<editor_edit_side>
943 {
944  team t;
946  dialog_tester() : info(t) {}
947  editor_edit_side* create()
948  {
949  return new editor_edit_side(info);
950  }
951 };
952 
953 template<>
954 struct dialog_tester<formula_debugger>
955 {
956  wfl::formula_debugger debugger;
957  formula_debugger* create()
958  {
959  return new formula_debugger(debugger);
960  }
961 };
962 
963 template<>
964 struct dialog_tester<game_load>
965 {
966  config cfg;
967  game_config_view view;
968  // It would be good to have a test directory instead of using the same directory as the player,
969  // however this code will support that - default_saves_dir() will respect --userdata-dir.
971  dialog_tester()
972  {
973  /** @todo Would be nice to add real data to the config. */
974  }
975  game_load* create()
976  {
977  view = game_config_view::wrap(cfg);
978  return new game_load(view, data);
979  }
980 
981 };
982 
983 template<>
984 struct dialog_tester<game_save>
985 {
986  std::string title = "Title";
987  std::string filename = "filename";
988  game_save* create()
989  {
990  return new game_save(title, filename);
991  }
992 
993 };
994 
995 template<>
996 struct dialog_tester<game_save_message>
997 {
998  std::string title = "Title";
999  std::string filename = "filename";
1000  std::string message = "message";
1001  game_save_message* create()
1002  {
1003  return new game_save_message(title, filename, message);
1004  }
1005 
1006 };
1007 
1008 template<>
1009 struct dialog_tester<game_save_oos>
1010 {
1011  bool ignore_all = false;
1012  std::string title = "Title";
1013  std::string filename = "filename";
1014  std::string message = "message";
1015  game_save_oos* create()
1016  {
1017  return new game_save_oos(ignore_all, title, filename, message);
1018  }
1019 
1020 };
1021 
1022 template<>
1023 struct dialog_tester<install_dependencies>
1024 {
1025  addons_list addons;
1026  install_dependencies* create()
1027  {
1028  return new install_dependencies(addons);
1029  }
1030 };
1031 
1032 template<>
1033 struct dialog_tester<hotkey_bind>
1034 {
1035  std::string id = "";
1036 
1037  hotkey_bind* create()
1038  {
1039  return new hotkey_bind(id);
1040  }
1041 };
1042 
1043 template<>
1044 struct dialog_tester<mp_lobby>
1045 {
1047  wesnothd_connection connection;
1048  mp::lobby_info li;
1049  int selected_game;
1050  dialog_tester() : connection("", ""), li()
1051  {
1052  }
1053  mp_lobby* create()
1054  {
1055  return new mp_lobby(li, connection, selected_game);
1056  }
1057 };
1058 
1059 template<>
1060 struct dialog_tester<mp_match_history>
1061 {
1062  wesnothd_connection connection;
1063  dialog_tester() : connection("", "")
1064  {
1065  }
1066  mp_match_history* create()
1067  {
1068  return new mp_match_history("", connection, false);
1069  }
1070 };
1071 
1072 class fake_chat_handler : public events::chat_handler {
1073  void add_chat_message(const std::time_t&,
1074  const std::string&, int, const std::string&,
1075  MESSAGE_TYPE) {}
1076  void send_chat_message(const std::string&, bool) {}
1077  void send_to_server(const config&) {}
1078  void clear_messages() {}
1079 };
1080 
1081 template<>
1082 struct dialog_tester<lobby_player_info>
1083 {
1084  config c;
1085  fake_chat_handler ch;
1086  wesnothd_connection connection;
1087  mp::user_info ui;
1088  mp::lobby_info li;
1089  dialog_tester()
1090  : connection("", "")
1091  , ui(c), li()
1092  {
1093  }
1094  lobby_player_info* create()
1095  {
1096  return new lobby_player_info(ch, ui, li);
1097  }
1098 };
1099 
1100 template<>
1101 struct dialog_tester<log_settings>
1102 {
1103  log_settings* create()
1104  {
1105  return new log_settings();
1106  }
1107 };
1108 
1109 template<>
1110 struct dialog_tester<message>
1111 {
1112  message* create()
1113  {
1114  return new message("Title", "Message", false, false, false);
1115  }
1116 };
1117 
1118 template<>
1119 struct dialog_tester<mp_create_game>
1120 {
1121  saved_game state;
1122  dialog_tester() : state(config {"campaign_type", "multiplayer"})
1123  {
1124  }
1125  mp_create_game* create()
1126  {
1127  return new mp_create_game(state, true);
1128  }
1129 };
1130 
1131 template<>
1132 struct dialog_tester<mp_join_game_password_prompt>
1133 {
1134  std::string password;
1136  {
1138  }
1139 };
1140 
1141 template<>
1142 struct dialog_tester<mp_report>
1143 {
1144  std::string report_text;
1145  mp_report* create()
1146  {
1147  return new mp_report(report_text);
1148  }
1149 };
1150 
1151 static std::vector<std::string> depcheck_mods {"mod_one", "some other", "more"};
1152 
1153 template<>
1154 struct dialog_tester<depcheck_confirm_change>
1155 {
1156  depcheck_confirm_change* create()
1157  {
1158  return new depcheck_confirm_change(true, depcheck_mods, "requester");
1159  }
1160 };
1161 
1162 template<>
1163 struct dialog_tester<depcheck_select_new>
1164 {
1165  depcheck_select_new* create()
1166  {
1167  return new depcheck_select_new(ng::depcheck::MODIFICATION, depcheck_mods);
1168  }
1169 };
1170 
1171 template<>
1172 struct dialog_tester<mp_login>
1173 {
1174  mp_login* create()
1175  {
1176  return new mp_login("wesnoth.org", "label", true);
1177  }
1178 };
1179 
1180 template<>
1181 struct dialog_tester<simple_item_selector>
1182 {
1183  simple_item_selector* create()
1184  {
1185  return new simple_item_selector("title", "message", std::vector<std::string>(), false, false);
1186  }
1187 };
1188 
1189 template<>
1190 struct dialog_tester<screenshot_notification>
1191 {
1192  screenshot_notification* create()
1193  {
1194  return new screenshot_notification("path", nullptr);
1195  }
1196 };
1197 
1198 template<>
1199 struct dialog_tester<theme_list>
1200 {
1201  static theme_info make_theme(const std::string& name)
1202  {
1203  theme_info ti;
1204  ti.id = name;
1205  ti.name = name;
1206  ti.description = name + " this is a description";
1207  return ti;
1208  }
1209  static std::vector<theme_info> themes;
1210  theme_list* create()
1211  {
1212  return new theme_list(themes, 0);
1213  }
1214 };
1215 std::vector<theme_info> dialog_tester<theme_list>::themes {make_theme("classic"), make_theme("new"), make_theme("more"), make_theme("themes")};
1216 
1217 template<>
1218 struct dialog_tester<editor_generate_map>
1219 {
1220  std::vector<std::unique_ptr<map_generator>> map_generators;
1221  editor_generate_map* create()
1222  {
1223  for(const config &i : test_gui2_fixture::main_config.child_range("multiplayer")) {
1224  if(i["scenario_generation"] == "default") {
1225  auto generator_cfg = i.optional_child("generator");
1226  if (generator_cfg) {
1227  map_generators.emplace_back(create_map_generator("", *generator_cfg));
1228  }
1229  }
1230  }
1231 
1232  editor_generate_map* result = new editor_generate_map(map_generators);
1233  BOOST_REQUIRE_MESSAGE(result, "Failed to create a dialog.");
1234 
1235  return result;
1236  }
1237 };
1238 
1239 template<>
1240 struct dialog_tester<editor_new_map>
1241 {
1242  int width = 10;
1243  int height = 10;
1244  editor_new_map* create()
1245  {
1246  return new editor_new_map("Test", width, height);
1247  }
1248 };
1249 
1250 template<>
1251 struct dialog_tester<editor_resize_map>
1252 {
1253  int width = 0;
1254  int height = 0;
1256  bool copy = false;
1257  editor_resize_map* create()
1258  {
1259  return new editor_resize_map(width, height, expand_direction, copy);
1260  }
1261 };
1262 
1263 template<>
1264 struct dialog_tester<file_dialog>
1265 {
1266  file_dialog* create()
1267  {
1268  return new file_dialog();
1269  }
1270 };
1271 
1272 template<>
1273 struct dialog_tester<folder_create>
1274 {
1275  std::string folder_name;
1276  folder_create* create()
1277  {
1278  return new folder_create(folder_name);
1279  }
1280 };
1281 
1282 template<>
1283 struct dialog_tester<transient_message>
1284 {
1285  transient_message* create()
1286  {
1287  return new transient_message("Title", false, "Message", false, "");
1288  }
1289 };
1290 
1291 template<>
1292 struct dialog_tester<title_screen>
1293 {
1294  std::vector<std::string> args;
1295  commandline_options opts;
1297  dialog_tester() : opts(args), game(opts) {}
1298  title_screen* create()
1299  {
1300  return new title_screen(game);
1301  }
1302 };
1303 
1304 template<>
1305 struct dialog_tester<wml_error>
1306 {
1307  static std::vector<std::string> files;
1308  wml_error* create()
1309  {
1310  return new wml_error("Summary", "Post summary", files, "Details");
1311  }
1312 };
1313 std::vector<std::string> dialog_tester<wml_error>::files {"some", "files", "here"};
1314 
1315 template<>
1316 struct dialog_tester<wml_message_left>
1317 {
1318  wml_message_left* create()
1319  {
1320  return new wml_message_left("Title", "Message", "", false);
1321  }
1322 };
1323 
1324 template<>
1325 struct dialog_tester<wml_message_right>
1326 {
1327  wml_message_right* create()
1328  {
1329  return new wml_message_right("Title", "Message", "", false);
1330  }
1331 };
1332 
1333 template<>
1334 struct dialog_tester<wml_message_double>
1335 {
1336  wml_message_double* create()
1337  {
1338  return new wml_message_double("Title", "Message", "", false, "", true);
1339  }
1340 };
1341 
1342 template<>
1343 struct dialog_tester<faction_select>
1344 {
1345  config era_cfg, side_cfg;
1346  std::vector<const config*> eras;
1347  ng::flg_manager flg;
1348  std::string color;
1349  dialog_tester()
1350  : era_cfg(), side_cfg(), eras(1, &era_cfg) // TODO: Add an actual era definition
1351  , flg(eras, side_cfg, false, false, false)
1352  , color("teal")
1353  {}
1354  faction_select* create() {
1355  return new faction_select(flg, color, 1);
1356  }
1357 };
1358 
1359 template<>
1360 struct dialog_tester<generator_settings>
1361 {
1362  config cfg;
1364  dialog_tester() : data(cfg) {}
1365  generator_settings* create()
1366  {
1367  return new generator_settings(data);
1368  }
1369 };
1370 
1371 template<>
1372 struct dialog_tester<sp_options_configure>
1373 {
1374  saved_game state;
1375  ng::create_engine create_eng;
1376  ng::configure_engine config_eng;
1377  dialog_tester() : create_eng(state)
1378  , config_eng(create_eng.get_state()) {}
1379  sp_options_configure* create()
1380  {
1381  return new sp_options_configure(create_eng, config_eng);
1382  }
1383 };
1384 
1385 template<>
1386 struct dialog_tester<statistics_dialog>
1387 {
1388  team t;
1390  statistics_t stats;
1391  dialog_tester() : t() , stats_record(), stats(stats_record) {}
1392  statistics_dialog* create()
1393  {
1394  return new statistics_dialog(stats, t);
1395  }
1396 };
1397 
1398 template<>
1399 struct dialog_tester<surrender_quit>
1400 {
1401  dialog_tester() {}
1402  surrender_quit* create()
1403  {
1404  return new surrender_quit();
1405  }
1406 };
1407 
1408 template<>
1409 struct dialog_tester<tod_new_schedule>
1410 {
1411  std::string id = "id";
1412  std::string name = "name";
1413  dialog_tester() {}
1414  tod_new_schedule* create()
1415  {
1416  return new tod_new_schedule(id, name);
1417  }
1418 };
1419 
1420 } // 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:159
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)
This shows the dialog to provide a password when uploading an add-on.
Definition: addon_auth.hpp:32
This shows the dialog for managing addons and connecting to the addon server.
Definition: connect.hpp:34
Shows the list of addons on the server available for installation.
Definition: manager.hpp:50
The campaign mode difficulty menu.
This shows the dialog which allows the user to choose which campaign to play.
This shows the dialog which allows the user to choose which core to play.
This shows the dialog to modify tod schedules.
Definition: custom_tod.hpp:49
Asks the user to confirm a change required to proceed.
Offers a list of compatible items if a currently selected one is incompatible.
Dialog for editing gamemap labels.
Definition: edit_label.hpp:34
Dialog for renaming units in-game.
Definition: edit_text.hpp:32
Dialog for adding a translation while editing an add-on's _server.pbl.
Dialog for editing gamemap labels.
Definition: edit_label.hpp:34
Dialog for adding a translation while editing an add-on's _server.pbl.
Dialog for editing an add-on's _server.pbl.
Definition: edit_pbl.hpp:46
Dialog for editing gamemap scenarios.
Dialog for editing gamemap sides.
Definition: edit_side.hpp:40
The dialog for selecting which random generator to use in the editor.
This shows the dialog to resize the current map.
Definition: resize_map.hpp:50
Dialog for providing the name of a new folder to create.
This shows the debugger for the formulas.
This shows the dialog to select and load a savegame file.
Definition: game_load.hpp:48
This shows the dialog to create a savegame file.
Definition: game_save.hpp:33
Main class to show messages to the user.
Definition: message.hpp:36
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.
Dialog for entering a password for joining a password-protected MP game.
This shows the dialog to log in to the MP server.
Definition: mp_login.hpp:41
This shows a dialog to report players on the multiplayer server.
Definition: mp_report.hpp:35
Dialog for getting a single text value from the player.
Definition: prompt.hpp:34
Notification dialog used after saving a game or map screenshot to display information about it for th...
A simple one-column listbox with OK and Cancel buttons.
This shows the dialog to confirm surrender and/or quitting the game.
Dialog for selecting a GUI theme.
Definition: theme_list.hpp:36
This class implements the title screen.
Dialog that takes new schedule ID and name from the player.
Shows a transient message.
WML preprocessor/parser error report dialog.
Definition: wml_error.hpp:36
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:63
void draw()
Draws the window.
Definition: window.cpp:606
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:208
This class stores all the data for a single 'side' (in game nomenclature).
Definition: team.hpp:74
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:968
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:209
std::string id
Text to match against addon_info.tags()
Definition: manager.cpp:207
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:295
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:60
std::string path
Definition: filesystem.cpp:83
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:79
void remove()
Removes a tip.
Definition: tooltip.cpp:109
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
std::pair< std::string, unsigned > item
Definition: help_impl.hpp:412
logger & info()
Definition: log.cpp:314
const std::vector< std::string > items
void send_to_server(const config &data)
Attempts to send given data to server if a connection is open.
bool fog()
Definition: game.cpp:522
bool shroud()
Definition: game.cpp:532
std::string password(const std::string &server, const std::string &login)
point resolution()
Definition: general.cpp:392
int turns()
Definition: game.cpp:542
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:194
Replay control code.
This file contains the settings handling of the widget library.
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:398
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:38
t_string description
Definition: theme.hpp:39
std::string id
Definition: theme.hpp:37
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