Support for running the testsuite in command line programs for continuous integration.
Here is a small example inspired from SDLmain.c:
g_launcher = new JGameLauncher();
InitGame();
MTGCollection()->loadFolder("sets/primitives/");
MTGCollection()->loadFolder("sets/", "_cards.dat");
options.reloadProfile();
TestSuite testSuite("test/_tests.txt");
int result = testSuite.run();
DestroyGame();
delete g_launcher;
return result;
This commit is contained in:
@@ -125,6 +125,8 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
MTGCard * getCardByName(string name);
|
MTGCard * getCardByName(string name);
|
||||||
|
void loadFolder(const string& folder, const string& filename="" );
|
||||||
|
|
||||||
int load(const char * config_file, const char * setName = NULL, int autoload = 1);
|
int load(const char * config_file, const char * setName = NULL, int autoload = 1);
|
||||||
int countByType(const char * _type);
|
int countByType(const char * _type);
|
||||||
int countByColor(int color);
|
int countByColor(int color);
|
||||||
@@ -181,9 +183,8 @@ public:
|
|||||||
return instance->subtypesList.find(value,false);
|
return instance->subtypesList.find(value,false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void loadInstance();
|
|
||||||
static void unloadAll();
|
static void unloadAll();
|
||||||
static inline MTGAllCards* getInstance() { return instance; };
|
static MTGAllCards* getInstance();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
boost::mutex mMutex;
|
boost::mutex mMutex;
|
||||||
|
|||||||
@@ -85,26 +85,33 @@ private:
|
|||||||
void cleanup();
|
void cleanup();
|
||||||
vector<boost::thread*> mWorkerThread;
|
vector<boost::thread*> mWorkerThread;
|
||||||
Rules* mRules;
|
Rules* mRules;
|
||||||
bool mProcessing;
|
|
||||||
|
|
||||||
public:
|
bool mProcessing;
|
||||||
int startTime, endTime;
|
int startTime, endTime;
|
||||||
unsigned int seed;
|
static void ThreadProc(void* inParam);
|
||||||
int nbFailed, nbTests, nbAIFailed, nbAITests;
|
|
||||||
TestSuite(const char * filename);
|
|
||||||
~TestSuite();
|
|
||||||
void initGame(GameObserver* g);
|
|
||||||
void pregameTests();
|
|
||||||
int loadNext();
|
|
||||||
string getNextFile() {
|
string getNextFile() {
|
||||||
boost::mutex::scoped_lock lock(mMutex);
|
boost::mutex::scoped_lock lock(mMutex);
|
||||||
if (currentfile >= nbfiles) return "";
|
if (currentfile >= nbfiles) return "";
|
||||||
currentfile++;
|
currentfile++;
|
||||||
return files[currentfile - 1];
|
return files[currentfile - 1];
|
||||||
};
|
};
|
||||||
static void ThreadProc(void* inParam);
|
void pregameTests();
|
||||||
void setRules(Rules* rules) {mRules = rules;};
|
|
||||||
|
public:
|
||||||
|
int getElapsedTime() {return endTime-startTime;};
|
||||||
|
unsigned int seed;
|
||||||
|
int nbFailed, nbTests, nbAIFailed, nbAITests;
|
||||||
|
TestSuite(const char * filename);
|
||||||
|
~TestSuite();
|
||||||
|
void initGame(GameObserver* g);
|
||||||
|
int loadNext();
|
||||||
|
void setRules(Rules* rules) {
|
||||||
|
mRules = rules;
|
||||||
|
};
|
||||||
void handleResults(bool wasAI, int error);
|
void handleResults(bool wasAI, int error);
|
||||||
|
// run the test suite in turbo mode without UI,
|
||||||
|
// returns the amount of failed tests (AI or not), so 0 if everything went fine.
|
||||||
|
int run();
|
||||||
};
|
};
|
||||||
|
|
||||||
class TestSuiteAI:public AIPlayerBaka
|
class TestSuiteAI:public AIPlayerBaka
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ void GameApp::Create()
|
|||||||
HasMusic = jfs->FileExists(WResourceManager::Instance()->musicFile("Track0.mp3")) && jfs->FileExists(WResourceManager::Instance()->musicFile("Track1.mp3"));
|
HasMusic = jfs->FileExists(WResourceManager::Instance()->musicFile("Track0.mp3")) && jfs->FileExists(WResourceManager::Instance()->musicFile("Track1.mp3"));
|
||||||
|
|
||||||
LOG("Init Collection");
|
LOG("Init Collection");
|
||||||
MTGAllCards::loadInstance();
|
MTGAllCards::getInstance();
|
||||||
|
|
||||||
LOG("Loading rules");
|
LOG("Loading rules");
|
||||||
Rules::loadAllRules();
|
Rules::loadAllRules();
|
||||||
|
|||||||
@@ -1097,7 +1097,7 @@ void GameStateDuel::Render()
|
|||||||
char buf[4096];
|
char buf[4096];
|
||||||
mFont->SetColor(ARGB(255,255,255,255));
|
mFont->SetColor(ARGB(255,255,255,255));
|
||||||
|
|
||||||
int elapsedTime = (testSuite->endTime - testSuite->startTime);
|
int elapsedTime = testSuite->getElapsedTime();
|
||||||
sprintf(buf, "Time to run the tests: %is", elapsedTime/1000);
|
sprintf(buf, "Time to run the tests: %is", elapsedTime/1000);
|
||||||
mFont->DrawString(buf,0,SCREEN_HEIGHT/2 - 20);
|
mFont->DrawString(buf,0,SCREEN_HEIGHT/2 - 20);
|
||||||
|
|
||||||
|
|||||||
@@ -336,6 +336,42 @@ void MTGAllCards::init()
|
|||||||
initCounters();
|
initCounters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MTGAllCards::loadFolder(const string& folder, const string& filename )
|
||||||
|
{
|
||||||
|
vector<string> files = JFileSystem::GetInstance()->scanfolder(folder);
|
||||||
|
|
||||||
|
if (!files.size())
|
||||||
|
{
|
||||||
|
DebugTrace("loadPrimitives:WARNING:Primitives folder is missing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < files.size(); ++i)
|
||||||
|
{
|
||||||
|
string afile = folder;
|
||||||
|
afile.append(files[i]);
|
||||||
|
|
||||||
|
if(files[i] == "." || files[i] == "..")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!JFileSystem::GetInstance()->FileExists(afile))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(JFileSystem::GetInstance()->DirExists(afile))
|
||||||
|
loadFolder(string(afile+"/").c_str(), filename);
|
||||||
|
|
||||||
|
if(filename.size())
|
||||||
|
{
|
||||||
|
if(filename == files[i])
|
||||||
|
{
|
||||||
|
load(afile.c_str(), folder.c_str());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
load(afile.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int MTGAllCards::load(const char * config_file, const char * set_name, int)
|
int MTGAllCards::load(const char * config_file, const char * set_name, int)
|
||||||
{
|
{
|
||||||
conf_read_mode = 0;
|
conf_read_mode = 0;
|
||||||
@@ -445,10 +481,12 @@ MTGAllCards::~MTGAllCards()
|
|||||||
primitives.clear();
|
primitives.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MTGAllCards::loadInstance()
|
MTGAllCards* MTGAllCards::getInstance()
|
||||||
{
|
{
|
||||||
if(!instance)
|
if(!instance)
|
||||||
instance = new MTGAllCards();
|
instance = new MTGAllCards();
|
||||||
|
|
||||||
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MTGAllCards::unloadAll()
|
void MTGAllCards::unloadAll()
|
||||||
|
|||||||
@@ -531,7 +531,6 @@ TestSuite::TestSuite(const char * filename)
|
|||||||
|
|
||||||
int TestSuite::loadNext()
|
int TestSuite::loadNext()
|
||||||
{
|
{
|
||||||
|
|
||||||
endTime = JGEGetTime();
|
endTime = JGEGetTime();
|
||||||
summoningSickness = 0;
|
summoningSickness = 0;
|
||||||
seed = 0;
|
seed = 0;
|
||||||
@@ -582,6 +581,43 @@ int TestSuite::loadNext()
|
|||||||
return currentfile;
|
return currentfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestSuite::ThreadProc(void* inParam)
|
||||||
|
{
|
||||||
|
LOG("Entering TestSuite::ThreadProc");
|
||||||
|
TestSuite* instance = reinterpret_cast<TestSuite*>(inParam);
|
||||||
|
if (instance)
|
||||||
|
{
|
||||||
|
string filename;
|
||||||
|
float counter = 1.0f;
|
||||||
|
while(instance->mProcessing && (filename = instance->getNextFile()) != "")
|
||||||
|
{
|
||||||
|
TestSuiteGame theGame(instance, filename);
|
||||||
|
if(theGame.isOK)
|
||||||
|
{
|
||||||
|
theGame.observer->loadTestSuitePlayer(0, &theGame);
|
||||||
|
theGame.observer->loadTestSuitePlayer(1, &theGame);
|
||||||
|
|
||||||
|
theGame.observer->startGame(theGame.gameType, /*instance->mRules*/Rules::getRulesByFilename("testsuite.txt"));
|
||||||
|
theGame.initGame();
|
||||||
|
|
||||||
|
while(!theGame.observer->didWin())
|
||||||
|
theGame.observer->Update(counter++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG("Leaving TestSuite::ThreadProc");
|
||||||
|
}
|
||||||
|
|
||||||
|
int TestSuite::run()
|
||||||
|
{
|
||||||
|
mProcessing = false;
|
||||||
|
loadNext();
|
||||||
|
ThreadProc(this);
|
||||||
|
|
||||||
|
return nbFailed + nbAIFailed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void TestSuiteActions::cleanup()
|
void TestSuiteActions::cleanup()
|
||||||
{
|
{
|
||||||
nbitems = 0;
|
nbitems = 0;
|
||||||
@@ -755,41 +791,6 @@ void TestSuite::pregameTests()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestSuite::ThreadProc(void* inParam)
|
|
||||||
{
|
|
||||||
LOG("Entering TestSuite::ThreadProc");
|
|
||||||
TestSuite* instance = reinterpret_cast<TestSuite*>(inParam);
|
|
||||||
if (instance)
|
|
||||||
{
|
|
||||||
string filename;
|
|
||||||
while(instance->mProcessing && (filename = instance->getNextFile()) != "")
|
|
||||||
{
|
|
||||||
TestSuiteGame theGame(instance, filename);
|
|
||||||
if(theGame.isOK)
|
|
||||||
{
|
|
||||||
theGame.observer->loadTestSuitePlayer(0, &theGame);
|
|
||||||
theGame.observer->loadTestSuitePlayer(1, &theGame);
|
|
||||||
|
|
||||||
theGame.observer->startGame(theGame.gameType, instance->mRules);
|
|
||||||
theGame.initGame();
|
|
||||||
|
|
||||||
while(!theGame.observer->didWin())
|
|
||||||
theGame.observer->Update(1);
|
|
||||||
/*
|
|
||||||
if(theGame.observer->gameType() != GAME_TYPE_MOMIR)
|
|
||||||
{
|
|
||||||
stringstream stream;
|
|
||||||
stream << *(theGame.observer);
|
|
||||||
theGame.observer->load(stream.str(), false, &theGame);
|
|
||||||
theGame.assertGame();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LOG("Leaving TestSuite::ThreadProc");
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::mutex TestSuiteGame::mMutex;
|
boost::mutex TestSuiteGame::mMutex;
|
||||||
|
|
||||||
TestSuiteGame::~TestSuiteGame()
|
TestSuiteGame::~TestSuiteGame()
|
||||||
|
|||||||
Reference in New Issue
Block a user