Last active
October 20, 2023 16:21
-
-
Save aabiji/a6f69970fff7389af41984e2672d4b8e to your computer and use it in GitHub Desktop.
Single header, C++ testing library.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Tinytest -- a tiny testing library under the MIT liscense. | |
* Should compile with std=c++17 | |
* Example usage: | |
``` | |
#include "tinytest.h" | |
int main() { | |
Tinytest::test("Test example", [](){ | |
const char *a = "hello"; | |
const char *b = "hello"; | |
Tinytest::assert_equal(a, b); | |
}); | |
Tinytest::test("Test example #1", [](){ | |
const char *a = "world"; | |
const char *b = "world"; | |
Tinytest::assert_equal(a, b); | |
}); | |
Tinytest::test("Test example #2", [](){ | |
const char *a = "col"; | |
const char *b = "cool"; | |
Tinytest::assert_equal(a, b); | |
}); | |
Tinytest::test_all(true); // Run all tests with logging enabled | |
} | |
``` | |
*/ | |
#ifndef TINYTEST_H_ | |
#define TINYTEST_H_ | |
#include <functional> | |
#include <iostream> | |
#include <cstdlib> | |
#include <string> | |
#include <vector> | |
namespace Tinytest { | |
// ANSI color codes | |
enum Colors { | |
RED_FG = 31, | |
GREEN_FG = 32, | |
YELLOW_FG = 33, | |
BLUE_FG = 34, | |
DEFAULT_FG = 39, | |
RED_BG = 41, | |
GREEN_BG = 42, | |
BLUE_BG = 44, | |
YELLOW_BG = 43, | |
DEFAULT_BG = 49, | |
}; | |
static void print_color(Colors c, std::string s) { | |
std::cout << "\033[" << c << "m"; | |
std::cout << s; | |
std::cout << "\033[" << DEFAULT_FG << "m"; | |
std::cout << "\033[" << DEFAULT_BG << "m"; | |
} | |
#define assert_equal(a, b) _assert_equal(a, b, __LINE__, __FILE__) | |
template <typename T> void _assert_equal(T a, T b, int line, const char *file) { | |
if (a == b) return; | |
std::string info = std::string(file) + ":" + std::to_string(line); | |
print_color(RED_FG, "FAIL"); | |
std::cout << " ("; | |
print_color(YELLOW_FG, info); | |
std::cout << ")\nFound '" << a << "' expecting '" << b << "'\n"; | |
std::exit(0); | |
return; | |
} | |
class Test { | |
public: | |
Test(std::string n, std::function<void()> f) : name(n), function(f) {} | |
std::string name; | |
std::function<void()> function; | |
}; | |
class Tests { | |
private: | |
Tests() {} | |
public: | |
Tests(const Tests& obj) = delete; | |
std::vector<Test> m_tests; | |
inline static Tests *m_instance = nullptr; | |
static Tests *get_instance() { | |
if (m_instance == nullptr) | |
m_instance = new Tests(); | |
return m_instance; | |
} | |
}; | |
static void test(std::string s, std::function<void()> f) { | |
Test t(s, f); | |
Tests *singleton = Tests::get_instance(); | |
singleton->m_tests.push_back(t); | |
} | |
static void test_all(bool should_log) { | |
Tests *singleton = Tests::get_instance(); | |
for (int i = 0; i < int(singleton->m_tests.size()); i++) { | |
if (should_log) { | |
print_color(YELLOW_FG, "Testing ... "); | |
std::cout << singleton->m_tests[i].name << " -- "; | |
} | |
singleton->m_tests[i].function(); | |
if (should_log) print_color(GREEN_FG, "PASS\n"); | |
} | |
print_color(GREEN_FG, "All tests passed!\n"); | |
} | |
} // namespace Tinytest | |
#endif // TINYTEST_H_ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment