Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
TestHarness.cpp
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#include "Stroika/Foundation/StroikaPreComp.h"
5
6#include <cstdlib>
7#include <iostream>
8
12#include "Stroika/Foundation/Containers/Common.h"
14#include "Stroika/Foundation/Debug/Debugger.h"
15#include "Stroika/Foundation/Debug/Fatal.h"
16#include "Stroika/Foundation/Execution/Exceptions.h"
17#include "Stroika/Foundation/Execution/SignalHandlers.h"
18
19#include "TestHarness.h"
20
21using namespace Stroika::Foundation;
22using namespace Stroika::Frameworks;
23
25
26using namespace Stroika::Frameworks::Test;
27
28namespace {
29 void ASSERT_HANDLER_ (const wchar_t* assertCategory, const wchar_t* assertionText, const wchar_t* fileName, int lineNum, const wchar_t* functionName) noexcept
30 {
31 if (assertCategory == nullptr) {
32 assertCategory = L"Unknown assertion";
33 }
34 if (assertionText == nullptr) {
35 assertionText = L"";
36 }
37 if (fileName == nullptr) {
38 fileName = L"";
39 }
40 if (functionName == nullptr) {
41 functionName = L"";
42 }
43 wcerr << "FAILED: " << assertCategory << "; " << assertionText << ";" << functionName << ";" << fileName << ": " << lineNum << endl;
44 DbgTrace ("FAILED: {}; {}; {}; {}; {}"_f, assertCategory, assertionText, functionName, fileName, lineNum);
45
46 Debug::DropIntoDebuggerIfPresent ();
47
48 _Exit (EXIT_FAILURE); // skip
49 }
50 void WEAK_ASSERT_HANDLER_ (const wchar_t* assertCategory, const wchar_t* assertionText, const wchar_t* fileName, int lineNum,
51 const wchar_t* functionName) noexcept
52 {
53 if (assertCategory == nullptr) {
54 assertCategory = L"Unknown assertion";
55 }
56 if (assertionText == nullptr) {
57 assertionText = L"";
58 }
59 if (fileName == nullptr) {
60 fileName = L"";
61 }
62 if (functionName == nullptr) {
63 functionName = L"";
64 }
65 wcerr << "WARNING: weak assertion " << assertCategory << "; " << assertionText << ";" << functionName << ";" << fileName << ": "
66 << lineNum << endl;
67 DbgTrace ("WARNING: weak assertion {}; {}; {}; {}; {}"_f, assertCategory, assertionText, functionName, fileName, lineNum);
68 }
69 void FatalErrorHandler_ (const Characters::SDKChar* msg) noexcept
70 {
71#if qTargetPlatformSDKUseswchar_t
72 cerr << "FAILED: " << Characters::String::FromSDKString (msg) << endl;
73#else
74 cerr << "FAILED: " << msg << endl;
75#endif
76 Debug::DropIntoDebuggerIfPresent ();
77 _Exit (EXIT_FAILURE); // skip
78 }
79 void FatalSignalHandler_ (Execution::SignalID signal) noexcept
80 {
81 cerr << "FAILED: SIGNAL= " << Execution::SignalToName (signal) << endl;
82 DbgTrace ("FAILED: SIGNAL= {}"_f, Execution::SignalToName (signal));
83 Debug::DropIntoDebuggerIfPresent ();
84 _Exit (EXIT_FAILURE); // skip
85 }
86}
87
88vector<string> Test::Setup ([[maybe_unused]] int argc, [[maybe_unused]] const char* argv[])
89{
90#if qStroika_Foundation_Debug_AssertionsChecked
93#endif
94 Debug::RegisterDefaultFatalErrorHandlers (FatalErrorHandler_);
95 using namespace Execution;
96 SignalHandlerRegistry::Get ().SetStandardCrashHandlerSignals (SignalHandler{FatalSignalHandler_, SignalHandler::Type::eDirect});
97#if qStroika_HasComponent_googletest
98 // @todo fix to COPY so safe...
99 testing::InitGoogleTest (&argc, const_cast<char**> (argv));
100#endif
101 vector<string> v;
102 for (int i = 0; i < argc; ++i) {
103 v.push_back (argv[i]);
104 }
105 return v;
106}
107
108int Test::PrintPassOrFail (void (*regressionTest) ())
109{
110 try {
111 (*regressionTest) ();
112 cout << "Succeeded" << endl;
113 DbgTrace ("Succeeded"_f);
114 }
115 catch (...) {
116 auto exc = current_exception ();
117 cerr << "FAILED: REGRESSION TEST DUE TO EXCEPTION: '" << Characters::ToString (exc) << "'" << endl;
118 cout << "Failed" << endl;
119 DbgTrace ("FAILED: REGRESSION TEST (Exception): '{}"_f, Characters::ToString (exc));
120 Debug::DropIntoDebuggerIfPresent ();
121 return EXIT_FAILURE;
122 }
123 return EXIT_SUCCESS;
124}
125
126void Test::Private_::Test_ (bool failIfFalse, bool isFailureElseWarning, const wchar_t* regressionTestText, const wchar_t* fileName, int lineNum)
127{
128 if (not failIfFalse) {
129 if (isFailureElseWarning) {
130 ASSERT_HANDLER_ (L"RegressionTestFailure", regressionTestText, fileName, lineNum, nullptr);
131 }
132 else {
133 wcerr << "WARNING: REGRESSION TEST ISSUE: " << regressionTestText << ";" << fileName << ": " << lineNum << endl;
134 DbgTrace ("WARNING: REGRESSION TEST ISSUE: ; {}; {}; {}"_f, regressionTestText, fileName, lineNum);
135 // OK to continue
136 }
137 }
138}
139
140void Test::Private_::VerifyTestResultWarning_ (bool failIfFalse, bool isFailureElseWarning, const wchar_t* regressionTestText,
141 const wchar_t* fileName, int lineNum)
142{
143 if (not failIfFalse) {
144 if (isFailureElseWarning) {
145 ASSERT_HANDLER_ (L"RegressionTestFailure", regressionTestText, fileName, lineNum, nullptr);
146 }
147 else {
148 wcerr << "WARNING: REGRESSION TEST ISSUE: " << regressionTestText << ";" << fileName << ": " << lineNum << endl;
149 DbgTrace ("WARNING: REGRESSION TEST ISSUE: ; {}; {}; {}"_f, regressionTestText, fileName, lineNum);
150 // OK to continue
151 }
152 }
153}
154
155void Test::WarnTestIssue (const char* issue)
156{
157 using namespace Characters;
158 WarnTestIssue (NarrowSDK2Wide (issue).c_str ());
159}
160
161void Test::WarnTestIssue (const wchar_t* issue)
162{
163 wcerr << "WARNING: REGRESSION TEST ISSUE: '" << issue << "'" << endl;
164 DbgTrace ("WARNING: REGRESSION TEST ISSUE: '{}"_f, issue);
165}
166
167void Test::WarnTestIssue (const Foundation::Characters::String& issue)
168{
169 WarnTestIssue (issue.As<wstring> ().c_str ());
170}
void SetWeakAssertionHandler(AssertionHandlerType assertionHandler)
void SetAssertionHandler(AssertionHandlerType assertionHandler)
#define DbgTrace
Definition Trace.h:309
String is like std::u32string, except it is much easier to use, often much more space efficient,...
Definition String.h:201
static String FromSDKString(const SDKChar *from)
Definition String.inl:447
Create a format-string (see std::wformat_string or Stroika FormatString, or python 'f' strings.
conditional_t< qTargetPlatformSDKUseswchar_t, wchar_t, char > SDKChar
Definition SDKChar.h:71