The Battle for Wesnoth  1.19.8+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"
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"
113 #include "gui/dialogs/tooltip.hpp"
118 #include "gui/dialogs/wml_error.hpp"
120 #include "gui/widgets/settings.hpp"
121 #include "gui/widgets/window.hpp"
122 #include "language.hpp"
123 #include "map/map.hpp"
124 #include "replay.hpp"
125 #include "save_index.hpp"
126 #include "saved_game.hpp"
128 #include "terrain/type_data.hpp"
130 #include "utils/general.hpp"
131 #include "wesnothd_connection.hpp"
132 #include "wml_exception.hpp"
133 
134 #include <boost/test/unit_test.hpp>
135 
136 #include <functional>
137 #include <memory>
138 
139 using namespace gui2::dialogs;
140 
143  : config_manager()
144  , dummy_args({"wesnoth", "--noaddons"})
145  {
146  /** The main config, which contains the entire WML tree. */
147  game_config_view game_config_view_ = game_config_view::wrap(main_config);
148  config_manager.reset(new game_config_manager(dummy_args));
149 
151 
152  cache.clear_defines();
153  cache.add_define("EDITOR");
154  cache.add_define("MULTIPLAYER");
155  cache.get_config(game_config::path +"/data", main_config);
156 
157  const filesystem::binary_paths_manager bin_paths_manager(game_config_view_);
158 
160  game_config::load_config(main_config.mandatory_child("game_config"));
161  }
163  {
164  }
166  static const std::string widgets_file;
167  std::unique_ptr<game_config_manager> config_manager;
168  std::vector<std::string> dummy_args;
169 };
171 const std::string test_gui2_fixture::widgets_file = "widgets_tested.log";
172 
173 namespace gui2 {
174 
175 namespace dialogs {
176 
177 std::string get_modal_dialog_id(const modal_dialog& dialog)
178 {
179  return dialog.window_id();
180 }
181 
182 std::string get_modeless_dialog_id(const modeless_dialog& dialog)
183 {
184  return dialog.window_id();
185 }
186 
187 } // namespace dialogs
188 } // namespace gui2
189 
190 namespace {
191 
192  /**
193  * Helper class to generate a dialog.
194  *
195  * This class makes sure the dialog is properly created and initialized.
196  * The specialized versions are at the end of this file.
197  */
198  template<class T>
199  struct dialog_tester
200  {
201  T* create() { return new T(); }
202  };
203 
204  typedef std::pair<unsigned, unsigned> resolution;
205  typedef std::vector<std::pair<unsigned, unsigned>> resolution_list;
206 
207  template<class T>
208  void test_resolutions(const resolution_list& resolutions)
209  {
210  for(const resolution& resolution : resolutions) {
211  test_utils::get_fake_display(resolution.first, resolution.second);
212 
213  dialog_tester<T> ctor;
214  const std::unique_ptr<modal_dialog> dlg(ctor.create());
215  BOOST_REQUIRE_MESSAGE(dlg.get(), "Failed to create a dialog.");
216 
217  std::string id = get_modal_dialog_id(*dlg.get());
218  filesystem::write_file(test_gui2_fixture::widgets_file, ","+id, std::ios_base::app);
219 
220  std::string exception;
221  try {
222  dlg->show(1);
223  } catch(const gui2::layout_exception_width_modified&) {
224  exception = "gui2::layout_exception_width_modified";
226  exception = "gui2::layout_exception_width_resize_failed";
228  exception = "gui2::layout_exception_height_resize_failed";
229  } catch(const wml_exception& e) {
230  exception = e.dev_message;
231  } catch(const std::exception& e) {
232  exception = e.what();
233  } catch(...) {
234  exception = utils::get_unknown_exception_type();
235  }
236  BOOST_CHECK_MESSAGE(exception.empty(),
237  "Test for '" << id
238  << "' Failed\nnew widgets = " << gui2::new_widgets
239  << " resolution = " << resolution.first
240  << 'x' << resolution.second
241  << "\nException caught: " << exception << '.');
242  }
243  }
244 
245  template<class T>
246  void test_popup_resolutions(const resolution_list& resolutions)
247  {
248  bool interact = false;
249  for(int i = 0; i < 2; ++i) {
250  for(const resolution& resolution : resolutions) {
251  // debug clock doesn't work at 800x600
252  if(resolution.first == 800 && resolution.second == 600) {
253  continue;
254  }
255  test_utils::get_fake_display(resolution.first, resolution.second);
256 
257  dialog_tester<T> ctor;
258  const std::unique_ptr<modeless_dialog> dlg(ctor.create());
259  BOOST_REQUIRE_MESSAGE(dlg.get(), "Failed to create a dialog.");
260 
261  std::string id = get_modeless_dialog_id(*dlg.get());
262  filesystem::write_file(test_gui2_fixture::widgets_file, ","+id, std::ios_base::app);
263 
264  std::string exception;
265  try {
266  dlg->show(interact);
267  gui2::window* window = dlg.get();
268  BOOST_REQUIRE_NE(window, static_cast<void*>(nullptr));
269  window->draw();
270  } catch(const gui2::layout_exception_width_modified&) {
271  exception = "gui2::layout_exception_width_modified";
273  exception = "gui2::layout_exception_width_resize_failed";
275  exception = "gui2::layout_exception_height_resize_failed";
276  } catch(const wml_exception& e) {
277  exception = e.dev_message;
278  } catch(const std::exception& e) {
279  exception = e.what();
280  } catch(...) {
281  exception = utils::get_unknown_exception_type();
282  }
283  BOOST_CHECK_MESSAGE(exception.empty(),
284  "Test for '" << id
285  << "' Failed\nnew widgets = " << gui2::new_widgets
286  << " resolution = " << resolution.first
287  << 'x' << resolution.second
288  << "\nException caught: " << exception << '.');
289  }
290 
291  interact = true;
292  }
293  }
294 
295 #ifdef _MSC_VER
296 #pragma warning(push)
297 #pragma warning(disable: 4702)
298 #endif
299  void test_tip_resolutions(const resolution_list& resolutions
300  , const std::string& id)
301  {
302  for(const auto& resolution : resolutions) {
303  test_utils::get_fake_display(resolution.first, resolution.second);
304 
305  filesystem::write_file(test_gui2_fixture::widgets_file, ","+id, std::ios_base::app);
306 
307  std::string exception;
308  try {
309  tip::show(id
310  , "Test message for a tooltip."
311  , point(0, 0)
312  , {0,0,0,0});
313  tip::remove();
314  } catch(const gui2::layout_exception_width_modified&) {
315  exception = "gui2::layout_exception_width_modified";
317  exception = "gui2::layout_exception_width_resize_failed";
319  exception = "gui2::layout_exception_height_resize_failed";
320  } catch(const wml_exception& e) {
321  exception = e.dev_message;
322  } catch(const std::exception& e) {
323  exception = e.what();
324  } catch(...) {
325  exception = utils::get_unknown_exception_type();
326  }
327  BOOST_CHECK_MESSAGE(exception.empty(),
328  "Test for tip '" << id
329  << "' Failed\nnew widgets = " << gui2::new_widgets
330  << " resolution = " << resolution.first
331  << 'x' << resolution.second
332  << "\nException caught: " << exception << '.');
333  }
334  }
335 #ifdef _MSC_VER
336 #pragma warning(pop)
337 #endif
338 
339 const resolution_list& get_gui_resolutions()
340 {
341  static resolution_list result {
342  {800, 600},
343  {1024, 768},
344  {1280, 1024},
345  {1680, 1050},
346  };
347 
348  return result;
349 }
350 
351 template<class T>
352 void test()
353 {
354  gui2::new_widgets = false;
355 
356 // for(std::size_t i = 0; i < 2; ++i) {
357 
358  test_resolutions<T>(get_gui_resolutions());
359 
360 // break; // FIXME: New widgets break
361 // gui2::new_widgets = true;
362 // }
363 }
364 
365 template<class T>
366 void test_popup()
367 {
368  gui2::new_widgets = false;
369 
370  for(std::size_t i = 0; i < 2; ++i) {
371 
372  test_popup_resolutions<T>(get_gui_resolutions());
373 
374  gui2::new_widgets = true;
375  }
376 }
377 
378 void test_tip(const std::string& id)
379 {
380  gui2::new_widgets = false;
381 
382  for(std::size_t i = 0; i < 2; ++i) {
383 
384  test_tip_resolutions(get_gui_resolutions(), id);
385 
386  gui2::new_widgets = true;
387  }
388 }
389 
390 } // namespace
391 
393 
394 BOOST_AUTO_TEST_CASE(modal_dialog_test_addon_auth)
395 {
396  test<addon_auth>();
397 }
398 BOOST_AUTO_TEST_CASE(modal_dialog_test_addon_connect)
399 {
400  test<addon_connect>();
401 }
402 BOOST_AUTO_TEST_CASE(modal_dialog_test_addon_license_prompt)
403 {
404  test<addon_license_prompt>();
405 }
406 BOOST_AUTO_TEST_CASE(modal_dialog_test_campaign_difficulty)
407 {
408  test<campaign_difficulty>();
409 }
410 BOOST_AUTO_TEST_CASE(modal_dialog_test_chat_log)
411 {
412  test<chat_log>();
413 }
414 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_choose_addon)
415 {
416  test<editor_choose_addon>();
417 }
418 BOOST_AUTO_TEST_CASE(modal_dialog_test_prompt)
419 {
420  test<prompt>();
421 }
422 BOOST_AUTO_TEST_CASE(modal_dialog_test_core_selection)
423 {
424  test<core_selection>();
425 }
426 BOOST_AUTO_TEST_CASE(modal_dialog_test_custom_tod)
427 {
428  test<custom_tod>();
429 }
430 BOOST_AUTO_TEST_CASE(modal_dialog_test_depcheck_confirm_change)
431 {
432  test<depcheck_confirm_change>();
433 }
434 BOOST_AUTO_TEST_CASE(modal_dialog_test_depcheck_select_new)
435 {
436  test<depcheck_select_new>();
437 }
438 BOOST_AUTO_TEST_CASE(modal_dialog_test_edit_label)
439 {
440  test<edit_label>();
441 }
442 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_edit_pbl)
443 {
444  test<editor_edit_pbl>();
445 }
446 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_edit_pbl_translation)
447 {
448  test<editor_edit_pbl_translation>();
449 }
450 BOOST_AUTO_TEST_CASE(modal_dialog_test_edit_text)
451 {
452  test<edit_text>();
453 }
454 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_edit_label)
455 {
456  test<editor_edit_label>();
457 }
458 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_edit_side)
459 {
460  test<editor_edit_side>();
461 }
462 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_edit_scenario)
463 {
464  test<editor_edit_scenario>();
465 }
466 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_generate_map)
467 {
468  test<editor_generate_map>();
469 }
470 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_new_map)
471 {
472  test<editor_new_map>();
473 }
474 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_resize_map)
475 {
476  test<editor_resize_map>();
477 }
478 BOOST_AUTO_TEST_CASE(modal_dialog_test_faction_select)
479 {
480  test<faction_select>();
481 }
482 BOOST_AUTO_TEST_CASE(modal_dialog_test_file_dialog)
483 {
484  test<file_dialog>();
485 }
486 BOOST_AUTO_TEST_CASE(modal_dialog_test_folder_create)
487 {
488  test<folder_create>();
489 }
490 BOOST_AUTO_TEST_CASE(modal_dialog_test_formula_debugger)
491 {
492  test<formula_debugger>();
493 }
494 BOOST_AUTO_TEST_CASE(modal_dialog_test_game_cache_options)
495 {
496  test<game_cache_options>();
497 }
498 BOOST_AUTO_TEST_CASE(modal_dialog_test_game_delete)
499 {
500  test<game_delete>();
501 }
502 BOOST_AUTO_TEST_CASE(modal_dialog_test_game_version)
503 {
504  test<game_version>();
505 }
506 BOOST_AUTO_TEST_CASE(modal_dialog_test_game_save)
507 {
508  test<game_save>();
509 }
510 BOOST_AUTO_TEST_CASE(modal_dialog_test_game_save_message)
511 {
512  test<game_save_message>();
513 }
514 BOOST_AUTO_TEST_CASE(modal_dialog_test_game_save_oos)
515 {
516  test<game_save_oos>();
517 }
518 BOOST_AUTO_TEST_CASE(modal_dialog_test_generator_settings)
519 {
520  test<generator_settings>();
521 }
522 BOOST_AUTO_TEST_CASE(modal_dialog_test_gui_test_dialog)
523 {
524  test<gui_test_dialog>();
525 }
526 BOOST_AUTO_TEST_CASE(modal_dialog_test_hotkey_bind)
527 {
528  test<hotkey_bind>();
529 }
530 BOOST_AUTO_TEST_CASE(modal_dialog_test_install_dependencies)
531 {
532  test<install_dependencies>();
533 }
534 BOOST_AUTO_TEST_CASE(modal_dialog_test_language_selection)
535 {
536  test<language_selection>();
537 }
538 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_lobby)
539 {
540  test<mp_lobby>();
541 }
542 BOOST_AUTO_TEST_CASE(modal_dialog_test_lobby_player_info)
543 {
544  test<lobby_player_info>();
545 }
546 BOOST_AUTO_TEST_CASE(modal_dialog_test_log_settings)
547 {
548  test<log_settings>();
549 }
550 BOOST_AUTO_TEST_CASE(modal_dialog_test_message)
551 {
552  test<message>();
553 }
554 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_alerts_options)
555 {
556  test<mp_alerts_options>();
557 }
558 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_connect)
559 {
560  test<mp_connect>();
561 }
562 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_join_game_password_prompt)
563 {
564  test<mp_join_game_password_prompt>();
565 }
566 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_login)
567 {
568  test<mp_login>();
569 }
570 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_method_selection)
571 {
572  test<mp_method_selection>();
573 }
574 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_report)
575 {
576  test<mp_report>();
577 }
578 BOOST_AUTO_TEST_CASE(modal_dialog_test_simple_item_selector)
579 {
580  test<simple_item_selector>();
581 }
582 BOOST_AUTO_TEST_CASE(modal_dialog_test_screenshot_notification)
583 {
584  test<screenshot_notification>();
585 }
586 BOOST_AUTO_TEST_CASE(modal_dialog_test_select_orb_colors)
587 {
588  test<select_orb_colors>();
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  };
711 
712  for(const std::string& item : widgets_tested)
713  {
714  widget_list.erase(item);
715  PLAIN_LOG << "Checking widget " << item;
716  BOOST_CHECK_EQUAL(omitted.count(item), 0);
717  }
718  for(const std::string& item : omitted)
719  {
720  widget_list.erase(item);
721  }
722 
723  // Test size() instead of empty() to get the number of offenders
724  BOOST_CHECK_EQUAL(widget_list.size(), 0);
725  for(const std::string& id : widget_list) {
726  PLAIN_LOG << "Window '" << id << "' registered but not tested.";
727  }
728 }
729 
730 BOOST_AUTO_TEST_CASE(test_make_test_fake)
731 {
733 
734  try {
735  message dlg("title", "message", true, false, false);
736  dlg.show(1);
737  } catch(const wml_exception& e) {
738  BOOST_CHECK(e.user_message == _("Failed to show a dialog, which doesn’t fit on the screen."));
739  return;
740  } catch(...) {
741  BOOST_ERROR("Didn't catch the wanted exception, instead caught " << utils::get_unknown_exception_type() << ".");
742  }
743  BOOST_ERROR("Didn't catch the wanted exception, instead caught nothing.");
744 }
745 
746 BOOST_AUTO_TEST_SUITE_END()
747 
748 namespace {
749 
750 template<>
751 struct dialog_tester<addon_server_info>
752 {
753  std::string s = "";
754  bool b = false;
755  addon_server_info* create()
756  {
757  addons_client client("localhost:15999");
758  return new addon_server_info(client, s, b);
759  }
760 };
761 
762 template<>
763 struct dialog_tester<addon_auth>
764 {
765  config cfg;
766  addon_auth* create()
767  {
768  return new addon_auth(cfg);
769  }
770 };
771 
772 template<>
773 struct dialog_tester<addon_connect>
774 {
775  std::string host_name = "host_name";
776  addon_connect* create()
777  {
778  return new addon_connect(host_name, true);
779  }
780 };
781 
782 template<>
783 struct dialog_tester<addon_license_prompt>
784 {
785  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.
786 
787 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.)";
788  addon_license_prompt* create()
789  {
790  return new addon_license_prompt(license_terms);
791  }
792 };
793 
794 template<>
795 struct dialog_tester<addon_manager>
796 {
797  dialog_tester()
798  {
800  }
801  addon_manager* create()
802  {
803  addons_client client("localhost:15999");
804  return new addon_manager(client);
805  }
806 };
807 
808 template<>
809 struct dialog_tester<campaign_difficulty>
810 {
811  campaign_difficulty* create()
812  {
813  const config items("difficulty");
814 
815  return new campaign_difficulty(items);
816  }
817 };
818 
819 template<>
820 struct dialog_tester<campaign_selection>
821 {
822  saved_game state;
824  dialog_tester() : state(config {"campaign_type", "scenario"}), ng(state)
825  {
826  }
827  campaign_selection* create()
828  {
829  return new campaign_selection(ng);
830  }
831 };
832 
833 template<>
834 struct dialog_tester<chat_log>
835 {
836  config cfg;
837  vconfig vcfg;
838  replay_recorder_base rbase;
839  replay r;
840  dialog_tester() : vcfg(cfg), r(rbase) {}
841  chat_log* create()
842  {
843  return new chat_log(vcfg, r);
844  }
845 };
846 
847 template<>
848 struct dialog_tester<editor_choose_addon>
849 {
850  std::string temp;
851  editor_choose_addon* create()
852  {
853  return new editor_choose_addon(temp);
854  }
855 };
856 
857 template<>
858 struct dialog_tester<prompt>
859 {
860  std::string temp;
861  prompt* create()
862  {
863  return new prompt(temp);
864  }
865 };
866 
867 template<>
868 struct dialog_tester<core_selection>
869 {
870  std::vector<config> cores;
871  dialog_tester()
872  {
873  cores.resize(1);
874  }
875  core_selection* create()
876  {
877  return new core_selection(cores, 0);
878  }
879 };
880 
881 template<>
882 struct dialog_tester<custom_tod>
883 {
884  std::vector<time_of_day> times;
885  int current_tod = 0;
886  dialog_tester()
887  {
888  times.resize(1);
889  }
890  custom_tod* create()
891  {
892  return new custom_tod(times, current_tod);
893  }
894 };
895 
896 template<>
897 struct dialog_tester<edit_label>
898 {
899  std::string label = "Label text to modify";
900  bool team_only = false;
901  edit_label* create()
902  {
903  return new edit_label(label, team_only);
904  }
905 };
906 
907 template<>
908 struct dialog_tester<edit_text>
909 {
910  std::string text = "text to modify";
911  edit_text* create()
912  {
913  return new edit_text("title", "label", text);
914  }
915 };
916 
917 template<>
918 struct dialog_tester<editor_edit_label>
919 {
920  std::string label = "Label text to modify";
921  std::string category = "test";
922  bool immutable = false, fog = false, shroud = false;
923  color_t color;
924  editor_edit_label* create()
925  {
926  return new editor_edit_label(label, immutable, fog, shroud, color, category);
927  }
928 };
929 
930 template<>
931 struct dialog_tester<editor_edit_pbl>
932 {
933  std::string temp;
934  std::string temp1;
935  editor_edit_pbl* create()
936  {
937  return new editor_edit_pbl(temp, temp1);
938  }
939 };
940 
941 template<>
942 struct dialog_tester<editor_edit_pbl_translation>
943 {
944  std::string temp1;
945  std::string temp2;
946  std::string temp3;
948  {
949  return new editor_edit_pbl_translation(temp1, temp2, temp3);
950  }
951 };
952 
953 template<>
954 struct dialog_tester<editor_edit_scenario>
955 {
956  std::string id, name, descr;
957  int turns = 0, xp_mod = 50;
958  bool defeat_enemies = false, random_start = false;
959  editor_edit_scenario* create()
960  {
961  return new editor_edit_scenario(id, name, descr, turns, xp_mod, defeat_enemies, random_start);
962  }
963 };
964 
965 template<>
966 struct dialog_tester<editor_edit_side>
967 {
968  team t;
970  dialog_tester() : info(t) {}
971  editor_edit_side* create()
972  {
973  return new editor_edit_side(info);
974  }
975 };
976 
977 template<>
978 struct dialog_tester<formula_debugger>
979 {
980  wfl::formula_debugger debugger;
981  formula_debugger* create()
982  {
983  return new formula_debugger(debugger);
984  }
985 };
986 
987 template<>
988 struct dialog_tester<game_load>
989 {
990  config cfg;
991  game_config_view view;
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  view = game_config_view::wrap(cfg);
1002  return new game_load(view, data);
1003  }
1004 
1005 };
1006 
1007 template<>
1008 struct dialog_tester<game_save>
1009 {
1010  std::string title = "Title";
1011  std::string filename = "filename";
1012  game_save* create()
1013  {
1014  return new game_save(title, filename);
1015  }
1016 
1017 };
1018 
1019 template<>
1020 struct dialog_tester<game_save_message>
1021 {
1022  std::string title = "Title";
1023  std::string filename = "filename";
1024  std::string message = "message";
1025  game_save_message* create()
1026  {
1027  return new game_save_message(title, filename, message);
1028  }
1029 
1030 };
1031 
1032 template<>
1033 struct dialog_tester<game_save_oos>
1034 {
1035  bool ignore_all = false;
1036  std::string title = "Title";
1037  std::string filename = "filename";
1038  std::string message = "message";
1039  game_save_oos* create()
1040  {
1041  return new game_save_oos(ignore_all, title, filename, message);
1042  }
1043 
1044 };
1045 
1046 template<>
1047 struct dialog_tester<install_dependencies>
1048 {
1049  addons_list addons;
1050  install_dependencies* create()
1051  {
1052  return new install_dependencies(addons);
1053  }
1054 };
1055 
1056 template<>
1057 struct dialog_tester<hotkey_bind>
1058 {
1059  std::string id = "";
1060 
1061  hotkey_bind* create()
1062  {
1063  return new hotkey_bind(id);
1064  }
1065 };
1066 
1067 template<>
1068 struct dialog_tester<mp_lobby>
1069 {
1071  wesnothd_connection connection;
1072  mp::lobby_info li;
1073  int selected_game;
1074  dialog_tester() : connection("", ""), li()
1075  {
1076  }
1077  mp_lobby* create()
1078  {
1079  return new mp_lobby(li, connection, selected_game);
1080  }
1081 };
1082 
1083 template<>
1084 struct dialog_tester<mp_match_history>
1085 {
1086  wesnothd_connection connection;
1087  dialog_tester() : connection("", "")
1088  {
1089  }
1090  mp_match_history* create()
1091  {
1092  return new mp_match_history("", connection, false);
1093  }
1094 };
1095 
1096 template<>
1097 struct dialog_tester<gui2::dialogs::migrate_version_selection>
1098 {
1100  {
1102  }
1103 };
1104 
1105 class fake_chat_handler : public events::chat_handler {
1106  void add_chat_message(const std::time_t&,
1107  const std::string&, int, const std::string&,
1108  MESSAGE_TYPE) {}
1109  void send_chat_message(const std::string&, bool) {}
1110  void send_to_server(const config&) {}
1111  void clear_messages() {}
1112 };
1113 
1114 template<>
1115 struct dialog_tester<lobby_player_info>
1116 {
1117  config c;
1118  fake_chat_handler ch;
1119  wesnothd_connection connection;
1120  mp::user_info ui;
1121  mp::lobby_info li;
1122  dialog_tester()
1123  : connection("", "")
1124  , ui(c), li()
1125  {
1126  }
1127  lobby_player_info* create()
1128  {
1129  return new lobby_player_info(ch, ui, li);
1130  }
1131 };
1132 
1133 template<>
1134 struct dialog_tester<log_settings>
1135 {
1136  log_settings* create()
1137  {
1138  return new log_settings();
1139  }
1140 };
1141 
1142 template<>
1143 struct dialog_tester<message>
1144 {
1145  message* create()
1146  {
1147  return new message("Title", "Message", false, false, false);
1148  }
1149 };
1150 
1151 template<>
1152 struct dialog_tester<mp_create_game>
1153 {
1154  saved_game state;
1155  dialog_tester() : state(config {"campaign_type", "multiplayer"})
1156  {
1157  }
1158  mp_create_game* create()
1159  {
1160  return new mp_create_game(state, true);
1161  }
1162 };
1163 
1164 template<>
1165 struct dialog_tester<mp_join_game_password_prompt>
1166 {
1167  std::string password;
1169  {
1170  return new mp_join_game_password_prompt(password);
1171  }
1172 };
1173 
1174 template<>
1175 struct dialog_tester<mp_report>
1176 {
1177  std::string report_text;
1178  mp_report* create()
1179  {
1180  return new mp_report(report_text);
1181  }
1182 };
1183 
1184 static std::vector<std::string> depcheck_mods {"mod_one", "some other", "more"};
1185 
1186 template<>
1187 struct dialog_tester<depcheck_confirm_change>
1188 {
1189  depcheck_confirm_change* create()
1190  {
1191  return new depcheck_confirm_change(true, depcheck_mods, "requester");
1192  }
1193 };
1194 
1195 template<>
1196 struct dialog_tester<depcheck_select_new>
1197 {
1198  depcheck_select_new* create()
1199  {
1200  return new depcheck_select_new(ng::depcheck::MODIFICATION, depcheck_mods);
1201  }
1202 };
1203 
1204 template<>
1205 struct dialog_tester<mp_login>
1206 {
1207  mp_login* create()
1208  {
1209  return new mp_login("wesnoth.org", "label", true);
1210  }
1211 };
1212 
1213 template<>
1214 struct dialog_tester<simple_item_selector>
1215 {
1216  simple_item_selector* create()
1217  {
1218  return new simple_item_selector("title", "message", std::vector<std::string>(), false, false);
1219  }
1220 };
1221 
1222 template<>
1223 struct dialog_tester<screenshot_notification>
1224 {
1225  screenshot_notification* create()
1226  {
1227  return new screenshot_notification("path", nullptr);
1228  }
1229 };
1230 
1231 template<>
1232 struct dialog_tester<theme_list>
1233 {
1234  static theme_info make_theme(const std::string& name)
1235  {
1236  theme_info ti;
1237  ti.id = name;
1238  ti.name = name;
1239  ti.description = name + " this is a description";
1240  return ti;
1241  }
1242  static std::vector<theme_info> themes;
1243  theme_list* create()
1244  {
1245  return new theme_list(themes, 0);
1246  }
1247 };
1248 std::vector<theme_info> dialog_tester<theme_list>::themes {make_theme("classic"), make_theme("new"), make_theme("more"), make_theme("themes")};
1249 
1250 template<>
1251 struct dialog_tester<editor_generate_map>
1252 {
1253  std::vector<std::unique_ptr<map_generator>> map_generators;
1254  editor_generate_map* create()
1255  {
1256  for(const config &i : test_gui2_fixture::main_config.child_range("multiplayer")) {
1257  if(i["scenario_generation"] == "default") {
1258  auto generator_cfg = i.optional_child("generator");
1259  if (generator_cfg) {
1260  map_generators.emplace_back(create_map_generator("", *generator_cfg));
1261  }
1262  }
1263  }
1264 
1265  editor_generate_map* result = new editor_generate_map(map_generators);
1266  BOOST_REQUIRE_MESSAGE(result, "Failed to create a dialog.");
1267 
1268  return result;
1269  }
1270 };
1271 
1272 template<>
1273 struct dialog_tester<editor_new_map>
1274 {
1275  int width = 10;
1276  int height = 10;
1277  editor_new_map* create()
1278  {
1279  return new editor_new_map("Test", width, height);
1280  }
1281 };
1282 
1283 template<>
1284 struct dialog_tester<editor_resize_map>
1285 {
1286  int width = 0;
1287  int height = 0;
1289  bool copy = false;
1290  editor_resize_map* create()
1291  {
1292  return new editor_resize_map(width, height, expand_direction, copy);
1293  }
1294 };
1295 
1296 template<>
1297 struct dialog_tester<file_dialog>
1298 {
1299  file_dialog* create()
1300  {
1301  return new file_dialog();
1302  }
1303 };
1304 
1305 template<>
1306 struct dialog_tester<folder_create>
1307 {
1308  std::string folder_name;
1309  folder_create* create()
1310  {
1311  return new folder_create(folder_name);
1312  }
1313 };
1314 
1315 template<>
1316 struct dialog_tester<transient_message>
1317 {
1318  transient_message* create()
1319  {
1320  return new transient_message("Title", false, "Message", false, "");
1321  }
1322 };
1323 
1324 template<>
1325 struct dialog_tester<title_screen>
1326 {
1327  std::vector<std::string> args;
1328  commandline_options opts;
1330  dialog_tester() : opts(args), game(opts) {}
1331  title_screen* create()
1332  {
1333  return new title_screen(game);
1334  }
1335 };
1336 
1337 template<>
1338 struct dialog_tester<wml_error>
1339 {
1340  static std::vector<std::string> files;
1341  wml_error* create()
1342  {
1343  return new wml_error("Summary", "Post summary", files, "Details");
1344  }
1345 };
1346 std::vector<std::string> dialog_tester<wml_error>::files {"some", "files", "here"};
1347 
1348 template<>
1349 struct dialog_tester<wml_message_left>
1350 {
1351  wml_message_left* create()
1352  {
1353  return new wml_message_left("Title", "Message", "", false);
1354  }
1355 };
1356 
1357 template<>
1358 struct dialog_tester<wml_message_right>
1359 {
1360  wml_message_right* create()
1361  {
1362  return new wml_message_right("Title", "Message", "", false);
1363  }
1364 };
1365 
1366 template<>
1367 struct dialog_tester<wml_message_double>
1368 {
1369  wml_message_double* create()
1370  {
1371  return new wml_message_double("Title", "Message", "", false, "", true);
1372  }
1373 };
1374 
1375 template<>
1376 struct dialog_tester<faction_select>
1377 {
1378  config era_cfg, side_cfg;
1379  std::vector<const config*> eras;
1380  ng::flg_manager flg;
1381  std::string color;
1382  dialog_tester()
1383  : era_cfg(), side_cfg(), eras(1, &era_cfg) // TODO: Add an actual era definition
1384  , flg(eras, side_cfg, false, false, false)
1385  , color("teal")
1386  {}
1387  faction_select* create() {
1388  return new faction_select(flg, color, 1);
1389  }
1390 };
1391 
1392 template<>
1393 struct dialog_tester<generator_settings>
1394 {
1395  config cfg;
1397  dialog_tester() : data(cfg) {}
1398  generator_settings* create()
1399  {
1400  return new generator_settings(data);
1401  }
1402 };
1403 
1404 template<>
1405 struct dialog_tester<sp_options_configure>
1406 {
1407  saved_game state;
1408  ng::create_engine create_eng;
1409  ng::configure_engine config_eng;
1410  dialog_tester() : create_eng(state)
1411  , config_eng(create_eng.get_state()) {}
1412  sp_options_configure* create()
1413  {
1414  return new sp_options_configure(create_eng, config_eng);
1415  }
1416 };
1417 
1418 template<>
1419 struct dialog_tester<statistics_dialog>
1420 {
1421  team t;
1423  statistics_t stats;
1424  dialog_tester() : t() , stats_record(), stats(stats_record) {}
1425  statistics_dialog* create()
1426  {
1427  return new statistics_dialog(stats, t);
1428  }
1429 };
1430 
1431 template<>
1432 struct dialog_tester<surrender_quit>
1433 {
1434  dialog_tester() {}
1435  surrender_quit* create()
1436  {
1437  return new surrender_quit();
1438  }
1439 };
1440 
1441 template<>
1442 struct dialog_tester<tod_new_schedule>
1443 {
1444  std::string id = "id";
1445  t_string name = "name";
1446  dialog_tester() {}
1447  tod_new_schedule* create()
1448  {
1449  return new tod_new_schedule(id, name);
1450  }
1451 };
1452 
1453 template<>
1454 struct dialog_tester<editor_edit_unit>
1455 {
1456  config cfg;
1457  game_config_view view;
1458 
1459  dialog_tester() {}
1460  editor_edit_unit* create()
1461  {
1462  config& units = cfg.add_child("units");
1463  cfg.add_child("race");
1464  config& movetype = units.add_child("movetype");
1465  movetype["name"] = "Test Movetype";
1466  movetype.add_child("defense");
1467  movetype.add_child("resistance");
1468  movetype.add_child("movement_costs");
1469  view = game_config_view::wrap(cfg);
1470  return new editor_edit_unit(view, "test_addon");
1471  }
1472 };
1473 
1474 template<>
1475 struct dialog_tester<gui_test_dialog>
1476 {
1477  dialog_tester() {}
1478  gui_test_dialog* create()
1479  {
1480  return new gui_test_dialog();
1481  }
1482 };
1483 
1484 } // namespace
double t
Definition: astarsearch.cpp:63
Add-ons (campaignd) client class.
Definition: client.hpp:41
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:158
config & add_child(config_key_type key)
Definition: config.cpp:440
Singleton class to manage game config file caching.
void add_define(const std::string &define)
Add a entry to preproc defines map.
static config_cache & instance()
Get reference to the singleton object.
void clear_defines()
Clear stored defines map to default values.
void get_config(const std::string &path, config &cfg, abstract_validator *validator=nullptr)
Gets a config object from given path.
A class grating read only view to a vector of config objects, viewed as one config with all children ...
static game_config_view wrap(const config &cfg)
Dialog that allows user to create custom unit types.
Definition: edit_unit.hpp:33
A test dialog for testing various gui2 features.
Main class to show messages to the user.
Definition: message.hpp:36
This shows the dialog to select a previous version of Wesnoth to migrate preferences from and redownl...
Abstract base class for all modal dialogs.
virtual const std::string & window_id() const =0
The ID of the window to build.
bool show(const unsigned auto_close_time=0)
Shows the window.
The popup class shows windows that are shown non-modal.
virtual const std::string & window_id() const
The ID of the window to build.
This shows the dialog to confirm surrender and/or quitting the game.
This class implements the title screen.
Dialog that takes new schedule ID and name from the player.
Shows a transient message.
Shows a dialog with two portraits, one on each side.
Shows a dialog with the portrait on the left side.
Shows a dialog with the portrait on the right side.
base class of top level items, the only item which needs to store the final canvases to draw on.
Definition: window.hpp:61
void draw()
Draws the window.
Definition: window.cpp:591
The basic "size" of the unit - flying, small land, large land, etc.
Definition: movetype.hpp:44
This class represents the collective information the client has about the players and games on the se...
Definition: lobby_info.hpp:31
FLG stands for faction, leader and gender.
Definition: flg_manager.hpp:30
static std::shared_ptr< save_index_class > default_saves_dir()
Returns an instance for managing saves in filesystem::get_saves_dir()
Definition: save_index.cpp:209
This class stores all the data for a single 'side' (in game nomenclature).
Definition: team.hpp:75
A variable-expanding proxy for the config class.
Definition: variable.hpp:45
A class that represents a TCP/IP connection to the wesnothd server.
Networked add-ons (campaignd) client interface.
Formula AI debugger.
Declarations for File-IO.
std::size_t i
Definition: function.cpp:1029
static std::string _(const char *str)
Definition: gettext.hpp:93
std::string label
What to show in the filter's drop-down list.
Definition: manager.cpp: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:103
Defines the exception classes for the layout algorithm.
#define PLAIN_LOG
Definition: log.hpp:297
map_generator * create_map_generator(const std::string &name, const config &cfg, const config *vars)
Definition: map_create.cpp:28
Various uncategorised dialogs.
void point(int x, int y)
Draw a single point.
Definition: draw.cpp:209
bool delete_file(const std::string &filename)
std::string read_file(const std::string &fname)
Basic disk I/O - read file.
void write_file(const std::string &fname, const std::string &data, std::ios_base::openmode mode)
Throws io_exception if an error occurs.
Game configuration data as global variables.
Definition: build_info.cpp:61
std::string path
Definition: filesystem.cpp:92
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:177
std::string get_modeless_dialog_id(const modeless_dialog &dialog)
Definition: test_gui2.cpp:182
Generic file dialog.
std::set< std::string > & registered_window_types()
Returns the list of registered windows.
bool new_widgets
Do we wish to use the new library or not.
Definition: settings.cpp:23
logger & info()
Definition: log.cpp:319
void send_to_server(const config &data)
Attempts to send given data to server if a connection is open.
game_display & get_fake_display(const int width, const int height)
Gets a fake test display.
std::string get_unknown_exception_type()
Utility function for finding the type of thing caught with catch(...).
Definition: general.cpp:23
std::vector< std::string > split(const config_attribute_value &val)
std::string_view data
Definition: picture.cpp:178
Replay control code.
This file contains the settings handling of the widget library.
std::string filename
Filename.
The basic class for representing 8-bit RGB or RGBA colour values.
Definition: color.hpp:59
The paths manager is responsible for recording the various paths that binary files may be located at.
Definition: filesystem.hpp:440
Exception thrown when the height resizing has failed.
Exception thrown when the width has been modified during resizing.
Exception thrown when the width resizing has failed.
This class represents the information a client has about another player.
Definition: lobby_data.hpp:30
static config main_config
Definition: test_gui2.cpp:165
std::unique_ptr< game_config_manager > config_manager
Definition: test_gui2.cpp:167
std::vector< std::string > dummy_args
Definition: test_gui2.cpp:168
static const std::string widgets_file
Definition: test_gui2.cpp:166
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:394
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