Renames tinytest files again.

This commit is contained in:
2023-04-26 00:08:30 -07:00
parent e07055e3de
commit 738cd58577
3 changed files with 228 additions and 216 deletions

7
BUILD
View File

@@ -2,6 +2,9 @@ load("@rules_cc//cc:defs.bzl", "cc_library")
cc_library( cc_library(
name = "tinytest", name = "tinytest",
srcs = ["test.cpp"], srcs = ["tinytest.cpp"],
hdrs = ["test.h"], hdrs = ["tinytest.h"],
visibility = ["//visibility:public"],
)
) )

View File

@@ -1,5 +1,5 @@
#define _XOPEN_SOURCE_EXTENDED #define _XOPEN_SOURCE_EXTENDED
#include "test.h" #include "tinytest.h"
#include <cstdint> #include <cstdint>
#include <cstdio> #include <cstdio>
@@ -7,7 +7,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
namespace Test { namespace TinyTest {
namespace { namespace {
using std::endl; using std::endl;
using std::string; using std::string;
@@ -143,146 +143,164 @@ using std::vector;
// Default to (string, _FnToTest, vector<tuple<"", _T1, [](a,b){return a==b;}, // Default to (string, _FnToTest, vector<tuple<"", _T1, [](a,b){return a==b;},
// make_tuple()) Also allow make_tuple(T2) if the last param is not a tuple. // make_tuple()) Also allow make_tuple(T2) if the last param is not a tuple.
TestResults::TestResults() TestResults::TestResults() : errors_(0), failed_(0), passed_(0), skipped_(0), total_(0) {}
: errors_(0), failed_(0), passed_(0), skipped_(0), total_(0) {}
TestResults::TestResults(const TestResults &other) TestResults::TestResults(const TestResults& other)
: error_messages_(other.error_messages_), errors_(other.errors_), : error_messages_(other.error_messages_),
failed_(other.failed_), failure_messages_(other.failure_messages_), errors_(other.errors_),
passed_(other.passed_), skip_messages_(other.skip_messages_), failed_(other.failed_),
skipped_(other.skipped_), total_(other.total_) {} failure_messages_(other.failure_messages_),
passed_(other.passed_),
skip_messages_(other.skip_messages_),
skipped_(other.skipped_),
total_(other.total_) {}
TestResults::TestResults(uint32_t errors, uint32_t failed, uint32_t passed, TestResults::TestResults(uint32_t errors,
uint32_t skipped, uint32_t total, uint32_t failed,
uint32_t passed,
uint32_t skipped,
uint32_t total,
vector<string> error_messages, vector<string> error_messages,
vector<string> failure_messages, vector<string> failure_messages,
vector<string> skip_messages) vector<string> skip_messages)
: error_messages_(error_messages), errors_(errors), failed_(failed), : error_messages_(error_messages),
failure_messages_(failure_messages), passed_(passed), errors_(errors),
skip_messages_(skip_messages), skipped_(skipped), total_(total) {} failed_(failed),
failure_messages_(failure_messages),
passed_(passed),
skip_messages_(skip_messages),
skipped_(skipped),
total_(total) {}
TestResults &TestResults::error() { TestResults& TestResults::error() {
errors_++; errors_++;
return *this; return *this;
} }
TestResults &TestResults::error(string message) { TestResults& TestResults::error(string message) {
errors_++; errors_++;
error_messages_.push_back(message); error_messages_.push_back(message);
return *this; return *this;
} }
TestResults &TestResults::fail() { TestResults& TestResults::fail() {
total_++; total_++;
failed_++; failed_++;
return *this; return *this;
} }
TestResults &TestResults::fail(const string &message) { TestResults& TestResults::fail(const string& message) {
total_++; total_++;
failed_++; failed_++;
failure_messages_.push_back(message); failure_messages_.push_back(message);
return *this; return *this;
} }
vector<string> TestResults::failure_messages() { return failure_messages_; } vector<string> TestResults::failure_messages() {
return failure_messages_;
}
TestResults &TestResults::pass() { TestResults& TestResults::pass() {
total_++; total_++;
passed_++; passed_++;
return *this; return *this;
} }
TestResults &TestResults::skip() { TestResults& TestResults::skip() {
total_++; total_++;
skipped_++; skipped_++;
return *this; return *this;
} }
TestResults &TestResults::skip(const string &message) { TestResults& TestResults::skip(const string& message) {
total_++; total_++;
skipped_++; skipped_++;
skip_messages_.push_back(message); skip_messages_.push_back(message);
return *this; return *this;
} }
vector<string> TestResults::skip_messages() { return skip_messages_; } vector<string> TestResults::skip_messages() {
return skip_messages_;
}
vector<string> TestResults::error_messages() { return error_messages_; } vector<string> TestResults::error_messages() {
return error_messages_;
}
uint32_t TestResults::errors() { return errors_; } uint32_t TestResults::errors() {
return errors_;
}
uint32_t TestResults::failed() { return failed_; } uint32_t TestResults::failed() {
return failed_;
}
uint32_t TestResults::passed() { return passed_; } uint32_t TestResults::passed() {
return passed_;
}
uint32_t TestResults::skipped() { return skipped_; } uint32_t TestResults::skipped() {
return skipped_;
}
uint32_t TestResults::total() { return total_; } uint32_t TestResults::total() {
return total_;
}
TestResults TestResults::operator+(const TestResults &other) const { TestResults TestResults::operator+(const TestResults& other) const {
vector<string> error_messages; vector<string> error_messages;
error_messages.insert(error_messages.end(), error_messages_.begin(), error_messages.insert(error_messages.end(), error_messages_.begin(), error_messages_.end());
error_messages_.end()); error_messages.insert(error_messages.end(), other.error_messages_.begin(), other.error_messages_.end());
error_messages.insert(error_messages.end(), other.error_messages_.begin(),
other.error_messages_.end());
vector<string> failure_messages; vector<string> failure_messages;
failure_messages.insert(failure_messages.end(), failure_messages_.begin(), failure_messages.insert(failure_messages.end(), failure_messages_.begin(), failure_messages_.end());
failure_messages_.end()); failure_messages.insert(failure_messages.end(), other.failure_messages_.begin(), other.failure_messages_.end());
failure_messages.insert(failure_messages.end(),
other.failure_messages_.begin(),
other.failure_messages_.end());
vector<string> skip_messages; vector<string> skip_messages;
skip_messages.insert(skip_messages.end(), skip_messages_.begin(), skip_messages.insert(skip_messages.end(), skip_messages_.begin(), skip_messages_.end());
skip_messages_.end()); skip_messages.insert(skip_messages.end(), other.skip_messages_.begin(), other.skip_messages_.end());
skip_messages.insert(skip_messages.end(), other.skip_messages_.begin(),
other.skip_messages_.end());
return TestResults(errors_ + other.errors_, failed_ + other.failed_, return TestResults(errors_ + other.errors_,
passed_ + other.passed_, skipped_ + other.skipped_, failed_ + other.failed_,
total_ + other.total_, error_messages, failure_messages, passed_ + other.passed_,
skipped_ + other.skipped_,
total_ + other.total_,
error_messages,
failure_messages,
skip_messages); skip_messages);
} }
TestResults &TestResults::operator+=(const TestResults &other) { TestResults& TestResults::operator+=(const TestResults& other) {
error_messages_.insert(error_messages_.end(), other.error_messages_.begin(), error_messages_.insert(error_messages_.end(), other.error_messages_.begin(), other.error_messages_.end());
other.error_messages_.end());
errors_ += other.errors_; errors_ += other.errors_;
failed_ += other.failed_; failed_ += other.failed_;
failure_messages_.insert(failure_messages_.end(), failure_messages_.insert(failure_messages_.end(), other.failure_messages_.begin(), other.failure_messages_.end());
other.failure_messages_.begin(),
other.failure_messages_.end());
passed_ += other.passed_; passed_ += other.passed_;
skip_messages_.insert(skip_messages_.end(), other.skip_messages_.begin(), skip_messages_.insert(skip_messages_.end(), other.skip_messages_.begin(), other.skip_messages_.end());
other.skip_messages_.end());
skipped_ += other.skipped_; skipped_ += other.skipped_;
total_ += other.total_; total_ += other.total_;
return *this; return *this;
} }
void PrintResults(std::ostream &os, TestResults results) { void PrintResults(std::ostream& os, TestResults results) {
auto skip_messages = results.skip_messages(); auto skip_messages = results.skip_messages();
if (skip_messages.size() > 0) { if (skip_messages.size() > 0) {
os << "Skipped:" << endl; os << "Skipped:" << endl;
for_each(skip_messages.begin(), skip_messages.end(), for_each(skip_messages.begin(), skip_messages.end(), [&os](const string& message) {
[&os](const string &message) {
os << "🚧Skipped: " << message << endl; os << "🚧Skipped: " << message << endl;
}); });
} }
auto failure_messages = results.failure_messages(); auto failure_messages = results.failure_messages();
if (failure_messages.size() > 0) { if (failure_messages.size() > 0) {
os << "Failures:" << endl; os << "Failures:" << endl;
for_each(failure_messages.begin(), failure_messages.end(), for_each(failure_messages.begin(), failure_messages.end(), [&os](const string& message) {
[&os](const string &message) {
os << "❌FAILED: " << message << endl; os << "❌FAILED: " << message << endl;
}); });
} }
auto error_messages = results.error_messages(); auto error_messages = results.error_messages();
if (error_messages.size() > 0) { if (error_messages.size() > 0) {
os << "Errors:" << endl; os << "Errors:" << endl;
for_each( for_each(error_messages.begin(), error_messages.end(), [&os](const string& message) {
error_messages.begin(), error_messages.end(), os << "🔥ERROR: " << message << endl;
[&os](const string &message) { os << "🔥ERROR: " << message << endl; }); });
} }
os << "Total tests: " << results.total() << endl; os << "Total tests: " << results.total() << endl;
os << "Passed: " << results.passed() << "" << endl; os << "Passed: " << results.passed() << "" << endl;
@@ -294,4 +312,4 @@ void PrintResults(std::ostream &os, TestResults results) {
MaybeTestConfigureFunction DefaultTestConfigureFunction() { MaybeTestConfigureFunction DefaultTestConfigureFunction() {
return std::nullopt; return std::nullopt;
} }
} // End namespace Test } // namespace TinyTest

View File

@@ -52,14 +52,13 @@
// Tuple printer from: // Tuple printer from:
// https://stackoverflow.com/questions/6245735/pretty-print-stdtuple/31116392#58417285 // https://stackoverflow.com/questions/6245735/pretty-print-stdtuple/31116392#58417285
template <typename TChar, typename TTraits, typename... TArgs> template <typename TChar, typename TTraits, typename... TArgs>
auto &operator<<(std::basic_ostream<TChar, TTraits> &os, auto& operator<<(std::basic_ostream<TChar, TTraits>& os, std::tuple<TArgs...> const& t) {
std::tuple<TArgs...> const &t) { std::apply([&os](auto&&... args) { ((os << args << " "), ...); }, t);
std::apply([&os](auto &&...args) { ((os << args << " "), ...); }, t);
return os; return os;
} }
template <typename TChar, typename TTraits, typename TItem> template <typename TChar, typename TTraits, typename TItem>
auto &operator<<(std::basic_ostream<TChar, TTraits> &os, std::vector<TItem> v) { auto& operator<<(std::basic_ostream<TChar, TTraits>& os, std::vector<TItem> v) {
os << "[ "; os << "[ ";
for (auto it = v.begin(); it != v.end(); it++) { for (auto it = v.begin(); it != v.end(); it++) {
if (it != v.begin()) { if (it != v.begin()) {
@@ -72,40 +71,38 @@ auto &operator<<(std::basic_ostream<TChar, TTraits> &os, std::vector<TItem> v) {
} }
template <typename TChar, typename TTraits, typename TItem> template <typename TChar, typename TTraits, typename TItem>
auto &compare(std::basic_ostream<TChar, TTraits> &error_message, auto& compare(std::basic_ostream<TChar, TTraits>& error_message,
std::vector<TItem> expected, std::vector<TItem> actual) { std::vector<TItem> expected,
std::vector<TItem> actual) {
if (expected.size() != actual.size()) { if (expected.size() != actual.size()) {
error_message << "size mismatch expected: " << expected.size() error_message << "size mismatch expected: " << expected.size() << ", actual: " << actual.size();
<< ", actual: " << actual.size();
return error_message; return error_message;
} }
for (size_t index = 0; index < expected.size(); index++) { for (size_t index = 0; index < expected.size(); index++) {
if (expected[index] != actual[index]) { if (expected[index] != actual[index]) {
error_message << "vectors differ at index " << index << ", \"" error_message << "vectors differ at index " << index << ", \"" << expected[index] << "\" != \"" << actual[index]
<< expected[index] << "\" != \"" << actual[index] << "\", expected: \"" << expected << "\", actual: \"" << actual << "\"";
<< "\", expected: \"" << expected << "\", actual: \""
<< actual << "\"";
return error_message; return error_message;
} }
} }
return error_message; return error_message;
} }
namespace Test { namespace TinyTest {
using std::string; using std::string;
using std::tuple; using std::tuple;
using std::vector; using std::vector;
/// @brief /// @brief
class TestResults { class TestResults {
public: public:
/// @brief Creates an empty TestResults instance representing no tests run. /// @brief Creates an empty TestResults instance representing no tests run.
TestResults(); TestResults();
/// @brief Creates a new TestResults instance that is a copy of other. /// @brief Creates a new TestResults instance that is a copy of other.
/// @param other /// @param other
TestResults(const TestResults &other); TestResults(const TestResults& other);
/// @brief Creates a new TestResults instance with specific counts. /// @brief Creates a new TestResults instance with specific counts.
/// @param errors The number of errors while running the tests. /// @param errors The number of errors while running the tests.
@@ -117,45 +114,48 @@ public:
/// @param error_messages The list of error messages. /// @param error_messages The list of error messages.
/// @param failure_messages The list of failure messages. /// @param failure_messages The list of failure messages.
/// @param skip_messages The list of skip messages. /// @param skip_messages The list of skip messages.
TestResults(uint32_t errors, uint32_t failed, uint32_t passed, TestResults(uint32_t errors,
uint32_t skipped, uint32_t total, uint32_t failed,
uint32_t passed,
uint32_t skipped,
uint32_t total,
std::vector<std::string> error_messages, std::vector<std::string> error_messages,
std::vector<std::string> failure_messages, std::vector<std::string> failure_messages,
std::vector<std::string> skip_messages); std::vector<std::string> skip_messages);
/// @brief Adds an error. This increments errors. /// @brief Adds an error. This increments errors.
/// @return A reference to this instance. Used for chaining. /// @return A reference to this instance. Used for chaining.
TestResults &error(); TestResults& error();
/// @brief Adds an error with a message. This increments errors as well as /// @brief Adds an error with a message. This increments errors as well as
/// saving the error message. /// saving the error message.
/// @param message The error message. /// @param message The error message.
/// @return A reference to this instance. Used for chaining. /// @return A reference to this instance. Used for chaining.
TestResults &error(std::string message); TestResults& error(std::string message);
/// @brief Adds a failed test. This increments total and failed. /// @brief Adds a failed test. This increments total and failed.
/// @return A reference to this instance. Used for chaining. /// @return A reference to this instance. Used for chaining.
TestResults &fail(); TestResults& fail();
/// @brief Adds a failed test with a message. This increments total and failed /// @brief Adds a failed test with a message. This increments total and failed
/// as well as saving the failure message. /// as well as saving the failure message.
/// @param message The reason the test failed. /// @param message The reason the test failed.
/// @return A reference to this instance. Used for chaining. /// @return A reference to this instance. Used for chaining.
TestResults &fail(const std::string &message); TestResults& fail(const std::string& message);
/// @brief Adds a passed test. This increments total and passed. /// @brief Adds a passed test. This increments total and passed.
/// @return A reference to this instance. Used for chaining. /// @return A reference to this instance. Used for chaining.
TestResults &pass(); TestResults& pass();
/// @brief Adds a skipped test. This increments total and skipped. /// @brief Adds a skipped test. This increments total and skipped.
/// @return A reference to this instance. Used for chaining. /// @return A reference to this instance. Used for chaining.
TestResults &skip(); TestResults& skip();
/// @brief Adds a skipped test with a message. This increments total and /// @brief Adds a skipped test with a message. This increments total and
/// skipped as well as saving the skip message. /// skipped as well as saving the skip message.
/// @param message The reason the test was skipped. /// @param message The reason the test was skipped.
/// @return A reference to this instance. Used for chaining. /// @return A reference to this instance. Used for chaining.
TestResults &skip(const std::string &message); TestResults& skip(const std::string& message);
/// @brief Getter for the list of error messages. /// @brief Getter for the list of error messages.
/// @return /// @return
@@ -192,15 +192,15 @@ public:
/// @brief Returns the combination of this and another TestResults instance. /// @brief Returns the combination of this and another TestResults instance.
/// @param other The other TestResults instance to add to this one. /// @param other The other TestResults instance to add to this one.
/// @return The combination of the two TestResults instances. /// @return The combination of the two TestResults instances.
TestResults operator+(const TestResults &other) const; TestResults operator+(const TestResults& other) const;
/// @brief Adds another TestResults to this one and returns a reference to /// @brief Adds another TestResults to this one and returns a reference to
/// this instance. /// this instance.
/// @param other The other TestResults instance to add to this one. /// @param other The other TestResults instance to add to this one.
/// @return A reference to this instance. /// @return A reference to this instance.
TestResults &operator+=(const TestResults &other); TestResults& operator+=(const TestResults& other);
private: private:
std::vector<std::string> error_messages_; std::vector<std::string> error_messages_;
uint32_t errors_; uint32_t errors_;
uint32_t failed_; uint32_t failed_;
@@ -214,8 +214,7 @@ private:
/// @brief /// @brief
/// @tparam TResult /// @tparam TResult
template <typename TResult> template <typename TResult>
using TestCompareFunction = using TestCompareFunction = std::function<bool(const TResult& expected, const TResult& actual)>;
std::function<bool(const TResult &expected, const TResult &actual)>;
/// @brief /// @brief
/// @tparam TResult /// @tparam TResult
@@ -263,11 +262,13 @@ using TestTuple =
/// @tparam TFunctionToTest /// @tparam TFunctionToTest
/// @tparam ...TInputParams /// @tparam ...TInputParams
template <typename TResult, typename... TInputParams> template <typename TResult, typename... TInputParams>
using TestSuite = using TestSuite = std::tuple<std::string,
std::tuple<std::string, std::function<TResult(TInputParams...)>, std::function<TResult(TInputParams...)>,
std::vector<TestTuple<TResult, TInputParams...>>, std::vector<TestTuple<TResult, TInputParams...>>,
MaybeTestCompareFunction<TResult>, MaybeTestConfigureFunction, MaybeTestCompareFunction<TResult>,
MaybeTestConfigureFunction, bool>; MaybeTestConfigureFunction,
MaybeTestConfigureFunction,
bool>;
// This function is called to execute a test suite. You provide it with some // This function is called to execute a test suite. You provide it with some
// configuration info, optional utility callback functions, and test data (input // configuration info, optional utility callback functions, and test data (input
@@ -366,8 +367,7 @@ using TestSuite =
/// @param is_enabled If false none of these tests are run and they are all /// @param is_enabled If false none of these tests are run and they are all
/// reported as skipped. /// reported as skipped.
template <typename TResult, typename... TInputParams> template <typename TResult, typename... TInputParams>
TestResults TestResults execute_suite(std::string suite_label,
execute_suite(std::string suite_label,
std::function<TResult(TInputParams...)> function_to_test, std::function<TResult(TInputParams...)> function_to_test,
vector<TestTuple<TResult, TInputParams...>> tests, vector<TestTuple<TResult, TInputParams...>> tests,
MaybeTestCompareFunction<TResult> suite_compare = std::nullopt, MaybeTestCompareFunction<TResult> suite_compare = std::nullopt,
@@ -384,22 +384,19 @@ execute_suite(std::string suite_label,
} }
// Step 2: Execute Tests // Step 2: Execute Tests
for_each( for_each(tests.begin(),
tests.begin(), tests.end(), tests.end(),
[&suite_label, &function_to_test, &results, [&suite_label, &function_to_test, &results, &suite_compare](TestTuple<TResult, TInputParams...> test_data) {
&suite_compare](TestTuple<TResult, TInputParams...> test_data) {
// Step 2a: Extract our variables from the TestTuple. // Step 2a: Extract our variables from the TestTuple.
const std::string &test_name = std::get<0>(test_data); const std::string& test_name = std::get<0>(test_data);
const std::string qualified_test_name = suite_label + "::" + test_name; const std::string qualified_test_name = suite_label + "::" + test_name;
const TResult &expected_output = std::get<1>(test_data); const TResult& expected_output = std::get<1>(test_data);
std::tuple<TInputParams...> input_params = std::get<2>(test_data); std::tuple<TInputParams...> input_params = std::get<2>(test_data);
MaybeTestCompareFunction<TResult> maybe_compare_function = MaybeTestCompareFunction<TResult> maybe_compare_function = std::get<3>(test_data);
std::get<3>(test_data);
TestCompareFunction<TResult> compare_function = TestCompareFunction<TResult> compare_function =
maybe_compare_function.has_value() ? *maybe_compare_function maybe_compare_function.has_value() ? *maybe_compare_function
: suite_compare.has_value() : suite_compare.has_value() ? *suite_compare
? *suite_compare : [](const TResult& l, const TResult& r) { return l == r; };
: [](const TResult &l, const TResult &r) { return l == r; };
MaybeTestConfigureFunction before_each = std::get<4>(test_data); MaybeTestConfigureFunction before_each = std::get<4>(test_data);
MaybeTestConfigureFunction after_each = std::get<5>(test_data); MaybeTestConfigureFunction after_each = std::get<5>(test_data);
bool is_enabled = std::get<6>(test_data); bool is_enabled = std::get<6>(test_data);
@@ -420,18 +417,19 @@ execute_suite(std::string suite_label,
try { try {
// Step 2c: Execute the test method. // Step 2c: Execute the test method.
actual = std::apply(function_to_test, input_params); actual = std::apply(function_to_test, input_params);
} catch (const std::exception &ex) { } catch (const std::exception& ex) {
std::ostringstream os; std::ostringstream os;
os << "Caught exception \"" << ex.what() << "\""; os << "Caught exception \"" << ex.what() << "\"";
results.error(qualified_test_name + " " + os.str()); results.error(qualified_test_name + " " + os.str());
std::cout << " 🔥ERROR: " << os.str() << std::endl; std::cout << " 🔥ERROR: " << os.str() << std::endl;
} catch (const std::string &message) { } catch (const std::string& message) {
std::ostringstream os; std::ostringstream os;
os << "Caught string \"" << message << "\""; os << "Caught string \"" << message << "\"";
results.error(qualified_test_name + " " + os.str()); results.error(qualified_test_name + " " + os.str());
std::cout << " 🔥ERROR: " << os.str() << std::endl; std::cout << " 🔥ERROR: " << os.str() << std::endl;
} catch (...) { } catch (...) {
string message = "Caught something that is neither an std::exception " string message =
"Caught something that is neither an std::exception "
"nor an std::string."; "nor an std::string.";
results.error(qualified_test_name + " " + message); results.error(qualified_test_name + " " + message);
std::cout << " 🔥ERROR: " << message << std::endl; std::cout << " 🔥ERROR: " << message << std::endl;
@@ -443,8 +441,7 @@ execute_suite(std::string suite_label,
std::cout << " ✅PASSED" << std::endl; std::cout << " ✅PASSED" << std::endl;
} else { } else {
std::ostringstream os; std::ostringstream os;
os << "expected: \"" << expected_output << "\", actual: \"" << actual os << "expected: \"" << expected_output << "\", actual: \"" << actual << "\"";
<< "\"";
results.fail(qualified_test_name + " " + os.str()); results.fail(qualified_test_name + " " + os.str());
std::cout << " ❌FAILED: " << os.str() << std::endl; std::cout << " ❌FAILED: " << os.str() << std::endl;
} }
@@ -482,8 +479,7 @@ execute_suite(std::string suite_label,
/// @param is_enabled If false the test is reported as skipped. If true the test /// @param is_enabled If false the test is reported as skipped. If true the test
/// is run as normal. /// is run as normal.
template <typename TResult, typename... TInputParams> template <typename TResult, typename... TInputParams>
TestResults TestResults execute_suite(std::string suite_label,
execute_suite(std::string suite_label,
std::function<TResult(TInputParams...)> function_to_test, std::function<TResult(TInputParams...)> function_to_test,
std::initializer_list<TestTuple<TResult, TInputParams...>> tests, std::initializer_list<TestTuple<TResult, TInputParams...>> tests,
MaybeTestCompareFunction<TResult> suite_compare = std::nullopt, MaybeTestCompareFunction<TResult> suite_compare = std::nullopt,
@@ -491,8 +487,7 @@ execute_suite(std::string suite_label,
MaybeTestConfigureFunction after_all = std::nullopt, MaybeTestConfigureFunction after_all = std::nullopt,
bool is_enabled = true) { bool is_enabled = true) {
std::vector test_data = std::vector(tests); std::vector test_data = std::vector(tests);
return execute_suite(suite_label, function_to_test, tests, suite_compare, return execute_suite(suite_label, function_to_test, tests, suite_compare, before_all, after_all, is_enabled);
before_all, after_all, is_enabled);
} }
/// @brief /// @brief
@@ -516,15 +511,14 @@ execute_suite(std::string suite_label,
/// skipped for reporting purposes. /// skipped for reporting purposes.
/// @return A TestTuple suitable for use as a test run when calling test_fn. /// @return A TestTuple suitable for use as a test run when calling test_fn.
template <typename TResult, typename... TInputParams> template <typename TResult, typename... TInputParams>
TestTuple<TResult, TInputParams...> TestTuple<TResult, TInputParams...> make_test(const string& test_name,
make_test(const string &test_name, const TResult &expected, const TResult& expected,
tuple<TInputParams...> input_params, tuple<TInputParams...> input_params,
MaybeTestCompareFunction<TResult> test_compare_fn = std::nullopt, MaybeTestCompareFunction<TResult> test_compare_fn = std::nullopt,
MaybeTestConfigureFunction before_each = std::nullopt, MaybeTestConfigureFunction before_each = std::nullopt,
MaybeTestConfigureFunction after_each = std::nullopt, MaybeTestConfigureFunction after_each = std::nullopt,
bool is_enabled = true) { bool is_enabled = true) {
return make_tuple(test_name, expected, input_params, test_compare_fn, return make_tuple(test_name, expected, input_params, test_compare_fn, before_each, after_each, is_enabled);
before_each, after_each, is_enabled);
} }
/// @brief /// @brief
@@ -540,27 +534,26 @@ make_test(const string &test_name, const TResult &expected,
/// @param is_enabled /// @param is_enabled
/// @return /// @return
template <typename TResult, typename TFunctionToTest, typename... TInputParams> template <typename TResult, typename TFunctionToTest, typename... TInputParams>
TestSuite<TResult, TInputParams...> TestSuite<TResult, TInputParams...> make_test_suite(const string& suite_name,
make_test_suite(const string &suite_name, TFunctionToTest function_to_test, TFunctionToTest function_to_test,
vector<TestTuple<TResult, TInputParams...>> test_data, vector<TestTuple<TResult, TInputParams...>> test_data,
MaybeTestCompareFunction<TResult> compare = std::nullopt, MaybeTestCompareFunction<TResult> compare = std::nullopt,
MaybeTestConfigureFunction before_each = std::nullopt, MaybeTestConfigureFunction before_each = std::nullopt,
MaybeTestConfigureFunction after_each = std::nullopt, MaybeTestConfigureFunction after_each = std::nullopt,
bool is_enabled = true) { bool is_enabled = true) {
return make_tuple(suite_name, function_to_test, test_data, compare, return make_tuple(suite_name, function_to_test, test_data, compare, before_each, after_each, is_enabled);
before_each, after_each, is_enabled);
} }
template <typename TResult, typename TFunctionToTest, typename... TInputParams> template <typename TResult, typename TFunctionToTest, typename... TInputParams>
TestSuite<TResult, TInputParams...> make_test_suite( TestSuite<TResult, TInputParams...> make_test_suite(
const string &suite_name, TFunctionToTest function_to_test, const string& suite_name,
TFunctionToTest function_to_test,
std::initializer_list<TestTuple<TResult, TInputParams...>> test_data, std::initializer_list<TestTuple<TResult, TInputParams...>> test_data,
MaybeTestCompareFunction<TResult> compare = std::nullopt, MaybeTestCompareFunction<TResult> compare = std::nullopt,
MaybeTestConfigureFunction before_each = std::nullopt, MaybeTestConfigureFunction before_each = std::nullopt,
MaybeTestConfigureFunction after_each = std::nullopt, MaybeTestConfigureFunction after_each = std::nullopt,
bool is_enabled = true) { bool is_enabled = true) {
return make_tuple(suite_name, function_to_test, test_data, compare, return make_tuple(suite_name, function_to_test, test_data, compare, before_each, after_each, is_enabled);
before_each, after_each, is_enabled);
} }
/// @brief /// @brief
@@ -568,8 +561,7 @@ TestSuite<TResult, TInputParams...> make_test_suite(
/// @tparam TInputParams... The types of parameters sent to the test function. /// @tparam TInputParams... The types of parameters sent to the test function.
/// @param test_suite A tuple representing the test suite configuration. /// @param test_suite A tuple representing the test suite configuration.
template <typename TResult, typename... TInputParams> template <typename TResult, typename... TInputParams>
TestResults TestResults execute_suite(const TestSuite<TResult, TInputParams...>& test_suite) {
execute_suite(const TestSuite<TResult, TInputParams...> &test_suite) {
return execute_suite<TResult, TInputParams...>( return execute_suite<TResult, TInputParams...>(
std::get<0>(test_suite), std::get<1>(test_suite), std::get<2>(test_suite) std::get<0>(test_suite), std::get<1>(test_suite), std::get<2>(test_suite)
// TODO: make this work for the optional parts of the tuple too. // TODO: make this work for the optional parts of the tuple too.
@@ -582,8 +574,7 @@ execute_suite(const TestSuite<TResult, TInputParams...> &test_suite) {
/// @param second /// @param second
/// @return /// @return
template <typename... TInputParams> template <typename... TInputParams>
MaybeTestConfigureFunction coalesce(MaybeTestConfigureFunction first, MaybeTestConfigureFunction coalesce(MaybeTestConfigureFunction first, MaybeTestConfigureFunction second) {
MaybeTestConfigureFunction second) {
if (first.has_value()) { if (first.has_value()) {
if (second.has_value()) { if (second.has_value()) {
// This is the only place we actually need to combine them. // This is the only place we actually need to combine them.
@@ -602,8 +593,8 @@ MaybeTestConfigureFunction coalesce(MaybeTestConfigureFunction first,
/// @brief Writes a friendly version of results to the provided stream. /// @brief Writes a friendly version of results to the provided stream.
/// @param os The stream to write to. /// @param os The stream to write to.
/// @param results The TestResults to write. /// @param results The TestResults to write.
void PrintResults(std::ostream &os, TestResults results); void PrintResults(std::ostream& os, TestResults results);
} // End namespace Test } // End namespace TinyTest
// TODO: Add TShared(*)(string /*test_name*/, UUID /*test_run_id*/) // TODO: Add TShared(*)(string /*test_name*/, UUID /*test_run_id*/)
// allocate_shared_data to the test tuple to make some shared data that can be // allocate_shared_data to the test tuple to make some shared data that can be