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