C++ Utilities: tests/misctests.cpp Source File

C++ Utilities 5.32.1 Useful C++ classes and routines such as argument parser, IO and conversion utilities

Loading...
Searching...
No Matches
misctests.cpp
Go to the documentation of this file.
1#include "../misc/flagenumclass.h"
2#include "../misc/levenshtein.h"
3#include "../misc/multiarray.h"
4
5#ifdef CPP_UTILITIES_HAS_OPENSSL_CRYPTO
6#include "../misc/signingkeys.h"
7#include "../misc/verification.h"
8#endif
9
10#include "../conversion/stringbuilder.h"
11#include "../conversion/stringconversion.h"
12
13#include "../io/misc.h"
14
15#include "../tests/testutils.h"
16
17#include "resources/version.h"
18
19#include <cppunit/TestFixture.h>
20#include <cppunit/extensions/HelperMacros.h>
21
22#include <regex>
23
24using namespace std;
25using namespace CppUtilities;
26using namespace CppUtilities::Literals;
27using namespace CPPUNIT_NS;
28
29// test version check macro
30#if CPP_UTILITIES_VERSION_CHECK(5, 2, 1) > CPP_UTILITIES_VERSION_CHECK(6, 0, 0)
31#error "Check for major version doesn't work"
32#endif
33#if CPP_UTILITIES_VERSION_CHECK(5, 2, 2) > CPP_UTILITIES_VERSION_CHECK(5, 3, 0)
34#error "Check for minor version doesn't work"
35#endif
36#if CPP_UTILITIES_VERSION_CHECK(5, 2, 1) > CPP_UTILITIES_VERSION_CHECK(5, 2, 2)
37#error "Check for path version doesn't work"
38#endif
39#if CPP_UTILITIES_VERSION < CPP_UTILITIES_VERSION_CHECK(5, 0, 0)
40#error "Library version seems wrongly defined, should be already >= 5.0.0"
41#endif
42
46 class MiscTests : public TestFixture {
47 CPPUNIT_TEST_SUITE(MiscTests);
48 CPPUNIT_TEST(testMultiArray);
49 CPPUNIT_TEST(testLevenshtein);
50 CPPUNIT_TEST(testTestUtilities);
51#ifdef CPP_UTILITIES_HAS_OPENSSL_CRYPTO
52 CPPUNIT_TEST(testVerification);
53#endif
54 CPPUNIT_TEST_SUITE_END();
55
56public:
57 void setUp()
58 {
59 }
60 void tearDown()
61 {
62 }
63
64 void testMultiArray();
65 void testLevenshtein();
66 void testTestUtilities();
67#ifdef CPP_UTILITIES_HAS_OPENSSL_CRYPTO
68 void testVerification();
69#endif
70};
71
72CPPUNIT_TEST_SUITE_REGISTRATION(MiscTests);
73
74 void MiscTests::testMultiArray()
75{
76 static_assert(decltype(makeMultiArray<char>(3))::dimensionCount() == 1, "dimension count 1D");
77 static_assert(decltype(makeMultiArray<char>(3, 2))::dimensionCount() == 2, "dimension count 2D");
78 static_assert(decltype(makeMultiArray<char>(3, 2, 3))::dimensionCount() == 3, "dimension count 3D");
79
80 auto array1d(makeMultiArray<char>(3));
81 CPPUNIT_ASSERT_EQUAL(3_st, array1d.dimensionSize<0>());
82 CPPUNIT_ASSERT_EQUAL(3_st, array1d.totalSize());
83 array1d.at(0) = 'a';
84 array1d.at(1) = 'b';
85 array1d.at(2) = 'c';
86 CPPUNIT_ASSERT_EQUAL("abc"s, string(array1d.data(), 3));
87
88 auto array2d(makeMultiArray<char>(3, 2));
89 CPPUNIT_ASSERT_EQUAL(3_st, array2d.dimensionSize<0>());
90 CPPUNIT_ASSERT_EQUAL(2_st, array2d.dimensionSize<1>());
91 CPPUNIT_ASSERT_EQUAL(6_st, array2d.totalSize());
92 const char *const data(array2d.data());
93 array2d.at(0, 0) = 'a';
94 array2d.at(0, 1) = 'b';
95 array2d.at(1, 0) = 'c';
96 array2d.at(1, 1) = 'd';
97 array2d.at(2, 0) = 'e';
98 array2d.at(2, 1) = 'f';
99 CPPUNIT_ASSERT_EQUAL("abcdef"s, string(data, 6));
100
101 auto array3d(makeMultiArray<char>(3, 2, 3));
102 CPPUNIT_ASSERT_EQUAL(3_st, array3d.dimensionSize<0>());
103 CPPUNIT_ASSERT_EQUAL(2_st, array3d.dimensionSize<1>());
104 CPPUNIT_ASSERT_EQUAL(3_st, array3d.dimensionSize<2>());
105 CPPUNIT_ASSERT_EQUAL(18_st, array3d.totalSize());
106 array3d.at(0, 0, 0) = 'a';
107 array3d.at(0, 0, 1) = 'b';
108 array3d.at(0, 0, 2) = 'c';
109 array3d.at(0, 1, 0) = 'd';
110 array3d.at(0, 1, 1) = 'e';
111 array3d.at(0, 1, 2) = 'f';
112 array3d.at(1, 0, 0) = 'g';
113 array3d.at(1, 0, 1) = 'h';
114 array3d.at(1, 0, 2) = 'i';
115 array3d.at(1, 1, 0) = 'j';
116 array3d.at(1, 1, 1) = 'k';
117 array3d.at(1, 1, 2) = 'l';
118 array3d.at(2, 0, 0) = 'm';
119 array3d.at(2, 0, 1) = 'n';
120 array3d.at(2, 0, 2) = 'o';
121 array3d.at(2, 1, 0) = 'p';
122 array3d.at(2, 1, 1) = 'q';
123 array3d.at(2, 1, 2) = 'r';
124 CPPUNIT_ASSERT_EQUAL("abcdefghijklmnopqr"s, string(array3d.data(), 18));
125
126 auto stackMultiArray(makeFixedSizeMultiArray<char, 9>(3, 3));
127 CPPUNIT_ASSERT_EQUAL(3_st, stackMultiArray.dimensionSize<0>());
128 CPPUNIT_ASSERT_EQUAL(3_st, stackMultiArray.dimensionSize<1>());
129 CPPUNIT_ASSERT_EQUAL(9_st, stackMultiArray.totalSize());
130 stackMultiArray.at(0, 0) = 'a';
131 stackMultiArray.at(0, 1) = 'b';
132 stackMultiArray.at(0, 2) = 'c';
133 stackMultiArray.at(1, 0) = 'd';
134 stackMultiArray.at(1, 1) = 'e';
135 stackMultiArray.at(1, 2) = 'f';
136 stackMultiArray.at(2, 0) = 'g';
137 stackMultiArray.at(2, 1) = 'h';
138 stackMultiArray.at(2, 2) = 'i';
139 CPPUNIT_ASSERT_EQUAL("abcdefghi"s, string(stackMultiArray.data(), 9));
140}
141
142 void MiscTests::testLevenshtein()
143{
144 CPPUNIT_ASSERT_EQUAL(1_st, computeDamerauLevenshteinDistance("ab", "abc"));
145 CPPUNIT_ASSERT_EQUAL(1_st, computeDamerauLevenshteinDistance("abc", "ab"));
146 CPPUNIT_ASSERT_EQUAL(2_st, computeDamerauLevenshteinDistance("xzaby", "xbay"));
147 CPPUNIT_ASSERT_EQUAL(0_st, computeDamerauLevenshteinDistance("", ""));
148 CPPUNIT_ASSERT_EQUAL(1_st, computeDamerauLevenshteinDistance("ab", "ba"));
149 CPPUNIT_ASSERT_EQUAL(1_st, computeDamerauLevenshteinDistance("xaby", "xbay"));
150 CPPUNIT_ASSERT_EQUAL(0_st, computeDamerauLevenshteinDistance("abc", "abc"));
151 CPPUNIT_ASSERT_EQUAL(1_st, computeDamerauLevenshteinDistance("ab", "abc"));
152 CPPUNIT_ASSERT_EQUAL(2_st, computeDamerauLevenshteinDistance("ca", "abc"));
153 CPPUNIT_ASSERT_EQUAL(4_st, computeDamerauLevenshteinDistance("", "abcd"));
154 CPPUNIT_ASSERT_EQUAL(4_st, computeDamerauLevenshteinDistance("abcd", ""));
155 CPPUNIT_ASSERT_EQUAL(3_st, computeDamerauLevenshteinDistance("abcd", "d"));
156 CPPUNIT_ASSERT_EQUAL(2_st, computeDamerauLevenshteinDistance("abcd", "bc"));
157 CPPUNIT_ASSERT_EQUAL(3_st, computeDamerauLevenshteinDistance("abcd", "a"));
158 CPPUNIT_ASSERT_EQUAL(2_st, computeDamerauLevenshteinDistance("adb", "abc"));
159 CPPUNIT_ASSERT_EQUAL(2_st, computeDamerauLevenshteinDistance("xxaxx", "xxäxx"));
160 CPPUNIT_ASSERT_EQUAL(1_st, computeDamerauLevenshteinDistance("xxöxx", "xxäxx"));
161 CPPUNIT_ASSERT_EQUAL(11_st, computeDamerauLevenshteinDistance("this is a long text", "this is too long for stack"));
162}
163
167 void MiscTests::testTestUtilities()
168{
169 const auto workingCopyPathForNestedTestFile = workingCopyPath("subdir/nested-testfile.txt");
170 CPPUNIT_ASSERT_EQUAL_MESSAGE("creation of subdirectories in working dir", "some file\n"s, readFile(workingCopyPathForNestedTestFile));
171
172 const auto workingCopyPathUnderDifferentNameForNestedTestFile = workingCopyPathAs("subdir/nested-testfile.txt", "subdir2/foo.txt");
173 const auto splittedPath = splitString<vector<string>>(workingCopyPathUnderDifferentNameForNestedTestFile, "/", EmptyPartsTreat::Omit);
174 CPPUNIT_ASSERT_GREATEREQUAL(2_st, splittedPath.size());
175 CPPUNIT_ASSERT_EQUAL_MESSAGE("different subdir", "subdir2"s, splittedPath[splittedPath.size() - 2]);
176 CPPUNIT_ASSERT_EQUAL_MESSAGE("different file name", "foo.txt"s, splittedPath[splittedPath.size() - 1]);
177 CPPUNIT_ASSERT_EQUAL_MESSAGE(
178 "creation of subdirectories in working dir", "some file\n"s, readFile(workingCopyPathUnderDifferentNameForNestedTestFile));
179
180 stringstream ss;
181 ss << asHexNumber(16);
182 CPPUNIT_ASSERT_EQUAL_MESSAGE("printing hex numbers", "0x10"s, ss.str());
183
184 TESTUTILS_ASSERT_LIKE("assert like works", ".*foo.*", " foo ");
185}
186
187#ifdef CPP_UTILITIES_HAS_OPENSSL_CRYPTO
188void MiscTests::testVerification()
189{
190 const auto key = std::string_view(
191 R"(-----BEGIN PUBLIC KEY-----
192MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAWJAn1E7ZE5Q6H69oaV5sqCIppJdg
1934bXDan9dJv6GOg70/t7q2CvwcwUXhV4FvCZxCHo25+rWYINfqKU2Utul8koAx8tK
19459ohfOzI63I+CC76GfX41uRGU0P5i6hS7o/hgBLiVXqT0FgS2BMfmnLMUvUjqnI2
195YQM7C55/5BM5Vrblkow=
196-----END PUBLIC KEY-----)");
197 const auto signature = std::string_view(
198 R"(-----BEGIN SIGNATURE-----
199MIGIAkIB+LB01DduBFMVs7Ea2McD7/kXpP0XktDNR7WpVgkOn4+/ilR8b8lpO9dd
200FGmxKj5UVr2GpcWX6I216PjaVL9tr5oCQgFMpvNjSgFQ/KFaE+0d+QCegr3V7Uz6
201sWB0iGdPa+oXbRish7HoNCU/k0lD3ffXaf8ueC78Zme9NFO18Ol+NWXJDA==
202-----END SIGNATURE-----)");
203
204 auto message = std::string("test message");
205 CPPUNIT_ASSERT_EQUAL_MESSAGE("valid message", std::string(), verifySignature(key, signature, message));
206
207 message[5] = '?';
208 CPPUNIT_ASSERT_EQUAL_MESSAGE("manipulate message", "incorrect signature"s, verifySignature(key, signature, message));
209 CPPUNIT_ASSERT_EQUAL_MESSAGE("manipulate message", "incorrect signature"s, verifySignature(key, signature, message));
210
211 CPPUNIT_ASSERT_EQUAL_MESSAGE(
212 "verifySignature can be called with array of signatures", "incorrect signature"s, verifySignature(SigningKeys::openssl, signature, message));
213 CPPUNIT_ASSERT_EQUAL_MESSAGE(
214 "verifySignature can be called with empty vector", "no keys provided"s, verifySignature(std::vector<std::string_view>(), signature, message));
215}
216#endif
217
218// test flagenumclass.h
219
220 namespace FlagEnumTests {
221 enum class TestFlags { None, Foo = 1, Bar = 2, Baz = 4, Biz = 8 };
222}
223
224 CPP_UTILITIES_MARK_FLAG_ENUM_CLASS(FlagEnumTests, FlagEnumTests::TestFlags);
225
226namespace FlagEnumTests {
227
228 constexpr bool testFlagEnumClass()
229{
230 // test const operations
231 const auto testFlags = TestFlags::Foo | TestFlags::Baz;
232 static_assert((testFlags & TestFlags::Foo) == TestFlags::Foo);
233 static_assert(testFlags && TestFlags::Foo);
234 static_assert(!(testFlags && TestFlags::Bar));
235 static_assert((testFlags & TestFlags::Bar) == TestFlags::None);
236 static_assert(testFlags && TestFlags::Baz);
237 static_assert((testFlags & TestFlags::Baz) == TestFlags::Baz);
238 static_assert(checkFlagEnum(testFlags, TestFlags::Foo | TestFlags::Baz));
239 static_assert(checkFlagEnum(testFlags, TestFlags::Foo));
240 static_assert(!checkFlagEnum(testFlags, TestFlags::Foo | TestFlags::Bar));
241
242 // test modifying
243 auto nonConstFlags = TestFlags::Foo | TestFlags::Biz;
244 modFlagEnum(nonConstFlags, TestFlags::Foo | TestFlags::Bar, false);
245 nonConstFlags += TestFlags::Bar;
246 modFlagEnum(nonConstFlags, TestFlags::Baz | TestFlags::Biz, true);
247 return nonConstFlags == (TestFlags::Bar | TestFlags::Baz | TestFlags::Biz);
248}
249static_assert(testFlagEnumClass());
250
251} // namespace FlagEnumTests
MiscTests
The MiscTests class tests misc functions and classes (mainly of files contained by the misc directory...
Definition misctests.cpp:46
MiscTests::testTestUtilities
void testTestUtilities()
Tests helper from TestUtilities namespace which aren't used in other tests anyways.
Definition misctests.cpp:167
MiscTests::setUp
void setUp()
Definition misctests.cpp:57
MiscTests::tearDown
void tearDown()
Definition misctests.cpp:60
MiscTests::testLevenshtein
void testLevenshtein()
Definition misctests.cpp:142
MiscTests::testMultiArray
void testMultiArray()
Definition misctests.cpp:74
flagenumclass.h
CPP_UTILITIES_MARK_FLAG_ENUM_CLASS
#define CPP_UTILITIES_MARK_FLAG_ENUM_CLASS(Namespace, EnumClassType)
Definition flagenumclass.h:18
levenshtein.h
misc.h
CPPUNIT_TEST_SUITE_REGISTRATION
CPPUNIT_TEST_SUITE_REGISTRATION(MiscTests)
multiarray.h
CppUtilities::Literals
Contains literals to ease asserting with CPPUNIT_ASSERT_EQUAL.
Definition testutils.h:366
CppUtilities::SigningKeys::openssl
constexpr auto openssl
Definition signingkeys.h:37
CppUtilities
Contains all utilities provided by the c++utilities library.
Definition argumentparser.h:18
CppUtilities::readFile
CPP_UTILITIES_EXPORT std::string readFile(const std::string &path, std::string::size_type maxSize=std::string::npos)
Reads all contents of the specified file in a single call.
Definition misc.cpp:17
CppUtilities::workingCopyPath
CPP_UTILITIES_EXPORT std::string workingCopyPath(const std::string &relativeTestFilePath, WorkingCopyMode mode=WorkingCopyMode::CreateCopy)
Convenience function to invoke TestApplication::workingCopyPath().
Definition testutils.h:179
CppUtilities::checkFlagEnum
constexpr bool checkFlagEnum(FlagEnumClass flagVariable, FlagEnumClass flagsToCheck)
Returns whether the specified flagVariable has set all flags specified via flagsToCheck to true.
Definition flagenumclass.h:104
CppUtilities::EmptyPartsTreat::Omit
@ Omit
Definition stringconversion.h:159
CppUtilities::makeFixedSizeMultiArray
auto makeFixedSizeMultiArray(DimensionSizes... dimensionSizes)
Constructs a new N-dimensional array using a fixed size array as underlying container....
Definition multiarray.h:177
CppUtilities::makeMultiArray
auto makeMultiArray(DimensionSizes... dimensionSizes)
Constructs a new N-dimensional array using an std::vector with std::allocator as underlying container...
Definition multiarray.h:169
CppUtilities::verifySignature
std::string verifySignature(std::string_view publicKeyPem, std::string_view signaturePem, std::string_view data)
Verifies data with the specified public key publicKeyPem and signature signaturePem.
Definition verification.h:107
CppUtilities::asHexNumber
AsHexNumber< T > asHexNumber(const T &value)
Wraps a value to be printed using the hex system in the error case when asserted with cppunit (or sim...
Definition testutils.h:258
CppUtilities::workingCopyPathAs
CPP_UTILITIES_EXPORT std::string workingCopyPathAs(const std::string &relativeTestFilePath, const std::string &relativeWorkingCopyPath, WorkingCopyMode mode=WorkingCopyMode::CreateCopy)
Convenience function to invoke TestApplication::workingCopyPathAs().
Definition testutils.h:188
CppUtilities::modFlagEnum
constexpr FlagEnumClass & modFlagEnum(FlagEnumClass &flagVariable, FlagEnumClass relevantFlags, bool value)
Sets the specified relevantFlags in the specified flagVariable to the specified value.
Definition flagenumclass.h:95
CppUtilities::computeDamerauLevenshteinDistance
CPP_UTILITIES_EXPORT std::size_t computeDamerauLevenshteinDistance(const char *str1, std::size_t size1, const char *str2, std::size_t size2)
CppUtilities::splitString
Container splitString(Detail::StringParamForContainer< Container > string, Detail::StringParamForContainer< Container > delimiter, EmptyPartsTreat emptyPartsRole=EmptyPartsTreat::Keep, int maxParts=-1)
Splits the given string at the specified delimiter.
Definition stringconversion.h:173
FlagEnumTests
Definition misctests.cpp:220
FlagEnumTests::TestFlags
TestFlags
Definition misctests.cpp:221
FlagEnumTests::TestFlags::Foo
@ Foo
Definition misctests.cpp:221
FlagEnumTests::TestFlags::None
@ None
Definition misctests.cpp:221
FlagEnumTests::TestFlags::Biz
@ Biz
Definition misctests.cpp:221
FlagEnumTests::TestFlags::Bar
@ Bar
Definition misctests.cpp:221
FlagEnumTests::TestFlags::Baz
@ Baz
Definition misctests.cpp:221
FlagEnumTests::testFlagEnumClass
constexpr bool testFlagEnumClass()
Definition misctests.cpp:228
std
STL namespace.
signingkeys.h
stringbuilder.h
stringconversion.h
testutils.h
TESTUTILS_ASSERT_LIKE
#define TESTUTILS_ASSERT_LIKE(message, expectedRegex, actualString)
Asserts whether the specified string matches the specified regex.
Definition testutils.h:336
verification.h