Skip to content

Conversation

@eljonny
Copy link
Owner

@eljonny eljonny commented Feb 28, 2025

Fix the issues tagged by #5.

@eljonny eljonny added static-analysis An issue related to a static analysis result test-suite Relating to TestCPP TestSuite labels Feb 28, 2025
@eljonny eljonny added this to the 0.3-release milestone Feb 28, 2025
@eljonny eljonny self-assigned this Feb 28, 2025
@eljonny eljonny marked this pull request as draft February 28, 2025 09:08
@eljonny eljonny linked an issue Feb 28, 2025 that may be closed by this pull request
@github-actions
Copy link

github-actions bot commented Feb 28, 2025

⚡ Static analysis result ⚡

🔴 cppcheck found 20 issues! Click here to see details.

static constexpr const char* nullAssertionMessage = "Null assertion failed!";
bool null = ptr == nullptr;
if (!null) {
return logTestFailure(
"", "",

!Line: 304 - style: The scope of the variable 'nullAssertionMessage' can be reduced. [variableScope]

static constexpr const char* notNullAssertionMessage = "Not Null assertion failed!";
bool notNull = ptr != nullptr;
if (!notNull) {
return logTestFailure(
"", "",

!Line: 324 - style: The scope of the variable 'notNullAssertionMessage' can be reduced. [variableScope]

void clearStdoutCapture ();
/**
* @brief Clears the captured output from std::clog.
*
* This can be used for checking sections of output based on

!Line: 199 - performance: inconclusive: Technically the member function 'TestCPP::TestCase::clearStdoutCapture' can be static (but you may consider moving to unnamed namespace). [functionStatic]

!Line: 461 - note: Technically the member function 'TestCPP::TestCase::clearStdoutCapture' can be static (but you may consider moving to unnamed namespace).
!Line: 199 - note: Technically the member function 'TestCPP::TestCase::clearStdoutCapture' can be static (but you may consider moving to unnamed namespace).

void clearLogCapture ();
/**
* @brief Clears the captured output from stderr.
*
* This can be used for checking sections of output based on

!Line: 207 - performance: inconclusive: Technically the member function 'TestCPP::TestCase::clearLogCapture' can be static (but you may consider moving to unnamed namespace). [functionStatic]

!Line: 467 - note: Technically the member function 'TestCPP::TestCase::clearLogCapture' can be static (but you may consider moving to unnamed namespace).
!Line: 207 - note: Technically the member function 'TestCPP::TestCase::clearLogCapture' can be static (but you may consider moving to unnamed namespace).

void clearStderrCapture ();
/**
* @brief Check the argument against what is captured from
* stdout using the configured comparison mode.
* @param against The value to check the captured output against

!Line: 215 - performance: inconclusive: Technically the member function 'TestCPP::TestCase::clearStderrCapture' can be static (but you may consider moving to unnamed namespace). [functionStatic]

!Line: 473 - note: Technically the member function 'TestCPP::TestCase::clearStderrCapture' can be static (but you may consider moving to unnamed namespace).
!Line: 215 - note: Technically the member function 'TestCPP::TestCase::clearStderrCapture' can be static (but you may consider moving to unnamed namespace).

void logFailure (ostream& out, string& reason);
/**
* @brief If a test encounters an error while running, this
* function will be called to log the test error.
* @param failureMessage The error message from the test that
* should be logged.

!Line: 292 - style: inconclusive: Technically the member function 'TestCPP::TestCase::logFailure' can be const. [functionConst]

!Line: 292 - note: Technically the member function 'TestCPP::TestCase::logFailure' can be const.
!Line: 292 - note: Technically the member function 'TestCPP::TestCase::logFailure' can be const.

this->outCompareOption(std::move(o.option));
this->setNotifyPassed(std::move(o.notifyTestPassed));
this->pass = std::move(o.pass);
this->lastRunTime = std::move(o.lastRunTime);

!Line: 171 - error: Exception thrown in function declared not to throw exceptions. [throwInNoexceptFunction]

this->outCompareOption(std::move(rhs.option));
this->setNotifyPassed(std::move(rhs.notifyTestPassed));
this->pass = std::move(rhs.pass);
this->lastRunTime = std::move(rhs.lastRunTime);

!Line: 262 - error: Exception thrown in function declared not to throw exceptions. [throwInNoexceptFunction]

TestCase::TestCase (TestObjName&& name,
function<void()> testFn,
bool msg,
bool captureOut, bool captureLog,
bool captureErr,
TestCase::TestCaseOutCompareOptions opt)

!Line: 114 - style: inconclusive: Function 'TestCase' argument 1 names different: declaration 'testName' definition 'name'. [funcArgNamesDifferent]

!Line: 132 - note: Function 'TestCase' argument 1 names different: declaration 'testName' definition 'name'.
!Line: 114 - note: Function 'TestCase' argument 1 names different: declaration 'testName' definition 'name'.

function<void()> testFn,
bool msg,
bool captureOut, bool captureLog,
bool captureErr,
TestCase::TestCaseOutCompareOptions opt)
{

!Line: 115 - style: inconclusive: Function 'TestCase' argument 2 names different: declaration 'test' definition 'testFn'. [funcArgNamesDifferent]

!Line: 133 - note: Function 'TestCase' argument 2 names different: declaration 'test' definition 'testFn'.
!Line: 115 - note: Function 'TestCase' argument 2 names different: declaration 'test' definition 'testFn'.

bool msg,
bool captureOut, bool captureLog,
bool captureErr,
TestCase::TestCaseOutCompareOptions opt)
{
this->notifyTestPassed = msg;

!Line: 116 - style: inconclusive: Function 'TestCase' argument 3 names different: declaration 'testPassedMessage' definition 'msg'. [funcArgNamesDifferent]

!Line: 134 - note: Function 'TestCase' argument 3 names different: declaration 'testPassedMessage' definition 'msg'.
!Line: 116 - note: Function 'TestCase' argument 3 names different: declaration 'testPassedMessage' definition 'msg'.

void TestCase::logTestFailure (string reason) {
unique_ptr<ostream> logStream = nullptr;
if (this->clogOriginal.get() != nullptr) {
logStream = unique_ptr<ostream>(
new ostream(this->clogOriginal.get().get())

!Line: 304 - style: inconclusive: Function 'logTestFailure' argument 1 names different: declaration 'failureMessage' definition 'reason'. [funcArgNamesDifferent]

!Line: 299 - note: Function 'logTestFailure' argument 1 names different: declaration 'failureMessage' definition 'reason'.
!Line: 304 - note: Function 'logTestFailure' argument 1 names different: declaration 'failureMessage' definition 'reason'.

void TestCase::setNotifyPassed (bool notify) {
this->notifyTestPassed = notify;
}
void TestCase::captureStdout () {
if (TestCase::stdoutCaptureCasesConstructed ==

!Line: 371 - style: inconclusive: Function 'setNotifyPassed' argument 1 names different: declaration 'shouldNotify' definition 'notify'. [funcArgNamesDifferent]

!Line: 180 - note: Function 'setNotifyPassed' argument 1 names different: declaration 'shouldNotify' definition 'notify'.
!Line: 371 - note: Function 'setNotifyPassed' argument 1 names different: declaration 'shouldNotify' definition 'notify'.

TestCase::TestCase (TestCase& o) {
this->outCompareOption(o.option);
this->setNotifyPassed(o.notifyTestPassed);
this->pass = o.pass;
this->lastRunTime = o.lastRunTime;

!Line: 145 - style: Parameter 'o' can be declared as reference to const [constParameterReference]

TestCase& TestCase::operator= (TestCase& rhs) {
this->outCompareOption(rhs.option);
this->setNotifyPassed(rhs.notifyTestPassed);
this->pass = rhs.pass;
this->lastRunTime = rhs.lastRunTime;

!Line: 234 - style: Parameter 'rhs' can be declared as reference to const [constParameterReference]

void TestCase::logFailure(ostream& out, string& reason) {
out << fixed;
out << setprecision(TCPPNum::TIME_PRECISION);
out << TCPPStr::TEST << this->testName << TCPPStr::FAIL
<< TCPPStr::PARENL
<< static_cast<double>(this->lastRunTime)/

!Line: 292 - style: Parameter 'reason' can be declared as reference to const [constParameterReference]

inline addTests () { }
/**
* @brief Add one or more tests at once to the test suite.
* @param test The first test to add.
* @param tests The rest of the tests to add.

!Line: 112 - performance: inconclusive: Technically the member function 'TestCPP::TestSuite::addTests' can be static (but you may consider moving to unnamed namespace). [functionStatic]

unsigned getLastRunFailCount ();
/**
* @brief Retrieve the total number of tests in the suite that
* succeeded (passed) during the last suite run.
* @return The total number of tests that passed in the last

!Line: 148 - style: inconclusive: Technically the member function 'TestCPP::TestSuite::getLastRunFailCount' can be const. [functionConst]

!Line: 73 - note: Technically the member function 'TestCPP::TestSuite::getLastRunFailCount' can be const.
!Line: 148 - note: Technically the member function 'TestCPP::TestSuite::getLastRunFailCount' can be const.

unsigned getLastRunSuccessCount();
/**
* @brief Run all tests in the test suite.
*/
void run ();

!Line: 156 - style: inconclusive: Technically the member function 'TestCPP::TestSuite::getLastRunSuccessCount' can be const. [functionConst]

!Line: 77 - note: Technically the member function 'TestCPP::TestSuite::getLastRunSuccessCount' can be const.
!Line: 156 - note: Technically the member function 'TestCPP::TestSuite::getLastRunSuccessCount' can be const.

const string& getName ();
/**
* @brief Output the test object name to the specified stream.
* @param s The stream to output to.
* @param tcName The test object name object.

!Line: 81 - style: inconclusive: Technically the member function 'TestCPP::TestObjName::getName' can be const. [functionConst]

!Line: 59 - note: Technically the member function 'TestCPP::TestObjName::getName' can be const.
!Line: 81 - note: Technically the member function 'TestCPP::TestObjName::getName' can be const.

🔴 clang-tidy found 149 issues! Click here to see details.

static constexpr const char * SP = " ";
static constexpr const char * START_RUN =
"Starting run of test ";
static constexpr const char * SUITE = "Suite ";
static constexpr const char * SUITE_TESTS_PASSED =
" suite tests passed!";

!Line: 88 - error: variable name 'SP' is too short, expected at least 3 characters [readability-identifier-length,-warnings-as-errors]

TestObjName (const char* name);
/**
* @brief Get the encapsulated name for the TestCPP object that
* holds this object.
* @return The name of the TestCPP object that this object

!Line: 73 - error: single-argument constructors must be marked explicit to avoid unintentional implicit conversions [hicpp-explicit-conversions,-warnings-as-errors]

const string& getName ();
/**
* @brief Output the test object name to the specified stream.
* @param s The stream to output to.
* @param tcName The test object name object.

!Line: 81 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

friend std::ostream& operator<< (
std::ostream& s,
TestObjName& tcName
);
private:

!Line: 89 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

std::ostream& s,
TestObjName& tcName
);
private:
string testCaseName;

!Line: 90 - error: parameter name 's' is too short, expected at least 3 characters [readability-identifier-length,-warnings-as-errors]

template <class T> class no_destroy {
alignas(T) unsigned char data[sizeof(T)];
public:
template <class... Ts> no_destroy(Ts&&... ts) { new (data) T(std::forward<Ts>(ts)...); }
T& get() { return *reinterpret_cast<T*>(data); }
};

!Line: 106 - error: constructor does not initialize these fields: data [cppcoreguidelines-pro-type-member-init,hicpp-member-init,-warnings-as-errors]

alignas(T) unsigned char data[sizeof(T)];
public:
template <class... Ts> no_destroy(Ts&&... ts) { new (data) T(std::forward<Ts>(ts)...); }
T& get() { return *reinterpret_cast<T*>(data); }
};

!Line: 107 - error: do not declare C-style arrays, use 'std::array' instead [cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays,-warnings-as-errors]

template <class... Ts> no_destroy(Ts&&... ts) { new (data) T(std::forward<Ts>(ts)...); }
T& get() { return *reinterpret_cast<T*>(data); }
};
/**
* @brief Log a message that will only be output when debug

!Line: 109 - error: constructor does not initialize these fields: data [cppcoreguidelines-pro-type-member-init,hicpp-member-init,-warnings-as-errors]

template <class... Ts> no_destroy(Ts&&... ts) { new (data) T(std::forward<Ts>(ts)...); }
T& get() { return *reinterpret_cast<T*>(data); }
};
/**
* @brief Log a message that will only be output when debug

!Line: 109 - error: constructors that are callable with a single argument must be marked explicit to avoid unintentional implicit conversions [hicpp-explicit-conversions,-warnings-as-errors]

template <class... Ts> no_destroy(Ts&&... ts) { new (data) T(std::forward<Ts>(ts)...); }
T& get() { return *reinterpret_cast<T*>(data); }
};
/**
* @brief Log a message that will only be output when debug

!Line: 109 - error: parameter name 'ts' is too short, expected at least 3 characters [readability-identifier-length,-warnings-as-errors]

T& get() { return *reinterpret_cast<T*>(data); }
};
/**
* @brief Log a message that will only be output when debug
* logging is enabled.

!Line: 110 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

T& get() { return *reinterpret_cast<T*>(data); }
};
/**
* @brief Log a message that will only be output when debug
* logging is enabled.

!Line: 110 - error: do not use reinterpret_cast [cppcoreguidelines-pro-type-reinterpret-cast,-warnings-as-errors]

bool stringContains (const string& source,
const string& contains);
/**
* @brief Safely converts unsigned integer values to signed.
* @param toCast The unsigned value to convert.

!Line: 136 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

int unsignedToSigned(unsigned toCast);
}
}
#endif

!Line: 144 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

if (name) {
this->testCaseName = name;
}
else {
throw TestCPPException(TCPPStr::NVTN);
}

!Line: 51 - error: implicit conversion 'const char *' -> 'bool' [readability-implicit-bool-conversion,-warnings-as-errors]

const string& TestObjName::getName () {
return this->testCaseName;
}
std::ostream& operator<< (
std::ostream& s,

!Line: 59 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

std::ostream& operator<< (
std::ostream& s,
TestObjName& tcName
)
{
s << tcName.getName();

!Line: 63 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

std::ostream& s,
TestObjName& tcName
)
{
s << tcName.getName();
return s;

!Line: 64 - error: parameter name 's' is too short, expected at least 3 characters [readability-identifier-length,-warnings-as-errors]

clog << endl;
}
#endif
}
bool stringContains(const string& source,

!Line: 78 - error: do not use 'endl' with streams; use '\n' instead [performance-avoid-endl,-warnings-as-errors]

bool stringContains(const string& source,
const string& contains)
{
return source.find(contains) != string::npos;
}

!Line: 83 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

int unsignedToSigned(unsigned toCast) {
if (toCast <= INT_MAX) {
return static_cast<int>(toCast);
}
if (toCast >= static_cast<unsigned>(INT_MIN)) {

!Line: 89 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

#include <iostream>
#include "internal/TestCPPExceptions.h"
#ifdef TESTCPP_STACKTRACE_ENABLED
#include <boost/stacktrace.hpp>

!Line: 28 - error: included header iostream is not used directly [misc-include-cleaner,-warnings-as-errors]

using std::string;
using std::runtime_error;
namespace TestCPP {
TestCPPException::TestCPPException (const char * msg) :

!Line: 37 - error: no header providing "std::string" is directly included [misc-include-cleaner,-warnings-as-errors]

using std::runtime_error;
namespace TestCPP {
TestCPPException::TestCPPException (const char * msg) :
runtime_error(msg)

!Line: 38 - error: no header providing "std::runtime_error" is directly included [misc-include-cleaner,-warnings-as-errors]

TestCPPException(std::move(msg))
{
#ifdef TESTCPP_STACKTRACE_ENABLED
clog << boost::stacktrace::stacktrace();
#endif
}

!Line: 66 - error: std::move of the const variable 'msg' has no effect or make the variable non-const [hicpp-move-const-arg,performance-move-const-arg,-warnings-as-errors]

!Line: 49 - note: consider changing the 1st parameter of 'TestCPPException' from 'const string &&' (aka 'const basic_string<char> &&') to 'const string &'

TestCPPException(std::move(msg))
{
#ifdef TESTCPP_STACKTRACE_ENABLED
clog << boost::stacktrace::stacktrace();
#endif
}

!Line: 66 - error: no header providing "std::move" is directly included [misc-include-cleaner,-warnings-as-errors]

if (err.size()) {
throw TestFailedException(std::move(err));
}
}
/**

!Line: 84 - error: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty,-warnings-as-errors]

throw TestFailedException(std::move(err));
}
}
/**
* @brief Check that something is not equivalent to something

!Line: 85 - error: std::move of the const variable 'err' has no effect or make the variable non-const [hicpp-move-const-arg,performance-move-const-arg,-warnings-as-errors]

!Line: 98 - note: consider changing the 1st parameter of 'TestFailedException' from 'const string &&' (aka 'const basic_string<char> &&') to 'const string &'

if (err.size()) {
throw TestFailedException(std::move(err));
}
}
/**

!Line: 110 - error: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty,-warnings-as-errors]

throw TestFailedException(std::move(err));
}
}
/**
* @brief Check that a pointer is null.

!Line: 111 - error: std::move of the const variable 'err' has no effect or make the variable non-const [hicpp-move-const-arg,performance-move-const-arg,-warnings-as-errors]

!Line: 98 - note: consider changing the 1st parameter of 'TestFailedException' from 'const string &&' (aka 'const basic_string<char> &&') to 'const string &'

if (err.size()) {
throw TestFailedException(std::move(err));
}
}
/**

!Line: 131 - error: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty,-warnings-as-errors]

throw TestFailedException(std::move(err));
}
}
/**
* @brief Check that a pointer is non-null.

!Line: 132 - error: std::move of the const variable 'err' has no effect or make the variable non-const [hicpp-move-const-arg,performance-move-const-arg,-warnings-as-errors]

!Line: 98 - note: consider changing the 1st parameter of 'TestFailedException' from 'const string &&' (aka 'const basic_string<char> &&') to 'const string &'

if (err.size()) {
throw TestFailedException(std::move(err));
}
}
/**

!Line: 152 - error: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty,-warnings-as-errors]

throw TestFailedException(std::move(err));
}
}
/**
* @brief Verify that a function throws something.

!Line: 153 - error: std::move of the const variable 'err' has no effect or make the variable non-const [hicpp-move-const-arg,performance-move-const-arg,-warnings-as-errors]

!Line: 98 - note: consider changing the 1st parameter of 'TestFailedException' from 'const string &&' (aka 'const basic_string<char> &&') to 'const string &'

static const string logTestFailure(
T1 expectationValue, T2 actual,
const string& assertionTypeMessage,
const string& failureMessage,
const bool logValues
)

!Line: 243 - error: return type 'const string' (aka 'const basic_string<char>') is 'const'-qualified at the top level, which may reduce code readability without improving const correctness [readability-const-return-type,-warnings-as-errors]

static const string logTestFailure(
T1 expectationValue, T2 actual,
const string& assertionTypeMessage,
const string& failureMessage,
const bool logValues
)

!Line: 243 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

err << assertionTypeMessage << endl;
err << failureMessage << endl;
if (logValues) {
err << "Expectation value: <" << expectationValue << ">"
<< endl;

!Line: 252 - error: do not use 'endl' with streams; use '\n' instead [performance-avoid-endl,-warnings-as-errors]

err << failureMessage << endl;
if (logValues) {
err << "Expectation value: <" << expectationValue << ">"
<< endl;
err << "Actual: <" << actual << ">" << endl;

!Line: 253 - error: do not use 'endl' with streams; use '\n' instead [performance-avoid-endl,-warnings-as-errors]

static const string checkEquals(
T1 expected, T2 actual,
const string& failureMessage
)
{
if (expected != actual) {

!Line: 265 - error: return type 'const string' (aka 'const basic_string<char>') is 'const'-qualified at the top level, which may reduce code readability without improving const correctness [readability-const-return-type,-warnings-as-errors]

static const string checkEquals(
T1 expected, T2 actual,
const string& failureMessage
)
{
if (expected != actual) {

!Line: 265 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

static const string checkNotEquals(
T1 shouldNotBe, T2 actual,
const string& failureMessage
)
{
if (shouldNotBe == actual) {

!Line: 282 - error: return type 'const string' (aka 'const basic_string<char>') is 'const'-qualified at the top level, which may reduce code readability without improving const correctness [readability-const-return-type,-warnings-as-errors]

static const string checkNotEquals(
T1 shouldNotBe, T2 actual,
const string& failureMessage
)
{
if (shouldNotBe == actual) {

!Line: 282 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

static const string checkNull(
T ptr,
const string& failureMessage
)
{
static constexpr const char* nullAssertionMessage = "Null assertion failed!";

!Line: 299 - error: return type 'const string' (aka 'const basic_string<char>') is 'const'-qualified at the top level, which may reduce code readability without improving const correctness [readability-const-return-type,-warnings-as-errors]

static const string checkNull(
T ptr,
const string& failureMessage
)
{
static constexpr const char* nullAssertionMessage = "Null assertion failed!";

!Line: 299 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

static const string checkNotNull(
T ptr,
const string& failureMessage
)
{
static constexpr const char* notNullAssertionMessage = "Not Null assertion failed!";

!Line: 319 - error: return type 'const string' (aka 'const basic_string<char>') is 'const'-qualified at the top level, which may reduce code readability without improving const correctness [readability-const-return-type,-warnings-as-errors]

static const string checkNotNull(
T ptr,
const string& failureMessage
)
{
static constexpr const char* notNullAssertionMessage = "Not Null assertion failed!";

!Line: 319 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

const string TestCPP::Assertions::checkEquals<const char*, const char*>(
const char* expected, const char* actual,
const string& failureMessage
);
template<>

!Line: 389 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

const string TestCPP::Assertions::checkNotEquals<const char*, const char*>(
const char* shouldNotBe, const char* actual,
const string& failureMessage
);
#endif

!Line: 395 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

using std::clog;
using std::current_exception;
using std::endl;
using std::exception;
using std::exception_ptr;
using std::function;

!Line: 30 - error: no header providing "std::clog" is directly included [misc-include-cleaner,-warnings-as-errors]

using std::current_exception;
using std::endl;
using std::exception;
using std::exception_ptr;
using std::function;
using std::rethrow_exception;

!Line: 31 - error: no header providing "std::current_exception" is directly included [misc-include-cleaner,-warnings-as-errors]

using std::exception;
using std::exception_ptr;
using std::function;
using std::rethrow_exception;
using std::string;
using std::stringstream;

!Line: 33 - error: no header providing "std::exception" is directly included [misc-include-cleaner,-warnings-as-errors]

using std::exception_ptr;
using std::function;
using std::rethrow_exception;
using std::string;
using std::stringstream;

!Line: 34 - error: no header providing "std::__exception_ptr::exception_ptr" is directly included [misc-include-cleaner,-warnings-as-errors]

using std::function;
using std::rethrow_exception;
using std::string;
using std::stringstream;
namespace TestCPP {

!Line: 35 - error: no header providing "std::function" is directly included [misc-include-cleaner,-warnings-as-errors]

using std::rethrow_exception;
using std::string;
using std::stringstream;
namespace TestCPP {

!Line: 36 - error: no header providing "std::rethrow_exception" is directly included [misc-include-cleaner,-warnings-as-errors]

using std::string;
using std::stringstream;
namespace TestCPP {
template<>

!Line: 37 - error: no header providing "std::string" is directly included [misc-include-cleaner,-warnings-as-errors]

using std::stringstream;
namespace TestCPP {
template<>
const string Assertions::checkEquals<const char*, const char*>(

!Line: 38 - error: no header providing "std::stringstream" is directly included [misc-include-cleaner,-warnings-as-errors]

const string Assertions::checkEquals<const char*, const char*>(
const char* expected, const char* actual,
const string& failureMessage
)
{
if (strcmp(expected, actual)) {

!Line: 43 - error: return type 'const string' (aka 'const basic_string<char>') is 'const'-qualified at the top level, which may reduce code readability without improving const correctness [readability-const-return-type,-warnings-as-errors]

const string Assertions::checkEquals<const char*, const char*>(
const char* expected, const char* actual,
const string& failureMessage
)
{
if (strcmp(expected, actual)) {

!Line: 43 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

if (strcmp(expected, actual)) {
return logTestFailure(
expected, actual,
equivalenceAssertionMessage,
failureMessage,
true

!Line: 48 - error: function 'strcmp' is called without explicitly comparing result [bugprone-suspicious-string-compare,-warnings-as-errors]

if (strcmp(expected, actual)) {
return logTestFailure(
expected, actual,
equivalenceAssertionMessage,
failureMessage,
true

!Line: 48 - error: no header providing "strcmp" is directly included [misc-include-cleaner,-warnings-as-errors]

if (strcmp(expected, actual)) {
return logTestFailure(
expected, actual,
equivalenceAssertionMessage,
failureMessage,
true

!Line: 48 - error: implicit conversion 'int' -> 'bool' [readability-implicit-bool-conversion,-warnings-as-errors]

const string Assertions::checkNotEquals<const char*, const char*>(
const char* shouldNotBe, const char* actual,
const string& failureMessage
)
{
if (!strcmp(shouldNotBe, actual)) {

!Line: 60 - error: return type 'const string' (aka 'const basic_string<char>') is 'const'-qualified at the top level, which may reduce code readability without improving const correctness [readability-const-return-type,-warnings-as-errors]

const string Assertions::checkNotEquals<const char*, const char*>(
const char* shouldNotBe, const char* actual,
const string& failureMessage
)
{
if (!strcmp(shouldNotBe, actual)) {

!Line: 60 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

if (!strcmp(shouldNotBe, actual)) {
return logTestFailure(
shouldNotBe, actual,
nonequivalenceAssertionMessage,
failureMessage,
true

!Line: 65 - error: implicit conversion 'int' -> 'bool' [readability-implicit-bool-conversion,-warnings-as-errors]

if (err.size()) {
throw TestFailedException(std::move(err));
}
}
template<>

!Line: 83 - error: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty,-warnings-as-errors]

if (err.size()) {
throw TestFailedException(std::move(err));
}
}
template<>

!Line: 83 - error: implicit conversion 'size_type' (aka 'unsigned long') -> 'bool' [readability-implicit-bool-conversion,-warnings-as-errors]

throw TestFailedException(std::move(err));
}
}
template<>
void Assertions::assertNotEquals<const char*, const char*>(

!Line: 84 - error: std::move of the const variable 'err' has no effect or make the variable non-const [hicpp-move-const-arg,performance-move-const-arg,-warnings-as-errors]

!Line: 98 - note: consider changing the 1st parameter of 'TestFailedException' from 'const string &&' (aka 'const basic_string<char> &&') to 'const string &'

throw TestFailedException(std::move(err));
}
}
template<>
void Assertions::assertNotEquals<const char*, const char*>(

!Line: 84 - error: no header providing "std::move" is directly included [misc-include-cleaner,-warnings-as-errors]

if (err.size()) {
throw TestFailedException(std::move(err));
}
}
void Assertions::assertThrows (

!Line: 96 - error: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty,-warnings-as-errors]

if (err.size()) {
throw TestFailedException(std::move(err));
}
}
void Assertions::assertThrows (

!Line: 96 - error: implicit conversion 'size_type' (aka 'unsigned long') -> 'bool' [readability-implicit-bool-conversion,-warnings-as-errors]

throw TestFailedException(std::move(err));
}
}
void Assertions::assertThrows (
function<void()> shouldThrow,

!Line: 97 - error: std::move of the const variable 'err' has no effect or make the variable non-const [hicpp-move-const-arg,performance-move-const-arg,-warnings-as-errors]

!Line: 98 - note: consider changing the 1st parameter of 'TestFailedException' from 'const string &&' (aka 'const basic_string<char> &&') to 'const string &'

function<void()> shouldThrow,
const string& failureMessage
)
{
try {
shouldThrow();

!Line: 102 - error: the parameter 'shouldThrow' is copied for each invocation but only used as a const reference; consider making it a const reference [performance-unnecessary-value-param,-warnings-as-errors]

exception_ptr eptr = current_exception();
if (eptr) {
try {
rethrow_exception(eptr);
}

!Line: 110 - error: variable 'eptr' of type 'exception_ptr' can be declared 'const' [misc-const-correctness,-warnings-as-errors]

<< endl;
}
}
else {
clog << "Something was thrown, not sure what." << endl
<< "This satisfies the assertion, so no failure is"

!Line: 119 - error: do not use 'endl' with streams; use '\n' instead [performance-avoid-endl,-warnings-as-errors]

clog << "Something was thrown, not sure what." << endl
<< "This satisfies the assertion, so no failure is"
<< " present. "
<< TestFailedException("Unknown thrown object").
what();
}

!Line: 123 - error: do not use 'endl' with streams; use '\n' instead [performance-avoid-endl,-warnings-as-errors]

throw TestFailedException(std::move(failureMessage));
}
void Assertions::assertNoThrows (
function<void()> shouldNotThrow,
const string& failureMessage

!Line: 133 - error: std::move of the const variable 'failureMessage' has no effect or make the variable non-const [hicpp-move-const-arg,performance-move-const-arg,-warnings-as-errors]

!Line: 98 - note: consider changing the 1st parameter of 'TestFailedException' from 'const string &&' (aka 'const basic_string<char> &&') to 'const string &'

function<void()> shouldNotThrow,
const string& failureMessage
)
{
try {
shouldNotThrow();

!Line: 137 - error: the parameter 'shouldNotThrow' is copied for each invocation but only used as a const reference; consider making it a const reference [performance-unnecessary-value-param,-warnings-as-errors]

throw TestFailedException(std::move(failureMessage));
}
}
void Assertions::assertTrue (
bool condition,

!Line: 145 - error: std::move of the const variable 'failureMessage' has no effect or make the variable non-const [hicpp-move-const-arg,performance-move-const-arg,-warnings-as-errors]

!Line: 98 - note: consider changing the 1st parameter of 'TestFailedException' from 'const string &&' (aka 'const basic_string<char> &&') to 'const string &'

if (err.size()) {
throw TestFailedException(std::move(err));
}
}
}

!Line: 164 - error: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty,-warnings-as-errors]

if (err.size()) {
throw TestFailedException(std::move(err));
}
}
}

!Line: 164 - error: implicit conversion 'size_type' (aka 'unsigned long') -> 'bool' [readability-implicit-bool-conversion,-warnings-as-errors]

throw TestFailedException(std::move(err));
}
}
}
void Assertions::assertFalse (

!Line: 165 - error: std::move of the const variable 'err' has no effect or make the variable non-const [hicpp-move-const-arg,performance-move-const-arg,-warnings-as-errors]

!Line: 98 - note: consider changing the 1st parameter of 'TestFailedException' from 'const string &&' (aka 'const basic_string<char> &&') to 'const string &'

if (err.size()) {
throw TestFailedException(std::move(err));
}
}
}

!Line: 185 - error: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty,-warnings-as-errors]

if (err.size()) {
throw TestFailedException(std::move(err));
}
}
}

!Line: 185 - error: implicit conversion 'size_type' (aka 'unsigned long') -> 'bool' [readability-implicit-bool-conversion,-warnings-as-errors]

throw TestFailedException(std::move(err));
}
}
}
[[noreturn]] void Assertions::fail(string failureMessage) {

!Line: 186 - error: std::move of the const variable 'err' has no effect or make the variable non-const [hicpp-move-const-arg,performance-move-const-arg,-warnings-as-errors]

!Line: 98 - note: consider changing the 1st parameter of 'TestFailedException' from 'const string &&' (aka 'const basic_string<char> &&') to 'const string &'

[[noreturn]] void Assertions::fail(string failureMessage) {
throw TestFailedException(std::move(failureMessage));
}
}

!Line: 191 - error: the parameter 'failureMessage' is copied for each invocation but only used as a const reference; consider making it a const reference [performance-unnecessary-value-param,-warnings-as-errors]

throw TestFailedException(std::move(failureMessage));
}
}

!Line: 192 - error: no header providing "std::move" is directly included [misc-include-cleaner,-warnings-as-errors]

enum TestCaseOutCompareOptions {
CONTAINS,
EXACT
};
/**

!Line: 92 - error: enum 'TestCaseOutCompareOptions' uses a larger base type ('unsigned int', size: 4 bytes) than necessary for its value set, consider using 'std::uint8_t' (1 byte) as the base type to reduce its size [performance-enum-size,-warnings-as-errors]

TestCase (TestCase& o);
/**
* @brief Construct a TestCase by moving all data from another
* TestCase.
* @param o Move everything from this TestCase into the new one.

!Line: 146 - error: parameter name 'o' is too short, expected at least 3 characters [readability-identifier-length,-warnings-as-errors]

TestCase (TestCase&& o) noexcept;
/**
* @brief Copy a TestCase into another TestCase.
* @param rhs The test case to copy from.
* @return A reference to the new TestCase copy.

!Line: 153 - error: parameter name 'o' is too short, expected at least 3 characters [readability-identifier-length,-warnings-as-errors]

TestCase& operator= (TestCase& rhs);
/**
* @brief Move a TestCase into another TestCase.
* @param rhs Move everything from this TestCase into the new
* one.

!Line: 160 - error: operator=() should take 'TestCase const&', 'TestCase&&' or 'TestCase' [cppcoreguidelines-c-copy-assignment-signature,misc-unconventional-assign-operator,-warnings-as-errors]

TestCase& operator= (TestCase& rhs);
/**
* @brief Move a TestCase into another TestCase.
* @param rhs Move everything from this TestCase into the new
* one.

!Line: 160 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

TestCase& operator= (TestCase&& rhs) noexcept;
/**
* @brief Destroy a TestCase object.
*/
~TestCase ();

!Line: 169 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

bool checkStdout (const string& against);
/**
* @brief Check the argument against what is captured from
* std::clog using the configured comparison mode.
* @param against The value to check the captured output against

!Line: 224 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

bool checkLog (const string& against);
/**
* @brief Check the argument against what is captured from
* stderr using the configured comparison mode.
* @param against The value to check the captured output against

!Line: 233 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

bool checkStderr (const string& against);
/**
* @brief Run the test case.
* @return True if the test ran successfully, false otherwise.
*/

!Line: 243 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

bool go ();
/**
* @brief Returns the duration of the last run in nanoseconds.
* @return The duration of the last run of this TestCase in
* nanoseconds.

!Line: 249 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

long long getLastRuntime () const;
private:
bool notifyTestPassed = false;
bool pass = false;
bool stdoutCaptured = false;

!Line: 256 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

bool checkOutput (const string& source, const string& against);
static atomic_int stdoutCaptureCasesConstructed;
static atomic_int logCaptureCasesConstructed;
static atomic_int stderrCaptureCasesConstructed;
static atomic_int stdoutCaptureCasesDestroyed;

!Line: 315 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

static nanoseconds duration (F func, Args&&... args)
{
auto start = system_clock::now();
func(forward<Args>(args)...);
return duration_cast<nanoseconds>(
system_clock::now() - start

!Line: 345 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

TestSuite (TestObjName&& newSuiteName,
typename enable_if<sizeof...(TestType) == 0>::type)
{
commonInit(std::forward<TestObjName>(newSuiteName));
}

!Line: 79 - error: constructor does not initialize these fields: firstRun, testSuitePassedMessage, lastRunSucceeded, lastRunSuccessCount, lastRunFailCount, totalRuntime [cppcoreguidelines-pro-type-member-init,hicpp-member-init,-warnings-as-errors]

TestSuite (TestObjName&& newSuiteName,
typename enable_if<sizeof...(TestType) == 0>::type)
{
commonInit(std::forward<TestObjName>(newSuiteName));
}

!Line: 79 - error: rvalue reference parameter 'newSuiteName' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved,-warnings-as-errors]

typename enable_if<sizeof...(TestType) == 0>::type)
{
commonInit(std::forward<TestObjName>(newSuiteName));
}
/**

!Line: 80 - error: all parameters should be named in a function [hicpp-named-parameter,readability-named-parameter,-warnings-as-errors]

TestSuite (TestObjName&& newSuiteName, TestType ...tests)
{
commonInit(std::forward<TestObjName>(newSuiteName));
this->addTests(tests...);
}

!Line: 90 - error: constructor does not initialize these fields: firstRun, testSuitePassedMessage, lastRunSucceeded, lastRunSuccessCount, lastRunFailCount, totalRuntime [cppcoreguidelines-pro-type-member-init,hicpp-member-init,-warnings-as-errors]

TestSuite (TestObjName&& newSuiteName, TestType ...tests)
{
commonInit(std::forward<TestObjName>(newSuiteName));
this->addTests(tests...);
}

!Line: 90 - error: constructors that are callable with a single argument must be marked explicit to avoid unintentional implicit conversions [hicpp-explicit-conversions,-warnings-as-errors]

TestSuite (TestObjName&& newSuiteName, TestType ...tests)
{
commonInit(std::forward<TestObjName>(newSuiteName));
this->addTests(tests...);
}

!Line: 90 - error: rvalue reference parameter 'newSuiteName' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved,-warnings-as-errors]

inline addTests () { }
/**
* @brief Add one or more tests at once to the test suite.
* @param test The first test to add.
* @param tests The rest of the tests to add.

!Line: 112 - error: function 'addTests' has inline specifier but is implicitly inlined [readability-redundant-inline-specifier,-warnings-as-errors]

inline addTests () { }
/**
* @brief Add one or more tests at once to the test suite.
* @param test The first test to add.
* @param tests The rest of the tests to add.

!Line: 112 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

unsigned getLastRunFailCount ();
/**
* @brief Retrieve the total number of tests in the suite that
* succeeded (passed) during the last suite run.
* @return The total number of tests that passed in the last

!Line: 148 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

unsigned getLastRunSuccessCount();
/**
* @brief Run all tests in the test suite.
*/
void run ();

!Line: 156 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

void commonInit(TestObjName&& newSuiteName) {
this->firstRun = true;
this->testSuitePassedMessage = true;
this->lastRunSucceeded = true;
this->lastRunFailCount = zeroInit;

!Line: 181 - error: rvalue reference parameter 'newSuiteName' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved,-warnings-as-errors]

using std::cerr;
using std::clog;
using std::cout;
using std::endl;
using std::exception;
using std::fixed;

!Line: 36 - error: no header providing "std::cerr" is directly included [misc-include-cleaner,-warnings-as-errors]

using std::clog;
using std::cout;
using std::endl;
using std::exception;
using std::fixed;
using std::function;

!Line: 37 - error: no header providing "std::clog" is directly included [misc-include-cleaner,-warnings-as-errors]

using std::cout;
using std::endl;
using std::exception;
using std::fixed;
using std::function;
using std::invalid_argument;

!Line: 38 - error: no header providing "std::cout" is directly included [misc-include-cleaner,-warnings-as-errors]

using std::cout;
using std::endl;
using std::exception;
using std::fixed;
using std::function;
using std::invalid_argument;

!Line: 38 - error: using decl 'cout' is unused [misc-unused-using-decls,-warnings-as-errors]

!Line: 38 - note: remove the using

using std::exception;
using std::fixed;
using std::function;
using std::invalid_argument;
using std::ostream;
using std::rethrow_exception;

!Line: 40 - error: no header providing "std::exception" is directly included [misc-include-cleaner,-warnings-as-errors]

using std::fixed;
using std::function;
using std::invalid_argument;
using std::ostream;
using std::rethrow_exception;
using std::runtime_error;

!Line: 41 - error: no header providing "std::fixed" is directly included [misc-include-cleaner,-warnings-as-errors]

using std::function;
using std::invalid_argument;
using std::ostream;
using std::rethrow_exception;
using std::runtime_error;
using std::setprecision;

!Line: 42 - error: no header providing "std::function" is directly included [misc-include-cleaner,-warnings-as-errors]

using std::invalid_argument;
using std::ostream;
using std::rethrow_exception;
using std::runtime_error;
using std::setprecision;
using std::string;

!Line: 43 - error: no header providing "std::invalid_argument" is directly included [misc-include-cleaner,-warnings-as-errors]

using std::invalid_argument;
using std::ostream;
using std::rethrow_exception;
using std::runtime_error;
using std::setprecision;
using std::string;

!Line: 43 - error: using decl 'invalid_argument' is unused [misc-unused-using-decls,-warnings-as-errors]

!Line: 43 - note: remove the using

using std::ostream;
using std::rethrow_exception;
using std::runtime_error;
using std::setprecision;
using std::string;
using std::tuple;

!Line: 44 - error: no header providing "std::ostream" is directly included [misc-include-cleaner,-warnings-as-errors]

using std::rethrow_exception;
using std::runtime_error;
using std::setprecision;
using std::string;
using std::tuple;

!Line: 45 - error: no header providing "std::rethrow_exception" is directly included [misc-include-cleaner,-warnings-as-errors]

using std::rethrow_exception;
using std::runtime_error;
using std::setprecision;
using std::string;
using std::tuple;

!Line: 45 - error: using decl 'rethrow_exception' is unused [misc-unused-using-decls,-warnings-as-errors]

!Line: 45 - note: remove the using

using std::runtime_error;
using std::setprecision;
using std::string;
using std::tuple;
using TCPPNum = TestCPP::TestCPPCommon::Nums;

!Line: 46 - error: no header providing "std::runtime_error" is directly included [misc-include-cleaner,-warnings-as-errors]

using std::runtime_error;
using std::setprecision;
using std::string;
using std::tuple;
using TCPPNum = TestCPP::TestCPPCommon::Nums;

!Line: 46 - error: using decl 'runtime_error' is unused [misc-unused-using-decls,-warnings-as-errors]

!Line: 46 - note: remove the using

using std::string;
using std::tuple;
using TCPPNum = TestCPP::TestCPPCommon::Nums;
using TCPPStr = TestCPP::TestCPPCommon::Strings;

!Line: 48 - error: no header providing "std::string" is directly included [misc-include-cleaner,-warnings-as-errors]

using std::tuple;
using TCPPNum = TestCPP::TestCPPCommon::Nums;
using TCPPStr = TestCPP::TestCPPCommon::Strings;
namespace TestCPP {

!Line: 49 - error: no header providing "std::tuple" is directly included [misc-include-cleaner,-warnings-as-errors]

void TestSuite::setSuiteName (TestObjName&& testSuiteName) {
this->suiteName = std::move(testSuiteName);
}
unsigned TestSuite::getLastRunFailCount () {
return this->lastRunFailCount;

!Line: 69 - error: no header providing "TestCPP::TestObjName" is directly included [misc-include-cleaner,-warnings-as-errors]

this->suiteName = std::move(testSuiteName);
}
unsigned TestSuite::getLastRunFailCount () {
return this->lastRunFailCount;
}

!Line: 70 - error: no header providing "std::move" is directly included [misc-include-cleaner,-warnings-as-errors]

unsigned TestSuite::getLastRunFailCount () {
return this->lastRunFailCount;
}
unsigned TestSuite::getLastRunSuccessCount() {
return this->lastRunSuccessCount;

!Line: 73 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

unsigned TestSuite::getLastRunFailCount () {
return this->lastRunFailCount;
}
unsigned TestSuite::getLastRunSuccessCount() {
return this->lastRunSuccessCount;

!Line: 73 - error: method 'getLastRunFailCount' can be made const [readability-make-member-function-const,-warnings-as-errors]

unsigned TestSuite::getLastRunSuccessCount() {
return this->lastRunSuccessCount;
}
void TestSuite::run () {
if (this->tests.size() == 0) {

!Line: 77 - error: use a trailing return type for this function [modernize-use-trailing-return-type,-warnings-as-errors]

unsigned TestSuite::getLastRunSuccessCount() {
return this->lastRunSuccessCount;
}
void TestSuite::run () {
if (this->tests.size() == 0) {

!Line: 77 - error: method 'getLastRunSuccessCount' can be made const [readability-make-member-function-const,-warnings-as-errors]

if (this->tests.size() == 0) {
clog << TCPPStr::NTR << endl;
return;
}
if (!this->firstRun) {

!Line: 82 - error: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty,-warnings-as-errors]

clog << TCPPStr::NTR << endl;
return;
}
if (!this->firstRun) {
this->lastRunSucceeded = true;

!Line: 83 - error: do not use 'endl' with streams; use '\n' instead [performance-avoid-endl,-warnings-as-errors]

clog << endl
<< TCPPStr::START_RUN << TCPPStr::SUITE
<< TCPPStr::APOS << this->suiteName << TCPPStr::APOS
<< endl
<< endl;

!Line: 97 - error: do not use 'endl' with streams; use '\n' instead [performance-avoid-endl,-warnings-as-errors]

<< endl
<< endl;
for (TestCase test : this->tests) {
bool testPassed = false;
try {

!Line: 100 - error: do not use 'endl' with streams; use '\n' instead [performance-avoid-endl,-warnings-as-errors]

<< endl;
for (TestCase test : this->tests) {
bool testPassed = false;
try {
testPassed = test.go();

!Line: 101 - error: do not use 'endl' with streams; use '\n' instead [performance-avoid-endl,-warnings-as-errors]

<< endl;
}
catch (...) {
cerr << TCPPStr::UNK_EXC
<< endl;
}

!Line: 110 - error: do not use 'endl' with streams; use '\n' instead [performance-avoid-endl,-warnings-as-errors]

<< endl;
}
if (!testPassed) {
this->lastRunFailCount++;

!Line: 114 - error: do not use 'endl' with streams; use '\n' instead [performance-avoid-endl,-warnings-as-errors]

clog << endl;
if (this->testSuitePassedMessage &&
this->lastRunFailCount == 0) {
clog << TCPPStr::ALL << TCPPStr::APOS << this->suiteName
<< TCPPStr::APOS << TCPPStr::SUITE_TESTS_PASSED

!Line: 131 - error: do not use 'endl' with streams; use '\n' instead [performance-avoid-endl,-warnings-as-errors]

<< endl;
}
double suiteRuntimeElapsed = static_cast<double>(
this->totalRuntime)/TCPPNum::NANOS_IN_SEC;

!Line: 137 - error: do not use 'endl' with streams; use '\n' instead [performance-avoid-endl,-warnings-as-errors]

double suiteRuntimeElapsed = static_cast<double>(
this->totalRuntime)/TCPPNum::NANOS_IN_SEC;
clog << fixed;
clog << setprecision(0);
clog << TCPPStr::FINISHED_SUITE << TCPPStr::APOS

!Line: 140 - error: variable 'suiteRuntimeElapsed' of type 'double' can be declared 'const' [misc-const-correctness,-warnings-as-errors]

<< endl;
}
/**
* @brief Add a test to this test suite.
*

!Line: 151 - error: do not use 'endl' with streams; use '\n' instead [performance-avoid-endl,-warnings-as-errors]

void TestSuite::addTest (TestCase&& test) {
this->tests.emplace_back(test);
}
/**
* @brief Add a test to this test suite.

!Line: 160 - error: rvalue reference parameter 'test' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved,-warnings-as-errors]

test)
{
this->tests.emplace_back(
std::get<0>(test),
std::get<1>(test),
this->testSuitePassedMessage

!Line: 173 - error: rvalue reference parameter 'test' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved,-warnings-as-errors]

TestCase (
TestObjName&& testName,
function<void()> test,
bool testPassedMessage = true,
bool captureOut = false,
bool captureLog = false,

!Line: 131 - error: function 'TestCPP::TestCase::TestCase' has a definition with different parameter names [readability-inconsistent-declaration-parameter-name,-warnings-as-errors]

!Line: 114 - note: the definition seen here
!Line: 131 - note: differing parameters are named here: ('testPassedMessage'), in definition: ('msg')

void logTestFailure (string failureMessage);
/**
* @brief Internal test run controller.
*/
void runTest ();
/**

!Line: 299 - error: function 'TestCPP::TestCase::logTestFailure' has a definition with different parameter names [readability-inconsistent-declaration-parameter-name,-warnings-as-errors]

!Line: 304 - note: the definition seen here
!Line: 299 - note: differing parameters are named here: ('failureMessage'), in definition: ('reason')

static nanoseconds duration (F func, Args&&... args)
{
auto start = system_clock::now();
func(forward<Args>(args)...);
return duration_cast<nanoseconds>(
system_clock::now() - start

!Line: 345 - error: the parameter 'func' is copied for each invocation but only used as a const reference; consider making it a const reference [performance-unnecessary-value-param,-warnings-as-errors]

template <class... Ts> no_destroy(Ts&&... ts) { new (data) T(std::forward<Ts>(ts)...); }
T& get() { return *reinterpret_cast<T*>(data); }
};
/**
* @brief Log a message that will only be output when debug

!Line: 109 - error: do not implicitly decay an array into a pointer; consider using gsl::array_view or an explicit cast instead [cppcoreguidelines-pro-bounds-array-to-pointer-decay,hicpp-no-array-decay,-warnings-as-errors]


!Maximum character count per GitHub comment has been reached! Not all warnings/errors has been parsed!

@codecov
Copy link

codecov bot commented Feb 28, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 84.86%. Comparing base (2540ca0) to head (819b877).
Report is 5 commits behind head on main.

✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #96      +/-   ##
==========================================
+ Coverage   84.69%   84.86%   +0.17%     
==========================================
  Files          10       10              
  Lines         477      489      +12     
  Branches       60       61       +1     
==========================================
+ Hits          404      415      +11     
  Misses         66       66              
- Partials        7        8       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

eljonny added 3 commits March 4, 2025 18:30
Whitespace/newline formatting in function header.

Adjust the name of the TestSuite ctor parameter so it doesn't shadow
 the member field.

Create a common initialization function since the majority of the
 initialization logic is the same in both cases and I added a few more
 initialization statements; it is more correct to have them initialized
 by the constructor than the run() function for the initial suite run.
I added a firstRun bool to indicate when the run() re-initialization
 logic should be run since the suites can be rerun if desired; for
 example if the client application is running tests interactively and
 the end-user wants to run a suite 4 or 5 times to validate that tests
 are not flakey, or if an automated application wants to do something
 along those lines, or with other use cases that I have not conceived.
The common initialization function is inlined and removed by the
 compiler, which is a warning in MSVC; it is suppressed with a #pragma
 since it is an internal function, and it's ok if it is removed because
 of inlining with no further references.
Maybe using std::forward helped the compiler to decide to inline? Or
 maybe it would have done it anyways.

Removed using std::forward since it is now fully-qualified.
This is a multi-platform project and I needed to use an MSVC pragma to
 suppress (appropriately) a specific instance of a warning with the the
 MSVC pragma used to do that.
Introduce tests for TestSuite that run each suite twice and ensure that
 the failed and success counts are correct; it would help to implement
 runs that also include failed tests to check that as well.
Also introduce tests dedicated to the TestSuite::run() function.

The files were getting pretty big so I split the TestSuite tests up
 into categories centered on functionality, including:
 - Construction
 - Running
 - Test Passed Message
These splits are their own CMake CTest executables and all build
 modifications have been completed that support these splits.

Also renamed the assertions tests headers and sources files such that
 they align properly with the naming of the rest of the test code TUs
 and headers.

To do this properly, I had to add a function to get the number of tests
 that ran successfully from the TestSuite.

Resolves #97 and #98.
@eljonny eljonny marked this pull request as ready for review March 5, 2025 05:28
@eljonny eljonny merged commit 5dfd711 into main Mar 5, 2025
41 of 42 checks passed
eljonny added a commit that referenced this pull request Mar 5, 2025
@eljonny eljonny deleted the fix-cppcheck-warning-uninitmembervar branch March 5, 2025 05:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

static-analysis An issue related to a static analysis result test-suite Relating to TestCPP TestSuite

Projects

None yet

2 participants