00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #pragma once
00012
00013 #include "assert.h"
00014 #include <set>
00015 #include <vector>
00016 #include <iostream>
00017 #include <iomanip>
00018 using namespace std;
00019
00020 #include "TestToolBox/TestEvents.h"
00021 #include "TestToolBox/CheckerForMultipleSequences.h"
00022 #include "TestToolBox/IEventReceiver.h"
00023 #include "TestToolBox/IProtocol.h"
00024
00025
00026 #pragma warning( push )
00027 #pragma warning( disable : 4996 ) // vsprintf declared deprecated
00028
00029
00030
00031
00032
00033 #ifdef TTB_NOT_INLINE
00034 #define TTB_INLINE
00035 #else
00036 #define TTB_INLINE inline
00037 #endif
00038
00039 namespace TestToolBox
00040 {
00041 class TestEvents;
00042
00043
00044
00045
00046
00047
00048 TTB_INLINE TestEvents::TestEvents():
00049 m_firstError (),
00050 m_events (),
00051 m_curCheckPos (0),
00052 m_active (true),
00053 m_curTestStillOk (true),
00054 m_numPerformedTests (0),
00055 m_numFailedTests (0),
00056 m_descCurrentTest (),
00057 m_detailedLog (false),
00058 m_detailedCheckLog (false),
00059 m_pIEventReceiver (0),
00060 m_pIProtocol (0),
00061 m_checkType (CheckType::eNOT_SET),
00062 m_doublePrecision (6),
00063 m_checkForUnexpected (true),
00064 m_widthCommandNameInLogFile (20),
00065 S_UNEXPECTED_EVENTS ("Unexpected Events"),
00066 S_EVENT_NOT_FOUND ("Event not found: "),
00067 S_EXPECTED ("Expected : "),
00068 S_FOUND ("Found : "),
00069 S_SEPARATOR_LINE_1 ("================================================================================"),
00070 S_SEPARATOR_LINE_2 ("------------------------------------------------------------------------")
00071 {
00072 m_pCheckerForMultipleSequences = new CheckerForMultipleSequences(*this);
00073
00074 }
00075
00076
00077
00078
00079
00080
00081 TTB_INLINE TestEvents::~TestEvents()
00082 {
00083 TRCF("TestEvents::~TestEvents");
00084 TRC(TL_DEBUG, "Destructor");
00085 CheckForUnexpectedEvents("Context: automatic check within ~TestEvents");
00086
00087 if (m_pIProtocol)
00088 {
00089 m_pIProtocol->WriteFooter();
00090
00091 long numTests;
00092 long numFailedTests;
00093 std::string result1, result2;
00094 GetTestResult (numTests, numFailedTests, result1, result2);
00095
00096 m_pIProtocol->Writeln(OutputLevel::eREGULAR, OutputMode::M_ALL);
00097 m_pIProtocol->Writeln(OutputLevel::eREGULAR, OutputMode::M_ALL, "Tests performed : " + ToString(numTests));
00098 m_pIProtocol->Writeln(OutputLevel::eERROR, OutputMode::M_ALL, "Tests failed : " + ToString(numFailedTests));
00099 m_pIProtocol->Writeln(OutputLevel::eREGULAR, OutputMode::M_ALL);
00100
00101 if (numFailedTests > 0)
00102 {
00103 m_pIProtocol->Writeln(OutputLevel::eERROR, OutputMode::M_ALL, "First error in : ");
00104 if (!result1.empty())
00105 {
00106 m_pIProtocol->Writeln(OutputLevel::eERROR, OutputMode::M_ALL, result1);
00107 }
00108
00109 if (!result2.empty())
00110 {
00111 m_pIProtocol->Writeln(OutputLevel::eERROR, OutputMode::M_ALL, result2);
00112 }
00113 }
00114 else
00115 {
00116 m_pIProtocol->Writeln(OutputLevel::eERROR, OutputMode::M_ALL, "No error detected!");
00117 }
00118 }
00119
00120 m_pIEventReceiver = 0;
00121 delete m_pCheckerForMultipleSequences;
00122
00123 }
00124
00125
00126
00127
00128
00129
00130 TTB_INLINE void TestEvents::Act (const char* in_actualEvent, ...)
00131 {
00132 UTIL_GET_FORMATTED_LINE_NO_NEWLINE (in_actualEvent);
00133 std::string eventStr = formattedLine;
00134 if (!m_eventPrefix.empty())
00135 {
00136 eventStr = m_eventPrefix + "(" + eventStr + ");";
00137 }
00138 TestEvents::Get()->AddTestEvent(eventStr);
00139
00140 }
00141
00142
00143
00144
00145
00146
00147 TTB_INLINE void TestEvents::ActualResult (const char* in_actualEvent, ...)
00148 {
00149 UTIL_GET_FORMATTED_LINE_NO_NEWLINE (in_actualEvent);
00150 TestEvents::Get()->AddTestEvent(formattedLine);
00151
00152 }
00153
00154
00155
00156
00157
00158
00159 TTB_INLINE EventPosition TestEvents::ExpectResult(
00160 const char* in_fileName,
00161 const long in_lineNum,
00162 const char* in_expectedEvent, ...)
00163 {
00164
00165 UTIL_GET_FORMATTED_LINE_NO_NEWLINE (in_expectedEvent);
00166
00167 return ExpectResultInternal(in_fileName, in_lineNum, formattedLine,
00168 m_checkType != CheckType::eNOT_SET
00169 ? m_checkType
00170 : CheckType::eSTRICT);
00171
00172 }
00173
00174
00175
00176
00177
00178
00179 TTB_INLINE EventPosition TestEvents::ExpectResultSequential(
00180 const char* in_fileName,
00181 const long in_lineNum,
00182 const char* in_expectedEvent, ...)
00183 {
00184
00185 UTIL_GET_FORMATTED_LINE_NO_NEWLINE (in_expectedEvent);
00186
00187 return ExpectResultInternal(in_fileName, in_lineNum, formattedLine, CheckType::eSEQUENTIAL);
00188
00189 }
00190
00191
00192
00193
00194
00195
00196 TTB_INLINE EventPosition TestEvents::ExpectResultVariable(
00197 const char* in_fileName,
00198 const long in_lineNum,
00199 const char* in_expectedEvent, ...)
00200 {
00201
00202 UTIL_GET_FORMATTED_LINE_NO_NEWLINE (in_expectedEvent);
00203
00204 return ExpectResultInternal(in_fileName, in_lineNum, formattedLine, CheckType::eVARIABLE);
00205
00206 }
00207
00208
00209
00210
00211
00212
00213 TTB_INLINE void TestEvents::CheckForUnexpectedEvents (
00214 const char* in_context,
00215 const char* in_fileName,
00216 const long in_lineNum)
00217 {
00218 AutoLock o (this);
00219
00220 if (!m_checkForUnexpected) return;
00221 m_checkForUnexpected = false;
00222
00223 std::string errMsg;
00224 if (!CheckForUnexpectedEvents (errMsg))
00225 {
00226 std::ostringstream fullInfoStr;
00227
00228 fullInfoStr << "\n!!" << S_UNEXPECTED_EVENTS << std::endl;
00229
00230
00231 AddFileNameAndLineNumber (fullInfoStr, in_fileName, in_lineNum);
00232
00233 fullInfoStr << " (" << in_context << ") " ;
00234 fullInfoStr << errMsg <<std::endl;
00235
00236 if (m_pIEventReceiver)
00237 {
00238 m_pIEventReceiver->Event (TestToolBox::CTX_UNEXPECTED_EVENTS, fullInfoStr. str());
00239 }
00240
00241
00242 if (m_pIProtocol)
00243 {
00244 m_pIProtocol->Writeln(OutputLevel::eERROR, OutputMode::M_ALL, fullInfoStr. str());
00245 }
00246
00247
00248 ListAllStoredEvents();
00249 }
00250
00251 }
00252
00253
00254
00255
00256
00257
00258 TTB_INLINE void TestEvents::ResetCurrentCheckPosition (void)
00259 {
00260 m_curCheckPos = 0;
00261 IncrementCurPos();
00262 }
00263
00264 TTB_INLINE void TestEvents::SetCurrentCheckPosition (
00265 int in_newPos)
00266 {
00267 m_curCheckPos = static_cast<Events::size_type>(in_newPos);
00268 IncrementCurPos();
00269 }
00270
00271 TTB_INLINE int TestEvents::GetCurrentCheckPosition (void)
00272 {
00273 return static_cast<int>(m_curCheckPos);
00274 }
00275
00276
00277
00278
00279
00280 TTB_INLINE void TestEvents::ListAllStoredEvents (
00281 const char* in_fileName,
00282 const long in_lineNum,
00283 CheckType::Enum in_checkType)
00284 {
00285 AutoLock o (this);
00286
00287 std::ostringstream outStr;
00288
00289 outStr << "List of stored TestEvents (current check position = "
00290 << m_curCheckPos;
00291 if (in_checkType == CheckType::eNOT_SET)
00292 {
00293 outStr << ", for checkType see last EXP macro, m_checkType=" << GetCheckTypeAsText(m_checkType) << ") ";
00294 }
00295 else
00296 {
00297 outStr << ", used checkType = " << GetCheckTypeAsText(in_checkType) << ") " << endl;
00298 }
00299
00300
00301
00302 if (in_fileName)
00303 {
00304 AddFileNameAndLineNumber (outStr, in_fileName, in_lineNum);
00305 outStr << " (call location)" << endl;
00306 }
00307
00308 std::string eventList;
00309 ListAllStoredEvents(eventList);
00310 outStr << eventList;
00311
00312 if (m_pIEventReceiver)
00313 {
00314 m_pIEventReceiver->Event (TestToolBox::CTX_INFO, outStr. str());
00315 }
00316
00317
00318 if (m_pIProtocol)
00319 {
00320 m_pIProtocol->SetMode(OutputMode::M_OUTFILE);
00321 m_pIProtocol->Writeln();
00322 m_pIProtocol->Writeln(outStr. str());
00323 }
00324
00325 }
00326
00327
00328
00329
00330
00331
00332 TTB_INLINE void TestEvents::ClearAllStoredEvents (void)
00333 {
00334 m_events.clear();
00335
00336 }
00337
00338
00339
00340
00341
00342
00343 TTB_INLINE std::string TestEvents::GetCheckTypeAsText (CheckType::Enum in_checkType)
00344 {
00345 switch (in_checkType)
00346 {
00347 case CheckType::eNOT_SET:
00348 return "eNOT_SET";
00349 break;
00350 case CheckType::eSTRICT:
00351 return "eSTRICT";
00352 break;
00353 case CheckType::eSEQUENTIAL:
00354 return "eSEQUENTIAL";
00355 break;
00356 case CheckType::eVARIABLE:
00357 return "eVARIABLE";
00358 break;
00359 default:
00360 return "unknown";
00361 break;
00362 }
00363
00364 }
00365
00366
00367
00368
00369
00370
00371 TTB_INLINE void TestEvents::DefineSequence (std::string const & in_nameSequence)
00372 {
00373 SetCheckType(CheckType::eMULTIPLE_SEQUENCES);
00374 m_pCheckerForMultipleSequences->DefineSequence(in_nameSequence);
00375 }
00376
00377
00378
00379 TTB_INLINE void TestEvents::StoreExpectedEventWithinSelectedSequence(
00380 std::string const & in_expectedEvent,
00381 const char* in_fileName,
00382 const long in_lineNum)
00383 {
00384 m_pCheckerForMultipleSequences->StoreExpectedEventWithinSelectedSequence(
00385 in_expectedEvent, in_fileName, in_lineNum);
00386 }
00387
00388
00389
00390 TTB_INLINE void TestEvents::CheckDefinedSequences(
00391 const char* in_fileName,
00392 const long in_lineNum)
00393 {
00394 m_pCheckerForMultipleSequences->CheckDefinedSequences(in_fileName, in_lineNum);
00395 SetCheckType(CheckType::eNOT_SET);
00396 }
00397
00398
00399
00400 TTB_INLINE void TestEvents::SetDetailedLogSequences (
00401 bool in_detailedLog)
00402 {
00403 m_pCheckerForMultipleSequences->SetDetailedLog(in_detailedLog);
00404 }
00405
00406
00407
00408
00409
00410 TTB_INLINE bool TestEvents::CheckCondition (
00411 const char* in_fileName,
00412 const long in_lineNum,
00413 std::string const & in_expressionAsText,
00414 bool in_expressionValue)
00415 {
00416 bool errorFound = !in_expressionValue;
00417
00418 DisplayCheckInfo (
00419 in_fileName, in_lineNum,
00420 "CheckCondition", errorFound,
00421 in_expressionAsText, ToString(in_expressionValue));
00422
00423 return errorFound;
00424
00425 }
00426
00427
00428
00429
00430
00431
00432 TTB_INLINE bool TestEvents::CheckEqual(
00433 const char* in_fileName,
00434 const long in_lineNum,
00435 std::string const & leftAsText,
00436 double const & left,
00437 std::string const & rightAsText,
00438 double const & right)
00439 {
00440
00441 std::ostringstream leftStr;
00442 std::ostringstream rightStr;
00443
00444 leftStr << std::fixed << std::setprecision(m_doublePrecision) << left;
00445 rightStr << std::fixed << std::setprecision(m_doublePrecision) << right;
00446
00447 std::string leftValAsText = leftStr.str();
00448 std::string rightValAsText = rightStr.str();
00449
00450 bool errorFound = (leftValAsText != rightValAsText);
00451
00452 DisplayCheckInfo (in_fileName, in_lineNum,
00453 "CheckEqual", errorFound,
00454 leftAsText, leftValAsText, rightAsText, rightValAsText,
00455 "==",
00456 "specialization for double, precision is " + ToString (m_doublePrecision));
00457
00458 return errorFound;
00459
00460 }
00461
00462
00463
00464
00465
00466
00467 TTB_INLINE void TestEvents::StartNewTestCase (
00468 const std::string& in_rDescTestCase)
00469 {
00470 AutoLock o (this);
00471
00472
00473 ++m_numPerformedTests;
00474
00475 TRCF("TestEvents::StartNewTestCase");
00476 TRC(TL_PROD, "=================================================="
00477 "==============================");
00478 TRC(TL_PROD, "Test %d: %s", m_numPerformedTests,
00479 in_rDescTestCase.c_str());
00480 TRC(TL_PROD, "=================================================="
00481 "==============================");
00482 if (m_pIProtocol)
00483 {
00484 m_pIProtocol->Writeln(OutputLevel::eREGULAR, OutputMode::M_OUTFILE);
00485 m_pIProtocol->Writeln(OutputLevel::eREGULAR, OutputMode::M_OUTFILE, S_SEPARATOR_LINE_1);
00486 m_pIProtocol->Writeln(OutputLevel::eREGULAR, OutputMode::M_ALL, "Test: " + in_rDescTestCase);
00487 m_pIProtocol->Writeln(OutputLevel::eREGULAR, OutputMode::M_OUTFILE, S_SEPARATOR_LINE_1);
00488 m_pIProtocol->Writeln(OutputLevel::eREGULAR, OutputMode::M_OUTFILE);
00489 }
00490
00491
00492 m_descCurrentTest = in_rDescTestCase;
00493
00494
00495 m_events.clear();
00496
00497
00498 m_curCheckPos = 0;
00499
00500
00501 m_active = true;
00502
00503
00504 m_curTestStillOk = true;
00505
00506 }
00507
00508
00509
00510
00511
00512
00513 TTB_INLINE void TestEvents::Command (
00514 std::string const & in_cmd,
00515 std::string const & in_params)
00516 {
00517 if (m_detailedLog)
00518 {
00519 if (m_pIEventReceiver)
00520 {
00521 std::string cmdStr = in_cmd;
00522 if (!in_params.empty())
00523 {
00524 cmdStr += " " + in_params;
00525 }
00526 m_pIEventReceiver->Event (CTX_INFO, "Cmd: " + cmdStr);
00527 }
00528
00529
00530 if (m_pIProtocol)
00531 {
00532 std::ostringstream oss;
00533 oss << std::setw(m_widthCommandNameInLogFile) << std::left << in_cmd;
00534 if (!in_params.empty())
00535 {
00536 oss << " " << in_params;
00537 }
00538
00539 m_pIProtocol->SetMode(OutputMode::M_OUTFILE);
00540 m_pIProtocol->Writeln();
00541 m_pIProtocol->Writeln("<" + oss.str());
00542 }
00543 }
00544
00545 }
00546
00547
00548
00549
00550
00551
00552 TTB_INLINE void TestEvents::Info (
00553 std::string const & in_info)
00554 {
00555 if (m_detailedLog)
00556 {
00557 if (m_pIEventReceiver)
00558 {
00559 m_pIEventReceiver->Event (CTX_INFO, in_info);
00560 }
00561
00562
00563 if (m_pIProtocol)
00564 {
00565 m_pIProtocol->SetMode(OutputMode::M_OUTFILE);
00566 m_pIProtocol->Writeln(in_info);
00567 }
00568 }
00569
00570 }
00571
00572
00573
00574
00575
00576
00577 TTB_INLINE void TestEvents::Section (
00578 std::string const & in_sectionName)
00579 {
00580 if (m_detailedLog)
00581 {
00582 if (m_pIEventReceiver)
00583 {
00584 m_pIEventReceiver->Event (CTX_INFO, "Section: " + in_sectionName);
00585 }
00586
00587
00588 if (m_pIProtocol)
00589 {
00590 m_pIProtocol->SetMode(OutputMode::M_OUTFILE);
00591 m_pIProtocol->Writeln();
00592 m_pIProtocol->Writeln(S_SEPARATOR_LINE_2);
00593 m_pIProtocol->Writeln("Section: " + in_sectionName);
00594 m_pIProtocol->Writeln(S_SEPARATOR_LINE_2);
00595 }
00596 }
00597
00598 }
00599
00600
00601
00602
00603
00604
00605 TTB_INLINE void TestEvents::GenerateErrorMessage (
00606 const char* in_fileName,
00607 const long in_lineNum,
00608 std::string const & in_errorInfo)
00609 {
00610 std::ostringstream fullInfoStr;
00611
00612
00613
00614 AddFileNameAndLineNumber (fullInfoStr, in_fileName, in_lineNum);
00615 fullInfoStr << " (call location of error)" << std::endl;
00616 fullInfoStr << in_errorInfo;
00617 if (m_pIEventReceiver)
00618 {
00619 m_pIEventReceiver->Event (fullInfoStr. str());
00620 }
00621
00622
00623 if (m_pIProtocol)
00624 {
00625 m_pIProtocol->Writeln(OutputLevel::eERROR, OutputMode::M_ALL, "\n!!Error at location\n" + fullInfoStr. str());
00626 }
00627 StoreError (in_errorInfo, "");
00628
00629 }
00630
00631
00632
00633
00634
00635
00636 TTB_INLINE bool TestEvents::CheckForUnexpectedEvents (
00637 std::string& out_rResult)
00638 {
00639 AutoLock o (this);
00640
00641 bool unexpectedEventFound = false;
00642 out_rResult = "";
00643
00644
00645
00646
00647 if (m_active)
00648 {
00649 for (Events::iterator i = m_events.begin(); i < m_events .end();
00650 ++i)
00651 {
00652 if (!i->first)
00653 {
00654 if (!unexpectedEventFound)
00655 {
00656 unexpectedEventFound = true;
00657 out_rResult = "unexpected events:";
00658 }
00659 out_rResult += '\n';
00660 out_rResult += i->second;
00661 }
00662 }
00663 }
00664
00665 if (unexpectedEventFound)
00666 {
00667 StoreError (out_rResult, "");
00668 }
00669
00670 return !unexpectedEventFound;
00671
00672 }
00673
00674
00675
00676
00677
00678
00679 TTB_INLINE void TestEvents::ListAllStoredEvents (
00680 std::string& out_rListOfEvents)
00681 {
00682 out_rListOfEvents = "";
00683
00684
00685
00686
00687 std::ostringstream outListStr;
00688 if (m_events.empty())
00689 {
00690 outListStr << "No TestEvents stored!" << endl;
00691 }
00692
00693 for (Events::iterator i = m_events.begin(); i < m_events .end();
00694 ++i)
00695 {
00696 int eventIdx = static_cast<int>(std::distance(m_events.begin(), i));
00697 WriteEventEntry(eventIdx, outListStr);
00698 }
00699 if (m_curCheckPos >= m_events.size())
00700 {
00701 outListStr << "##" << std::endl;
00702 }
00703 outListStr << std::endl;
00704
00705 out_rListOfEvents = outListStr.str();
00706
00707 }
00708
00709
00710
00711
00712
00713
00714 TTB_INLINE void TestEvents::AddTestEvent(
00715 const std::string& in_rEvent)
00716 {
00717 AutoLock o (this);
00718
00719 m_events.push_back (std::make_pair (false, in_rEvent));
00720
00721 if (m_detailedLog)
00722 {
00723 std::ostringstream outStr;
00724
00725 if (!m_actLogPrefix.empty())
00726 outStr << m_actLogPrefix + "(\"";
00727
00728 outStr << in_rEvent;
00729
00730 if (!m_actLogPrefix.empty())
00731 outStr << "\");";
00732
00733
00734 if (m_pIEventReceiver)
00735 {
00736 m_pIEventReceiver->Event (TestToolBox::CTX_INFO, "Act: " + outStr. str());
00737 }
00738
00739
00740 if (m_pIProtocol)
00741 {
00742 m_pIProtocol->SetMode(OutputMode::M_OUTFILE);
00743 if (m_actLogPrefix.empty())
00744 {
00745 m_pIProtocol->Writeln(">" + outStr. str());
00746 }
00747 else
00748 {
00749 m_pIProtocol->Writeln(outStr. str());
00750 }
00751 }
00752 }
00753
00754
00755 m_checkForUnexpected = true;
00756
00757 }
00758
00759
00760
00761
00762
00763
00764 TTB_INLINE EventPosition TestEvents::CheckForTestEvent(
00765 const std::string& in_rEvent,
00766 std::string& out_rResult1,
00767 std::string& out_rResult2)
00768 {
00769 AutoLock o (this);
00770
00771 m_positionOfLastEvent.Reset();
00772 bool errorFound = true;
00773 out_rResult1 = "";
00774 out_rResult2 = "";
00775
00776 if (!m_active)
00777 {
00778
00779 errorFound = false;
00780 m_positionOfLastEvent = EventPosition(99999);
00781 return m_positionOfLastEvent;
00782 }
00783 else if (m_curCheckPos >= m_events .size())
00784 {
00785 out_rResult1 = S_EVENT_NOT_FOUND + in_rEvent;
00786 }
00787 else
00788 {
00789 if (m_events [m_curCheckPos]. first)
00790 {
00791 out_rResult1 = "Internal error (compare algorithm "
00792 "has an error). Expected: " + in_rEvent;
00793 }
00794 else
00795 {
00796 if (m_events [m_curCheckPos] .second == in_rEvent)
00797 {
00798
00799 m_events [m_curCheckPos] .first = true;
00800 m_positionOfLastEvent = m_curCheckPos;
00801
00802 IncrementCurPos();
00803
00804
00805 errorFound = false;
00806 }
00807 else
00808 {
00809 out_rResult1 = S_EXPECTED + in_rEvent;
00810 out_rResult2 = S_FOUND + m_events [m_curCheckPos] .second;
00811 }
00812 }
00813 }
00814
00815
00816
00817 if (errorFound)
00818 {
00819 m_active = false;
00820 StoreError (out_rResult1, out_rResult2);
00821 }
00822
00823 return m_positionOfLastEvent;
00824
00825 }
00826
00827
00828
00829
00830
00831
00832 TTB_INLINE EventPosition TestEvents::CheckForTestEventSequential (
00833 const std::string& in_rEvent,
00834 std::string& out_rResult1,
00835 std::string& out_rResult2)
00836 {
00837 AutoLock o (this);
00838
00839 m_positionOfLastEvent.Reset();
00840 bool errorFound = true;
00841 out_rResult1 = "";
00842 out_rResult2 = "";
00843
00844 if (!m_active)
00845 {
00846
00847 errorFound = false;
00848 m_positionOfLastEvent = EventPosition(99999);
00849 return m_positionOfLastEvent;
00850 }
00851 else
00852 {
00853 Events::size_type pos = m_curCheckPos;
00854 bool eventFound = false;
00855 while ((!eventFound) && pos < m_events .size())
00856 {
00857 if ((!m_events [pos] .first)
00858
00859 && (m_events [pos] .second == in_rEvent))
00860 {
00861 eventFound = true;
00862
00863
00864 m_events [pos] .first = true;
00865 m_positionOfLastEvent = pos;
00866
00867
00868
00869 m_curCheckPos = pos;
00870 IncrementCurPos();
00871 }
00872 else
00873 {
00874 ++pos;
00875 }
00876 }
00877
00878 if (eventFound)
00879 {
00880
00881 errorFound = false;
00882 }
00883 else
00884 {
00885 out_rResult1 = S_EVENT_NOT_FOUND + in_rEvent;
00886 }
00887
00888 }
00889
00890
00891
00892 if (errorFound)
00893 {
00894 m_active = false;
00895 StoreError (out_rResult1, out_rResult2);
00896 }
00897
00898 return m_positionOfLastEvent;
00899
00900 }
00901
00902
00903
00904
00905
00906
00907 TTB_INLINE EventPosition TestEvents::CheckForTestEventVariable (
00908 const std::string& in_rEvent,
00909 std::string& out_rResult1,
00910 std::string& out_rResult2)
00911 {
00912 AutoLock o (this);
00913
00914 m_positionOfLastEvent.Reset();
00915 bool errorFound = true;
00916 out_rResult1 = "";
00917 out_rResult2 = "";
00918
00919 if (!m_active)
00920 {
00921
00922 errorFound = false;
00923 m_positionOfLastEvent = EventPosition(99999);
00924 return m_positionOfLastEvent;
00925 }
00926 else
00927 {
00928 Events::size_type pos = 0;
00929 bool eventFound = false;
00930 while ((!eventFound) && pos < m_events .size())
00931 {
00932 if ((!m_events [pos] .first)
00933
00934 && (m_events [pos] .second == in_rEvent))
00935 {
00936 eventFound = true;
00937
00938
00939 m_events [pos] .first = true;
00940
00941 m_positionOfLastEvent = pos;
00942 }
00943 else
00944 {
00945 ++pos;
00946 }
00947 }
00948
00949 if (eventFound)
00950 {
00951
00952 errorFound = false;
00953
00954
00955
00956
00957 if (pos == m_curCheckPos)
00958 {
00959 IncrementCurPos();
00960 }
00961 }
00962 else
00963 {
00964 out_rResult1 = S_EVENT_NOT_FOUND + in_rEvent;
00965 }
00966
00967 }
00968
00969
00970
00971 if (errorFound)
00972 {
00973 m_active = false;
00974 StoreError (out_rResult1, out_rResult2);
00975 }
00976
00977 return m_positionOfLastEvent;
00978
00979 }
00980
00981
00982
00983
00984
00985
00986 TTB_INLINE bool TestEvents::GetTestResult (
00987 long& out_rNumPerformedTests,
00988 long& out_rNumFailedTests,
00989 std::string& out_rDescFirstFailedTest,
00990 std::string& out_rDescError)
00991 {
00992 AutoLock o (this);
00993
00994 out_rNumPerformedTests = m_numPerformedTests;
00995 out_rNumFailedTests = m_numFailedTests;
00996
00997 if (m_firstError .m_exists)
00998 {
00999
01000 std::ostringstream tmpStr;
01001 tmpStr << m_firstError .m_idxFirstFailedTest;
01002 out_rDescFirstFailedTest = "Test " + tmpStr. str();
01003
01004
01005 out_rDescFirstFailedTest += " / " +
01006 m_firstError .m_descFirstFailedTest;
01007
01008
01009 out_rDescError = m_firstError .m_descError;
01010 }
01011
01012 return out_rNumFailedTests == 0;
01013
01014 }
01015
01016
01017
01018
01019
01020
01021 TTB_INLINE void TestEvents::Reset (void)
01022 {
01023 AutoLock o (this);
01024
01025
01026 m_firstError.m_exists = false;
01027
01028
01029 m_events.clear();
01030
01031
01032 m_curCheckPos = 0;
01033
01034
01035 m_active = true;
01036
01037
01038 m_curTestStillOk = true;
01039
01040
01041 m_numPerformedTests = 0;
01042 m_numFailedTests = 0;
01043
01044
01045 m_descCurrentTest = "";
01046
01047 m_checkForUnexpected = true;
01048
01049 }
01050
01051
01052
01053
01054
01055
01056 TTB_INLINE void TestEvents::IncrementCurPos (void)
01057 {
01058 AutoLock o (this);
01059
01060
01061
01062
01063 while ( (m_curCheckPos < m_events .size())
01064 && (m_events [m_curCheckPos]. first))
01065 ++m_curCheckPos;
01066
01067 }
01068
01069
01070
01071
01072
01073
01074 TTB_INLINE void TestEvents::StoreError (
01075 const std::string& in_rErrStr1,
01076 const std::string& in_rErrStr2)
01077 {
01078
01079 if (!m_firstError. m_exists)
01080 {
01081 m_firstError. m_exists = true;
01082 m_firstError. m_idxFirstFailedTest = m_numPerformedTests;
01083 m_firstError. m_descFirstFailedTest = m_descCurrentTest;
01084 m_firstError. m_descError = in_rErrStr1;
01085 if (!in_rErrStr2 .empty())
01086 {
01087 m_firstError. m_descError += '\n' + in_rErrStr2;
01088 }
01089 }
01090
01091
01092 if (m_curTestStillOk)
01093 {
01094 m_curTestStillOk = false;
01095 ++m_numFailedTests;
01096 }
01097
01098 }
01099
01100
01101
01102
01103
01104
01105 TTB_INLINE EventPosition TestEvents::ExpectResultInternal(
01106 const char* in_fileName,
01107 const long in_lineNum,
01108 const char* in_formattedResult,
01109 CheckType::Enum in_checkType)
01110 {
01111 AutoLock o (this);
01112
01113 EventPosition eventPos;
01114 std::string result1, result2;
01115 bool testOk = false;
01116 switch (in_checkType)
01117 {
01118 case CheckType::eSTRICT:
01119 eventPos = CheckForTestEvent (in_formattedResult, result1, result2);
01120 break;
01121 case CheckType::eSEQUENTIAL:
01122 eventPos = CheckForTestEventSequential (in_formattedResult, result1, result2);
01123 break;
01124 case CheckType::eMULTIPLE_SEQUENCES:
01125 StoreExpectedEventWithinSelectedSequence (in_formattedResult, in_fileName, in_lineNum);
01126 eventPos = 0;
01127 break;
01128 case CheckType::eVARIABLE:
01129 eventPos = CheckForTestEventVariable (in_formattedResult, result1, result2);
01130 break;
01131 }
01132
01133 testOk = eventPos.IsOk();
01134
01135
01136 if (!testOk)
01137 {
01138 std::ostringstream fullInfoStr;
01139
01140
01141
01142 AddFileNameAndLineNumber (fullInfoStr, in_fileName, in_lineNum);
01143 fullInfoStr << " (call location of error)" << endl;
01144
01145 if (!result1.empty())
01146 {
01147 fullInfoStr << result1 << endl;
01148 }
01149 if (!result2.empty())
01150 {
01151 fullInfoStr << result2;
01152 }
01153 if (m_pIEventReceiver)
01154 {
01155 m_pIEventReceiver->Event (fullInfoStr. str());
01156 }
01157
01158
01159 if (m_pIProtocol)
01160 {
01161 m_pIProtocol->Writeln(OutputLevel::eERROR, OutputMode::M_ALL, "\n!!Error at location\n" + fullInfoStr. str());
01162 }
01163
01164
01165 ListAllStoredEvents(0, 0, in_checkType);
01166 }
01167
01168 return eventPos;
01169
01170 }
01171
01172
01173
01174
01175
01176
01177 TTB_INLINE void TestEvents::DisplayCheckInfo (
01178 const char* in_fileName,
01179 const long in_lineNum,
01180 std::string const & in_checkType,
01181 bool in_checkFailed,
01182 std::string const & in_paramLeftAsText,
01183 std::string const & in_paramValLeftAsText,
01184 std::string const & in_paramRightAsText,
01185 std::string const & in_paramValRightAsText,
01186 std::string const & in_compareOpAsText,
01187 std::string const & in_paramTypeAsText)
01188 {
01189 std::ostringstream infoStr;
01190 infoStr << in_checkType
01191 << (in_checkFailed ? " NOT OK: " : " Ok: ")
01192 << in_paramLeftAsText << " (=" << in_paramValLeftAsText << ")";
01193
01194 if (!in_compareOpAsText.empty())
01195 {
01196 infoStr << " " << in_compareOpAsText;
01197 }
01198 if (!in_paramValRightAsText.empty())
01199 {
01200 infoStr << " " << in_paramRightAsText << " (=" << in_paramValRightAsText << ")";
01201 }
01202
01203 if (!in_paramTypeAsText.empty())
01204 {
01205 infoStr
01206 << ", used type: "
01207 << in_paramTypeAsText;
01208 }
01209 infoStr << std::endl;
01210
01211 if (in_checkFailed)
01212 {
01213 if (!in_paramValRightAsText.empty())
01214 {
01215
01216 infoStr
01217 << "left : " << std::setw(15) << in_paramValLeftAsText << std::setw(15) << " (" << in_paramLeftAsText << ")" << std::endl
01218 << "right: " << std::setw(15) << in_paramValRightAsText << std::setw(15) << " (" << in_paramRightAsText << ")" << std::endl;
01219 }
01220 GenerateErrorMessage (in_fileName, in_lineNum, infoStr.str());
01221 }
01222 else if (m_detailedCheckLog && m_pIProtocol)
01223 {
01224 m_pIProtocol->Writeln(OutputLevel::eREGULAR, OutputMode::M_OUTFILE, infoStr. str());
01225 }
01226
01227 }
01228
01229
01230
01231
01232
01233
01234 TTB_INLINE void TestEvents::WriteEventEntry (
01235 int in_idxEvent,
01236 std::ostringstream & io_stream,
01237 std::string const & in_prefix)
01238 {
01239 io_stream << in_prefix;
01240
01241 if (in_idxEvent == m_curCheckPos)
01242 {
01243 io_stream << "## ";
01244 }
01245 else
01246 {
01247 io_stream << " ";
01248 }
01249 io_stream
01250 << (m_events[in_idxEvent].first ? "Ok " : " ? " )
01251 << std::setw(3) << in_idxEvent
01252 << ": " << m_events[in_idxEvent].second << endl;
01253
01254 }
01255
01256
01257
01258
01259
01260 };
01261
01262 #include "TestToolBox\CheckerForMultipleSequencesImpl.h"
01263
01264
01265
01266
01267
01268 #pragma warning( pop )