Steppable 0.0.1
A CAS project written from scratch in C++
Loading...
Searching...
No Matches
testing.hpp
1/**************************************************************************************************
2 * Copyright (c) 2023-2025 NWSOFT *
3 * *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy *
5 * of this software and associated documentation files (the "Software"), to deal *
6 * in the Software without restriction, including without limitation the rights *
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell *
8 * copies of the Software, and to permit persons to whom the Software is *
9 * furnished to do so, subject to the following conditions: *
10 * *
11 * The above copyright notice and this permission notice shall be included in all *
12 * copies or substantial portions of the Software. *
13 * *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE *
20 * SOFTWARE. *
21 **************************************************************************************************/
22
30
31#pragma once
32
33#include "format.hpp"
34#include "types/concepts.hpp"
35
36#include <string>
37
38using namespace std::literals;
39
41// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
42#define TEST_START() \
43 /* NOLINTNEXTLINE(bugprone-exception-escape) */ \
44 int main() \
45 { \
46 using namespace steppable::__internals::stringUtils; \
47 using namespace steppable::__internals::utils; \
48 using namespace steppable::testing; \
49 using namespace steppable::output; \
50 Utf8CodePage use_utf8; \
51 int errors = 0;
52
54// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
55#define SECTION(...) \
56 { \
57 const std::string& nameSection = #__VA_ARGS__; \
58 std::cout << colors::brightBlue << std::setw(80) << std::setfill('-') << reset << '\n'; \
59 std::cout << colors::brightBlue << "[Testing: " << nameSection << ']' << reset << '\n'; \
60 auto start = std::chrono::high_resolution_clock::now(); \
61 auto _ = TestCase(nameSection);
62
64// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
65#define SECTION_END() \
66 auto end = std::chrono::high_resolution_clock::now(); \
67 auto duration = \
68 std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - start) \
69 .count(); \
70 _.summarize(); \
71 std::cout << colors::brightBlue << '[' << nameSection << " took " << duration << "(microseconds) to finish]" \
72 << reset << '\n'; \
73 std::cout << reset << '\n'; \
74 errors += _.errorCount; \
75 }
76
78// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
79#define TEST_END() \
80 if (errors) \
81 error("TEST_END"s, "Not all tests passed. There are {0} errors."s, { std::to_string(errors) }); \
82 else \
83 info("TEST_END"s, "All tests passed."s); \
84 std::cout << colors::brightBlue << std::setw(80) << std::setfill('=') << reset << '\n'; \
85 if (errors) \
86 return 1; \
87 }
88
93namespace steppable::testing
94{
100 {
101 private:
107 void _assertCondition(bool condition, const std::string& conditionName);
108
109 std::string testCaseName;
110
111 public:
112 int errorCount = 0; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes)
113
118 explicit TestCase(std::string testCaseName);
119
125 void assertIsEqual(const std::string& a, const std::string& b);
126
132 void assertIsNotEqual(const std::string& a, const std::string& b);
133
139 template<concepts::Numeric ValueT>
140 void assertIsEqual(ValueT a, ValueT b)
141 {
142 const std::string& conditionName =
143 __internals::format::format("Value {0} == {1}", { std::to_string(a), std::to_string(b) });
144 _assertCondition(a == b, conditionName);
145 }
146
152 template<concepts::Numeric ValueT>
153 void assertIsNearlyEqual(ValueT a, ValueT b)
154 {
155 const std::string& conditionName =
156 __internals::format::format("Value {0} ≈ {1}", { std::to_string(a), std::to_string(b) });
157 // Take less than 10% error as equal
158 _assertCondition(abs(a - b) / a < 0.1, conditionName);
159 }
160
166 template<concepts::Numeric ValueT>
167 void assertIsNotEqual(ValueT a, ValueT b)
168 {
169 const std::string& conditionName =
170 __internals::format::format("Value {0} != {1}", { std::to_string(a), std::to_string(b) });
171 _assertCondition(a != b, conditionName);
172 }
173
179 template<concepts::Presentable ValueT>
180 void assertIsEqual(ValueT a, ValueT b)
181 {
182 const std::string& conditionName =
183 __internals::format::format("Object {0} == {1}", { a.present(), b.present() });
184 _assertCondition(a == b, conditionName);
185 }
186
192 template<concepts::Presentable ValueT>
193 void assertIsNotEqual(ValueT a, ValueT b)
194 {
195 const std::string& conditionName =
196 __internals::format::format("Object {0} != {1}", { a.present(), b.present() });
197 _assertCondition(a != b, conditionName);
198 }
199
204 void assertTrue(bool value);
205
210 void assertFalse(bool value);
211
215 void summarize() const;
216 };
217} // namespace steppable::testing
void _assertCondition(bool condition, const std::string &conditionName)
Asserts a given condition and logs the condition name if it fails.
Definition testing.cpp:38
int errorCount
Definition testing.hpp:112
std::string testCaseName
Definition testing.hpp:109
TestCase(std::string testCaseName)
Constructs a new TestCase object with the given name.
Definition testing.cpp:36
void summarize() const
Prints a summary of the test case, including the number of errors encountered.
Definition testing.cpp:75
void assertFalse(bool value)
Asserts that a boolean value is false.
Definition testing.cpp:69
void assertTrue(bool value)
Asserts that a boolean value is true.
Definition testing.cpp:63
void assertIsEqual(const std::string &a, const std::string &b)
Asserts that two strings are equal.
Definition testing.cpp:51
void assertIsEqual(ValueT a, ValueT b)
Asserts that two numeric values are equal.
Definition testing.hpp:140
void assertIsNearlyEqual(ValueT a, ValueT b)
Asserts that two numeric values are nearly equal.
Definition testing.hpp:153
void assertIsNotEqual(const std::string &a, const std::string &b)
Asserts that two strings are not equal.
Definition testing.cpp:57
void assertIsNotEqual(ValueT a, ValueT b)
Asserts that two numeric values are not equal.
Definition testing.hpp:167
std::string abs(const std::string &_number, const int steps)
Calculates the absolute value of a string representation of a number.
Definition abs.cpp:56
std::string format(const std::string &format, const std::vector< std::string > &args)
Definition format.cpp:33
Includes testing utilities for Steppable.
Definition testing.cpp:35
Untitled