Made endlevel test to use fake screen object
moved fake_event_source class to test tests/utils/
This commit is contained in:
parent
c4046c3466
commit
21b0f0bc47
8 changed files with 324 additions and 140 deletions
|
@ -318,13 +318,19 @@ exploder_sources = Split("""
|
|||
env.WesnothProgram("exploder", exploder_sources + [libcutter, libwesnoth_core, libwesnoth_sdl, libwesnothd, libwesnoth], have_client_prereqs,
|
||||
LIBS = env["LIBS"] + ["png"])
|
||||
|
||||
test_utils_sources = Split("""
|
||||
tests/utils/fake_event_source.cpp
|
||||
""")
|
||||
|
||||
libtest_utils = env.Library("test_utils", test_utils_sources)
|
||||
|
||||
test_sources = Split("""
|
||||
tests/main.cpp
|
||||
tests/test_util.cpp
|
||||
tests/test_network_worker.cpp
|
||||
tests/test_endlevel.cpp
|
||||
""")
|
||||
test = test_env.WesnothProgram("test", test_sources + [libwesnoth_extras, libwesnoth_core, libwesnoth_sdl, libwesnoth], have_test_prereqs)
|
||||
test = test_env.WesnothProgram("test", test_sources + [libwesnoth_extras, libwesnoth_core, libwesnoth_sdl, libwesnoth,libtest_utils], have_test_prereqs)
|
||||
#Export("test")
|
||||
|
||||
if env["svnrev"] != "" and env["svnrev"] != "exported":
|
||||
|
|
|
@ -165,6 +165,7 @@ handler::handler(const bool auto_join) : unicode_(SDL_EnableUNICODE(1)), has_joi
|
|||
{
|
||||
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY,SDL_DEFAULT_REPEAT_INTERVAL);
|
||||
if(auto_join) {
|
||||
assert(!event_contexts.empty());
|
||||
event_contexts.back().add_handler(this);
|
||||
has_joined_ = true;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/unit_test_monitor.hpp>
|
||||
#include <boost/test/detail/unit_test_parameters.hpp>
|
||||
#include "SDL.h"
|
||||
|
||||
#include "game_errors.hpp"
|
||||
#include "network.hpp"
|
||||
|
@ -42,6 +43,7 @@ void exception_translator_game(const game::error& e)
|
|||
struct wesnoth_global_fixture {
|
||||
wesnoth_global_fixture()
|
||||
{
|
||||
SDL_Init(SDL_INIT_TIMER);
|
||||
if (boost::unit_test::runtime_config::log_level() < boost::unit_test::log_messages)
|
||||
boost::unit_test::unit_test_log.set_threshold_level( boost::unit_test::log_messages );
|
||||
BOOST_MESSAGE("Initializing test!");
|
||||
|
|
|
@ -14,14 +14,13 @@
|
|||
|
||||
#include <boost/test/auto_unit_test.hpp>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <queue>
|
||||
#include "SDL.h"
|
||||
|
||||
#include "key.hpp"
|
||||
#include "events.hpp"
|
||||
//#include "dialogs.hpp"
|
||||
#include "unit_types.hpp"
|
||||
#include "dialogs.hpp"
|
||||
#include "gamestatus.hpp"
|
||||
//
|
||||
|
||||
#include "tests/utils/fake_event_source.hpp"
|
||||
|
||||
|
||||
// Linker workarounds start here
|
||||
|
@ -43,142 +42,28 @@ WML_HANDLER_FUNCTION(test_sources, , , )
|
|||
// To load libwesnoth_sdl
|
||||
SDL_Color color = int_to_color(255);
|
||||
std::cerr << "Fooled you\n";
|
||||
{
|
||||
config cfg;
|
||||
scoped_istream stream = preprocess_file("data/hardwired/language.cfg");
|
||||
read(cfg, *stream);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// Linker workarounds end here
|
||||
|
||||
/**
|
||||
* fake_sdl_event_source is used to generate new events in
|
||||
* events::pump()
|
||||
**/
|
||||
namespace test {
|
||||
|
||||
// bool event_fired = false;
|
||||
|
||||
template<class T>
|
||||
struct test_less_ptr {
|
||||
bool operator()(const T& a, const T& b) const
|
||||
{
|
||||
return (*a) < (*b);
|
||||
}
|
||||
};
|
||||
|
||||
class fake_sdl_event_source
|
||||
: public events::pump_monitor,
|
||||
public boost::noncopyable
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Base class for all event nodes to be used to fire fake input events
|
||||
**/
|
||||
class event_node :
|
||||
public boost::noncopyable
|
||||
{
|
||||
size_t time_;
|
||||
bool fired_;
|
||||
protected:
|
||||
SDL_Event event_;
|
||||
|
||||
public:
|
||||
event_node(const size_t time, const SDL_Event& event) : time_(time), fired_(false), event_(event)
|
||||
{}
|
||||
virtual ~event_node()
|
||||
{ }
|
||||
|
||||
virtual void fire_event()
|
||||
{
|
||||
const int number_of_events = 1;
|
||||
const Uint32 mask = 0;
|
||||
SDL_PeepEvents(&event_, number_of_events, SDL_ADDEVENT, mask);
|
||||
fired_ = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this should stop firing events
|
||||
**/
|
||||
bool test_if_should_fire(const size_t time_now) const
|
||||
{
|
||||
return time_ <= time_now;
|
||||
}
|
||||
|
||||
bool is_fired() const
|
||||
{
|
||||
return fired_;
|
||||
}
|
||||
|
||||
/**
|
||||
* We want the smallestat the top
|
||||
**/
|
||||
bool operator<(const event_node& o) const
|
||||
{ return time_ > o.time_; }
|
||||
};
|
||||
|
||||
class event_node_keyboard : public event_node {
|
||||
public:
|
||||
event_node_keyboard(size_t time, SDL_Event& event) : event_node(time,event)
|
||||
{}
|
||||
void fire_event()
|
||||
{
|
||||
event_node::fire_event();
|
||||
static int num_keys = 300;
|
||||
Uint8* key_list = SDL_GetKeyState( &num_keys );
|
||||
if (event_.type == SDL_KEYDOWN)
|
||||
key_list[SDLK_ESCAPE] = 5;
|
||||
else
|
||||
key_list[SDLK_ESCAPE] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<event_node> event_node_ptr;
|
||||
|
||||
private:
|
||||
typedef std::priority_queue<event_node_ptr,std::vector<event_node_ptr>,test_less_ptr<event_node_ptr> > event_queue;
|
||||
|
||||
event_queue queue_;
|
||||
|
||||
public:
|
||||
void add_event(const size_t time, const SDL_Event& event)
|
||||
{
|
||||
event_node_ptr new_node(new event_node(time,event));
|
||||
queue_.push(new_node);
|
||||
}
|
||||
|
||||
void add_event(event_node_ptr new_node)
|
||||
{
|
||||
queue_.push(new_node);
|
||||
}
|
||||
|
||||
void process(events::pump_info& /*info*/);
|
||||
struct endlevel_fixture {
|
||||
test_utils::fake_event_source source;
|
||||
SDL_Event event;
|
||||
};
|
||||
|
||||
void fake_sdl_event_source::process(events::pump_info& /*info*/)
|
||||
{
|
||||
if (queue_.empty())
|
||||
return;
|
||||
size_t now = SDL_GetTicks();
|
||||
if (queue_.top()->test_if_should_fire(now))
|
||||
{
|
||||
queue_.top()->fire_event();
|
||||
queue_.pop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_SUITE( endlevel )
|
||||
BOOST_FIXTURE_TEST_SUITE( endlevel , endlevel_fixture)
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_fake_input )
|
||||
{
|
||||
#ifdef LD_WA
|
||||
{
|
||||
config cfg;
|
||||
scoped_istream stream = preprocess_file("data/hardwired/language.cfg");
|
||||
read(cfg, *stream);
|
||||
}
|
||||
#endif
|
||||
|
||||
fake_sdl_event_source source;
|
||||
SDL_Event event;
|
||||
BOOST_MESSAGE("Starting endlevel test!");
|
||||
|
||||
event.type = SDL_KEYDOWN;
|
||||
event.key.state = SDL_PRESSED;
|
||||
|
@ -186,23 +71,20 @@ namespace test {
|
|||
event.key.keysym.scancode = 65;
|
||||
event.key.keysym.mod = KMOD_NONE;
|
||||
event.key.keysym.unicode = 0;
|
||||
const size_t now = SDL_GetTicks();
|
||||
|
||||
fake_sdl_event_source::event_node_ptr new_keypress(new fake_sdl_event_source::event_node_keyboard(now + 10, event));
|
||||
|
||||
test_utils::event_node_ptr new_keypress(new test_utils::event_node_keyboard(3, event));
|
||||
event.type = SDL_KEYUP;
|
||||
event.key.state = SDL_RELEASED;
|
||||
fake_sdl_event_source::event_node_ptr new_keyrelease(new fake_sdl_event_source::event_node_keyboard(now + 20, event));
|
||||
test_utils::event_node_ptr new_keyrelease(new test_utils::event_node_keyboard(5, event));
|
||||
source.add_event(new_keypress);
|
||||
source.add_event(new_keyrelease);
|
||||
|
||||
|
||||
BOOST_MESSAGE("Starting endlevel test!");
|
||||
|
||||
CKey key;
|
||||
// dialogs::get_save_name();
|
||||
while(true)
|
||||
{
|
||||
events::pump();
|
||||
|
||||
|
||||
BOOST_CHECK_EQUAL(key[SDLK_ESCAPE], new_keypress->is_fired());
|
||||
if (key[SDLK_ESCAPE])
|
||||
break;
|
||||
|
@ -216,5 +98,43 @@ namespace test {
|
|||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_dialog_get_save_name_enter_pressed )
|
||||
{
|
||||
// fill in events to be used in test
|
||||
test_utils::event_node_ptr press_return_before = source.press_key(0, SDLK_RETURN);
|
||||
test_utils::event_node_ptr release_return_before = source.release_key(3, SDLK_RETURN);
|
||||
test_utils::event_node_ptr press_return_after = source.press_key(6, SDLK_RETURN);
|
||||
test_utils::event_node_ptr release_return_after = source.release_key(9, SDLK_RETURN);
|
||||
|
||||
CVideo video_;
|
||||
video_.make_test_fake();
|
||||
unit_map dummy_umap;
|
||||
config dummy_cfg;
|
||||
gamemap dummy_map(dummy_cfg, "");
|
||||
gamestatus dummy_status(dummy_cfg, 0);
|
||||
std::vector<team> dummy_teams;
|
||||
const events::event_context main_event_context_;
|
||||
|
||||
game_display disp(dummy_umap, video_, dummy_map, dummy_status,
|
||||
dummy_teams, dummy_cfg, dummy_cfg, dummy_cfg);
|
||||
|
||||
std::string fname("press_enter");
|
||||
|
||||
// Start test (set ticks start time)
|
||||
source.start();
|
||||
// Activated enter press
|
||||
events::pump();
|
||||
|
||||
BOOST_CHECK_MESSAGE(press_return_before->is_fired(), "Enter wasn't activated");
|
||||
BOOST_CHECK_MESSAGE(!release_return_before->is_fired(), "Enter was released before test");
|
||||
|
||||
BOOST_CHECK_EQUAL(dialogs::get_save_name(disp, "Save game?", "file", &fname,gui::OK_CANCEL, "Save game", false, true), 0);
|
||||
|
||||
BOOST_CHECK_MESSAGE(release_return_before->is_fired(), "get_save_name returned before releasing first enter.");
|
||||
BOOST_CHECK_MESSAGE(press_return_after->is_fired(), "get_save_name returned before 2nd enter event was sent");
|
||||
BOOST_CHECK_MESSAGE(!release_return_after->is_fired(), "get_save_name returned after 2nd release event was sent");
|
||||
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
}
|
||||
|
|
144
src/tests/utils/fake_event_source.cpp
Normal file
144
src/tests/utils/fake_event_source.cpp
Normal file
|
@ -0,0 +1,144 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
Copyright (C) 2008 by Pauli Nieminen <paniemin@cc.hut.fi>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
or at your option any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include "tests/utils/fake_event_source.hpp"
|
||||
|
||||
namespace test_utils {
|
||||
/**
|
||||
* Base class for all event nodes to be used to fire fake input events
|
||||
**/
|
||||
event_node::event_node(const size_t time, const SDL_Event& event) : time_(time), fired_(false), event_(event)
|
||||
{}
|
||||
|
||||
event_node::~event_node()
|
||||
{ }
|
||||
|
||||
void event_node::fire_event()
|
||||
{
|
||||
const int number_of_events = 1;
|
||||
const Uint32 mask = 0;
|
||||
SDL_PeepEvents(&event_, number_of_events, SDL_ADDEVENT, mask);
|
||||
fired_ = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this should stop firing events
|
||||
**/
|
||||
bool event_node::test_if_should_fire(const size_t start_time, const size_t time_now) const
|
||||
{
|
||||
return time_now - start_time >= time_;
|
||||
}
|
||||
|
||||
bool event_node::is_fired() const
|
||||
{
|
||||
return fired_;
|
||||
}
|
||||
|
||||
/**
|
||||
* We want the smallestat the top
|
||||
**/
|
||||
bool event_node::operator<(const event_node& o) const
|
||||
{ return time_ > o.time_; }
|
||||
|
||||
event_node_keyboard::event_node_keyboard(size_t time, SDL_Event& event) : event_node(time,event)
|
||||
{}
|
||||
void event_node_keyboard::fire_event()
|
||||
{
|
||||
event_node::fire_event();
|
||||
static int num_keys = 300;
|
||||
Uint8* key_list = SDL_GetKeyState( &num_keys );
|
||||
if (event_.type == SDL_KEYDOWN)
|
||||
key_list[SDLK_ESCAPE] = 5;
|
||||
else
|
||||
key_list[SDLK_ESCAPE] = 0;
|
||||
}
|
||||
|
||||
fake_event_source::fake_event_source() : start_time_(SDL_GetTicks())
|
||||
{
|
||||
}
|
||||
|
||||
fake_event_source::~fake_event_source()
|
||||
{
|
||||
// send all still queued events
|
||||
// so keyboard/mouse state is restored
|
||||
while(!queue_.empty())
|
||||
{
|
||||
queue_.top()->fire_event();
|
||||
queue_.pop();
|
||||
}
|
||||
events::pump();
|
||||
}
|
||||
|
||||
|
||||
void fake_event_source::add_event(const size_t time, const SDL_Event& event)
|
||||
{
|
||||
event_node_ptr new_node(new event_node(time,event));
|
||||
queue_.push(new_node);
|
||||
}
|
||||
|
||||
void fake_event_source::add_event(event_node_ptr new_node)
|
||||
{
|
||||
queue_.push(new_node);
|
||||
}
|
||||
|
||||
void fake_event_source::start()
|
||||
{
|
||||
start_time_ = SDL_GetTicks();
|
||||
}
|
||||
|
||||
SDL_Event fake_event_source::make_key_event(Uint8 type, const SDLKey key, const SDLMod mod)
|
||||
{
|
||||
SDL_Event event;
|
||||
event.type = type;
|
||||
if (type == SDL_KEYDOWN)
|
||||
event.key.state = SDL_PRESSED;
|
||||
else
|
||||
event.key.state = SDL_RELEASED;
|
||||
event.key.keysym.sym = key;
|
||||
event.key.keysym.scancode = 65; // Always report 65 as scancode
|
||||
event.key.keysym.mod = mod;
|
||||
event.key.keysym.unicode = 0; // Unicode disabled
|
||||
return event;
|
||||
}
|
||||
|
||||
event_node_ptr fake_event_source::press_key(const size_t time, const SDLKey key, const SDLMod mod)
|
||||
{
|
||||
SDL_Event event = make_key_event(SDL_KEYDOWN, key, mod);
|
||||
event_node_ptr new_key(new event_node_keyboard(time, event));
|
||||
add_event(new_key);
|
||||
return new_key;
|
||||
}
|
||||
|
||||
event_node_ptr fake_event_source::release_key(const size_t time, const SDLKey key, const SDLMod mod)
|
||||
{
|
||||
SDL_Event event = make_key_event(SDL_KEYUP, key, mod);
|
||||
event_node_ptr new_key(new event_node_keyboard(time, event));
|
||||
add_event(new_key);
|
||||
return new_key;
|
||||
}
|
||||
|
||||
void fake_event_source::process(events::pump_info& /*info*/)
|
||||
{
|
||||
if (queue_.empty())
|
||||
return;
|
||||
size_t now = SDL_GetTicks();
|
||||
while (!queue_.empty()
|
||||
&& queue_.top()->test_if_should_fire(start_time_, now))
|
||||
{
|
||||
queue_.top()->fire_event();
|
||||
queue_.pop();
|
||||
}
|
||||
}
|
||||
}
|
101
src/tests/utils/fake_event_source.hpp
Normal file
101
src/tests/utils/fake_event_source.hpp
Normal file
|
@ -0,0 +1,101 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
Copyright (C) 2008 by Pauli Nieminen <paniemin@cc.hut.fi>
|
||||
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2
|
||||
or at your option any later version.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY.
|
||||
|
||||
See the COPYING file for more details.
|
||||
*/
|
||||
|
||||
#ifndef TESTS_UTILS_FAKE_EVENT_SOURCE_HPP_INCLUDED
|
||||
#define TESTS_UTILS_FAKE_EVENT_SOURCE_HPP_INCLUDED
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <queue>
|
||||
#include "SDL.h"
|
||||
|
||||
#include "events.hpp"
|
||||
|
||||
namespace test_utils {
|
||||
|
||||
|
||||
template<class T>
|
||||
struct less_ptr {
|
||||
bool operator()(const T& a, const T& b) const
|
||||
{
|
||||
return (*a) < (*b);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class for all event nodes to be used to fire fake input events
|
||||
**/
|
||||
class event_node :
|
||||
public boost::noncopyable
|
||||
{
|
||||
size_t time_;
|
||||
bool fired_;
|
||||
protected:
|
||||
SDL_Event event_;
|
||||
|
||||
public:
|
||||
event_node(const size_t time, const SDL_Event& event);
|
||||
virtual ~event_node();
|
||||
|
||||
virtual void fire_event();
|
||||
/**
|
||||
* @return true if this should stop firing events
|
||||
**/
|
||||
bool test_if_should_fire(const size_t start_time, const size_t time_now) const;
|
||||
|
||||
bool is_fired() const;
|
||||
|
||||
/**
|
||||
* We want the smallestat the top
|
||||
**/
|
||||
bool operator<(const event_node& o) const;
|
||||
};
|
||||
|
||||
class event_node_keyboard : public event_node {
|
||||
public:
|
||||
event_node_keyboard(size_t time, SDL_Event& event);
|
||||
void fire_event();
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<event_node> event_node_ptr;
|
||||
|
||||
/**
|
||||
* fake_event_source is used to generate new events in
|
||||
* events::pump()
|
||||
**/
|
||||
|
||||
class fake_event_source
|
||||
: public events::pump_monitor,
|
||||
public boost::noncopyable
|
||||
{
|
||||
size_t start_time_;
|
||||
typedef std::priority_queue<event_node_ptr,std::vector<event_node_ptr>,less_ptr<event_node_ptr> > event_queue;
|
||||
|
||||
event_queue queue_;
|
||||
|
||||
public:
|
||||
fake_event_source();
|
||||
~fake_event_source();
|
||||
void add_event(const size_t time, const SDL_Event& event);
|
||||
void add_event(event_node_ptr new_node);
|
||||
void start();
|
||||
|
||||
SDL_Event make_key_event(Uint8 type, const SDLKey key, const SDLMod mod);
|
||||
event_node_ptr press_key(const size_t time, const SDLKey key, const SDLMod mod = KMOD_NONE);
|
||||
event_node_ptr release_key(const size_t time, const SDLKey key, const SDLMod mod =KMOD_NONE);
|
||||
|
||||
void process(events::pump_info& /*info*/);
|
||||
};
|
||||
}
|
||||
#endif
|
|
@ -283,6 +283,15 @@ void CVideo::make_fake()
|
|||
image::set_pixel_format(frameBuffer->format);
|
||||
}
|
||||
|
||||
void CVideo::make_test_fake()
|
||||
{
|
||||
// Create fake screen that is 1024x768 24bpp
|
||||
// We can then use this in tests to draw
|
||||
frameBuffer = SDL_CreateRGBSurface(SDL_SWSURFACE,1024,768,24,0xFF0000,0xFF00,0xFF,0);
|
||||
image::set_pixel_format(frameBuffer->format);
|
||||
|
||||
}
|
||||
|
||||
int CVideo::modePossible( int x, int y, int bits_per_pixel, int flags )
|
||||
{
|
||||
return SDL_VideoModeOK( x, y, bits_per_pixel, get_flags(flags) );
|
||||
|
|
|
@ -79,6 +79,7 @@ class CVideo {
|
|||
int getBpp();
|
||||
|
||||
void make_fake();
|
||||
void make_test_fake();
|
||||
bool faked() const { return fake_screen_; }
|
||||
|
||||
//functions to set and clear 'help strings'. A 'help string' is like a tooltip, but it appears
|
||||
|
|
Loading…
Add table
Reference in a new issue