TESTBED: Merge gsoc2010-testbed branch
svn-id: r52681
This commit is contained in:
commit
74118a7087
29 changed files with 4176 additions and 0 deletions
|
@ -157,6 +157,9 @@ public:
|
|||
#if PLUGIN_ENABLED_STATIC(TEENAGENT)
|
||||
LINK_PLUGIN(TEENAGENT)
|
||||
#endif
|
||||
#if PLUGIN_ENABLED_STATIC(TESTBED)
|
||||
LINK_PLUGIN(TESTBED)
|
||||
#endif
|
||||
#if PLUGIN_ENABLED_STATIC(TINSEL)
|
||||
LINK_PLUGIN(TINSEL)
|
||||
#endif
|
||||
|
|
1
configure
vendored
1
configure
vendored
|
@ -106,6 +106,7 @@ add_engine sky "Beneath a Steel Sky" yes
|
|||
add_engine sword1 "Broken Sword" yes
|
||||
add_engine sword2 "Broken Sword II" yes
|
||||
add_engine teenagent "Teen Agent" yes
|
||||
add_engine testbed "TestBed: the Testing framework" no
|
||||
add_engine tinsel "Tinsel" yes
|
||||
add_engine touche "Touche: The Adventures of the Fifth Musketeer" yes
|
||||
add_engine tucker "Bud Tucker in Double Trouble" yes
|
||||
|
|
52
dists/engine-data/create-testbed-data.sh
Executable file
52
dists/engine-data/create-testbed-data.sh
Executable file
|
@ -0,0 +1,52 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Create the directory structure
|
||||
# Avoided bash shortcuts / file-seperators in interest of portability
|
||||
|
||||
if [ -e testbed ]; then
|
||||
echo "Game-data already present as testbed/"
|
||||
echo "To regenerate, remove and rerun"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
mkdir testbed
|
||||
|
||||
cd testbed
|
||||
|
||||
# For game detection
|
||||
echo "ScummVM rocks!" > TESTBED
|
||||
|
||||
mkdir test1
|
||||
mkdir Test2
|
||||
mkdir TEST3
|
||||
mkdir tEST4
|
||||
mkdir test5
|
||||
|
||||
|
||||
cd test1
|
||||
echo "It works!" > file.txt
|
||||
cd ..
|
||||
|
||||
cd Test2
|
||||
echo "It works!" > File.txt
|
||||
cd ..
|
||||
|
||||
cd TEST3
|
||||
echo "It works!" > FILE.txt
|
||||
cd ..
|
||||
|
||||
cd tEST4
|
||||
echo "It works!" > fILe.txt
|
||||
cd ..
|
||||
|
||||
cd test5
|
||||
echo "It works!" > file.
|
||||
cd ..
|
||||
|
||||
# back to the top
|
||||
cd ..
|
||||
|
||||
# move the audiocd data to newly created directory
|
||||
cp -r testbed-audiocd-files testbed/audiocd-files
|
||||
|
||||
echo "Game data created"
|
BIN
dists/engine-data/testbed-audiocd-files/track01.mp3
Executable file
BIN
dists/engine-data/testbed-audiocd-files/track01.mp3
Executable file
Binary file not shown.
BIN
dists/engine-data/testbed-audiocd-files/track02.mp3
Executable file
BIN
dists/engine-data/testbed-audiocd-files/track02.mp3
Executable file
Binary file not shown.
BIN
dists/engine-data/testbed-audiocd-files/track03.mp3
Executable file
BIN
dists/engine-data/testbed-audiocd-files/track03.mp3
Executable file
Binary file not shown.
BIN
dists/engine-data/testbed-audiocd-files/track04.mp3
Executable file
BIN
dists/engine-data/testbed-audiocd-files/track04.mp3
Executable file
Binary file not shown.
|
@ -141,6 +141,11 @@ DEFINES += -DENABLE_SWORD2=$(ENABLE_SWORD2)
|
|||
MODULES += engines/sword2
|
||||
endif
|
||||
|
||||
ifdef ENABLE_TESTBED
|
||||
DEFINES += -DENABLE_TESTBED=$(ENABLE_TESTBED)
|
||||
MODULES += engines/testbed
|
||||
endif
|
||||
|
||||
ifdef ENABLE_TEENAGENT
|
||||
DEFINES += -DENABLE_TEENAGENT=$(ENABLE_TEENAGENT)
|
||||
MODULES += engines/teenagent
|
||||
|
|
292
engines/testbed/config.cpp
Normal file
292
engines/testbed/config.cpp
Normal file
|
@ -0,0 +1,292 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "common/fs.h"
|
||||
#include "common/stream.h"
|
||||
#include "common/config-manager.h"
|
||||
#include "engines/engine.h"
|
||||
#include "testbed/config.h"
|
||||
|
||||
namespace Testbed {
|
||||
|
||||
TestbedOptionsDialog::TestbedOptionsDialog(Common::Array<Testsuite *> &tsList, TestbedConfigManager *tsConfMan) : GUI::Dialog("Browser"), _testbedConfMan(tsConfMan) {
|
||||
|
||||
new GUI::StaticTextWidget(this, "Browser.Headline", "Select Testsuites to Execute");
|
||||
new GUI::StaticTextWidget(this, "Browser.Path", "Use Doubleclick to select/deselect");
|
||||
|
||||
// Construct a String Array
|
||||
Common::Array<Testsuite *>::const_iterator iter;
|
||||
Common::String description;
|
||||
uint selected = 0;
|
||||
|
||||
for (iter = tsList.begin(); iter != tsList.end(); iter++) {
|
||||
_testSuiteArray.push_back(*iter);
|
||||
description = (*iter)->getDescription();
|
||||
if ((*iter)->isEnabled()) {
|
||||
_testSuiteDescArray.push_back(description + "(selected)");
|
||||
selected++;
|
||||
_colors.push_back(GUI::ThemeEngine::kFontColorNormal);
|
||||
} else {
|
||||
_testSuiteDescArray.push_back(description);
|
||||
_colors.push_back(GUI::ThemeEngine::kFontColorAlternate);
|
||||
}
|
||||
}
|
||||
|
||||
_testListDisplay = new TestbedListWidget(this, "Browser.List", _testSuiteArray);
|
||||
_testListDisplay->setNumberingMode(GUI::kListNumberingOff);
|
||||
_testListDisplay->setList(_testSuiteDescArray, &_colors);
|
||||
|
||||
// This list shouldn't be editable
|
||||
_testListDisplay->setEditable(false);
|
||||
|
||||
if (selected > (tsList.size() - selected)) {
|
||||
_selectButton = new GUI::ButtonWidget(this, "Browser.Up", "Deselect All", 0, kTestbedDeselectAll, 0);
|
||||
} else {
|
||||
_selectButton = new GUI::ButtonWidget(this, "Browser.Up", "Select All", 0, kTestbedSelectAll, 0);
|
||||
}
|
||||
new GUI::ButtonWidget(this, "Browser.Cancel", "Run tests", 0, GUI::kCloseCmd);
|
||||
new GUI::ButtonWidget(this, "Browser.Choose", "Exit Testbed", 0, kTestbedQuitCmd);
|
||||
}
|
||||
|
||||
TestbedOptionsDialog::~TestbedOptionsDialog() {}
|
||||
|
||||
void TestbedOptionsDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) {
|
||||
Testsuite *ts;
|
||||
Common::WriteStream *ws;
|
||||
switch (cmd) {
|
||||
case GUI::kListItemDoubleClickedCmd:
|
||||
ts = _testSuiteArray[_testListDisplay->getSelected()];
|
||||
if (ts) {
|
||||
if (ts->isEnabled()) {
|
||||
ts->enable(false);
|
||||
_testListDisplay->markAsDeselected(_testListDisplay->getSelected());
|
||||
} else {
|
||||
ts->enable(true);
|
||||
_testListDisplay->markAsSelected(_testListDisplay->getSelected());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case kTestbedQuitCmd:
|
||||
Engine::quitGame();
|
||||
close();
|
||||
break;
|
||||
|
||||
case kTestbedDeselectAll:
|
||||
_selectButton->setLabel("Select All");
|
||||
_selectButton->setCmd(kTestbedSelectAll);
|
||||
for (uint i = 0; i < _testSuiteArray.size(); i++) {
|
||||
_testListDisplay->markAsDeselected(i);
|
||||
ts = _testSuiteArray[i];
|
||||
if (ts) {
|
||||
ts->enable(false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case kTestbedSelectAll:
|
||||
_selectButton->setLabel("Deselect All");
|
||||
_selectButton->setCmd(kTestbedDeselectAll);
|
||||
for (uint i = 0; i < _testSuiteArray.size(); i++) {
|
||||
_testListDisplay->markAsSelected(i);
|
||||
ts = _testSuiteArray[i];
|
||||
if (ts) {
|
||||
ts->enable(true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GUI::kCloseCmd:
|
||||
// This is final selected state, write it to config file.
|
||||
ws = _testbedConfMan->getConfigWriteStream();
|
||||
_testbedConfMan->writeTestbedConfigToStream(ws);
|
||||
delete ws;
|
||||
default:
|
||||
GUI::Dialog::handleCommand(sender, cmd, data);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void TestbedInteractionDialog::addText(uint w, uint h, const Common::String text, Graphics::TextAlign textAlign, uint xOffset, uint yPadding) {
|
||||
if (!xOffset) {
|
||||
xOffset = _xOffset;
|
||||
}
|
||||
_yOffset += yPadding;
|
||||
new GUI::StaticTextWidget(this, xOffset, _yOffset, w, h, text, textAlign);
|
||||
_yOffset += h;
|
||||
}
|
||||
|
||||
void TestbedInteractionDialog::addButton(uint w, uint h, const Common::String name, uint32 cmd, uint xOffset, uint yPadding) {
|
||||
if (!xOffset) {
|
||||
xOffset = _xOffset;
|
||||
}
|
||||
_yOffset += yPadding;
|
||||
_buttonArray.push_back(new GUI::ButtonWidget(this, xOffset, _yOffset, w, h, name, 0, cmd));
|
||||
_yOffset += h;
|
||||
}
|
||||
|
||||
void TestbedInteractionDialog::addList(uint x, uint y, uint w, uint h, Common::Array<Common::String> &strArray, uint yPadding) {
|
||||
_yOffset += yPadding;
|
||||
GUI::ListWidget *list = new GUI::ListWidget(this, x, y, w, h);
|
||||
list->setEditable(false);
|
||||
list->setNumberingMode(GUI::kListNumberingOff);
|
||||
list->setList(strArray);
|
||||
_yOffset += h;
|
||||
}
|
||||
|
||||
void TestbedInteractionDialog::addButtonXY(uint x, uint y, uint w, uint h, const Common::String name, uint32 cmd) {
|
||||
_buttonArray.push_back(new GUI::ButtonWidget(this, x, _yOffset, w, h, name, 0, cmd));
|
||||
}
|
||||
|
||||
void TestbedInteractionDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) {
|
||||
switch (cmd) {
|
||||
default:
|
||||
GUI::Dialog::handleCommand(sender, cmd, data);
|
||||
}
|
||||
}
|
||||
|
||||
void TestbedConfigManager::initDefaultConfiguration() {
|
||||
// Default Configuration
|
||||
// Add Global configuration Parameters here.
|
||||
_configFileInterface.setKey("isSessionInteractive", "Global", "true");
|
||||
}
|
||||
|
||||
void TestbedConfigManager::writeTestbedConfigToStream(Common::WriteStream *ws) {
|
||||
Common::String wStr;
|
||||
for (Common::Array<Testsuite *>::const_iterator i = _testsuiteList.begin(); i < _testsuiteList.end(); i++) {
|
||||
_configFileInterface.setKey("this", (*i)->getName(), boolToString((*i)->isEnabled()));
|
||||
const Common::Array<Test *> &testList = (*i)->getTestList();
|
||||
for (Common::Array<Test *>::const_iterator j = testList.begin(); j != testList.end(); j++) {
|
||||
_configFileInterface.setKey((*j)->featureName, (*i)->getName(), boolToString((*j)->enabled));
|
||||
}
|
||||
}
|
||||
_configFileInterface.saveToStream(*ws);
|
||||
_configFileInterface.clear();
|
||||
ws->flush();
|
||||
}
|
||||
|
||||
Common::SeekableReadStream *TestbedConfigManager::getConfigReadStream() {
|
||||
// Look for config file in game-path
|
||||
const Common::String &path = ConfMan.get("path");
|
||||
Common::FSDirectory gameRoot(path);
|
||||
Common::SeekableReadStream *rs = gameRoot.createReadStreamForMember(_configFileName);
|
||||
return rs;
|
||||
}
|
||||
|
||||
Common::WriteStream *TestbedConfigManager::getConfigWriteStream() {
|
||||
// Look for config file in game-path
|
||||
const Common::String &path = ConfMan.get("path");
|
||||
Common::WriteStream *ws;
|
||||
Common::FSNode gameRoot(path);
|
||||
Common::FSNode config = gameRoot.getChild(_configFileName);
|
||||
ws = config.createWriteStream();
|
||||
return ws;
|
||||
}
|
||||
|
||||
void TestbedConfigManager::parseConfigFile() {
|
||||
Common::SeekableReadStream *rs = getConfigReadStream();
|
||||
|
||||
if (!rs) {
|
||||
Testsuite::logPrintf("Info! No config file found, using default configuration.\n");
|
||||
initDefaultConfiguration();
|
||||
return;
|
||||
}
|
||||
_configFileInterface.loadFromStream(*rs);
|
||||
Common::ConfigFile::SectionList sections = _configFileInterface.getSections();
|
||||
Testsuite *currTS = 0;
|
||||
|
||||
for (Common::ConfigFile::SectionList::const_iterator i = sections.begin(); i != sections.end(); i++) {
|
||||
if (i->name.equalsIgnoreCase("Global")) {
|
||||
// Global params may be directly queried, ignore them
|
||||
} else {
|
||||
// A testsuite, process it.
|
||||
currTS = getTestsuiteByName(i->name);
|
||||
Common::ConfigFile::SectionKeyList kList = i->getKeys();
|
||||
if (!currTS) {
|
||||
Testsuite::logPrintf("Warning! Error in config: Testsuite %s not found\n", i->name.c_str());
|
||||
}
|
||||
|
||||
for (Common::ConfigFile::SectionKeyList::const_iterator j = kList.begin(); j != kList.end(); j++) {
|
||||
if (j->key.equalsIgnoreCase("this")) {
|
||||
currTS->enable(stringToBool(j->value));
|
||||
} else {
|
||||
if (!currTS->enableTest(j->key, stringToBool(j->value))) {
|
||||
Testsuite::logPrintf("Warning! Error in config: Test %s not found\n", j->key.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delete rs;
|
||||
}
|
||||
|
||||
int TestbedConfigManager::getNumSuitesEnabled() {
|
||||
int count = 0;
|
||||
for (uint i = 0; i < _testsuiteList.size(); i++) {
|
||||
if (_testsuiteList[i]->isEnabled()) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
Testsuite *TestbedConfigManager::getTestsuiteByName(const Common::String &name) {
|
||||
for (uint i = 0; i < _testsuiteList.size(); i++) {
|
||||
if (name.equalsIgnoreCase(_testsuiteList[i]->getName())) {
|
||||
return _testsuiteList[i];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TestbedConfigManager::selectTestsuites() {
|
||||
|
||||
parseConfigFile();
|
||||
|
||||
if (_configFileInterface.hasKey("isSessionInteractive", "Global")) {
|
||||
Common::String in;
|
||||
_configFileInterface.getKey("isSessionInteractive", "Global", in);
|
||||
Testsuite::isSessionInteractive = stringToBool(in);
|
||||
}
|
||||
|
||||
if (!Testsuite::isSessionInteractive) {
|
||||
// Non interactive sessions don't need to go beyond
|
||||
return;
|
||||
}
|
||||
|
||||
// XXX: disabling these as of now for fastly testing other tests
|
||||
// Testsuite::isSessionInteractive = false;
|
||||
Common::String prompt("Welcome to the ScummVM testbed!\n"
|
||||
"It is a framework to test the various ScummVM subsystems namely GFX, Sound, FS, events etc.\n"
|
||||
"If you see this, it means interactive tests would run on this system :)");
|
||||
|
||||
Testsuite::logPrintf("Info! : Interactive tests are also being executed.\n");
|
||||
|
||||
if (Testsuite::handleInteractiveInput(prompt, "Proceed?", "Customize", kOptionRight)) {
|
||||
// Select testsuites using checkboxes
|
||||
TestbedOptionsDialog tbd(_testsuiteList, this);
|
||||
tbd.runModal();
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Testbed
|
135
engines/testbed/config.h
Normal file
135
engines/testbed/config.h
Normal file
|
@ -0,0 +1,135 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef TESTBED_CONFIG_H
|
||||
#define TESTBED_CONFIG_H
|
||||
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/config-file.h"
|
||||
#include "common/str-array.h"
|
||||
#include "common/tokenizer.h"
|
||||
|
||||
#include "gui/ListWidget.h"
|
||||
#include "gui/options.h"
|
||||
#include "gui/ThemeEngine.h"
|
||||
|
||||
#include "testbed/testsuite.h"
|
||||
|
||||
namespace Testbed {
|
||||
|
||||
enum {
|
||||
kTestbedQuitCmd = 'Quit',
|
||||
kTestbedSelectAll = 'sAll',
|
||||
kTestbedDeselectAll = 'dAll'
|
||||
};
|
||||
|
||||
|
||||
|
||||
class TestbedConfigManager {
|
||||
public:
|
||||
TestbedConfigManager(Common::Array<Testsuite *> &tList, const Common::String fName) : _testsuiteList(tList), _configFileName(fName) {}
|
||||
~TestbedConfigManager() {}
|
||||
void selectTestsuites();
|
||||
void setConfigFile(const Common::String fName) { _configFileName = fName; }
|
||||
Common::SeekableReadStream *getConfigReadStream();
|
||||
Common::WriteStream *getConfigWriteStream();
|
||||
void writeTestbedConfigToStream(Common::WriteStream *ws);
|
||||
Testsuite *getTestsuiteByName(const Common::String &name);
|
||||
bool stringToBool(const Common::String str) { return str.equalsIgnoreCase("true") ? true : false; }
|
||||
Common::String boolToString(bool val) { return val ? "true" : "false"; }
|
||||
void initDefaultConfiguration();
|
||||
int getNumSuitesEnabled();
|
||||
|
||||
private:
|
||||
Common::Array<Testsuite *> &_testsuiteList;
|
||||
Common::String _configFileName;
|
||||
Common::ConfigFile _configFileInterface;
|
||||
void parseConfigFile();
|
||||
};
|
||||
|
||||
class TestbedListWidget : public GUI::ListWidget {
|
||||
public:
|
||||
TestbedListWidget(GUI::Dialog *boss, const Common::String &name, Common::Array<Testsuite *> tsArray) : GUI::ListWidget(boss, name), _testSuiteArray(tsArray) {}
|
||||
|
||||
void markAsSelected(int i) {
|
||||
if (!_list[i].contains("selected")) {
|
||||
_list[i] += " (selected)";
|
||||
}
|
||||
_listColors[i] = GUI::ThemeEngine::kFontColorNormal;
|
||||
draw();
|
||||
}
|
||||
|
||||
void markAsDeselected(int i) {
|
||||
if (_list[i].contains("selected")) {
|
||||
_list[i] = _testSuiteArray[i]->getDescription();
|
||||
}
|
||||
_listColors[i] = GUI::ThemeEngine::kFontColorAlternate;
|
||||
draw();
|
||||
}
|
||||
|
||||
void setColor(uint32 indx, GUI::ThemeEngine::FontColor color) {
|
||||
assert(indx < _listColors.size());
|
||||
_listColors[indx] = color;
|
||||
draw();
|
||||
}
|
||||
|
||||
private:
|
||||
Common::Array<Testsuite *> _testSuiteArray;
|
||||
};
|
||||
|
||||
class TestbedOptionsDialog : public GUI::Dialog {
|
||||
public:
|
||||
TestbedOptionsDialog(Common::Array<Testsuite *> &tsList, TestbedConfigManager *tsConfMan);
|
||||
~TestbedOptionsDialog();
|
||||
void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data);
|
||||
|
||||
private:
|
||||
GUI::ListWidget::ColorList _colors;
|
||||
GUI::ButtonWidget *_selectButton;
|
||||
Common::Array<Testsuite *> _testSuiteArray;
|
||||
Common::StringArray _testSuiteDescArray;
|
||||
TestbedListWidget *_testListDisplay;
|
||||
TestbedConfigManager *_testbedConfMan;
|
||||
};
|
||||
|
||||
class TestbedInteractionDialog : public GUI::Dialog {
|
||||
public:
|
||||
TestbedInteractionDialog(uint x, uint y, uint w, uint h) : GUI::Dialog(x, y, w, h) {}
|
||||
~TestbedInteractionDialog() {}
|
||||
virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data);
|
||||
void addButton(uint w, uint h, const Common::String name, uint32 cmd, uint xOffset = 0, uint yPadding = 8);
|
||||
void addButtonXY(uint x, uint y, uint w, uint h, const Common::String name, uint32 cmd);
|
||||
void addText(uint w, uint h, const Common::String text, Graphics::TextAlign textAlign, uint xOffset, uint yPadding = 8);
|
||||
void addList(uint x, uint y, uint w, uint h, Common::Array<Common::String> &strArray, uint yPadding = 8);
|
||||
protected:
|
||||
Common::Array<GUI::ButtonWidget *> _buttonArray;
|
||||
uint _xOffset;
|
||||
uint _yOffset;
|
||||
|
||||
};
|
||||
|
||||
} // End of namespace Testbed
|
||||
|
||||
#endif // TESTBED_CONFIG_H
|
92
engines/testbed/detection.cpp
Normal file
92
engines/testbed/detection.cpp
Normal file
|
@ -0,0 +1,92 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/config-manager.h"
|
||||
#include "engines/advancedDetector.h"
|
||||
#include "common/system.h"
|
||||
#include "common/fs.h"
|
||||
|
||||
#include "base/plugins.h"
|
||||
|
||||
#include "testbed/testbed.h"
|
||||
|
||||
static const PlainGameDescriptor testbed_setting[] = {
|
||||
{ "testbed", "Testbed: The backend testing framework" },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static const ADGameDescription testbedDescriptions[] = {
|
||||
{
|
||||
"testbed",
|
||||
"",
|
||||
AD_ENTRY1(NULL, 0), // No data files required
|
||||
Common::EN_ANY,
|
||||
Common::kPlatformPC,
|
||||
ADGF_NO_FLAGS,
|
||||
Common::GUIO_NONE
|
||||
},
|
||||
AD_TABLE_END_MARKER
|
||||
};
|
||||
|
||||
static const ADParams detectionParams = {
|
||||
(const byte *)testbedDescriptions,
|
||||
sizeof(ADGameDescription),
|
||||
512,
|
||||
testbed_setting,
|
||||
0,
|
||||
"testbed",
|
||||
0,
|
||||
ADGF_NO_FLAGS,
|
||||
Common::GUIO_NONE,
|
||||
1,
|
||||
0
|
||||
};
|
||||
|
||||
class TestbedMetaEngine : public AdvancedMetaEngine {
|
||||
public:
|
||||
TestbedMetaEngine() : AdvancedMetaEngine(detectionParams) {
|
||||
}
|
||||
|
||||
virtual const char *getName() const {
|
||||
return "TestBed: The backend testing framework";
|
||||
}
|
||||
|
||||
virtual const char *getOriginalCopyright() const {
|
||||
return "Copyright (C) ScummVM";
|
||||
}
|
||||
|
||||
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
|
||||
// Instantiate Engine even if the game data is not found.
|
||||
*engine = new Testbed::TestbedEngine(syst);
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#if PLUGIN_ENABLED_DYNAMIC(TESTBED)
|
||||
REGISTER_PLUGIN_DYNAMIC(TESTBED, PLUGIN_TYPE_ENGINE, TestbedMetaEngine);
|
||||
#else
|
||||
REGISTER_PLUGIN_STATIC(TESTBED, PLUGIN_TYPE_ENGINE, TestbedMetaEngine);
|
||||
#endif
|
294
engines/testbed/events.cpp
Normal file
294
engines/testbed/events.cpp
Normal file
|
@ -0,0 +1,294 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "common/events.h"
|
||||
#include "common/keyboard.h"
|
||||
|
||||
#include "engines/engine.h"
|
||||
|
||||
#include "graphics/cursorman.h"
|
||||
|
||||
#include "testbed/events.h"
|
||||
#include "testbed/graphics.h"
|
||||
|
||||
namespace Testbed {
|
||||
|
||||
struct keycodeToChar {
|
||||
Common::KeyCode code;
|
||||
char value;
|
||||
} keyCodeLUT[] = {
|
||||
{Common::KEYCODE_a, 'a'},
|
||||
{Common::KEYCODE_b, 'b'},
|
||||
{Common::KEYCODE_c, 'c'},
|
||||
{Common::KEYCODE_d, 'd'},
|
||||
{Common::KEYCODE_e, 'e'},
|
||||
{Common::KEYCODE_f, 'f'},
|
||||
{Common::KEYCODE_g, 'g'},
|
||||
{Common::KEYCODE_h, 'h'},
|
||||
{Common::KEYCODE_i, 'i'},
|
||||
{Common::KEYCODE_j, 'j'},
|
||||
{Common::KEYCODE_k, 'k'},
|
||||
{Common::KEYCODE_l, 'l'},
|
||||
{Common::KEYCODE_m, 'm'},
|
||||
{Common::KEYCODE_n, 'n'},
|
||||
{Common::KEYCODE_o, 'o'},
|
||||
{Common::KEYCODE_p, 'p'},
|
||||
{Common::KEYCODE_q, 'q'},
|
||||
{Common::KEYCODE_r, 'r'},
|
||||
{Common::KEYCODE_s, 's'},
|
||||
{Common::KEYCODE_t, 't'},
|
||||
{Common::KEYCODE_u, 'u'},
|
||||
{Common::KEYCODE_v, 'v'},
|
||||
{Common::KEYCODE_w, 'w'},
|
||||
{Common::KEYCODE_x, 'x'},
|
||||
{Common::KEYCODE_y, 'y'},
|
||||
{Common::KEYCODE_z, 'z'},
|
||||
{Common::KEYCODE_SPACE, ' '}
|
||||
};
|
||||
|
||||
char EventTests::keystrokeToChar() {
|
||||
Common::EventManager *eventMan = g_system->getEventManager();
|
||||
bool quitLoop = false;
|
||||
Common::Event event;
|
||||
|
||||
// handle all keybd events
|
||||
while (!quitLoop) {
|
||||
while (eventMan->pollEvent(event)) {
|
||||
// Quit if explicitly requested!
|
||||
if (Engine::shouldQuit()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (event.type) {
|
||||
case Common::EVENT_KEYDOWN:
|
||||
if (event.kbd.keycode == Common::KEYCODE_ESCAPE) {
|
||||
return 0;
|
||||
}
|
||||
for (int i = 0; i < ARRAYSIZE(keyCodeLUT); i++) {
|
||||
if (event.kbd.keycode == keyCodeLUT[i].code) {
|
||||
return keyCodeLUT[i].value;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break; // Ignore other events
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Common::Rect EventTests::drawFinishZone() {
|
||||
Graphics::Surface *screen = g_system->lockScreen();
|
||||
const Graphics::Font &font(*FontMan.getFontByUsage(Graphics::FontManager::kBigGUIFont));
|
||||
int width = 35;
|
||||
int height = 20;
|
||||
int right = g_system->getWidth();
|
||||
Common::Rect rect(0, 0, right, height);
|
||||
Common::Rect rect2(0, 0, right - width, height);
|
||||
screen->fillRect(rect, kColorSpecial);
|
||||
screen->fillRect(rect2, kColorBlack);
|
||||
g_system->unlockScreen();
|
||||
font.drawString(screen, "Close", rect.left, rect.top, screen->w, kColorBlack, Graphics::kTextAlignRight);
|
||||
g_system->updateScreen();
|
||||
return Common::Rect(right - width, 0, right, height);
|
||||
}
|
||||
|
||||
bool EventTests::mouseEvents() {
|
||||
|
||||
Testsuite::clearScreen();
|
||||
Common::String info = "Testing Mouse events.\n "
|
||||
"Any movement/click generated by L/R/M mouse buttons or the mouse wheel should be detected.\n"
|
||||
"Press X to exit";
|
||||
|
||||
if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) {
|
||||
Testsuite::logPrintf("Info! Skipping test : keyboard events\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
Common::EventManager *eventMan = g_system->getEventManager();
|
||||
|
||||
Common::Point pt(0, 100);
|
||||
Common::Rect rect = Testsuite::writeOnScreen("Generate mouse events make L/R/M button clicks", pt);
|
||||
pt.y = 120;
|
||||
Testsuite::writeOnScreen("Testbed should be able to detect them, Press X to exit", pt);
|
||||
|
||||
// Init Mouse Palette
|
||||
GFXtests::initMousePalette();
|
||||
Common::Rect finishZone = drawFinishZone();
|
||||
|
||||
bool quitLoop = false;
|
||||
bool passed = true;
|
||||
// handle all mouse events
|
||||
Common::Event event;
|
||||
while (!quitLoop) {
|
||||
// Show mouse
|
||||
CursorMan.showMouse(true);
|
||||
g_system->updateScreen();
|
||||
|
||||
while (eventMan->pollEvent(event)) {
|
||||
// Quit if explicitly requested
|
||||
if (Engine::shouldQuit()) {
|
||||
return passed;
|
||||
}
|
||||
switch (event.type) {
|
||||
case Common::EVENT_MOUSEMOVE:
|
||||
// Movements havee already been tested in GFX
|
||||
break;
|
||||
case Common::EVENT_LBUTTONDOWN:
|
||||
Testsuite::clearScreen(rect);
|
||||
Testsuite::writeOnScreen("Mouse left-button pressed", pt);
|
||||
break;
|
||||
case Common::EVENT_RBUTTONDOWN:
|
||||
Testsuite::clearScreen(rect);
|
||||
Testsuite::writeOnScreen("Mouse right-button pressed", pt);
|
||||
break;
|
||||
case Common::EVENT_WHEELDOWN:
|
||||
Testsuite::clearScreen(rect);
|
||||
Testsuite::writeOnScreen("Mouse wheel moved down", pt);
|
||||
break;
|
||||
case Common::EVENT_MBUTTONDOWN:
|
||||
Testsuite::clearScreen(rect);
|
||||
Testsuite::writeOnScreen("Mouse middle-button pressed ", pt);
|
||||
break;
|
||||
case Common::EVENT_LBUTTONUP:
|
||||
Testsuite::clearScreen(rect);
|
||||
if (finishZone.contains(eventMan->getMousePos())) {
|
||||
quitLoop = true;
|
||||
}
|
||||
Testsuite::writeOnScreen("Mouse left-button released", pt);
|
||||
break;
|
||||
case Common::EVENT_RBUTTONUP:
|
||||
Testsuite::clearScreen(rect);
|
||||
Testsuite::writeOnScreen("Mouse right-button released", pt);
|
||||
break;
|
||||
case Common::EVENT_WHEELUP:
|
||||
Testsuite::clearScreen(rect);
|
||||
Testsuite::writeOnScreen("Mouse wheel moved up", pt);
|
||||
break;
|
||||
case Common::EVENT_MBUTTONUP:
|
||||
Testsuite::clearScreen(rect);
|
||||
Testsuite::writeOnScreen("Mouse middle-button released ", pt);
|
||||
break;
|
||||
case Common::EVENT_KEYDOWN:
|
||||
if (event.kbd.keycode == Common::KEYCODE_x) {
|
||||
Testsuite::clearScreen(rect);
|
||||
Testsuite::writeOnScreen("Exit requested", pt);
|
||||
quitLoop = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
CursorMan.showMouse(false);
|
||||
|
||||
// Verify results now!
|
||||
if (Testsuite::handleInteractiveInput("Were mouse clicks L/R/M buttons identfied?", "Yes", "No", kOptionRight)) {
|
||||
Testsuite::logDetailedPrintf("Mouse clicks (L/R/M buttons) failed");
|
||||
passed = false;
|
||||
}
|
||||
if (Testsuite::handleInteractiveInput("Were mouse wheel movements identified?", "Yes", "No", kOptionRight)) {
|
||||
Testsuite::logDetailedPrintf("Mouse wheel movements failed");
|
||||
passed = false;
|
||||
}
|
||||
|
||||
return passed;
|
||||
}
|
||||
|
||||
bool EventTests::kbdEvents() {
|
||||
|
||||
Testsuite::clearScreen();
|
||||
Common::String info = "Testing keyboard events.\n "
|
||||
"Testbed should be able to figure out any alphanumeric keystrokes made by the user and display them back.\n"
|
||||
"Press ESC key when done of the input.";
|
||||
|
||||
if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) {
|
||||
Testsuite::logPrintf("Info! Skipping test : keyboard events\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Make user type some word and display the output on screen
|
||||
Common::String text = "You Entered : ";
|
||||
Common::Point pt(0, 100);
|
||||
Testsuite::clearScreen();
|
||||
Testsuite::writeOnScreen("Enter your word, press ESC when done, it will be echoed back", pt);
|
||||
pt.y += 20;
|
||||
Common::Rect rect = Testsuite::writeOnScreen(text, pt);
|
||||
char letter;
|
||||
while ((letter = keystrokeToChar()) != 0) {
|
||||
Testsuite::clearScreen(rect);
|
||||
text += letter;
|
||||
rect = Testsuite::writeOnScreen(text, pt);
|
||||
}
|
||||
|
||||
bool passed = true;
|
||||
|
||||
if (Testsuite::handleInteractiveInput("Was the word you entered same as that displayed on screen?", "Yes", "No", kOptionRight)) {
|
||||
Testsuite::logDetailedPrintf("Keyboard Events failed");
|
||||
passed = false;
|
||||
}
|
||||
|
||||
Testsuite::clearScreen();
|
||||
return passed;
|
||||
}
|
||||
|
||||
bool EventTests::showMainMenu() {
|
||||
|
||||
Testsuite::clearScreen();
|
||||
Common::String info = "Testing Main Menu events.\n "
|
||||
"Main Menu event is normally trigerred by user pressing (Ctrl + f5).\n"
|
||||
"Click 'resume' to continue testbed.";
|
||||
|
||||
if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) {
|
||||
Testsuite::logPrintf("Info! Skipping test : Main Menu\n");
|
||||
return true;
|
||||
}
|
||||
Common::EventManager *eventMan = g_system->getEventManager();
|
||||
Common::Event mainMenuEvent;
|
||||
mainMenuEvent.type = Common::EVENT_MAINMENU;
|
||||
eventMan->pushEvent(mainMenuEvent);
|
||||
|
||||
bool passed = true;
|
||||
|
||||
if (Testsuite::handleInteractiveInput("Were you able to see a main menu widget?", "Yes", "No", kOptionRight)) {
|
||||
Testsuite::logDetailedPrintf("Event MAINMENU failed");
|
||||
passed = false;
|
||||
}
|
||||
|
||||
return passed;
|
||||
}
|
||||
|
||||
EventTestSuite::EventTestSuite() {
|
||||
addTest("MouseEvents", &EventTests::mouseEvents);
|
||||
addTest("KeyboardEvents", &EventTests::kbdEvents);
|
||||
addTest("MainmenuEvent", &EventTests::showMainMenu);
|
||||
}
|
||||
|
||||
} // End of namespace Testbed
|
67
engines/testbed/events.h
Normal file
67
engines/testbed/events.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef TESTBED_EVENTS_H
|
||||
#define TESTBED_EVENTS_H
|
||||
|
||||
#include "testbed/testsuite.h"
|
||||
|
||||
namespace Testbed {
|
||||
|
||||
namespace EventTests {
|
||||
|
||||
// Helper functions for Event tests
|
||||
char keystrokeToChar();
|
||||
Common::Rect drawFinishZone();
|
||||
// will contain function declarations for Event tests
|
||||
bool mouseEvents();
|
||||
bool kbdEvents();
|
||||
bool showMainMenu();
|
||||
// add more here
|
||||
|
||||
} // End of namespace EventTests
|
||||
|
||||
class EventTestSuite : public Testsuite {
|
||||
public:
|
||||
/**
|
||||
* The constructor for the EventTestSuite
|
||||
* For every test to be executed one must:
|
||||
* 1) Create a function that would invoke the test
|
||||
* 2) Add that test to list by executing addTest()
|
||||
*
|
||||
* @see addTest()
|
||||
*/
|
||||
EventTestSuite();
|
||||
~EventTestSuite() {}
|
||||
const char *getName() const {
|
||||
return "Events";
|
||||
}
|
||||
const char *getDescription() const {
|
||||
return "Events : Keyboard/Mouse/RTL";
|
||||
}
|
||||
};
|
||||
|
||||
} // End of namespace Testbed
|
||||
|
||||
#endif // TESTBED_EVENTS_H
|
169
engines/testbed/fs.cpp
Normal file
169
engines/testbed/fs.cpp
Normal file
|
@ -0,0 +1,169 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "common/config-manager.h"
|
||||
#include "common/stream.h"
|
||||
#include "common/util.h"
|
||||
|
||||
#include "testbed/fs.h"
|
||||
|
||||
namespace Testbed {
|
||||
|
||||
/**
|
||||
* This test does the following:
|
||||
* 1) acquires the game-data path
|
||||
* 2) In the game-root it navigates to "directory" and opens the file "file"
|
||||
*
|
||||
* The code accesses the appropriate file using the fileSystem API, creates a read stream of it and
|
||||
* compares the message contained in it, with what it expects.
|
||||
*
|
||||
*/
|
||||
bool FStests::readDataFromFile(Common::FSDirectory *directory, const char *file) {
|
||||
|
||||
Common::SeekableReadStream *readStream = directory->createReadStreamForMember(file);
|
||||
|
||||
if (!readStream) {
|
||||
Testsuite::logDetailedPrintf("Can't open game file for reading\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
Common::String msg = readStream->readLine();
|
||||
delete readStream;
|
||||
|
||||
Testsuite::logDetailedPrintf("Message Extracted from %s/%s : %s\n", directory->getFSNode().getName().c_str(), file, msg.c_str());
|
||||
|
||||
Common::String expectedMsg = "It works!";
|
||||
|
||||
if (!msg.equals(expectedMsg)) {
|
||||
Testsuite::logDetailedPrintf("Can't read Correct data from file\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FStests::testReadFile() {
|
||||
const Common::String &path = ConfMan.get("path");
|
||||
Common::FSDirectory gameRoot(path);
|
||||
int numFailed = 0;
|
||||
|
||||
if (!gameRoot.getFSNode().isDirectory()) {
|
||||
Testsuite::logDetailedPrintf("game Path should be a directory");
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *dirList[] = {"test1" ,"Test2", "TEST3" , "tEST4", "test5"};
|
||||
const char *file[] = {"file.txt", "File.txt", "FILE.txt", "fILe.txt", "file"};
|
||||
|
||||
for (unsigned int i = 0; i < ARRAYSIZE(dirList); i++) {
|
||||
Common::String dirName = dirList[i];
|
||||
Common::String fileName = file[i];
|
||||
Common::FSDirectory *directory = gameRoot.getSubDirectory(dirName);
|
||||
|
||||
if (!readDataFromFile(directory, fileName.c_str())) {
|
||||
Testsuite::logDetailedPrintf("Reading from %s/%s failed\n", dirName.c_str(), fileName.c_str());
|
||||
numFailed++;
|
||||
}
|
||||
|
||||
dirName.toLowercase();
|
||||
fileName.toLowercase();
|
||||
delete directory;
|
||||
directory = gameRoot.getSubDirectory(dirName);
|
||||
|
||||
if (!readDataFromFile(directory, fileName.c_str())) {
|
||||
Testsuite::logDetailedPrintf("Reading from %s/%s failed\n", dirName.c_str(), fileName.c_str());
|
||||
numFailed++;
|
||||
}
|
||||
|
||||
dirName.toUppercase();
|
||||
fileName.toUppercase();
|
||||
delete directory;
|
||||
directory = gameRoot.getSubDirectory(dirName);
|
||||
|
||||
if (!readDataFromFile(directory, fileName.c_str())) {
|
||||
Testsuite::logDetailedPrintf("Reading from %s/%s failed\n", dirName.c_str(), fileName.c_str());
|
||||
numFailed++;
|
||||
}
|
||||
delete directory;
|
||||
}
|
||||
|
||||
Testsuite::logDetailedPrintf("Failed %d out of 15\n", numFailed);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This test creates a file testbed.out, writes a sample data and confirms if
|
||||
* it is same by reading the file again.
|
||||
*/
|
||||
bool FStests::testWriteFile() {
|
||||
const Common::String &path = ConfMan.get("path");
|
||||
Common::FSNode gameRoot(path);
|
||||
|
||||
Common::FSNode fileToWrite = gameRoot.getChild("testbed.out");
|
||||
|
||||
Common::WriteStream *ws = fileToWrite.createWriteStream();
|
||||
|
||||
if (!ws) {
|
||||
Testsuite::logDetailedPrintf("Can't open writable file in game data dir\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
ws->writeString("ScummVM Rocks!");
|
||||
ws->flush();
|
||||
delete ws;
|
||||
|
||||
Common::SeekableReadStream *rs = fileToWrite.createReadStream();
|
||||
Common::String readFromFile = rs->readLine();
|
||||
delete rs;
|
||||
|
||||
if (readFromFile.equals("ScummVM Rocks!")) {
|
||||
// All good
|
||||
Testsuite::logDetailedPrintf("Data written and read correctly\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
FSTestSuite::FSTestSuite() {
|
||||
addTest("ReadingFile", &FStests::testReadFile, false);
|
||||
addTest("WritingFile", &FStests::testWriteFile, false);
|
||||
}
|
||||
|
||||
void FSTestSuite::enable(bool flag) {
|
||||
const Common::String &path = ConfMan.get("path");
|
||||
Common::FSNode gameRoot(path);
|
||||
|
||||
Common::FSNode gameIdentificationFile = gameRoot.getChild("TESTBED");
|
||||
if (!gameIdentificationFile.exists()) {
|
||||
logPrintf("WARNING! : Game Data not found. Skipping FS tests\n");
|
||||
Testsuite::enable(false);
|
||||
return;
|
||||
}
|
||||
Testsuite::enable(flag);
|
||||
}
|
||||
|
||||
} // End of namespace Testbed
|
74
engines/testbed/fs.h
Normal file
74
engines/testbed/fs.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef TESTBED_FS_H
|
||||
#define TESTBED_FS_H
|
||||
|
||||
#include "common/fs.h"
|
||||
|
||||
#include "testbed/testsuite.h"
|
||||
|
||||
namespace Testbed {
|
||||
|
||||
namespace FStests {
|
||||
|
||||
// Note: These tests require a game-data directory
|
||||
// So would work if game-path is set in the launcher or invoked as ./scummvm --path="path-to-testbed-data" testbed
|
||||
// from commandline
|
||||
|
||||
// Helper functions for FS tests
|
||||
bool readDataFromFile(Common::FSDirectory *directory, const char *file);
|
||||
|
||||
// will contain function declarations for FS tests
|
||||
bool testReadFile();
|
||||
bool testWriteFile();
|
||||
bool testOpeningSaveFile();
|
||||
// add more here
|
||||
|
||||
} // End of namespace FStests
|
||||
|
||||
class FSTestSuite : public Testsuite {
|
||||
public:
|
||||
/**
|
||||
* The constructor for the FSTestSuite
|
||||
* For every test to be executed one must:
|
||||
* 1) Create a function that would invoke the test
|
||||
* 2) Add that test to list by executing addTest()
|
||||
*
|
||||
* @see addTest()
|
||||
*/
|
||||
FSTestSuite();
|
||||
~FSTestSuite() {}
|
||||
const char *getName() const {
|
||||
return "FS";
|
||||
}
|
||||
const char *getDescription() const {
|
||||
return "File system tests (Navigation, Read/Write)";
|
||||
}
|
||||
void enable(bool flag);
|
||||
};
|
||||
|
||||
} // End of namespace Testbed
|
||||
|
||||
#endif // TESTBED_FS_H
|
1102
engines/testbed/graphics.cpp
Normal file
1102
engines/testbed/graphics.cpp
Normal file
File diff suppressed because it is too large
Load diff
94
engines/testbed/graphics.h
Normal file
94
engines/testbed/graphics.h
Normal file
|
@ -0,0 +1,94 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef TESTBED_GRAPHICS_H
|
||||
#define TESTBED_GRAPHICS_H
|
||||
|
||||
#include "testbed/testsuite.h"
|
||||
|
||||
namespace Testbed {
|
||||
|
||||
namespace GFXtests {
|
||||
|
||||
// Helper functions for GFX tests
|
||||
void drawEllipse(int x, int y, int a, int b);
|
||||
void setupMouseLoop(bool disableCursorPalette = false, const char *gfxModeName = "", int cursorTargetScale = 1);
|
||||
void initMousePalette();
|
||||
Common::Rect computeSize(Common::Rect &cursorRect, int scalingFactor, int cursorTargetScale);
|
||||
void HSVtoRGB(int &rComp, int &gComp, int &bComp, int hue, int sat, int val);
|
||||
Common::Rect drawCursor(bool cursorPaletteDisabled = false, const char *gfxModeName = "", int cursorTargetScale = 1);
|
||||
|
||||
// will contain function declarations for GFX tests
|
||||
bool cursorTrails();
|
||||
bool fullScreenMode();
|
||||
bool aspectRatio();
|
||||
bool palettizedCursors();
|
||||
bool mouseMovements();
|
||||
bool copyRectToScreen();
|
||||
bool iconifyWindow();
|
||||
bool scaledCursors();
|
||||
bool shakingEffect();
|
||||
bool focusRectangle();
|
||||
bool overlayGraphics();
|
||||
bool paletteRotation();
|
||||
bool pixelFormats();
|
||||
// add more here
|
||||
|
||||
} // End of namespace GFXtests
|
||||
|
||||
class GFXTestSuite : public Testsuite {
|
||||
public:
|
||||
/**
|
||||
* The constructor for the GFXTestSuite
|
||||
* For every test to be executed one must:
|
||||
* 1) Create a function that would invoke the test
|
||||
* 2) Add that test to list by executing addTest()
|
||||
*
|
||||
* @see addTest()
|
||||
*/
|
||||
GFXTestSuite();
|
||||
~GFXTestSuite() {}
|
||||
const char *getName() const {
|
||||
return "GFX";
|
||||
}
|
||||
const char *getDescription() const {
|
||||
return "Graphics Subsystem";
|
||||
}
|
||||
static void setCustomColor(uint r, uint g, uint b);
|
||||
|
||||
private:
|
||||
/**
|
||||
* A Palette consists of 4 components RGBA.
|
||||
* As of now we only take 3 colors
|
||||
* 0 (R:0, G:0, B:0) Black (kColorBlack)
|
||||
* 1 (R:255, G:255, B:255) White (kColorWhite)
|
||||
* 2 (R:255, G:255, B:255) your customized color (by default white) (kColorCustom)
|
||||
* The remaining values are zero
|
||||
*/
|
||||
static byte _palette[256 * 4];
|
||||
};
|
||||
|
||||
} // End of namespace Testbed
|
||||
|
||||
#endif // TESTBED_GRAPHICS_H
|
172
engines/testbed/misc.cpp
Normal file
172
engines/testbed/misc.cpp
Normal file
|
@ -0,0 +1,172 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "testbed/misc.h"
|
||||
#include "common/timer.h"
|
||||
|
||||
namespace Testbed {
|
||||
|
||||
Common::String MiscTests::getHumanReadableFormat(TimeDate &td) {
|
||||
return Common::String::printf("%d:%d:%d on %d/%d/%d (dd/mm/yyyy)", td.tm_hour, td.tm_min, td.tm_sec, td.tm_mday, td.tm_mon + 1, td.tm_year + 1900);
|
||||
}
|
||||
|
||||
void MiscTests::timerCallback(void *arg) {
|
||||
// Increment arg which actually points to an int
|
||||
// arg must point to a static data, threads otherwise have their own stack
|
||||
int &valToModify = *((int *) arg);
|
||||
valToModify = 999; // some arbitrary value
|
||||
}
|
||||
|
||||
void MiscTests::criticalSection(void *arg) {
|
||||
SharedVars &sv = *((SharedVars *)arg);
|
||||
|
||||
Testsuite::logDetailedPrintf("Before critical section: %d %d\n", sv.first, sv.second);
|
||||
g_system->lockMutex(sv.mutex);
|
||||
|
||||
// In any case, the two vars must be equal at entry, if mutex works fine.
|
||||
// verify this here.
|
||||
if (sv.first != sv.second) {
|
||||
sv.resultSoFar = false;
|
||||
}
|
||||
|
||||
sv.first++;
|
||||
g_system->delayMillis(1000);
|
||||
|
||||
// This should bring no change as well in the difference between vars
|
||||
// verify this too.
|
||||
if (sv.second + 1 != sv.first) {
|
||||
sv.resultSoFar = false;
|
||||
}
|
||||
|
||||
sv.second *= sv.first;
|
||||
Testsuite::logDetailedPrintf("After critical section: %d %d\n", sv.first, sv.second);
|
||||
g_system->unlockMutex(sv.mutex);
|
||||
|
||||
g_system->getTimerManager()->removeTimerProc(criticalSection);
|
||||
}
|
||||
|
||||
bool MiscTests::testDateTime() {
|
||||
|
||||
if (Testsuite::isSessionInteractive) {
|
||||
if (Testsuite::handleInteractiveInput("Testing the date time API implementation", "Continue", "Skip", kOptionRight)) {
|
||||
Testsuite::logPrintf("Info! Date time tests skipped by the user.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
Testsuite::writeOnScreen("Verifying Date-Time...", Common::Point(0, 100));
|
||||
}
|
||||
|
||||
TimeDate t1, t2;
|
||||
g_system->getTimeAndDate(t1);
|
||||
Testsuite::logDetailedPrintf("Current Time and Date: ");
|
||||
Common::String dateTimeNow;
|
||||
dateTimeNow = getHumanReadableFormat(t1);
|
||||
|
||||
if (Testsuite::isSessionInteractive) {
|
||||
// Directly verify date
|
||||
dateTimeNow = "We expect the current date time to be " + dateTimeNow;
|
||||
if (Testsuite::handleInteractiveInput(dateTimeNow, "Correct!", "Wrong", kOptionRight)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
g_system->getTimeAndDate(t1);
|
||||
dateTimeNow = getHumanReadableFormat(t1);
|
||||
Testsuite::logDetailedPrintf("%s\n", dateTimeNow.c_str());
|
||||
// Now, Put some delay
|
||||
g_system->delayMillis(2000);
|
||||
g_system->getTimeAndDate(t2);
|
||||
Testsuite::logDetailedPrintf("Time and Date 2s later: ");
|
||||
dateTimeNow = getHumanReadableFormat(t2);
|
||||
Testsuite::logDetailedPrintf("%s\n", dateTimeNow.c_str());
|
||||
|
||||
if (t1.tm_year == t2.tm_year && t1.tm_mon == t2.tm_mon && t1.tm_mday == t2.tm_mday) {
|
||||
if (t1.tm_mon == t2.tm_mon && t1.tm_year == t2.tm_year) {
|
||||
// Ignore lag due to processing time
|
||||
if (t1.tm_sec + 2 == t2.tm_sec) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MiscTests::testTimers() {
|
||||
static int valToModify = 0;
|
||||
if (g_system->getTimerManager()->installTimerProc(timerCallback, 100000, &valToModify)) {
|
||||
g_system->delayMillis(150);
|
||||
g_system->getTimerManager()->removeTimerProc(timerCallback);
|
||||
|
||||
if (999 == valToModify) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MiscTests::testMutexes() {
|
||||
|
||||
if (Testsuite::isSessionInteractive) {
|
||||
if (Testsuite::handleInteractiveInput("Testing the Mutual Exclusion API implementation", "Continue", "Skip", kOptionRight)) {
|
||||
Testsuite::logPrintf("Info! Mutex tests skipped by the user.\n");
|
||||
return true;
|
||||
}
|
||||
Testsuite::writeOnScreen("Installing mutex", Common::Point(0, 100));
|
||||
}
|
||||
|
||||
static SharedVars sv = {1, 1, true, g_system->createMutex()};
|
||||
|
||||
if (g_system->getTimerManager()->installTimerProc(criticalSection, 100000, &sv)) {
|
||||
g_system->delayMillis(150);
|
||||
}
|
||||
|
||||
g_system->lockMutex(sv.mutex);
|
||||
sv.first++;
|
||||
g_system->delayMillis(1000);
|
||||
sv.second *= sv.first;
|
||||
g_system->unlockMutex(sv.mutex);
|
||||
|
||||
// wait till timed process exits
|
||||
if (Testsuite::isSessionInteractive) {
|
||||
Testsuite::writeOnScreen("Waiting for 3s so that timed processes finish", Common::Point(0, 100));
|
||||
}
|
||||
g_system->delayMillis(3000);
|
||||
|
||||
Testsuite::logDetailedPrintf("Final Value: %d %d\n", sv.first, sv.second);
|
||||
g_system->deleteMutex(sv.mutex);
|
||||
|
||||
if (sv.resultSoFar && 6 == sv.second) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
MiscTestSuite::MiscTestSuite() {
|
||||
addTest("Datetime", &MiscTests::testDateTime, false);
|
||||
addTest("Timers", &MiscTests::testTimers, false);
|
||||
addTest("Mutexes", &MiscTests::testMutexes, false);
|
||||
}
|
||||
|
||||
} // End of namespace Testbed
|
80
engines/testbed/misc.h
Normal file
80
engines/testbed/misc.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef TESTBED_MISC_H
|
||||
#define TESTBED_MISC_H
|
||||
|
||||
#include "testbed/testsuite.h"
|
||||
|
||||
|
||||
namespace Testbed {
|
||||
|
||||
// Shared variables used in mutex handling test
|
||||
struct SharedVars {
|
||||
int first;
|
||||
int second;
|
||||
bool resultSoFar;
|
||||
OSystem::MutexRef mutex;
|
||||
};
|
||||
|
||||
namespace MiscTests {
|
||||
|
||||
// Miscellaneous tests include testing datetime, timers and mutexes
|
||||
|
||||
// Helper functions for Misc tests
|
||||
Common::String getHumanReadableFormat(TimeDate &td);
|
||||
void timerCallback(void *arg);
|
||||
void criticalSection(void *arg);
|
||||
|
||||
// will contain function declarations for Misc tests
|
||||
bool testDateTime();
|
||||
bool testTimers();
|
||||
bool testMutexes();
|
||||
// add more here
|
||||
|
||||
} // End of namespace MiscTests
|
||||
|
||||
class MiscTestSuite : public Testsuite {
|
||||
public:
|
||||
/**
|
||||
* The constructor for the MiscTestSuite
|
||||
* For every test to be executed one must:
|
||||
* 1) Create a function that would invoke the test
|
||||
* 2) Add that test to list by executing addTest()
|
||||
*
|
||||
* @see addTest()
|
||||
*/
|
||||
MiscTestSuite();
|
||||
~MiscTestSuite() {}
|
||||
const char *getName() const {
|
||||
return "Misc";
|
||||
}
|
||||
const char *getDescription() const {
|
||||
return "Miscellaneous: Timers/Mutexes/Datetime";
|
||||
}
|
||||
};
|
||||
|
||||
} // End of namespace Testbed
|
||||
|
||||
#endif // TESTBED_MISC_H
|
24
engines/testbed/module.mk
Normal file
24
engines/testbed/module.mk
Normal file
|
@ -0,0 +1,24 @@
|
|||
MODULE := engines/testbed
|
||||
|
||||
MODULE_OBJS := \
|
||||
config.o \
|
||||
detection.o \
|
||||
events.o \
|
||||
fs.o \
|
||||
graphics.o \
|
||||
misc.o \
|
||||
savegame.o \
|
||||
sound.o \
|
||||
testbed.o \
|
||||
testsuite.o
|
||||
|
||||
MODULE_DIRS += \
|
||||
engines/testbed
|
||||
|
||||
# This module can be built as a plugin
|
||||
ifeq ($(ENABLE_TESTBED), DYNAMIC_PLUGIN)
|
||||
PLUGIN := 1
|
||||
endif
|
||||
|
||||
# Include common rules
|
||||
include $(srcdir)/rules.mk
|
199
engines/testbed/savegame.cpp
Normal file
199
engines/testbed/savegame.cpp
Normal file
|
@ -0,0 +1,199 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "common/savefile.h"
|
||||
|
||||
#include "testbed/savegame.h"
|
||||
|
||||
namespace Testbed {
|
||||
|
||||
/**
|
||||
* This test creates a savefile for the given testbed-state and could be reloaded using the saveFile API.
|
||||
* It is intended to test saving and loading from savefiles.
|
||||
*/
|
||||
bool SaveGametests::writeDataToFile(const char *fileName, const char *msg) {
|
||||
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
|
||||
Common::OutSaveFile *saveFile = saveFileMan->openForSaving(fileName);
|
||||
|
||||
if (!saveFile) {
|
||||
Testsuite::logDetailedPrintf("Can't open saveFile %s\n", fileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
saveFile->writeString(msg);
|
||||
saveFile->finalize();
|
||||
delete saveFile;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SaveGametests::readAndVerifyData(const char *fileName, const char *expected) {
|
||||
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
|
||||
Common::InSaveFile *loadFile = saveFileMan->openForLoading(fileName);
|
||||
|
||||
if (!loadFile) {
|
||||
Testsuite::logDetailedPrintf("Can't open save File to load\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
Common::String lineToRead = loadFile->readLine();
|
||||
delete loadFile;
|
||||
|
||||
if (lineToRead.equals(expected)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SaveGametests::testSaveLoadState() {
|
||||
// create a savefile with "ScummVM Rocks!" written on it
|
||||
if (!writeDataToFile("tBedSavefile.0", "ScummVM Rocks!")) {
|
||||
Testsuite::logDetailedPrintf("Writing data to savefile failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verify if it contains the same data
|
||||
if (!readAndVerifyData("tBedSavefile.0", "ScummVM Rocks!")) {
|
||||
Testsuite::logDetailedPrintf("Reading data from savefile failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SaveGametests::testRemovingSavefile() {
|
||||
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
|
||||
|
||||
// Create a dummy savefile
|
||||
if (!writeDataToFile("tBedSavefileToRemove.0", "Dummy Savefile!")) {
|
||||
Testsuite::logDetailedPrintf("Writing data to savefile failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove it
|
||||
saveFileMan->removeSavefile("tBedSavefileToRemove.0");
|
||||
|
||||
// Try opening it Now
|
||||
Common::InSaveFile *loadFile = saveFileMan->openForLoading("saveFile.0");
|
||||
if (loadFile) {
|
||||
// Removing failed
|
||||
Testsuite::logDetailedPrintf("Removing savefile failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SaveGametests::testRenamingSavefile() {
|
||||
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
|
||||
// Open a file for renaming
|
||||
if (!writeDataToFile("tBedSomeWeirdName.0", "Rename me!")) {
|
||||
Testsuite::logDetailedPrintf("Writing data to savefile failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Rename it
|
||||
saveFileMan->renameSavefile("tBedSomeWeirdName.0", "tBedSomeCoolName.0");
|
||||
|
||||
// Verify if it contains the same data
|
||||
if (!readAndVerifyData("tBedSomeCoolName.0", "Rename me!")) {
|
||||
Testsuite::logDetailedPrintf("Renaming savefile failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SaveGametests::testListingSavefile() {
|
||||
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
|
||||
saveFileMan->clearError();
|
||||
|
||||
// create some savefiles
|
||||
const char *savefileName[] = {"tBedSavefileToList.0", "tBedSavefileToList.1", "tBedSavefileToList.2"};
|
||||
writeDataToFile("tBedSavefileToList.0", "Save me!");
|
||||
writeDataToFile("tBedSavefileToList.1", "Save me!");
|
||||
writeDataToFile("tBedSavefileToList.2", "Save me!");
|
||||
|
||||
Common::Error error = saveFileMan->getError();
|
||||
|
||||
if (error != Common::kNoError) {
|
||||
// Abort. Some Error in writing files
|
||||
Testsuite::logDetailedPrintf("Error while creating savefiles: %s\n", Common::errorToString(error));
|
||||
return false;
|
||||
}
|
||||
|
||||
Common::StringArray savefileList = saveFileMan->listSavefiles("tBedSavefileToList.?");
|
||||
if (savefileList.size() == ARRAYSIZE(savefileName)) {
|
||||
// Match them exactly
|
||||
// As the order of savefileList may be platform specific, match them exhaustively
|
||||
for (uint i = 0; i < ARRAYSIZE(savefileName); i++) {
|
||||
for (uint j = 0; j < savefileList.size(); j++) {
|
||||
if (savefileList[j].equals(savefileName[i])) {
|
||||
break;
|
||||
}
|
||||
if (savefileList.size() == j) {
|
||||
// A match for this name not found
|
||||
Testsuite::logDetailedPrintf("Listed Names don't match\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
Testsuite::logDetailedPrintf("listing Savefiles failed!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SaveGametests::testErrorMessages() {
|
||||
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
|
||||
saveFileMan->clearError();
|
||||
|
||||
// Try opening a non existing file
|
||||
readAndVerifyData("tBedSomeNonExistentSaveFile.0", "File doesn't exists!");
|
||||
|
||||
Common::Error error = saveFileMan->getError();
|
||||
if (error == Common::kNoError) {
|
||||
// blunder! how come?
|
||||
Testsuite::logDetailedPrintf("SaveFileMan.getError() failed\n");
|
||||
return false;
|
||||
}
|
||||
// Can't actually predict whether which error, kInvalidPath or kPathDoesNotExist or some other?
|
||||
// So just return true if some error
|
||||
Testsuite::logDetailedPrintf("getError returned : %s\n", saveFileMan->getErrorDesc().c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
SaveGameTestSuite::SaveGameTestSuite() {
|
||||
addTest("OpeningSaveFile", &SaveGametests::testSaveLoadState, false);
|
||||
addTest("RemovingSaveFile", &SaveGametests::testRemovingSavefile, false);
|
||||
addTest("RenamingSaveFile", &SaveGametests::testRenamingSavefile, false);
|
||||
addTest("ListingSaveFile", &SaveGametests::testListingSavefile, false);
|
||||
addTest("VerifyErrorMessages", &SaveGametests::testErrorMessages, false);
|
||||
}
|
||||
|
||||
} // End of namespace Testbed
|
69
engines/testbed/savegame.h
Normal file
69
engines/testbed/savegame.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef TESTBED_SAVEGAME_H
|
||||
#define TESTBED_SAVEGAME_H
|
||||
|
||||
#include "testbed/testsuite.h"
|
||||
|
||||
namespace Testbed {
|
||||
|
||||
namespace SaveGametests {
|
||||
|
||||
// Helper functions for SaveGame tests
|
||||
bool writeDataToFile(const char *fileName, const char *msg);
|
||||
bool readAndVerifyData(const char *fileName, const char *expected);
|
||||
// will contain function declarations for SaveGame tests
|
||||
bool testSaveLoadState();
|
||||
bool testRemovingSavefile();
|
||||
bool testRenamingSavefile();
|
||||
bool testListingSavefile();
|
||||
bool testErrorMessages();
|
||||
// add more here
|
||||
|
||||
} // End of namespace SaveGametests
|
||||
|
||||
class SaveGameTestSuite : public Testsuite {
|
||||
public:
|
||||
/**
|
||||
* The constructor for the SaveGameTestSuite
|
||||
* For every test to be executed one must:
|
||||
* 1) Create a function that would invoke the test
|
||||
* 2) Add that test to list by executing addTest()
|
||||
*
|
||||
* @see addTest()
|
||||
*/
|
||||
SaveGameTestSuite();
|
||||
~SaveGameTestSuite() {}
|
||||
const char *getName() const {
|
||||
return "SaveGames";
|
||||
}
|
||||
const char *getDescription() const {
|
||||
return "Saving Game state tests";
|
||||
}
|
||||
};
|
||||
|
||||
} // End of namespace Testbed
|
||||
|
||||
#endif // TESTBED_SAVEGAME_H
|
264
engines/testbed/sound.cpp
Normal file
264
engines/testbed/sound.cpp
Normal file
|
@ -0,0 +1,264 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "sound/audiocd.h"
|
||||
#include "sound/softsynth/pcspk.h"
|
||||
|
||||
#include "testbed/sound.h"
|
||||
|
||||
namespace Testbed {
|
||||
|
||||
enum {
|
||||
kPlayChannel1 = 'pch1',
|
||||
kPlayChannel2 = 'pch2',
|
||||
kPlayChannel3 = 'pch3',
|
||||
kPauseChannel1 = 'pac1',
|
||||
kPauseChannel2 = 'pac2',
|
||||
kPauseChannel3 = 'pac3'
|
||||
};
|
||||
|
||||
SoundSubsystemDialog::SoundSubsystemDialog() : TestbedInteractionDialog(80, 60, 400, 170) {
|
||||
_xOffset = 25;
|
||||
_yOffset = 0;
|
||||
Common::String text = "Sound Subsystem Tests: Test Mixing of Audio Streams.";
|
||||
addText(350, 20, text, Graphics::kTextAlignCenter, _xOffset, 15);
|
||||
addButton(200, 20, "Play Channel #1", kPlayChannel1);
|
||||
addButton(200, 20, "Play Channel #2", kPlayChannel2);
|
||||
addButton(200, 20, "Play Channel #3", kPlayChannel3);
|
||||
addButton(50, 20, "Close", GUI::kCloseCmd, 160, 15);
|
||||
|
||||
_mixer = g_system->getMixer();
|
||||
|
||||
// the three streams to be mixed
|
||||
Audio::PCSpeaker *s1 = new Audio::PCSpeaker();
|
||||
Audio::PCSpeaker *s2 = new Audio::PCSpeaker();
|
||||
Audio::PCSpeaker *s3 = new Audio::PCSpeaker();
|
||||
|
||||
s1->play(Audio::PCSpeaker::kWaveFormSine, 1000, -1);
|
||||
s2->play(Audio::PCSpeaker::kWaveFormSine, 1200, -1);
|
||||
s3->play(Audio::PCSpeaker::kWaveFormSine, 1400, -1);
|
||||
|
||||
_mixer->playStream(Audio::Mixer::kPlainSoundType, &_h1, s1);
|
||||
_mixer->pauseHandle(_h1, true);
|
||||
|
||||
_mixer->playStream(Audio::Mixer::kSpeechSoundType, &_h2, s2);
|
||||
_mixer->pauseHandle(_h2, true);
|
||||
|
||||
_mixer->playStream(Audio::Mixer::kSFXSoundType, &_h3, s3);
|
||||
_mixer->pauseHandle(_h3, true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void SoundSubsystemDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) {
|
||||
|
||||
switch (cmd) {
|
||||
case kPlayChannel1:
|
||||
_buttonArray[0]->setLabel("Pause Channel #1");
|
||||
_buttonArray[0]->setCmd(kPauseChannel1);
|
||||
_mixer->pauseHandle(_h1, false);
|
||||
break;
|
||||
case kPlayChannel2:
|
||||
_buttonArray[1]->setLabel("Pause Channel #2");
|
||||
_buttonArray[1]->setCmd(kPauseChannel2);
|
||||
_mixer->pauseHandle(_h2, false);
|
||||
break;
|
||||
case kPlayChannel3:
|
||||
_buttonArray[2]->setLabel("Pause Channel #3");
|
||||
_buttonArray[2]->setCmd(kPauseChannel3);
|
||||
_mixer->pauseHandle(_h3, false);
|
||||
break;
|
||||
case kPauseChannel1:
|
||||
_buttonArray[0]->setLabel("Play Channel #1");
|
||||
_buttonArray[0]->setCmd(kPlayChannel1);
|
||||
_mixer->pauseHandle(_h1, true);
|
||||
break;
|
||||
case kPauseChannel2:
|
||||
_buttonArray[1]->setLabel("Play Channel #2");
|
||||
_buttonArray[1]->setCmd(kPlayChannel2);
|
||||
_mixer->pauseHandle(_h2, true);
|
||||
break;
|
||||
case kPauseChannel3:
|
||||
_buttonArray[2]->setLabel("Play Channel #3");
|
||||
_buttonArray[2]->setCmd(kPlayChannel3);
|
||||
_mixer->pauseHandle(_h3, true);
|
||||
break;
|
||||
default:
|
||||
_mixer->stopAll();
|
||||
GUI::Dialog::handleCommand(sender, cmd, data);
|
||||
}
|
||||
}
|
||||
|
||||
bool SoundSubsystem::playBeeps() {
|
||||
Testsuite::clearScreen();
|
||||
bool passed = true;
|
||||
Common::String info = "Testing Sound Output by generating beeps\n"
|
||||
"You should hear a left beep followed by a right beep\n";
|
||||
|
||||
if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) {
|
||||
Testsuite::logPrintf("Info! Skipping test : Play Beeps\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
Audio::PCSpeaker *speaker = new Audio::PCSpeaker();
|
||||
Audio::Mixer *mixer = g_system->getMixer();
|
||||
Audio::SoundHandle handle;
|
||||
mixer->playStream(Audio::Mixer::kPlainSoundType, &handle, speaker);
|
||||
|
||||
// Left Beep
|
||||
Testsuite::writeOnScreen("Left Beep", Common::Point(0, 100));
|
||||
mixer->setChannelBalance(handle, -127);
|
||||
speaker->play(Audio::PCSpeaker::kWaveFormSine, 1000, -1);
|
||||
g_system->delayMillis(500);
|
||||
mixer->pauseHandle(handle, true);
|
||||
|
||||
if (Testsuite::handleInteractiveInput("Were you able to hear the left beep?", "Yes", "No", kOptionRight)) {
|
||||
Testsuite::logDetailedPrintf("Error! Left Beep couldn't be detected : Error with Mixer::setChannelBalance()\n");
|
||||
passed = false;
|
||||
}
|
||||
|
||||
// Right Beep
|
||||
Testsuite::writeOnScreen("Right Beep", Common::Point(0, 100));
|
||||
mixer->setChannelBalance(handle, 127);
|
||||
mixer->pauseHandle(handle, false);
|
||||
g_system->delayMillis(500);
|
||||
mixer->stopAll();
|
||||
|
||||
if (Testsuite::handleInteractiveInput("Were you able to hear the right beep?", "Yes", "No", kOptionRight)) {
|
||||
Testsuite::logDetailedPrintf("Error! Right Beep couldn't be detected : Error with Mixer::setChannelBalance()\n");
|
||||
passed = false;
|
||||
}
|
||||
return passed;
|
||||
}
|
||||
|
||||
bool SoundSubsystem::mixSounds() {
|
||||
Testsuite::clearScreen();
|
||||
bool passed = true;
|
||||
Common::String info = "Testing Mixer Output by generating multichannel sound output using PC speaker emulator.\n"
|
||||
"The mixer should be able to play them simultaneously\n";
|
||||
|
||||
if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) {
|
||||
Testsuite::logPrintf("Info! Skipping test : Mix Sounds\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
SoundSubsystemDialog sDialog;
|
||||
sDialog.runModal();
|
||||
if (Testsuite::handleInteractiveInput("Was the mixer able to simultaneously play multiple channels?", "Yes", "No", kOptionRight)) {
|
||||
Testsuite::logDetailedPrintf("Error! Multiple channels couldn't be played : Error with Mixer Class\n");
|
||||
passed = false;
|
||||
}
|
||||
return passed;
|
||||
}
|
||||
|
||||
bool SoundSubsystem::audiocdOutput() {
|
||||
Testsuite::clearScreen();
|
||||
bool passed = true;
|
||||
Common::String info = "Testing AudioCD API implementation.\n"
|
||||
"Here we have four tracks, we play them in order i.e 1-2-3-last.\n"
|
||||
"The user should verify if the tracks were run in correct order or not.";
|
||||
|
||||
if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) {
|
||||
Testsuite::logPrintf("Info! Skipping test : AudioCD API\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
Common::Point pt(0, 100);
|
||||
Testsuite::writeOnScreen("Playing the tracks of testCD in order i.e 1-2-3-last", pt);
|
||||
|
||||
// Make audio-files discoverable
|
||||
Common::FSNode gameRoot(ConfMan.get("path"));
|
||||
SearchMan.addSubDirectoryMatching(gameRoot, "audiocd-files");
|
||||
|
||||
// Play all tracks
|
||||
for (int i = 1; i < 5; i++) {
|
||||
AudioCD.play(i, 1, 0, 0);
|
||||
while (AudioCD.isPlaying()) {
|
||||
g_system->delayMillis(500);
|
||||
Testsuite::writeOnScreen(Common::String::printf("Playing Now: track%02d", i), pt);
|
||||
}
|
||||
g_system->delayMillis(500);
|
||||
}
|
||||
|
||||
Testsuite::clearScreen();
|
||||
if (Testsuite::handleInteractiveInput("Were all the tracks played in order i.e 1-2-3-last ?", "Yes", "No", kOptionRight)) {
|
||||
Testsuite::logPrintf("Error! Error in AudioCD.play() or probably sound files were not detected, try -d1 (debuglevel 1)\n");
|
||||
passed = false;
|
||||
}
|
||||
|
||||
return passed;
|
||||
}
|
||||
|
||||
bool SoundSubsystem::sampleRates() {
|
||||
bool passed = true;
|
||||
Audio::Mixer *mixer = g_system->getMixer();
|
||||
|
||||
Audio::PCSpeaker *s1 = new Audio::PCSpeaker();
|
||||
// Stream at half sampling rate
|
||||
Audio::PCSpeaker *s2 = new Audio::PCSpeaker(s1->getRate() - 10000);
|
||||
// Stream at twice sampling rate
|
||||
Audio::PCSpeaker *s3 = new Audio::PCSpeaker(s1->getRate() + 10000);
|
||||
|
||||
s1->play(Audio::PCSpeaker::kWaveFormSine, 1000, -1);
|
||||
s2->play(Audio::PCSpeaker::kWaveFormSine, 1000, -1);
|
||||
s3->play(Audio::PCSpeaker::kWaveFormSine, 1000, -1);
|
||||
|
||||
Audio::SoundHandle handle;
|
||||
Common::Point pt(0, 100);
|
||||
|
||||
mixer->playStream(Audio::Mixer::kPlainSoundType, &handle, s1);
|
||||
Testsuite::writeOnScreen(Common::String::printf("Playing at smaple rate: %d", s1->getRate()), pt);
|
||||
g_system->delayMillis(1000);
|
||||
mixer->stopHandle(handle);
|
||||
g_system->delayMillis(1000);
|
||||
|
||||
mixer->playStream(Audio::Mixer::kSpeechSoundType, &handle, s2);
|
||||
Testsuite::writeOnScreen(Common::String::printf("Playing at sample rate : %d", s2->getRate()), pt);
|
||||
g_system->delayMillis(1000);
|
||||
mixer->stopHandle(handle);
|
||||
g_system->delayMillis(1000);
|
||||
|
||||
mixer->playStream(Audio::Mixer::kSFXSoundType, &handle, s3);
|
||||
Testsuite::writeOnScreen(Common::String::printf("Playing at sample rate : %d", s3->getRate()), pt);
|
||||
g_system->delayMillis(1000);
|
||||
mixer->stopHandle(handle);
|
||||
g_system->delayMillis(1000);
|
||||
|
||||
Testsuite::clearScreen();
|
||||
if (Testsuite::handleInteractiveInput("Was the mixer able to play beeps with variable sample rates?", "Yes", "No", kOptionRight)) {
|
||||
Testsuite::logDetailedPrintf("Error! Error with variable sample rates\n");
|
||||
passed = false;
|
||||
}
|
||||
|
||||
return passed;
|
||||
}
|
||||
|
||||
SoundSubsystemTestSuite::SoundSubsystemTestSuite() {
|
||||
addTest("SimpleBeeps", &SoundSubsystem::playBeeps, true);
|
||||
addTest("MixSounds", &SoundSubsystem::mixSounds, true);
|
||||
addTest("AudiocdOutput", &SoundSubsystem::audiocdOutput, true);
|
||||
addTest("SampleRates", &SoundSubsystem::sampleRates, true);
|
||||
}
|
||||
|
||||
} // End of namespace Testbed
|
80
engines/testbed/sound.h
Normal file
80
engines/testbed/sound.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef TESTBED_SOUND_H
|
||||
#define TESTBED_SOUND_H
|
||||
|
||||
#include "gui/dialog.h"
|
||||
#include "sound/mixer.h"
|
||||
#include "testbed/config.h"
|
||||
#include "testbed/testsuite.h"
|
||||
|
||||
namespace Testbed {
|
||||
|
||||
class SoundSubsystemDialog : public TestbedInteractionDialog {
|
||||
public:
|
||||
SoundSubsystemDialog();
|
||||
~SoundSubsystemDialog() {}
|
||||
void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data);
|
||||
Audio::Mixer *_mixer;
|
||||
Audio::SoundHandle _h1, _h2, _h3;
|
||||
};
|
||||
|
||||
namespace SoundSubsystem {
|
||||
|
||||
// Helper functions for SoundSubsystem tests
|
||||
|
||||
// will contain function declarations for SoundSubsystem tests
|
||||
bool playBeeps();
|
||||
bool mixSounds();
|
||||
bool audiocdOutput();
|
||||
bool sampleRates();
|
||||
}
|
||||
|
||||
class SoundSubsystemTestSuite : public Testsuite {
|
||||
public:
|
||||
/**
|
||||
* The constructor for the SoundSubsystemTestSuite
|
||||
* For every test to be executed one must:
|
||||
* 1) Create a function that would invoke the test
|
||||
* 2) Add that test to list by executing addTest()
|
||||
*
|
||||
* @see addTest()
|
||||
*/
|
||||
SoundSubsystemTestSuite();
|
||||
~SoundSubsystemTestSuite() {}
|
||||
|
||||
const char *getName() const {
|
||||
return "SoundSubsystem";
|
||||
}
|
||||
|
||||
const char *getDescription() const {
|
||||
return "Sound Subsystem";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // End of namespace Testbed
|
||||
|
||||
#endif // TESTBED_SOUND_H
|
67
engines/testbed/template.h
Normal file
67
engines/testbed/template.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef TESTBED_TEMPLATE_H
|
||||
#define TESTBED_TEMPLATE_H
|
||||
|
||||
#include "testbed/testsuite.h"
|
||||
|
||||
// This file can be used as template for header files of other newer testsuites.
|
||||
|
||||
namespace Testbed {
|
||||
|
||||
namespace XXXtests {
|
||||
|
||||
// Helper functions for XXX tests
|
||||
|
||||
// will contain function declarations for XXX tests
|
||||
// add more here
|
||||
|
||||
} // End of namespace XXXtests
|
||||
|
||||
class XXXTestSuite : public Testsuite {
|
||||
public:
|
||||
/**
|
||||
* The constructor for the XXXTestSuite
|
||||
* For every test to be executed one must:
|
||||
* 1) Create a function that would invoke the test
|
||||
* 2) Add that test to list by executing addTest()
|
||||
*
|
||||
* @see addTest()
|
||||
*/
|
||||
XXXTestSuite();
|
||||
~XXXTestSuite() {}
|
||||
const char *getName() const {
|
||||
return "Dummy Template";
|
||||
}
|
||||
|
||||
const char *getDescription() const {
|
||||
return "Some Arbit description";
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // End of namespace Testbed
|
||||
|
||||
#endif // TESTBED_TEMPLATE_H
|
169
engines/testbed/testbed.cpp
Normal file
169
engines/testbed/testbed.cpp
Normal file
|
@ -0,0 +1,169 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "common/debug-channels.h"
|
||||
#include "common/scummsys.h"
|
||||
#include "common/system.h"
|
||||
|
||||
#include "engines/util.h"
|
||||
|
||||
#include "testbed/events.h"
|
||||
#include "testbed/fs.h"
|
||||
#include "testbed/graphics.h"
|
||||
#include "testbed/misc.h"
|
||||
#include "testbed/savegame.h"
|
||||
#include "testbed/sound.h"
|
||||
#include "testbed/testbed.h"
|
||||
|
||||
namespace Testbed {
|
||||
|
||||
void TestbedExitDialog::init() {
|
||||
_xOffset = 25;
|
||||
_yOffset = 0;
|
||||
Common::String text = "Thank you for using ScummVM testbed! Here are yor summarized results:";
|
||||
addText(450, 20, text, Graphics::kTextAlignCenter, _xOffset, 15);
|
||||
Common::Array<Common::String> strArray;
|
||||
|
||||
for (Common::Array<Testsuite *>::const_iterator i = _testsuiteList.begin(); i != _testsuiteList.end(); ++i) {
|
||||
strArray.push_back(Common::String::printf("%s (%d/%d tests failed)", (*i)->getName(), (*i)->getNumTestsFailed(),
|
||||
(*i)->getNumTestsEnabled()));
|
||||
}
|
||||
|
||||
addList(0, _yOffset, 500, 200, strArray);
|
||||
text = "More Details can be viewed in the Log file : " + Testsuite::getLogFile();
|
||||
addText(450, 20, text, Graphics::kTextAlignLeft, 0, 0);
|
||||
text = "Directory : " + Testsuite::getLogDir();
|
||||
addText(500, 20, text, Graphics::kTextAlignLeft, 0, 0);
|
||||
_yOffset += 5;
|
||||
addButtonXY(_xOffset + 80, _yOffset, 120, 20, "Rerun Tests", kCmdRerunTestbed);
|
||||
addButtonXY(_xOffset + 240, _yOffset, 60, 20, "Close", GUI::kCloseCmd);
|
||||
}
|
||||
|
||||
void TestbedExitDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) {
|
||||
switch (cmd) {
|
||||
case kCmdRerunTestbed :
|
||||
_rerun = true;
|
||||
GUI::Dialog::close();
|
||||
default:
|
||||
GUI::Dialog::handleCommand(sender, cmd, data);
|
||||
}
|
||||
}
|
||||
|
||||
bool TestbedEngine::hasFeature(EngineFeature f) const {
|
||||
return (f == kSupportsRTL) ? true : false;
|
||||
}
|
||||
|
||||
TestbedEngine::TestbedEngine(OSystem *syst)
|
||||
: Engine(syst) {
|
||||
// Put your engine in a sane state, but do nothing big yet;
|
||||
// in particular, do not load data from files; rather, if you
|
||||
// need to do such things, do them from init().
|
||||
|
||||
// Do not initialize graphics here
|
||||
|
||||
// However this is the place to specify all default directories
|
||||
|
||||
DebugMan.addDebugChannel(kTestbedLogOutput, "LOG", "Log of test results generated by testbed");
|
||||
DebugMan.addDebugChannel(kTestbedEngineDebug, "Debug", "Engine-specific debug statements");
|
||||
DebugMan.enableDebugChannel("LOG");
|
||||
|
||||
// Initialize testsuites here
|
||||
// GFX
|
||||
Testsuite *ts = new GFXTestSuite();
|
||||
_testsuiteList.push_back(ts);
|
||||
// FS
|
||||
ts = new FSTestSuite();
|
||||
_testsuiteList.push_back(ts);
|
||||
// Savegames
|
||||
ts = new SaveGameTestSuite();
|
||||
_testsuiteList.push_back(ts);
|
||||
// Misc.
|
||||
ts = new MiscTestSuite();
|
||||
_testsuiteList.push_back(ts);
|
||||
// Events
|
||||
ts = new EventTestSuite();
|
||||
_testsuiteList.push_back(ts);
|
||||
// Sound
|
||||
ts = new SoundSubsystemTestSuite();
|
||||
_testsuiteList.push_back(ts);
|
||||
}
|
||||
|
||||
TestbedEngine::~TestbedEngine() {
|
||||
Testsuite::deleteWriteStream();
|
||||
// Remove all of our debug levels here
|
||||
DebugMan.clearAllDebugChannels();
|
||||
|
||||
for (Common::Array<Testsuite *>::const_iterator i = _testsuiteList.begin(); i != _testsuiteList.end(); ++i) {
|
||||
delete (*i);
|
||||
}
|
||||
}
|
||||
|
||||
void TestbedEngine::invokeTestsuites(TestbedConfigManager &cfMan) {
|
||||
Common::Array<Testsuite *>::const_iterator iter;
|
||||
uint count = 1;
|
||||
Common::Point pt = Testsuite::getDisplayRegionCoordinates();
|
||||
int numSuitesEnabled = cfMan.getNumSuitesEnabled();
|
||||
|
||||
for (iter = _testsuiteList.begin(); iter != _testsuiteList.end(); iter++) {
|
||||
(*iter)->reset();
|
||||
if ((*iter)->isEnabled()) {
|
||||
Testsuite::updateStats("Testsuite", (*iter)->getName(), count++, numSuitesEnabled, pt);
|
||||
(*iter)->execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Common::Error TestbedEngine::run() {
|
||||
// Initialize graphics using following:
|
||||
initGraphics(320, 200, false);
|
||||
|
||||
// As of now we are using GUI::MessageDialog for interaction, Test if it works.
|
||||
// interactive mode could also be modified by a config parameter "non-interactive=1"
|
||||
// TODO: Implement that
|
||||
|
||||
TestbedConfigManager cfMan(_testsuiteList, "testbed.config");
|
||||
|
||||
// Keep running if rerun requested
|
||||
TestbedExitDialog tbDialog(_testsuiteList);
|
||||
|
||||
do {
|
||||
Testsuite::clearEntireScreen();
|
||||
cfMan.selectTestsuites();
|
||||
// Init logging
|
||||
Testsuite::initLogging(true);
|
||||
// Check if user wanted to exit.
|
||||
if (Engine::shouldQuit()) {
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
invokeTestsuites(cfMan);
|
||||
tbDialog.init();
|
||||
tbDialog.run();
|
||||
|
||||
} while (tbDialog.rerunRequired());
|
||||
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
} // End of namespace Testbed
|
85
engines/testbed/testbed.h
Normal file
85
engines/testbed/testbed.h
Normal file
|
@ -0,0 +1,85 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef TESTBED_H
|
||||
#define TESTBED_H
|
||||
|
||||
#include "engines/engine.h"
|
||||
|
||||
#include "gui/options.h"
|
||||
|
||||
#include "testbed/config.h"
|
||||
#include "testbed/testsuite.h"
|
||||
|
||||
namespace Testbed {
|
||||
|
||||
class TestbedConfigManager;
|
||||
|
||||
enum {
|
||||
kTestbedLogOutput = 1 << 0,
|
||||
kTestbedEngineDebug = 1 << 2,
|
||||
kCmdRerunTestbed = 'crtb'
|
||||
};
|
||||
|
||||
class TestbedEngine : public Engine {
|
||||
public:
|
||||
TestbedEngine(OSystem *syst);
|
||||
~TestbedEngine();
|
||||
|
||||
virtual Common::Error run();
|
||||
|
||||
/**
|
||||
* Invokes configured testsuites.
|
||||
*/
|
||||
void invokeTestsuites(TestbedConfigManager &cfMan);
|
||||
|
||||
bool hasFeature(EngineFeature f) const;
|
||||
|
||||
private:
|
||||
Common::Array<Testsuite *> _testsuiteList;
|
||||
};
|
||||
|
||||
class TestbedExitDialog : public TestbedInteractionDialog {
|
||||
public:
|
||||
TestbedExitDialog(Common::Array<Testsuite *> &testsuiteList) : TestbedInteractionDialog(80, 60, 500, 320), _rerun(false),
|
||||
_testsuiteList(testsuiteList) {}
|
||||
~TestbedExitDialog() {}
|
||||
void init();
|
||||
void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data);
|
||||
void run() { runModal(); }
|
||||
bool rerunRequired() {
|
||||
if (_rerun) {
|
||||
_rerun = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private:
|
||||
bool _rerun;
|
||||
Common::Array<Testsuite *> &_testsuiteList;
|
||||
};
|
||||
|
||||
} // End of namespace Testbed
|
||||
|
||||
#endif // TESTBED_H
|
373
engines/testbed/testsuite.cpp
Normal file
373
engines/testbed/testsuite.cpp
Normal file
|
@ -0,0 +1,373 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include "common/config-manager.h"
|
||||
#include "common/events.h"
|
||||
#include "common/stream.h"
|
||||
|
||||
#include "graphics/fontman.h"
|
||||
#include "graphics/surface.h"
|
||||
|
||||
#include "gui/message.h"
|
||||
|
||||
#include "testbed/graphics.h"
|
||||
#include "testbed/testbed.h"
|
||||
#include "testbed/testsuite.h"
|
||||
|
||||
namespace Testbed {
|
||||
|
||||
// Static public variable of Testsuite
|
||||
bool Testsuite::isSessionInteractive = true;
|
||||
|
||||
// Static private variable of Testsuite
|
||||
Common::String Testsuite::_logDirectory = "";
|
||||
Common::String Testsuite::_logFilename = "";
|
||||
Graphics::FontManager::FontUsage Testsuite::_displayFont = Graphics::FontManager::kGUIFont;
|
||||
Common::WriteStream *Testsuite::_ws = 0;
|
||||
uint Testsuite::toQuit = kLoopNormal;
|
||||
|
||||
void Testsuite::setLogDir(const char *dirname) {
|
||||
_logDirectory = dirname;
|
||||
}
|
||||
|
||||
void Testsuite::setLogFile(const char *filename) {
|
||||
_logFilename = filename;
|
||||
}
|
||||
|
||||
void Testsuite::deleteWriteStream() {
|
||||
if (_ws) {
|
||||
delete _ws;
|
||||
}
|
||||
}
|
||||
|
||||
void Testsuite::initLogging(const char *logdir, const char *filename, bool enable) {
|
||||
setLogDir(logdir);
|
||||
setLogFile(filename);
|
||||
|
||||
if (enable) {
|
||||
_ws = Common::FSNode(_logDirectory).getChild(_logFilename).createWriteStream();
|
||||
} else {
|
||||
_ws = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Testsuite::initLogging(bool enable) {
|
||||
setLogDir(ConfMan.get("path").c_str());
|
||||
setLogFile("testbed.log");
|
||||
|
||||
if (enable) {
|
||||
_ws = Common::FSNode(_logDirectory).getChild(_logFilename).createWriteStream();
|
||||
} else {
|
||||
_ws = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Testsuite::logPrintf(const char *fmt, ...) {
|
||||
// Assuming log message size to be not greater than STRINGBUFLEN i.e 256
|
||||
char buffer[STRINGBUFLEN];
|
||||
va_list vl;
|
||||
va_start(vl, fmt);
|
||||
vsnprintf(buffer, STRINGBUFLEN, fmt, vl);
|
||||
va_end(vl);
|
||||
|
||||
if (_ws) {
|
||||
_ws->writeString(buffer);
|
||||
debugCN(kTestbedLogOutput, "%s", buffer);
|
||||
} else {
|
||||
debugCN(kTestbedLogOutput, "%s", buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void Testsuite::logDetailedPrintf(const char *fmt, ...) {
|
||||
// Assuming log message size to be not greater than STRINGBUFLEN i.e 256
|
||||
// Messages with this function would only be displayed if -d1 is specified on command line
|
||||
char buffer[STRINGBUFLEN];
|
||||
va_list vl;
|
||||
va_start(vl, fmt);
|
||||
vsnprintf(buffer, STRINGBUFLEN, fmt, vl);
|
||||
va_end(vl);
|
||||
|
||||
if (_ws) {
|
||||
_ws->writeString(buffer);
|
||||
debugCN(1, kTestbedLogOutput, "%s", buffer);
|
||||
} else {
|
||||
debugCN(1, kTestbedLogOutput, "%s", buffer);
|
||||
}
|
||||
}
|
||||
|
||||
Testsuite::Testsuite() {
|
||||
_numTestsPassed = 0;
|
||||
_numTestsExecuted = 0;
|
||||
// Initially all testsuites are enabled, disable them by calling enableTestSuite(name, false)
|
||||
_isTsEnabled = true;
|
||||
// Set custom color for progress bar
|
||||
GFXTestSuite::setCustomColor(0, 0, 0);
|
||||
}
|
||||
|
||||
Testsuite::~Testsuite() {
|
||||
for (Common::Array<Test *>::iterator i = _testsToExecute.begin(); i != _testsToExecute.end(); ++i) {
|
||||
delete (*i);
|
||||
}
|
||||
}
|
||||
|
||||
void Testsuite::reset() {
|
||||
_numTestsPassed = 0;
|
||||
_numTestsExecuted = 0;
|
||||
toQuit = kLoopNormal;
|
||||
for (Common::Array<Test *>::iterator i = _testsToExecute.begin(); i != _testsToExecute.end(); ++i) {
|
||||
(*i)->passed = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Testsuite::genReport() const {
|
||||
logPrintf("\n");
|
||||
logPrintf("Consolidating results...\n");
|
||||
logPrintf("Subsystem: %s ", getName());
|
||||
logPrintf("(Tests Executed: %d)\n", _numTestsExecuted);
|
||||
logPrintf("Passed: %d ", _numTestsPassed);
|
||||
logPrintf("Failed: %d\n", getNumTestsFailed());
|
||||
logPrintf("\n");
|
||||
}
|
||||
|
||||
bool Testsuite::handleInteractiveInput(const Common::String &textToDisplay, const char *opt1, const char *opt2, OptionSelected result) {
|
||||
GUI::MessageDialog prompt(textToDisplay, opt1, opt2);
|
||||
return prompt.runModal() == result ? true : false;
|
||||
}
|
||||
|
||||
void Testsuite::displayMessage(const Common::String &textToDisplay, const char *defaultButton, const char *altButton) {
|
||||
GUI::MessageDialog prompt(textToDisplay, defaultButton);
|
||||
prompt.runModal();
|
||||
}
|
||||
|
||||
Common::Rect Testsuite::writeOnScreen(const Common::String &textToDisplay, const Common::Point &pt, bool flag) {
|
||||
const Graphics::Font &font(*FontMan.getFontByUsage(Graphics::FontManager::kConsoleFont));
|
||||
uint fillColor = kColorBlack;
|
||||
uint textColor = kColorWhite;
|
||||
|
||||
Graphics::Surface *screen = g_system->lockScreen();
|
||||
|
||||
int height = font.getFontHeight();
|
||||
int width = screen->w;
|
||||
|
||||
Common::Rect rect(pt.x, pt.y, pt.x + width, pt.y + height);
|
||||
|
||||
if (flag) {
|
||||
Graphics::PixelFormat pf = g_system->getScreenFormat();
|
||||
fillColor = pf.RGBToColor(0, 0, 0);
|
||||
textColor = pf.RGBToColor(255, 255, 255);
|
||||
}
|
||||
|
||||
screen->fillRect(rect, fillColor);
|
||||
font.drawString(screen, textToDisplay, rect.left, rect.top, screen->w, textColor, Graphics::kTextAlignCenter);
|
||||
|
||||
g_system->unlockScreen();
|
||||
g_system->updateScreen();
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
void Testsuite::clearScreen(const Common::Rect &rect) {
|
||||
Graphics::Surface *screen = g_system->lockScreen();
|
||||
|
||||
screen->fillRect(rect, kColorBlack);
|
||||
|
||||
g_system->unlockScreen();
|
||||
g_system->updateScreen();
|
||||
}
|
||||
|
||||
void Testsuite::clearScreen() {
|
||||
int numBytesPerLine = g_system->getWidth() * g_system->getScreenFormat().bytesPerPixel;
|
||||
int height = getDisplayRegionCoordinates().y;
|
||||
|
||||
// Don't clear test info display region
|
||||
int size = height * numBytesPerLine;
|
||||
byte *buffer = new byte[size];
|
||||
memset(buffer, 0, size);
|
||||
g_system->copyRectToScreen(buffer, numBytesPerLine, 0, 0, g_system->getWidth(), height);
|
||||
g_system->updateScreen();
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
void Testsuite::clearScreen(bool flag) {
|
||||
Graphics::Surface *screen = g_system->lockScreen();
|
||||
uint fillColor = kColorBlack;
|
||||
|
||||
if (flag) {
|
||||
fillColor = g_system->getScreenFormat().RGBToColor(0, 0, 0);
|
||||
}
|
||||
|
||||
screen->fillRect(Common::Rect(0, 0, g_system->getWidth(), g_system->getHeight()), fillColor);
|
||||
|
||||
g_system->unlockScreen();
|
||||
g_system->updateScreen();
|
||||
}
|
||||
|
||||
void Testsuite::addTest(const Common::String &name, InvokingFunction f, bool isInteractive) {
|
||||
Test *featureTest = new Test(name, f, isInteractive);
|
||||
_testsToExecute.push_back(featureTest);
|
||||
}
|
||||
|
||||
int Testsuite::getNumTestsEnabled() {
|
||||
int count = 0;
|
||||
Common::Array<Test *>::const_iterator iter;
|
||||
|
||||
if (!isEnabled()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (iter = _testsToExecute.begin(); iter != _testsToExecute.end(); iter++) {
|
||||
if ((*iter)->enabled) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
uint Testsuite::parseEvents() {
|
||||
uint startTime = g_system->getMillis();
|
||||
uint end = startTime + kEventHandlingTime;
|
||||
do {
|
||||
Common::Event ev;
|
||||
while (g_system->getEventManager()->pollEvent(ev)) {
|
||||
switch (ev.type) {
|
||||
case Common::EVENT_KEYDOWN:
|
||||
if (ev.kbd.keycode == Common::KEYCODE_ESCAPE) {
|
||||
return kSkipNext;
|
||||
}
|
||||
break;
|
||||
case Common::EVENT_QUIT:
|
||||
case Common::EVENT_RTL:
|
||||
return kEngineQuit;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
g_system->delayMillis(10);
|
||||
startTime = g_system->getMillis();
|
||||
} while (startTime <= end);
|
||||
|
||||
return kLoopNormal;
|
||||
}
|
||||
|
||||
void Testsuite::updateStats(const char *prefix, const char *info, uint testNum, uint numTests, Common::Point pt) {
|
||||
Common::String text = Common::String::printf(" Running %s: %s (%d of %d) ", prefix, info, testNum, numTests);
|
||||
writeOnScreen(text, pt);
|
||||
uint barColor = kColorSpecial;
|
||||
// below the text a rectangle denoting the progress in the testsuite can be drawn.
|
||||
int separation = getLineSeparation();
|
||||
pt.y += separation;
|
||||
int wRect = 200;
|
||||
int lRect = 7;
|
||||
pt.x = g_system->getWidth() / 2 - 100;
|
||||
byte *buffer = new byte[lRect * wRect];
|
||||
memset(buffer, 0, sizeof(byte) * lRect * wRect);
|
||||
|
||||
int wShaded = (int) (wRect * (((float)testNum) / numTests));
|
||||
|
||||
// draw the boundary
|
||||
memset(buffer, barColor, sizeof(byte) * wRect);
|
||||
memset(buffer + (wRect * (lRect - 1)) , barColor, sizeof(byte) * wRect);
|
||||
|
||||
for (int i = 0; i < lRect; i++) {
|
||||
for (int j = 0; j < wRect; j++) {
|
||||
if (j < wShaded) {
|
||||
buffer[i * wRect + j] = barColor;
|
||||
}
|
||||
}
|
||||
buffer[i * wRect + 0] = barColor;
|
||||
buffer[i * wRect + wRect - 1] = barColor;
|
||||
}
|
||||
g_system->copyRectToScreen(buffer, wRect, pt.x, pt.y, wRect, lRect);
|
||||
g_system->updateScreen();
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
bool Testsuite::enableTest(const Common::String &testName, bool toEnable) {
|
||||
for (uint i = 0; i < _testsToExecute.size(); i++) {
|
||||
if (_testsToExecute[i]->featureName.equalsIgnoreCase(testName)) {
|
||||
_testsToExecute[i]->enabled = toEnable;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void Testsuite::execute() {
|
||||
// Main Loop for a testsuite
|
||||
|
||||
// Do nothing if meant to exit
|
||||
if (toQuit == kEngineQuit) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint count = 0;
|
||||
Common::Point pt = getDisplayRegionCoordinates();
|
||||
pt.y += getLineSeparation();
|
||||
int numEnabledTests = getNumTestsEnabled();
|
||||
|
||||
for (Common::Array<Test *>::iterator i = _testsToExecute.begin(); i != _testsToExecute.end(); ++i) {
|
||||
if (!(*i)->enabled) {
|
||||
logPrintf("Info! Skipping Test: %s, Skipped by configuration.\n", ((*i)->featureName).c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (toQuit == kSkipNext) {
|
||||
logPrintf("Info! Skipping Test: %s, Skipped by user.\n", ((*i)->featureName).c_str());
|
||||
toQuit = kLoopNormal;
|
||||
continue;
|
||||
}
|
||||
|
||||
if((*i)->isInteractive && !isSessionInteractive) {
|
||||
logPrintf("Info! Skipping Test: %s, non-interactive environment is selected\n", ((*i)->featureName).c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
logPrintf("Info! Executing Test: %s\n", ((*i)->featureName).c_str());
|
||||
updateStats("Test", ((*i)->featureName).c_str(), count++, numEnabledTests, pt);
|
||||
_numTestsExecuted++;
|
||||
if ((*i)->driver()) {
|
||||
logPrintf("Result: Passed\n");
|
||||
_numTestsPassed++;
|
||||
} else {
|
||||
logPrintf("Result: Failed\n");
|
||||
}
|
||||
updateStats("Test", ((*i)->featureName).c_str(), count, numEnabledTests, pt);
|
||||
// TODO: Display a screen here to user with details of upcoming test, he can skip it or Quit or RTL
|
||||
// Check if user wants to quit/RTL/Skip next test by parsing events.
|
||||
// Quit directly if explicitly requested
|
||||
|
||||
if (Engine::shouldQuit()) {
|
||||
toQuit = kEngineQuit;
|
||||
genReport();
|
||||
return;
|
||||
}
|
||||
|
||||
toQuit = parseEvents();
|
||||
}
|
||||
genReport();
|
||||
}
|
||||
|
||||
} // End of namespace Testebed
|
214
engines/testbed/testsuite.h
Normal file
214
engines/testbed/testsuite.h
Normal file
|
@ -0,0 +1,214 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef TESTBED_TESTSUITE_H
|
||||
#define TESTBED_TESTSUITE_H
|
||||
|
||||
#include "common/system.h"
|
||||
#include "common/str.h"
|
||||
#include "common/array.h"
|
||||
|
||||
#include "graphics/fontman.h"
|
||||
|
||||
namespace Testbed {
|
||||
|
||||
enum {
|
||||
kColorBlack = 0,
|
||||
kColorWhite = 1,
|
||||
kColorCustom = 2,
|
||||
kColorSpecial = 5 ///< some random number
|
||||
};
|
||||
|
||||
enum OptionSelected {
|
||||
kOptionLeft = 1,
|
||||
kOptionRight = 0
|
||||
};
|
||||
|
||||
enum {
|
||||
kEngineQuit = 0,
|
||||
kSkipNext = 1,
|
||||
kLoopNormal = 2,
|
||||
// Event handling time,(in ms) used in parseEvent()
|
||||
kEventHandlingTime = 50
|
||||
};
|
||||
|
||||
typedef bool (*InvokingFunction)();
|
||||
|
||||
/**
|
||||
* This represents a feature to be tested
|
||||
*/
|
||||
|
||||
struct Test {
|
||||
Test(Common::String name, InvokingFunction f, bool interactive) : featureName(name) {
|
||||
driver = f;
|
||||
enabled = true;
|
||||
passed = false;
|
||||
isInteractive = interactive;
|
||||
}
|
||||
const Common::String featureName; ///< Name of feature to be tested
|
||||
InvokingFunction driver; ///< Pointer to the function that will invoke this feature test
|
||||
bool enabled; ///< Decides whether or not this test is to be executed
|
||||
bool passed; ///< Collects and stores result of this feature test
|
||||
bool isInteractive; ///< Decides if the test is interactive or not, An interactive testsuite may have non-interactive tests, hence this change.
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The basic Testsuite class
|
||||
* All the other testsuites would inherit it and override its virtual methods
|
||||
*/
|
||||
|
||||
class Testsuite {
|
||||
public:
|
||||
Testsuite();
|
||||
virtual ~Testsuite();
|
||||
int getNumTests() const { return _testsToExecute.size(); }
|
||||
int getNumTestsPassed() const { return _numTestsPassed; }
|
||||
int getNumTestsFailed() const { return _numTestsExecuted - _numTestsPassed; }
|
||||
void genReport() const;
|
||||
bool isEnabled() const { return _isTsEnabled; }
|
||||
virtual void enable(bool flag) {
|
||||
_isTsEnabled = flag;
|
||||
}
|
||||
bool enableTest(const Common::String &testName, bool enable);
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* Prompts for User Input in form of "Yes" or "No" for interactive tests
|
||||
* e.g: "Is this like you expect?" "Yes" or "No"
|
||||
*
|
||||
* @param textToDisplay Display text
|
||||
* @return true if "Yes" false otherwise
|
||||
*/
|
||||
static bool handleInteractiveInput(const Common::String &textToDisplay, const char *opt1 = "Yes", const char *opt2 = "No", OptionSelected result = kOptionLeft);
|
||||
|
||||
static void displayMessage(const Common::String &textToDisplay, const char *defaultButton = "OK", const char *altButton = 0);
|
||||
static Common::Rect writeOnScreen(const Common::String &textToDisplay, const Common::Point &pt, bool flag = false);
|
||||
static void clearScreen(const Common::Rect &rect);
|
||||
static void clearEntireScreen() {
|
||||
const int width = g_system->getWidth();
|
||||
const int height = g_system->getHeight();
|
||||
Common::Rect r(0, 0, width, height);
|
||||
clearScreen(r);
|
||||
}
|
||||
static void clearScreen();
|
||||
static void clearScreen(bool flag);
|
||||
|
||||
/**
|
||||
* Adds a test to the list of tests to be executed
|
||||
*
|
||||
* @param name the string description of the test, for display purposes
|
||||
* @param f pointer to the function that invokes this test
|
||||
* @param isInteractive decides if the test is to be executed in interactive mode/ default true
|
||||
*/
|
||||
void addTest(const Common::String &name, InvokingFunction f, bool isInteractive = true);
|
||||
|
||||
/**
|
||||
* The driver function for the testsuite
|
||||
* All code should go in here.
|
||||
*/
|
||||
virtual void execute();
|
||||
static uint parseEvents();
|
||||
|
||||
virtual const char *getName() const = 0;
|
||||
virtual const char *getDescription() const = 0;
|
||||
|
||||
static void logPrintf(const char *s, ...) GCC_PRINTF(1, 2);
|
||||
static void logDetailedPrintf(const char *s, ...) GCC_PRINTF(1, 2);
|
||||
/**
|
||||
* Note: To enable logging, this function must be called once first.
|
||||
*/
|
||||
static void initLogging(const char *dirname, const char *filename, bool enable = true);
|
||||
static void initLogging(bool enable = true);
|
||||
static void setLogDir(const char *dirname);
|
||||
static void setLogFile(const char *filename);
|
||||
static Common::String getLogDir() { return _logDirectory; }
|
||||
static Common::String getLogFile() { return _logFilename; }
|
||||
|
||||
static void deleteWriteStream();
|
||||
|
||||
// Progress bar (Information Display) related methods.
|
||||
/**
|
||||
* Display region is in the bottom. Probably 1/4th of the game screen.
|
||||
* It contains:
|
||||
* 1) Information about executing testsuite.
|
||||
* 2) Total progress within this testsuite.
|
||||
* 3) Total overall progress in the number of testsuites
|
||||
*/
|
||||
|
||||
static Common::Point getDisplayRegionCoordinates() {
|
||||
Common::Point pt(0, 0);
|
||||
// start from bottom
|
||||
pt.y = g_system->getHeight();
|
||||
// Will Contain 3 lines
|
||||
pt.y -= (FontMan.getFontByUsage(_displayFont)->getFontHeight() * 3 + 15); // Buffer of 5 pixels per line
|
||||
return pt;
|
||||
}
|
||||
|
||||
static uint getLineSeparation() {
|
||||
return FontMan.getFontByUsage(_displayFont)->getFontHeight() + 5;
|
||||
}
|
||||
static Graphics::FontManager::FontUsage getCurrentFontUsageType() { return _displayFont; }
|
||||
static void setCurrentFontUsageType(Graphics::FontManager::FontUsage f) { _displayFont = f; }
|
||||
|
||||
static void updateStats(const char *prefix, const char *info, uint numTests, uint testNum, Common::Point pt);
|
||||
const Common::Array<Test *>& getTestList() { return _testsToExecute; }
|
||||
int getNumTestsEnabled();
|
||||
|
||||
protected:
|
||||
Common::Array<Test *> _testsToExecute; ///< List of tests to be executed
|
||||
int _numTestsPassed; ///< Number of tests passed
|
||||
int _numTestsExecuted; ///< Number of tests executed
|
||||
bool _isTsEnabled;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Static variable of this class that determines if the user initiated testing session is interactive or not.
|
||||
* Used by various tests to respond accordingly
|
||||
*/
|
||||
static bool isSessionInteractive;
|
||||
|
||||
/**
|
||||
* Used from the code to decide if the engine needs to exit
|
||||
*/
|
||||
static uint toQuit;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Private variables related to logging files
|
||||
*/
|
||||
static Common::String _logDirectory;
|
||||
static Common::String _logFilename;
|
||||
static Common::WriteStream *_ws;
|
||||
|
||||
/**
|
||||
* Private variable used for font
|
||||
*/
|
||||
static Graphics::FontManager::FontUsage _displayFont;
|
||||
};
|
||||
|
||||
} // End of namespace Testbed
|
||||
|
||||
#endif // TESTBED_TESTSUITE_H
|
Loading…
Add table
Add a link
Reference in a new issue