Skip to content

Instantly share code, notes, and snippets.

@aabiji
Last active October 20, 2023 16:21
Show Gist options
  • Save aabiji/a6f69970fff7389af41984e2672d4b8e to your computer and use it in GitHub Desktop.
Save aabiji/a6f69970fff7389af41984e2672d4b8e to your computer and use it in GitHub Desktop.
Single header, C++ testing library.
/* 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