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