The Battle for Wesnoth  1.19.10+dev
test_gui2.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2025
3  by Mark de Wever <koraq@xs4all.nl>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 // In this domain since it compares a shared string from this domain.
17 #define GETTEXT_DOMAIN "wesnoth-lib"
18 
19 #include "addon/client.hpp"
20 #include "addon/info.hpp"
21 #include "config_cache.hpp"
22 #include "filesystem.hpp"
23 #include "formula/debugger.hpp"
24 #include "game_config.hpp"
25 #include "game_config_manager.hpp"
26 #include "game_config_view.hpp"
27 #include "game_display.hpp"
28 #include "game_events/manager.hpp"
32 #include "game_launcher.hpp"
34 #include "gettext.hpp"
46 #include "gui/dialogs/chat_log.hpp"
85 #include "gui/dialogs/message.hpp"
101 #include "gui/dialogs/outro.hpp"
102 #include "gui/dialogs/prompt.hpp"
114 #include "gui/dialogs/tooltip.hpp"
119 #include "gui/dialogs/wml_error.hpp"
121 #include "gui/widgets/settings.hpp"
122 #include "gui/widgets/window.hpp"
123 #include "language.hpp"
124 #include "map/map.hpp"
125 #include "replay.hpp"
126 #include "save_index.hpp"
127 #include "saved_game.hpp"
129 #include "terrain/type_data.hpp"
131 #include "utils/general.hpp"
132 #include "wesnothd_connection.hpp"
133 #include "wml_exception.hpp"
134 
135 #include <boost/test/unit_test.hpp>
136 
137 #include <functional>
138 #include <memory>
139 
140 using namespace gui2::dialogs;
141 
144  : config_manager()
145  , dummy_args({"wesnoth", "--noaddons"})
146  {
147  /** The main config, which contains the entire WML tree. */
148  game_config_view game_config_view_ = game_config_view::wrap(main_config);
149  config_manager.reset(new game_config_manager(dummy_args));
150 
152 
153  cache.clear_defines();
154  cache.add_define("EDITOR");
155  cache.add_define("MULTIPLAYER");
156  cache.get_config(game_config::path +"/data", main_config);
157 
158  const filesystem::binary_paths_manager bin_paths_manager(game_config_view_);
159 
161  game_config::load_config(main_config.mandatory_child("game_config"));
162  }
164  {
165  }
167  static const std::string widgets_file;
168  std::unique_ptr<game_config_manager> config_manager;
169  std::vector<std::string> dummy_args;
170 };
172 const std::string test_gui2_fixture::widgets_file = "widgets_tested.log";
173 
174 namespace gui2 {
175 
176 namespace dialogs {
177 
178 std::string get_modal_dialog_id(const modal_dialog& dialog)
179 {
180  return dialog.window_id();
181 }
182 
183 std::string get_modeless_dialog_id(const modeless_dialog& dialog)
184 {
185  return dialog.window_id();
186 }
187 
188 } // namespace dialogs
189 } // namespace gui2
190 
191 namespace {
192 
193  /**
194  * Helper class to generate a dialog.
195  *
196  * This class makes sure the dialog is properly created and initialized.
197  * The specialized versions are at the end of this file.
198  */
199  template<class T>
200  struct dialog_tester
201  {
202  T* create() { return new T(); }
203  };
204 
205  typedef std::pair<unsigned, unsigned> resolution;
206  typedef std::vector<std::pair<unsigned, unsigned>> resolution_list;
207 
208  template<class T>
209  void test_resolutions(const resolution_list& resolutions)
210  {
211  for(const resolution& resolution : resolutions) {
212  test_utils::get_fake_display(resolution.first, resolution.second);
213 
214  dialog_tester<T> ctor;
215  const std::unique_ptr<modal_dialog> dlg(ctor.create());
216  BOOST_REQUIRE_MESSAGE(dlg.get(), "Failed to create a dialog.");
217 
218  std::string id = get_modal_dialog_id(*dlg.get());
219  filesystem::write_file(test_gui2_fixture::widgets_file, ","+id, std::ios_base::app);
220 
221  std::string exception;
222  try {
223  dlg->show(1);
224  } catch(const gui2::layout_exception_width_modified&) {
225  exception = "gui2::layout_exception_width_modified";
227  exception = "gui2::layout_exception_width_resize_failed";
229  exception = "gui2::layout_exception_height_resize_failed";
230  } catch(const wml_exception& e) {
231  exception = e.dev_message;
232  } catch(const std::exception& e) {
233  exception = e.what();
234  } catch(...) {
235  exception = utils::get_unknown_exception_type();
236  }
237  BOOST_CHECK_MESSAGE(exception.empty(),
238  "Test for '" << id
239  << "' Failed\nnew widgets = " << gui2::new_widgets
240  << " resolution = " << resolution.first
241  << 'x' << resolution.second
242  << "\nException caught: " << exception << '.');
243  }
244  }
245 
246  template<class T>
247  void test_popup_resolutions(const resolution_list& resolutions)
248  {
249  bool interact = false;
250  for(int i = 0; i < 2; ++i) {
251  for(const resolution& resolution : resolutions) {
252  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) {
739  BOOST_CHECK(e.user_message == _("Failed to show a dialog, which doesn’t fit on the screen."));
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  game_config_view view;
993  // It would be good to have a test directory instead of using the same directory as the player,
994  // however this code will support that - default_saves_dir() will respect --userdata-dir.
996  dialog_tester()
997  {
998  /** @todo Would be nice to add real data to the config. */
999  }
1000  game_load* create()
1001  {
1002  view = game_config_view::wrap(cfg);
1003  return new game_load(view, data);
1004  }
1005 
1006 };
1007 
1008 template<>
1009 struct dialog_tester<game_save>
1010 {
1011  std::string title = "Title";
1012  std::string filename = "filename";
1013  game_save* create()
1014  {
1015  return new game_save(title, filename);
1016  }
1017 
1018 };
1019 
1020 template<>
1021 struct dialog_tester<game_save_message>
1022 {
1023  std::string title = "Title";
1024  std::string filename = "filename";
1025  std::string message = "message";
1026  game_save_message* create()
1027  {
1028  return new game_save_message(title, filename, message);
1029  }
1030 
1031 };
1032 
1033 template<>
1034 struct dialog_tester<game_save_oos>
1035 {
1036  bool ignore_all = false;
1037  std::string title = "Title";
1038  std::string filename = "filename";
1039  std::string message = "message";
1040  game_save_oos* create()
1041  {
1042  return new game_save_oos(ignore_all, title, filename, message);
1043  }
1044 
1045 };
1046 
1047 template<>
1048 struct dialog_tester<install_dependencies>
1049 {
1050  addons_list addons;
1051  install_dependencies* create()
1052  {
1053  return new install_dependencies(addons);
1054  }
1055 };
1056 
1057 template<>
1058 struct dialog_tester<hotkey_bind>
1059 {
1060  std::string id = "";
1061 
1062  hotkey_bind* create()
1063  {
1064  return new hotkey_bind(id);
1065  }
1066 };
1067 
1068 template<>
1069 struct dialog_tester<mp_lobby>
1070 {
1072  wesnothd_connection connection;
1073  mp::lobby_info li;
1074  int selected_game;
1075  dialog_tester() : connection("", ""), li()
1076  {
1077  }
1078  mp_lobby* create()
1079  {
1080  return new mp_lobby(li, connection, selected_game);
1081  }
1082 };
1083 
1084 template<>
1085 struct dialog_tester<mp_match_history>
1086 {
1087  wesnothd_connection connection;
1088  dialog_tester() : connection("", "")
1089  {
1090  }
1091  mp_match_history* create()
1092  {
1093  return new mp_match_history("", connection, false);
1094  }
1095 };
1096 
1097 template<>
1098 struct dialog_tester<gui2::dialogs::migrate_version_selection>
1099 {
1101  {
1103  }
1104 };
1105 
1106 class fake_chat_handler : public events::chat_handler {
1107  void add_chat_message(const std::time_t&,
1108  const std::string&, int, const std::string&,
1109  MESSAGE_TYPE) {}
1110  void send_chat_message(const std::string&, bool) {}
1111  void send_to_server(const config&) {}
1112  void clear_messages() {}
1113 };
1114 
1115 template<>
1116 struct dialog_tester<lobby_player_info>
1117 {
1118  config c;
1119  fake_chat_handler ch;
1120  wesnothd_connection connection;
1121  mp::user_info ui;
1122  mp::lobby_info li;
1123  dialog_tester()
1124  : connection("", "")
1125  , ui(c), li()
1126  {
1127  }
1128  lobby_player_info* create()
1129  {
1130  return new lobby_player_info(ch, ui, li);
1131  }
1132 };
1133 
1134 template<>
1135 struct dialog_tester<log_settings>
1136 {
1137  log_settings* create()
1138  {
1139  return new log_settings();
1140  }
1141 };
1142 
1143 template<>
1144 struct dialog_tester<message>
1145 {
1146  message* create()
1147  {
1148  return new message("Title", "Message", false, false, false);
1149  }
1150 };
1151 
1152 template<>
1153 struct dialog_tester<mp_create_game>
1154 {
1155  saved_game state;
1156  dialog_tester() : state(config {"campaign_type", "multiplayer"})
1157  {
1158  }
1159  mp_create_game* create()
1160  {
1161  return new mp_create_game(state, true);
1162  }
1163 };
1164 
1165 template<>
1166 struct dialog_tester<mp_join_game_password_prompt>
1167 {
1168  std::string password;
1170  {
1171  return new mp_join_game_password_prompt(password);
1172  }
1173 };
1174 
1175 template<>
1176 struct dialog_tester<mp_report>
1177 {
1178  std::string report_text;
1179  mp_report* create()
1180  {
1181  return new mp_report(report_text);
1182  }
1183 };
1184 
1185 static std::vector<std::string> depcheck_mods {"mod_one", "some other", "more"};
1186 
1187 template<>
1188 struct dialog_tester<depcheck_confirm_change>
1189 {
1190  depcheck_confirm_change* create()
1191  {
1192  return new depcheck_confirm_change(true, depcheck_mods, "requester");
1193  }
1194 };
1195 
1196 template<>
1197 struct dialog_tester<depcheck_select_new>
1198 {
1199  depcheck_select_new* create()
1200  {
1201  return new depcheck_select_new(ng::depcheck::MODIFICATION, depcheck_mods);
1202  }
1203 };
1204 
1205 template<>
1206 struct dialog_tester<mp_login>
1207 {
1208  mp_login* create()
1209  {
1210  return new mp_login("wesnoth.org", "label", true);
1211  }
1212 };
1213 
1214 template<>
1215 struct dialog_tester<simple_item_selector>
1216 {
1217  simple_item_selector* create()
1218  {
1219  return new simple_item_selector("title", "message", std::vector<std::string>(), false, false);
1220  }
1221 };
1222 
1223 template<>
1224 struct dialog_tester<screenshot_notification>
1225 {
1226  screenshot_notification* create()
1227  {
1228  return new screenshot_notification("path", nullptr);
1229  }
1230 };
1231 
1232 template<>
1233 struct dialog_tester<theme_list>
1234 {
1235  static theme_info make_theme(const std::string& name)
1236  {
1237  theme_info ti;
1238  ti.id = name;
1239  ti.name = name;
1240  ti.description = name + " this is a description";
1241  return ti;
1242  }
1243  static std::vector<theme_info> themes;
1244  theme_list* create()
1245  {
1246  return new theme_list(themes, 0);
1247  }
1248 };
1249 std::vector<theme_info> dialog_tester<theme_list>::themes {make_theme("classic"), make_theme("new"), make_theme("more"), make_theme("themes")};
1250 
1251 template<>
1252 struct dialog_tester<editor_generate_map>
1253 {
1254  std::vector<std::unique_ptr<map_generator>> map_generators;
1255  editor_generate_map* create()
1256  {
1257  for(const config &i : test_gui2_fixture::main_config.child_range("multiplayer")) {
1258  if(i["scenario_generation"] == "default") {
1259  auto generator_cfg = i.optional_child("generator");
1260  if (generator_cfg) {
1261  map_generators.emplace_back(create_map_generator("", *generator_cfg));
1262  }
1263  }
1264  }
1265 
1266  editor_generate_map* result = new editor_generate_map(map_generators);
1267  BOOST_REQUIRE_MESSAGE(result, "Failed to create a dialog.");
1268 
1269  return result;
1270  }
1271 };
1272 
1273 template<>
1274 struct dialog_tester<editor_new_map>
1275 {
1276  int width = 10;
1277  int height = 10;
1278  editor_new_map* create()
1279  {
1280  return new editor_new_map("Test", width, height);
1281  }
1282 };
1283 
1284 template<>
1285 struct dialog_tester<editor_resize_map>
1286 {
1287  int width = 0;
1288  int height = 0;
1290  bool copy = false;
1291  editor_resize_map* create()
1292  {
1293  return new editor_resize_map(width, height, expand_direction, copy);
1294  }
1295 };
1296 
1297 template<>
1298 struct dialog_tester<file_dialog>
1299 {
1300  file_dialog* create()
1301  {
1302  return new file_dialog();
1303  }
1304 };
1305 
1306 template<>
1307 struct dialog_tester<folder_create>
1308 {
1309  std::string folder_name;
1310  folder_create* create()
1311  {
1312  return new folder_create(folder_name);
1313  }
1314 };
1315 
1316 template<>
1317 struct dialog_tester<transient_message>
1318 {
1319  transient_message* create()
1320  {
1321  return new transient_message("Title", false, "Message", false, "");
1322  }
1323 };
1324 
1325 template<>
1326 struct dialog_tester<title_screen>
1327 {
1328  std::vector<std::string> args;
1329  commandline_options opts;
1331  dialog_tester() : opts(args), game(opts) {}
1332  title_screen* create()
1333  {
1334  return new title_screen(game);
1335  }
1336 };
1337 
1338 template<>
1339 struct dialog_tester<wml_error>
1340 {
1341  static std::vector<std::string> files;
1342  wml_error* create()
1343  {
1344  return new wml_error("Summary", "Post summary", files, "Details");
1345  }
1346 };
1347 std::vector<std::string> dialog_tester<wml_error>::files {"some", "files", "here"};
1348 
1349 template<>
1350 struct dialog_tester<wml_message_left>
1351 {
1352  wml_message_left* create()
1353  {
1354  return new wml_message_left("Title", "Message", "", false);
1355  }
1356 };
1357 
1358 template<>
1359 struct dialog_tester<wml_message_right>
1360 {
1361  wml_message_right* create()
1362  {
1363  return new wml_message_right("Title", "Message", "", false);
1364  }
1365 };
1366 
1367 template<>
1368 struct dialog_tester<wml_message_double>
1369 {
1370  wml_message_double* create()
1371  {
1372  return new wml_message_double("Title", "Message", "", false, "", true);
1373  }
1374 };
1375 
1376 template<>
1377 struct dialog_tester<faction_select>
1378 {
1379  config era_cfg, side_cfg;
1380  std::vector<const config*> eras;
1381  ng::flg_manager flg;
1382  std::string color;
1383  dialog_tester()
1384  : era_cfg(), side_cfg(), eras(1, &era_cfg) // TODO: Add an actual era definition
1385  , flg(eras, side_cfg, false, false, false)
1386  , color("teal")
1387  {}
1388  faction_select* create() {
1389  return new faction_select(flg, color, 1);
1390  }
1391 };
1392 
1393 template<>
1394 struct dialog_tester<generator_settings>
1395 {
1396  config cfg;
1398  dialog_tester() : data(cfg) {}
1399  generator_settings* create()
1400  {
1401  return new generator_settings(data);
1402  }
1403 };
1404 
1405 template<>
1406 struct dialog_tester<sp_options_configure>
1407 {
1408  saved_game state;
1409  ng::create_engine create_eng;
1410  dialog_tester() : create_eng(state) {}
1411  sp_options_configure* create()
1412  {
1413  return new sp_options_configure(create_eng);
1414  }
1415 };
1416 
1417 template<>
1418 struct dialog_tester<statistics_dialog>
1419 {
1420  team t;
1422  statistics_t stats;
1423  dialog_tester() : t() , stats_record(), stats(stats_record) {}
1424  statistics_dialog* create()
1425  {
1426  return new statistics_dialog(stats, t);
1427  }
1428 };
1429 
1430 template<>
1431 struct dialog_tester<surrender_quit>
1432 {
1433  dialog_tester() {}
1434  surrender_quit* create()
1435  {
1436  return new surrender_quit();
1437  }
1438 };
1439 
1440 template<>
1441 struct dialog_tester<tod_new_schedule>
1442 {
1443  std::string id = "id";
1444  t_string name = "name";
1445  dialog_tester() {}
1446  tod_new_schedule* create()
1447  {
1448  return new tod_new_schedule(id, name);
1449  }
1450 };
1451 
1452 template<>
1453 struct dialog_tester<editor_edit_unit>
1454 {
1455  config cfg;
1456  game_config_view view;
1457 
1458  dialog_tester() {}
1459  editor_edit_unit* create()
1460  {
1461  config& units = cfg.add_child("units");
1462  cfg.add_child("race");
1463  config& movetype = units.add_child("movetype");
1464  movetype["name"] = "Test Movetype";
1465  movetype.add_child("defense");
1466  movetype.add_child("resistance");
1467  movetype.add_child("movement_costs");
1468  view = game_config_view::wrap(cfg);
1469  return new editor_edit_unit(view, "test_addon");
1470  }
1471 };
1472 
1473 template<>
1474 struct dialog_tester<gui_test_dialog>
1475 {
1476  dialog_tester() {}
1477  gui_test_dialog* create()
1478  {
1479  return new gui_test_dialog();
1480  }
1481 };
1482 
1483 } // namespace
double t
Definition: astarsearch.cpp:63
Add-ons (campaignd) client class.
Definition: client.hpp:41
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:158
config & add_child(config_key_type key)
Definition: config.cpp:436
Singleton class to manage game config file caching.
void add_define(const std::string &define)
Add a entry to preproc defines map.
static config_cache & instance()
Get reference to the singleton object.
void clear_defines()
Clear stored defines map to default values.
void get_config(const std::string &path, config &cfg, abstract_validator *validator=nullptr)
Gets a config object from given path.
A class grating read only view to a vector of config objects, viewed as one config with all children ...
static game_config_view wrap(const config &cfg)
Dialog that allows user to create custom unit types.
Definition: edit_unit.hpp:33
A test dialog for testing various gui2 features.
Main class to show messages to the user.
Definition: message.hpp:36
This shows the dialog to select a previous version of Wesnoth to migrate preferences from and redownl...
Abstract base class for all modal dialogs.
virtual const std::string & window_id() const =0
The ID of the window to build.
bool show(const unsigned auto_close_time=0)
Shows the window.
The popup class shows windows that are shown non-modal.
virtual const std::string & window_id() const
The ID of the window to build.
This shows the dialog to confirm surrender and/or quitting the game.
This class implements the title screen.
Dialog that takes new schedule ID and name from the player.
Shows a transient message.
Shows a dialog with two portraits, one on each side.
Shows a dialog with the portrait on the left side.
Shows a dialog with the portrait on the right side.
base class of top level items, the only item which needs to store the final canvases to draw on.
Definition: window.hpp:61
void draw()
Draws the window.
Definition: window.cpp:594
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:210
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:1030
static std::string _(const char *str)
Definition: gettext.hpp:97
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:211
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:93
bool addon_server_info
Definition: game_config.cpp:79
void load_config(const config &v)
void show(const std::string &window_id, const t_string &message, const point &mouse, const SDL_Rect &source_rect)
Shows a tip.
Definition: tooltip.cpp:64
void remove()
Removes a tip.
Definition: tooltip.cpp:94
std::string get_modal_dialog_id(const modal_dialog &dialog)
Definition: test_gui2.cpp:178
std::string get_modeless_dialog_id(const modeless_dialog &dialog)
Definition: test_gui2.cpp:183
Generic file dialog.
std::set< std::string > & registered_window_types()
Returns the list of registered windows.
bool new_widgets
Do we wish to use the new library or not.
Definition: settings.cpp:23
logger & info()
Definition: log.cpp:318
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: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: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: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