/************************************************************************ MeOS - Orienteering Software Copyright (C) 2009-2018 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); //string pmOrig = oe_main->getPropertyString("PayModes", ""); //oe_main->setProperty("PayModes", ""); 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) { 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; 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 (...) { 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(); if (protect) { cleanup(); } } 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; 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); }