CloverBootloader/rEFIt_UEFI/cpp_unit_test/XString_test.cpp

1646 lines
62 KiB
C++
Raw Normal View History

2020-03-12 15:40:38 +01:00
#include <Platform.h>
#include "../cpp_foundation/XString.h"
#include "../cpp_foundation/unicode_conversions.h"
2020-03-12 15:40:38 +01:00
2020-04-23 15:20:48 +02:00
int nbTest = 0;
int nbTestFailed = 0;
bool displayOnlyFailed = true;
#define STRINGIFY_(s) #s
#define STRINGIFY(s) STRINGIFY_(s)
#define CONCATENATE(e1, e2) e1 ## e2
#define PREFIX_L(s) CONCATENATE(L, s)
#define PREFIX_u(s) CONCATENATE(u, s)
#define PREFIX_U(s) CONCATENATE(U, s)
template <class _Tp>
struct make_unsigned
2020-03-31 17:59:35 +02:00
{
};
2020-03-12 15:40:38 +01:00
template <> struct make_unsigned< char> {typedef unsigned char type;};
template <> struct make_unsigned< signed char> {typedef unsigned char type;};
template <> struct make_unsigned<unsigned char> {typedef unsigned char type;};
template <> struct make_unsigned< signed short> {typedef unsigned short type;};
template <> struct make_unsigned<unsigned short> {typedef unsigned short type;};
template <> struct make_unsigned< signed int> {typedef unsigned int type;};
template <> struct make_unsigned<unsigned int> {typedef unsigned int type;};
template <> struct make_unsigned< signed long> {typedef unsigned long type;};
template <> struct make_unsigned<unsigned long> {typedef unsigned long type;};
2020-04-23 15:20:48 +02:00
template <> struct make_unsigned< signed long long> {typedef unsigned long long type;};
template <> struct make_unsigned<unsigned long long> {typedef unsigned long long type;};
/*
* Set a breakpoint here to catch failed test under debugger
*/
void breakpoint()
2020-03-12 15:40:38 +01:00
{
2020-04-23 15:20:48 +02:00
int a;
(void)a;
}
class SimpleString
{
char* data;
size_t allocatedSize;
public:
SimpleString() : data(NULL) {}
SimpleString(const SimpleString& simpleString) {
allocatedSize = strlen(simpleString.data)+1;
data = (char*)malloc(allocatedSize);
strcpy(data, simpleString.data);
}
SimpleString(const char* s) {
allocatedSize = strlen(s)+1;
data = (char*)malloc(allocatedSize);
strcpy(data, s);
}
SimpleString(const char16_t* s) {
#if defined(__GNUC__) && !defined(__clang__)
data = 0; // silence warning
#endif
allocatedSize = utf_size_of_utf_string(data, s)+1;
data = (char*)malloc(allocatedSize);
utf_string_from_utf_string(data, allocatedSize, s);
}
SimpleString(const char32_t* s) {
#if defined(__GNUC__) && !defined(__clang__)
data = 0; // silence warning
#endif
allocatedSize = utf_size_of_utf_string(data, s)+1;
data = (char*)malloc(allocatedSize);
utf_string_from_utf_string(data, allocatedSize, s);
}
SimpleString(const wchar_t* s) {
#if defined(__GNUC__) && !defined(__clang__)
data = 0; // silence warning
#endif
allocatedSize = utf_size_of_utf_string(data, s)+1;
data = (char*)malloc(allocatedSize);
utf_string_from_utf_string(data, allocatedSize, s);
}
SimpleString& operator =(const SimpleString& simpleString)
{
size_t newSize = strlen(simpleString.data)+1;
data = (char*)Xrealloc(data, newSize+1, allocatedSize);
2020-04-23 15:20:48 +02:00
allocatedSize = newSize+1;
strncpy(data, simpleString.data, allocatedSize);
return *this;
}
const char* c_str() const { return data; }
SimpleString& svprintf(const char* format, va_list va)
{
VA_LIST va2;
VA_COPY(va2, va);
size_t size = (size_t)vsnprintf(NULL, 0, format, va);
data = (char*)Xrealloc(data, size+1, allocatedSize);
2020-04-23 15:20:48 +02:00
allocatedSize = size+1;
data[size] = 0;
vsnprintf(data, allocatedSize, format, va2);
VA_END(va);
return *this;
}
~SimpleString() { delete data; }
};
2020-04-24 11:30:09 +02:00
/* ssprintf = SimpleStringprintf */
SimpleString ssprintf(const char* format, ...) __attribute__((__format__(__printf__, 1, 2)));
SimpleString ssprintf(const char* format, ...)
2020-04-23 15:20:48 +02:00
{
SimpleString ss;
va_list va;
va_start(va, format);
ss.svprintf(format, va);
va_end(va);
return ss;
}
// ""
// Don't put any "" in test strings or it will break indexOf and rindexOf tests.
#define utf8_1 "Āࠀ𐀀🧊Выход'UTF16'из"
#define utf8_2 "൧൨൩൪൫൬൭൮"
#define utf8_3 "éàùœ°æƒÌÚ®"
#define utf8_4 "ﰨﰩﰪﰫﰬﰭﰮﰯﰰﰱﰲﰳ"
#define utf8_5 "ォオカガキギクグケゲ"
#define utf8_6 "ꇆꇇꇈꇉꇊꇋꇌꇍ"
#define utf8_7 "伻似伽伾伿佀佁佂佃佄"
#define utf8_8 "楔楕楖楗楘楙楚楛楜楝楞楟楠楡"
//#define utf8_9 "abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįijĵķĺļľŀłńņňŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷÿźżžɓƃƅɔƈɖɗƌǝəɛƒɠɣɩɨƙɯɲɵơƣƥƨʃƭʈưʊʋƴƶʒƹƽdždžljljnjnjǎǐǒǔǖǘ"
//#define utf8_10 "ἯἸἹἺἻἼἽἾἿὈὉὊὋὌὍὙὛὝὟὨὩὪὫὬὭὮὯάέήίόύώᾈᾉᾊᾋᾌᾍᾎᾏᾘᾙᾚᾛᾜᾝᾞᾟᾨᾩᾪᾫᾬᾭᾮᾯᾸᾹᾺΆᾼιῈΈῊΉῌΐῘῙῚΊΰῨῩῪΎῬ΅`ῸΌῺΏῼ´  ΩKÅℲⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪⅫⅬⅭⅮⅯↃⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏⰀⰁⰂⰃⰄⰅⰆⰇⰈⰉⰊⰋⰌⰍⰎⰏⰐⰑⰒⰓⰔⰕⰖⰗⰘⰙⰚⰛⰜⰝⰞⰟⰠⰡⰢⰣⰤⰥⰦⰧⰨⰩⰪⰫⰬⰭⰮⱠⱢⱣⱤⱧⱩⱫⱭⱮⱯⱰⱲⱵⱾⱿⲀⲂⲄⲆⲈⲊⲌⲎⲐⲒⲔⲖⲘⲚⲜⲞⲠⲢⲤⲦⲨⲪⲬⲮⲰⲲⲴⲶⲸⲺⲼⲾⳀⳂⳄⳆⳈⳊⳌⳎⳐⳒⳔⳖⳘⳚⳜⳞⳠⳢⳫⳭⳲ〈〉Ꙁ"
//#define utf8_11 "煉璉秊練聯輦蓮連鍊列劣咽烈裂說廉念捻殮簾獵令囹寧嶺怜玲瑩羚聆鈴零靈領例禮醴隸惡了僚寮尿料樂燎療蓼遼龍暈阮劉杻柳流溜琉留硫紐類六戮陸倫崙淪輪律慄栗率隆利吏履易李梨泥理痢罹裏裡里離匿溺吝燐璘藺隣鱗麟林淋臨立笠粒狀炙識什茶刺切度拓糖宅洞暴輻行降見廓兀嗀塚晴凞猪益礼神祥福靖精羽蘒諸逸都飯飼館鶴郞隷侮僧免勉勤卑喝嘆器塀墨層屮悔慨憎懲敏既暑梅海渚漢煮爫琢碑社祉祈祐祖祝禍禎穀突節練縉繁署者臭艹艹著褐視謁謹賓贈辶逸難響頻恵舘並况全侀充冀勇勺喝啕喙嗢塚墳奄奔婢嬨廒廙彩徭惘慎愈憎慠懲戴揄搜摒敖晴朗望杖歹殺流滛滋漢瀞煮瞧爵犯猪"
struct AbstractTestString
{
size_t size; // size in nb of char (or char16_t, char32_t or wchar_t) not bytes, not including null termiator
size_t utf32_length; // length in nb of UTF32 char, not including null termiator
//size_t utf32_size; // size == length for UTF32
const char32_t* utf32;
AbstractTestString(size_t _size, size_t _utf32_length, const char32_t* _utf32)
: size(_size), utf32_length(_utf32_length), utf32(_utf32) {
}
};
template<typename CharType>
struct TestString : public AbstractTestString
{
const CharType* cha;
TestString(size_t _size, const CharType* _cha, size_t _utf32_length, const char32_t* _utf32) : AbstractTestString(_size, _utf32_length, _utf32), cha(_cha) {
}
size_t getSizeInBytes() const { return size*sizeof(CharType); }
size_t getSizeInBytesIncludingTerminator() const { return (size+1)*sizeof(CharType); }
2020-04-23 15:20:48 +02:00
};
struct TestStringMultiCoded
{
TestString<char> utf8;
TestString<char16_t> utf16;
TestString<char32_t> utf32;
TestString<wchar_t> wchar;
};
#define nbchar(s) (sizeof(s)/sizeof(*s)-1)
2020-04-25 13:33:01 +02:00
#define testStringArray_LINE(utf) \
2020-04-23 15:20:48 +02:00
TestString<char>(nbchar(utf), utf, nbchar(PREFIX_U(utf)), PREFIX_U(utf)), \
TestString<char16_t>(nbchar(PREFIX_u(utf)), PREFIX_u(utf), nbchar(PREFIX_U(utf)), PREFIX_U(utf)), \
TestString<char32_t>(nbchar(PREFIX_U(utf)), PREFIX_U(utf), nbchar(PREFIX_U(utf)), PREFIX_U(utf)), \
TestString<wchar_t>(nbchar(PREFIX_L(utf)), PREFIX_L(utf), nbchar(PREFIX_U(utf)), PREFIX_U(utf)), \
2020-04-25 13:33:01 +02:00
struct TestStringMultiCodedAndExpectedResult
{
TestString<char> utf8;
TestString<char16_t> utf16;
TestString<char32_t> utf32;
TestString<wchar_t> wchar;
TestString<char> utf8_expectedResult;
TestString<char16_t> utf16_expectedResult;
TestString<char32_t> utf32_expectedResult;
TestString<wchar_t> wchar_expectedResult;
};
#define testStringExpectedArray_LINE(utf, expected) \
testStringArray_LINE(utf) testStringArray_LINE(expected)
2020-04-23 15:20:48 +02:00
//TestString<char> foo("", "utf8", 1, "a", 1, U"a");
const TestStringMultiCoded testStringMultiCodedArray[] = {
2020-04-25 13:33:01 +02:00
{ testStringArray_LINE("") },
{ testStringArray_LINE("a") },
#ifndef _MSC_VER
2020-04-25 13:33:01 +02:00
{ testStringArray_LINE(utf8_1) },
{ testStringArray_LINE(utf8_2) },
{ testStringArray_LINE(utf8_3) },
{ testStringArray_LINE(utf8_4) },
{ testStringArray_LINE(utf8_5) },
{ testStringArray_LINE(utf8_6) },
{ testStringArray_LINE(utf8_7) },
{ testStringArray_LINE(utf8_8) },
// { testStringArray_LINE(utf8_9) },
// { testStringArray_LINE(utf8_10) },
// { testStringArray_LINE(utf8_11) },
#endif
2020-04-23 15:20:48 +02:00
};
size_t nbTestStringMultiCoded = *(&testStringMultiCodedArray + 1) - testStringMultiCodedArray;
const TestStringMultiCoded testStringMultiCoded4CaseArray[] = {
2020-04-25 13:33:01 +02:00
{ testStringArray_LINE("A൧൨BCギDEизF") },
{ testStringArray_LINE("abc聯輦deFGꇊHIjklmn") },
2020-04-23 15:20:48 +02:00
};
size_t nbTestStringMultiCoded4CaseArray = *(&testStringMultiCoded4CaseArray + 1) - testStringMultiCoded4CaseArray;
2020-04-25 13:33:01 +02:00
const TestStringMultiCodedAndExpectedResult testStringMultiCoded4TrimArray[] = {
{ testStringExpectedArray_LINE(" A൧൨BCギDEизF", "A൧൨BCギDEизF") },
{ testStringExpectedArray_LINE("A൧൨BCギDEизF ", "A൧൨BCギDEизF") },
{ testStringExpectedArray_LINE(" A൧൨BCギDEизF ", "A൧൨BCギDEизF") },
{ testStringExpectedArray_LINE("\1 \31 abc聯輦deFGꇊHIjklmn \1 \31 ", "abc聯輦deFGꇊHIjklmn") },
};
size_t nbTestStringMultiCoded4TrimArray = *(&testStringMultiCoded4TrimArray + 1) - testStringMultiCoded4TrimArray;
2020-04-23 15:20:48 +02:00
2020-04-27 11:50:49 +02:00
const TestStringMultiCodedAndExpectedResult testStringMultiCoded4BasenameArray[] = {
{ testStringExpectedArray_LINE(" A൧൨BC/ギDEизF", "ギDEизF") },
{ testStringExpectedArray_LINE(" A൧൨BC//ギDEизF", "ギDEизF") },
{ testStringExpectedArray_LINE(" A൧൨BC\\\\ギDEизF", "ギDEизF") },
{ testStringExpectedArray_LINE(" A൧൨BC///ギDEизF", "ギDEизF") },
{ testStringExpectedArray_LINE(" A൧൨BC\\\\\\ギDEизF", "ギDEизF") },
{ testStringExpectedArray_LINE(" A൧൨BC/ギDEизF ", "ギDEизF ") },
{ testStringExpectedArray_LINE(" /ギDEизF ", "ギDEизF ") },
{ testStringExpectedArray_LINE(" ギDEизF ", " ギDEизF ") },
{ testStringExpectedArray_LINE("", ".") },
{ testStringExpectedArray_LINE(" ", " ") },
{ testStringExpectedArray_LINE("abc聯/輦deFG\\ꇊHIjklmn", "ꇊHIjklmn") },
{ testStringExpectedArray_LINE("abc聯\\輦deFG/ꇊHIjklmn", "ꇊHIjklmn") },
};
size_t nbTestStringMultiCoded4BasenameArray = *(&testStringMultiCoded4BasenameArray + 1) - testStringMultiCoded4BasenameArray;
2020-04-23 15:20:48 +02:00
template<class XStringType>
struct XStringClassInfo
{
typedef XStringType xs_t;
static const char* xStringClassName;
};
template<>
struct XStringClassInfo<XString>
{
typedef char ch_t;
typedef XString xs_t;
static constexpr const char* prefix = "";
static constexpr const char* xStringClassName = "XString";
};
template<>
struct XStringClassInfo<XString16>
{
typedef char16_t ch_t;
typedef XString16 xs_t;
static constexpr const char* prefix = "u";
static constexpr const char* xStringClassName = "XString16";
};
template<>
struct XStringClassInfo<XString32>
{
typedef char32_t ch_t;
typedef XString32 xs_t;
static constexpr const char* prefix = "U";
static constexpr const char* xStringClassName = "XString32";
};
template<>
struct XStringClassInfo<XStringW>
{
typedef wchar_t ch_t;
typedef XStringW xs_t;
static constexpr const char* prefix = "L";
static constexpr const char* xStringClassName = "XStringW";
};
template<>
struct XStringClassInfo<char>
{
typedef char ch_t;
typedef XString xs_t;
static constexpr const char* prefix = "";
static constexpr const char* xStringClassName = "XString";
};
template<>
struct XStringClassInfo<char16_t>
{
typedef char16_t ch_t;
typedef XString16 xs_t;
static constexpr const char* prefix = "u";
static constexpr const char* xStringClassName = "XString16";
};
template<>
struct XStringClassInfo<char32_t>
{
typedef char32_t ch_t;
typedef XString32 xs_t;
static constexpr const char* prefix = "U";
static constexpr const char* xStringClassName = "XString32";
};
template<>
struct XStringClassInfo<wchar_t>
{
typedef wchar_t ch_t;
typedef XStringW xs_t;
static constexpr const char* prefix = "L";
static constexpr const char* xStringClassName = "XStringW";
};
template<>
struct XStringClassInfo<TestString<char>>
{
typedef char ch_t;
typedef XString xs_t;
static constexpr const char* prefix = "";
static constexpr const char* xStringClassName = "XString";
};
template<>
struct XStringClassInfo<TestString<char16_t>>
{
typedef char16_t ch_t;
typedef XString16 xs_t;
static constexpr const char* prefix = "u";
static constexpr const char* xStringClassName = "XString16";
};
template<>
struct XStringClassInfo<TestString<char32_t>>
{
typedef char32_t ch_t;
typedef XString32 xs_t;
static constexpr const char* prefix = "U";
static constexpr const char* xStringClassName = "XString32";
};
template<>
struct XStringClassInfo<TestString<wchar_t>>
{
typedef wchar_t ch_t;
typedef XStringW xs_t;
static constexpr const char* prefix = "L";
static constexpr const char* xStringClassName = "XStringW";
};
SimpleString title_tmp;
bool title_tmp_needs_reprinted;
bool displayOnlyIfFailed_tmp;
#define TEST_TITLE(__displayOnlyIfFailed__, title) \
do { \
displayOnlyIfFailed_tmp = __displayOnlyIfFailed__; \
title_tmp = title; \
title_tmp_needs_reprinted = true; \
if ( !displayOnlyIfFailed_tmp ) { \
printf("%s", title_tmp.c_str()); \
title_tmp_needs_reprinted = false; \
} \
}while(0);
#define CHECK_RESULT(condition, okmessage, failedmessage) \
do { \
if ( !(condition) ) { \
if ( title_tmp_needs_reprinted ) { \
printf("%s", title_tmp.c_str()); \
} \
printf(" : -> "); \
printf("%s", failedmessage.c_str()); \
printf("\n"); \
title_tmp_needs_reprinted = true; \
nbTestFailed += 1; \
}else if ( !displayOnlyIfFailed_tmp ) { \
if ( title_tmp_needs_reprinted ) { \
printf("%s", title_tmp.c_str()); \
} \
title_tmp_needs_reprinted = true; \
printf(" -> OK : %s\n", okmessage.c_str()); \
} \
nbTest += 1; \
if ( !(condition) ) breakpoint(); \
}while(0);
#define __TEST0(test, XStringClass, classEncoding) \
test(XStringClass, classEncoding); \
#define __TEST1(test, XStringClass, classEncoding, encoding1) \
test(XStringClass, classEncoding, encoding1); \
#define __TEST2(test, XStringClass, classEncoding, encoding1, encoding2) \
test(XStringClass, classEncoding, encoding1, encoding2); \
#define __TEST_ALL_UTF2(test, XStringClass, classEncoding, encoding1) \
__TEST2(test, XStringClass, classEncoding, encoding1, utf8); \
__TEST2(test, XStringClass, classEncoding, encoding1, utf16); \
__TEST2(test, XStringClass, classEncoding, encoding1, utf32); \
__TEST2(test, XStringClass, classEncoding, encoding1, wchar); \
/* Warning about array indexes of char type is on, so don't test it
TODO disable warning with pragma and uncomment to test with char */
2020-04-23 15:20:48 +02:00
#define TEST_ALL_INTEGRAL(test, XStringClass, classEncoding) \
/*__TEST1(test, XStringClass, classEncoding, char);*/ \
/*__TEST1(test, XStringClass, classEncoding, signed char);*/ \
/*__TEST1(test, XStringClass, classEncoding, unsigned char);*/ \
__TEST1(test, XStringClass, classEncoding, short); \
2020-04-23 15:20:48 +02:00
__TEST1(test, XStringClass, classEncoding, signed short); \
__TEST1(test, XStringClass, classEncoding, unsigned short); \
__TEST1(test, XStringClass, classEncoding, int); \
__TEST1(test, XStringClass, classEncoding, signed int); \
__TEST1(test, XStringClass, classEncoding, unsigned int); \
__TEST1(test, XStringClass, classEncoding, long); \
__TEST1(test, XStringClass, classEncoding, signed long); \
__TEST1(test, XStringClass, classEncoding, unsigned long); \
__TEST1(test, XStringClass, classEncoding, long long); \
__TEST1(test, XStringClass, classEncoding, signed long long); \
__TEST1(test, XStringClass, classEncoding, unsigned long long); \
2020-04-23 15:20:48 +02:00
#define TEST_ALL_UTF(test, XStringClass, classEncoding) \
__TEST1(test, XStringClass, classEncoding, utf8); \
__TEST1(test, XStringClass, classEncoding, utf16); \
__TEST1(test, XStringClass, classEncoding, utf32); \
__TEST1(test, XStringClass, classEncoding, wchar); \
#define TEST_ALL_UTF_ALL_UTF(test, XStringClass, classEncoding) \
__TEST_ALL_UTF2(test, XStringClass, classEncoding, utf8); \
__TEST_ALL_UTF2(test, XStringClass, classEncoding, utf16); \
__TEST_ALL_UTF2(test, XStringClass, classEncoding, utf32); \
__TEST_ALL_UTF2(test, XStringClass, classEncoding, wchar); \
#define TEST_ALL_CLASSES(test, macro) \
macro(test, XString, utf8); \
macro(test, XString16, utf16); \
macro(test, XString32, utf32); \
macro(test, XStringW, wchar); \
/***************************** Default ctor *****************************/
template<class XStringClass>
SimpleString testDefaultCtor_()
{
XStringClass xstr;
2020-04-24 11:30:09 +02:00
TEST_TITLE(displayOnlyFailed, ssprintf("Test default ctor of %s", XStringClassInfo<XStringClass>::xStringClassName));
2020-04-23 15:20:48 +02:00
CHECK_RESULT(xstr.length() == 0,
2020-04-24 11:30:09 +02:00
ssprintf("xstr.length() == 0"),
ssprintf("xstr.length() != 0")
2020-04-23 15:20:48 +02:00
);
CHECK_RESULT(xstr.sizeInBytes() == 0,
2020-04-24 11:30:09 +02:00
ssprintf("xstr.sizeInBytes() == 0"),
ssprintf("xstr.sizeInBytes() != 0")
2020-04-23 15:20:48 +02:00
);
CHECK_RESULT(*xstr.s() == 0,
2020-04-24 11:30:09 +02:00
ssprintf("*xstr.s() == 0"),
ssprintf("*xstr.s() != 0")
2020-04-23 15:20:48 +02:00
);
return SimpleString();
}
#define testDefaultCtor(XStringClass, classEncoding) \
printf("Test %s::testDefaultCtor\n", STRINGIFY(XStringClass)); \
testDefaultCtor_<XStringClass>();
/***************************** Assignement : ctor, strcpy, takeValueFrom *****************************/
2020-04-23 15:20:48 +02:00
#define CHECK_XSTRING_EQUAL_TESTSTRING(xstr, expectedResult) \
/* We don't use XString::operator == to check xstr == xstr because operator == is not tested yet. */ \
CHECK_RESULT(xstr.sizeInBytes() == expectedResult.getSizeInBytes(), \
ssprintf("xstr.sizeInBytes() == expectedResult.getSizeInBytes() (%zu)", expectedResult.getSizeInBytes()), \
ssprintf("xstr.sizeInBytes() != expectedResult.getSizeInBytes() (%zu!=%zu)", xstr.sizeInBytes(), expectedResult.getSizeInBytes()) \
); \
CHECK_RESULT(memcmp(xstr.s(), expectedResult.cha, expectedResult.getSizeInBytesIncludingTerminator()) == 0, \
ssprintf("memcmp(xstr.s(), expectedResult.cha, expectedResult.getSizeInBytesIncludingTerminator()) == 0"), \
ssprintf("memcmp(xstr.s(), expectedResult.cha, expectedResult.getSizeInBytesIncludingTerminator()) != 0") \
); \
2020-04-23 15:20:48 +02:00
template<class XStringClass, class TestStringSrc, class TestStringExpectedResult>
SimpleString testTakeValueFrom_(const TestStringSrc& src, const TestStringExpectedResult& expectedResult)
2020-04-23 15:20:48 +02:00
{
2020-04-24 11:30:09 +02:00
TEST_TITLE(displayOnlyFailed, ssprintf("Test %s::testTakeValueFrom(%s\"%s\")", XStringClassInfo<XStringClass>::xStringClassName, XStringClassInfo<TestStringSrc>::prefix, SimpleString(src.cha).c_str()));
typedef typename XStringClassInfo<XStringClass>::ch_t ch_t;
ch_t c; (void)c; // dummy for call utf function
2020-04-23 15:20:48 +02:00
// takeValueFrom(native char type)
{
XStringClass xstr;
xstr.takeValueFrom(src.cha);
CHECK_XSTRING_EQUAL_TESTSTRING(xstr, expectedResult);
}
// strcpy(native char type)
{
XStringClass xstr;
xstr.takeValueFrom("blabla");
xstr.strcpy(src.cha);
CHECK_XSTRING_EQUAL_TESTSTRING(xstr, expectedResult);
}
// strcpy one native char
{
if ( src.utf32_length > 0 )
{
XStringClass xstr;
for ( size_t pos = 0 ; pos < src.utf32_length - 1 ; pos++ )
{
char32_t char32 = get_char32_from_utf_string_at_pos(src.cha, pos);
xstr.takeValueFrom("foobar");
xstr.strcpy(char32);
//printf("%s\n", SimpleString(xstr.s()).c_str());
size_t expectedSize = utf_size_of_utf_string_len(&c, &char32, 1) * sizeof(c);
CHECK_RESULT(xstr.sizeInBytes() == expectedSize,
ssprintf("xstr.sizeInBytes() == expectedSize (%zu)", expectedSize),
ssprintf("xstr.sizeInBytes() != expectedSize (%zu!=%zu)", xstr.sizeInBytes(), expectedSize)
);
ch_t buf[8];
utf_string_from_utf_string_len(buf, sizeof(buf)/sizeof(buf[0]), &char32, 1);
size_t expectedSizeIncludingTerminator = expectedSize+sizeof(buf[0]);
CHECK_RESULT(memcmp(xstr.s(), buf, expectedSizeIncludingTerminator) == 0, // +1 char
ssprintf("memcmp(xstr.s(), buf, expectedSizeIncludingTerminator) == 0"),
ssprintf("memcmp(xstr.s(), buf, expectedSizeIncludingTerminator) != 0")
);
//xstr.takeValueFrom("foobar");
//xstr.strcpy(src.cha[0]);
}
}
}
2020-04-23 15:20:48 +02:00
typename XStringClassInfo<TestStringSrc>::xs_t srcXString;
srcXString.takeValueFrom(src.cha);
// takeValueFrom(XString)
2020-04-23 15:20:48 +02:00
{
XStringClass xstr;
xstr.takeValueFrom(srcXString);
CHECK_XSTRING_EQUAL_TESTSTRING(xstr, expectedResult);
2020-04-23 15:20:48 +02:00
}
// ctor XString
2020-04-23 15:20:48 +02:00
{
XStringClass xstr(srcXString);
CHECK_XSTRING_EQUAL_TESTSTRING(xstr, expectedResult);
}
// = XString
{
XStringClass xstr;
xstr = srcXString;
CHECK_XSTRING_EQUAL_TESTSTRING(xstr, expectedResult);
2020-04-23 15:20:48 +02:00
}
// TODO test ctor with litteral
// XStringClass xstr;
// xstr = src.cha;
2020-04-23 15:20:48 +02:00
return SimpleString();
}
#define testTakeValueFrom(XStringClass, classEncoding, encoding1) \
printf("Test %s::testTakeValueFrom, strcpy(%s)\n", STRINGIFY(XStringClass), STRINGIFY(encoding1)); \
2020-04-23 15:20:48 +02:00
for ( size_t i = 0 ; i < nbTestStringMultiCoded ; i++ ) { \
testTakeValueFrom_<XStringClass>(testStringMultiCodedArray[i].encoding1, testStringMultiCodedArray[i].classEncoding); \
2020-04-23 15:20:48 +02:00
} \
/***************************** Default isEmpty, SetEmpty *****************************/
template<class XStringClass>
SimpleString testEmpty_()
{
2020-04-24 11:30:09 +02:00
TEST_TITLE(displayOnlyFailed, ssprintf("Test isEmpty(),notEmpty(),setEmpty() of %s", XStringClassInfo<XStringClass>::xStringClassName));
2020-04-23 15:20:48 +02:00
XStringClass str;
str.takeValueFrom("aa");
CHECK_RESULT(str.isEmpty() == false,
2020-04-24 11:30:09 +02:00
ssprintf("str.isEmpty() == false"),
ssprintf("str.isEmpty() != true")
2020-04-23 15:20:48 +02:00
);
CHECK_RESULT(str.notEmpty() == true,
2020-04-24 11:30:09 +02:00
ssprintf("str.notEmpty() == true"),
ssprintf("str.notEmpty() != false")
2020-04-23 15:20:48 +02:00
);
str.setEmpty();
CHECK_RESULT(str.isEmpty() == true,
2020-04-24 11:30:09 +02:00
ssprintf("str.isEmpty() == true"),
ssprintf("str.isEmpty() != false")
2020-04-23 15:20:48 +02:00
);
CHECK_RESULT(str.notEmpty() == false,
2020-04-24 11:30:09 +02:00
ssprintf("str.notEmpty() == false"),
ssprintf("str.notEmpty() != true")
2020-04-23 15:20:48 +02:00
);
return SimpleString();
}
#define testEmpty(XStringClass, classEncoding) \
printf("Test %s::testEmpty\n", STRINGIFY(XStringClass)); \
testEmpty_<XStringClass>(); \
/***************************** char32At *****************************/
2020-04-23 15:20:48 +02:00
template<class XStringClass, typename integralType, class InitialValue>
SimpleString testchar32At_(const InitialValue& initialValue)
2020-04-23 15:20:48 +02:00
{
2020-04-24 11:30:09 +02:00
TEST_TITLE(displayOnlyFailed, ssprintf("Test %s::char32At_u()", XStringClassInfo<XStringClass>::xStringClassName));
2020-04-23 15:20:48 +02:00
XStringClass xstr;
xstr.takeValueFrom(initialValue.cha);
for ( integralType i=0 ; (typename make_unsigned<integralType>::type)i < xstr.length() ; i++ )
{
CHECK_RESULT(xstr[i] == initialValue.utf32[i],
2020-04-24 11:30:09 +02:00
ssprintf("xstr[i] == dst.cha[i] (%d)", initialValue.utf32[i]),
ssprintf("xstr[i] != dst.cha[i] (%d!=%d)", xstr[i], initialValue.utf32[i])
2020-04-23 15:20:48 +02:00
);
}
return SimpleString();
}
#define testchar32At(XStringClass, classEncoding, integralType) \
printf("Test %s::testchar32At\n", STRINGIFY(XStringClass)); \
2020-04-23 15:20:48 +02:00
for ( size_t i = 0 ; i < nbTestStringMultiCoded ; i++ ) { \
testchar32At_<XStringClass, integralType>(testStringMultiCodedArray[i].classEncoding); \
2020-04-23 15:20:48 +02:00
}
/***************************** dataSized *****************************/
template<class XStringClass, typename integralType>
SimpleString testdataSized_()
{
2020-04-24 11:30:09 +02:00
TEST_TITLE(displayOnlyFailed, ssprintf("Test %s::dataSized()", XStringClassInfo<XStringClass>::xStringClassName));
XStringClass xstr;
integralType i = 10;
typename XStringClassInfo<XStringClass>::ch_t* s = xstr.dataSized(i);
(void)s;
CHECK_RESULT(xstr.allocatedSize() >= 10,
2020-04-24 11:30:09 +02:00
ssprintf("xstr[i] == dst.cha[i] (%d)", 10),
ssprintf("xstr[i] != dst.cha[i] (%zu!=%d)", xstr.allocatedSize(), 10)
);
return SimpleString();
}
#define testdataSized(XStringClass, classEncoding, integralType) \
printf("Test %s::testdataSized\n", STRINGIFY(XStringClass)); \
testdataSized_<XStringClass, integralType>(); \
2020-04-23 15:20:48 +02:00
/***************************** strncpy *****************************/
template<class XStringClass, class TestStringSameAsClass, class TestStringSrc>
SimpleString teststrncpy_(const TestStringSameAsClass& encodedSameAsClass, const TestStringSrc& src)
{
2020-04-24 11:30:09 +02:00
TEST_TITLE(displayOnlyFailed, ssprintf("Test %s::strncpy(%s\"%s\")", XStringClassInfo<XStringClass>::xStringClassName, XStringClassInfo<TestStringSrc>::prefix, SimpleString(src.cha).c_str()));
2020-04-23 15:20:48 +02:00
for ( size_t i = 0 ; i < length_of_utf_string(src.cha)+5 ; i++ )
{
XStringClass xstr;
xstr.takeValueFrom("foobar");
xstr.strncpy(src.cha, i);
size_t expectedLength = length_of_utf_string(encodedSameAsClass.cha);
if ( expectedLength > i ) expectedLength = i;
CHECK_RESULT(xstr.length() == expectedLength,
ssprintf("xstr.length() == expectedLength (%zu)", expectedLength),
ssprintf("xstr.length() != expectedLength (%zu!=%zu)", xstr.length(), expectedLength)
2020-04-23 15:20:48 +02:00
);
CHECK_RESULT(memcmp(xstr.s(), encodedSameAsClass.cha, xstr.sizeInBytes()) == 0, // cannot include terminator as xstr is a substring of encodedSameAsClass. But length() test shows that xstr is really a substring.
ssprintf("memcmp(xstr.s(), encodedSameAsClass.cha, xstr.sizeInBytes()) == 0"),
ssprintf("memcmp(xstr.s(), encodedSameAsClass.cha, xstr.sizeInBytes()) != 0")
2020-04-23 15:20:48 +02:00
);
}
return SimpleString();
}
#define teststrncpy(XStringClass, classEncoding, encoding1) \
printf("Test %s::teststrncpy(%s)\n", STRINGIFY(XStringClass), STRINGIFY(encoding1)); \
for ( size_t i = 0 ; i < nbTestStringMultiCoded ; i++ ) { \
teststrncpy_<XStringClass>(testStringMultiCodedArray[i].classEncoding, testStringMultiCodedArray[i].encoding1); \
} \
/***************************** strcat *****************************/
template<class XStringClass, typename ch_t>
static void teststrcatCheckResult(size_t expectedLength, size_t expectedSize, ch_t* expectedString, XStringClass xstr)
{
CHECK_RESULT(xstr.length() == expectedLength,
2020-04-24 11:30:09 +02:00
ssprintf("xstr.length() == expectedLength (%zu)", expectedLength),
ssprintf("xstr.length() != expectedLength (%zu!=%zu)", xstr.length(), expectedLength)
2020-04-23 15:20:48 +02:00
);
//expectedLength = length_of_utf_string(initialValue.cha) + length_of_utf_string(valueToCat.cha);
//xstr.takeValueFrom(initialValue.cha);
//xstr.strcat(valueToCat.cha);
CHECK_RESULT(xstr.sizeInBytes() == expectedSize,
2020-04-24 11:30:09 +02:00
ssprintf("xstr.sizeInBytes() == expectedSize (%zu)", expectedSize),
ssprintf("xstr.sizeInBytes() != expectedSize (%zu!=%zu)", xstr.sizeInBytes(), expectedSize)
2020-04-23 15:20:48 +02:00
);
CHECK_RESULT(memcmp(xstr.s(), expectedString, expectedSize+sizeof(ch_t)) == 0,
2020-04-24 11:30:09 +02:00
ssprintf("memcmp(xstr.s(), dst.cha, dst.size) == 0"),
ssprintf("memcmp(xstr.s(), dst.cha, dst.size) != 0")
2020-04-23 15:20:48 +02:00
);
}
template<class XStringClass, class InitialValue, typename TestStringCharType>
SimpleString teststrcat_(const InitialValue& initialValue, const TestString<TestStringCharType>& valueToCat)
2020-04-23 15:20:48 +02:00
{
TEST_TITLE(displayOnlyFailed, ssprintf("Test %s::strcpy(%s\"%s\") strcat(%s\"%s\")", XStringClassInfo<XStringClass>::xStringClassName, XStringClassInfo<InitialValue>::prefix, SimpleString(initialValue.cha).c_str(), XStringClassInfo<TestStringCharType>::prefix, SimpleString(valueToCat.cha).c_str()));
2020-04-23 15:20:48 +02:00
typedef typename XStringClassInfo<XStringClass>::ch_t ch_t;
ch_t c; // dummy for call utf function
size_t expectedLength = length_of_utf_string(initialValue.cha) + length_of_utf_string(valueToCat.cha);
size_t expectedSize = (utf_size_of_utf_string(&c, initialValue.cha) + utf_size_of_utf_string(&c, valueToCat.cha))*sizeof(ch_t);
ch_t* expectedString = (ch_t*)malloc(expectedSize + sizeof(ch_t));
utf_string_from_utf_string(expectedString, expectedSize*sizeof(ch_t) + 1, initialValue.cha);
utf_string_from_utf_string(expectedString + size_of_utf_string(expectedString), expectedSize*sizeof(ch_t) + 1 - size_of_utf_string(expectedString), valueToCat.cha);
// strcat(native char)
{
XStringClass xstr;
xstr.takeValueFrom(initialValue.cha);
for ( size_t i = 0 ; i < valueToCat.utf32_length ; i++) xstr.strcat(valueToCat.utf32[i]);
teststrcatCheckResult(expectedLength, expectedSize, expectedString, xstr);
}
// += native char
{
XStringClass xstr;
xstr.takeValueFrom(initialValue.cha);
for ( size_t i = 0 ; i < valueToCat.utf32_length ; i++) xstr += valueToCat.utf32[i];
teststrcatCheckResult(expectedLength, expectedSize, expectedString, xstr);
}
// strcat(native char*)
2020-04-23 15:20:48 +02:00
{
XStringClass xstr;
xstr.takeValueFrom(initialValue.cha);
xstr.strcat(valueToCat.cha);
teststrcatCheckResult(expectedLength, expectedSize, expectedString, xstr);
}
// += native char*
2020-04-23 15:20:48 +02:00
{
XStringClass xstr;
xstr.takeValueFrom(initialValue.cha);
xstr += valueToCat.cha;
teststrcatCheckResult(expectedLength, expectedSize, expectedString, xstr);
}
// strcat XString
{
typename XStringClassInfo<TestStringCharType>::xs_t valueToCatXString;
2020-04-23 15:20:48 +02:00
valueToCatXString.takeValueFrom(valueToCat.cha);
XStringClass xstr;
xstr.takeValueFrom(initialValue.cha);
xstr += valueToCatXString;
teststrcatCheckResult(expectedLength, expectedSize, expectedString, xstr);
}
// XString + native char*
2020-04-23 15:20:48 +02:00
{
XStringClass xinitialValue;
xinitialValue.takeValueFrom(initialValue.cha);
XStringClass xstr;
xstr = xinitialValue + valueToCat.cha;
teststrcatCheckResult(expectedLength, expectedSize, expectedString, xstr);
}
// XString + XString
{
XStringClass xinitialValue;
xinitialValue.takeValueFrom(initialValue.cha);
typename XStringClassInfo<TestStringCharType>::xs_t valueToCatXString;
2020-04-23 15:20:48 +02:00
valueToCatXString.takeValueFrom(valueToCat.cha);
XStringClass xstr;
xstr = xinitialValue + valueToCatXString;
teststrcatCheckResult(expectedLength, expectedSize, expectedString, xstr);
}
// native char* + XString
2020-04-23 15:20:48 +02:00
{
typename XStringClassInfo<TestStringCharType>::xs_t valueToCatXString;
2020-04-23 15:20:48 +02:00
valueToCatXString.takeValueFrom(valueToCat.cha);
XStringClass xstr;
xstr = initialValue.cha + valueToCatXString;
teststrcatCheckResult(expectedLength, expectedSize, expectedString, xstr);
}
free(expectedString);
return SimpleString();
}
#define teststrcat(XStringClass, classEncoding, encoding1, encoding2) \
printf("Test %s(%s)::teststrcat(%s)\n", STRINGIFY(XStringClass), STRINGIFY(encoding1), STRINGIFY(encoding2)); \
for ( size_t i = 0 ; i < nbTestStringMultiCoded ; i++ ) { \
for ( size_t j = 0 ; j < nbTestStringMultiCoded ; j++ ) { \
teststrcat_<XStringClass>(testStringMultiCodedArray[i].encoding1, testStringMultiCodedArray[i].encoding2); \
} \
} \
2020-04-25 11:59:07 +02:00
#define Xmin(x,y) ( (x) < (y) ? (x) : (y) )
#define Xmax(x,y) ( (x) > (y) ? (x) : (y) )
2020-04-23 15:20:48 +02:00
/***************************** strncat *****************************/
template<class XStringClass, class InitialValue, class ValueToCat>
SimpleString teststrncat_(const InitialValue& initialValue, const ValueToCat& valueToCat)
{
2020-04-24 11:30:09 +02:00
TEST_TITLE(displayOnlyFailed, ssprintf("Test %s::strcpy(%s\"%s\") strncat(%s\"%s\")", XStringClassInfo<XStringClass>::xStringClassName, XStringClassInfo<InitialValue>::prefix, SimpleString(initialValue.cha).c_str(), XStringClassInfo<ValueToCat>::prefix, SimpleString(valueToCat.cha).c_str()));
2020-04-23 15:20:48 +02:00
for ( size_t i = 0 ; i < valueToCat.utf32_length+5 ; i++ )
{
typedef typename XStringClassInfo<XStringClass>::ch_t ch_t;
ch_t c; // dummy for call utf function
XStringClass xstr;
xstr.takeValueFrom(initialValue.cha);
xstr.strncat(valueToCat.cha, i);
size_t expectedLength = length_of_utf_string(initialValue.cha) + min(i, valueToCat.utf32_length);
CHECK_RESULT(xstr.length() == expectedLength,
2020-04-24 11:30:09 +02:00
ssprintf("xstr.length() == expectedLength (%zu)", expectedLength),
ssprintf("xstr.length() != expectedLength (%zu!=%zu)", xstr.length(), expectedLength)
2020-04-23 15:20:48 +02:00
);
//expectedLength = length_of_utf_string(initialValue.cha) + min(i, valueToCat.utf32_length);
//xstr.takeValueFrom(initialValue.cha);
//xstr.strncat(valueToCat.cha, i);
size_t expectedSize = (utf_size_of_utf_string(&c, initialValue.cha) + utf_size_of_utf_string_len(&c, valueToCat.cha, i));
CHECK_RESULT(xstr.sizeInBytes() == expectedSize * sizeof(ch_t),
2020-04-24 11:30:09 +02:00
ssprintf("xstr.sizeInBytes() == expectedSize (%zu)", expectedSize * sizeof(ch_t)),
ssprintf("xstr.sizeInBytes() != expectedSize (%zu!=%zu)", xstr.sizeInBytes(), expectedSize * sizeof(ch_t))
2020-04-23 15:20:48 +02:00
);
ch_t* expectedString = (ch_t*)malloc((expectedSize+1)*sizeof(ch_t));
utf_string_from_utf_string(expectedString, expectedSize + 1, initialValue.cha);
utf_string_from_utf_string_len(expectedString + utf_size_of_utf_string(&c, initialValue.cha), expectedSize + 1 - size_of_utf_string(expectedString), valueToCat.cha, i);
2020-04-23 15:20:48 +02:00
CHECK_RESULT(memcmp(xstr.s(), expectedString, expectedSize+sizeof(ch_t)) == 0,
2020-04-24 11:30:09 +02:00
ssprintf("memcmp(xstr.s(), expectedString, dst.size) == 0"),
ssprintf("memcmp(xstr.s(), expectedString, dst.size) != 0")
2020-04-23 15:20:48 +02:00
);
//utf_string_from_utf_string(expectedString, expectedSize*sizeof(XStringCharClass) + 1, initialValue.cha);
//utf_string_from_utf_string_len(expectedString + utf_size_of_utf_string(&c, initialValue.cha), expectedSize*sizeof(XStringCharClass) + 1 - size_of_utf_string(expectedString), valueToCat.cha, i);
//expectedLength = length_of_utf_string(initialValue.cha) + min(i, valueToCat.utf32_length);
//xstr.takeValueFrom(initialValue.cha);
//xstr.strncat(valueToCat.cha, i);
free(expectedString);
}
return SimpleString();
}
#define teststrncat(XStringClass, classEncoding, encoding1, encoding2) \
printf("Test %s(%s)::teststrncat(%s)\n", STRINGIFY(XStringClass), STRINGIFY(encoding1), STRINGIFY(encoding2)); \
for ( size_t i = 0 ; i < nbTestStringMultiCoded ; i++ ) { \
for ( size_t j = 0 ; j < nbTestStringMultiCoded ; j++ ) { \
teststrncat_<XStringClass>(testStringMultiCodedArray[i].encoding1, testStringMultiCodedArray[i].encoding2); \
} \
} \
/***************************** subString *****************************/
template<class XStringClass, class InitialValue>
SimpleString testSubString_(const InitialValue& initialValue)
{
TEST_TITLE(displayOnlyFailed, ssprintf("Test %s::subString(%s\"%s\")", XStringClassInfo<XStringClass>::xStringClassName, XStringClassInfo<InitialValue>::prefix, SimpleString(initialValue.cha).c_str()));
2020-04-23 15:20:48 +02:00
typedef typename XStringClassInfo<XStringClass>::ch_t ch_t;
ch_t c; // dummy for call utf function
XStringClass str;
str.takeValueFrom(initialValue.cha);
for ( size_t pos = 0 ; pos < initialValue.utf32_length+3 ; pos+=1 ) {
for ( size_t count = 0 ; count < initialValue.utf32_length-pos+3 ; count+=1 )
{
size_t expectedLength = 0;
2020-04-27 11:50:49 +02:00
if ( pos < initialValue.utf32_length ) expectedLength = Xmin( count, initialValue.utf32_length - pos);
2020-04-23 15:20:48 +02:00
size_t expectedSize = 0;
if ( pos < initialValue.utf32_length ) expectedSize = utf_size_of_utf_string_len(&c, initialValue.cha, pos+count) - utf_size_of_utf_string_len(&c, initialValue.cha, pos);
size_t offset;
if ( pos < initialValue.utf32_length ) offset = utf_size_of_utf_string_len(&c, initialValue.cha, pos);
else offset = utf_size_of_utf_string(&c, initialValue.cha);
XStringClass subStr = str.subString(pos, count);
2020-04-23 15:20:48 +02:00
CHECK_RESULT(subStr.length() == expectedLength,
2020-04-24 11:30:09 +02:00
ssprintf("subStr.length() == expectedLength (%zu)", expectedLength),
ssprintf("subStr.length() != expectedLength (%zu!=%zu)", subStr.length(), expectedLength)
2020-04-23 15:20:48 +02:00
);
2020-04-24 11:30:09 +02:00
subStr = str.subString(pos, count);
2020-04-23 15:20:48 +02:00
CHECK_RESULT(memcmp(subStr.s(), initialValue.cha + offset, expectedSize) == 0,
2020-04-24 11:30:09 +02:00
ssprintf("memcmp == 0"),
ssprintf("memcmp != 0)")
2020-04-23 15:20:48 +02:00
);
}
}
return SimpleString();
}
#define testSubString(XStringClass, classEncoding) \
printf("Test %s::testSubString\n", STRINGIFY(XStringClass)); \
for ( size_t i = 0 ; i < nbTestStringMultiCoded ; i++ ) { \
testSubString_<XStringClass>(testStringMultiCodedArray[i].classEncoding); \
} \
/***************************** Compare *****************************/
template<typename CharType>
CharType* incrementChar(const CharType* s, size_t pos, int increment)
{
size_t initialSize = size_of_utf_string(s);
CharType* buf = (CharType*)malloc( (initialSize+1)*sizeof(CharType) );
size_t dst_max_len = initialSize+1;
char32_t char32;
size_t n = 0;
CharType* d = buf;
s = get_char32_from_string(s, &char32);
while ( char32 ) {
if ( n == pos ) {
if ( increment >= 0 ) {
d = store_utf_from_char32(d, &dst_max_len, char32+(unsigned int)increment);
}else{
d = store_utf_from_char32(d, &dst_max_len, char32-(unsigned int)(-increment)); // avoid signedness warning
}
}else{
d = store_utf_from_char32(d, &dst_max_len, char32);
}
s = get_char32_from_string(s, &char32);
n++;
}
2020-04-24 11:30:09 +02:00
*d = 0;
2020-04-23 15:20:48 +02:00
return buf;
}
template<class XStringClass, class InitialValue>
SimpleString testCompare_(const InitialValue& initialValue)
{
2020-04-24 11:30:09 +02:00
TEST_TITLE(displayOnlyFailed, ssprintf("Test %s::strcmp(%s\"%s\")", XStringClassInfo<XStringClass>::xStringClassName, XStringClassInfo<InitialValue>::prefix, SimpleString(initialValue.cha).c_str()));
2020-04-23 15:20:48 +02:00
// typedef typename XStringClassInfo<XStringClass>::ch_t xs_ch_t;
// ch_t c; // dummy for call utf function
XStringClass xstr;
xstr.takeValueFrom(initialValue.cha);
typename XStringClassInfo<InitialValue>::xs_t xstr2;
xstr2.takeValueFrom(initialValue.cha);
CHECK_RESULT(xstr.strcmp(xstr2.s()) == 0,
2020-04-24 11:30:09 +02:00
ssprintf("subStr.length() == 0"),
ssprintf("subStr.length() != 0 (%d)", xstr.strcmp(xstr2.s()))
2020-04-23 15:20:48 +02:00
);
2020-04-24 11:30:09 +02:00
// CHECK_RESULT(xstr == xstr2.s(),
// ssprintf("subStr.length() == 0"),
// ssprintf("subStr.length() != 0 (%d)", xstr.strcmp(xstr2.s()))
// );
2020-04-23 15:20:48 +02:00
CHECK_RESULT(xstr == xstr2,
2020-04-24 11:30:09 +02:00
ssprintf("subStr.length() == 0"),
ssprintf("subStr.length() != 0 (%d)", xstr.strcmp(xstr2.s()))
2020-04-23 15:20:48 +02:00
);
2020-04-24 11:30:09 +02:00
// CHECK_RESULT(!(xstr != xstr2.s()),
// ssprintf("subStr.length() == 0"),
// ssprintf("subStr.length() != 0 (%d)", xstr.strcmp(xstr2.s()))
// );
2020-04-23 15:20:48 +02:00
CHECK_RESULT(!(xstr != xstr2),
2020-04-24 11:30:09 +02:00
ssprintf("subStr.length() == 0"),
ssprintf("subStr.length() != 0 (%d)", xstr.strcmp(xstr2.s()))
2020-04-23 15:20:48 +02:00
);
2020-04-24 11:30:09 +02:00
// CHECK_RESULT(!(xstr != xstr2.s()),
// ssprintf("subStr.length() == 0"),
// ssprintf("subStr.length() != 0 (%d)", xstr.strcmp(xstr2.s()))
// );
2020-04-23 15:20:48 +02:00
CHECK_RESULT(!(xstr != xstr2),
2020-04-24 11:30:09 +02:00
ssprintf("subStr.length() == 0"),
ssprintf("subStr.length() != 0 (%d)", xstr.strcmp(xstr2.s()))
2020-04-23 15:20:48 +02:00
);
//res = xstr.strcmp(xstr2.s());
typedef typename XStringClassInfo<InitialValue>::ch_t ch_t;
for ( size_t pos = 0 ; pos < initialValue.utf32_length ; pos++) // this avoid empty string
{
const ch_t* s = incrementChar(initialValue.cha, pos, 1);
CHECK_RESULT(xstr.strcmp(s) == -1,
2020-04-24 11:30:09 +02:00
ssprintf("xstr.strcmp(s) == -1"),
ssprintf("xstr.strcmp(s) != -1 (%d)", xstr.strcmp(s))
2020-04-23 15:20:48 +02:00
);
/* operator comparison with native type */
2020-04-24 11:30:09 +02:00
// CHECK_RESULT(!(xstr == s),
// ssprintf("!(xstr == s)"),
// ssprintf("!!(xstr == s)")
// );
// CHECK_RESULT(!(s == xstr),
// ssprintf("!(s == xstr)"),
// ssprintf("!!(s == xstr)")
// );
// CHECK_RESULT(xstr != s,
// ssprintf("xstr != s"),
// ssprintf("!xstr != s")
// );
// CHECK_RESULT(s != xstr,
// ssprintf("s != xstr"),
// ssprintf("!s != xstr")
// );
// CHECK_RESULT(xstr < s,
// ssprintf("xstr < s"),
// ssprintf("!xstr < s")
// );
// CHECK_RESULT(s > xstr,
// ssprintf("s > xstr"),
// ssprintf("!s > xstr")
// );
// CHECK_RESULT(xstr <= s,
// ssprintf("xstr <= s"),
// ssprintf("!xstr <= s")
// );
// CHECK_RESULT(s >= xstr,
// ssprintf("s >= xstr"),
// ssprintf("!s >= xstr")
// );
// CHECK_RESULT(!(xstr > s),
// ssprintf("!(xstr > s)"),
// ssprintf("!!(xstr < s)")
// );
// CHECK_RESULT(!(s < xstr),
// ssprintf("!(s < xstr)"),
// ssprintf("!!(s < xstr)")
// );
// CHECK_RESULT(!(xstr >= s),
// ssprintf("!(xstr >= s)"),
// ssprintf("!!(xstr >= s)")
// );
// CHECK_RESULT(!(s <= xstr),
// ssprintf("!(s <= xstr)"),
// ssprintf("!!(s <= xstr)")
// );
2020-04-23 15:20:48 +02:00
/* operator comparison with other XString */
xstr2.takeValueFrom(s);
2020-04-24 11:30:09 +02:00
2020-04-23 15:20:48 +02:00
CHECK_RESULT(!(xstr == xstr2),
2020-04-24 11:30:09 +02:00
ssprintf("!(xstr == xstr2)"),
ssprintf("!!(xstr == xstr2)")
2020-04-23 15:20:48 +02:00
);
CHECK_RESULT(!(xstr2 == xstr),
2020-04-24 11:30:09 +02:00
ssprintf("!(xstr2 == xstr)"),
ssprintf("!!(xstr2 == xstr)")
2020-04-23 15:20:48 +02:00
);
CHECK_RESULT(xstr != xstr2,
2020-04-24 11:30:09 +02:00
ssprintf("xstr != xstr2"),
ssprintf("!xstr != xstr2")
2020-04-23 15:20:48 +02:00
);
CHECK_RESULT(xstr2 != xstr,
2020-04-24 11:30:09 +02:00
ssprintf("xstr2 != xstr"),
ssprintf("!xstr2 != xstr")
2020-04-23 15:20:48 +02:00
);
CHECK_RESULT(xstr < xstr2,
2020-04-24 11:30:09 +02:00
ssprintf("xstr < xstr2"),
ssprintf("!xstr < xstr2")
2020-04-23 15:20:48 +02:00
);
CHECK_RESULT(xstr2 > xstr,
2020-04-24 11:30:09 +02:00
ssprintf("xstr2 > xstr"),
ssprintf("!xstr2 > xstr")
2020-04-23 15:20:48 +02:00
);
CHECK_RESULT(xstr <= xstr2,
2020-04-24 11:30:09 +02:00
ssprintf("xstr <= xstr2"),
ssprintf("!xstr <= xstr2")
2020-04-23 15:20:48 +02:00
);
CHECK_RESULT(xstr2 >= xstr,
2020-04-24 11:30:09 +02:00
ssprintf("xstr2 >= xstr"),
ssprintf("!xstr2 >= xstr")
2020-04-23 15:20:48 +02:00
);
CHECK_RESULT(!(xstr > xstr2),
2020-04-24 11:30:09 +02:00
ssprintf("!(xstr > xstr2)"),
ssprintf("!!(xstr < xstr2)")
2020-04-23 15:20:48 +02:00
);
CHECK_RESULT(!(xstr2 < xstr),
2020-04-24 11:30:09 +02:00
ssprintf("!(xstr2 < xstr)"),
ssprintf("!!(xstr2 < xstr)")
2020-04-23 15:20:48 +02:00
);
CHECK_RESULT(!(xstr >= xstr2),
2020-04-24 11:30:09 +02:00
ssprintf("!(xstr >= xstr2)"),
ssprintf("!!(xstr >= xstr2)")
2020-04-23 15:20:48 +02:00
);
CHECK_RESULT(!(xstr2 <= xstr),
2020-04-24 11:30:09 +02:00
ssprintf("!(xstr2 <= xstr)"),
ssprintf("!!(xstr2 <= xstr)")
2020-04-23 15:20:48 +02:00
);
2020-04-24 11:30:09 +02:00
free((void*)s);
2020-04-23 15:20:48 +02:00
}
for ( size_t pos = 0 ; pos < initialValue.utf32_length ; pos++) // this avoid empty string
{
const ch_t* s = incrementChar(initialValue.cha, pos, -1);
CHECK_RESULT(xstr.strcmp(s) == 1,
2020-04-24 11:30:09 +02:00
ssprintf("xstr.strcmp(s) == 1"),
ssprintf("xstr.strcmp(s) != 1 (%d)", xstr.strcmp(s))
2020-04-23 15:20:48 +02:00
);
//const ch_t* s2 = incrementChar(initialValue.cha, pos, 1);
}
return SimpleString();
}
#define testCompare(XStringClass, classEncoding, encoding) \
printf("Test %s::strcmp(%s)\n", STRINGIFY(XStringClass), STRINGIFY(encoding)); \
for ( size_t i = 0 ; i < nbTestStringMultiCoded ; i++ ) { \
testCompare_<XStringClass>(testStringMultiCodedArray[i].encoding); \
} \
/***************************** indexOf, rindexOf *****************************/
template<class XStringClass, typename ch_t>
static void testindexOf__(XStringClass subStr, bool ignoreCase,
2020-04-23 15:20:48 +02:00
size_t (XStringClass::*indexOfChar)(char32_t, size_t) const,
size_t (XStringClass::*indexOfString)(const ch_t*, size_t) const,
size_t (XStringClass::*rindexOfChar)(char32_t, size_t) const,
size_t (XStringClass::*rindexOfString)(const ch_t*, size_t) const
)
{
XStringClass testStr;
testStr = subStr;
if ( ignoreCase ) testStr.lowerAscii();
CHECK_RESULT((testStr.*indexOfString)(subStr.s(), 0) == 0,
2020-04-24 11:30:09 +02:00
ssprintf("testStr.indexOf(subStr.s(), 0) == 0"),
ssprintf("testStr.indexOf(subStr.s(), 0) != 0 (%zu)", (testStr.*indexOfString)(subStr.s(), 0))
2020-04-23 15:20:48 +02:00
);
(testStr.*indexOfString)(subStr.s(), 0);
size_t expectedPos = subStr.length()==0 ? testStr.length() : 0;
CHECK_RESULT((testStr.*rindexOfString)(subStr.s(), MAX_XSIZE-1) == expectedPos,
2020-04-24 11:30:09 +02:00
ssprintf("testStr.indexOf(subStr.s(), 0) == expectedPos (%zu)", expectedPos),
ssprintf("testStr.indexOf(subStr.s(), 0) != 0 (%zu!=%zu)", (testStr.*rindexOfString)(subStr.s(), MAX_XSIZE-1), expectedPos)
2020-04-23 15:20:48 +02:00
);
(testStr.*rindexOfString)(subStr.s(), MAX_XSIZE-1);
XStringClass apple;
apple.takeValueFrom("");
CHECK_RESULT((testStr.*indexOfString)(apple.s(), 0) == MAX_XSIZE,
2020-04-24 11:30:09 +02:00
ssprintf("testStr.*indexOfString)(\"\", 0) == MAX_XSIZE"),
ssprintf("testStr.*indexOfString)(\"\", 0) != MAX_XSIZE (%zu)", (testStr.*indexOfString)(subStr.s(), 0))
2020-04-23 15:20:48 +02:00
);
//(testStr.*indexOfString)("");
CHECK_RESULT((testStr.*rindexOfString)(apple.s(), MAX_XSIZE-1) == MAX_XSIZE,
2020-04-24 11:30:09 +02:00
ssprintf("(testStr.*rindexOfString)(\"\", MAX_XSIZE-1) == MAX_XSIZE"),
ssprintf("(testStr.*rindexOfString)(\"\", MAX_XSIZE-1) != MAX_XSIZE (%zu)", (testStr.*rindexOfString)(subStr.s(), MAX_XSIZE-1))
2020-04-23 15:20:48 +02:00
);
if ( subStr.length() > 0 )
{
testStr.takeValueFrom("");
testStr.strcat(subStr.s());
if ( ignoreCase ) testStr.lowerAscii();
CHECK_RESULT((testStr.*indexOfString)(subStr.s(), 0) == 3,
2020-04-24 11:30:09 +02:00
ssprintf("testStr.indexOf(subStr.s(), 0) == 3"),
ssprintf("testStr.indexOf(subStr.s(), 0) != 3 (%zu)", (testStr.*indexOfString)(subStr.s(), 0))
2020-04-23 15:20:48 +02:00
);
(testStr.*indexOfString)(subStr.s(), 0);
CHECK_RESULT((testStr.*indexOfString)(subStr.s(), 0) == 3,
2020-04-24 11:30:09 +02:00
ssprintf("(testStr.*indexOfString)(subStr.s(), 0) == 3"),
ssprintf("(testStr.*indexOfString)(subStr.s(), 0) != 3 (%zu)", (testStr.*indexOfString)(subStr.s(), 0))
2020-04-23 15:20:48 +02:00
);
CHECK_RESULT((testStr.*indexOfChar)(subStr[0], 0) == 3,
2020-04-24 11:30:09 +02:00
ssprintf("(testStr.*indexOfString)(subStr[0]) == 3"),
ssprintf("(testStr.*indexOfString)(subStr[0]) != 3 (%zu)", (testStr.*indexOfChar)(subStr[0], 0))
2020-04-23 15:20:48 +02:00
);
CHECK_RESULT((testStr.*rindexOfString)(subStr.s(), MAX_XSIZE-1) == 3,
2020-04-24 11:30:09 +02:00
ssprintf("testStr.indexOf(subStr.s(), MAX_XSIZE-1) == 3"),
ssprintf("testStr.indexOf(subStr.s(), MAX_XSIZE-1) != 3 (%zu)", (testStr.*rindexOfString)(subStr.s(), MAX_XSIZE-1))
2020-04-23 15:20:48 +02:00
);
(testStr.*rindexOfString)(subStr.s(), MAX_XSIZE-1);
CHECK_RESULT((testStr.*rindexOfString)(subStr.s(), MAX_XSIZE-1) == 3,
2020-04-24 11:30:09 +02:00
ssprintf("(testStr.*rindexOfString)(subStr.s(), 0) == 3"),
ssprintf("(testStr.*rindexOfString)(subStr.s(), 0) != 3 (%zu)", (testStr.*rindexOfString)(subStr.s(), MAX_XSIZE-1))
2020-04-23 15:20:48 +02:00
);
CHECK_RESULT((testStr.*rindexOfChar)(subStr[subStr.length()-1], MAX_XSIZE-1) == 3 + subStr.length() - 1,
2020-04-24 11:30:09 +02:00
ssprintf("(testStr.*rindexOfString)(subStr[subStr.length()-1]) == 3 + subStr.length() - 1 (%zu)", 3 + subStr.length() - 1),
ssprintf("(testStr.*rindexOfString)(subStr[subStr.length()-1]) == 3 + subStr.length() - 1 (%zu!=%zu)", (testStr.*rindexOfChar)(subStr[subStr.length()-1], MAX_XSIZE-1), 3 + subStr.length() - 1)
2020-04-23 15:20:48 +02:00
);
testStr.takeValueFrom("");
testStr.strcat(subStr.s());
testStr.strcat("");
if ( ignoreCase ) testStr.lowerAscii();
CHECK_RESULT((testStr.*indexOfString)(subStr.s(), 0) == 4,
2020-04-24 11:30:09 +02:00
ssprintf("testStr.indexOf(subStr.s(), 0) == 4"),
ssprintf("testStr.indexOf(subStr.s(), 0) != 4 (%zu)", (testStr.*indexOfString)(subStr.s(), 0))
2020-04-23 15:20:48 +02:00
);
(testStr.*indexOfString)(subStr.s(), 0);
CHECK_RESULT((testStr.*indexOfString)(subStr.s(), 0) == 4,
2020-04-24 11:30:09 +02:00
ssprintf("(testStr.*indexOfString)(subStr.s(), 0) == 4"),
ssprintf("(testStr.*indexOfString)(subStr.s(), 0) != 4 (%zu)", (testStr.*indexOfString)(subStr.s(), 0))
2020-04-23 15:20:48 +02:00
);
CHECK_RESULT((testStr.*indexOfChar)(subStr[0], 0) == 4,
2020-04-24 11:30:09 +02:00
ssprintf("(testStr.*indexOfString)(subStr[0]) == 4"),
ssprintf("(testStr.*indexOfString)(subStr[0]) != 4 (%zu)", (testStr.*indexOfChar)(subStr[0], 0))
2020-04-23 15:20:48 +02:00
);
CHECK_RESULT((testStr.*rindexOfString)(subStr.s(), MAX_XSIZE-1) == 4,
2020-04-24 11:30:09 +02:00
ssprintf("testStr.indexOf(subStr.s(), 0) == 4"),
ssprintf("testStr.indexOf(subStr.s(), 0) != 4 (%zu)", (testStr.*rindexOfString)(subStr.s(), MAX_XSIZE-1))
2020-04-23 15:20:48 +02:00
);
CHECK_RESULT((testStr.*rindexOfString)(subStr.s(), MAX_XSIZE-1) == 4,
2020-04-24 11:30:09 +02:00
ssprintf("(testStr.*rindexOfString)(subStr.s(), 0) == 4"),
ssprintf("(testStr.*rindexOfString)(subStr.s(), 0) != 4 (%zu)", (testStr.*rindexOfString)(subStr.s(), MAX_XSIZE-1))
2020-04-23 15:20:48 +02:00
);
CHECK_RESULT((testStr.*rindexOfChar)(subStr[subStr.length()-1], MAX_XSIZE-1) == 4 + subStr.length() - 1,
2020-04-24 11:30:09 +02:00
ssprintf("(testStr.*rindexOfString)(subStr[subStr.length()-1]) == 4 + subStr.length() - 1 (%zu)", 4 + subStr.length() - 1),
ssprintf("(testStr.*rindexOfString)(subStr[subStr.length()-1]) == 4 + subStr.length() - 1 (%zu!=%zu)", (testStr.*rindexOfChar)(subStr[subStr.length()-1], MAX_XSIZE-1), 4 + subStr.length() - 1)
2020-04-23 15:20:48 +02:00
);
testStr.takeValueFrom("");
testStr.strcat(subStr.s());
testStr.strcat("");
testStr.strcat(subStr.s());
testStr.strcat("");
if ( ignoreCase ) testStr.lowerAscii();
CHECK_RESULT((testStr.*indexOfString)(subStr.s(), 0) == 5,
2020-04-24 11:30:09 +02:00
ssprintf("testStr.indexOf(subStr.s(), 0) == 5"),
ssprintf("testStr.indexOf(subStr.s(), 0) != 5 (%zu)", (testStr.*indexOfString)(subStr.s(), 0))
2020-04-23 15:20:48 +02:00
);
CHECK_RESULT((testStr.*indexOfString)(subStr.s(), 0) == 5,
2020-04-24 11:30:09 +02:00
ssprintf("(testStr.*indexOfString)(subStr.s(), 0) == 5"),
ssprintf("(testStr.*indexOfString)(subStr.s(), 0) != 5 (%zu)", (testStr.*indexOfString)(subStr.s(), 0))
2020-04-23 15:20:48 +02:00
);
CHECK_RESULT((testStr.*indexOfChar)(subStr[0], 0) == 5,
2020-04-24 11:30:09 +02:00
ssprintf("(testStr.*indexOfString)(subStr[0]) == 5"),
ssprintf("(testStr.*indexOfString)(subStr[0]) != 5 (%zu)", (testStr.*indexOfChar)(subStr[0], 0))
2020-04-23 15:20:48 +02:00
);
CHECK_RESULT((testStr.*rindexOfString)(subStr.s(), MAX_XSIZE-1) == 5 + subStr.length() + 6,
2020-04-24 11:30:09 +02:00
ssprintf("testStr.indexOf(subStr.s(), 0) == 5 + subStr.length() + 6"),
ssprintf("testStr.indexOf(subStr.s(), 0) != 5 + subStr.length() + 6 (%zu!=%zu)", (testStr.*rindexOfString)(subStr.s(), MAX_XSIZE-1), 5 + subStr.length() + 6)
2020-04-23 15:20:48 +02:00
);
(testStr.*rindexOfString)(subStr.s(), MAX_XSIZE-1);
CHECK_RESULT((testStr.*rindexOfString)(subStr.s(), MAX_XSIZE-1) == 5 + subStr.length() + 6,
2020-04-24 11:30:09 +02:00
ssprintf("(testStr.*rindexOfString)(subStr.s(), 0) == 5 + subStr.length() + 6"),
ssprintf("(testStr.*rindexOfString)(subStr.s(), 0) != 5 + subStr.length() + 6 (%zu!=%zu)", (testStr.*rindexOfString)(subStr.s(), MAX_XSIZE-1), 5 + subStr.length() + 6)
2020-04-23 15:20:48 +02:00
);
CHECK_RESULT((testStr.*rindexOfChar)(subStr[subStr.length()-1], MAX_XSIZE-1) == 5 + subStr.length() + 6 + subStr.length() - 1,
2020-04-24 11:30:09 +02:00
ssprintf("(testStr.*rindexOfString)(subStr[subStr.length()-1]) == 5 + subStr.length() + 6 + subStr.length() - 1 (%zu)", 5 + subStr.length() + 6 + subStr.length() - 1),
ssprintf("(testStr.*rindexOfString)(subStr[subStr.length()-1]) == 5 + subStr.length() + 6 + subStr.length() - 1 (%zu!=%zu)", (testStr.*rindexOfChar)(subStr[subStr.length()-1], MAX_XSIZE-1), 5 + subStr.length() + 6 + subStr.length() - 1)
2020-04-23 15:20:48 +02:00
);
}
}
template<class XStringClass, class InitialValue>
SimpleString testindexOf_(const InitialValue& initialValue)
2020-04-23 15:20:48 +02:00
{
2020-04-24 11:30:09 +02:00
TEST_TITLE(displayOnlyFailed, ssprintf("Test %s::idxOf", XStringClassInfo<XStringClass>::xStringClassName));
2020-04-23 15:20:48 +02:00
typedef typename XStringClassInfo<XStringClass>::xs_t ixs_t;
typedef typename XStringClassInfo<XStringClass>::ch_t ich_t;
// ch_t c; // dummy for call utf function
ixs_t str;
str.takeValueFrom(initialValue.cha);
for ( size_t pos = 0 ; pos < initialValue.utf32_length+3 ; pos+=1 ) {
for ( size_t count = 0 ; count < initialValue.utf32_length-pos+3 ; count+=1 )
{
ixs_t subStr = str.subString(pos, count);
2020-04-23 15:20:48 +02:00
// size_t (ixs_t::*p)(const ich_t* S, size_t Pos) const = &ixs_t::template indexOf<ich_t>;
testindexOf__<ixs_t, ich_t>(subStr, false, &ixs_t::indexOf, &ixs_t::template indexOf, &ixs_t::rindexOf, &ixs_t::template rindexOf);
2020-04-23 15:20:48 +02:00
ixs_t subStrLower = subStr;
testindexOf__<ixs_t, ich_t>(subStrLower, true, &ixs_t::indexOfIC, &ixs_t::template indexOfIC, &ixs_t::rindexOfIC, &ixs_t::template rindexOfIC);
2020-04-23 15:20:48 +02:00
// if ( subStrLower != subStr ) {
// }
}
}
return SimpleString();
}
#define testindexOf(XStringClass, classEncoding, encoding) \
printf("Test %s::testindexOf(%s)\n", STRINGIFY(XStringClass), STRINGIFY(encoding)); \
2020-04-23 15:20:48 +02:00
for ( size_t i = 0 ; i < nbTestStringMultiCoded ; i++ ) { \
testindexOf_<XStringClass>(testStringMultiCodedArray[i].encoding); \
2020-04-23 15:20:48 +02:00
} \
for ( size_t i = 0 ; i < nbTestStringMultiCoded4CaseArray ; i++ ) { \
testindexOf_<XStringClass>(testStringMultiCoded4CaseArray[i].encoding); \
2020-04-23 15:20:48 +02:00
} \
2020-04-25 11:59:07 +02:00
/***************************** lastChar *****************************/
template<class XStringClass, class InitialValue>
SimpleString testlastChar_(const InitialValue& initialValue)
{
TEST_TITLE(displayOnlyFailed, ssprintf("Test %s::lastChar(%s\"%s\")", XStringClassInfo<XStringClass>::xStringClassName, XStringClassInfo<InitialValue>::prefix, SimpleString(initialValue.cha).c_str()));
2020-04-25 11:59:07 +02:00
// typedef typename XStringClassInfo<XStringClass>::ch_t ch_t;
// ch_t c; // dummy for call utf function
XStringClass str;
str.takeValueFrom(initialValue.cha);
char32_t expectedChar = 0;
if ( initialValue.utf32_length > 0) expectedChar = initialValue.utf32[initialValue.utf32_length-1];
char32_t char32 = str.lastChar();
CHECK_RESULT(char32 == expectedChar,
ssprintf("char32 == expectedChar (%d)", expectedChar),
ssprintf("char32 == expectedChar (%d!=%d)", char32, expectedChar)
);
return SimpleString();
}
#define testlastChar(XStringClass, classEncoding) \
printf("Test %s::testlastChar\n", STRINGIFY(XStringClass)); \
for ( size_t i = 0 ; i < nbTestStringMultiCoded ; i++ ) { \
testlastChar_<XStringClass>(testStringMultiCodedArray[i].classEncoding); \
} \
2020-04-23 15:20:48 +02:00
2020-04-25 13:33:01 +02:00
/***************************** trim *****************************/
template<class XStringClass, class InitialValue, class ExpectedValue>
SimpleString testtrim_(const InitialValue& initialValue, const ExpectedValue& expectedValue)
{
TEST_TITLE(displayOnlyFailed, ssprintf("Test %s::trim(%s\"%s\")", XStringClassInfo<XStringClass>::xStringClassName, XStringClassInfo<InitialValue>::prefix, SimpleString(initialValue.cha).c_str()));
2020-04-25 13:33:01 +02:00
// typedef typename XStringClassInfo<XStringClass>::ch_t ch_t;
// ch_t c; // dummy for call utf function
XStringClass str;
str.takeValueFrom(initialValue.cha);
char32_t expectedChar = 0;
if ( initialValue.utf32_length > 0) expectedChar = initialValue.utf32[initialValue.utf32_length-1];
str.trim();
CHECK_RESULT(str.strcmp(expectedValue.cha) == 0,
ssprintf("str.strcmp(expectedValue.cha) == 0 (\"%s\")", SimpleString(expectedValue.cha).c_str()),
ssprintf("str.strcmp(expectedValue.cha) != 0 (\"%s\"!=\"%s\")", SimpleString(str.c_str()).c_str(), SimpleString(expectedValue.cha).c_str())
);
//str.takeValueFrom(initialValue.cha);
//str.trim();
return SimpleString();
}
#define testtrim(XStringClass, classEncoding) \
printf("Test %s::testtrim\n", STRINGIFY(XStringClass)); \
for ( size_t i = 0 ; i < nbTestStringMultiCoded4TrimArray ; i++ ) { \
testtrim_<XStringClass>(testStringMultiCoded4TrimArray[i].classEncoding, testStringMultiCoded4TrimArray[i].classEncoding##_expectedResult); \
} \
/***************************** startWith *****************************/
template<class XStringClass, class InitialValue>
SimpleString teststartWith_(const InitialValue& initialValue)
{
TEST_TITLE(displayOnlyFailed, ssprintf("Test %s::startWith(%s\"%s\")", XStringClassInfo<XStringClass>::xStringClassName, XStringClassInfo<InitialValue>::prefix, SimpleString(initialValue.cha).c_str()));
// typedef typename XStringClassInfo<XStringClass>::ch_t ch_t;
// ch_t c; // dummy for call utf function
XStringClass initialString;
initialString.takeValueFrom(initialValue.cha);
char32_t expectedChar = 0;
if ( initialValue.utf32_length > 0) expectedChar = initialValue.utf32[initialValue.utf32_length-1];
for ( size_t count = 0 ; count < initialValue.utf32_length+3 ; count+=1 )
{
XStringClass subStr = initialString.subString(0, count);
bool expectedResult = true;
if ( subStr.length() > 0 && count >= initialValue.utf32_length ) expectedResult = false;
CHECK_RESULT(initialString.startWith(subStr) == expectedResult,
ssprintf("\"%s\".startWith(\"%s\") == %d", SimpleString(initialString.s()).c_str(), SimpleString(subStr.s()).c_str(), expectedResult),
ssprintf("\"%s\".startWith(\"%s\") != %d", SimpleString(initialString.s()).c_str(), SimpleString(subStr.s()).c_str(), expectedResult)
);
//initialString.startWith(subStr);
subStr = initialString.subString(0, count-1) + ((char32_t)(initialValue.utf32[count-1]+1));
expectedResult = false;
CHECK_RESULT(initialString.startWith(subStr) == expectedResult,
ssprintf("\"%s\".startWith(\"%s\") == %d", SimpleString(initialString.s()).c_str(), SimpleString(subStr.s()).c_str(), expectedResult),
ssprintf("\"%s\".startWith(\"%s\") != %d", SimpleString(initialString.s()).c_str(), SimpleString(subStr.s()).c_str(), expectedResult)
);
//subStr = initialString.subString(0, count-1);
//subStr = subStr + ((char32_t)(initialValue.utf32[count-1]+1));
//initialString.startWith(subStr);
}
//str.takeValueFrom(initialValue.cha);
//str.startWith();
return SimpleString();
}
#define teststartWith(XStringClass, classEncoding) \
printf("Test %s::teststartWith\n", STRINGIFY(XStringClass)); \
for ( size_t i = 0 ; i < nbTestStringMultiCoded ; i++ ) { \
teststartWith_<XStringClass>(testStringMultiCodedArray[i].classEncoding); \
} \
2020-04-27 11:50:49 +02:00
/***************************** basename *****************************/
template<class XStringClass, class InitialValue, typename ExpectedResult>
SimpleString testbasename_(const InitialValue& initialValue, const TestString<ExpectedResult>& expectedResult)
{
TEST_TITLE(displayOnlyFailed, ssprintf("Test %s::basename(%s\"%s\")", XStringClassInfo<XStringClass>::xStringClassName, XStringClassInfo<InitialValue>::prefix, SimpleString(initialValue.cha).c_str()));
// typedef typename XStringClassInfo<XStringClass>::ch_t ch_t;
// ch_t c; // dummy for call utf function
XStringClass initialString;
initialString.takeValueFrom(initialValue.cha);
XStringClass xstr = initialString.basename();
CHECK_RESULT(xstr.strcmp(expectedResult.cha) == 0,
ssprintf("\"%s\".basename() == \"%s\"", SimpleString(initialString.s()).c_str(), SimpleString(expectedResult.cha).c_str()),
ssprintf("\"%s\".basename() != (\"%s\"!=\"%s\")", SimpleString(initialString.s()).c_str(), SimpleString(xstr.s()).c_str(), SimpleString(expectedResult.cha).c_str())
);
XStringClass xstr2 = initialString.basename();
return SimpleString();
}
#define testbasename(XStringClass, classEncoding) \
printf("Test %s::testbasename\n", STRINGIFY(XStringClass)); \
for ( size_t i = 0 ; i < nbTestStringMultiCoded4BasenameArray ; i++ ) { \
testbasename_<XStringClass>(testStringMultiCoded4BasenameArray[i].classEncoding, testStringMultiCoded4BasenameArray[i].classEncoding##_expectedResult); \
} \
2020-04-25 13:33:01 +02:00
2020-04-23 15:20:48 +02:00
/***************************** *****************************/
#undef realloc
2020-04-05 14:25:39 +02:00
//
2020-04-23 15:20:48 +02:00
//#include <type_traits>
//#include <typeinfo>
//#include <iostream>
2020-04-27 11:50:49 +02:00
//#include <libgen.h>
2020-04-23 15:20:48 +02:00
//std::is_class
void func_test(XStringW& xsw)
{
(void)xsw;
}
2020-04-27 11:50:49 +02:00
template<typename T>
class CE
{
public:
const T* data;
constexpr CE() : data(0) { }
};
class CE2 : public XStringAbstractNoDtor<char, CE2>
{
};
int XString_tests()
2020-04-23 15:20:48 +02:00
{
#ifdef JIEF_DEBUG
2020-04-24 11:30:09 +02:00
// printf("XString16_tests -> Enter\n");
2020-04-23 15:20:48 +02:00
#endif
2020-04-27 11:50:49 +02:00
//constexpr CE<char> ce;
//constexpr CE2 xsw;
2020-04-23 15:20:48 +02:00
//const char c = ' ';
//const char* cc = " ";
//char buf[64];
//char16_t* buf16 = (char16_t*)u"foo16";
XString x1("a"_XS);
XString x2("b"_XS);
XStringW xw1("c"_XS);
char c = 1;
int ii = sizeof(size_t);
2020-04-25 11:59:07 +02:00
unsigned long long ull = 1;
unsigned long long ll = 3;
xw1.dataSized(c);
xw1.dataSized(ii);
xw1.dataSized(ull);
xw1.dataSized(ll);
//auto x3 = xw1 = x1;
//func_test(x3);
2020-04-05 14:25:39 +02:00
//
2020-04-23 15:20:48 +02:00
//XStringAbstract__is_char_st<decltype(buf16)> a;
//printf("a.v()=%d\n", a.v());
//XStringW sw1 = buf16;
//std::is_array<decltype(buf)> b;
//XStringAbstract__enable_if_t<is_char(decltype(c))>::type a;
//printf("%ls", XStringW().takeValueFrom(" ").s());
//func_test(XStringW().takeValueFrom(" "));
// testDefaultCtor<XString>("XString");
// XString16 a = u"toto"_XS16;
const char* utf8 = "ギ"; (void)utf8;
size_t utf8_size = sizeof("ギ") - 1; (void)utf8_size; // this char is 6 bytes long !
const wchar_t* utfw = L"ギ"; (void)utfw;
size_t utfw_size = sizeof(L"ギ") - 1; (void)utfw_size; // this char is 6 bytes long !
const char16_t* utf16 = u"ギ"; (void)utf16;
size_t utf16_size = sizeof(u"ギ") - 1; (void)utf16_size; // this char is 6 bytes long !
const char32_t* utf32 = U"ギ"; (void)utf32;
size_t utf32_size = sizeof(U"ギ") - 1; (void)utf32_size; // this char is 6 bytes long !
2020-04-23 15:20:48 +02:00
//size_t size = sizeof("ꇉ")-1; // this char is 3 bytes long
//size_t size = sizeof("伽")-1; // this char is 3 bytes long
//size_t size = sizeof("楘")-1; // this char is 3 bytes long
//XString str = "ギꇉ伽楘"_XS;
//char* s = str.data(42);
2020-04-25 11:59:07 +02:00
//size_t size1 = sizeof("В")-1;
//size_t size2 = sizeof("ы")-1;
//size_t size3 = sizeof("х")-1;
//size_t size4 = sizeof("о")-1;
//size_t size5 = sizeof("д")-1;
#ifdef _MSC_VER
//SetConsoleOutputCP(65001);
#endif
2020-04-25 13:33:01 +02:00
//
//printf("%s", "Выход \n");
//XString ddd = "Выход "_XS;
//printf(" xstring %s, asize=%zu, sizeinbyte=%zu sizeof=%zu lastcharat=%zu\n", ddd.c_str(), ddd.allocatedSize(), ddd.sizeInBytes(), sizeof(ddd), ddd.indexOf(ddd.lastChar()));
//
//TestString<char> ts1 = TestString<char>(nbchar("Выход "), "Выход ", nbchar(PREFIX_U("Выход ")), PREFIX_U("Выход "));
//testlastChar_<XString>(ts1);
2020-04-25 11:59:07 +02:00
2020-04-24 11:30:09 +02:00
//teststrncpy_<XString>("utf8", testStringMultiCodedArray[1].utf8, testStringMultiCodedArray[1].wchar);
//testindexOf(XString, utf8, utf16);
2020-04-25 13:33:01 +02:00
//testCompare(XString, utf8, utf16);
2020-04-24 11:30:09 +02:00
//testindexOf_<XString>(testStringMultiCoded4CaseArray[0].utf8);
2020-04-27 11:50:49 +02:00
//const char* p1 = "foo/bar"; // basename returns bar
//const char* p1 = "foo/"; // basename returns foo
//const char* p1 = "foo//"; // basename returns foo
//const char* p1 = "foo///"; // basename returns foo
//const char* p1 = ""; // basename returns "."
//const char* p1 = " foo/bar "; // basename returns "bar "
//const char* p1 = " foo "; // basename returns " foo "
//const char* p1 = " "; // basename returns " "
//const char* p2 = basename((char*)p1);
2020-04-23 15:20:48 +02:00
2020-04-24 11:30:09 +02:00
// TEST_ALL_CLASSES(testDefaultCtor, __TEST0);
// TEST_ALL_CLASSES(testEmpty, __TEST0);
2020-04-27 11:50:49 +02:00
// TEST_ALL_CLASSES(testTakeValueFrom, TEST_ALL_UTF);
2020-04-24 11:30:09 +02:00
// TEST_ALL_CLASSES(testchar32At, TEST_ALL_INTEGRAL);
// TEST_ALL_CLASSES(testdataSized, TEST_ALL_INTEGRAL);
//
2020-04-27 11:50:49 +02:00
// TEST_ALL_CLASSES(teststrncpy, TEST_ALL_UTF); // 26944 tests
// TEST_ALL_CLASSES(teststrcat, TEST_ALL_UTF_ALL_UTF);
2020-04-24 11:30:09 +02:00
// TEST_ALL_CLASSES(teststrncat, TEST_ALL_UTF_ALL_UTF); // 2101632 tests
//
2020-04-27 11:50:49 +02:00
TEST_ALL_CLASSES(testSubString, __TEST0);
2020-04-25 13:33:01 +02:00
// TEST_ALL_CLASSES(testCompare, TEST_ALL_UTF);
// TEST_ALL_CLASSES(testindexOf, TEST_ALL_UTF);
//
// TEST_ALL_CLASSES(testlastChar, __TEST0);
TEST_ALL_CLASSES(testtrim, __TEST0);
TEST_ALL_CLASSES(teststartWith, __TEST0);
2020-04-27 11:50:49 +02:00
TEST_ALL_CLASSES(testbasename, __TEST0);
2020-04-25 11:59:07 +02:00
2020-04-23 15:20:48 +02:00
2020-04-05 14:25:39 +02:00
//
2020-04-23 15:20:48 +02:00
//// str2.insert(1, str);
2020-04-05 14:25:39 +02:00
//
2020-04-24 11:30:09 +02:00
// str2.ssprintf("%c", 'a'); // signle UTF8 ascii char
2020-04-23 15:20:48 +02:00
// if ( str2 != L"a" ) return
// IMPORTANT : you can't pass a litteral char in a vararg function with Visual Studio (Microsoft strikes again :-).
// At least, you got a warning C4066
// IMPORTANT2 : Litteral string containing UTF16 char are WRONG. And you don't get a warning !!! If litteral is only ascii, it's ok.
// Maybe it's compilation option but I didn't find them.
2020-03-12 15:40:38 +01:00
2020-04-23 15:20:48 +02:00
#ifdef JIEF_DEBUG
if ( nbTestFailed == 0 ) printf("All %d tests succeeded.\n", nbTest);
2020-04-24 11:30:09 +02:00
else printf("%d tests succeeded out of %d.\n", nbTest-nbTestFailed, nbTest);
2020-04-23 15:20:48 +02:00
#endif
2020-04-24 11:30:09 +02:00
return nbTestFailed > 0;
2020-03-12 15:40:38 +01:00
}