1 #include "../conversion/binaryconversion.h"
2 #include "../conversion/stringbuilder.h"
3 #include "../conversion/stringconversion.h"
4 #include "../tests/testutils.h"
8 #include <cppunit/TestFixture.h>
9 #include <cppunit/extensions/HelperMacros.h>
12 #include <initializer_list>
18 using namespace CPPUNIT_NS;
22 static_assert(
toNormalInt(383) == 255,
"toNormalInt()");
23 static_assert(
swapOrder(static_cast<std::uint16_t>(0xABCD)) == 0xCDAB,
"swapOrder(uint16)");
24 static_assert(
swapOrder(static_cast<std::uint32_t>(0xABCDEF12)) == 0x12EFCDAB,
"swapOrder(uint32)");
25 static_assert(
swapOrder(static_cast<std::uint64_t>(0xABCDEF1234567890)) == 0x9078563412EFCDAB,
"swapOrder(uint64)");
32 CPPUNIT_TEST(testConversionException);
33 CPPUNIT_TEST(testEndianness);
34 CPPUNIT_TEST(testBinaryConversions);
35 CPPUNIT_TEST(testSwapOrderFunctions);
36 CPPUNIT_TEST(testStringEncodingConversions);
37 CPPUNIT_TEST(testStringConversions);
38 CPPUNIT_TEST(testStringBuilder);
39 CPPUNIT_TEST_SUITE_END();
51 void testConversionException();
52 void testEndianness();
53 void testBinaryConversions();
54 void testSwapOrderFunctions();
55 void testStringEncodingConversions();
56 void testStringConversions();
57 void testStringBuilder();
60 template <
typename intType>
61 void testConversion(
const char *message,
function<
void(intType,
char *)> vice,
function<intType(
const char *)> verca, intType
min, intType
max);
64 random_device m_randomDevice;
65 mt19937 m_randomEngine;
72 , m_randomEngine(m_randomDevice())
89 } test = { 0x01020304 };
90 #if defined(CONVERSION_UTILITIES_BYTE_ORDER_BIG_ENDIAN)
92 CPPUNIT_ASSERT(CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN ==
true);
93 CPPUNIT_ASSERT(CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN ==
false);
95 CPPUNIT_ASSERT_MESSAGE(
"Byte order assumption (big-endian) is wrong", test.characters[0] == 0x01);
96 #elif defined(CONVERSION_UTILITIES_BYTE_ORDER_LITTLE_ENDIAN)
98 CPPUNIT_ASSERT(CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN ==
false);
99 CPPUNIT_ASSERT(CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN ==
true);
101 CPPUNIT_ASSERT_MESSAGE(
"Byte order assumption (little-endian) is wrong", test.characters[0] == 0x04);
103 CPPUNIT_FAIL(
"There is not valid byte order assumption");
107 template <
typename intType>
108 void ConversionTests::testConversion(
109 const char *message,
function<
void(intType,
char *)> vice,
function<intType(
const char *)> versa, intType
min, intType
max)
111 const intType random = uniform_int_distribution<intType>(
min,
max)(m_randomEngine);
113 msg << message <<
'(' << hex <<
'0' <<
'x' << random <<
')';
114 vice(random, m_buff);
115 CPPUNIT_ASSERT_MESSAGE(msg.str(), versa(m_buff) == random);
118 #define TEST_TYPE(endianness, function) decltype(endianness::function(m_buff))
120 #define TEST_CONVERSION(function, endianness) \
121 testConversion<TEST_TYPE(endianness, function)>("testing " #function, \
122 static_cast<void (*)(TEST_TYPE(endianness, function), char *)>(&endianness::getBytes), endianness::function, \
123 numeric_limits<TEST_TYPE(endianness, function)>::min(), numeric_limits<TEST_TYPE(endianness, function)>::max())
125 #define TEST_BE_CONVERSION(function) TEST_CONVERSION(function, BE)
127 #define TEST_LE_CONVERSION(function) TEST_CONVERSION(function, LE)
129 #define TEST_CUSTOM_CONVERSION(vice, versa, endianness, min, max) \
130 testConversion<TEST_TYPE(endianness, versa)>( \
131 "testing " #versa, static_cast<void (*)(TEST_TYPE(endianness, versa), char *)>(&endianness::vice), endianness::versa, min, max)
142 for (
auto b = 1; b < 100; ++b) {
165 CPPUNIT_ASSERT(
swapOrder(static_cast<std::uint16_t>(0x7825)) == 0x2578);
166 CPPUNIT_ASSERT(
swapOrder(static_cast<std::uint32_t>(0x12345678)) == 0x78563412);
167 CPPUNIT_ASSERT(
swapOrder(static_cast<std::uint64_t>(0x1122334455667788)) == 0x8877665544332211);
173 void assertEqual(
const char *message,
const std::uint8_t *expectedValues,
size_t expectedSize,
const StringData &actualValues)
176 CPPUNIT_ASSERT_EQUAL_MESSAGE(message, expectedSize, actualValues.second);
178 auto *end = expectedValues + expectedSize;
179 auto *
i = reinterpret_cast<std::uint8_t *>(actualValues.first.get());
180 for (; expectedValues != end; ++expectedValues, ++
i) {
185 #if CONVERSION_UTILITIES_IS_BYTE_ORDER_LITTLE_ENDIAN == true
186 #define LE_STR_FOR_ENDIANNESS(name) name##LE##String
187 #define BE_STR_FOR_ENDIANNESS(name) name##BE##String
188 #elif CONVERSION_UTILITIES_IS_BYTE_ORDER_BIG_ENDIAN == true
189 #define LE_STR_FOR_ENDIANNESS(name) name##BE##String
190 #define BE_STR_FOR_ENDIANNESS(name) name##LE##String
209 const std::uint8_t simpleString[] = {
'A',
'B',
'C',
'D' };
210 const std::uint16_t simpleUtf16LEString[] = { 0x0041, 0x0042, 0x0043, 0x0044 };
211 const std::uint16_t simpleUtf16BEString[] = { 0x4100, 0x4200, 0x4300, 0x4400 };
213 const std::uint8_t latin1String[] = {
'A',
'B', 0xD6,
'C',
'D' };
214 const std::uint8_t utf8String[] = {
'A',
'B', 0xC3, 0x96,
'C',
'D' };
215 const std::uint16_t utf16LEString[] = { 0x0041, 0x0042, 0x00D6, 0x0043, 0x0044 };
216 const std::uint16_t utf16BEString[] = { 0x4100, 0x4200, 0xD600, 0x4300, 0x4400 };
246 CPPUNIT_ASSERT_EQUAL(
"0"s, numberToString<unsigned int>(0));
247 CPPUNIT_ASSERT_EQUAL(
"0"s, numberToString<signed int>(0));
249 uniform_int_distribution<std::uint64_t> randomDistUnsigned(0);
250 const string stringMsg(
"string"), wideStringMsg(
"wide string"), bufferMsg(
"buffer");
251 for (std::uint8_t b = 1; b < 100; ++b) {
252 auto signedRandom = randomDistSigned(m_randomEngine);
253 auto unsignedRandom = randomDistUnsigned(m_randomEngine);
254 for (
const auto base : initializer_list<std::uint8_t>{ 2, 8, 10, 16 }) {
255 const auto asString = numberToString<std::uint64_t, string>(unsignedRandom, static_cast<string::value_type>(base));
256 const auto asWideString = numberToString<std::uint64_t, wstring>(unsignedRandom, base);
257 CPPUNIT_ASSERT_EQUAL_MESSAGE(stringMsg, unsignedRandom, stringToNumber<std::uint64_t>(asString, static_cast<string::value_type>(base)));
258 CPPUNIT_ASSERT_EQUAL_MESSAGE(wideStringMsg, unsignedRandom, stringToNumber<std::uint64_t>(asWideString, base));
259 CPPUNIT_ASSERT_EQUAL_MESSAGE(bufferMsg, unsignedRandom, bufferToNumber<std::uint64_t>(asString.data(), asString.size(), base));
261 for (
const auto base : initializer_list<std::uint8_t>{ 10 }) {
262 const auto asString = numberToString<std::int64_t, string>(signedRandom, static_cast<string::value_type>(base));
263 const auto asWideString = numberToString<std::int64_t, wstring>(signedRandom, base);
264 CPPUNIT_ASSERT_EQUAL_MESSAGE(stringMsg, signedRandom, stringToNumber<std::int64_t>(asString, static_cast<string::value_type>(base)));
265 CPPUNIT_ASSERT_EQUAL_MESSAGE(wideStringMsg, signedRandom, stringToNumber<std::int64_t>(asWideString, base));
266 CPPUNIT_ASSERT_EQUAL_MESSAGE(bufferMsg, signedRandom, bufferToNumber<std::int64_t>(asString.data(), asString.size(), base));
271 CPPUNIT_ASSERT_EQUAL(1, stringToNumber<std::int32_t>(
"01"));
272 CPPUNIT_ASSERT_EQUAL(1, stringToNumber<std::int32_t>(L
"01"s));
273 CPPUNIT_ASSERT_EQUAL(1, stringToNumber<std::int32_t>(u
"01"s));
274 CPPUNIT_ASSERT_EQUAL(-23, stringToNumber<std::int32_t>(
" - 023"s));
275 CPPUNIT_ASSERT_EQUAL(-23, bufferToNumber<std::int32_t>(
" - 023", 6));
276 CPPUNIT_ASSERT_EQUAL(1u, stringToNumber<std::uint32_t>(
"01"));
277 CPPUNIT_ASSERT_EQUAL(1u, stringToNumber<std::uint32_t>(L
"01"s));
278 CPPUNIT_ASSERT_EQUAL(1u, stringToNumber<std::uint32_t>(u
"01"s));
279 CPPUNIT_ASSERT_EQUAL(23u, stringToNumber<std::uint32_t>(
" 023"s));
280 CPPUNIT_ASSERT_EQUAL(23u, bufferToNumber<std::uint32_t>(
" 023", 5));
281 CPPUNIT_ASSERT_EQUAL(255u, stringToNumber<std::uint32_t>(
"fF", 16));
286 CPPUNIT_ASSERT_EQUAL(
"TEST"s, interpretIntegerAsString<std::uint32_t>(0x54455354));
289 vector<string> splitTestExpected({
"1",
"2,3" });
290 vector<string> splitTestActual = splitString<vector<string>>(
"1,2,3"s,
","s, EmptyPartsTreat::Keep, 2);
291 CPPUNIT_ASSERT_EQUAL(splitTestExpected, splitTestActual);
292 splitTestActual = splitStringSimple<vector<string>>(
"1,2,3"s,
","s, 2);
293 CPPUNIT_ASSERT_EQUAL(splitTestExpected, splitTestActual);
294 splitTestExpected = {
"1",
"2,3",
"4,,5" };
295 splitTestActual = splitString<vector<string>>(
"1,2,,3,4,,5"s,
","s, EmptyPartsTreat::Merge, 3);
296 CPPUNIT_ASSERT_EQUAL(splitTestExpected, splitTestActual);
297 string splitJoinTest =
joinStrings(
splitString<vector<string>>(
",a,,ab,ABC,s"s,
","s, EmptyPartsTreat::Keep),
" "s,
false,
"("s,
")"s);
298 CPPUNIT_ASSERT_EQUAL(
"() (a) () (ab) (ABC) (s)"s, splitJoinTest);
299 splitJoinTest =
joinStrings(
splitString<vector<string>>(
",a,,ab,ABC,s"s,
","s, EmptyPartsTreat::Keep),
" "s,
true,
"("s,
")"s);
300 CPPUNIT_ASSERT_EQUAL(
"(a) (ab) (ABC) (s)"s, splitJoinTest);
301 splitJoinTest =
joinStrings(
splitStringSimple<vector<string>>(
",a,,ab,ABC,s"s,
","s),
" "s,
true,
"("s,
")"s);
302 CPPUNIT_ASSERT_EQUAL(
"(a) (ab) (ABC) (s)"s, splitJoinTest);
303 splitJoinTest =
joinStrings(
splitString<vector<string>>(
",a,,ab,ABC,s"s,
","s, EmptyPartsTreat::Omit),
" "s,
false,
"("s,
")"s);
304 CPPUNIT_ASSERT_EQUAL(
"(a) (ab) (ABC) (s)"s, splitJoinTest);
305 splitJoinTest =
joinStrings(
splitString<vector<string>>(
",a,,ab,ABC,s"s,
","s, EmptyPartsTreat::Merge),
" "s,
false,
"("s,
")"s);
306 CPPUNIT_ASSERT_EQUAL(
"(a,ab) (ABC) (s)"s, splitJoinTest);
309 string findReplaceTest(
"findAndReplace()");
310 findAndReplace<string>(findReplaceTest,
"And",
"Or");
311 CPPUNIT_ASSERT_EQUAL(
"findOrReplace()"s, findReplaceTest);
314 CPPUNIT_ASSERT(!startsWith<string>(findReplaceTest,
"findAnd"));
315 CPPUNIT_ASSERT(startsWith<string>(findReplaceTest,
"findOr"));
316 CPPUNIT_ASSERT(!startsWith<string>(findReplaceTest,
"findAnd"s));
317 CPPUNIT_ASSERT(startsWith<string>(findReplaceTest,
"findOr"s));
320 CPPUNIT_ASSERT(containsSubstrings<string>(
"this string contains foo and bar", {
"foo",
"bar" }));
321 CPPUNIT_ASSERT(!containsSubstrings<string>(
"this string contains foo and bar", {
"bar",
"foo" }));
324 string truncateTest(
"foo bar ");
326 CPPUNIT_ASSERT_EQUAL(
"foo"s, truncateTest);
329 uniform_int_distribution<std::uint8_t> randomDistChar;
330 std::uint8_t originalBase64Data[4047];
331 for (std::uint8_t &c : originalBase64Data) {
332 c = randomDistChar(m_randomEngine);
334 auto encodedBase64Data =
encodeBase64(originalBase64Data,
sizeof(originalBase64Data));
335 auto decodedBase64Data =
decodeBase64(encodedBase64Data.data(), static_cast<std::uint32_t>(encodedBase64Data.size()));
336 CPPUNIT_ASSERT(decodedBase64Data.second ==
sizeof(originalBase64Data));
337 for (
unsigned int i = 0;
i <
sizeof(originalBase64Data); ++
i) {
338 CPPUNIT_ASSERT(decodedBase64Data.first[
i] == originalBase64Data[
i]);
341 encodedBase64Data =
encodeBase64(originalBase64Data,
sizeof(originalBase64Data) - 1);
342 CPPUNIT_ASSERT_EQUAL(
'=', encodedBase64Data.at(encodedBase64Data.size() - 1));
343 CPPUNIT_ASSERT_NO_THROW(
decodeBase64(encodedBase64Data.data(), static_cast<std::uint32_t>(encodedBase64Data.size())));
344 encodedBase64Data =
encodeBase64(originalBase64Data,
sizeof(originalBase64Data) - 2);
345 CPPUNIT_ASSERT_EQUAL(
'=', encodedBase64Data.at(encodedBase64Data.size() - 1));
346 CPPUNIT_ASSERT_EQUAL(
'=', encodedBase64Data.at(encodedBase64Data.size() - 2));
347 CPPUNIT_ASSERT_NO_THROW(
decodeBase64(encodedBase64Data.data(), static_cast<std::uint32_t>(encodedBase64Data.size())));
354 CPPUNIT_ASSERT_EQUAL(
"2.50 KiB (2560 byte)"s,
dataSizeToString((2048ull + 512ull),
true));
355 CPPUNIT_ASSERT_EQUAL(
"2.50 MiB"s,
dataSizeToString((2048ull + 512ull) * 1024ull));
356 CPPUNIT_ASSERT_EQUAL(
"2.50 GiB"s,
dataSizeToString((2048ull + 512ull) * 1024ull * 1024ull));
357 CPPUNIT_ASSERT_EQUAL(
"2.50 TiB"s,
dataSizeToString((2048ull + 512ull) * 1024ull * 1024ull * 1024ull));
360 CPPUNIT_ASSERT_EQUAL(
"128 Mbit/s"s,
bitrateToString(128.0 * 1e3,
false));
361 CPPUNIT_ASSERT_EQUAL(
"128 Gbit/s"s,
bitrateToString(128.0 * 1e6,
false));
376 const tuple<const char *, string, int, const char *> tuple(
"string1",
"string2", 1234,
"string3");
377 CPPUNIT_ASSERT_EQUAL(
string(
"string1string21234string3"),
tupleToString(tuple));
378 CPPUNIT_ASSERT_EQUAL(
string(
"foobarfoo2bar2"),
tupleToString(
string(
"foo") %
"bar" %
string(
"foo2") %
"bar2"));
379 CPPUNIT_ASSERT_EQUAL(
string(
"v2.3.0"),
argsToString(
"v2.", 3,
'.', 0));
382 CPPUNIT_ASSERT_EQUAL_MESSAGE(
383 "result can be passed to any function taking a std::string"s,
"123456789"s,
functionTakingString(
"12" %
string(
"34") %
'5' % 67 +
"89"));
384 constexpr
double velocityExample = 27.0;
385 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"real-word example"s,
"velocity: 27 km/h (7.5 m/s)"s,
387 CPPUNIT_ASSERT_EQUAL_MESSAGE(
388 "regular + operator still works (no problems with ambiguity)"s,
"regular + still works"s,
"regular"s +
" + still works");