00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #define GETTEXT_DOMAIN "wesnoth-lib"
00018
00019 #include <boost/test/unit_test.hpp>
00020
00021 #include "config_cache.hpp"
00022 #include "filesystem.hpp"
00023 #include "foreach.hpp"
00024 #include "formula_debugger.hpp"
00025 #include "gettext.hpp"
00026 #include "game_config.hpp"
00027 #include "game_display.hpp"
00028 #include "gui/auxiliary/layout_exception.hpp"
00029 #include "gui/dialogs/addon_connect.hpp"
00030 #include "gui/dialogs/addon_list.hpp"
00031 #include "gui/dialogs/campaign_difficulty.hpp"
00032 #include "gui/dialogs/campaign_selection.hpp"
00033 #include "gui/dialogs/chat_log.hpp"
00034 #include "gui/dialogs/data_manage.hpp"
00035 #include "gui/dialogs/debug_clock.hpp"
00036 #include "gui/dialogs/edit_label.hpp"
00037 #include "gui/dialogs/editor_generate_map.hpp"
00038 #include "gui/dialogs/editor_new_map.hpp"
00039 #include "gui/dialogs/editor_resize_map.hpp"
00040 #include "gui/dialogs/editor_set_starting_position.hpp"
00041 #include "gui/dialogs/editor_settings.hpp"
00042 #include "gui/dialogs/folder_create.hpp"
00043 #include "gui/dialogs/formula_debugger.hpp"
00044 #include "gui/dialogs/game_delete.hpp"
00045 #include "gui/dialogs/game_load.hpp"
00046 #include "gui/dialogs/game_save.hpp"
00047 #include "gui/dialogs/gamestate_inspector.hpp"
00048 #include "gui/dialogs/language_selection.hpp"
00049 #include "gui/dialogs/message.hpp"
00050 #include "gui/dialogs/mp_change_control.hpp"
00051 #include "gui/dialogs/mp_cmd_wrapper.hpp"
00052 #include "gui/dialogs/mp_connect.hpp"
00053 #include "gui/dialogs/mp_create_game.hpp"
00054 #include "gui/dialogs/mp_login.hpp"
00055 #include "gui/dialogs/mp_method_selection.hpp"
00056 #include "gui/dialogs/simple_item_selector.hpp"
00057 #include "gui/dialogs/title_screen.hpp"
00058 #include "gui/dialogs/tip.hpp"
00059 #include "gui/dialogs/transient_message.hpp"
00060 #include "gui/dialogs/unit_attack.hpp"
00061 #include "gui/dialogs/unit_create.hpp"
00062 #include "gui/dialogs/wml_message.hpp"
00063 #include "gui/widgets/settings.hpp"
00064 #include "gui/widgets/window.hpp"
00065 #include "language.hpp"
00066 #include "map_create.hpp"
00067 #include "tests/utils/fake_display.hpp"
00068 #include "video.hpp"
00069 #include "wml_exception.hpp"
00070
00071 #include <boost/bind.hpp>
00072
00073 #include <memory>
00074
00075 namespace gui2 {
00076
00077 std::vector<std::string>& unit_test_registered_window_list()
00078 {
00079 static std::vector<std::string> result =
00080 tunit_test_access_only::get_registered_window_list();
00081
00082 return result;
00083 }
00084
00085 std::string unit_test_mark_as_tested(const tdialog& dialog)
00086 {
00087 std::vector<std::string>& list = unit_test_registered_window_list();
00088 list.erase(
00089 std::remove(list.begin(), list.end(), dialog.window_id())
00090 , list.end());
00091 return dialog.window_id();
00092 }
00093
00094 std::string unit_test_mark_popup_as_tested(const tpopup& dialog)
00095 {
00096 std::vector<std::string>& list = unit_test_registered_window_list();
00097 list.erase(
00098 std::remove(list.begin(), list.end(), dialog.window_id())
00099 , list.end());
00100 return dialog.window_id();
00101 }
00102
00103 twindow* unit_test_window(const tpopup& dialog)
00104 {
00105 return dialog.window_;
00106 }
00107
00108 class tmp_server_list;
00109
00110 tdialog* unit_test_mp_server_list()
00111 {
00112 return tmp_connect::mp_server_list_for_unit_test();
00113 }
00114
00115 }
00116
00117 namespace {
00118
00119
00120 config main_config;
00121
00122
00123
00124
00125
00126
00127
00128 template<class T>
00129 struct twrapper
00130 {
00131 static T* create() { return new T(); }
00132 };
00133
00134 typedef std::pair<unsigned, unsigned> tresolution;
00135 typedef std::vector<std::pair<unsigned, unsigned> > tresolution_list;
00136
00137 CVideo & video() {
00138 static CVideo * v_ = new CVideo(CVideo::FAKE_TEST);
00139 return *v_;
00140 }
00141
00142 template<class T>
00143 void test_resolutions(const tresolution_list& resolutions)
00144 {
00145 foreach(const tresolution& resolution, resolutions) {
00146 video().make_test_fake(resolution.first, resolution.second);
00147
00148 boost::scoped_ptr<gui2::tdialog> dlg(twrapper<T>::create());
00149 BOOST_REQUIRE_MESSAGE(dlg.get(), "Failed to create a dialog.");
00150
00151 const std::string id = gui2::unit_test_mark_as_tested(*(dlg.get()));
00152
00153 std::string exception;
00154 try {
00155 dlg->show(video(), 1);
00156 } catch(gui2::tlayout_exception_width_modified&) {
00157 exception = "gui2::tlayout_exception_width_modified";
00158 } catch(gui2::tlayout_exception_width_resize_failed&) {
00159 exception = "gui2::tlayout_exception_width_resize_failed";
00160 } catch(gui2::tlayout_exception_height_resize_failed&) {
00161 exception = "gui2::tlayout_exception_height_resize_failed";
00162 } catch(twml_exception& e) {
00163 exception = e.dev_message;
00164 } catch(std::exception& e) {
00165 exception = e.what();
00166 } catch(...) {
00167 exception = "unknown";
00168 }
00169 BOOST_CHECK_MESSAGE(exception.empty(),
00170 "Test for '" << id
00171 << "' Failed\nnew widgets = " << gui2::new_widgets
00172 << " small gui = " << game_config::small_gui
00173 << " resolution = " << resolution.first
00174 << 'x' << resolution.second
00175 << "\nException caught: " << exception << '.');
00176 }
00177 }
00178
00179 template<class T>
00180 void test_popup_resolutions(const tresolution_list& resolutions)
00181 {
00182 bool interact = false;
00183 for(int i = 0; i < 2; ++i) {
00184 foreach(const tresolution& resolution, resolutions) {
00185 video().make_test_fake(resolution.first, resolution.second);
00186
00187 boost::scoped_ptr<gui2::tpopup> dlg(twrapper<T>::create());
00188 BOOST_REQUIRE_MESSAGE(dlg.get(), "Failed to create a dialog.");
00189
00190 const std::string id = gui2::unit_test_mark_popup_as_tested(*(dlg.get()));
00191
00192 std::string exception;
00193 try {
00194 dlg->show(video(), interact);
00195 gui2::twindow* window = gui2::unit_test_window((*dlg.get()));
00196 BOOST_REQUIRE_NE(window, static_cast<void*>(NULL));
00197 window->draw();
00198 } catch(gui2::tlayout_exception_width_modified&) {
00199 exception = "gui2::tlayout_exception_width_modified";
00200 } catch(gui2::tlayout_exception_width_resize_failed&) {
00201 exception = "gui2::tlayout_exception_width_resize_failed";
00202 } catch(gui2::tlayout_exception_height_resize_failed&) {
00203 exception = "gui2::tlayout_exception_height_resize_failed";
00204 } catch(twml_exception& e) {
00205 exception = e.dev_message;
00206 } catch(std::exception& e) {
00207 exception = e.what();
00208 } catch(...) {
00209 exception = "unknown";
00210 }
00211 BOOST_CHECK_MESSAGE(exception.empty(),
00212 "Test for '" << id
00213 << "' Failed\nnew widgets = " << gui2::new_widgets
00214 << " small gui = " << game_config::small_gui
00215 << " resolution = " << resolution.first
00216 << 'x' << resolution.second
00217 << "\nException caught: " << exception << '.');
00218 }
00219
00220 interact = true;
00221 }
00222 }
00223
00224 #ifdef _MSC_VER
00225 #pragma warning(push)
00226 #pragma warning(disable: 4702)
00227 #endif
00228 void test_tip_resolutions(const tresolution_list& resolutions
00229 , const std::string& id)
00230 {
00231 foreach(const tresolution& resolution, resolutions) {
00232 video().make_test_fake(resolution.first, resolution.second);
00233
00234 std::vector<std::string>& list =
00235 gui2::unit_test_registered_window_list();
00236 list.erase(std::remove(list.begin(), list.end(), id), list.end());
00237
00238 std::string exception;
00239 try {
00240
00241
00242
00243
00244
00245
00246
00247 #if 0
00248 gui2::tip::show(video()
00249 , id
00250 , "Test messsage for a tooltip."
00251 , gui2::tpoint(0, 0));
00252 #endif
00253 } catch(gui2::tlayout_exception_width_modified&) {
00254 exception = "gui2::tlayout_exception_width_modified";
00255 } catch(gui2::tlayout_exception_width_resize_failed&) {
00256 exception = "gui2::tlayout_exception_width_resize_failed";
00257 } catch(gui2::tlayout_exception_height_resize_failed&) {
00258 exception = "gui2::tlayout_exception_height_resize_failed";
00259 } catch(twml_exception& e) {
00260 exception = e.dev_message;
00261 } catch(std::exception& e) {
00262 exception = e.what();
00263 } catch(...) {
00264 exception = "unknown";
00265 }
00266 BOOST_CHECK_MESSAGE(exception.empty(),
00267 "Test for tip '" << id
00268 << "' Failed\nnew widgets = " << gui2::new_widgets
00269 << " small gui = " << game_config::small_gui
00270 << " resolution = " << resolution.first
00271 << 'x' << resolution.second
00272 << "\nException caught: " << exception << '.');
00273 }
00274 }
00275 #ifdef _MSC_VER
00276 #pragma warning(pop)
00277 #endif
00278
00279 const tresolution_list& get_small_gui_resolutions()
00280 {
00281 static tresolution_list result;
00282 if(result.empty()) {
00283 result.push_back(std::make_pair(800, 480));
00284 }
00285 return result;
00286 }
00287
00288 const tresolution_list& get_gui_resolutions()
00289 {
00290 static tresolution_list result;
00291 if(result.empty()) {
00292 result.push_back(std::make_pair(800, 600));
00293 result.push_back(std::make_pair(1024, 768));
00294 result.push_back(std::make_pair(1280, 1024));
00295 result.push_back(std::make_pair(1680, 1050));
00296 }
00297 return result;
00298 }
00299
00300 template<class T>
00301 void test()
00302 {
00303 gui2::new_widgets = false;
00304
00305 for(size_t i = 0; i < 2; ++i) {
00306
00307 game_config::small_gui = true;
00308 test_resolutions<T>(get_small_gui_resolutions());
00309
00310 game_config::small_gui = false;
00311 test_resolutions<T>(get_gui_resolutions());
00312
00313 gui2::new_widgets = true;
00314 }
00315 }
00316
00317 template<class T>
00318 void test_popup()
00319 {
00320 gui2::new_widgets = false;
00321
00322 for(size_t i = 0; i < 2; ++i) {
00323
00324 game_config::small_gui = true;
00325 test_popup_resolutions<T>(get_small_gui_resolutions());
00326
00327 game_config::small_gui = false;
00328 test_popup_resolutions<T>(get_gui_resolutions());
00329
00330 gui2::new_widgets = true;
00331 }
00332 }
00333
00334 void test_tip(const std::string& id)
00335 {
00336 gui2::new_widgets = false;
00337
00338 for(size_t i = 0; i < 2; ++i) {
00339
00340 game_config::small_gui = true;
00341 test_tip_resolutions(get_small_gui_resolutions(), id);
00342
00343 game_config::small_gui = false;
00344 test_tip_resolutions(get_gui_resolutions(), id);
00345
00346 gui2::new_widgets = true;
00347 }
00348 }
00349
00350 }
00351
00352 BOOST_AUTO_TEST_CASE(test_gui2)
00353 {
00354
00355 game_config::config_cache& cache = game_config::config_cache::instance();
00356
00357 cache.clear_defines();
00358 cache.add_define("EDITOR");
00359 cache.add_define("MULTIPLAYER");
00360 cache.get_config(game_config::path +"/data", main_config);
00361
00362 const binary_paths_manager bin_paths_manager(main_config);
00363
00364 load_language_list();
00365 game_config::load_config(main_config.child("game_config"));
00366
00367
00368
00369
00370 test<gui2::taddon_connect>();
00371 test<gui2::taddon_list>();
00372 test<gui2::tcampaign_difficulty>();
00373 test<gui2::tcampaign_selection>();
00374
00375 test<gui2::tdata_manage>();
00376 test<gui2::tedit_label>();
00377 test<gui2::teditor_generate_map>();
00378 test<gui2::teditor_new_map>();
00379 test<gui2::teditor_resize_map>();
00380 test<gui2::teditor_set_starting_position>();
00381 test<gui2::teditor_settings>();
00382 test<gui2::tfolder_create>();
00383 test<gui2::tformula_debugger>();
00384 test<gui2::tgame_delete>();
00385 test<gui2::tgame_load>();
00386 test<gui2::tgame_save>();
00387 test<gui2::tgame_save_message>();
00388 test<gui2::tgame_save_oos>();
00389 test<gui2::tgamestate_inspector>();
00390 test<gui2::tlanguage_selection>();
00391 test<gui2::tmessage>();
00392 test<gui2::tsimple_item_selector>();
00393 test<gui2::tmp_change_control>();
00394 test<gui2::tmp_cmd_wrapper>();
00395 test<gui2::tmp_connect>();
00396 test<gui2::tmp_create_game>();
00397 test<gui2::tmp_login>();
00398 test<gui2::tmp_method_selection>();
00399 test<gui2::tmp_server_list>();
00400 test<gui2::ttitle_screen>();
00401 test<gui2::ttransient_message>();
00402
00403 test<gui2::tunit_create>();
00404 test<gui2::twml_message_left>();
00405 test<gui2::twml_message_right>();
00406
00407
00408 test_popup<gui2::tdebug_clock>();
00409
00410
00411 test_tip("tooltip_large");
00412
00413 std::vector<std::string>& list = gui2::unit_test_registered_window_list();
00414
00415
00416
00417
00418
00419 list.erase(
00420 std::remove(list.begin(), list.end(), "unit_attack")
00421 , list.end());
00422
00423
00424
00425
00426 list.erase(
00427 std::remove(list.begin(), list.end(), "chat_log")
00428 , list.end());
00429
00430
00431 BOOST_CHECK_EQUAL(list.size(), 0);
00432 foreach(const std::string& id, list) {
00433 std::cerr << "Window '" << id << "' registered but not tested.\n";
00434 }
00435 }
00436
00437 BOOST_AUTO_TEST_CASE(test_make_test_fake)
00438 {
00439 video().make_test_fake(10, 10);
00440
00441 try {
00442 gui2::tmessage dlg("title", "message", true);
00443 dlg.show(video(), 1);
00444 } catch(twml_exception& e) {
00445 BOOST_CHECK(e.user_message == _("Failed to show a dialog, "
00446 "which doesn't fit on the screen."));
00447 return;
00448 } catch(...) {
00449 }
00450 BOOST_ERROR("Didn't catch the wanted exception.");
00451 }
00452
00453 namespace {
00454
00455 template<>
00456 struct twrapper<gui2::taddon_connect>
00457 {
00458 static gui2::taddon_connect* create()
00459 {
00460 static std::string host_name = "host_name";
00461 return new gui2::taddon_connect(host_name, true, true);
00462 }
00463 };
00464
00465 template<>
00466 struct twrapper<gui2::taddon_list>
00467 {
00468 static gui2::taddon_list* create()
00469 {
00470
00471 static config cfg;
00472 return new gui2::taddon_list(cfg);
00473 }
00474 };
00475
00476 template<>
00477 struct twrapper<gui2::tcampaign_difficulty>
00478 {
00479 static gui2::tcampaign_difficulty* create()
00480 {
00481 static std::vector<std::string> items;
00482
00483 return new gui2::tcampaign_difficulty(items);
00484 }
00485 };
00486
00487 template<>
00488 struct twrapper<gui2::tcampaign_selection>
00489 {
00490 static gui2::tcampaign_selection* create()
00491 {
00492 const config::const_child_itors &ci =
00493 main_config.child_range("campaign");
00494 static std::vector<config> campaigns(ci.first, ci.second);
00495
00496 return new gui2::tcampaign_selection(campaigns);
00497 }
00498 };
00499
00500 template<>
00501 struct twrapper<gui2::tchat_log>
00502 {
00503 static gui2::tchat_log* create()
00504 {
00505 static config cfg;
00506 static vconfig vcfg(cfg);
00507
00508 return new gui2::tchat_log(vcfg, NULL);
00509 }
00510 };
00511
00512 template<>
00513 struct twrapper<gui2::tdata_manage>
00514 {
00515 static gui2::tdata_manage* create()
00516 {
00517
00518 return new gui2::tdata_manage(config());
00519 }
00520 };
00521
00522 template<>
00523 struct twrapper<gui2::tedit_label>
00524 {
00525 static gui2::tedit_label* create()
00526 {
00527 static std::string label = "Label text to modify";
00528 static bool team_only = false;
00529 return new gui2::tedit_label(label, team_only);
00530 }
00531 };
00532
00533 template<>
00534 struct twrapper<gui2::tformula_debugger>
00535 {
00536 static gui2::tformula_debugger* create()
00537 {
00538 static game_logic::formula_debugger debugger;
00539 return new gui2::tformula_debugger(debugger);
00540 }
00541 };
00542
00543 template<>
00544 struct twrapper<gui2::tgame_load>
00545 {
00546 static gui2::tgame_load* create()
00547 {
00548
00549 static config cfg;
00550 return new gui2::tgame_load(cfg);
00551 }
00552
00553 };
00554
00555 template<>
00556 struct twrapper<gui2::tgame_save>
00557 {
00558 static gui2::tgame_save* create()
00559 {
00560 static std::string title = "Title";
00561 static std::string filename = "filename";
00562 return new gui2::tgame_save(title, filename);
00563 }
00564
00565 };
00566
00567 template<>
00568 struct twrapper<gui2::tgame_save_message>
00569 {
00570 static gui2::tgame_save_message* create()
00571 {
00572 static std::string title = "Title";
00573 static std::string filename = "filename";
00574 static std::string message = "message";
00575 return new gui2::tgame_save_message(title, filename, message);
00576 }
00577
00578 };
00579
00580 template<>
00581 struct twrapper<gui2::tgame_save_oos>
00582 {
00583 static gui2::tgame_save_oos* create()
00584 {
00585 static bool ignore_all = false;
00586 static std::string title = "Title";
00587 static std::string filename = "filename";
00588 static std::string message = "message";
00589 return new gui2::tgame_save_oos(ignore_all, title, filename, message);
00590 }
00591
00592 };
00593
00594 template<>
00595 struct twrapper<gui2::tgamestate_inspector>
00596 {
00597 static gui2::tgamestate_inspector* create()
00598 {
00599
00600
00601
00602
00603 static config cfg;
00604 static vconfig vcfg(cfg);
00605 return new gui2::tgamestate_inspector(vcfg);
00606 }
00607
00608 };
00609
00610 template<>
00611 struct twrapper<gui2::tmessage>
00612 {
00613 static gui2::tmessage* create()
00614 {
00615 return new gui2::tmessage("Title", "Message", false);
00616 }
00617 };
00618
00619 template<>
00620 struct twrapper<gui2::tmp_change_control>
00621 {
00622 static gui2::tmp_change_control* create()
00623 {
00624 return new gui2::tmp_change_control(NULL);
00625 }
00626 };
00627
00628 template<>
00629 struct twrapper<gui2::tmp_cmd_wrapper>
00630 {
00631 static gui2::tmp_cmd_wrapper* create()
00632 {
00633 return new gui2::tmp_cmd_wrapper("foo");
00634 }
00635 };
00636
00637 template<>
00638 struct twrapper<gui2::tmp_create_game>
00639 {
00640 static gui2::tmp_create_game* create()
00641 {
00642 return new gui2::tmp_create_game(main_config);
00643 }
00644 };
00645
00646 template<>
00647 struct twrapper<gui2::tmp_login>
00648 {
00649 static gui2::tmp_login* create()
00650 {
00651 return new gui2::tmp_login("label", true);
00652 }
00653 };
00654
00655 template<>
00656 struct twrapper<gui2::tsimple_item_selector>
00657 {
00658 static gui2::tsimple_item_selector* create()
00659 {
00660 return new gui2::tsimple_item_selector("title"
00661 , "message"
00662 , std::vector<std::string>()
00663 , false
00664 , false);
00665 }
00666 };
00667
00668 template<>
00669 struct twrapper<gui2::teditor_generate_map>
00670 {
00671 static gui2::teditor_generate_map* create()
00672 {
00673 gui2::teditor_generate_map* result = new gui2::teditor_generate_map();
00674 BOOST_REQUIRE_MESSAGE(result, "Failed to create a dialog.");
00675
00676 std::vector<map_generator*> map_generators;
00677 foreach (const config &i, main_config.child_range("multiplayer")) {
00678 if(i["map_generation"] == "default") {
00679 const config &generator_cfg = i.child("generator");
00680 if (generator_cfg) {
00681 map_generators.push_back(
00682 create_map_generator("", generator_cfg));
00683 }
00684 }
00685 }
00686 result->set_map_generators(map_generators);
00687
00688 result->set_gui(
00689 static_cast<display*>(&test_utils::get_fake_display(-1, -1)));
00690
00691 return result;
00692 }
00693 };
00694
00695 template<>
00696 struct twrapper<gui2::teditor_new_map>
00697 {
00698 static gui2::teditor_new_map* create()
00699 {
00700 static int width;
00701 static int height;
00702 return new gui2::teditor_new_map(width, height);
00703 }
00704 };
00705
00706 template<>
00707 struct twrapper<gui2::teditor_set_starting_position>
00708 {
00709 static gui2::teditor_set_starting_position* create()
00710 {
00711 static std::vector<map_location> locations;
00712
00713 return new gui2::teditor_set_starting_position(0, 0, locations);
00714 }
00715 };
00716
00717 template<>
00718 struct twrapper<gui2::teditor_resize_map>
00719 {
00720 static gui2::teditor_resize_map* create()
00721 {
00722 static int width = 0;
00723 static int height = 0;
00724 static gui2::teditor_resize_map::EXPAND_DIRECTION expand_direction =
00725 gui2::teditor_resize_map::EXPAND_TOP;
00726 static bool copy = false;
00727 return new gui2::teditor_resize_map(
00728 width
00729 , height
00730 , expand_direction
00731 , copy);
00732 }
00733 };
00734
00735 template<>
00736 struct twrapper<gui2::teditor_settings>
00737 {
00738 static gui2::teditor_settings* create()
00739 {
00740 const config &cfg = main_config.child("editor_times");
00741 BOOST_REQUIRE_MESSAGE(cfg, "No editor time-of-day defined");
00742
00743 std::vector<time_of_day> tods;
00744 foreach (const config &i, cfg.child_range("time")) {
00745 tods.push_back(time_of_day(i));
00746 }
00747 return new gui2::teditor_settings(NULL, tods);
00748 }
00749 };
00750
00751 template<>
00752 struct twrapper<gui2::tfolder_create>
00753 {
00754 static gui2::tfolder_create* create()
00755 {
00756 static std::string folder_name;
00757 return new gui2::tfolder_create(folder_name);
00758 }
00759 };
00760
00761 template<>
00762 struct twrapper<gui2::tmp_server_list>
00763 {
00764 static gui2::tdialog* create()
00765 {
00766 return gui2::unit_test_mp_server_list();
00767 }
00768 };
00769
00770 template<>
00771 struct twrapper<gui2::ttransient_message>
00772 {
00773 static gui2::ttransient_message* create()
00774 {
00775 return new gui2::ttransient_message("Title", false, "Message", false, "");
00776 }
00777 };
00778
00779 template<>
00780 struct twrapper<gui2::twml_message_left>
00781 {
00782 static gui2::twml_message_left* create()
00783 {
00784 return new gui2::twml_message_left("Title", "Message", "", false);
00785 }
00786 };
00787
00788 template<>
00789 struct twrapper<gui2::twml_message_right>
00790 {
00791 static gui2::twml_message_right* create()
00792 {
00793 return new gui2::twml_message_right("Title", "Message", "", false);
00794 }
00795 };
00796
00797 }
00798