StormByte C++ Library 1.2.0
StormByte is a comprehensive, cross-platform C++ library aimed at easing system programming, configuration management, logging, and database handling tasks. This library provides a unified API that abstracts away the complexities and inconsistencies of different platforms (Windows, Linux).
Loading...
Searching...
No Matches
test_handlers.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2024-2026 David C. Manuelda (StormBytePP)
3 *
4 * This file is part of StormByte.
5 *
6 * StormByte is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License version 3
8 * or later, as published by the Free Software Foundation.
9 *
10 * StormByte is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with StormByte. If not, see
17 * <https://www.gnu.org/licenses/lgpl-3.0.html>.
18 */
19
20#pragma once
21
22#include <exception>
23#include <filesystem>
24#include <iostream>
25#include <ostream>
26#include <string_view>
27
29 template<typename T>
30 void PrintValue(std::ostream& stream, const T& value) {
31 if constexpr (requires { stream << value; }) {
32 stream << value;
33 } else {
34 stream << "<unprintable>";
35 }
36 }
37}
38
45#define RETURN_TEST(fn_name, fn_result) do { \
46 const int stormbyte_test_result = (fn_result); \
47 if (stormbyte_test_result != 0) { \
48 std::cerr << "Test " << fn_name << " FAILED!" << std::endl; \
49 } \
50 return stormbyte_test_result; \
51} while (false)
52
57#define CurrentFileDirectory std::filesystem::path(__FILE__).parent_path()
58
66#define ASSERT_EQUAL(fn_name, expected, actual) do { \
67 const auto& stormbyte_expected = (expected); \
68 const auto& stormbyte_actual = (actual); \
69 if (!(stormbyte_expected == stormbyte_actual)) { \
70 std::cerr << fn_name << ": Assertion failed at " << __FILE__ << ":" << __LINE__ << ": expected \""; \
71 ::StormByte::Test::Detail::PrintValue(std::cerr, stormbyte_expected); \
72 std::cerr << "\", got \""; \
73 ::StormByte::Test::Detail::PrintValue(std::cerr, stormbyte_actual); \
74 std::cerr << "\"" << std::endl; \
75 return 1; \
76 } \
77} while (false)
78
86#define ASSERT_NOT_EQUAL(fn_name, expected, actual) do { \
87 const auto& stormbyte_expected = (expected); \
88 const auto& stormbyte_actual = (actual); \
89 if (stormbyte_expected == stormbyte_actual) { \
90 std::cerr << fn_name << ": Assertion failed at " << __FILE__ << ":" << __LINE__ << ": values should differ; both were \""; \
91 ::StormByte::Test::Detail::PrintValue(std::cerr, stormbyte_actual); \
92 std::cerr << "\"" << std::endl; \
93 return 1; \
94 } \
95} while (false)
96
103#define ASSERT_FALSE(fn_name, condition) do { \
104 if ((condition)) { \
105 std::cerr << fn_name << ": Assertion failed at " << __FILE__ << ":" << __LINE__ << ": condition is true, expected false" << std::endl; \
106 return 1; \
107 } \
108} while (false)
109
116#define ASSERT_TRUE(fn_name, condition) do { \
117 if (!(condition)) { \
118 std::cerr << fn_name << ": Assertion failed at " << __FILE__ << ":" << __LINE__ << ": condition is false, expected true" << std::endl; \
119 return 1; \
120 } \
121} while (false)
122
127#define ASSERT_THROWS(fn_name, expression, exception_type) do { \
128 bool stormbyte_threw = false; \
129 try { \
130 (void)(expression); \
131 } catch (const exception_type&) { \
132 stormbyte_threw = true; \
133 } catch (...) { \
134 } \
135 if (!stormbyte_threw) { \
136 std::cerr << fn_name << ": Assertion failed at " << __FILE__ << ":" << __LINE__ << ": expected " << #exception_type << " to be thrown" << std::endl; \
137 return 1; \
138 } \
139} while (false)
140
145#define ASSERT_NO_THROW(fn_name, expression) do { \
146 try { \
147 (void)(expression); \
148 } catch (const std::exception& stormbyte_exception) { \
149 std::cerr << fn_name << ": Assertion failed at " << __FILE__ << ":" << __LINE__ << ": unexpected exception: " << stormbyte_exception.what() << std::endl; \
150 return 1; \
151 } catch (...) { \
152 std::cerr << fn_name << ": Assertion failed at " << __FILE__ << ":" << __LINE__ << ": unexpected non-standard exception" << std::endl; \
153 return 1; \
154 } \
155} while (false)
156
161#define ASSERT_NEAR(fn_name, expected, actual, tolerance) do { \
162 const auto stormbyte_expected = (expected); \
163 const auto stormbyte_actual = (actual); \
164 const auto stormbyte_tolerance = (tolerance); \
165 const auto stormbyte_difference = stormbyte_expected > stormbyte_actual ? \
166 stormbyte_expected - stormbyte_actual : stormbyte_actual - stormbyte_expected; \
167 if (stormbyte_difference > stormbyte_tolerance) { \
168 std::cerr << fn_name << ": Assertion failed at " << __FILE__ << ":" << __LINE__ << ": values differ beyond tolerance" << std::endl; \
169 return 1; \
170 } \
171} while (false)
172
177#define ASSERT_CONTAINS(fn_name, haystack, needle) do { \
178 const auto& stormbyte_haystack = (haystack); \
179 const auto& stormbyte_needle = (needle); \
180 if (stormbyte_haystack.find(stormbyte_needle) == std::string_view::npos) { \
181 std::cerr << fn_name << ": Assertion failed at " << __FILE__ << ":" << __LINE__ << ": expected text to contain \"" << stormbyte_needle << "\"" << std::endl; \
182 return 1; \
183 } \
184} while (false)
185
190#define ASSERT_NOT_NULL(fn_name, pointer) do { \
191 if ((pointer) == nullptr) { \
192 std::cerr << fn_name << ": Assertion failed at " << __FILE__ << ":" << __LINE__ << ": pointer is null" << std::endl; \
193 return 1; \
194 } \
195} while (false)
Definition test_handlers.h:28
void PrintValue(std::ostream &stream, const T &value)
Definition test_handlers.h:30