diff options
author | Neeraj Kumar | 2010-10-02 01:05:16 +0000 |
---|---|---|
committer | Neeraj Kumar | 2010-10-02 01:05:16 +0000 |
commit | a16832760bfd1916ad60938e177a5ca6b920d781 (patch) | |
tree | be8dd3757cc98ce6596e0a37a6a6e42168102950 /engines/testbed | |
parent | f94752f7528c406d68353dc75cad4047c4af86a2 (diff) | |
parent | 81a646c9bd32662f2a72fc0b3db32105857b9416 (diff) | |
download | scummvm-rg350-a16832760bfd1916ad60938e177a5ca6b920d781.tar.gz scummvm-rg350-a16832760bfd1916ad60938e177a5ca6b920d781.tar.bz2 scummvm-rg350-a16832760bfd1916ad60938e177a5ca6b920d781.zip |
1. Added ConfigParams Singelton class to eliminate use of configuration specific static variables.
2. Modified code to handle the change
3. Updated the previously merged obsolete copy of branch gsoc2010-testbed.
svn-id: r52973
Diffstat (limited to 'engines/testbed')
-rw-r--r-- | engines/testbed/config-params.cpp | 73 | ||||
-rw-r--r-- | engines/testbed/config-params.h | 99 | ||||
-rw-r--r-- | engines/testbed/config.cpp | 61 | ||||
-rw-r--r-- | engines/testbed/config.h | 6 | ||||
-rw-r--r-- | engines/testbed/detection.cpp | 4 | ||||
-rw-r--r-- | engines/testbed/events.cpp | 110 | ||||
-rw-r--r-- | engines/testbed/events.h | 6 | ||||
-rw-r--r-- | engines/testbed/fs.cpp | 61 | ||||
-rw-r--r-- | engines/testbed/fs.h | 6 | ||||
-rw-r--r-- | engines/testbed/graphics.cpp | 231 | ||||
-rw-r--r-- | engines/testbed/graphics.h | 26 | ||||
-rw-r--r-- | engines/testbed/midi.cpp | 155 | ||||
-rw-r--r-- | engines/testbed/midi.h | 77 | ||||
-rw-r--r-- | engines/testbed/misc.cpp | 40 | ||||
-rw-r--r-- | engines/testbed/misc.h | 6 | ||||
-rw-r--r-- | engines/testbed/module.mk | 2 | ||||
-rw-r--r-- | engines/testbed/savegame.cpp | 44 | ||||
-rw-r--r-- | engines/testbed/savegame.h | 10 | ||||
-rw-r--r-- | engines/testbed/sound.cpp | 90 | ||||
-rw-r--r-- | engines/testbed/sound.h | 15 | ||||
-rw-r--r-- | engines/testbed/template.h | 2 | ||||
-rw-r--r-- | engines/testbed/testbed.cpp | 63 | ||||
-rw-r--r-- | engines/testbed/testbed.h | 14 | ||||
-rw-r--r-- | engines/testbed/testsuite.cpp | 100 | ||||
-rw-r--r-- | engines/testbed/testsuite.h | 60 |
25 files changed, 928 insertions, 433 deletions
diff --git a/engines/testbed/config-params.cpp b/engines/testbed/config-params.cpp new file mode 100644 index 0000000000..e5a581ec29 --- /dev/null +++ b/engines/testbed/config-params.cpp @@ -0,0 +1,73 @@ +/* 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/fs.h" + +#include "testbed/config-params.h" + +DECLARE_SINGLETON(Testbed::ConfigParams) + +namespace Testbed { + +ConfigParams::ConfigParams() { + _logDirectory = ""; + _logFilename = ""; + _ws = 0; + _displayFont = Graphics::FontManager::kGUIFont; + _isInteractive = true; + _isGameDataFound = true; + _rerunTests = false; +} + +void ConfigParams::initLogging(const char *dirname, const char *filename, bool enable) { + setLogDirectory(dirname); + setLogFilename(filename); + if (enable) { + _ws = Common::FSNode(_logDirectory).getChild(_logFilename).createWriteStream(); + } else { + _ws = 0; + } +} + +void ConfigParams::initLogging(bool enable) { + // Default Log Directory is game-data directory and filename is 'testbed.log'. + initLogging(ConfMan.get("path").c_str(), "testbed.log", enable); +} + +bool ConfigParams::isRerunRequired() { + if (_rerunTests) { + _rerunTests = false; + return true; + } + return false; +} + +void ConfigParams::deleteWriteStream() { + if (_ws) { + delete _ws; + } +} + +} // End of namespace Testbed diff --git a/engines/testbed/config-params.h b/engines/testbed/config-params.h new file mode 100644 index 0000000000..7a0e1cf5f2 --- /dev/null +++ b/engines/testbed/config-params.h @@ -0,0 +1,99 @@ +/* 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_PARAMS_H +#define TESTBED_CONFIG_PARAMS_H + +#include "common/singleton.h" +#include "common/stream.h" +#include "graphics/fontman.h" + +class TestbedConfigManager; + +namespace Testbed { + +class ConfigParams : public Common::Singleton<ConfigParams> { +private: + friend class Common::Singleton<SingletonBaseType>; + ConfigParams(); + + /** + * Private variables related to log files. + */ + Common::String _logDirectory; + Common::String _logFilename; + Common::WriteStream *_ws; + + /** + * Private variable used for font. + */ + Graphics::FontManager::FontUsage _displayFont; + + /** + * Determines if the user initiated testing session is interactive or not. + * Used by various tests to respond accordingly. + */ + bool _isInteractive; + bool _isGameDataFound; + bool _rerunTests; + TestbedConfigManager *_testbedConfMan; + +public: + + bool isRerunRequired(); + void setRerunFlag(bool flag) { _rerunTests = flag; } + + bool isSessionInteractive() { return _isInteractive; } + void setSessionAsInteractive(bool status) { _isInteractive = status; } + + bool isGameDataFound() { return _isGameDataFound; } + void setGameDataFound(bool status) { _isGameDataFound = status; } + + TestbedConfigManager *getTestbedConfigManager() { return _testbedConfMan; } + void setTestbedConfigManager(TestbedConfigManager* confMan) { _testbedConfMan = confMan; } + + Common::String &getLogDirectory() { return _logDirectory; } + void setLogDirectory(const Common::String &dirname) { _logDirectory = dirname; } + Common::String &getLogFilename() { return _logFilename; } + void setLogFilename(const Common::String &filename) { _logFilename = filename; } + + Common::WriteStream *getLogWriteStream() { return _ws; } + Graphics::FontManager::FontUsage getCurrentFontUsageType() { return _displayFont; } + void setCurrentFontUsageType(Graphics::FontManager::FontUsage f) { _displayFont = f; } + + /** + * Note: To enable logging, this function must be called once first. + */ + void initLogging(const char *dirname, const char *filename, bool enable = true); + void initLogging(bool enable = true); + + void deleteWriteStream(); +}; + +/** Shortcut for accessing ConfigParams */ +#define ConfParams ConfigParams::instance() + +} // End of Namespace Testbed + +#endif diff --git a/engines/testbed/config.cpp b/engines/testbed/config.cpp index 1acbe72837..fe34910204 100644 --- a/engines/testbed/config.cpp +++ b/engines/testbed/config.cpp @@ -22,16 +22,18 @@ * $Id$ */ -#include "common/fs.h" #include "common/stream.h" #include "common/config-manager.h" + #include "engines/engine.h" + #include "testbed/config.h" +#include "testbed/fs.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"); @@ -52,7 +54,7 @@ TestbedOptionsDialog::TestbedOptionsDialog(Common::Array<Testsuite *> &tsList, T _colors.push_back(GUI::ThemeEngine::kFontColorAlternate); } } - + _testListDisplay = new TestbedListWidget(this, "Browser.List", _testSuiteArray); _testListDisplay->setNumberingMode(GUI::kListNumberingOff); _testListDisplay->setList(_testSuiteDescArray, &_colors); @@ -78,12 +80,18 @@ void TestbedOptionsDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, case GUI::kListItemDoubleClickedCmd: ts = _testSuiteArray[_testListDisplay->getSelected()]; if (ts) { + // Toggle status if (ts->isEnabled()) { ts->enable(false); - _testListDisplay->markAsDeselected(_testListDisplay->getSelected()); } else { ts->enable(true); + } + + // Now render status + if (ts->isEnabled()) { _testListDisplay->markAsSelected(_testListDisplay->getSelected()); + } else { + _testListDisplay->markAsDeselected(_testListDisplay->getSelected()); } } break; @@ -123,7 +131,7 @@ void TestbedOptionsDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, delete ws; default: GUI::Dialog::handleCommand(sender, cmd, data); - + } } @@ -145,16 +153,16 @@ void TestbedInteractionDialog::addButton(uint w, uint h, const Common::String na _yOffset += h; } -void TestbedInteractionDialog::addList(uint x, uint y, uint w, uint h, Common::Array<Common::String> &strArray, uint yPadding) { +void TestbedInteractionDialog::addList(uint x, uint y, uint w, uint h, Common::Array<Common::String> &strArray, GUI::ListWidget::ColorList *colors, 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); + list->setList(strArray, colors); _yOffset += h; } -void TestbedInteractionDialog::addButtonXY(uint x, uint y, uint w, uint h, const Common::String name, uint32 cmd) { +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)); } @@ -178,15 +186,12 @@ void TestbedConfigManager::writeTestbedConfigToStream(Common::WriteStream *ws) { } } _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); + // Look for config file using SearchMan + Common::SeekableReadStream *rs = SearchMan.createReadStreamForMember(_configFileName); return rs; } @@ -200,9 +205,9 @@ Common::WriteStream *TestbedConfigManager::getConfigWriteStream() { return ws; } -void TestbedConfigManager::parseConfigFile() { +void TestbedConfigManager::parseConfigFile() { Common::SeekableReadStream *rs = getConfigReadStream(); - + if (!rs) { Testsuite::logPrintf("Info! No config file found, using default configuration.\n"); initDefaultConfiguration(); @@ -214,13 +219,14 @@ void TestbedConfigManager::parseConfigFile() { 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 + // 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()); + continue; } for (Common::ConfigFile::SectionKeyList::const_iterator j = kList.begin(); j != kList.end(); j++) { @@ -259,14 +265,14 @@ Testsuite *TestbedConfigManager::getTestsuiteByName(const Common::String &name) void TestbedConfigManager::selectTestsuites() { parseConfigFile(); - + if (_configFileInterface.hasKey("isSessionInteractive", "Global")) { Common::String in; _configFileInterface.getKey("isSessionInteractive", "Global", in); - Testsuite::isSessionInteractive = stringToBool(in); + ConfParams.setSessionAsInteractive(stringToBool(in)); } - if (!Testsuite::isSessionInteractive) { + if (!ConfParams.isSessionInteractive()) { // Non interactive sessions don't need to go beyond return; } @@ -275,15 +281,28 @@ void TestbedConfigManager::selectTestsuites() { // 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 :)"); + "If you see this, it means interactive tests would run on this system :)\n"); + + if (!ConfParams.isGameDataFound()) { + prompt += "\nSeems like Game data files are not configured properly.\n" + "Create Game data files using script ./create-testbed-data.sh in dists/engine-data\n" + "Next, Configure the game path in launcher / command-line.\n" + "Currently a few testsuites namely FS/AudioCD/MIDI would be disabled\n"; + } Testsuite::logPrintf("Info! : Interactive tests are also being executed.\n"); - + if (Testsuite::handleInteractiveInput(prompt, "Proceed?", "Customize", kOptionRight)) { + if (Engine::shouldQuit()) { + return; + } // Select testsuites using checkboxes TestbedOptionsDialog tbd(_testsuiteList, this); tbd.runModal(); } + + // Clear it to remove entries before next rerun + _configFileInterface.clear(); } } // End of namespace Testbed diff --git a/engines/testbed/config.h b/engines/testbed/config.h index 0c734c95fb..2ee5b09002 100644 --- a/engines/testbed/config.h +++ b/engines/testbed/config.h @@ -80,7 +80,7 @@ public: _listColors[i] = GUI::ThemeEngine::kFontColorNormal; draw(); } - + void markAsDeselected(int i) { if (_list[i].contains("selected")) { _list[i] = _testSuiteArray[i]->getDescription(); @@ -88,7 +88,7 @@ public: _listColors[i] = GUI::ThemeEngine::kFontColorAlternate; draw(); } - + void setColor(uint32 indx, GUI::ThemeEngine::FontColor color) { assert(indx < _listColors.size()); _listColors[indx] = color; @@ -122,7 +122,7 @@ public: 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); + void addList(uint x, uint y, uint w, uint h, Common::Array<Common::String> &strArray, GUI::ListWidget::ColorList *colors = 0, uint yPadding = 8); protected: Common::Array<GUI::ButtonWidget *> _buttonArray; uint _xOffset; diff --git a/engines/testbed/detection.cpp b/engines/testbed/detection.cpp index d335fd2dfd..1b8a86cea6 100644 --- a/engines/testbed/detection.cpp +++ b/engines/testbed/detection.cpp @@ -41,7 +41,7 @@ static const ADGameDescription testbedDescriptions[] = { { "testbed", "", - AD_ENTRY1("TESTBED", 0), // Game-data file for detection. + AD_ENTRY1("TESTBED", 0), // Game-data file for detection Common::EN_ANY, Common::kPlatformPC, ADGF_NO_FLAGS, @@ -70,7 +70,7 @@ public: } virtual const char *getName() const { - return "Testbed: The Backend Testing Framework"; + return "TestBed: The Backend Testing Framework"; } virtual const char *getOriginalCopyright() const { diff --git a/engines/testbed/events.cpp b/engines/testbed/events.cpp index a8e2816266..b0a930172d 100644 --- a/engines/testbed/events.cpp +++ b/engines/testbed/events.cpp @@ -64,6 +64,16 @@ struct keycodeToChar { {Common::KEYCODE_x, 'x'}, {Common::KEYCODE_y, 'y'}, {Common::KEYCODE_z, 'z'}, + {Common::KEYCODE_0, '0'}, + {Common::KEYCODE_1, '1'}, + {Common::KEYCODE_2, '2'}, + {Common::KEYCODE_3, '3'}, + {Common::KEYCODE_4, '4'}, + {Common::KEYCODE_5, '5'}, + {Common::KEYCODE_6, '6'}, + {Common::KEYCODE_7, '7'}, + {Common::KEYCODE_8, '8'}, + {Common::KEYCODE_9, '9'}, {Common::KEYCODE_SPACE, ' '} }; @@ -116,8 +126,8 @@ Common::Rect EventTests::drawFinishZone() { return Common::Rect(right - width, 0, right, height); } -bool EventTests::mouseEvents() { - +TestExitStatus 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" @@ -125,22 +135,31 @@ bool EventTests::mouseEvents() { if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { Testsuite::logPrintf("Info! Skipping test : keyboard events\n"); - return true; + return kTestSkipped; } - + 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); + Common::Point pt(0, 30); + Common::Rect rectInfo = Testsuite::writeOnScreen("Generate mouse events make L/R/M button clicks, move wheel", pt); + pt.y += 15; + Testsuite::writeOnScreen("Press X to exit", pt); + pt.y = 70; + Common::Rect rectLB = Testsuite::writeOnScreen("Left-button click : Not tested", pt); + pt.y += 15; + Common::Rect rectRB = Testsuite::writeOnScreen("Right-button click : Not tested", pt); + pt.y += 15; + Common::Rect rectMB = Testsuite::writeOnScreen("Middle-button click : Not tested", pt); + pt.y += 15; + Common::Rect rectWheel = Testsuite::writeOnScreen("Wheel Movements : Not tested", pt); + // Init Mouse Palette GFXtests::initMousePalette(); Common::Rect finishZone = drawFinishZone(); bool quitLoop = false; - bool passed = true; + TestExitStatus passed = kTestPassed; // handle all mouse events Common::Event event; while (!quitLoop) { @@ -158,44 +177,49 @@ bool EventTests::mouseEvents() { // Movements havee already been tested in GFX break; case Common::EVENT_LBUTTONDOWN: - Testsuite::clearScreen(rect); - Testsuite::writeOnScreen("Mouse left-button pressed", pt); + Testsuite::clearScreen(rectInfo); + Testsuite::writeOnScreen("Mouse left-button pressed", Common::Point(rectInfo.left, rectInfo.top)); break; case Common::EVENT_RBUTTONDOWN: - Testsuite::clearScreen(rect); - Testsuite::writeOnScreen("Mouse right-button pressed", pt); + Testsuite::clearScreen(rectInfo); + Testsuite::writeOnScreen("Mouse right-button pressed", Common::Point(rectInfo.left, rectInfo.top)); break; case Common::EVENT_WHEELDOWN: - Testsuite::clearScreen(rect); - Testsuite::writeOnScreen("Mouse wheel moved down", pt); + Testsuite::clearScreen(rectInfo); + Testsuite::writeOnScreen("Mouse wheel moved down", Common::Point(rectInfo.left, rectInfo.top)); + Testsuite::writeOnScreen("Wheel Movements : Done!", Common::Point(rectWheel.left, rectWheel.top)); break; case Common::EVENT_MBUTTONDOWN: - Testsuite::clearScreen(rect); - Testsuite::writeOnScreen("Mouse middle-button pressed ", pt); + Testsuite::clearScreen(rectInfo); + Testsuite::writeOnScreen("Mouse middle-button pressed ", Common::Point(rectInfo.left, rectInfo.top)); break; case Common::EVENT_LBUTTONUP: - Testsuite::clearScreen(rect); + Testsuite::clearScreen(rectInfo); if (finishZone.contains(eventMan->getMousePos())) { quitLoop = true; } - Testsuite::writeOnScreen("Mouse left-button released", pt); + Testsuite::writeOnScreen("Mouse left-button released", Common::Point(rectInfo.left, rectInfo.top)); + Testsuite::writeOnScreen("Left-button clicks : Done!", Common::Point(rectLB.left, rectLB.top)); break; case Common::EVENT_RBUTTONUP: - Testsuite::clearScreen(rect); - Testsuite::writeOnScreen("Mouse right-button released", pt); + Testsuite::clearScreen(rectInfo); + Testsuite::writeOnScreen("Mouse right-button released", Common::Point(rectInfo.left, rectInfo.top)); + Testsuite::writeOnScreen("Right-button clicks : Done!", Common::Point(rectRB.left, rectRB.top)); break; case Common::EVENT_WHEELUP: - Testsuite::clearScreen(rect); - Testsuite::writeOnScreen("Mouse wheel moved up", pt); + Testsuite::clearScreen(rectInfo); + Testsuite::writeOnScreen("Mouse wheel moved up", Common::Point(rectInfo.left, rectInfo.top)); + Testsuite::writeOnScreen("Wheel Movements : Done!", Common::Point(rectWheel.left, rectWheel.top)); break; case Common::EVENT_MBUTTONUP: - Testsuite::clearScreen(rect); - Testsuite::writeOnScreen("Mouse middle-button released ", pt); + Testsuite::clearScreen(rectInfo); + Testsuite::writeOnScreen("Mouse middle-button released ", Common::Point(rectInfo.left, rectInfo.top)); + Testsuite::writeOnScreen("Middle-button clicks : Done!", Common::Point(rectMB.left, rectMB.top)); break; case Common::EVENT_KEYDOWN: if (event.kbd.keycode == Common::KEYCODE_x) { - Testsuite::clearScreen(rect); - Testsuite::writeOnScreen("Exit requested", pt); + Testsuite::clearScreen(rectInfo); + Testsuite::writeOnScreen("Exit requested", Common::Point(rectInfo.left, rectInfo.top)); quitLoop = true; } break; @@ -209,20 +233,16 @@ bool EventTests::mouseEvents() { 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; + if (Testsuite::handleInteractiveInput("Were mouse clicks (L/R/M buttons) and wheel movements identfied ?", "Yes", "No", kOptionRight)) { + Testsuite::logDetailedPrintf("Mouse clicks (L/R/M buttons) and wheel movements failed"); + passed = kTestFailed; } return passed; } -bool EventTests::kbdEvents() { - +TestExitStatus 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" @@ -230,7 +250,7 @@ bool EventTests::kbdEvents() { if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { Testsuite::logPrintf("Info! Skipping test : keyboard events\n"); - return true; + return kTestSkipped; } @@ -248,38 +268,38 @@ bool EventTests::kbdEvents() { rect = Testsuite::writeOnScreen(text, pt); } - bool passed = true; + TestExitStatus passed = kTestPassed; if (Testsuite::handleInteractiveInput("Was the word you entered same as that displayed on screen?", "Yes", "No", kOptionRight)) { Testsuite::logDetailedPrintf("Keyboard Events failed"); - passed = false; + passed = kTestFailed; } Testsuite::clearScreen(); return passed; } -bool EventTests::showMainMenu() { - +TestExitStatus 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."; + "Click 'resume'(the topmost button) to continue testbed."; if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { Testsuite::logPrintf("Info! Skipping test : Main Menu\n"); - return true; + return kTestSkipped; } Common::EventManager *eventMan = g_system->getEventManager(); Common::Event mainMenuEvent; mainMenuEvent.type = Common::EVENT_MAINMENU; eventMan->pushEvent(mainMenuEvent); - bool passed = true; + TestExitStatus passed = kTestPassed; if (Testsuite::handleInteractiveInput("Were you able to see a main menu widget?", "Yes", "No", kOptionRight)) { Testsuite::logDetailedPrintf("Event MAINMENU failed"); - passed = false; + passed = kTestFailed; } return passed; diff --git a/engines/testbed/events.h b/engines/testbed/events.h index e857deec25..607bba79d5 100644 --- a/engines/testbed/events.h +++ b/engines/testbed/events.h @@ -35,9 +35,9 @@ namespace EventTests { char keystrokeToChar(); Common::Rect drawFinishZone(); // will contain function declarations for Event tests -bool mouseEvents(); -bool kbdEvents(); -bool showMainMenu(); +TestExitStatus mouseEvents(); +TestExitStatus kbdEvents(); +TestExitStatus showMainMenu(); // add more here } // End of namespace EventTests diff --git a/engines/testbed/fs.cpp b/engines/testbed/fs.cpp index 6bd67022ee..f951224910 100644 --- a/engines/testbed/fs.cpp +++ b/engines/testbed/fs.cpp @@ -63,14 +63,14 @@ bool FStests::readDataFromFile(Common::FSDirectory *directory, const char *file) return true; } -bool FStests::testReadFile() { +TestExitStatus 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; + if (!gameRoot.getFSNode().exists() || !gameRoot.getFSNode().isDirectory()) { + Testsuite::logDetailedPrintf("game Path should be an existing directory"); + return kTestFailed; } const char *dirList[] = {"test1" ,"Test2", "TEST3" , "tEST4", "test5"}; @@ -81,6 +81,11 @@ bool FStests::testReadFile() { Common::String fileName = file[i]; Common::FSDirectory *directory = gameRoot.getSubDirectory(dirName); + if (!directory) { + Testsuite::logDetailedPrintf("Failed to open directory %s during FS tests\n", dirName.c_str()); + return kTestFailed; + } + if (!readDataFromFile(directory, fileName.c_str())) { Testsuite::logDetailedPrintf("Reading from %s/%s failed\n", dirName.c_str(), fileName.c_str()); numFailed++; @@ -91,6 +96,11 @@ bool FStests::testReadFile() { delete directory; directory = gameRoot.getSubDirectory(dirName); + if (!directory) { + Testsuite::logDetailedPrintf("Failed to open directory %s during FS tests\n", dirName.c_str()); + return kTestFailed; + } + if (!readDataFromFile(directory, fileName.c_str())) { Testsuite::logDetailedPrintf("Reading from %s/%s failed\n", dirName.c_str(), fileName.c_str()); numFailed++; @@ -101,6 +111,11 @@ bool FStests::testReadFile() { delete directory; directory = gameRoot.getSubDirectory(dirName); + if (!directory) { + Testsuite::logDetailedPrintf("Failed to open directory %s during FS tests\n", dirName.c_str()); + return kTestFailed; + } + if (!readDataFromFile(directory, fileName.c_str())) { Testsuite::logDetailedPrintf("Reading from %s/%s failed\n", dirName.c_str(), fileName.c_str()); numFailed++; @@ -109,16 +124,24 @@ bool FStests::testReadFile() { } Testsuite::logDetailedPrintf("Failed %d out of 15\n", numFailed); - return false; + if (numFailed) { + return kTestFailed; + } else { + return kTestPassed; + } } /** * 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() { +TestExitStatus FStests::testWriteFile() { const Common::String &path = ConfMan.get("path"); Common::FSNode gameRoot(path); + if (!gameRoot.exists()) { + Testsuite::logPrintf("Couldn't open the game data directory %s", path.c_str()); + return kTestFailed; + } Common::FSNode fileToWrite = gameRoot.getChild("testbed.out"); @@ -126,7 +149,7 @@ bool FStests::testWriteFile() { if (!ws) { Testsuite::logDetailedPrintf("Can't open writable file in game data dir\n"); - return false; + return kTestFailed; } ws->writeString("ScummVM Rocks!"); @@ -134,36 +157,42 @@ bool FStests::testWriteFile() { delete ws; Common::SeekableReadStream *rs = fileToWrite.createReadStream(); + if (!rs) { + Testsuite::logDetailedPrintf("Can't open recently written file testbed.out in game data dir\n"); + return kTestFailed; + } 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 kTestPassed; } - return false; + return kTestFailed; } FSTestSuite::FSTestSuite() { - addTest("ReadingFile", &FStests::testReadFile, false); - addTest("WritingFile", &FStests::testWriteFile, false); -} - -void FSTestSuite::enable(bool flag) { + // FS tests depend on Game Data files. + // If those are not found. Disable this testsuite. 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"); + ConfParams.setGameDataFound(false); Testsuite::enable(false); - return; } - Testsuite::enable(flag); + addTest("ReadingFile", &FStests::testReadFile, false); + addTest("WritingFile", &FStests::testWriteFile, false); +} + +void FSTestSuite::enable(bool flag) { + Testsuite::enable(ConfParams.isGameDataFound() & flag); } } // End of namespace Testbed diff --git a/engines/testbed/fs.h b/engines/testbed/fs.h index a5e79c10ce..c51d898c9d 100644 --- a/engines/testbed/fs.h +++ b/engines/testbed/fs.h @@ -41,9 +41,9 @@ namespace FStests { bool readDataFromFile(Common::FSDirectory *directory, const char *file); // will contain function declarations for FS tests -bool testReadFile(); -bool testWriteFile(); -bool testOpeningSaveFile(); +TestExitStatus testReadFile(); +TestExitStatus testWriteFile(); +TestExitStatus testOpeningSaveFile(); // add more here } // End of namespace FStests diff --git a/engines/testbed/graphics.cpp b/engines/testbed/graphics.cpp index 7e462a18b0..086db21c67 100644 --- a/engines/testbed/graphics.cpp +++ b/engines/testbed/graphics.cpp @@ -62,7 +62,7 @@ GFXTestSuite::GFXTestSuite() { // Mouse Layer tests (Palettes and movements) addTest("PalettizedCursors", &GFXtests::palettizedCursors); addTest("MouseMovements", &GFXtests::mouseMovements); - // FIXME: Scaled cursor crsh with odd dimmensions + // FIXME: Scaled cursor crash with odd dimmensions addTest("ScaledCursors", &GFXtests::scaledCursors); // Effects @@ -82,7 +82,7 @@ void GFXTestSuite::setCustomColor(uint r, uint g, uint b) { _palette[8] = r; _palette[9] = g; _palette[10] = b; - + // Set colorNum kColorSpecial with a special color. int absIndx = kColorSpecial * 4; _palette[absIndx + 1] = 173; @@ -270,7 +270,7 @@ void GFXtests::setupMouseLoop(bool disableCursorPalette, const char *gfxModeName if (!gfxScalarMode.equals("")) { info = "The cursor size (yellow) should match the red rectangle."; } - + Testsuite::writeOnScreen(info, pt); info = "GFX Mode"; @@ -346,7 +346,7 @@ void GFXtests::setupMouseLoop(bool disableCursorPalette, const char *gfxModeName * Used by aspectRatio() */ void GFXtests::drawEllipse(int cx, int cy, int a, int b) { - + // Take a buffer of screen size int width = g_system->getWidth(); int height = Testsuite::getDisplayRegionCoordinates().y; @@ -397,22 +397,22 @@ void GFXtests::drawEllipse(int cx, int cy, int a, int b) { /** * Tests the fullscreen mode by: toggling between fullscreen and windowed mode */ -bool GFXtests::fullScreenMode() { +TestExitStatus GFXtests::fullScreenMode() { Testsuite::clearScreen(); Common::String info = "Fullscreen test. Here you should expect a toggle between windowed and fullscreen states depending " "upon your initial state."; Common::Point pt(0, 100); Testsuite::writeOnScreen("Testing fullscreen mode", pt); - + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { Testsuite::logPrintf("Info! Skipping test : FullScreenMode\n"); - return true; + return kTestSkipped; } bool isFeaturePresent; bool isFeatureEnabled; - bool passed = true; + TestExitStatus passed = kTestPassed; Common::String prompt; OptionSelected shouldSelect; @@ -435,7 +435,7 @@ bool GFXtests::fullScreenMode() { if (!Testsuite::handleInteractiveInput(prompt, "Fullscreen", "Windowed", shouldSelect)) { // User selected incorrect current state - passed = false; + passed = kTestFailed; Testsuite::logDetailedPrintf("g_system->getFeatureState() failed\n"); } @@ -453,7 +453,7 @@ bool GFXtests::fullScreenMode() { if (!Testsuite::handleInteractiveInput(prompt, "Fullscreen", "Windowed", shouldSelect)) { // User selected incorrect mode - passed = false; + passed = kTestFailed; Testsuite::logDetailedPrintf("g_system->setFeatureState() failed\n"); } @@ -468,7 +468,7 @@ bool GFXtests::fullScreenMode() { if (!Testsuite::handleInteractiveInput(prompt, "Yes, it is", "Nopes", shouldSelect)) { // User selected incorrect mode Testsuite::logDetailedPrintf("switching back to initial state failed\n"); - passed = false; + passed = kTestFailed; } } else { @@ -481,22 +481,22 @@ bool GFXtests::fullScreenMode() { /** * Tests the aspect ratio correction by: drawing an ellipse, when corrected the ellipse should render to a circle */ -bool GFXtests::aspectRatio() { - +TestExitStatus GFXtests::aspectRatio() { + Testsuite::clearScreen(); Common::String info = "Aspect Ratio Correction test. If aspect ratio correction is enabled you should expect a circle on screen," " an ellipse otherwise."; if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { Testsuite::logPrintf("Info! Skipping test : Aspect Ratio\n"); - return true; + return kTestSkipped; } // Draw an ellipse on the screen drawEllipse(80, 160, 72, 60); bool isFeaturePresent; bool isFeatureEnabled; - bool passed = true; + TestExitStatus passed = kTestPassed; Common::String prompt; OptionSelected shouldSelect; @@ -510,7 +510,7 @@ bool GFXtests::aspectRatio() { prompt = " What does the curve on screen appears to you ?"; if (!Testsuite::handleInteractiveInput(prompt, "Circle", "Ellipse", shouldSelect)) { // User selected incorrect option - passed = false; + passed = kTestFailed; Testsuite::logDetailedPrintf("Aspect Ratio Correction failed\n"); } @@ -524,7 +524,7 @@ bool GFXtests::aspectRatio() { prompt = " What does the curve on screen appears to you ?"; if (!Testsuite::handleInteractiveInput(prompt, "Circle", "Ellipse", shouldSelect)) { // User selected incorrect option - passed = false; + passed = kTestFailed; Testsuite::logDetailedPrintf("Aspect Ratio Correction failed\n"); } @@ -540,7 +540,7 @@ bool GFXtests::aspectRatio() { if (Testsuite::handleInteractiveInput("This should definetely be your initial state?", "Yes, it is", "Nopes", kOptionRight)) { // User selected incorrect mode Testsuite::logDetailedPrintf("Switching back to initial state failed\n"); - passed = false; + passed = kTestFailed; } return passed; @@ -550,7 +550,7 @@ bool GFXtests::aspectRatio() { * Tests Palettized cursors. * Method: Create a yellow colored cursor, should be able to move it. Once you click test terminates */ -bool GFXtests::palettizedCursors() { +TestExitStatus GFXtests::palettizedCursors() { Testsuite::clearScreen(); Common::String info = "Palettized Cursors test.\n " @@ -562,17 +562,17 @@ bool GFXtests::palettizedCursors() { if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { Testsuite::logPrintf("Info! Skipping test : Palettized Cursors\n"); - return true; + return kTestSkipped; } - - bool passed = true; + + TestExitStatus passed = kTestPassed; // Testing with cursor Palette setupMouseLoop(); - + if (Testsuite::handleInteractiveInput("Which color did the cursor appeared to you?", "Yellow", "Any other", kOptionRight)) { Testsuite::logDetailedPrintf("Couldn't use cursor palette for rendering cursor\n"); - passed = false; + passed = kTestFailed; } // Testing with game Palette @@ -581,11 +581,11 @@ bool GFXtests::palettizedCursors() { if (Testsuite::handleInteractiveInput("Which color did the cursor appeared to you?", "Red", "Any other", kOptionRight)) { Testsuite::logDetailedPrintf("Couldn't use Game palette for rendering cursor\n"); - passed = false; + passed = kTestFailed; } - if (!Testsuite::handleInteractiveInput("Did test run as was described?")) { - passed = false; + if (!Testsuite::handleInteractiveInput(" Did test run as was described? ")) { + passed = kTestFailed; } // re-enable cursor palette @@ -599,22 +599,24 @@ bool GFXtests::palettizedCursors() { * Tests automated mouse movements. "Warp" functionality provided by the backend. */ -bool GFXtests::mouseMovements() { +TestExitStatus GFXtests::mouseMovements() { Testsuite::clearScreen(); - // Make mouse visible + // Ensure that the cursor is visible CursorMan.showMouse(true); - + Common::String info = "Testing Automated Mouse movements.\n" "You should expect cursor hotspot(top-left corner) to automatically move from (0, 0) to (100, 100).\n" "There we have a rectangle drawn, finally the cursor would lie centred in that rectangle."; if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { Testsuite::logPrintf("Info! Skipping test : Mouse Movements\n"); - return true; + return kTestSkipped; } - + // Draw Rectangle Graphics::Surface *screen = g_system->lockScreen(); + // Ensure that 2 represents red in current palette + GFXTestSuite::setCustomColor(255, 0, 0); screen->fillRect(Common::Rect::center(106, 106, 14, 14), 2); g_system->unlockScreen(); @@ -635,11 +637,11 @@ bool GFXtests::mouseMovements() { g_system->delayMillis(1500); CursorMan.showMouse(false); - if (Testsuite::handleInteractiveInput("Was the cursor symmetrically contained in the rectangle at (100, 100)?", "Yes", "No", kOptionRight)) { - return false; + if (Testsuite::handleInteractiveInput("Was the cursor centred in the rectangle at (100, 100)?", "Yes", "No", kOptionRight)) { + return kTestFailed; } - return true; + return kTestPassed; } @@ -648,17 +650,17 @@ bool GFXtests::mouseMovements() { * This basically blits the screen by the contents of its buffer. * */ -bool GFXtests::copyRectToScreen() { - +TestExitStatus GFXtests::copyRectToScreen() { + Testsuite::clearScreen(); Common::String info = "Testing Blitting a Bitmap to screen.\n" "You should expect to see a 20x40 yellow horizontal rectangle centred at the screen."; if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { Testsuite::logPrintf("Info! Skipping test : Blitting Bitmap\n"); - return true; + return kTestSkipped; } - + GFXTestSuite::setCustomColor(255, 255, 0); byte buffer[20 * 40]; memset(buffer, 2, 20 * 40); @@ -670,28 +672,28 @@ bool GFXtests::copyRectToScreen() { g_system->updateScreen(); g_system->delayMillis(1000); - if (Testsuite::handleInteractiveInput("Did you see yellow rectangle?", "Yes", "No", kOptionRight)) { - return false; + if (Testsuite::handleInteractiveInput(" Did you see yellow rectangle ? ", "Yes", "No", kOptionRight)) { + return kTestFailed; } - return true; + return kTestPassed; } /** * Testing feature : Iconifying window * It is expected the screen minimizes when this feature is enabled */ -bool GFXtests::iconifyWindow() { - +TestExitStatus GFXtests::iconifyWindow() { + Testsuite::clearScreen(); Common::String info = "Testing Iconify Window mode.\n If the feature is supported by the backend, " "you should expect the window to be minimized.\n However you would manually need to de-iconify."; if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { Testsuite::logPrintf("Info! Skipping test : Iconifying window\n"); - return true; + return kTestSkipped; } - + Common::Point pt(0, 100); Testsuite::writeOnScreen("Testing Iconifying window", pt); @@ -718,27 +720,33 @@ bool GFXtests::iconifyWindow() { Testsuite::displayMessage("feature not supported"); } - if (Testsuite::handleInteractiveInput("Did you see window minimized?", "Yes", "No", kOptionRight)) { - return false; + if (Testsuite::handleInteractiveInput(" Did you see the window minimized? ", "Yes", "No", kOptionRight)) { + return kTestFailed; } - return true; + return kTestPassed; } /** * Testing feature: Scaled cursors */ -bool GFXtests::scaledCursors() { +TestExitStatus GFXtests::scaledCursors() { Testsuite::clearScreen(); Common::String info = "Testing : Scaled cursors\n" "Here every graphics mode is tried with a cursorTargetScale of 1, 2 and 3.\n" - "The expected cursor size is drawn as a rectangle, the cursor should entirely cover that rectangle.\n" + "The expected cursor size is drawn as a rectangle.\n The cursor should approximately match that rectangle.\n" "This may take time, You may skip the later scalers and just examine the first three i.e 1x, 2x and 3x"; + bool isAspectRatioCorrected = g_system->getFeatureState(OSystem::kFeatureAspectRatioCorrection); + + if (isAspectRatioCorrected) { + info += "\nDisabling Aspect ratio correction, for letting cusors match exactly, will be restored after this test."; + } + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { Testsuite::logPrintf("Info! Skipping test : Scaled Cursors\n"); - return true; + return kTestSkipped; } int maxLimit = 1000; @@ -746,6 +754,13 @@ bool GFXtests::scaledCursors() { maxLimit = 3; } + + if (isAspectRatioCorrected) { + g_system->beginGFXTransaction(); + g_system->setFeatureState(OSystem::kFeatureAspectRatioCorrection, false); + g_system->endGFXTransaction(); + } + const int currGFXMode = g_system->getGraphicsMode(); const OSystem::GraphicsMode *gfxMode = g_system->getSupportedGraphicsModes(); @@ -753,6 +768,20 @@ bool GFXtests::scaledCursors() { // for every graphics mode display cursors for cursorTargetScale 1, 2 and 3 // Switch Graphics mode // FIXME: Crashes with "3x" mode now.: + + info = Common::String::printf("Testing : Scaled cursors with GFX Mode %s\n", gfxMode->name); + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { + Testsuite::logPrintf("\tInfo! Skipping sub-test : Scaled Cursors :: GFX Mode %s\n", gfxMode->name); + gfxMode++; + maxLimit--; + continue; + } + if (Engine::shouldQuit()) { + // Explicit exit requested + Testsuite::logPrintf("Info! Explicit exit requested during scaling test, this test may be incomplete\n"); + return kTestSkipped; + } + g_system->beginGFXTransaction(); bool isGFXModeSet = g_system->setGraphicsMode(gfxMode->id); @@ -771,67 +800,86 @@ bool GFXtests::scaledCursors() { Testsuite::clearScreen(); } else { Testsuite::logDetailedPrintf("Switching to graphics mode %s failed\n", gfxMode->name); - return false; + return kTestFailed; } gfxMode++; maxLimit--; + + info = "Did the expected cursor size and the actual cursor size matched?"; + if (Testsuite::handleInteractiveInput(info, "Yes", "No", kOptionRight)) { + Testsuite::logPrintf("\tInfo! Failed sub-test : Scaled Cursors :: GFX Mode %s\n", gfxMode->name); + } + + if (Engine::shouldQuit()) { + // Explicit exit requested + Testsuite::logPrintf("Info! Explicit exit requested during scaling test, this test may be incomplete\n"); + return kTestSkipped; + } + } // Restore Original State g_system->beginGFXTransaction(); bool isGFXModeSet = g_system->setGraphicsMode(currGFXMode); g_system->initSize(320, 200); + + if (isAspectRatioCorrected) { + g_system->setFeatureState(OSystem::kFeatureAspectRatioCorrection, true); + } + OSystem::TransactionError gfxError = g_system->endGFXTransaction(); if (gfxError != OSystem::kTransactionSuccess || !isGFXModeSet) { Testsuite::logDetailedPrintf("Switcing to initial state failed\n"); - return false; + return kTestFailed; } // Done with cursors, Make them invisible, any other test may enable and use it. CursorMan.showMouse(false); - return true; + return kTestPassed; } -bool GFXtests::shakingEffect() { - +TestExitStatus GFXtests::shakingEffect() { + Testsuite::clearScreen(); Common::String info = "Shaking test. You should expect the graphics(text/bars etc) drawn on the screen to shake!"; if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { Testsuite::logPrintf("Info! Skipping test : Shaking Effect\n"); - return true; + return kTestSkipped; } Common::Point pt(0, 100); Testsuite::writeOnScreen("If Shaking Effect works, this should shake!", pt); - int times = 35; + int times = 15; while (times--) { g_system->setShakePos(25); + g_system->delayMillis(50); g_system->updateScreen(); g_system->setShakePos(0); + g_system->delayMillis(50); g_system->updateScreen(); } g_system->delayMillis(1500); if (Testsuite::handleInteractiveInput("Did the Shaking test worked as you were expecting?", "Yes", "No", kOptionRight)) { Testsuite::logDetailedPrintf("Shaking Effect didn't worked"); - return false; + return kTestFailed; } - return true; + return kTestPassed; } -bool GFXtests::focusRectangle() { - +TestExitStatus GFXtests::focusRectangle() { + Testsuite::clearScreen(); Common::String info = "Testing : Setting and hiding Focus \n" "If this feature is implemented, the focus should be toggled between the two rectangles on the corners"; if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { Testsuite::logPrintf("Info! Skipping test : focus Rectangle\n"); - return true; + return kTestSkipped; } - + const Graphics::Font &font(*FontMan.getFontByUsage(Graphics::FontManager::kConsoleFont)); Graphics::Surface *screen = g_system->lockScreen(); @@ -867,18 +915,18 @@ bool GFXtests::focusRectangle() { Testsuite::logDetailedPrintf("Focus Rectangle feature doesn't works. Check platform.\n"); } - return true; + return kTestPassed; } -bool GFXtests::overlayGraphics() { +TestExitStatus GFXtests::overlayGraphics() { Testsuite::clearScreen(); Common::String info = "Overlay Graphics. You should expect to see a green colored rectangle on the screen"; if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { Testsuite::logPrintf("Info! Skipping test : Overlay Graphics\n"); - return true; + return kTestSkipped; } - + Graphics::PixelFormat pf = g_system->getOverlayFormat(); OverlayColor buffer[50 * 100]; @@ -899,22 +947,24 @@ bool GFXtests::overlayGraphics() { if (Testsuite::handleInteractiveInput("Did you see a green overlayed rectangle?", "Yes", "No", kOptionRight)) { Testsuite::logDetailedPrintf("Overlay Rectangle feature doesn't works\n"); - return false; + return kTestFailed; } - return true; + return kTestPassed; } -bool GFXtests::paletteRotation() { - +TestExitStatus GFXtests::paletteRotation() { + Common::String info = "Palette rotation. Here we draw a full 256 colored rainbow and then rotate it.\n" "Note that the screen graphics change without having to draw anything.\n" - "The palette should appear to rotate, Click the mouse button to exit."; + "The palette should appear to rotate, as a result, the background will change its color too.\n" + "Click the mouse button to exit."; if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { Testsuite::logPrintf("Info! Skipping test : palette Rotation\n"); - return true; + return kTestSkipped; } + Common::Point pt(0, 10); Testsuite::clearEntireScreen(); // Use 256 colors @@ -951,7 +1001,7 @@ bool GFXtests::paletteRotation() { } g_system->copyRectToScreen(buffer, 256, 22, 50, 256, 30); - + // Show mouse CursorMan.showMouse(true); g_system->updateScreen(); @@ -959,7 +1009,7 @@ bool GFXtests::paletteRotation() { bool toRotate = true; Common::Event event; - + while (toRotate) { while (g_system->getEventManager()->pollEvent(event)) { if (event.type == Common::EVENT_LBUTTONDOWN || event.type == Common::EVENT_RBUTTONDOWN) { @@ -979,41 +1029,41 @@ bool GFXtests::paletteRotation() { GFXTestSuite::setCustomColor(255, 0, 0); Testsuite::clearScreen(); - if(Testsuite::handleInteractiveInput("Did you saw a rotation in colors of rectangles displayed on screen?", "Yes", "No", kOptionRight)) { - return false; + if(Testsuite::handleInteractiveInput("Did you see a rotation in colors of rectangles displayed on screen?", "Yes", "No", kOptionRight)) { + return kTestFailed; } - return true; + return kTestPassed; } -bool GFXtests::cursorTrails() { +TestExitStatus GFXtests::cursorTrails() { Common::String info = "With some shake offset the cursor was known to leave trails in the GUI\n" "Here we set some offset and ask user to check for mouse trails, \n" "the test is passed when there are no trails"; if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { Testsuite::logPrintf("Info! Skipping test : Cursor Trails\n"); - return true; + return kTestSkipped; } - bool passed = false; + TestExitStatus passed = kTestFailed; g_system->setShakePos(25); g_system->updateScreen(); if (Testsuite::handleInteractiveInput("Does the cursor leaves trails while moving?", "Yes", "No", kOptionRight)) { - passed = true; + passed = kTestPassed; } g_system->setShakePos(0); g_system->updateScreen(); return passed; } -bool GFXtests::pixelFormats() { +TestExitStatus GFXtests::pixelFormats() { Testsuite::clearScreen(); Common::String info = "Testing pixel formats. Here we iterate over all the supported pixel formats and display some colors using them\n" "This may take long, especially if the backend supports many pixel formats"; if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { - Testsuite::logPrintf("Info! Skipping test : focus Rectangle\n"); - return true; + Testsuite::logPrintf("Info! Skipping test : Pixel Formats\n"); + return kTestSkipped; } Common::List<Graphics::PixelFormat> pfList = g_system->getSupportedFormats(); @@ -1054,7 +1104,6 @@ bool GFXtests::pixelFormats() { Common::Point pt(0, 170); Common::String msg; - // XXX: Can use snprintf? msg = Common::String::printf("Testing Pixel Formats, %d of %d", numFormatsTested, pfList.size()); Testsuite::writeOnScreen(msg, pt, true); @@ -1091,11 +1140,11 @@ bool GFXtests::pixelFormats() { Testsuite::clearScreen(); if (numFailed) { - Testsuite::logDetailedPrintf("Pixel Format test: Failed : %d, Passed : %d, Ignored %d\n", numFailed, numPassed, numFormatsTested - (numPassed + numFailed)); - return false; + Testsuite::logDetailedPrintf("Pixel Format test: Failed : %d, Passed : %d, Ignored %d\n",numFailed, numPassed, numFormatsTested - (numPassed + numFailed)); + return kTestFailed; } - return true; + return kTestPassed; } } // End of namespace Testbed diff --git a/engines/testbed/graphics.h b/engines/testbed/graphics.h index 42ab5df59e..4ab4ba65ab 100644 --- a/engines/testbed/graphics.h +++ b/engines/testbed/graphics.h @@ -40,19 +40,19 @@ 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(); +TestExitStatus cursorTrails(); +TestExitStatus fullScreenMode(); +TestExitStatus aspectRatio(); +TestExitStatus palettizedCursors(); +TestExitStatus mouseMovements(); +TestExitStatus copyRectToScreen(); +TestExitStatus iconifyWindow(); +TestExitStatus scaledCursors(); +TestExitStatus shakingEffect(); +TestExitStatus focusRectangle(); +TestExitStatus overlayGraphics(); +TestExitStatus paletteRotation(); +TestExitStatus pixelFormats(); // add more here } // End of namespace GFXtests diff --git a/engines/testbed/midi.cpp b/engines/testbed/midi.cpp new file mode 100644 index 0000000000..0ec2678d47 --- /dev/null +++ b/engines/testbed/midi.cpp @@ -0,0 +1,155 @@ +/* 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/archive.h" +#include "common/events.h" + +#include "graphics/cursorman.h" + +#include "sound/mididrv.h" + +#include "testbed/midi.h" +#include "testbed/testbed.h" + +namespace Testbed { + +bool MidiTests::loadMusicInMemory(Common::MemoryWriteStreamDynamic *ws) { + Common::SeekableReadStream *midiFile = SearchMan.createReadStreamForMember("music.mid"); + if (!midiFile) { + Testsuite::logPrintf("Error! Can't open Midi music file, check game data directory for file music.mid\n"); + return false; + } + + while (!midiFile->eos()) { + byte data = midiFile->readByte(); + ws->writeByte(data); + } + return true; +} + +void MidiTests::waitForMusicToPlay(MidiParser *parser) { + Common::EventManager *eventMan = g_system->getEventManager(); + bool quitLoop = false; + Common::Event event; + + CursorMan.showMouse(true); + while (!quitLoop) { + while (eventMan->pollEvent(event)) { + // Quit if explicitly requested! + if (Engine::shouldQuit()) { + return; + } + + if (event.type == Common::EVENT_LBUTTONDOWN || event.type == Common::EVENT_RBUTTONDOWN) { + quitLoop = true; + } else { + Testsuite::writeOnScreen("Playing Midi Music, Click to end", Common::Point(0, 100)); + if (!parser->isPlaying()) { + quitLoop = true; + } + } + } + } + CursorMan.showMouse(false); + return; +} + +TestExitStatus MidiTests::playMidiMusic() { + Testsuite::clearScreen(); + Common::String info = "Testing Midi Sound output.\n" + "Here, We generate some Music by using the Midi Driver selected in the GUI.\n" + "You should expect to hear that. The initialization may take some time.\n"; + + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { + Testsuite::logPrintf("Info! Skipping test : Play Midi Music\n"); + return kTestSkipped; + } + + MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB); + // Create a driver instance + MidiDriver *driver = MidiDriver::createMidi(dev); + // Create a SMF parser + MidiParser *smfParser = MidiParser::createParser_SMF(); + // Open the driver + int errCode = driver->open(); + + if (errCode) { + Common::String errMsg = driver->getErrorName(errCode); + Testsuite::writeOnScreen(errMsg, Common::Point(0, 100)); + Testsuite::logPrintf("Error! %s", errMsg.c_str()); + return kTestFailed; + } + + Testsuite::logDetailedPrintf("Info! Midi: Succesfully opened the driver\n"); + + Common::MemoryWriteStreamDynamic ws(DisposeAfterUse::YES); + loadMusicInMemory(&ws); + + // start playing + if (smfParser->loadMusic(ws.getData(), ws.size())) { + smfParser->setTrack(0); + smfParser->setMidiDriver(driver); + smfParser->setTimerRate(driver->getBaseTempo()); + driver->setTimerCallback(smfParser, MidiParser::timerCallback); + Testsuite::logDetailedPrintf("Info! Midi: Parser Successfully loaded Music data.\n"); + if (smfParser->isPlaying()) { + Testsuite::writeOnScreen("Playing Midi Music, Click to end.", Common::Point(0, 100)); + Testsuite::logDetailedPrintf("Info! Midi: Playing music!\n"); + } + } + + + // Play until track ends or an exit is requested. + waitForMusicToPlay(smfParser); + + // Done. Clean up. + smfParser->unloadMusic(); + driver->setTimerCallback(NULL, NULL); + driver->close(); + delete smfParser; + delete driver; + + if (Testsuite::handleInteractiveInput("Were you able to hear the music as described?", "Yes", "No", kOptionRight)) { + Testsuite::logDetailedPrintf("Error! Midi: Can't play Music\n"); + return kTestFailed; + } + return kTestPassed; +} + +MidiTestSuite::MidiTestSuite() { + addTest("MidiTests", &MidiTests::playMidiMusic); + _isMidiDataFound = true; + if (!SearchMan.hasFile("music.mid")) { + // add some fallback test if filesystem loading failed + Testsuite::logPrintf("Warning! Midi: Sound data file music.mid not found\n"); + _isMidiDataFound = false; + enable(false); + } +} + +void MidiTestSuite::enable(bool flag) { + Testsuite::enable(_isMidiDataFound & flag); +} + +} diff --git a/engines/testbed/midi.h b/engines/testbed/midi.h new file mode 100644 index 0000000000..c73d937834 --- /dev/null +++ b/engines/testbed/midi.h @@ -0,0 +1,77 @@ +/* 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_MIDI_H +#define TESTBED_MIDI_H + +#include "common/stream.h" +#include "sound/midiparser.h" +#include "testbed/testsuite.h" + +// This file can be used as template for header files of other newer testsuites. + +namespace Testbed { + +namespace MidiTests { + +// Helper functions for MIDI tests +bool loadMusicInMemory(Common::MemoryWriteStreamDynamic *ws); +void waitForMusicToPlay(MidiParser *parser); + +// will contain function declarations for MIDI tests +// add more here +TestExitStatus playMidiMusic(); + +} // End of namespace MIDItests + +class MidiTestSuite : 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() + */ + MidiTestSuite(); + ~MidiTestSuite() {} + const char *getName() const { + return "MIDI"; + } + + const char *getDescription() const { + return "Midi Music"; + } + + void enable(bool flag); + +private: + bool _isMidiDataFound; + +}; + +} // End of namespace Testbed + +#endif // TESTBED_MIDI_H diff --git a/engines/testbed/misc.cpp b/engines/testbed/misc.cpp index 74f0af2948..2159974c51 100644 --- a/engines/testbed/misc.cpp +++ b/engines/testbed/misc.cpp @@ -66,28 +66,28 @@ void MiscTests::criticalSection(void *arg) { g_system->getTimerManager()->removeTimerProc(criticalSection); } -bool MiscTests::testDateTime() { - - if (Testsuite::isSessionInteractive) { +TestExitStatus MiscTests::testDateTime() { + + if (ConfParams.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; + return kTestSkipped; } - + 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) { + if (ConfParams.isSessionInteractive()) { // Directly verify date dateTimeNow = "We expect the current date time to be " + dateTimeNow; if (Testsuite::handleInteractiveInput(dateTimeNow, "Correct!", "Wrong", kOptionRight)) { - return false; + return kTestFailed; } } @@ -105,32 +105,32 @@ bool MiscTests::testDateTime() { 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 kTestPassed; } } } - return false; + return kTestFailed; } -bool MiscTests::testTimers() { +TestExitStatus 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 kTestPassed; } } - return false; + return kTestFailed; } -bool MiscTests::testMutexes() { - - if (Testsuite::isSessionInteractive) { +TestExitStatus MiscTests::testMutexes() { + + if (ConfParams.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; + return kTestSkipped; } Testsuite::writeOnScreen("Installing mutex", Common::Point(0, 100)); } @@ -148,7 +148,7 @@ bool MiscTests::testMutexes() { g_system->unlockMutex(sv.mutex); // wait till timed process exits - if (Testsuite::isSessionInteractive) { + if (ConfParams.isSessionInteractive()) { Testsuite::writeOnScreen("Waiting for 3s so that timed processes finish", Common::Point(0, 100)); } g_system->delayMillis(3000); @@ -157,10 +157,10 @@ bool MiscTests::testMutexes() { g_system->deleteMutex(sv.mutex); if (sv.resultSoFar && 6 == sv.second) { - return true; + return kTestPassed; } - return false; + return kTestFailed; } MiscTestSuite::MiscTestSuite() { diff --git a/engines/testbed/misc.h b/engines/testbed/misc.h index 1ca01224e5..395955c7fe 100644 --- a/engines/testbed/misc.h +++ b/engines/testbed/misc.h @@ -48,9 +48,9 @@ void timerCallback(void *arg); void criticalSection(void *arg); // will contain function declarations for Misc tests -bool testDateTime(); -bool testTimers(); -bool testMutexes(); +TestExitStatus testDateTime(); +TestExitStatus testTimers(); +TestExitStatus testMutexes(); // add more here } // End of namespace MiscTests diff --git a/engines/testbed/module.mk b/engines/testbed/module.mk index 4c530e412a..ce78a48bc5 100644 --- a/engines/testbed/module.mk +++ b/engines/testbed/module.mk @@ -2,10 +2,12 @@ MODULE := engines/testbed MODULE_OBJS := \ config.o \ + config-params.o \ detection.o \ events.o \ fs.o \ graphics.o \ + midi.o \ misc.o \ savegame.o \ sound.o \ diff --git a/engines/testbed/savegame.cpp b/engines/testbed/savegame.cpp index 80c83725d2..b91d9fc47c 100644 --- a/engines/testbed/savegame.cpp +++ b/engines/testbed/savegame.cpp @@ -67,29 +67,29 @@ bool SaveGametests::readAndVerifyData(const char *fileName, const char *expected return false; } -bool SaveGametests::testSaveLoadState() { +TestExitStatus 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; + return kTestFailed; } // Verify if it contains the same data if (!readAndVerifyData("tBedSavefile.0", "ScummVM Rocks!")) { Testsuite::logDetailedPrintf("Reading data from savefile failed\n"); - return false; + return kTestFailed; } - return true; + return kTestPassed; } -bool SaveGametests::testRemovingSavefile() { +TestExitStatus 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; + return kTestFailed; } // Remove it @@ -100,18 +100,18 @@ bool SaveGametests::testRemovingSavefile() { if (loadFile) { // Removing failed Testsuite::logDetailedPrintf("Removing savefile failed\n"); - return false; + return kTestFailed; } - return true; + return kTestPassed; } -bool SaveGametests::testRenamingSavefile() { +TestExitStatus 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; + return kTestFailed; } // Rename it @@ -120,13 +120,13 @@ bool SaveGametests::testRenamingSavefile() { // Verify if it contains the same data if (!readAndVerifyData("tBedSomeCoolName.0", "Rename me!")) { Testsuite::logDetailedPrintf("Renaming savefile failed\n"); - return false; + return kTestFailed; } - return true; + return kTestPassed; } -bool SaveGametests::testListingSavefile() { +TestExitStatus SaveGametests::testListingSavefile() { Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); saveFileMan->clearError(); @@ -141,7 +141,7 @@ bool SaveGametests::testListingSavefile() { if (error != Common::kNoError) { // Abort. Some Error in writing files Testsuite::logDetailedPrintf("Error while creating savefiles: %s\n", Common::errorToString(error)); - return false; + return kTestFailed; } Common::StringArray savefileList = saveFileMan->listSavefiles("tBedSavefileToList.?"); @@ -156,20 +156,20 @@ bool SaveGametests::testListingSavefile() { if (savefileList.size() == j) { // A match for this name not found Testsuite::logDetailedPrintf("Listed Names don't match\n"); - return false; + return kTestFailed; } } } - return true; + return kTestPassed; } else { Testsuite::logDetailedPrintf("listing Savefiles failed!\n"); - return false; + return kTestFailed; } - return false; + return kTestFailed; } -bool SaveGametests::testErrorMessages() { +TestExitStatus SaveGametests::testErrorMessages() { Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); saveFileMan->clearError(); @@ -180,12 +180,12 @@ bool SaveGametests::testErrorMessages() { if (error == Common::kNoError) { // blunder! how come? Testsuite::logDetailedPrintf("SaveFileMan.getError() failed\n"); - return false; + return kTestFailed; } // Can't actually predict whether which error, kInvalidPath or kPathDoesNotExist or some other? - // So just return true if some error + // So just return kTestPassed if some error Testsuite::logDetailedPrintf("getError returned : %s\n", saveFileMan->getErrorDesc().c_str()); - return true; + return kTestPassed; } SaveGameTestSuite::SaveGameTestSuite() { diff --git a/engines/testbed/savegame.h b/engines/testbed/savegame.h index 98d630d237..dc41ff9b65 100644 --- a/engines/testbed/savegame.h +++ b/engines/testbed/savegame.h @@ -35,11 +35,11 @@ namespace SaveGametests { 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(); +TestExitStatus testSaveLoadState(); +TestExitStatus testRemovingSavefile(); +TestExitStatus testRenamingSavefile(); +TestExitStatus testListingSavefile(); +TestExitStatus testErrorMessages(); // add more here } // End of namespace SaveGametests diff --git a/engines/testbed/sound.cpp b/engines/testbed/sound.cpp index 89aede7ef8..e256621553 100644 --- a/engines/testbed/sound.cpp +++ b/engines/testbed/sound.cpp @@ -50,15 +50,15 @@ SoundSubsystemDialog::SoundSubsystemDialog() : TestbedInteractionDialog(80, 60, _mixer = g_system->getMixer(); - // the three streams to be mixed + // 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); @@ -72,7 +72,7 @@ SoundSubsystemDialog::SoundSubsystemDialog() : TestbedInteractionDialog(80, 60, void SoundSubsystemDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) { - + switch (cmd) { case kPlayChannel1: _buttonArray[0]->setLabel("Pause Channel #1"); @@ -110,89 +110,86 @@ void SoundSubsystemDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, } } -bool SoundSubsystem::playBeeps() { +TestExitStatus SoundSubsystem::playBeeps() { Testsuite::clearScreen(); - bool passed = true; + TestExitStatus passed = kTestPassed; 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; + return kTestSkipped; } - + 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)) { + + 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; + passed = kTestFailed; } - + // 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; + passed = kTestFailed; } return passed; } -bool SoundSubsystem::mixSounds() { +TestExitStatus SoundSubsystem::mixSounds() { Testsuite::clearScreen(); - bool passed = true; + TestExitStatus passed = kTestPassed; 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; + return kTestSkipped; } 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; + passed = kTestFailed; } return passed; } -bool SoundSubsystem::audiocdOutput() { +TestExitStatus SoundSubsystem::audiocdOutput() { Testsuite::clearScreen(); - bool passed = true; + TestExitStatus passed = kTestPassed; 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; + return kTestSkipped; } - + 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++) { + for (int i = 1; i < 5; i++) { AudioCD.play(i, 1, 0, 0); while (AudioCD.isPlaying()) { g_system->delayMillis(500); @@ -204,14 +201,23 @@ bool SoundSubsystem::audiocdOutput() { 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; + passed = kTestFailed; } - + return passed; } -bool SoundSubsystem::sampleRates() { - bool passed = true; +TestExitStatus SoundSubsystem::sampleRates() { + + Common::String info = "Testing Multiple Sample Rates.\n" + "Here we try to play sounds at three different sample rates."; + + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { + Testsuite::logPrintf("Info! Skipping test : Sample Rates\n"); + return kTestSkipped; + } + + TestExitStatus passed = kTestPassed; Audio::Mixer *mixer = g_system->getMixer(); Audio::PCSpeaker *s1 = new Audio::PCSpeaker(); @@ -219,14 +225,14 @@ bool SoundSubsystem::sampleRates() { 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); @@ -244,11 +250,11 @@ bool SoundSubsystem::sampleRates() { 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; + passed = kTestFailed; } return passed; @@ -257,7 +263,17 @@ bool SoundSubsystem::sampleRates() { SoundSubsystemTestSuite::SoundSubsystemTestSuite() { addTest("SimpleBeeps", &SoundSubsystem::playBeeps, true); addTest("MixSounds", &SoundSubsystem::mixSounds, true); - addTest("AudiocdOutput", &SoundSubsystem::audiocdOutput, true); + + // Make audio-files discoverable + Common::FSNode gameRoot(ConfMan.get("path")); + if (gameRoot.exists()) { + SearchMan.addSubDirectoryMatching(gameRoot, "audiocd-files"); + if (SearchMan.hasFile("track01.mp3") && SearchMan.hasFile("track02.mp3") && SearchMan.hasFile("track03.mp3") && SearchMan.hasFile("track04.mp3")) { + addTest("AudiocdOutput", &SoundSubsystem::audiocdOutput, true); + } else { + Testsuite::logPrintf("Warning! Skipping test AudioCD: Required data files missing, check game-dir/audiocd-files\n"); + } + } addTest("SampleRates", &SoundSubsystem::sampleRates, true); } diff --git a/engines/testbed/sound.h b/engines/testbed/sound.h index 53ff96cedb..24dcf45b99 100644 --- a/engines/testbed/sound.h +++ b/engines/testbed/sound.h @@ -46,10 +46,10 @@ namespace SoundSubsystem { // Helper functions for SoundSubsystem tests // will contain function declarations for SoundSubsystem tests -bool playBeeps(); -bool mixSounds(); -bool audiocdOutput(); -bool sampleRates(); +TestExitStatus playBeeps(); +TestExitStatus mixSounds(); +TestExitStatus audiocdOutput(); +TestExitStatus sampleRates(); } class SoundSubsystemTestSuite : public Testsuite { @@ -64,15 +64,18 @@ public: */ SoundSubsystemTestSuite(); ~SoundSubsystemTestSuite() {} - + const char *getName() const { return "SoundSubsystem"; } - + const char *getDescription() const { return "Sound Subsystem"; } +private: + bool _isTestDataFound; + }; } // End of namespace Testbed diff --git a/engines/testbed/template.h b/engines/testbed/template.h index a2efca1157..849d157a03 100644 --- a/engines/testbed/template.h +++ b/engines/testbed/template.h @@ -55,7 +55,7 @@ public: const char *getName() const { return "Dummy Template"; } - + const char *getDescription() const { return "Some Arbit description"; } diff --git a/engines/testbed/testbed.cpp b/engines/testbed/testbed.cpp index ef61cd7c13..071fba8c2c 100644 --- a/engines/testbed/testbed.cpp +++ b/engines/testbed/testbed.cpp @@ -31,6 +31,7 @@ #include "testbed/events.h" #include "testbed/fs.h" #include "testbed/graphics.h" +#include "testbed/midi.h" #include "testbed/misc.h" #include "testbed/savegame.h" #include "testbed/sound.h" @@ -44,27 +45,38 @@ void TestbedExitDialog::init() { 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; - + GUI::ListWidget::ColorList colors; + 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())); + strArray.push_back(Common::String::printf("%s :", (*i)->getDescription())); + colors.push_back(GUI::ThemeEngine::kFontColorNormal); + if ((*i)->isEnabled()) { + strArray.push_back(Common::String::printf("Passed: %d Failed: %d Skipped: %d", (*i)->getNumTestsPassed(), (*i)->getNumTestsFailed(), (*i)->getNumTestsSkipped())); + } else { + strArray.push_back("Skipped"); + } + colors.push_back(GUI::ThemeEngine::kFontColorAlternate); } - - addList(0, _yOffset, 500, 200, strArray); - text = "More Details can be viewed in the Log file : " + Testsuite::getLogFile(); + + addList(0, _yOffset, 500, 200, strArray, &colors); + text = "More Details can be viewed in the Log file : " + ConfParams.getLogFilename(); addText(450, 20, text, Graphics::kTextAlignLeft, 0, 0); - text = "Directory : " + Testsuite::getLogDir(); + if (ConfParams.getLogDirectory().size()) { + text = "Directory : " + ConfParams.getLogDirectory(); + } else { + text = "Directory : ."; + } 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); + addButtonXY(_xOffset + 80, _yOffset, 120, 24, "Rerun test suite", kCmdRerunTestbed); + addButtonXY(_xOffset + 240, _yOffset, 60, 24, "Close", GUI::kCloseCmd); } void TestbedExitDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) { switch (cmd) { case kCmdRerunTestbed : - _rerun = true; - GUI::Dialog::close(); + ConfParams.setRerunFlag(true); + cmd = GUI::kCloseCmd; default: GUI::Dialog::handleCommand(sender, cmd, data); } @@ -83,6 +95,11 @@ TestbedEngine::TestbedEngine(OSystem *syst) // Do not initialize graphics here // However this is the place to specify all default directories + // Put game-data dir in search path + Common::FSNode gameRoot(ConfMan.get("path")); + if (gameRoot.exists()) { + SearchMan.addDirectory(gameRoot.getDisplayName(), gameRoot); + } DebugMan.addDebugChannel(kTestbedLogOutput, "LOG", "Log of test results generated by testbed"); DebugMan.addDebugChannel(kTestbedEngineDebug, "Debug", "Engine-specific debug statements"); @@ -107,10 +124,13 @@ TestbedEngine::TestbedEngine(OSystem *syst) // Sound ts = new SoundSubsystemTestSuite(); _testsuiteList.push_back(ts); + // Midi + ts = new MidiTestSuite(); + _testsuiteList.push_back(ts); } TestbedEngine::~TestbedEngine() { - Testsuite::deleteWriteStream(); + ConfParams.deleteWriteStream(); // Remove all of our debug levels here DebugMan.clearAllDebugChannels(); @@ -126,6 +146,9 @@ void TestbedEngine::invokeTestsuites(TestbedConfigManager &cfMan) { int numSuitesEnabled = cfMan.getNumSuitesEnabled(); for (iter = _testsuiteList.begin(); iter != _testsuiteList.end(); iter++) { + if (shouldQuit()) { + return; + } (*iter)->reset(); if ((*iter)->isEnabled()) { Testsuite::updateStats("Testsuite", (*iter)->getName(), count++, numSuitesEnabled, pt); @@ -143,26 +166,26 @@ Common::Error TestbedEngine::run() { // TODO: Implement that TestbedConfigManager cfMan(_testsuiteList, "testbed.config"); - - // Keep running if rerun requested - TestbedExitDialog tbDialog(_testsuiteList); + + // Keep running if rerun requested do { Testsuite::clearEntireScreen(); cfMan.selectTestsuites(); // Init logging - Testsuite::initLogging(true); + ConfParams.initLogging(true); + invokeTestsuites(cfMan); // Check if user wanted to exit. if (Engine::shouldQuit()) { return Common::kNoError; } - - invokeTestsuites(cfMan); + + TestbedExitDialog tbDialog(_testsuiteList); tbDialog.init(); tbDialog.run(); - } while (tbDialog.rerunRequired()); - + } while (ConfParams.isRerunRequired()); + return Common::kNoError; } diff --git a/engines/testbed/testbed.h b/engines/testbed/testbed.h index 3959865cfd..e0feb52ff5 100644 --- a/engines/testbed/testbed.h +++ b/engines/testbed/testbed.h @@ -38,7 +38,7 @@ class TestbedConfigManager; enum { kTestbedLogOutput = 1 << 0, - kTestbedEngineDebug = 1 << 2, + kTestbedEngineDebug = 1 << 2, kCmdRerunTestbed = 'crtb' }; @@ -55,28 +55,20 @@ public: 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), + TestbedExitDialog(Common::Array<Testsuite *> &testsuiteList) : TestbedInteractionDialog(80, 40, 500, 330), _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; }; diff --git a/engines/testbed/testsuite.cpp b/engines/testbed/testsuite.cpp index efd31c051d..8cb9ffe309 100644 --- a/engines/testbed/testsuite.cpp +++ b/engines/testbed/testsuite.cpp @@ -37,52 +37,6 @@ 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]; @@ -90,9 +44,11 @@ void Testsuite::logPrintf(const char *fmt, ...) { va_start(vl, fmt); vsnprintf(buffer, STRINGBUFLEN, fmt, vl); va_end(vl); + Common::WriteStream *ws = ConfigParams::instance().getLogWriteStream(); - if (_ws) { - _ws->writeString(buffer); + if (ws) { + ws->writeString(buffer); + ws->flush(); debugCN(kTestbedLogOutput, "%s", buffer); } else { debugCN(kTestbedLogOutput, "%s", buffer); @@ -107,9 +63,11 @@ void Testsuite::logDetailedPrintf(const char *fmt, ...) { va_start(vl, fmt); vsnprintf(buffer, STRINGBUFLEN, fmt, vl); va_end(vl); + Common::WriteStream *ws = ConfigParams::instance().getLogWriteStream(); - if (_ws) { - _ws->writeString(buffer); + if (ws) { + ws->writeString(buffer); + ws->flush(); debugCN(1, kTestbedLogOutput, "%s", buffer); } else { debugCN(1, kTestbedLogOutput, "%s", buffer); @@ -119,6 +77,8 @@ void Testsuite::logDetailedPrintf(const char *fmt, ...) { Testsuite::Testsuite() { _numTestsPassed = 0; _numTestsExecuted = 0; + _numTestsSkipped = 0; + _toQuit = kLoopNormal; // Initially all testsuites are enabled, disable them by calling enableTestSuite(name, false) _isTsEnabled = true; // Set custom color for progress bar @@ -134,7 +94,7 @@ Testsuite::~Testsuite() { void Testsuite::reset() { _numTestsPassed = 0; _numTestsExecuted = 0; - toQuit = kLoopNormal; + _toQuit = kLoopNormal; for (Common::Array<Test *>::iterator i = _testsToExecute.begin(); i != _testsToExecute.end(); ++i) { (*i)->passed = false; } @@ -146,6 +106,7 @@ void Testsuite::genReport() const { logPrintf("Subsystem: %s ", getName()); logPrintf("(Tests Executed: %d)\n", _numTestsExecuted); logPrintf("Passed: %d ", _numTestsPassed); + logPrintf("Skipped: %d ", _numTestsSkipped); logPrintf("Failed: %d\n", getNumTestsFailed()); logPrintf("\n"); } @@ -199,7 +160,7 @@ void Testsuite::clearScreen(const Common::Rect &rect) { 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]; @@ -274,7 +235,7 @@ uint Testsuite::parseEvents() { 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; + uint barColor = kColorSpecial; // below the text a rectangle denoting the progress in the testsuite can be drawn. int separation = getLineSeparation(); pt.y += separation; @@ -289,7 +250,7 @@ void Testsuite::updateStats(const char *prefix, const char *info, uint testNum, // 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) { @@ -318,11 +279,6 @@ bool Testsuite::enableTest(const Common::String &testName, bool toEnable) { 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(); @@ -331,41 +287,45 @@ void Testsuite::execute() { 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; + _numTestsSkipped++; continue; } - if((*i)->isInteractive && !isSessionInteractive) { + if((*i)->isInteractive && !ConfParams.isSessionInteractive()) { logPrintf("Info! Skipping Test: %s, non-interactive environment is selected\n", ((*i)->featureName).c_str()); + _numTestsSkipped++; continue; } logPrintf("Info! Executing Test: %s\n", ((*i)->featureName).c_str()); updateStats("Test", ((*i)->featureName).c_str(), count++, numEnabledTests, pt); - _numTestsExecuted++; - if ((*i)->driver()) { + + // Run the test and capture exit status. + TestExitStatus eStatus = (*i)->driver(); + if (kTestPassed == eStatus) { logPrintf("Result: Passed\n"); + _numTestsExecuted++; _numTestsPassed++; + } else if (kTestSkipped == eStatus){ + logPrintf("Result: Skipped\n"); + _numTestsSkipped++; } else { + _numTestsExecuted++; 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; + _toQuit = kEngineQuit; genReport(); return; } - toQuit = parseEvents(); + _toQuit = parseEvents(); } genReport(); } diff --git a/engines/testbed/testsuite.h b/engines/testbed/testsuite.h index bd05f36e87..a738f40764 100644 --- a/engines/testbed/testsuite.h +++ b/engines/testbed/testsuite.h @@ -31,6 +31,8 @@ #include "graphics/fontman.h" +#include "testbed/config-params.h" + namespace Testbed { enum { @@ -53,7 +55,13 @@ enum { kEventHandlingTime = 50 }; -typedef bool (*InvokingFunction)(); +enum TestExitStatus { + kTestPassed = 0, + kTestSkipped, + kTestFailed +}; + +typedef TestExitStatus (*InvokingFunction)(); /** * This represents a feature to be tested @@ -85,6 +93,7 @@ public: virtual ~Testsuite(); int getNumTests() const { return _testsToExecute.size(); } int getNumTestsPassed() const { return _numTestsPassed; } + int getNumTestsSkipped() const { return _numTestsSkipped; } int getNumTestsFailed() const { return _numTestsExecuted - _numTestsPassed; } void genReport() const; bool isEnabled() const { return _isTsEnabled; } @@ -93,7 +102,7 @@ public: } 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" @@ -136,20 +145,9 @@ public: 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. @@ -162,15 +160,13 @@ public: // 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 + pt.y -= (FontMan.getFontByUsage(ConfParams.getCurrentFontUsageType())->getFontHeight() * 3 + 15); // Buffer of 5 pixels per line return pt; } static uint getLineSeparation() { - return FontMan.getFontByUsage(_displayFont)->getFontHeight() + 5; + return FontMan.getFontByUsage(ConfParams.getCurrentFontUsageType())->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; } @@ -180,33 +176,15 @@ protected: Common::Array<Test *> _testsToExecute; ///< List of tests to be executed int _numTestsPassed; ///< Number of tests passed int _numTestsExecuted; ///< Number of tests executed + int _numTestsSkipped; 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 + * Used from the code to decide if the engine needs to exit */ - static Graphics::FontManager::FontUsage _displayFont; + uint _toQuit; }; } // End of namespace Testbed |