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