/************************************************************************
MeOS - Orienteering Software
Copyright (C) 2009-2019 Melin Software HB
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 3 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, see .
Melin Software HB - software@melin.nu - www.melin.nu
Eksoppsvägen 16, SE-75646 UPPSALA, Sweden
************************************************************************/
#include "stdafx.h"
#include
#include "testmeos.h"
#include "gdioutput.h"
#include "meosexception.h"
#include "gdistructures.h"
#include "meos_util.h"
#include "localizer.h"
#include "oEvent.h"
#include "TabSI.h"
#include "SportIdent.h"
#include "metalist.h"
#include "Table.h"
void registerTests(TestMeOS &tm);
TestMeOS::TestMeOS(oEvent *oe, const string &test) : oe_main(oe),
gdi_main(&oe->gdibase),
test(test), status(NORUN) {
testId = 0;
testIdMain = &testId;
registerTests(*this);
testId = 0;
}
TestMeOS::TestMeOS(TestMeOS &tmIn, const char *test) : oe_main(tmIn.oe_main),
gdi_main(tmIn.gdi_main),
test(test), status(NORUN) {
testIdMain = 0;
testId = 0;
}
TestMeOS::TestMeOS(const TestMeOS &tmIn, gdioutput &newWindow) : oe_main(tmIn.oe_main),
gdi_main(&newWindow),
status(NORUN) {
testIdMain = 0;
testId = 0;
}
TestMeOS::~TestMeOS() {
for (size_t k = 0; k < subTests.size(); k++) {
delete subTests[k];
}
subTests.clear();
}
TestMeOS * TestMeOS::newInstance() const {
throw meosException("Unsupported");
}
void TestMeOS::publishChildren(gdioutput &gdi, pair &passFail) const {
if (status == FAILED) {
++passFail.second;
gdi.addStringUT(1, "FAILED " + test).setColor(colorRed);
if (!message.empty())
gdi.addStringUT(0, message);
}
else if (status == NORUN) {
gdi.addStringUT(1, "DNS: " + test).setColor(colorDarkBlue);
}
else if (status == RUNNING) {
gdi.addStringUT(1, "Running: " + test).setColor(colorDarkBlue);
}
else if (status == PASSED) {
++passFail.first;
gdi.addStringUT(1, "PASSED " + test).setColor(colorGreen);
}
if (!subTests.empty()) {
gdi.dropLine(0.5);
int cx = gdi.getCX();
gdi.setCX(cx + gdi.scaleLength(10));
for (size_t j = 0; j < subTests.size(); j++) {
subTests[j]->publishChildren(gdi, passFail);
}
gdi.setCX(cx);
}
}
void TestMeOS::publish(gdioutput &gdi) const {
gdi.clearPage(true);
gdi.addStringUT(boldLarge, "Test Results");
gdi.dropLine();
pair passFail;
for (size_t j = 0; j < subTests.size(); j++) {
subTests[j]->publishChildren(gdi, passFail);
}
gdi.dropLine();
gdi.addString("", 1, "X tests failed, Y tests passed.#" + itos(passFail.second) +
"#" + itos(passFail.first));
gdi.refresh();
}
void TestMeOS::run() const {
}
void TestMeOS::runProtected(bool protect) const {
cleanup();
gdi_main->setOnClearCb(0);
gdi_main->setPostClearCb(0);
gdi_main->clearPage(false, false);
gdi_main->dbRegisterSubCommand(0, "");
subWindows.clear();
oe_main->clear();
gdi_main->isTestMode = true;
showTab(TCmpTab);
wstring tp = oe_main->getPropertyString("TestPath", L"");
oe_main->useDefaultProperties(true);
oe_main->setProperty("FirstTime", 0);
oe_main->setProperty("TestPath", tp);
oe_main->getPropertyInt("UseEventor", 1);
oe_main->setProperty("Interactive", 0);
TabSI *tsi = dynamic_cast(gdi_main->getTabs().get(TabType::TSITab));
tsi->setMode(TabSI::ModeReadOut);
tsi->clearQueue();
//string pmOrig = oe_main->getPropertyString("PayModes", "");
//oe_main->setProperty("PayModes", "");
OutputDebugString((L"Running test" + gdi_main->widen(test) + L"\n").c_str());
try {
status = RUNNING;
run();
gdi_main->clearDialogAnswers(true);
status = PASSED;
if (protect) {
gdi_main->setOnClearCb(0);
gdi_main->setPostClearCb(0);
gdi_main->clearPage(false, false);
oe_main->clear();
showTab(TCmpTab);
}
gdi_main->isTestMode = false;
}
catch (const meosAssertionFailure & ex) {
OutputDebugString(L"Test FAILED (assert)\n");
status = FAILED;
oe_main->useDefaultProperties(false);
gdi_main->clearDialogAnswers(false);
gdi_main->dbRegisterSubCommand(0, "");
gdi_main->isTestMode = false;
subWindows.clear();
message = ex.message;
//oe_main->setProperty("PayModes", pmOrig);
if (!protect)
throw meosException(message);
}
catch (const std::exception &ex) {
status = FAILED;
OutputDebugString(L"Test FAILED (std)\n");
oe_main->useDefaultProperties(false);
gdi_main->clearDialogAnswers(false);
gdi_main->dbRegisterSubCommand(0, "");
gdi_main->isTestMode = false;
subWindows.clear();
//oe_main->setProperty("PayModes", pmOrig);
message = gdi_main->widen(ex.what());
if (!protect)
throw;
}
catch (...) {
OutputDebugString(L"Test FAILED (...)\n");
status = FAILED;
oe_main->useDefaultProperties(false);
gdi_main->clearDialogAnswers(false);
gdi_main->dbRegisterSubCommand(0, "");
gdi_main->isTestMode = false;
subWindows.clear();
//oe_main->setProperty("PayModes", pmOrig);
message = L"Unknown Exception";
cleanup();
if (!protect)
throw;
}
//oe_main->setProperty("PayModes", pmOrig);
oe_main->useDefaultProperties(false);
gdi_main->dbRegisterSubCommand(0, "");
for (size_t k = 0; k < tmpFiles.size(); k++)
removeTempFile(tmpFiles[k]);
tmpFiles.clear();
OutputDebugString(L"Test PASSED\n");
if (protect) {
cleanup();
}
else {
gdi_main->addStringUT(1, 1, 1, "Test PASSED").setColor(colorDarkGreen);
gdi_main->refresh();
}
}
void TestMeOS::runAll() const {
runInternal(true);
}
void TestMeOS::runInternal(bool protect) const {
runProtected(protect);
for (size_t k = 0; k < subTests.size(); k++)
subTests[k]->runInternal(protect);
}
bool TestMeOS::runSpecific(int id) const {
if (id == testId) {
runInternal(false);
return true;
}
else {
for (size_t k = 0; k < subTests.size(); k++) {
if (subTests[k]->runSpecific(id))
return true;
}
}
return false;
}
void TestMeOS::getTests(vector< pair > &tl) const {
tl.push_back(make_pair(gdi_main->widen(test), testId));
for (size_t k = 0; k < subTests.size(); k++) {
subTests[k]->getTests(tl);
}
}
TestMeOS &TestMeOS::registerTest(const TestMeOS &test) {
subTests.push_back(test.newInstance());
subTests.back()->testId = ++(*testIdMain);
subTests.back()->testIdMain = testIdMain;
return *subTests.back();
}
void mainMessageLoop(HACCEL hAccelTable, DWORD time);
void TestMeOS::showTab(TabType type) const {
if (gdi_main->canClear()) {
gdi_main->getTabs().get(type)->loadPage(*gdi_main);
mainMessageLoop(0, 50);
}
}
void TestMeOS::press(const char *btn) const {
gdi_main->dbPress(btn, -65536);
mainMessageLoop(0, 50);
}
void TestMeOS::press(const char *btn, int extra) const {
gdi_main->dbPress(btn, extra);
mainMessageLoop(0, 50);
}
void TestMeOS::press(const char *btn, const char *extra) const {
gdi_main->dbPress(btn, extra);
mainMessageLoop(0, 50);
}
string TestMeOS::selectString(const char *id, const char *data) const {
int d = gdi_main->getItemDataByName(id, data);
if (d == -1)
throw meosException(string(data) + string(" not found in ") + id);
string res = gdi_main->dbSelect(id, d);
mainMessageLoop(0, 50);
return res;
}
string TestMeOS::select(const char *id, size_t data) const {
string res = gdi_main->dbSelect(id, data);
mainMessageLoop(0, 100);
return res;
}
void TestMeOS::dblclick(const char *id, size_t data) const {
gdi_main->dbDblClick(id, data);
}
void TestMeOS::input(const char *id, const char *data) const {
string arg;
while(*data) {
if (*data == '\n') {
arg.push_back('\r');
arg.push_back('\n');
}
else {
arg.push_back(*data);
}
data++;
}
gdi_main->dbInput(id, arg);
mainMessageLoop(0, 50);
}
void TestMeOS::click(const char *id) const {
gdi_main->dbClick(id, -65536);
mainMessageLoop(0, 50);
}
void TestMeOS::click(const char *id, int extra) const {
gdi_main->dbClick(id, extra);
mainMessageLoop(0, 50);
}
string TestMeOS::getText(const char *ctrl) const {
return gdi_main->narrow(gdi_main->getText(ctrl, false));
}
bool TestMeOS::isChecked(const char *ctrl) const {
return gdi_main->isChecked(ctrl);
}
void TestMeOS::assertEquals(const string &expected,
const string &value) const {
if (expected != value)
throw meosAssertionFailure("Expected " + expected + " but got " + value);
}
void TestMeOS::assertEquals(const wstring &expected,
const wstring &value) const {
if (expected != value)
throw meosAssertionFailure(L"Expected " + expected + L" but got " + value);
}
void TestMeOS::assertEquals(int expected, int value) const {
assertEquals(itos(expected), itos(value));
}
void TestMeOS::assertTrue(const char *message, bool condition) const {
assertEquals(message, "true", condition ? "true" : "false");
}
void TestMeOS::assertEquals(const string &message,
const string &expected,
const string &value) const {
if (expected != value)
throw meosAssertionFailure(message + ": Expected " + expected + " but got " + value);
}
void TestMeOS::assertEquals(const char *message,
const char *expected,
const string &value) const {
assertEquals(string(message), string(expected), value);
}
void TestMeOS::assertEquals(const wstring &message,
const wstring &expected,
const wstring &value) const {
if (expected != value)
throw meosAssertionFailure(message + L": Expected " + expected + L" but got " + value);
}
void TestMeOS::checkString(const char *str, int count) const {
int c = gdi_main->dbGetStringCount(str, false);
assertEquals("String " + string(str) + " not found", itos(count), itos(c));
}
void TestMeOS::checkSubString(const char *str, int count) const {
int c = gdi_main->dbGetStringCount(str, true);
assertEquals("String " + string(str) + " not found", itos(count), itos(c));
}
void TestMeOS::checkStringRes(const char *str, int count) const {
int c = gdi_main->dbGetStringCount(gdi_main->narrow(lang.tl(str)), false);
assertEquals("String " + string(str) + " not found", itos(count), itos(c));
}
void TestMeOS::insertCard(int cardNo, const char *ser) const {
SICard sic(ConvertedTimeStatus::Unknown);
sic.CardNumber = cardNo;
sic.deserializePunches(ser);
TabSI::getSI(*gdi_main).addCard(sic);
mainMessageLoop(0, 100);
}
void TestMeOS::setAnswer(const char *ans) const {
gdi_main->dbPushDialogAnswer(ans);
}
void TestMeOS::setFile(const string &file) const {
gdi_main->dbPushDialogAnswer("*" + file);
}
void TestMeOS::cleanup() const {
}
int TestMeOS::getResultModuleIndex(const char *tag) const {
vector< pair > > mol;
oe_main->getGeneralResults(false, mol, true);
for (size_t k = 0; k < mol.size(); k++) {
if (mol[k].second.first == tag) {
return mol[k].first;
}
}
throw meosException(string("Result module not found: ") + tag);
}
int TestMeOS::getListIndex(const char *name) const {
vector< pair > lst;
oe_main->getListContainer().getLists(lst, false, false, false);
for (size_t k = 0; k < lst.size(); k++) {
if (lst[k].first == lang.tl(name))
return lst[k].second;
}
throw meosException(string("List not found: ") + name);
}
const string &getLastExtraWindow();
const string TestMeOS::getLastExtraWindow() const {
return ::getLastExtraWindow();
}
const TestMeOS &TestMeOS::getExtraWindow(const string &tag) const {
gdioutput *ge = ::getExtraWindow(tag, false);
if (ge == 0)
throw meosException(string("Window not found: ") + tag);
subWindows.push_back(TestMeOS(*this, *ge));
return subWindows.back();
}
void TestMeOS::pressEscape() const {
gdi_main->doEscape();
}
void TestMeOS::closeWindow() const {
gdi_main->closeWindow();
}
string TestMeOS::getTestFile(const char *relPath) const {
string tp = oe_main->getPropertyString("TestPath", "");
if (tp.length() == 0)
return relPath;
else if (*tp.rbegin() == '\\')
return tp + relPath;
else
return tp + "\\" + relPath;
}
wstring TestMeOS::getTempFile() const {
wstring fn = ::getTempFile();
tmpFiles.push_back(fn);
return fn;
}
void TestMeOS::tableCmd(const char *id) const {
gdi_main->processToolbarMessage(id, &gdi_main->getTable());
mainMessageLoop(0, 50);
}
void TestMeOS::setTableText(int editRow, int editCol, const string &text) const {
Table &t = gdi_main->getTable();
t.setTableText(*gdi_main, editRow, editCol, gdi_main->widen(text));
mainMessageLoop(0, 50);
}
string TestMeOS::getTableText(int editRow, int editCol) const {
Table &t = gdi_main->getTable();
return gdi_main->narrow(t.getTableText(*gdi_main, editRow, editCol));
}
void TestMeOS::registerSubCommand(const string &cmd) const {
gdi_main->dbRegisterSubCommand(this, cmd);
}