#include "ZUnitTest.hpp" //Hijack the assert #define ZSTL_ASSERT(condition, message) SST_OS_RuntimeAssert(condition, message) #include #include static const char* test_Constructors(); static const char* test_AbsoluteIndex(); static const char* test_Allocator(); static const char* test_Array(); static const char* test_At(); static const char* test_Back(); static const char* test_Capacity(); static const char* test_Clear(); static const char* test_Clear_With_Capacity(); static const char* test_Compare_To_Array(); static const char* test_Compare_To_ZString(); static const char* test_Copy(); static const char* test_Data(); static const char* test_Empty(); static const char* test_Equals_To_Array(); static const char* test_Equals_To_ZString(); static const char* test_Erase(); static const char* test_Erase_Substring(); static const char* test_Front(); static const char* test_Hash(); static const char* test_Insert(); static const char* test_Length(); static const char* test_OperatorPlus(); static const char* test_PopBack(); static const char* test_PopFront(); static const char* test_PushBack(); static const char* test_PushFront(); static const char* test_Reserve(); static const char* test_Resize(); static const char* test_Resize_With_Fill(); static const char* test_Swap(); ZUnitTest ZBasicStringUnitTests[] = { { "ZBasicString: Constructors", test_Constructors }, { "ZBasicString: AbsoluteIndex", test_AbsoluteIndex }, { "ZBasicString: Allocator", test_Allocator }, { "ZBasicString: Array", test_Array }, { "ZBasicString: At", test_At }, { "ZBasicString: Back", test_Back }, { "ZBasicString: Capacity", test_Capacity }, { "ZBasicString: Clear", test_Clear }, { "ZBasicString: Clear with capacity", test_Clear_With_Capacity }, { "ZBasicString: Compare to array", test_Compare_To_Array }, { "ZBasicString: Compare to zstring", test_Compare_To_ZString }, { "ZBasicString: Copy", test_Copy }, { "ZBasicString: Data", test_Data }, { "ZBasicString: Empty", test_Empty }, { "ZBasicString: Equals to array", test_Equals_To_Array }, { "ZBasicString: Equals to zstring", test_Equals_To_ZString }, { "ZBasicString: Erase", test_Erase }, { "ZBasicString: Erase substring", test_Erase_Substring }, { "ZBasicString: Front", test_Front }, { "ZBasicString: Hash", test_Hash }, { "ZBasicString: Insert", test_Insert }, { "ZBasicString: Length", test_Length }, { "ZBasicString: OperatorPlus", test_OperatorPlus }, { "ZBasicString: PopBack", test_PopBack }, { "ZBasicString: PopFront", test_PopFront }, { "ZBasicString: PushBack", test_PushBack }, { "ZBasicString: PushFront", test_PushFront }, { "ZBasicString: Reserve", test_Reserve }, { "ZBasicString: Resize", test_Resize }, { "ZBasicString: Resize with fill", test_Resize_With_Fill }, { "ZBasicString: Swap", test_Swap } }; DECLARE_ZTESTBLOCK(ZBasicString); /*************************************************************************/ //We use this allocator to ensure that allocator-agnostic functions work correctly class CharArrayAllocator { public: char* Allocate(size_t _size) { return new (std::nothrow) char[_size]; } void Deallocate(char* _ptr, size_t _size) { (void)_size; delete[] _ptr; } }; /*************************************************************************/ static const char* test_Constructors() { const char* testData1 = "SuperAwesomeString"; const char* testData2 = "Super. Awesome. String."; ZBasicString<> string1; ZBasicString<> string2(testData1); ZBasicString<> string3(&testData1[5], 7); ZBasicString<> string4(string2); ZBasicString string5(testData2); ZBasicString<> string6(string5); TASSERT( strcmp(string1.Data(), "") == 0 && string1.Empty() == true && string1.Length() == 0, "Default string initialized with incorrect string!\n"); TASSERT( strcmp(string2.Data(), testData1) == 0 && string2.Empty() == false && string2.Length() == 18, "String initialized with incorrect string!\n"); TASSERT( strcmp(string3.Data(), "Awesome") == 0 && string3.Empty() == false && string3.Length() == 7, "Copy substring constructor initialized with incorrect string!\n"); TASSERT( strcmp(string4.Data(), testData1) == 0 && string4.Empty() == false && string4.Length() == 18, "Copy string constructor initialized with incorrect string!\n"); TASSERT( strcmp(string5.Data(), testData2) == 0 && string5.Empty() == false && string5.Length() == 23, "String constructor with custom allocator initialized with incorrect string!\n"); TASSERT( strcmp(string6.Data(), testData2) == 0 && string6.Empty() == false && string6.Length() == 23, "Copy string constructor with custom allocator initialized with incorrect string!\n"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_AbsoluteIndex() { ZBasicString<> string("1235"); TASSERT( string.BoundsCheck(0, string.Length()) == 0, "AbsoluteIndex() mismaps 0!\n"); TASSERT( string.BoundsCheck(1, string.Length()) == 1, "AbsoluteIndex() mismaps 1!\n"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Allocator() { // This is a pass-through for ZArray::Allocator(), so we don't need to do anything return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Array() { ZBasicString<> string("12345"); TASSERT( string.Array().Empty() == false, "Array() gave back empty backing array!\n"); TASSERT( string.Array().Back() == ZBASICSTRING_NULL_TERMINATOR, "Array() is not null terminated!\n"); TASSERT( string.Array().Size() == 6, "Array() gave back missized array!\n"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_At() { ZBasicString<> string("12345"); TASSERT( string.At(0) == '1', "At() returned incorrect character!\n"); TASSERT( string.At(1) == '2', "At() returned incorrect character!\n"); TASSERT( string.At(2) == '3', "At() returned incorrect character!\n"); TASSERT( string.At(3) == '4', "At() returned incorrect character!\n"); TASSERT( string.At(4) == '5', "At() returned incorrect character!\n"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Back() { ZBasicString<> string = ZBasicString<>("abcde"); ZBasicString<> string2 = ZBasicString<>("1"); ZBasicString<> string3 = ZBasicString<>(); TASSERT(string.Back() == 'e', "Back() returned wrong front character for string length > 2"); string.Back() = '!'; TASSERT(string.Back() == '!', "Back() returned the correct reference"); TASSERT(string2.Back() == '1', "Back() returned the wrong character for a string of length 1."); // Uncomment to test if Back() raises an assert on an empty string. // TASSERT(string3.Back() == '\0', "This should have asserted."); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Capacity() { ZBasicString > string("12435"); //NOTE: We can do this because (at the moment) constructing from a const char array // and that will init the capacity to just enough to hold it. TASSERT( string.Capacity() == 5, "Capacity() returned incorrect capacity!\n"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Clear() { ZBasicString<> string("12435"); TASSERT( string.Length() == 5, "String initialized with incorrect size!\n"); string.Clear(); TASSERT( string.Length() == 0, "Clear() did not set string length to 0!\n"); TASSERT( string.Equals("") == true, "Clear() did not set string to empty string!\n"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Clear_With_Capacity() { ZBasicString<> string("12435"); TASSERT( string.Length() == 5, "String initialized with incorrect size!\n"); string.Clear(16); TASSERT( string.Length() == 0, "Clear() did not set string length to 0!\n"); TASSERT( string.Capacity() == 16, "Clear() did not properly set new capacity of string!\n"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Compare_To_Array() { const char* str1 = "Hallo!"; const char* str2 = "Hello!"; const char* str3 = "Hullo!"; const char* str4 = "Goodbye!"; ZBasicString<> string("Hello!"); TASSERT( string.Compare(str3) < 0, "Compare() misclassified lexigraphically larger string!\n"); TASSERT( string.Compare(str2) == 0, "Compare() misclassified lexigraphically equal string!\n"); TASSERT( string.Compare(str1) > 0, "Compare() misclassified lexigraphically smaller string!\n"); TASSERT( string.Compare(str4) != 0, "Compare() misclassified different length different string!\n"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Compare_To_ZString() { ZBasicString<> str1("Hallo!"); ZBasicString<> str2("Hello!"); ZBasicString<> str3("Hullo!"); ZBasicString<> str4("Goodbye!"); ZBasicString<> str5("HELLO!"); ZBasicString<> string("Hello!"); TASSERT( string.Compare(str3) < 0, "Compare() misclassified lexigraphically larger string!"); TASSERT( string.Compare(str2) == 0, "Compare() misclassified lexigraphically equal string!"); TASSERT( string.Compare(str1) > 0, "Compare() misclassified lexigraphically smaller string!"); TASSERT( string.Compare(str4) != 0, "Compare() misclassified different length different string!"); TASSERT( string.Compare(str5) != 0, "Compare() is case-insensitive!"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Data() { ZBasicString<> string("Hello!"); TASSERT ( string.Data() != NULL, "Data() returned null pointer for valid string!\n"); TASSERT ( strcmp(string.Data(),"Hello!") == 0, "Data() returned null pointer for valid string!\n"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Equals_To_Array() { ZBasicString<> string("yes"); const char* yes = "yes"; const char* no = "no"; TASSERT( string.Equals(no) == false, "Equals() misclassified different char array string!\n"); TASSERT( string.Equals(yes) == true, "Equals() misclassified identical char array string!\n"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Equals_To_ZString() { ZBasicString<> str1("Hallo!"); ZBasicString<> str2("Hello!"); ZBasicString<> str3("Hello!"); TASSERT( str3.Equals(str1) == false, "Equals() miscompared two different ZBasicStrings!\n"); TASSERT( str3.Equals(str2) == true, "Equals() miscompared two equivalent ZBasicStrings!\n"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Copy() { ZBasicString<> emptyString(""); ZBasicString<> notEmptyString("notEmpty"); emptyString.Copy(notEmptyString); TASSERT( emptyString.Equals(notEmptyString), "Copy() failed to move data!\n"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Empty() { ZBasicString<> emptyString; ZBasicString<> emptyString2(""); ZBasicString<> notEmptyString("notEmpty"); TASSERT( emptyString.Empty() == true, "Empty() returned false on empty string from default constructor!\n"); TASSERT( emptyString2.Empty() == true, "Empty() returned false on empty string from empty constructor!\n"); TASSERT( notEmptyString.Empty() == false, "Empty() returned true on nonempty string!\n"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Erase() { ZBasicString<> string("abc"); ZBasicString<> string2("abc"); ZBasicString<> string3("abc"); ZBasicString<> string4("abc"); string.Erase(0); TASSERT(string.Equals("bc"), "Erase() failed to remove first character!\n"); string2.Erase(2); TASSERT(string2.Equals("ab"), "Erase() failed to remove last character!\n"); string3.Erase(1); TASSERT(string3.Equals("ac"), "Erase() failed to remove middle character!\n"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Erase_Substring() { ZBasicString<> string("abcde"); ZBasicString<> string2("abcde"); ZBasicString<> string3("abcde"); ZBasicString<> string4("abcde"); string.Erase(0,3); TASSERT(string.Equals("de") == true, "Erase() failed to remove first 3 characters!\n"); string2.Erase(2,5); TASSERT(string2.Equals("ab") == true, "Erase() failed to remove last 3 characters!\n"); string3.Erase(1,4); TASSERT(string3.Equals("ae") == true, "Erase() failed to remove middle 3 characters!\n"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Front() { ZBasicString<> string = ZBasicString<>("abcde"); ZBasicString<> string2 = ZBasicString<>("1"); ZBasicString<> string3 = ZBasicString<>(); TASSERT(string.Front() == 'a', "Front() returned wrong front character for string length > 2"); string.Front() = '!'; TASSERT(string.Front() == '!', "Front() returned the correct reference)"); TASSERT(string2.Front() == '1', "Front() returned the wrong character for a string of length 1."); //Uncomment to see if Front() asserts as advertised. //TASSERT(string3.Front() == '\0', "This should have asserted."); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Hash() { ZBasicString<> string("hashMe"); ZBasicString<> string2("hashMeToo"); TASSERT( string.Hash() == SST_Crypto_HashJ6("hashMe",6), "Hash() returned wrong hash on string!\n"); TASSERT( string.Hash() != string2.Hash(), "Hash() returned same hash on different strings!\n") return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Insert() { ZBasicString<> string1("hi"); ZBasicString<> string2("hi"); ZBasicString<> string3("hi"); ZBasicString<> string4("hi"); ZBasicString<> add("there"); string1.Insert(0,add); TASSERT( string1.Equals("therehi"), "Insert() returned wrong string on insert front\n"); string2.Insert(2,add); TASSERT( string2.Equals("hithere"), "Insert() returned wrong string on insert back\n"); string4.Insert(1,add); TASSERT( string4.Equals("htherei"), "Insert() returned wrong string on insert middle\n"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Length() { ZBasicString<> emptyString1(""); ZBasicString<> emptyString2; ZBasicString<> mystring("12345"); TASSERT( emptyString1.Length() == 0, "Length() reports nonempty on empty string!\n"); TASSERT( emptyString2.Length() == 0, "Length() reports nonempty on default string!\n"); TASSERT( mystring.Length() == 5, "Length() reports wrong length on string!\n"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_OperatorPlus() { /* ZBasicString operator + (const char *_lhs, const ZBasicString& _rhs) ZBasicString operator + (const ZBasicString& _lhs, const char *_rhs) */ ZBasicString<> string = ZBasicString<>("abcde"); ZBasicString<> emptyString = ZBasicString<>(); const char cString[5] = "1234"; const char emptyCString[1] = ""; TASSERT(string + cString == "abcde1234", "Right add of a c-string failed."); TASSERT(cString + string == "1234abcde", "Left add of a c-string failed"); TASSERT(cString + emptyString == "1234", "Right add of empty ZBasicString failed"); TASSERT(emptyString + cString == "1234", "Left add of empty ZBasicString failed"); TASSERT(string + emptyCString == "abcde", "Right add of empty c-string failed."); TASSERT(emptyCString + string == "abcde", "Left add of empty c-string failed."); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_PopBack() { ZBasicString<> string("apple"); char back; back = string.PopBack(); TASSERT ( (back == 'e') && string.Equals("appl"), "PopBack() returned incorrect character!\n"); back = string.PopBack(); TASSERT ( (back == 'l') && string.Equals("app"), "PopBack() returned incorrect character!\n"); back = string.PopBack(); TASSERT ( (back == 'p') && string.Equals("ap"), "PopBack() returned incorrect character!\n"); back = string.PopBack(); TASSERT ( (back == 'p') && string.Equals("a"), "PopBack() returned incorrect character!\n"); back = string.PopBack(); TASSERT ( (back == 'a') && string.Empty(), "PopBack() returned incorrect character!\n"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_PopFront() { ZBasicString<> string("apple"); char front; front = string.PopFront(); TASSERT ( (front == 'a') && string.Equals("pple"), "PopFront() returned incorrect character!\n"); front = string.PopFront(); TASSERT ( (front == 'p') && string.Equals("ple"), "PopFront() returned incorrect character!\n"); front = string.PopFront(); TASSERT ( (front == 'p') && string.Equals("le"), "PopFront() returned incorrect character!\n"); front = string.PopFront(); TASSERT ( (front == 'l') && string.Equals("e"), "PopFront() returned incorrect character!\n"); front = string.PopFront(); TASSERT ( (front == 'e') && string.Empty(), "PopFront() returned incorrect character!\n"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_PushBack() { ZBasicString<> string(""); string.PushBack('a'); TASSERT ( string.Equals("a"), "PushBack() returned broken string!\n"); string.PushBack('p'); TASSERT ( string.Equals("ap"), "PushBack() returned broken string!\n"); string.PushBack('p'); TASSERT ( string.Equals("app"), "PushBack() returned broken string!\n"); string.PushBack('l'); TASSERT ( string.Equals("appl"), "PushBack() returned broken string!\n"); string.PushBack('e'); TASSERT ( string.Equals("apple"), "PushBack() returned broken string!\n"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_PushFront() { ZBasicString<> string(""); string.PushFront('e'); TASSERT ( string.Equals("e"), "PushFront() returned broken string!\n"); string.PushFront('l'); TASSERT ( string.Equals("le"), "PushFront() returned broken string!\n"); string.PushFront('p'); TASSERT ( string.Equals("ple"), "PushFront() returned broken string!\n"); string.PushFront('p'); TASSERT ( string.Equals("pple"), "PushFront() returned broken string!\n"); string.PushFront('a'); TASSERT ( string.Equals("apple"), "PushFront() returned broken string!\n"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Reserve() { ZBasicString<> str("wat"); str.Reserve(34); TASSERT( str.Capacity() == 34, "Reserve() failed to set capacity to correct value!\n"); str.Reserve(43); TASSERT( str.Capacity() == 43, "Reserve() failed to set capacity to correct value!\n"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Resize() { ZBasicString<> str("wat"); TASSERT( str.Length() == 3, "Size() of string returned wrong size!\n"); str.Resize(2); TASSERT( str.Length() == 2, "Size(2) of string returned wrong size!\n"); str.Resize(4); TASSERT( str.Length() == 4, "Size(4) of string returned wrong size!\n"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Resize_With_Fill() { ZBasicString<> str(""); str.Resize(4,'a'); TASSERT( str.Equals("aaaa"), "Resize() did not fill new string correctly!\n"); str.Resize(2,'b'); TASSERT( str.Equals("aa"), "Resize() did resize the string correctly!\n"); return ZTEST_SUCCESS; } /*************************************************************************/ static const char* test_Swap() { ZBasicString<> str("hi"); ZBasicString<> str2("there"); str.Swap(str2); TASSERT( str.Equals("there") == true, "Swap did not replace first string!\n"); TASSERT( str2.Equals("hi") == true, "Swap did not replace second string!\n"); str.Swap(str2); TASSERT( str.Equals("hi") == true, "Swap did not put back first string!\n"); TASSERT( str2.Equals("there") == true, "Swap did not put back second string!\n"); return ZTEST_SUCCESS; } /*************************************************************************/