The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
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"
26#include "game_config_view.hpp"
27#include "game_display.hpp"
32#include "game_launcher.hpp"
34#include "gettext.hpp"
101#include "gui/dialogs/outro.hpp"
102#include "gui/dialogs/prompt.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"
133#include "wml_exception.hpp"
134
135#include <boost/test/unit_test.hpp>
136
137#include <functional>
138#include <memory>
139
140using namespace gui2::dialogs;
141
145 , dummy_args({"wesnoth", "--noaddons"})
146 {
149
150 cache.clear_defines();
151 cache.add_define("EDITOR");
152 cache.add_define("MULTIPLAYER");
153
154 /** The main config, which contains the entire WML tree. */
155 main_config = cache.get_config(game_config::path +"/data");
157
158 const filesystem::binary_paths_manager bin_paths_manager(game_config_view_);
159
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};
172const std::string test_gui2_fixture::widgets_file = "widgets_tested.log";
173
174namespace gui2 {
175
176namespace dialogs {
177
178std::string get_modal_dialog_id(const modal_dialog& dialog)
179{
180 return dialog.window_id();
181}
182
183std::string get_modeless_dialog_id(const modeless_dialog& dialog)
184{
185 return dialog.window_id();
186}
187
188} // namespace dialogs
189} // namespace gui2
190
191namespace {
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::set_test_resolution(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);
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(...) {
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::set_test_resolution(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();
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(...) {
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::set_test_resolution(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();
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(...) {
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
336const 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
347template<class T>
348void 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
361template<class T>
362void 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
374void 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
390BOOST_AUTO_TEST_CASE(modal_dialog_test_addon_auth)
391{
392 test<addon_auth>();
393}
394BOOST_AUTO_TEST_CASE(modal_dialog_test_addon_connect)
395{
396 test<addon_connect>();
397}
398BOOST_AUTO_TEST_CASE(modal_dialog_test_addon_license_prompt)
399{
400 test<addon_license_prompt>();
401}
402BOOST_AUTO_TEST_CASE(modal_dialog_test_campaign_difficulty)
403{
404 test<campaign_difficulty>();
405}
406BOOST_AUTO_TEST_CASE(modal_dialog_test_chat_log)
407{
408 test<chat_log>();
409}
410BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_choose_addon)
411{
412 test<editor_choose_addon>();
413}
414BOOST_AUTO_TEST_CASE(modal_dialog_test_prompt)
415{
416 test<prompt>();
417}
418BOOST_AUTO_TEST_CASE(modal_dialog_test_core_selection)
419{
420 test<core_selection>();
421}
422BOOST_AUTO_TEST_CASE(modal_dialog_test_depcheck_confirm_change)
423{
424 test<depcheck_confirm_change>();
425}
426BOOST_AUTO_TEST_CASE(modal_dialog_test_depcheck_select_new)
427{
428 test<depcheck_select_new>();
429}
430BOOST_AUTO_TEST_CASE(modal_dialog_test_edit_label)
431{
432 test<edit_label>();
433}
434BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_edit_pbl)
435{
436 test<editor_edit_pbl>();
437}
438BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_edit_pbl_translation)
439{
440 test<editor_edit_pbl_translation>();
441}
442BOOST_AUTO_TEST_CASE(modal_dialog_test_edit_text)
443{
444 test<edit_text>();
445}
446BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_edit_label)
447{
448 test<editor_edit_label>();
449}
450BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_edit_side)
451{
452 test<editor_edit_side>();
453}
454BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_edit_scenario)
455{
456 test<editor_edit_scenario>();
457}
458BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_generate_map)
459{
460 test<editor_generate_map>();
461}
462BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_new_map)
463{
464 test<editor_new_map>();
465}
466BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_resize_map)
467{
468 test<editor_resize_map>();
469}
470BOOST_AUTO_TEST_CASE(modal_dialog_test_faction_select)
471{
472 test<faction_select>();
473}
474BOOST_AUTO_TEST_CASE(modal_dialog_test_file_dialog)
475{
476 test<file_dialog>();
477}
478BOOST_AUTO_TEST_CASE(modal_dialog_test_folder_create)
479{
480 test<folder_create>();
481}
482BOOST_AUTO_TEST_CASE(modal_dialog_test_formula_debugger)
483{
484 test<formula_debugger>();
485}
486BOOST_AUTO_TEST_CASE(modal_dialog_test_game_cache_options)
487{
488 test<game_cache_options>();
489}
490BOOST_AUTO_TEST_CASE(modal_dialog_test_game_delete)
491{
492 test<game_delete>();
493}
494BOOST_AUTO_TEST_CASE(modal_dialog_test_game_version)
495{
496 test<game_version>();
497}
498BOOST_AUTO_TEST_CASE(modal_dialog_test_game_save)
499{
500 test<game_save>();
501}
502BOOST_AUTO_TEST_CASE(modal_dialog_test_game_save_message)
503{
504 test<game_save_message>();
505}
506BOOST_AUTO_TEST_CASE(modal_dialog_test_game_save_oos)
507{
508 test<game_save_oos>();
509}
510BOOST_AUTO_TEST_CASE(modal_dialog_test_generator_settings)
511{
512 test<generator_settings>();
513}
514BOOST_AUTO_TEST_CASE(modal_dialog_test_gui_test_dialog)
515{
516 test<gui_test_dialog>();
517}
518BOOST_AUTO_TEST_CASE(modal_dialog_test_hotkey_bind)
519{
520 test<hotkey_bind>();
521}
522BOOST_AUTO_TEST_CASE(modal_dialog_test_install_dependencies)
523{
524 test<install_dependencies>();
525}
526BOOST_AUTO_TEST_CASE(modal_dialog_test_language_selection)
527{
528 test<language_selection>();
529}
530BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_lobby)
531{
532 test<mp_lobby>();
533}
534BOOST_AUTO_TEST_CASE(modal_dialog_test_lobby_player_info)
535{
536 test<lobby_player_info>();
537}
538BOOST_AUTO_TEST_CASE(modal_dialog_test_log_settings)
539{
540 test<log_settings>();
541}
542BOOST_AUTO_TEST_CASE(modal_dialog_test_message)
543{
544 test<message>();
545}
546BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_alerts_options)
547{
548 test<mp_alerts_options>();
549}
550BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_connect)
551{
552 test<mp_connect>();
553}
554BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_join_game_password_prompt)
555{
556 test<mp_join_game_password_prompt>();
557}
558BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_login)
559{
560 test<mp_login>();
561}
562BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_method_selection)
563{
564 test<mp_method_selection>();
565}
566BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_report)
567{
568 test<mp_report>();
569}
570BOOST_AUTO_TEST_CASE(modal_dialog_test_simple_item_selector)
571{
572 test<simple_item_selector>();
573}
574BOOST_AUTO_TEST_CASE(modal_dialog_test_screenshot_notification)
575{
576 test<screenshot_notification>();
577}
578BOOST_AUTO_TEST_CASE(modal_dialog_test_select_orb_colors)
579{
580 test<select_orb_colors>();
581}
582BOOST_AUTO_TEST_CASE(modal_dialog_test_reachmap_options)
583{
584 test<reachmap_options>();
585}
586BOOST_AUTO_TEST_CASE(modal_dialog_test_statistics_dialog)
587{
588 test<statistics_dialog>();
589}
590BOOST_AUTO_TEST_CASE(modal_dialog_test_surrender_quit)
591{
592 test<surrender_quit>();
593}
594BOOST_AUTO_TEST_CASE(modal_dialog_test_theme_list)
595{
596 test<theme_list>();
597}
598BOOST_AUTO_TEST_CASE(modal_dialog_test_transient_message)
599{
600 test<transient_message>();
601}
602BOOST_AUTO_TEST_CASE(modal_dialog_test_wml_error)
603{
604 test<wml_error>();
605}
606BOOST_AUTO_TEST_CASE(modal_dialog_test_wml_message_left)
607{
608 test<wml_message_left>();
609}
610BOOST_AUTO_TEST_CASE(modal_dialog_test_wml_message_right)
611{
612 test<wml_message_right>();
613}
614BOOST_AUTO_TEST_CASE(modal_dialog_test_wml_message_double)
615{
616 test<wml_message_double>();
617}
618BOOST_AUTO_TEST_CASE(modal_dialog_test_achievements_dialog)
619{
620 test<achievements_dialog>();
621}
622BOOST_AUTO_TEST_CASE(modal_dialog_test_addon_server_info)
623{
624 test<addon_server_info>();
625}
626BOOST_AUTO_TEST_CASE(modal_dialog_test_mp_match_history_dialog)
627{
628 test<mp_match_history>();
629}
630BOOST_AUTO_TEST_CASE(modal_dialog_test_migrate_version_selection_dialog)
631{
632 test<gui2::dialogs::migrate_version_selection>();
633}
634BOOST_AUTO_TEST_CASE(modeless_dialog_test_debug_clock)
635{
636 test_popup<debug_clock>();
637}
638BOOST_AUTO_TEST_CASE(tooltip_test_tooltip_large)
639{
640 test_tip("tooltip_large");
641}
642BOOST_AUTO_TEST_CASE(tooltip_test_tooltip)
643{
644 test_tip("tooltip");
645}
646BOOST_AUTO_TEST_CASE(modal_dialog_test_tod_new_schedule)
647{
648 test<tod_new_schedule>();
649}
650
651BOOST_AUTO_TEST_CASE(modal_dialog_test_editor_edit_unit)
652{
653 test<editor_edit_unit>();
654}
655
656// execute last - checks that there aren't any unaccounted for GUIs
658{
659 std::set<std::string> widget_list = gui2::registered_window_types();
660 std::vector<std::string> widgets_tested = utils::split(filesystem::read_file(test_gui2_fixture::widgets_file));
661 std::set<std::string> omitted {
662 /*
663 * The unit attack unit test are disabled for now, they calling parameters
664 * don't allow 'nullptr's needs to be fixed.
665 */
666 "unit_attack",
667 // No test for this right now, not sure how to use the test system
668 // for dialog with no default constructor
669 "lua_interpreter",
670 /*
671 * Disable label settings dialog test because we need a display_context
672 * object, which we don't have, and it's a lot of work to produce a dummy
673 * one.
674 */
675 "label_settings",
676 "addon_uninstall_list",
677 "addon_manager",
678 "loading_screen",
679 "network_transmission",
680 "synched_choice_wait",
681 "drop_down_menu",
682 "preferences_dialog",
683 "units_dialog",
684 "unit_advance",
685 "mp_host_game_prompt",
686 "mp_create_game",
687 // The title screen appears to be throwing a bad_alloc on Travis, so disable it for now
688 "title_screen",
689 "end_credits",
690 "mp_staging",
691 "mp_join_game",
692 "terrain_layers",
693 "attack_predictions",
694 "help_browser",
695 "story_viewer",
696 "outro",
697 "mp_change_control", // Basically useless without a game_board object, so disabling
698 "game_stats", // segfault with LTO
699 "gamestate_inspector", // segfault with LTO
700 "server_info",
701 "sp_options_configure",// segfault with LTO
702 "campaign_selection",// segfault with LTO
703 "game_load",// segfault after disabling the above tests
704 "file_progress",
705 "fps_report", // needs something to report...
706 "custom_tod", // needs to be adapted to handle a null display
707 };
709
710 for(const std::string& item : widgets_tested)
711 {
712 widget_list.erase(item);
713 PLAIN_LOG << "Checking widget " << item;
714 BOOST_CHECK_EQUAL(omitted.count(item), 0);
715 }
716 for(const std::string& item : omitted)
717 {
718 widget_list.erase(item);
719 }
720
721 // Test size() instead of empty() to get the number of offenders
722 BOOST_CHECK_EQUAL(widget_list.size(), 0);
723 for(const std::string& id : widget_list) {
724 PLAIN_LOG << "Window '" << id << "' registered but not tested.";
725 }
726}
727
728BOOST_AUTO_TEST_CASE(test_make_test_fake)
729{
731
732 try {
733 message dlg("title", "message", true, false, false);
734 dlg.show(1);
735 } catch(const wml_exception& e) {
737 return;
738 } catch(...) {
739 BOOST_ERROR("Didn't catch the wanted exception, instead caught " << utils::get_unknown_exception_type() << ".");
740 }
741 BOOST_ERROR("Didn't catch the wanted exception, instead caught nothing.");
742}
743
744BOOST_AUTO_TEST_SUITE_END()
745
746namespace {
747
748template<>
749struct dialog_tester<addon_server_info>
750{
751 std::string s = "";
752 bool b = false;
753 addon_server_info* create()
754 {
755 addons_client client("localhost:15999");
756 return new addon_server_info(client, s, b);
757 }
758};
759
760template<>
761struct dialog_tester<addon_auth>
762{
763 config cfg;
764 addon_auth* create()
765 {
766 return new addon_auth(cfg);
767 }
768};
769
770template<>
771struct dialog_tester<addon_connect>
772{
773 std::string host_name = "host_name";
774 addon_connect* create()
775 {
776 return new addon_connect(host_name, true);
777 }
778};
779
780template<>
781struct dialog_tester<addon_license_prompt>
782{
783 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.
784
785Sed 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.)";
786 addon_license_prompt* create()
787 {
788 return new addon_license_prompt(license_terms);
789 }
790};
791
792template<>
793struct dialog_tester<addon_manager>
794{
795 dialog_tester()
796 {
798 }
799 addon_manager* create()
800 {
801 addons_client client("localhost:15999");
802 return new addon_manager(client);
803 }
804};
805
806template<>
807struct dialog_tester<campaign_difficulty>
808{
809 campaign_difficulty* create()
810 {
811 const config items("difficulty");
812
813 return new campaign_difficulty(items);
814 }
815};
816
817template<>
818struct dialog_tester<campaign_selection>
819{
820 saved_game state;
822 dialog_tester() : state(config {"campaign_type", "scenario"}), ng(state)
823 {
824 }
825 campaign_selection* create()
826 {
827 return new campaign_selection(ng);
828 }
829};
830
831template<>
832struct dialog_tester<chat_log>
833{
834 config cfg;
835 vconfig vcfg;
837 replay r;
838 dialog_tester() : vcfg(cfg), r(rbase) {}
839 chat_log* create()
840 {
841 return new chat_log(vcfg, r);
842 }
843};
844
845template<>
846struct dialog_tester<editor_choose_addon>
847{
848 std::string temp;
849 editor_choose_addon* create()
850 {
851 return new editor_choose_addon(temp);
852 }
853};
854
855template<>
856struct dialog_tester<prompt>
857{
858 std::string temp;
859 prompt* create()
860 {
861 return new prompt(temp);
862 }
863};
864
865template<>
866struct dialog_tester<core_selection>
867{
868 std::vector<config> cores;
869 dialog_tester()
870 {
871 cores.resize(1);
872 }
873 core_selection* create()
874 {
875 return new core_selection(cores, 0);
876 }
877};
878
879template<>
880struct dialog_tester<custom_tod>
881{
882 std::vector<time_of_day> times;
883 int current_tod = 0;
884 dialog_tester()
885 {
886 times.resize(1);
887 }
888 custom_tod* create()
889 {
890 return new custom_tod(times, current_tod);
891 }
892};
893
894template<>
895struct dialog_tester<edit_label>
896{
897 std::string label = "Label text to modify";
898 bool team_only = false;
899 edit_label* create()
900 {
901 return new edit_label(label, team_only);
902 }
903};
904
905template<>
906struct dialog_tester<edit_text>
907{
908 std::string text = "text to modify";
909 edit_text* create()
910 {
911 return new edit_text("title", "label", text);
912 }
913};
914
915template<>
916struct dialog_tester<editor_edit_label>
917{
918 std::string label = "Label text to modify";
919 std::string category = "test";
920 bool immutable = false, fog = false, shroud = false;
921 color_t color;
922 editor_edit_label* create()
923 {
924 return new editor_edit_label(label, immutable, fog, shroud, color, category);
925 }
926};
927
928template<>
929struct dialog_tester<editor_edit_pbl>
930{
931 std::string temp;
932 std::string temp1;
933 editor_edit_pbl* create()
934 {
935 return new editor_edit_pbl(temp, temp1);
936 }
937};
938
939template<>
940struct dialog_tester<editor_edit_pbl_translation>
941{
942 std::string temp1;
943 std::string temp2;
944 std::string temp3;
946 {
947 return new editor_edit_pbl_translation(temp1, temp2, temp3);
948 }
949};
950
951template<>
952struct dialog_tester<editor_edit_scenario>
953{
954 std::string id, name, descr;
955 int turns = 0, xp_mod = 50;
956 bool defeat_enemies = false, random_start = false;
957 editor_edit_scenario* create()
958 {
959 return new editor_edit_scenario(id, name, descr, turns, xp_mod, defeat_enemies, random_start);
960 }
961};
962
963template<>
964struct dialog_tester<editor_edit_side>
965{
966 team t;
968 dialog_tester() : info(t) {}
969 editor_edit_side* create()
970 {
971 return new editor_edit_side(info);
972 }
973};
974
975template<>
976struct dialog_tester<formula_debugger>
977{
978 wfl::formula_debugger debugger;
979 formula_debugger* create()
980 {
981 return new formula_debugger(debugger);
982 }
983};
984
985template<>
986struct dialog_tester<game_load>
987{
988 config cfg;
989 // It would be good to have a test directory instead of using the same directory as the player,
990 // however this code will support that - default_saves_dir() will respect --userdata-dir.
992 dialog_tester()
993 {
994 /** @todo Would be nice to add real data to the config. */
995 }
996 game_load* create()
997 {
998 return new game_load(data);
999 }
1000};
1001
1002template<>
1003struct dialog_tester<game_save>
1004{
1005 std::string title = "Title";
1006 std::string filename = "filename";
1007 game_save* create()
1008 {
1009 return new game_save(title, filename);
1010 }
1011
1012};
1013
1014template<>
1015struct dialog_tester<game_save_message>
1016{
1017 std::string title = "Title";
1018 std::string filename = "filename";
1019 std::string message = "message";
1020 game_save_message* create()
1021 {
1022 return new game_save_message(title, filename, message);
1023 }
1024
1025};
1026
1027template<>
1028struct dialog_tester<game_save_oos>
1029{
1030 bool ignore_all = false;
1031 std::string title = "Title";
1032 std::string filename = "filename";
1033 std::string message = "message";
1034 game_save_oos* create()
1035 {
1036 return new game_save_oos(ignore_all, title, filename, message);
1037 }
1038
1039};
1040
1041template<>
1042struct dialog_tester<install_dependencies>
1043{
1044 addons_list addons;
1045 install_dependencies* create()
1046 {
1047 return new install_dependencies(addons);
1048 }
1049};
1050
1051template<>
1052struct dialog_tester<hotkey_bind>
1053{
1054 std::string id = "";
1055
1056 hotkey_bind* create()
1057 {
1058 return new hotkey_bind(id);
1059 }
1060};
1061
1062template<>
1063struct dialog_tester<mp_lobby>
1064{
1066 wesnothd_connection connection;
1067 mp::lobby_info li;
1068 int selected_game;
1069 dialog_tester() : connection("", ""), li()
1070 {
1071 }
1072 mp_lobby* create()
1073 {
1074 return new mp_lobby(li, connection, selected_game);
1075 }
1076};
1077
1078template<>
1079struct dialog_tester<mp_match_history>
1080{
1081 wesnothd_connection connection;
1082 dialog_tester() : connection("", "")
1083 {
1084 }
1085 mp_match_history* create()
1086 {
1087 return new mp_match_history("", connection, false);
1088 }
1089};
1090
1091template<>
1092struct dialog_tester<gui2::dialogs::migrate_version_selection>
1093{
1095 {
1097 }
1098};
1099
1100class fake_chat_handler : public events::chat_handler {
1101 void add_chat_message(const std::chrono::system_clock::time_point&,
1102 const std::string&, int, const std::string&,
1103 MESSAGE_TYPE) {}
1104 void send_chat_message(const std::string&, bool) {}
1105 void send_to_server(const config&) {}
1106 void clear_messages() {}
1107};
1108
1109template<>
1110struct dialog_tester<lobby_player_info>
1111{
1112 config c;
1113 fake_chat_handler ch;
1114 wesnothd_connection connection;
1115 mp::user_info ui;
1116 mp::lobby_info li;
1117 dialog_tester()
1118 : connection("", "")
1119 , ui(c), li()
1120 {
1121 }
1122 lobby_player_info* create()
1123 {
1124 return new lobby_player_info(ch, ui, li);
1125 }
1126};
1127
1128template<>
1129struct dialog_tester<log_settings>
1130{
1131 log_settings* create()
1132 {
1133 return new log_settings();
1134 }
1135};
1136
1137template<>
1138struct dialog_tester<message>
1139{
1140 message* create()
1141 {
1142 return new message("Title", "Message", false, false, false);
1143 }
1144};
1145
1146template<>
1147struct dialog_tester<mp_create_game>
1148{
1149 saved_game state;
1150 dialog_tester() : state(config {"campaign_type", "multiplayer"})
1151 {
1152 }
1153 mp_create_game* create()
1154 {
1155 return new mp_create_game(state, true);
1156 }
1157};
1158
1159template<>
1160struct dialog_tester<mp_join_game_password_prompt>
1161{
1162 std::string password;
1164 {
1165 return new mp_join_game_password_prompt(password);
1166 }
1167};
1168
1169template<>
1170struct dialog_tester<mp_report>
1171{
1172 std::string report_text;
1173 mp_report* create()
1174 {
1175 return new mp_report(report_text);
1176 }
1177};
1178
1179static std::vector<std::string> depcheck_mods {"mod_one", "some other", "more"};
1180
1181template<>
1182struct dialog_tester<depcheck_confirm_change>
1183{
1184 depcheck_confirm_change* create()
1185 {
1186 return new depcheck_confirm_change(true, depcheck_mods, "requester");
1187 }
1188};
1189
1190template<>
1191struct dialog_tester<depcheck_select_new>
1192{
1193 depcheck_select_new* create()
1194 {
1195 return new depcheck_select_new(ng::depcheck::MODIFICATION, depcheck_mods);
1196 }
1197};
1198
1199template<>
1200struct dialog_tester<mp_login>
1201{
1202 mp_login* create()
1203 {
1204 return new mp_login("wesnoth.org", "label", true);
1205 }
1206};
1207
1208template<>
1209struct dialog_tester<simple_item_selector>
1210{
1211 simple_item_selector* create()
1212 {
1213 return new simple_item_selector("title", "message", std::vector<std::string>(), false, false);
1214 }
1215};
1216
1217template<>
1218struct dialog_tester<screenshot_notification>
1219{
1220 screenshot_notification* create()
1221 {
1222 return new screenshot_notification("path", nullptr);
1223 }
1224};
1225
1226template<>
1227struct dialog_tester<theme_list>
1228{
1229 static theme_info make_theme(const std::string& name)
1230 {
1231 theme_info ti;
1232 ti.id = name;
1233 ti.name = name;
1234 ti.description = name + " this is a description";
1235 return ti;
1236 }
1237 static std::vector<theme_info> themes;
1238 theme_list* create()
1239 {
1240 return new theme_list(themes, 0);
1241 }
1242};
1243std::vector<theme_info> dialog_tester<theme_list>::themes {make_theme("classic"), make_theme("new"), make_theme("more"), make_theme("themes")};
1244
1245template<>
1246struct dialog_tester<editor_generate_map>
1247{
1248 std::vector<std::unique_ptr<map_generator>> map_generators;
1249 editor_generate_map* create()
1250 {
1251 for(const config &i : test_gui2_fixture::main_config.child_range("multiplayer")) {
1252 if(i["scenario_generation"] == "default") {
1253 auto generator_cfg = i.optional_child("generator");
1254 if (generator_cfg) {
1255 map_generators.emplace_back(create_map_generator("", *generator_cfg));
1256 }
1257 }
1258 }
1259
1260 editor_generate_map* result = new editor_generate_map(map_generators);
1261 BOOST_REQUIRE_MESSAGE(result, "Failed to create a dialog.");
1262
1263 return result;
1264 }
1265};
1266
1267template<>
1268struct dialog_tester<editor_new_map>
1269{
1270 int width = 10;
1271 int height = 10;
1272 editor_new_map* create()
1273 {
1274 return new editor_new_map("Test", width, height);
1275 }
1276};
1277
1278template<>
1279struct dialog_tester<editor_resize_map>
1280{
1281 int width = 0;
1282 int height = 0;
1284 bool copy = false;
1285 editor_resize_map* create()
1286 {
1287 return new editor_resize_map(width, height, expand_direction, copy);
1288 }
1289};
1290
1291template<>
1292struct dialog_tester<file_dialog>
1293{
1294 file_dialog* create()
1295 {
1296 return new file_dialog();
1297 }
1298};
1299
1300template<>
1301struct dialog_tester<folder_create>
1302{
1303 std::string folder_name;
1304 folder_create* create()
1305 {
1306 return new folder_create(folder_name);
1307 }
1308};
1309
1310template<>
1311struct dialog_tester<transient_message>
1312{
1313 transient_message* create()
1314 {
1315 return new transient_message("Title", false, "Message", false, "");
1316 }
1317};
1318
1319template<>
1320struct dialog_tester<title_screen>
1321{
1322 std::vector<std::string> args;
1325 dialog_tester() : opts(args), game(opts) {}
1326 title_screen* create()
1327 {
1328 return new title_screen(game);
1329 }
1330};
1331
1332template<>
1333struct dialog_tester<wml_error>
1334{
1335 static std::vector<std::string> files;
1336 wml_error* create()
1337 {
1338 return new wml_error("Summary", "Post summary", files, "Details");
1339 }
1340};
1341std::vector<std::string> dialog_tester<wml_error>::files {"some", "files", "here"};
1342
1343template<>
1344struct dialog_tester<wml_message_left>
1345{
1346 wml_message_left* create()
1347 {
1348 return new wml_message_left("Title", "Message", "", false);
1349 }
1350};
1351
1352template<>
1353struct dialog_tester<wml_message_right>
1354{
1355 wml_message_right* create()
1356 {
1357 return new wml_message_right("Title", "Message", "", false);
1358 }
1359};
1360
1361template<>
1362struct dialog_tester<wml_message_double>
1363{
1364 wml_message_double* create()
1365 {
1366 return new wml_message_double("Title", "Message", "", false, "", true);
1367 }
1368};
1369
1370template<>
1371struct dialog_tester<faction_select>
1372{
1373 config era_cfg, side_cfg;
1374 std::vector<const config*> eras;
1375 ng::era_metadata era;
1376 ng::flg_manager flg;
1377 std::string color;
1378 dialog_tester()
1379 : era_cfg(), side_cfg(), eras(1, &era_cfg), era(era_cfg) // TODO: Add an actual era definition
1380 , flg(era, eras, side_cfg, false, false, false)
1381 , color("teal")
1382 {}
1383 faction_select* create() {
1384 return new faction_select(flg, color, 1);
1385 }
1386};
1387
1388template<>
1389struct dialog_tester<generator_settings>
1390{
1391 config cfg;
1393 dialog_tester() : data(cfg) {}
1394 generator_settings* create()
1395 {
1396 return new generator_settings(data);
1397 }
1398};
1399
1400template<>
1401struct dialog_tester<sp_options_configure>
1402{
1403 saved_game state;
1404 ng::create_engine create_eng;
1405 dialog_tester() : create_eng(state) {}
1406 sp_options_configure* create()
1407 {
1408 return new sp_options_configure(create_eng);
1409 }
1410};
1411
1412template<>
1413struct dialog_tester<statistics_dialog>
1414{
1415 team t;
1417 statistics_t stats;
1418 dialog_tester() : t() , stats_record(), stats(stats_record) {}
1419 statistics_dialog* create()
1420 {
1421 return new statistics_dialog(stats, t);
1422 }
1423};
1424
1425template<>
1426struct dialog_tester<surrender_quit>
1427{
1428 dialog_tester() {}
1429 surrender_quit* create()
1430 {
1431 return new surrender_quit();
1432 }
1433};
1434
1435template<>
1436struct dialog_tester<tod_new_schedule>
1437{
1438 std::string id = "id";
1439 t_string name = "name";
1440 dialog_tester() {}
1441 tod_new_schedule* create()
1442 {
1443 return new tod_new_schedule(id, name);
1444 }
1445};
1446
1447template<>
1448struct dialog_tester<editor_edit_unit>
1449{
1450 config cfg;
1451 game_config_view view;
1452
1453 dialog_tester() {}
1454 editor_edit_unit* create()
1455 {
1456 config& units = cfg.add_child("units");
1457 cfg.add_child("race");
1458 config& movetype = units.add_child("movetype");
1459 movetype["name"] = "Test Movetype";
1460 movetype.add_child("defense");
1461 movetype.add_child("resistance");
1462 movetype.add_child("movement_costs");
1464 return new editor_edit_unit(view, "test_addon");
1465 }
1466};
1467
1468template<>
1469struct dialog_tester<gui_test_dialog>
1470{
1471 dialog_tester() {}
1472 gui_test_dialog* create()
1473 {
1474 return new gui_test_dialog();
1475 }
1476};
1477
1478} // namespace
double t
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:157
config & add_child(std::string_view key)
Definition config.cpp:436
config & mandatory_child(std::string_view key, int n=0)
Returns the nth child with the given key, or throws an error if there is none.
Definition config.cpp:362
virtual void add_chat_message(const std::chrono::system_clock::time_point &time, const std::string &speaker, int side, const std::string &message, MESSAGE_TYPE type=MESSAGE_PRIVATE)=0
virtual void clear_messages()=0
virtual void send_chat_message(const std::string &message, bool allies_only=false)=0
virtual void send_to_server(const config &cfg)=0
Singleton class to manage game config file caching.
static config_cache & instance()
Get reference to the singleton object.
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 dialog with two portraits, one on each side.
Shows a dialog with the portrait on the left side.
Shows a dialog with the portrait on the right side.
base class of top level items, the only item which needs to store the final canvases to draw on.
Definition window.hpp:59
void draw()
Draws the window.
Definition window.cpp:593
The basic "size" of the unit - flying, small land, large land, etc.
Definition movetype.hpp:44
This class represents the collective information the client has about the players and games on the se...
FLG stands for faction, leader and gender.
static std::shared_ptr< save_index_class > default_saves_dir()
Returns an instance for managing saves in filesystem::get_saves_dir()
This class stores all the data for a single 'side' (in game nomenclature).
Definition team.hpp:74
A variable-expanding proxy for the config class.
Definition variable.hpp:45
A class that represents a TCP/IP connection to the wesnothd server.
Networked add-ons (campaignd) client interface.
Formula AI debugger.
const config * cfg
Declarations for File-IO.
std::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:28
bool load_language_list()
Definition language.cpp:138
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)
Various uncategorised dialogs.
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=std::ios_base::binary)
Throws io_exception if an error occurs.
Game configuration data as global variables.
std::string path
void load_config(const config &v)
void remove()
Removes a tip.
Definition tooltip.cpp:94
void show(const std::string &window_id, const t_string &message, const point &mouse, const rect &source_rect)
Shows a tip.
Definition tooltip.cpp:64
std::string get_modal_dialog_id(const modal_dialog &dialog)
std::string get_modeless_dialog_id(const modeless_dialog &dialog)
Generic file dialog.
std::set< std::string > & registered_window_types()
Returns the list of registered windows.
bool new_widgets
Do we wish to use the new library or not.
Definition settings.cpp:23
logger & info()
Definition log.cpp:351
void set_test_resolution(const int width, const int height)
Sets the dummy display resolution for use by the tests.
std::string get_unknown_exception_type()
Utility function for finding the type of thing caught with catch(...).
Definition general.cpp:23
std::vector< std::string > split(const config_attribute_value &val)
std::string_view data
Definition picture.cpp:188
Replay control code.
This file contains the settings handling of the widget library.
std::unordered_map< std::string, cache_item > cache
Definition sound.cpp:146
std::string filename
Filename.
The basic class for representing 8-bit RGB or RGBA colour values.
Definition color.hpp:51
The paths manager is responsible for recording the various paths that binary files may be located at.
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.
Holds a 2D point.
Definition point.hpp:25
static config main_config
std::unique_ptr< game_config_manager > config_manager
std::vector< std::string > dummy_args
static const std::string widgets_file
t_string name
Definition theme.hpp:38
t_string description
Definition theme.hpp:39
std::string id
Definition theme.hpp:37
Helper class, don't construct this directly.
BOOST_AUTO_TEST_CASE(modal_dialog_test_addon_auth)
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 i
#define e
#define c
#define b