The Battle for Wesnoth  1.17.14+dev
test_gui2.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2022
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"
78 #include "gui/dialogs/message.hpp"
93 #include "gui/dialogs/outro.hpp"
104 #include "gui/dialogs/tooltip.hpp"
109 #include "gui/dialogs/unit_list.hpp"
112 #include "gui/dialogs/wml_error.hpp"
114 #include "gui/widgets/settings.hpp"
115 #include "gui/widgets/window.hpp"
116 #include "language.hpp"
117 #include "map/map.hpp"
118 #include "replay.hpp"
119 #include "save_index.hpp"
120 #include "saved_game.hpp"
122 #include "terrain/type_data.hpp"
124 #include "utils/general.hpp"
125 #include "wesnothd_connection.hpp"
126 #include "wml_exception.hpp"
127 
128 #include <boost/test/unit_test.hpp>
129 
130 #include <functional>
131 #include <memory>
132 
133 using namespace gui2::dialogs;
134 
137  : config_manager()
138  , dummy_args({"wesnoth", "--noaddons"})
139  {
140  /** The main config, which contains the entire WML tree. */
141  game_config_view game_config_view_ = game_config_view::wrap(main_config);
142  config_manager.reset(new game_config_manager(dummy_args));
143 
145 
146  cache.clear_defines();
147  cache.add_define("EDITOR");
148  cache.add_define("MULTIPLAYER");
149  cache.get_config(game_config::path +"/data", main_config);
150 
151  const filesystem::binary_paths_manager bin_paths_manager(game_config_view_);
152 
154  game_config::load_config(main_config.child("game_config"));
155  }
157  {
158  }
160  static const std::string widgets_file;
161  std::unique_ptr<game_config_manager> config_manager;
162  std::vector<std::string> dummy_args;
163 };
165 const std::string test_gui2_fixture::widgets_file = "widgets_tested.log";
166 
167 namespace gui2 {
168 
169 namespace dialogs {
170 
171 std::string get_modal_dialog_id(const modal_dialog& dialog)
172 {
173  return dialog.window_id();
174 }
175 
176 std::string get_modeless_dialog_id(const modeless_dialog& dialog)
177 {
178  return dialog.window_id();
179 }
180 
181 } // namespace dialogs
182 } // namespace gui2
183 
184 namespace {
185 
186  /**
187  * Helper class to generate a dialog.
188  *
189  * This class makes sure the dialog is properly created and initialized.
190  * The specialized versions are at the end of this file.
191  */
192  template<class T>
193  struct dialog_tester
194  {
195  T* create() { return new T(); }
196  };
197 
198  typedef std::pair<unsigned, unsigned> resolution;
199  typedef std::vector<std::pair<unsigned, unsigned>> resolution_list;
200 
201  template<class T>
202  void test_resolutions(const resolution_list& resolutions)
203  {
204  for(const resolution& resolution : resolutions) {
205  test_utils::get_fake_display(resolution.first, resolution.second);
206 
207  dialog_tester<T> ctor;
208  const std::unique_ptr<modal_dialog> dlg(ctor.create());
209  BOOST_REQUIRE_MESSAGE(dlg.get(), "Failed to create a dialog.");
210 
211  std::string id = get_modal_dialog_id(*dlg.get());
212  filesystem::write_file(test_gui2_fixture::widgets_file, ","+id, std::ios_base::app);
213 
214  std::string exception;
215  try {
216  dlg->show(1);
217  } catch(const gui2::layout_exception_width_modified&) {
218  exception = "gui2::layout_exception_width_modified";
220  exception = "gui2::layout_exception_width_resize_failed";
222  exception = "gui2::layout_exception_height_resize_failed";
223  } catch(const wml_exception& e) {
224  exception = e.dev_message;
225  } catch(const std::exception& e) {
226  exception = e.what();
227  } catch(...) {
228  exception = utils::get_unknown_exception_type();
229  }
230  BOOST_CHECK_MESSAGE(exception.empty(),
231  "Test for '" << id
232  << "' Failed\nnew widgets = " << gui2::new_widgets
233  << " resolution = " << resolution.first
234  << 'x' << resolution.second
235  << "\nException caught: " << exception << '.');
236  }
237  }
238 
239  template<class T>
240  void test_popup_resolutions(const resolution_list& resolutions)
241  {
242  bool interact = false;
243  for(int i = 0; i < 2; ++i) {
244  for(const resolution& resolution : resolutions) {
245  // debug clock doesn't work at 800x600
246  if(resolution.first == 800 && resolution.second == 600) {
247  continue;
248  }
249  test_utils::get_fake_display(resolution.first, resolution.second);
250 
251  dialog_tester<T> ctor;
252  const std::unique_ptr<modeless_dialog> dlg(ctor.create());
253  BOOST_REQUIRE_MESSAGE(dlg.get(), "Failed to create a dialog.");
254 
255  std::string id = get_modeless_dialog_id(*dlg.get());
256  filesystem::write_file(test_gui2_fixture::widgets_file, ","+id, std::ios_base::app);
257 
258  std::string exception;
259  try {
260  dlg->show(interact);
261  gui2::window* window = dlg.get();
262  BOOST_REQUIRE_NE(window, static_cast<void*>(nullptr));
263  window->draw();
264  } catch(const gui2::layout_exception_width_modified&) {
265  exception = "gui2::layout_exception_width_modified";
267  exception = "gui2::layout_exception_width_resize_failed";
269  exception = "gui2::layout_exception_height_resize_failed";
270  } catch(const wml_exception& e) {
271  exception = e.dev_message;
272  } catch(const std::exception& e) {
273  exception = e.what();
274  } catch(...) {
275  exception = utils::get_unknown_exception_type();
276  }
277  BOOST_CHECK_MESSAGE(exception.empty(),
278  "Test for '" << id
279  << "' Failed\nnew widgets = " << gui2::new_widgets
280  << " resolution = " << resolution.first
281  << 'x' << resolution.second
282  << "\nException caught: " << exception << '.');
283  }
284 
285  interact = true;
286  }
287  }
288 
289 #ifdef _MSC_VER
290 #pragma warning(push)
291 #pragma warning(disable: 4702)
292 #endif
293  void test_tip_resolutions(const resolution_list& resolutions
294  , const std::string& id)
295  {
296  for(const auto& resolution : resolutions) {
297  test_utils::get_fake_display(resolution.first, resolution.second);
298 
299  filesystem::write_file(test_gui2_fixture::widgets_file, ","+id, std::ios_base::app);
300 
301  std::string exception;
302  try {
303  tip::show(id
304  , "Test message for a tooltip."
305  , point(0, 0)
306  , {0,0,0,0});
307  tip::remove();
308  } catch(const gui2::layout_exception_width_modified&) {
309  exception = "gui2::layout_exception_width_modified";
311  exception = "gui2::layout_exception_width_resize_failed";
313  exception = "gui2::layout_exception_height_resize_failed";
314  } catch(const wml_exception& e) {
315  exception = e.dev_message;
316  } catch(const std::exception& e) {
317  exception = e.what();
318  } catch(...) {
319  exception = utils::get_unknown_exception_type();
320  }
321  BOOST_CHECK_MESSAGE(exception.empty(),
322  "Test for tip '" << id
323  << "' Failed\nnew widgets = " << gui2::new_widgets
324  << " resolution = " << resolution.first
325  << 'x' << resolution.second
326  << "\nException caught: " << exception << '.');
327  }
328  }
329 #ifdef _MSC_VER
330 #pragma warning(pop)
331 #endif
332 
333 const resolution_list& get_gui_resolutions()
334 {
335  static resolution_list result {
336  {800, 600},
337  {1024, 768},
338  {1280, 1024},
339  {1680, 1050},
340  };
341 
342  return result;
343 }
344 
345 template<class T>
346 void test()
347 {
348  gui2::new_widgets = false;
349 
350 // for(std::size_t i = 0; i < 2; ++i) {
351 
352  test_resolutions<T>(get_gui_resolutions());
353 
354 // break; // FIXME: New widgets break
355 // gui2::new_widgets = true;
356 // }
357 }
358 
359 template<class T>
360 void test_popup()
361 {
362  gui2::new_widgets = false;
363 
364  for(std::size_t i = 0; i < 2; ++i) {
365 
366  test_popup_resolutions<T>(get_gui_resolutions());
367 
368  gui2::new_widgets = true;
369  }
370 }
371 
372 void test_tip(const std::string& id)
373 {
374  gui2::new_widgets = false;
375 
376  for(std::size_t i = 0; i < 2; ++i) {
377 
378  test_tip_resolutions(get_gui_resolutions(), id);
379 
380  gui2::new_widgets = true;
381  }
382 }
383 
384 } // namespace
385 
387 
388 BOOST_AUTO_TEST_CASE(modal_dialog_test_addon_auth)
389 {
390  test<addon_auth>();
391 }
392 BOOST_AUTO_TEST_CASE(modal_dialog_test_addon_connect)
393 {
394  test<addon_connect>();
395 }
396 BOOST_AUTO_TEST_CASE(modal_dialog_test_addon_license_prompt)
397 {
398  test<addon_license_prompt>();
399 }
400 BOOST_AUTO_TEST_CASE(modal_dialog_test_campaign_difficulty)
401 {
402  test<campaign_difficulty>();
403 }
404 BOOST_AUTO_TEST_CASE(modal_dialog_test_chat_log)
405 {
406  test<chat_log>();
407 }
408 BOOST_AUTO_TEST_CASE(modal_dialog_test_core_selection)
409 {
410  test<core_selection>();
411 }
412 BOOST_AUTO_TEST_CASE(modal_dialog_test_custom_tod)
413 {
414  test<custom_tod>();
415 }
416 BOOST_AUTO_TEST_CASE(modal_dialog_test_depcheck_confirm_change)
417 {
418  test<depcheck_confirm_change>();
419 }
420 BOOST_AUTO_TEST_CASE(modal_dialog_test_depcheck_select_new)
421 {
422  test<depcheck_select_new>();
423 }
424 BOOST_AUTO_TEST_CASE(modal_dialog_test_edit_label)
425 {
426  test<edit_label>();
427 }
428 BOOST_AUTO_TEST_CASE(modal_dialog_test_edit_text)
429 {
430  test<edit_text>();
431 }
432 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_edit_label)
433 {
434  test<editor_edit_label>();
435 }
436 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_edit_side)
437 {
438  test<editor_edit_side>();
439 }
440 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_edit_scenario)
441 {
442  test<editor_edit_scenario>();
443 }
444 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_generate_map)
445 {
446  test<editor_generate_map>();
447 }
448 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_new_map)
449 {
450  test<editor_new_map>();
451 }
452 BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_resize_map)
453 {
454  test<editor_resize_map>();
455 }
456 BOOST_AUTO_TEST_CASE(modal_dialog_test_faction_select)
457 {
458  test<faction_select>();
459 }
460 BOOST_AUTO_TEST_CASE(modal_dialog_test_file_dialog)
461 {
462  test<file_dialog>();
463 }
464 BOOST_AUTO_TEST_CASE(modal_dialog_test_folder_create)
465 {
466  test<folder_create>();
467 }
468 BOOST_AUTO_TEST_CASE(modal_dialog_test_formula_debugger)
469 {
470  test<formula_debugger>();
471 }
472 BOOST_AUTO_TEST_CASE(modal_dialog_test_game_cache_options)
473 {
474  test<game_cache_options>();
475 }
476 BOOST_AUTO_TEST_CASE(modal_dialog_test_game_delete)
477 {
478  test<game_delete>();
479 }
480 BOOST_AUTO_TEST_CASE(modal_dialog_test_game_version)
481 {
482  test<game_version>();
483 }
484 BOOST_AUTO_TEST_CASE(modal_dialog_test_game_save)
485 {
486  test<game_save>();
487 }
488 BOOST_AUTO_TEST_CASE(modal_dialog_test_game_save_message)
489 {
490  test<game_save_message>();
491 }
492 BOOST_AUTO_TEST_CASE(modal_dialog_test_game_save_oos)
493 {
494  test<game_save_oos>();
495 }
496 BOOST_AUTO_TEST_CASE(modal_dialog_test_generator_settings)
497 {
498  test<generator_settings>();
499 }
500 BOOST_AUTO_TEST_CASE(modal_dialog_test_hotkey_bind)
501 {
502  test<hotkey_bind>();
503 }
504 BOOST_AUTO_TEST_CASE(modal_dialog_test_install_dependencies)
505 {
506  test<install_dependencies>();
507 }
508 BOOST_AUTO_TEST_CASE(modal_dialog_test_language_selection)
509 {
510  test<language_selection>();
511 }
512 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_lobby)
513 {
514  test<mp_lobby>();
515 }
516 BOOST_AUTO_TEST_CASE(modal_dialog_test_lobby_player_info)
517 {
518  test<lobby_player_info>();
519 }
520 BOOST_AUTO_TEST_CASE(modal_dialog_test_log_settings)
521 {
522  test<log_settings>();
523 }
524 BOOST_AUTO_TEST_CASE(modal_dialog_test_message)
525 {
526  test<message>();
527 }
528 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_alerts_options)
529 {
530  test<mp_alerts_options>();
531 }
532 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_connect)
533 {
534  test<mp_connect>();
535 }
536 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_join_game_password_prompt)
537 {
538  test<mp_join_game_password_prompt>();
539 }
540 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_login)
541 {
542  test<mp_login>();
543 }
544 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_method_selection)
545 {
546  test<mp_method_selection>();
547 }
548 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_report)
549 {
550  test<mp_report>();
551 }
552 BOOST_AUTO_TEST_CASE(modal_dialog_test_simple_item_selector)
553 {
554  test<simple_item_selector>();
555 }
556 BOOST_AUTO_TEST_CASE(modal_dialog_test_screenshot_notification)
557 {
558  test<screenshot_notification>();
559 }
560 BOOST_AUTO_TEST_CASE(modal_dialog_test_select_orb_colors)
561 {
562  test<select_orb_colors>();
563 }
564 BOOST_AUTO_TEST_CASE(modal_dialog_test_statistics_dialog)
565 {
566  test<statistics_dialog>();
567 }
568 BOOST_AUTO_TEST_CASE(modal_dialog_test_surrender_quit)
569 {
570  test<surrender_quit>();
571 }
572 BOOST_AUTO_TEST_CASE(modal_dialog_test_theme_list)
573 {
574  test<theme_list>();
575 }
576 BOOST_AUTO_TEST_CASE(modal_dialog_test_transient_message)
577 {
578  test<transient_message>();
579 }
580 BOOST_AUTO_TEST_CASE(modal_dialog_test_unit_create)
581 {
582  test<unit_create>();
583 }
584 BOOST_AUTO_TEST_CASE(modal_dialog_test_wml_error)
585 {
586  test<wml_error>();
587 }
588 BOOST_AUTO_TEST_CASE(modal_dialog_test_wml_message_left)
589 {
590  test<wml_message_left>();
591 }
592 BOOST_AUTO_TEST_CASE(modal_dialog_test_wml_message_right)
593 {
594  test<wml_message_right>();
595 }
596 BOOST_AUTO_TEST_CASE(modal_dialog_test_wml_message_double)
597 {
598  test<wml_message_double>();
599 }
600 BOOST_AUTO_TEST_CASE(modal_dialog_test_achievements_dialog)
601 {
602  test<achievements_dialog>();
603 }
604 BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_match_history_dialog)
605 {
606  test<mp_match_history>();
607 }
608 BOOST_AUTO_TEST_CASE(modeless_dialog_test_debug_clock)
609 {
610  test_popup<debug_clock>();
611 }
612 BOOST_AUTO_TEST_CASE(tooltip_test_tooltip_large)
613 {
614  test_tip("tooltip_large");
615 }
616 BOOST_AUTO_TEST_CASE(tooltip_test_tooltip)
617 {
618  test_tip("tooltip");
619 }
620 
621 // execute last - checks that there aren't any unaccounted for GUIs
623 {
624  std::set<std::string> widget_list = gui2::registered_window_types();
625  std::vector<std::string> widgets_tested = utils::split(filesystem::read_file(test_gui2_fixture::widgets_file));
626  std::set<std::string> omitted {
627  /*
628  * The unit attack unit test are disabled for now, they calling parameters
629  * don't allow 'nullptr's needs to be fixed.
630  */
631  "unit_attack",
632  // No test for this right now, not sure how to use the test system
633  // for dialog with no default constructor
634  "lua_interpreter",
635  /*
636  * Disable label settings dialog test because we need a display_context
637  * object, which we don't have, and it's a lot of work to produce a dummy
638  * one.
639  */
640  "label_settings",
641  "addon_uninstall_list",
642  "addon_manager",
643  "loading_screen",
644  "network_transmission",
645  "synched_choice_wait",
646  "drop_down_menu",
647  "preferences_dialog",
648  "unit_recruit",
649  "unit_recall",
650  "unit_list",
651  "unit_advance",
652  "mp_host_game_prompt",
653  "mp_create_game",
654  // The title screen appears to be throwing a bad_alloc on Travis, so disable it for now
655  "title_screen",
656  "end_credits",
657  "mp_staging",
658  "mp_join_game",
659  "terrain_layers",
660  "attack_predictions",
661  "help_browser",
662  "story_viewer",
663  "outro",
664  "mp_change_control", // Basically useless without a game_board object, so disabling
665  "game_stats", // segfault with LTO
666  "gamestate_inspector", // segfault with LTO
667  "server_info",
668  "sp_options_configure",// segfault with LTO
669  "campaign_selection",// segfault with LTO
670  "game_load",// segfault after disabling the above tests
671  "file_progress",
672  };
674 
675  for(const std::string& item : widgets_tested)
676  {
677  widget_list.erase(item);
678  PLAIN_LOG << "Checking widget " << item;
679  BOOST_CHECK_EQUAL(omitted.count(item), 0);
680  }
681  for(const std::string& item : omitted)
682  {
683  widget_list.erase(item);
684  }
685 
686  // Test size() instead of empty() to get the number of offenders
687  BOOST_CHECK_EQUAL(widget_list.size(), 0);
688  for(const std::string& id : widget_list) {
689  PLAIN_LOG << "Window '" << id << "' registered but not tested.";
690  }
691 }
692 
693 BOOST_AUTO_TEST_CASE(test_make_test_fake)
694 {
696 
697  try {
698  message dlg("title", "message", true, false, false);
699  dlg.show(1);
700  } catch(const wml_exception& e) {
701  BOOST_CHECK(e.user_message == _("Failed to show a dialog, which doesn't fit on the screen."));
702  return;
703  } catch(...) {
704  BOOST_ERROR("Didn't catch the wanted exception, instead caught " << utils::get_unknown_exception_type() << ".");
705  }
706  BOOST_ERROR("Didn't catch the wanted exception, instead caught nothing.");
707 }
708 
709 BOOST_AUTO_TEST_SUITE_END()
710 
711 namespace {
712 
713 template<>
714 struct dialog_tester<addon_auth>
715 {
716  config cfg;
717  addon_auth* create()
718  {
719  return new addon_auth(cfg);
720  }
721 };
722 
723 template<>
724 struct dialog_tester<addon_connect>
725 {
726  std::string host_name = "host_name";
727  addon_connect* create()
728  {
729  return new addon_connect(host_name, true);
730  }
731 };
732 
733 template<>
734 struct dialog_tester<addon_license_prompt>
735 {
736  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.
737 
738 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.)""";
739  addon_license_prompt* create()
740  {
741  return new addon_license_prompt(license_terms);
742  }
743 };
744 
745 template<>
746 struct dialog_tester<addon_manager>
747 {
748  dialog_tester()
749  {
751  }
752  addon_manager* create()
753  {
754  addons_client client("localhost:15999");
755  return new addon_manager(client);
756  }
757 };
758 
759 template<>
760 struct dialog_tester<campaign_difficulty>
761 {
762  campaign_difficulty* create()
763  {
764  const config items("difficulty");
765 
766  return new campaign_difficulty(items);
767  }
768 };
769 
770 template<>
771 struct dialog_tester<campaign_selection>
772 {
773  saved_game state;
775  dialog_tester() : state(config {"campaign_type", "scenario"}), ng(state)
776  {
777  }
778  campaign_selection* create()
779  {
780  return new campaign_selection(ng);
781  }
782 };
783 
784 template<>
785 struct dialog_tester<chat_log>
786 {
787  config cfg;
788  vconfig vcfg;
789  replay_recorder_base rbase;
790  replay r;
791  dialog_tester() : vcfg(cfg), r(rbase) {}
792  chat_log* create()
793  {
794  return new chat_log(vcfg, r);
795  }
796 };
797 
798 template<>
799 struct dialog_tester<core_selection>
800 {
801  std::vector<config> cores;
802  dialog_tester()
803  {
804  cores.resize(1);
805  }
806  core_selection* create()
807  {
808  return new core_selection(cores, 0);
809  }
810 };
811 
812 template<>
813 struct dialog_tester<custom_tod>
814 {
815  std::vector<time_of_day> times;
816  int current_tod = 0;
817  dialog_tester()
818  {
819  times.resize(1);
820  }
821  custom_tod* create()
822  {
823  return new custom_tod(times, current_tod);
824  }
825 };
826 
827 template<>
828 struct dialog_tester<edit_label>
829 {
830  std::string label = "Label text to modify";
831  bool team_only = false;
832  edit_label* create()
833  {
834  return new edit_label(label, team_only);
835  }
836 };
837 
838 template<>
839 struct dialog_tester<edit_text>
840 {
841  std::string text = "text to modify";
842  edit_text* create()
843  {
844  return new edit_text("title", "label", text);
845  }
846 };
847 
848 template<>
849 struct dialog_tester<editor_edit_label>
850 {
851  std::string label = "Label text to modify";
852  std::string category = "test";
853  bool immutable = false, fog = false, shroud = false;
854  color_t color;
855  editor_edit_label* create()
856  {
857  return new editor_edit_label(label, immutable, fog, shroud, color, category);
858  }
859 };
860 
861 template<>
862 struct dialog_tester<editor_edit_scenario>
863 {
864  std::string id, name, descr;
865  int turns = 0, xp_mod = 50;
866  bool defeat_enemies = false, random_start = false;
867  editor_edit_scenario* create()
868  {
869  return new editor_edit_scenario(id, name, descr, turns, xp_mod, defeat_enemies, random_start);
870  }
871 };
872 
873 template<>
874 struct dialog_tester<editor_edit_side>
875 {
876  team t;
878  dialog_tester() : info(t) {}
879  editor_edit_side* create()
880  {
881  return new editor_edit_side(info);
882  }
883 };
884 
885 template<>
886 struct dialog_tester<formula_debugger>
887 {
888  wfl::formula_debugger debugger;
889  formula_debugger* create()
890  {
891  return new formula_debugger(debugger);
892  }
893 };
894 
895 template<>
896 struct dialog_tester<game_load>
897 {
898  config cfg;
899  game_config_view view;
900  // It would be good to have a test directory instead of using the same directory as the player,
901  // however this code will support that - default_saves_dir() will respect --userdata-dir.
903  dialog_tester()
904  {
905  /** @todo Would be nice to add real data to the config. */
906  }
907  game_load* create()
908  {
909  view = game_config_view::wrap(cfg);
910  return new game_load(view, data);
911  }
912 
913 };
914 
915 template<>
916 struct dialog_tester<game_save>
917 {
918  std::string title = "Title";
919  std::string filename = "filename";
920  game_save* create()
921  {
922  return new game_save(title, filename);
923  }
924 
925 };
926 
927 template<>
928 struct dialog_tester<game_save_message>
929 {
930  std::string title = "Title";
931  std::string filename = "filename";
932  std::string message = "message";
933  game_save_message* create()
934  {
935  return new game_save_message(title, filename, message);
936  }
937 
938 };
939 
940 template<>
941 struct dialog_tester<game_save_oos>
942 {
943  bool ignore_all = false;
944  std::string title = "Title";
945  std::string filename = "filename";
946  std::string message = "message";
947  game_save_oos* create()
948  {
949  return new game_save_oos(ignore_all, title, filename, message);
950  }
951 
952 };
953 
954 template<>
955 struct dialog_tester<install_dependencies>
956 {
957  addons_list addons;
958  install_dependencies* create()
959  {
960  return new install_dependencies(addons);
961  }
962 };
963 
964 template<>
965 struct dialog_tester<hotkey_bind>
966 {
967  std::string id = "";
968 
969  hotkey_bind* create()
970  {
971  return new hotkey_bind(id);
972  }
973 };
974 
975 template<>
976 struct dialog_tester<mp_lobby>
977 {
979  wesnothd_connection connection;
980  mp::lobby_info li;
981  int selected_game;
982  dialog_tester() : connection("", ""), li()
983  {
984  }
985  mp_lobby* create()
986  {
987  return new mp_lobby(li, connection, selected_game);
988  }
989 };
990 
991 template<>
992 struct dialog_tester<mp_match_history>
993 {
994  wesnothd_connection connection;
995  dialog_tester() : connection("", "")
996  {
997  }
998  mp_match_history* create()
999  {
1000  return new mp_match_history("", connection, false);
1001  }
1002 };
1003 
1004 class fake_chat_handler : public events::chat_handler {
1005  void add_chat_message(const std::time_t&,
1006  const std::string&, int, const std::string&,
1007  MESSAGE_TYPE) {}
1008  void send_chat_message(const std::string&, bool) {}
1009  void send_to_server(const config&) {}
1010  void clear_messages() {}
1011 };
1012 
1013 template<>
1014 struct dialog_tester<lobby_player_info>
1015 {
1016  config c;
1017  fake_chat_handler ch;
1018  wesnothd_connection connection;
1019  mp::user_info ui;
1020  mp::lobby_info li;
1021  dialog_tester()
1022  : connection("", "")
1023  , ui(c), li()
1024  {
1025  }
1026  lobby_player_info* create()
1027  {
1028  return new lobby_player_info(ch, ui, li);
1029  }
1030 };
1031 
1032 template<>
1033 struct dialog_tester<log_settings>
1034 {
1035  log_settings* create()
1036  {
1037  return new log_settings();
1038  }
1039 };
1040 
1041 template<>
1042 struct dialog_tester<message>
1043 {
1044  message* create()
1045  {
1046  return new message("Title", "Message", false, false, false);
1047  }
1048 };
1049 
1050 template<>
1051 struct dialog_tester<mp_create_game>
1052 {
1053  saved_game state;
1054  dialog_tester() : state(config {"campaign_type", "multiplayer"})
1055  {
1056  }
1057  mp_create_game* create()
1058  {
1059  return new mp_create_game(state, true);
1060  }
1061 };
1062 
1063 template<>
1064 struct dialog_tester<mp_join_game_password_prompt>
1065 {
1066  std::string password;
1067  mp_join_game_password_prompt* create()
1068  {
1069  return new mp_join_game_password_prompt(password);
1070  }
1071 };
1072 
1073 template<>
1074 struct dialog_tester<mp_report>
1075 {
1076  std::string report_text;
1077  mp_report* create()
1078  {
1079  return new mp_report(report_text);
1080  }
1081 };
1082 
1083 static std::vector<std::string> depcheck_mods {"mod_one", "some other", "more"};
1084 
1085 template<>
1086 struct dialog_tester<depcheck_confirm_change>
1087 {
1088  depcheck_confirm_change* create()
1089  {
1090  return new depcheck_confirm_change(true, depcheck_mods, "requester");
1091  }
1092 };
1093 
1094 template<>
1095 struct dialog_tester<depcheck_select_new>
1096 {
1097  depcheck_select_new* create()
1098  {
1099  return new depcheck_select_new(ng::depcheck::MODIFICATION, depcheck_mods);
1100  }
1101 };
1102 
1103 template<>
1104 struct dialog_tester<mp_login>
1105 {
1106  mp_login* create()
1107  {
1108  return new mp_login("wesnoth.org", "label", true);
1109  }
1110 };
1111 
1112 template<>
1113 struct dialog_tester<simple_item_selector>
1114 {
1115  simple_item_selector* create()
1116  {
1117  return new simple_item_selector("title", "message", std::vector<std::string>(), false, false);
1118  }
1119 };
1120 
1121 template<>
1122 struct dialog_tester<screenshot_notification>
1123 {
1124  screenshot_notification* create()
1125  {
1126  return new screenshot_notification("path", nullptr);
1127  }
1128 };
1129 
1130 template<>
1131 struct dialog_tester<theme_list>
1132 {
1133  static theme_info make_theme(const std::string& name)
1134  {
1135  theme_info ti;
1136  ti.id = name;
1137  ti.name = name;
1138  ti.description = name + " this is a description";
1139  return ti;
1140  }
1141  static std::vector<theme_info> themes;
1142  theme_list* create()
1143  {
1144  return new theme_list(themes, 0);
1145  }
1146 };
1147 std::vector<theme_info> dialog_tester<theme_list>::themes {make_theme("classic"), make_theme("new"), make_theme("more"), make_theme("themes")};
1148 
1149 template<>
1150 struct dialog_tester<editor_generate_map>
1151 {
1152  std::vector<std::unique_ptr<map_generator>> map_generators;
1153  editor_generate_map* create()
1154  {
1155  for(const config &i : test_gui2_fixture::main_config.child_range("multiplayer")) {
1156  if(i["scenario_generation"] == "default") {
1157  const config &generator_cfg = i.child("generator");
1158  if (generator_cfg) {
1159  map_generators.emplace_back(create_map_generator("", generator_cfg));
1160  }
1161  }
1162  }
1163 
1164  editor_generate_map* result = new editor_generate_map(map_generators);
1165  BOOST_REQUIRE_MESSAGE(result, "Failed to create a dialog.");
1166 
1167  return result;
1168  }
1169 };
1170 
1171 template<>
1172 struct dialog_tester<editor_new_map>
1173 {
1174  int width = 10;
1175  int height = 10;
1176  editor_new_map* create()
1177  {
1178  return new editor_new_map("Test", width, height);
1179  }
1180 };
1181 
1182 template<>
1183 struct dialog_tester<editor_resize_map>
1184 {
1185  int width = 0;
1186  int height = 0;
1188  bool copy = false;
1189  editor_resize_map* create()
1190  {
1191  return new editor_resize_map(width, height, expand_direction, copy);
1192  }
1193 };
1194 
1195 template<>
1196 struct dialog_tester<file_dialog>
1197 {
1198  file_dialog* create()
1199  {
1200  return new file_dialog();
1201  }
1202 };
1203 
1204 template<>
1205 struct dialog_tester<folder_create>
1206 {
1207  std::string folder_name;
1208  folder_create* create()
1209  {
1210  return new folder_create(folder_name);
1211  }
1212 };
1213 
1214 template<>
1215 struct dialog_tester<transient_message>
1216 {
1217  transient_message* create()
1218  {
1219  return new transient_message("Title", false, "Message", false, "");
1220  }
1221 };
1222 
1223 template<>
1224 struct dialog_tester<title_screen>
1225 {
1226  std::vector<std::string> args;
1227  commandline_options opts;
1229  dialog_tester() : opts(args), game(opts) {}
1230  title_screen* create()
1231  {
1232  return new title_screen(game);
1233  }
1234 };
1235 
1236 template<>
1237 struct dialog_tester<wml_error>
1238 {
1239  static std::vector<std::string> files;
1240  wml_error* create()
1241  {
1242  return new wml_error("Summary", "Post summary", files, "Details");
1243  }
1244 };
1245 std::vector<std::string> dialog_tester<wml_error>::files {"some", "files", "here"};
1246 
1247 template<>
1248 struct dialog_tester<wml_message_left>
1249 {
1250  wml_message_left* create()
1251  {
1252  return new wml_message_left("Title", "Message", "", false);
1253  }
1254 };
1255 
1256 template<>
1257 struct dialog_tester<wml_message_right>
1258 {
1259  wml_message_right* create()
1260  {
1261  return new wml_message_right("Title", "Message", "", false);
1262  }
1263 };
1264 
1265 template<>
1266 struct dialog_tester<wml_message_double>
1267 {
1268  wml_message_double* create()
1269  {
1270  return new wml_message_double("Title", "Message", "", false, "", true);
1271  }
1272 };
1273 
1274 template<>
1275 struct dialog_tester<faction_select>
1276 {
1277  config era_cfg, side_cfg;
1278  std::vector<const config*> eras;
1279  ng::flg_manager flg;
1280  std::string color;
1281  dialog_tester()
1282  : era_cfg(), side_cfg(), eras(1, &era_cfg) // TODO: Add an actual era definition
1283  , flg(eras, side_cfg, false, false, false)
1284  , color("teal")
1285  {}
1286  faction_select* create() {
1287  return new faction_select(flg, color, 1);
1288  }
1289 };
1290 
1291 template<>
1292 struct dialog_tester<generator_settings>
1293 {
1294  config cfg;
1296  dialog_tester() : data(cfg) {}
1297  generator_settings* create()
1298  {
1299  return new generator_settings(data);
1300  }
1301 };
1302 
1303 template<>
1304 struct dialog_tester<sp_options_configure>
1305 {
1306  saved_game state;
1307  ng::create_engine create_eng;
1308  ng::configure_engine config_eng;
1309  dialog_tester() : create_eng(state)
1310  , config_eng(create_eng.get_state()) {}
1311  sp_options_configure* create()
1312  {
1313  return new sp_options_configure(create_eng, config_eng);
1314  }
1315 };
1316 
1317 template<>
1318 struct dialog_tester<statistics_dialog>
1319 {
1320  team t;
1321  dialog_tester() : t() {}
1322  statistics_dialog* create()
1323  {
1324  return new statistics_dialog(t);
1325  }
1326 };
1327 
1328 template<>
1329 struct dialog_tester<surrender_quit>
1330 {
1331  dialog_tester() {}
1332  surrender_quit* create()
1333  {
1334  return new surrender_quit();
1335  }
1336 };
1337 
1338 } // namespace
bool new_widgets
Do we wish to use the new library or not.
Definition: settings.cpp:23
t_string description
Definition: theme.hpp:39
void remove()
Removes a tip.
Definition: tooltip.cpp:111
Defines the exception classes for the layout algorithm.
#define PLAIN_LOG
Definition: log.hpp:260
static config_cache & instance()
Get reference to the singleton object.
configure_engine
saved_game & get_state()
static config main_config
Definition: test_gui2.cpp:159
std::string get_modeless_dialog_id(const modeless_dialog &dialog)
Definition: test_gui2.cpp:176
bool delete_file(const std::string &filename)
Add a special kind of assert to validate whether the input from WML doesn&#39;t contain any problems that...
Main class to show messages to the user.
Definition: message.hpp:35
static game_config_view wrap(const config &cfg)
Formula AI debugger.
logger & info()
Definition: log.cpp:228
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
std::string id
Definition: theme.hpp:37
game_display & get_fake_display(const int width, const int height)
Gets a fake test display.
std::unique_ptr< game_config_manager > config_manager
Definition: test_gui2.cpp:161
t_string name
Definition: theme.hpp:38
Exception thrown when the height resizing has failed.
This file contains the window object, this object is a top level container which has the event manage...
void draw()
Draws the window.
Definition: window.cpp:615
The paths manager is responsible for recording the various paths that binary files may be located at...
Definition: filesystem.hpp:402
This class represents the collective information the client has about the players and games on the se...
Definition: lobby_info.hpp:31
std::string_view data
Definition: picture.cpp:206
std::string user_message
The message for the user explaining what went wrong.
const std::vector< std::string > items
Replay control code.
std::string get_unknown_exception_type()
Utility function for finding the type of thing caught with catch(...).
Definition: general.cpp:23
static std::string _(const char *str)
Definition: gettext.hpp:93
FLG stands for faction, leader and gender.
Definition: flg_manager.hpp:29
bool show(const unsigned auto_close_time=0)
Shows the window.
void load_config(const config &v)
BOOST_FIXTURE_TEST_SUITE(test_map_location, MLFixture)
Generic file dialog.
bool fog()
Definition: game.cpp:525
This class stores all the data for a single &#39;side&#39; (in game nomenclature).
Definition: team.hpp:75
static const std::string widgets_file
Definition: test_gui2.cpp:160
Exception thrown when the width has been modified during resizing.
BOOST_AUTO_TEST_CASE(modal_dialog_test_addon_auth)
Definition: test_gui2.cpp:388
std::string label
What to show in the filter&#39;s drop-down list.
Definition: manager.cpp:217
This file contains the settings handling of the widget library.
virtual const std::string & window_id() const
The ID of the window to build.
A class that represents a TCP/IP connection to the wesnothd server.
The basic class for representing 8-bit RGB or RGBA colour values.
Definition: color.hpp:58
Exception thrown when the width resizing has failed.
std::string path
Definition: game_config.cpp:39
std::string read_file(const std::string &fname)
Basic disk I/O - read file.
Add-ons (campaignd) client class.
Definition: client.hpp:40
Various uncategorised dialogs.
std::vector< std::string > dummy_args
Definition: test_gui2.cpp:162
Helper class, don&#39;t construct this directly.
void get_config(const std::string &path, config &cfg, abstract_validator *validator=nullptr)
Gets a config object from given path.
std::string dev_message
The message for developers telling which problem was triggered, this shouldn&#39;t be translated...
bool shroud()
Definition: game.cpp:535
std::string id
Text to match against addon_info.tags()
Definition: manager.cpp:215
void write_file(const std::string &fname, const std::string &data, std::ios_base::openmode mode)
Throws io_exception if an error occurs.
void clear_defines()
Clear stored defines map to default values.
map_generator * create_map_generator(const std::string &name, const config &cfg, const config *vars)
Definition: map_create.cpp:29
std::size_t i
Definition: function.cpp:968
Game configuration data as global variables.
Definition: build_info.cpp:60
std::string get_modal_dialog_id(const modal_dialog &dialog)
Definition: test_gui2.cpp:171
std::string password(const std::string &server, const std::string &login)
bool load_language_list()
Definition: language.cpp:104
Declarations for File-IO.
virtual const std::string & window_id() const =0
The ID of the window to build.
This class represents the information a client has about another player.
Definition: lobby_data.hpp:32
int turns()
Definition: game.cpp:545
double t
Definition: astarsearch.cpp:65
std::vector< std::string > split(const config_attribute_value &val)
The popup class shows windows that are shown non-modal.
A variable-expanding proxy for the config class.
Definition: variable.hpp:44
Abstract base class for all modal dialogs.
void point(int x, int y)
Draw a single point.
Definition: draw.cpp:193
point resolution()
Definition: general.cpp:392
#define e
void send_to_server(const config &data)
Attempts to send given data to server if a connection is open.
std::set< std::string > & registered_window_types()
Returns the list of registered windows.
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:60
mock_char c
std::map< std::string, addon_info > addons_list
Definition: info.hpp:28
base class of top level items, the only item which needs to store the final canvases to draw on...
Definition: window.hpp:66
void add_define(const std::string &define)
Add a entry to preproc defines map.
Networked add-ons (campaignd) client interface.
std::pair< std::string, unsigned > item
Definition: help_impl.hpp:414
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:81
Singleton class to manage game config file caching.