diff options
Diffstat (limited to 'indra/llcommon/tests/llstring_test.cpp')
-rw-r--r-- | indra/llcommon/tests/llstring_test.cpp | 1742 |
1 files changed, 871 insertions, 871 deletions
diff --git a/indra/llcommon/tests/llstring_test.cpp b/indra/llcommon/tests/llstring_test.cpp index 89ef5b3450..b18712b8e9 100644 --- a/indra/llcommon/tests/llstring_test.cpp +++ b/indra/llcommon/tests/llstring_test.cpp @@ -1,871 +1,871 @@ -/**
- * @file llstring_test.cpp
- * @author Adroit, Steve Linden, Tofu Linden
- * @date 2006-12-24
- * @brief Test cases of llstring.cpp
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "linden_common.h"
-
-#include <boost/assign/list_of.hpp>
-#include "../llstring.h"
-#include "StringVec.h" // must come BEFORE lltut.h
-#include "../test/lltut.h"
-
-using boost::assign::list_of;
-
-namespace tut
-{
- struct string_index
- {
- };
- typedef test_group<string_index> string_index_t;
- typedef string_index_t::object string_index_object_t;
- tut::string_index_t tut_string_index("LLString");
-
- template<> template<>
- void string_index_object_t::test<1>()
- {
- std::string llstr1;
- ensure("Empty std::string", (llstr1.size() == 0) && llstr1.empty());
-
- std::string llstr2("Hello");
- ensure("std::string = Hello", (!strcmp(llstr2.c_str(), "Hello")) && (llstr2.size() == 5) && !llstr2.empty());
-
- std::string llstr3(llstr2);
- ensure("std::string = std::string(std::string)", (!strcmp(llstr3.c_str(), "Hello")) && (llstr3.size() == 5) && !llstr3.empty());
-
- std::string str("Hello World");
- std::string llstr4(str, 6);
- ensure("std::string = std::string(s, size_type pos, size_type n = npos)", (!strcmp(llstr4.c_str(), "World")) && (llstr4.size() == 5) && !llstr4.empty());
-
- std::string llstr5(str, str.size());
- ensure("std::string = std::string(s, size_type pos, size_type n = npos)", (llstr5.size() == 0) && llstr5.empty());
-
- std::string llstr6(5, 'A');
- ensure("std::string = std::string(count, c)", (!strcmp(llstr6.c_str(), "AAAAA")) && (llstr6.size() == 5) && !llstr6.empty());
-
- std::string llstr7("Hello World", 5);
- ensure("std::string(s, n)", (!strcmp(llstr7.c_str(), "Hello")) && (llstr7.size() == 5) && !llstr7.empty());
-
- std::string llstr8("Hello World", 6, 5);
- ensure("std::string(s, n, count)", (!strcmp(llstr8.c_str(), "World")) && (llstr8.size() == 5) && !llstr8.empty());
-
- std::string llstr9("Hello World", sizeof("Hello World")-1, 5); // go past end
- ensure("std::string(s, n, count) goes past end", (llstr9.size() == 0) && llstr9.empty());
- }
-
- template<> template<>
- void string_index_object_t::test<3>()
- {
- std::string str("Len=5");
- ensure("isValidIndex failed", LLStringUtil::isValidIndex(str, 0) == true &&
- LLStringUtil::isValidIndex(str, 5) == true &&
- LLStringUtil::isValidIndex(str, 6) == false);
-
- std::string str1;
- ensure("isValidIndex failed fo rempty string", LLStringUtil::isValidIndex(str1, 0) == false);
- }
-
- template<> template<>
- void string_index_object_t::test<4>()
- {
- std::string str_val(" Testing the extra whitespaces ");
- LLStringUtil::trimHead(str_val);
- ensure_equals("1: trimHead failed", str_val, "Testing the extra whitespaces ");
-
- std::string str_val1("\n\t\r\n Testing the extra whitespaces ");
- LLStringUtil::trimHead(str_val1);
- ensure_equals("2: trimHead failed", str_val1, "Testing the extra whitespaces ");
- }
-
- template<> template<>
- void string_index_object_t::test<5>()
- {
- std::string str_val(" Testing the extra whitespaces ");
- LLStringUtil::trimTail(str_val);
- ensure_equals("1: trimTail failed", str_val, " Testing the extra whitespaces");
-
- std::string str_val1("\n Testing the extra whitespaces \n\t\r\n ");
- LLStringUtil::trimTail(str_val1);
- ensure_equals("2: trimTail failed", str_val1, "\n Testing the extra whitespaces");
- }
-
-
- template<> template<>
- void string_index_object_t::test<6>()
- {
- std::string str_val(" \t \r Testing the extra \r\n whitespaces \n \t ");
- LLStringUtil::trim(str_val);
- ensure_equals("1: trim failed", str_val, "Testing the extra \r\n whitespaces");
- }
-
- template<> template<>
- void string_index_object_t::test<7>()
- {
- std::string str("Second LindenLabs");
- LLStringUtil::truncate(str, 6);
- ensure_equals("1: truncate", str, "Second");
-
- // further truncate more than the length
- LLStringUtil::truncate(str, 0);
- ensure_equals("2: truncate", str, "");
- }
-
- template<> template<>
- void string_index_object_t::test<8>()
- {
- std::string str_val("SecondLife Source");
- LLStringUtil::toUpper(str_val);
- ensure_equals("toUpper failed", str_val, "SECONDLIFE SOURCE");
- }
-
- template<> template<>
- void string_index_object_t::test<9>()
- {
- std::string str_val("SecondLife Source");
- LLStringUtil::toLower(str_val);
- ensure_equals("toLower failed", str_val, "secondlife source");
- }
-
- template<> template<>
- void string_index_object_t::test<10>()
- {
- std::string str_val("Second");
- ensure("1. isHead failed", LLStringUtil::isHead(str_val, "SecondLife Source") == true);
- ensure("2. isHead failed", LLStringUtil::isHead(str_val, " SecondLife Source") == false);
- std::string str_val2("");
- ensure("3. isHead failed", LLStringUtil::isHead(str_val2, "") == false);
- }
-
- template<> template<>
- void string_index_object_t::test<11>()
- {
- std::string str_val("Hello.\n\n Lindenlabs. \n This is \na simple test.\n");
- std::string orig_str_val(str_val);
- LLStringUtil::addCRLF(str_val);
- ensure_equals("addCRLF failed", str_val, "Hello.\r\n\r\n Lindenlabs. \r\n This is \r\na simple test.\r\n");
- LLStringUtil::removeCRLF(str_val);
- ensure_equals("removeCRLF failed", str_val, orig_str_val);
- }
-
- template<> template<>
- void string_index_object_t::test<12>()
- {
- std::string str_val("Hello.\n\n\t \t Lindenlabs. \t\t");
- std::string orig_str_val(str_val);
- LLStringUtil::replaceTabsWithSpaces(str_val, 1);
- ensure_equals("replaceTabsWithSpaces failed", str_val, "Hello.\n\n Lindenlabs. ");
- LLStringUtil::replaceTabsWithSpaces(orig_str_val, 0);
- ensure_equals("replaceTabsWithSpaces failed for 0", orig_str_val, "Hello.\n\n Lindenlabs. ");
-
- str_val = "\t\t\t\t";
- LLStringUtil::replaceTabsWithSpaces(str_val, 0);
- ensure_equals("replaceTabsWithSpaces failed for all tabs", str_val, "");
- }
-
- template<> template<>
- void string_index_object_t::test<13>()
- {
- std::string str_val("Hello.\n\n\t\t\r\nLindenlabsX.");
- LLStringUtil::replaceNonstandardASCII(str_val, 'X');
- ensure_equals("replaceNonstandardASCII failed", str_val, "Hello.\n\nXXX\nLindenlabsX.");
- }
-
- template<> template<>
- void string_index_object_t::test<14>()
- {
- std::string str_val("Hello.\n\t\r\nABCDEFGHIABABAB");
- LLStringUtil::replaceChar(str_val, 'A', 'X');
- ensure_equals("1: replaceChar failed", str_val, "Hello.\n\t\r\nXBCDEFGHIXBXBXB");
- std::string str_val1("Hello.\n\t\r\nABCDEFGHIABABAB");
- }
-
- template<> template<>
- void string_index_object_t::test<15>()
- {
- std::string str_val("Hello.\n\r\t");
- ensure("containsNonprintable failed", LLStringUtil::containsNonprintable(str_val) == true);
-
- str_val = "ABC ";
- ensure("containsNonprintable failed", LLStringUtil::containsNonprintable(str_val) == false);
- }
-
- template<> template<>
- void string_index_object_t::test<16>()
- {
- std::string str_val("Hello.\n\r\t Again!");
- LLStringUtil::stripNonprintable(str_val);
- ensure_equals("stripNonprintable failed", str_val, "Hello. Again!");
-
- str_val = "\r\n\t\t";
- LLStringUtil::stripNonprintable(str_val);
- ensure_equals("stripNonprintable resulting in empty string failed", str_val, "");
-
- str_val = "";
- LLStringUtil::stripNonprintable(str_val);
- ensure_equals("stripNonprintable of empty string resulting in empty string failed", str_val, "");
- }
-
- template<> template<>
- void string_index_object_t::test<17>()
- {
- bool value;
- std::string str_val("1");
- ensure("convertToBOOL 1 failed", LLStringUtil::convertToBOOL(str_val, value) && value);
- str_val = "T";
- ensure("convertToBOOL T failed", LLStringUtil::convertToBOOL(str_val, value) && value);
- str_val = "t";
- ensure("convertToBOOL t failed", LLStringUtil::convertToBOOL(str_val, value) && value);
- str_val = "TRUE";
- ensure("convertToBOOL TRUE failed", LLStringUtil::convertToBOOL(str_val, value) && value);
- str_val = "True";
- ensure("convertToBOOL True failed", LLStringUtil::convertToBOOL(str_val, value) && value);
- str_val = "true";
- ensure("convertToBOOL true failed", LLStringUtil::convertToBOOL(str_val, value) && value);
-
- str_val = "0";
- ensure("convertToBOOL 0 failed", LLStringUtil::convertToBOOL(str_val, value) && !value);
- str_val = "F";
- ensure("convertToBOOL F failed", LLStringUtil::convertToBOOL(str_val, value) && !value);
- str_val = "f";
- ensure("convertToBOOL f failed", LLStringUtil::convertToBOOL(str_val, value) && !value);
- str_val = "FALSE";
- ensure("convertToBOOL FASLE failed", LLStringUtil::convertToBOOL(str_val, value) && !value);
- str_val = "False";
- ensure("convertToBOOL False failed", LLStringUtil::convertToBOOL(str_val, value) && !value);
- str_val = "false";
- ensure("convertToBOOL false failed", LLStringUtil::convertToBOOL(str_val, value) && !value);
-
- str_val = "Tblah";
- ensure("convertToBOOL false failed", !LLStringUtil::convertToBOOL(str_val, value));
- }
-
- template<> template<>
- void string_index_object_t::test<18>()
- {
- U8 value;
- std::string str_val("255");
- ensure("1: convertToU8 failed", LLStringUtil::convertToU8(str_val, value) && value == 255);
-
- str_val = "0";
- ensure("2: convertToU8 failed", LLStringUtil::convertToU8(str_val, value) && value == 0);
-
- str_val = "-1";
- ensure("3: convertToU8 failed", !LLStringUtil::convertToU8(str_val, value));
-
- str_val = "256"; // bigger than MAX_U8
- ensure("4: convertToU8 failed", !LLStringUtil::convertToU8(str_val, value));
- }
-
- template<> template<>
- void string_index_object_t::test<19>()
- {
- S8 value;
- std::string str_val("127");
- ensure("1: convertToS8 failed", LLStringUtil::convertToS8(str_val, value) && value == 127);
-
- str_val = "0";
- ensure("2: convertToS8 failed", LLStringUtil::convertToS8(str_val, value) && value == 0);
-
- str_val = "-128";
- ensure("3: convertToS8 failed", LLStringUtil::convertToS8(str_val, value) && value == -128);
-
- str_val = "128"; // bigger than MAX_S8
- ensure("4: convertToS8 failed", !LLStringUtil::convertToS8(str_val, value));
-
- str_val = "-129";
- ensure("5: convertToS8 failed", !LLStringUtil::convertToS8(str_val, value));
- }
-
- template<> template<>
- void string_index_object_t::test<20>()
- {
- S16 value;
- std::string str_val("32767");
- ensure("1: convertToS16 failed", LLStringUtil::convertToS16(str_val, value) && value == 32767);
-
- str_val = "0";
- ensure("2: convertToS16 failed", LLStringUtil::convertToS16(str_val, value) && value == 0);
-
- str_val = "-32768";
- ensure("3: convertToS16 failed", LLStringUtil::convertToS16(str_val, value) && value == -32768);
-
- str_val = "32768";
- ensure("4: convertToS16 failed", !LLStringUtil::convertToS16(str_val, value));
-
- str_val = "-32769";
- ensure("5: convertToS16 failed", !LLStringUtil::convertToS16(str_val, value));
- }
-
- template<> template<>
- void string_index_object_t::test<21>()
- {
- U16 value;
- std::string str_val("65535"); //0xFFFF
- ensure("1: convertToU16 failed", LLStringUtil::convertToU16(str_val, value) && value == 65535);
-
- str_val = "0";
- ensure("2: convertToU16 failed", LLStringUtil::convertToU16(str_val, value) && value == 0);
-
- str_val = "-1";
- ensure("3: convertToU16 failed", !LLStringUtil::convertToU16(str_val, value));
-
- str_val = "65536";
- ensure("4: convertToU16 failed", !LLStringUtil::convertToU16(str_val, value));
- }
-
- template<> template<>
- void string_index_object_t::test<22>()
- {
- U32 value;
- std::string str_val("4294967295"); //0xFFFFFFFF
- ensure("1: convertToU32 failed", LLStringUtil::convertToU32(str_val, value) && value == 4294967295UL);
-
- str_val = "0";
- ensure("2: convertToU32 failed", LLStringUtil::convertToU32(str_val, value) && value == 0);
-
- str_val = "4294967296";
- ensure("3: convertToU32 failed", !LLStringUtil::convertToU32(str_val, value));
- }
-
- template<> template<>
- void string_index_object_t::test<23>()
- {
- S32 value;
- std::string str_val("2147483647"); //0x7FFFFFFF
- ensure("1: convertToS32 failed", LLStringUtil::convertToS32(str_val, value) && value == 2147483647);
-
- str_val = "0";
- ensure("2: convertToS32 failed", LLStringUtil::convertToS32(str_val, value) && value == 0);
-
- // Avoid "unary minus operator applied to unsigned type" warning on VC++. JC
- S32 min_val = -2147483647 - 1;
- str_val = "-2147483648";
- ensure("3: convertToS32 failed", LLStringUtil::convertToS32(str_val, value) && value == min_val);
-
- str_val = "2147483648";
- ensure("4: convertToS32 failed", !LLStringUtil::convertToS32(str_val, value));
-
- str_val = "-2147483649";
- ensure("5: convertToS32 failed", !LLStringUtil::convertToS32(str_val, value));
- }
-
- template<> template<>
- void string_index_object_t::test<24>()
- {
- F32 value;
- std::string str_val("2147483647"); //0x7FFFFFFF
- ensure("1: convertToF32 failed", LLStringUtil::convertToF32(str_val, value) && value == 2147483647);
-
- str_val = "0";
- ensure("2: convertToF32 failed", LLStringUtil::convertToF32(str_val, value) && value == 0);
-
- /* Need to find max/min F32 values
- str_val = "-2147483648";
- ensure("3: convertToF32 failed", LLStringUtil::convertToF32(str_val, value) && value == -2147483648);
-
- str_val = "2147483648";
- ensure("4: convertToF32 failed", !LLStringUtil::convertToF32(str_val, value));
-
- str_val = "-2147483649";
- ensure("5: convertToF32 failed", !LLStringUtil::convertToF32(str_val, value));
- */
- }
-
- template<> template<>
- void string_index_object_t::test<25>()
- {
- F64 value;
- std::string str_val("9223372036854775807"); //0x7FFFFFFFFFFFFFFF
- ensure("1: convertToF64 failed", LLStringUtil::convertToF64(str_val, value) && value == 9223372036854775807LL);
-
- str_val = "0";
- ensure("2: convertToF64 failed", LLStringUtil::convertToF64(str_val, value) && value == 0.0F);
-
- /* Need to find max/min F64 values
- str_val = "-2147483648";
- ensure("3: convertToF32 failed", LLStringUtil::convertToF32(str_val, value) && value == -2147483648);
-
- str_val = "2147483648";
- ensure("4: convertToF32 failed", !LLStringUtil::convertToF32(str_val, value));
-
- str_val = "-2147483649";
- ensure("5: convertToF32 failed", !LLStringUtil::convertToF32(str_val, value));
- */
- }
-
- template<> template<>
- void string_index_object_t::test<26>()
- {
- const char* str1 = NULL;
- const char* str2 = NULL;
-
- ensure("1: compareStrings failed", LLStringUtil::compareStrings(str1, str2) == 0);
- str2 = "A";
- ensure("2: compareStrings failed", LLStringUtil::compareStrings(str1, str2) > 0);
- ensure("3: compareStrings failed", LLStringUtil::compareStrings(str2, str1) < 0);
-
- str1 = "A is smaller than B";
- str2 = "B is greater than A";
- ensure("4: compareStrings failed", LLStringUtil::compareStrings(str1, str2) < 0);
-
- str2 = "A is smaller than B";
- ensure("5: compareStrings failed", LLStringUtil::compareStrings(str1, str2) == 0);
- }
-
- template<> template<>
- void string_index_object_t::test<27>()
- {
- const char* str1 = NULL;
- const char* str2 = NULL;
-
- ensure("1: compareInsensitive failed", LLStringUtil::compareInsensitive(str1, str2) == 0);
- str2 = "A";
- ensure("2: compareInsensitive failed", LLStringUtil::compareInsensitive(str1, str2) > 0);
- ensure("3: compareInsensitive failed", LLStringUtil::compareInsensitive(str2, str1) < 0);
-
- str1 = "A is equal to a";
- str2 = "a is EQUAL to A";
- ensure("4: compareInsensitive failed", LLStringUtil::compareInsensitive(str1, str2) == 0);
- }
-
- template<> template<>
- void string_index_object_t::test<28>()
- {
- std::string lhs_str("PROgraM12files");
- std::string rhs_str("PROgram12Files");
- ensure("compareDict 1 failed", LLStringUtil::compareDict(lhs_str, rhs_str) < 0);
- ensure("precedesDict 1 failed", LLStringUtil::precedesDict(lhs_str, rhs_str) == true);
-
- lhs_str = "PROgram12Files";
- rhs_str = "PROgram12Files";
- ensure("compareDict 2 failed", LLStringUtil::compareDict(lhs_str, rhs_str) == 0);
- ensure("precedesDict 2 failed", LLStringUtil::precedesDict(lhs_str, rhs_str) == false);
-
- lhs_str = "PROgram12Files";
- rhs_str = "PROgRAM12FILES";
- ensure("compareDict 3 failed", LLStringUtil::compareDict(lhs_str, rhs_str) > 0);
- ensure("precedesDict 3 failed", LLStringUtil::precedesDict(lhs_str, rhs_str) == false);
- }
-
- template<> template<>
- void string_index_object_t::test<29>()
- {
- char str1[] = "First String...";
- char str2[100];
-
- LLStringUtil::copy(str2, str1, 100);
- ensure("LLStringUtil::copy with enough dest length failed", strcmp(str2, str1) == 0);
- LLStringUtil::copy(str2, str1, sizeof("First"));
- ensure("LLStringUtil::copy with less dest length failed", strcmp(str2, "First") == 0);
- }
-
- template<> template<>
- void string_index_object_t::test<30>()
- {
- std::string str1 = "This is the sentence...";
- std::string str2 = "This is the ";
- std::string str3 = "first ";
- std::string str4 = "This is the first sentence...";
- std::string str5 = "This is the sentence...first ";
- std::string dest;
-
- dest = str1;
- LLStringUtil::copyInto(dest, str3, str2.length());
- ensure("LLStringUtil::copyInto insert failed", dest == str4);
-
- dest = str1;
- LLStringUtil::copyInto(dest, str3, dest.length());
- ensure("LLStringUtil::copyInto append failed", dest == str5);
- }
-
- template<> template<>
- void string_index_object_t::test<31>()
- {
- std::string stripped;
-
- // Plain US ASCII text, including spaces and punctuation,
- // should not be altered.
- std::string simple_text = "Hello, world!";
- stripped = LLStringFn::strip_invalid_xml(simple_text);
- ensure("Simple text passed unchanged", stripped == simple_text);
-
- // Control characters should be removed
- // except for 0x09, 0x0a, 0x0d
- std::string control_chars;
- for (char c = 0x01; c < 0x20; c++)
- {
- control_chars.push_back(c);
- }
- std::string allowed_control_chars;
- allowed_control_chars.push_back( (char)0x09 );
- allowed_control_chars.push_back( (char)0x0a );
- allowed_control_chars.push_back( (char)0x0d );
-
- stripped = LLStringFn::strip_invalid_xml(control_chars);
- ensure("Only tab, LF, CR control characters allowed",
- stripped == allowed_control_chars);
-
- // UTF-8 should be passed intact, including high byte
- // characters. Try Francais (with C squiggle cedilla)
- std::string french = "Fran";
- french.push_back( (char)0xC3 );
- french.push_back( (char)0xA7 );
- french += "ais";
- stripped = LLStringFn::strip_invalid_xml( french );
- ensure("UTF-8 high byte text is allowed", french == stripped );
- }
-
- template<> template<>
- void string_index_object_t::test<32>()
- {
- // Test LLStringUtil::format() string interpolation
- LLStringUtil::format_map_t fmt_map;
- std::string s;
- int subcount;
-
- fmt_map["[TRICK1]"] = "[A]";
- fmt_map["[A]"] = "a";
- fmt_map["[B]"] = "b";
- fmt_map["[AAA]"] = "aaa";
- fmt_map["[BBB]"] = "bbb";
- fmt_map["[TRICK2]"] = "[A]";
- fmt_map["[EXPLOIT]"] = "!!!!!!!!!!!![EXPLOIT]!!!!!!!!!!!!";
- fmt_map["[KEYLONGER]"] = "short";
- fmt_map["[KEYSHORTER]"] = "Am I not a long string?";
- fmt_map["?"] = "?";
- fmt_map["[DELETE]"] = "";
- fmt_map["[]"] = "[]"; // doesn't do a substitution, but shouldn't crash either
-
- for (LLStringUtil::format_map_t::const_iterator iter = fmt_map.begin(); iter != fmt_map.end(); ++iter)
- {
- // Test when source string is entirely one key
- std::string s1 = (std::string)iter->first;
- std::string s2 = (std::string)iter->second;
- subcount = LLStringUtil::format(s1, fmt_map);
- ensure_equals("LLStringUtil::format: Raw interpolation result", s1, s2);
- if (s1 == "?" || s1 == "[]") // no interp expected
- {
- ensure_equals("LLStringUtil::format: Raw interpolation result count", 0, subcount);
- }
- else
- {
- ensure_equals("LLStringUtil::format: Raw interpolation result count", 1, subcount);
- }
- }
-
- for (LLStringUtil::format_map_t::const_iterator iter = fmt_map.begin(); iter != fmt_map.end(); ++iter)
- {
- // Test when source string is one key, duplicated
- std::string s1 = (std::string)iter->first;
- std::string s2 = (std::string)iter->second;
- s = s1 + s1 + s1 + s1;
- subcount = LLStringUtil::format(s, fmt_map);
- ensure_equals("LLStringUtil::format: Rawx4 interpolation result", s, s2 + s2 + s2 + s2);
- if (s1 == "?" || s1 == "[]") // no interp expected
- {
- ensure_equals("LLStringUtil::format: Rawx4 interpolation result count", 0, subcount);
- }
- else
- {
- ensure_equals("LLStringUtil::format: Rawx4 interpolation result count", 4, subcount);
- }
- }
-
- // Test when source string has no keys
- std::string srcs = "!!!!!!!!!!!!!!!!";
- s = srcs;
- subcount = LLStringUtil::format(s, fmt_map);
- ensure_equals("LLStringUtil::format: No key test result", s, srcs);
- ensure_equals("LLStringUtil::format: No key test result count", 0, subcount);
-
- // Test when source string has no keys and is empty
- std::string srcs3;
- s = srcs3;
- subcount = LLStringUtil::format(s, fmt_map);
- ensure("LLStringUtil::format: No key test3 result", s.empty());
- ensure_equals("LLStringUtil::format: No key test3 result count", 0, subcount);
-
- // Test a substitution where a key is substituted with blankness
- std::string srcs2 = "[DELETE]";
- s = srcs2;
- subcount = LLStringUtil::format(s, fmt_map);
- ensure("LLStringUtil::format: Delete key test2 result", s.empty());
- ensure_equals("LLStringUtil::format: Delete key test2 result count", 1, subcount);
-
- // Test an assorted substitution
- std::string srcs4 = "[TRICK1][A][B][AAA][BBB][TRICK2][KEYLONGER][KEYSHORTER]?[DELETE]";
- s = srcs4;
- subcount = LLStringUtil::format(s, fmt_map);
- ensure_equals("LLStringUtil::format: Assorted Test1 result", s, "[A]abaaabbb[A]shortAm I not a long string??");
- ensure_equals("LLStringUtil::format: Assorted Test1 result count", 9, subcount);
-
- // Test an assorted substitution
- std::string srcs5 = "[DELETE]?[KEYSHORTER][KEYLONGER][TRICK2][BBB][AAA][B][A][TRICK1]";
- s = srcs5;
- subcount = LLStringUtil::format(s, fmt_map);
- ensure_equals("LLStringUtil::format: Assorted Test2 result", s, "?Am I not a long string?short[A]bbbaaaba[A]");
- ensure_equals("LLStringUtil::format: Assorted Test2 result count", 9, subcount);
-
- // Test on nested brackets
- std::string srcs6 = "[[TRICK1]][[A]][[B]][[AAA]][[BBB]][[TRICK2]][[KEYLONGER]][[KEYSHORTER]]?[[DELETE]]";
- s = srcs6;
- subcount = LLStringUtil::format(s, fmt_map);
- ensure_equals("LLStringUtil::format: Assorted Test2 result", s, "[[A]][a][b][aaa][bbb][[A]][short][Am I not a long string?]?[]");
- ensure_equals("LLStringUtil::format: Assorted Test2 result count", 9, subcount);
-
-
- // Test an assorted substitution
- std::string srcs8 = "foo[DELETE]bar?";
- s = srcs8;
- subcount = LLStringUtil::format(s, fmt_map);
- ensure_equals("LLStringUtil::format: Assorted Test3 result", s, "foobar?");
- ensure_equals("LLStringUtil::format: Assorted Test3 result count", 1, subcount);
- }
-
- template<> template<>
- void string_index_object_t::test<33>()
- {
- // Test LLStringUtil::format() string interpolation
- LLStringUtil::format_map_t blank_fmt_map;
- std::string s;
- int subcount;
-
- // Test substituting out of a blank format_map
- std::string srcs6 = "12345";
- s = srcs6;
- subcount = LLStringUtil::format(s, blank_fmt_map);
- ensure_equals("LLStringUtil::format: Blankfmt Test1 result", s, "12345");
- ensure_equals("LLStringUtil::format: Blankfmt Test1 result count", 0, subcount);
-
- // Test substituting a blank string out of a blank format_map
- std::string srcs7;
- s = srcs7;
- subcount = LLStringUtil::format(s, blank_fmt_map);
- ensure("LLStringUtil::format: Blankfmt Test2 result", s.empty());
- ensure_equals("LLStringUtil::format: Blankfmt Test2 result count", 0, subcount);
- }
-
- template<> template<>
- void string_index_object_t::test<34>()
- {
- // Test that incorrect LLStringUtil::format() use does not explode.
- LLStringUtil::format_map_t nasty_fmt_map;
- std::string s;
- int subcount;
-
- nasty_fmt_map[""] = "never used"; // see, this is nasty.
-
- // Test substituting out of a nasty format_map
- std::string srcs6 = "12345";
- s = srcs6;
- subcount = LLStringUtil::format(s, nasty_fmt_map);
- ensure_equals("LLStringUtil::format: Nastyfmt Test1 result", s, "12345");
- ensure_equals("LLStringUtil::format: Nastyfmt Test1 result count", 0, subcount);
-
- // Test substituting a blank string out of a nasty format_map
- std::string srcs7;
- s = srcs7;
- subcount = LLStringUtil::format(s, nasty_fmt_map);
- ensure("LLStringUtil::format: Nastyfmt Test2 result", s.empty());
- ensure_equals("LLStringUtil::format: Nastyfmt Test2 result count", 0, subcount);
- }
-
- template<> template<>
- void string_index_object_t::test<35>()
- {
- // Make sure startsWith works
- std::string string("anybody in there?");
- std::string substr("anybody");
- ensure("startsWith works.", LLStringUtil::startsWith(string, substr));
- }
-
- template<> template<>
- void string_index_object_t::test<36>()
- {
- // Make sure startsWith correctly fails
- std::string string("anybody in there?");
- std::string substr("there");
- ensure("startsWith fails.", !LLStringUtil::startsWith(string, substr));
- }
-
- template<> template<>
- void string_index_object_t::test<37>()
- {
- // startsWith fails on empty strings
- std::string value("anybody in there?");
- std::string empty;
- ensure("empty string.", !LLStringUtil::startsWith(value, empty));
- ensure("empty substr.", !LLStringUtil::startsWith(empty, value));
- ensure("empty everything.", !LLStringUtil::startsWith(empty, empty));
- }
-
- template<> template<>
- void string_index_object_t::test<38>()
- {
- // Make sure endsWith works correctly
- std::string string("anybody in there?");
- std::string substr("there?");
- ensure("endsWith works.", LLStringUtil::endsWith(string, substr));
- }
-
- template<> template<>
- void string_index_object_t::test<39>()
- {
- // Make sure endsWith correctly fails
- std::string string("anybody in there?");
- std::string substr("anybody");
- ensure("endsWith fails.", !LLStringUtil::endsWith(string, substr));
- substr = "there";
- ensure("endsWith fails.", !LLStringUtil::endsWith(string, substr));
- substr = "ther?";
- ensure("endsWith fails.", !LLStringUtil::endsWith(string, substr));
- }
-
- template<> template<>
- void string_index_object_t::test<40>()
- {
- // endsWith fails on empty strings
- std::string value("anybody in there?");
- std::string empty;
- ensure("empty string.", !LLStringUtil::endsWith(value, empty));
- ensure("empty substr.", !LLStringUtil::endsWith(empty, value));
- ensure("empty everything.", !LLStringUtil::endsWith(empty, empty));
- }
-
- template<> template<>
- void string_index_object_t::test<41>()
- {
- set_test_name("getTokens(\"delims\")");
- ensure_equals("empty string", LLStringUtil::getTokens("", " "), StringVec());
- ensure_equals("only delims",
- LLStringUtil::getTokens(" \r\n ", " \r\n"), StringVec());
- ensure_equals("sequence of delims",
- LLStringUtil::getTokens(",,, one ,,,", ","), list_of("one"));
- // nat considers this a dubious implementation side effect, but I'd
- // hate to change it now...
- ensure_equals("noncontiguous tokens",
- LLStringUtil::getTokens(", ,, , one ,,,", ","), list_of("")("")("one"));
- ensure_equals("space-padded tokens",
- LLStringUtil::getTokens(", one , two ,", ","), list_of("one")("two"));
- ensure_equals("no delims", LLStringUtil::getTokens("one", ","), list_of("one"));
- }
-
- // Shorthand for verifying that getTokens() behaves the same when you
- // don't pass a string of escape characters, when you pass an empty string
- // (different overloads), and when you pass a string of characters that
- // aren't actually present.
- void ensure_getTokens(const std::string& desc,
- const std::string& string,
- const std::string& drop_delims,
- const std::string& keep_delims,
- const std::string& quotes,
- const std::vector<std::string>& expect)
- {
- ensure_equals(desc + " - no esc",
- LLStringUtil::getTokens(string, drop_delims, keep_delims, quotes),
- expect);
- ensure_equals(desc + " - empty esc",
- LLStringUtil::getTokens(string, drop_delims, keep_delims, quotes, ""),
- expect);
- ensure_equals(desc + " - unused esc",
- LLStringUtil::getTokens(string, drop_delims, keep_delims, quotes, "!"),
- expect);
- }
-
- void ensure_getTokens(const std::string& desc,
- const std::string& string,
- const std::string& drop_delims,
- const std::string& keep_delims,
- const std::vector<std::string>& expect)
- {
- ensure_getTokens(desc, string, drop_delims, keep_delims, "", expect);
- }
-
- template<> template<>
- void string_index_object_t::test<42>()
- {
- set_test_name("getTokens(\"delims\", etc.)");
- // Signatures to test in this method:
- // getTokens(string, drop_delims, keep_delims [, quotes [, escapes]])
- // If you omit keep_delims, you get the older function (test above).
-
- // cases like the getTokens(string, delims) tests above
- ensure_getTokens("empty string", "", " ", "", StringVec());
- ensure_getTokens("only delims",
- " \r\n ", " \r\n", "", StringVec());
- ensure_getTokens("sequence of delims",
- ",,, one ,,,", ", ", "", list_of("one"));
- // Note contrast with the case in the previous method
- ensure_getTokens("noncontiguous tokens",
- ", ,, , one ,,,", ", ", "", list_of("one"));
- ensure_getTokens("space-padded tokens",
- ", one , two ,", ", ", "",
- list_of("one")("two"));
- ensure_getTokens("no delims", "one", ",", "", list_of("one"));
-
- // drop_delims vs. keep_delims
- ensure_getTokens("arithmetic",
- " ab+def / xx* yy ", " ", "+-*/",
- list_of("ab")("+")("def")("/")("xx")("*")("yy"));
-
- // quotes
- ensure_getTokens("no quotes",
- "She said, \"Don't go.\"", " ", ",", "",
- list_of("She")("said")(",")("\"Don't")("go.\""));
- ensure_getTokens("quotes",
- "She said, \"Don't go.\"", " ", ",", "\"",
- list_of("She")("said")(",")("Don't go."));
- ensure_getTokens("quotes and delims",
- "run c:/'Documents and Settings'/someone", " ", "", "'",
- list_of("run")("c:/Documents and Settings/someone"));
- ensure_getTokens("unmatched quote",
- "baby don't leave", " ", "", "'",
- list_of("baby")("don't")("leave"));
- ensure_getTokens("adjacent quoted",
- "abc'def \"ghi'\"jkl' mno\"pqr", " ", "", "\"'",
- list_of("abcdef \"ghijkl' mnopqr"));
- ensure_getTokens("quoted empty string",
- "--set SomeVar ''", " ", "", "'",
- list_of("--set")("SomeVar")(""));
-
- // escapes
- // Don't use backslash as an escape for these tests -- you'll go nuts
- // between the C++ string scanner and getTokens() escapes. Test with
- // something else!
- ensure_equals("escaped delims",
- LLStringUtil::getTokens("^ a - dog^-gone^ phrase", " ", "-", "", "^"),
- list_of(" a")("-")("dog-gone phrase"));
- ensure_equals("escaped quotes",
- LLStringUtil::getTokens("say: 'this isn^'t w^orking'.", " ", "", "'", "^"),
- list_of("say:")("this isn't working."));
- ensure_equals("escaped escape",
- LLStringUtil::getTokens("want x^^2", " ", "", "", "^"),
- list_of("want")("x^2"));
- ensure_equals("escape at end",
- LLStringUtil::getTokens("it's^ up there^", " ", "", "'", "^"),
- list_of("it's up")("there^"));
- }
-}
+/** + * @file llstring_test.cpp + * @author Adroit, Steve Linden, Tofu Linden + * @date 2006-12-24 + * @brief Test cases of llstring.cpp + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include <boost/assign/list_of.hpp> +#include "../llstring.h" +#include "StringVec.h" // must come BEFORE lltut.h +#include "../test/lltut.h" + +using boost::assign::list_of; + +namespace tut +{ + struct string_index + { + }; + typedef test_group<string_index> string_index_t; + typedef string_index_t::object string_index_object_t; + tut::string_index_t tut_string_index("LLString"); + + template<> template<> + void string_index_object_t::test<1>() + { + std::string llstr1; + ensure("Empty std::string", (llstr1.size() == 0) && llstr1.empty()); + + std::string llstr2("Hello"); + ensure("std::string = Hello", (!strcmp(llstr2.c_str(), "Hello")) && (llstr2.size() == 5) && !llstr2.empty()); + + std::string llstr3(llstr2); + ensure("std::string = std::string(std::string)", (!strcmp(llstr3.c_str(), "Hello")) && (llstr3.size() == 5) && !llstr3.empty()); + + std::string str("Hello World"); + std::string llstr4(str, 6); + ensure("std::string = std::string(s, size_type pos, size_type n = npos)", (!strcmp(llstr4.c_str(), "World")) && (llstr4.size() == 5) && !llstr4.empty()); + + std::string llstr5(str, str.size()); + ensure("std::string = std::string(s, size_type pos, size_type n = npos)", (llstr5.size() == 0) && llstr5.empty()); + + std::string llstr6(5, 'A'); + ensure("std::string = std::string(count, c)", (!strcmp(llstr6.c_str(), "AAAAA")) && (llstr6.size() == 5) && !llstr6.empty()); + + std::string llstr7("Hello World", 5); + ensure("std::string(s, n)", (!strcmp(llstr7.c_str(), "Hello")) && (llstr7.size() == 5) && !llstr7.empty()); + + std::string llstr8("Hello World", 6, 5); + ensure("std::string(s, n, count)", (!strcmp(llstr8.c_str(), "World")) && (llstr8.size() == 5) && !llstr8.empty()); + + std::string llstr9("Hello World", sizeof("Hello World")-1, 5); // go past end + ensure("std::string(s, n, count) goes past end", (llstr9.size() == 0) && llstr9.empty()); + } + + template<> template<> + void string_index_object_t::test<3>() + { + std::string str("Len=5"); + ensure("isValidIndex failed", LLStringUtil::isValidIndex(str, 0) == true && + LLStringUtil::isValidIndex(str, 5) == true && + LLStringUtil::isValidIndex(str, 6) == false); + + std::string str1; + ensure("isValidIndex failed fo rempty string", LLStringUtil::isValidIndex(str1, 0) == false); + } + + template<> template<> + void string_index_object_t::test<4>() + { + std::string str_val(" Testing the extra whitespaces "); + LLStringUtil::trimHead(str_val); + ensure_equals("1: trimHead failed", str_val, "Testing the extra whitespaces "); + + std::string str_val1("\n\t\r\n Testing the extra whitespaces "); + LLStringUtil::trimHead(str_val1); + ensure_equals("2: trimHead failed", str_val1, "Testing the extra whitespaces "); + } + + template<> template<> + void string_index_object_t::test<5>() + { + std::string str_val(" Testing the extra whitespaces "); + LLStringUtil::trimTail(str_val); + ensure_equals("1: trimTail failed", str_val, " Testing the extra whitespaces"); + + std::string str_val1("\n Testing the extra whitespaces \n\t\r\n "); + LLStringUtil::trimTail(str_val1); + ensure_equals("2: trimTail failed", str_val1, "\n Testing the extra whitespaces"); + } + + + template<> template<> + void string_index_object_t::test<6>() + { + std::string str_val(" \t \r Testing the extra \r\n whitespaces \n \t "); + LLStringUtil::trim(str_val); + ensure_equals("1: trim failed", str_val, "Testing the extra \r\n whitespaces"); + } + + template<> template<> + void string_index_object_t::test<7>() + { + std::string str("Second LindenLabs"); + LLStringUtil::truncate(str, 6); + ensure_equals("1: truncate", str, "Second"); + + // further truncate more than the length + LLStringUtil::truncate(str, 0); + ensure_equals("2: truncate", str, ""); + } + + template<> template<> + void string_index_object_t::test<8>() + { + std::string str_val("SecondLife Source"); + LLStringUtil::toUpper(str_val); + ensure_equals("toUpper failed", str_val, "SECONDLIFE SOURCE"); + } + + template<> template<> + void string_index_object_t::test<9>() + { + std::string str_val("SecondLife Source"); + LLStringUtil::toLower(str_val); + ensure_equals("toLower failed", str_val, "secondlife source"); + } + + template<> template<> + void string_index_object_t::test<10>() + { + std::string str_val("Second"); + ensure("1. isHead failed", LLStringUtil::isHead(str_val, "SecondLife Source") == true); + ensure("2. isHead failed", LLStringUtil::isHead(str_val, " SecondLife Source") == false); + std::string str_val2(""); + ensure("3. isHead failed", LLStringUtil::isHead(str_val2, "") == false); + } + + template<> template<> + void string_index_object_t::test<11>() + { + std::string str_val("Hello.\n\n Lindenlabs. \n This is \na simple test.\n"); + std::string orig_str_val(str_val); + LLStringUtil::addCRLF(str_val); + ensure_equals("addCRLF failed", str_val, "Hello.\r\n\r\n Lindenlabs. \r\n This is \r\na simple test.\r\n"); + LLStringUtil::removeCRLF(str_val); + ensure_equals("removeCRLF failed", str_val, orig_str_val); + } + + template<> template<> + void string_index_object_t::test<12>() + { + std::string str_val("Hello.\n\n\t \t Lindenlabs. \t\t"); + std::string orig_str_val(str_val); + LLStringUtil::replaceTabsWithSpaces(str_val, 1); + ensure_equals("replaceTabsWithSpaces failed", str_val, "Hello.\n\n Lindenlabs. "); + LLStringUtil::replaceTabsWithSpaces(orig_str_val, 0); + ensure_equals("replaceTabsWithSpaces failed for 0", orig_str_val, "Hello.\n\n Lindenlabs. "); + + str_val = "\t\t\t\t"; + LLStringUtil::replaceTabsWithSpaces(str_val, 0); + ensure_equals("replaceTabsWithSpaces failed for all tabs", str_val, ""); + } + + template<> template<> + void string_index_object_t::test<13>() + { + std::string str_val("Hello.\n\n\t\t\r\nLindenlabsX."); + LLStringUtil::replaceNonstandardASCII(str_val, 'X'); + ensure_equals("replaceNonstandardASCII failed", str_val, "Hello.\n\nXXX\nLindenlabsX."); + } + + template<> template<> + void string_index_object_t::test<14>() + { + std::string str_val("Hello.\n\t\r\nABCDEFGHIABABAB"); + LLStringUtil::replaceChar(str_val, 'A', 'X'); + ensure_equals("1: replaceChar failed", str_val, "Hello.\n\t\r\nXBCDEFGHIXBXBXB"); + std::string str_val1("Hello.\n\t\r\nABCDEFGHIABABAB"); + } + + template<> template<> + void string_index_object_t::test<15>() + { + std::string str_val("Hello.\n\r\t"); + ensure("containsNonprintable failed", LLStringUtil::containsNonprintable(str_val) == true); + + str_val = "ABC "; + ensure("containsNonprintable failed", LLStringUtil::containsNonprintable(str_val) == false); + } + + template<> template<> + void string_index_object_t::test<16>() + { + std::string str_val("Hello.\n\r\t Again!"); + LLStringUtil::stripNonprintable(str_val); + ensure_equals("stripNonprintable failed", str_val, "Hello. Again!"); + + str_val = "\r\n\t\t"; + LLStringUtil::stripNonprintable(str_val); + ensure_equals("stripNonprintable resulting in empty string failed", str_val, ""); + + str_val = ""; + LLStringUtil::stripNonprintable(str_val); + ensure_equals("stripNonprintable of empty string resulting in empty string failed", str_val, ""); + } + + template<> template<> + void string_index_object_t::test<17>() + { + bool value; + std::string str_val("1"); + ensure("convertToBOOL 1 failed", LLStringUtil::convertToBOOL(str_val, value) && value); + str_val = "T"; + ensure("convertToBOOL T failed", LLStringUtil::convertToBOOL(str_val, value) && value); + str_val = "t"; + ensure("convertToBOOL t failed", LLStringUtil::convertToBOOL(str_val, value) && value); + str_val = "TRUE"; + ensure("convertToBOOL TRUE failed", LLStringUtil::convertToBOOL(str_val, value) && value); + str_val = "True"; + ensure("convertToBOOL True failed", LLStringUtil::convertToBOOL(str_val, value) && value); + str_val = "true"; + ensure("convertToBOOL true failed", LLStringUtil::convertToBOOL(str_val, value) && value); + + str_val = "0"; + ensure("convertToBOOL 0 failed", LLStringUtil::convertToBOOL(str_val, value) && !value); + str_val = "F"; + ensure("convertToBOOL F failed", LLStringUtil::convertToBOOL(str_val, value) && !value); + str_val = "f"; + ensure("convertToBOOL f failed", LLStringUtil::convertToBOOL(str_val, value) && !value); + str_val = "FALSE"; + ensure("convertToBOOL FASLE failed", LLStringUtil::convertToBOOL(str_val, value) && !value); + str_val = "False"; + ensure("convertToBOOL False failed", LLStringUtil::convertToBOOL(str_val, value) && !value); + str_val = "false"; + ensure("convertToBOOL false failed", LLStringUtil::convertToBOOL(str_val, value) && !value); + + str_val = "Tblah"; + ensure("convertToBOOL false failed", !LLStringUtil::convertToBOOL(str_val, value)); + } + + template<> template<> + void string_index_object_t::test<18>() + { + U8 value; + std::string str_val("255"); + ensure("1: convertToU8 failed", LLStringUtil::convertToU8(str_val, value) && value == 255); + + str_val = "0"; + ensure("2: convertToU8 failed", LLStringUtil::convertToU8(str_val, value) && value == 0); + + str_val = "-1"; + ensure("3: convertToU8 failed", !LLStringUtil::convertToU8(str_val, value)); + + str_val = "256"; // bigger than MAX_U8 + ensure("4: convertToU8 failed", !LLStringUtil::convertToU8(str_val, value)); + } + + template<> template<> + void string_index_object_t::test<19>() + { + S8 value; + std::string str_val("127"); + ensure("1: convertToS8 failed", LLStringUtil::convertToS8(str_val, value) && value == 127); + + str_val = "0"; + ensure("2: convertToS8 failed", LLStringUtil::convertToS8(str_val, value) && value == 0); + + str_val = "-128"; + ensure("3: convertToS8 failed", LLStringUtil::convertToS8(str_val, value) && value == -128); + + str_val = "128"; // bigger than MAX_S8 + ensure("4: convertToS8 failed", !LLStringUtil::convertToS8(str_val, value)); + + str_val = "-129"; + ensure("5: convertToS8 failed", !LLStringUtil::convertToS8(str_val, value)); + } + + template<> template<> + void string_index_object_t::test<20>() + { + S16 value; + std::string str_val("32767"); + ensure("1: convertToS16 failed", LLStringUtil::convertToS16(str_val, value) && value == 32767); + + str_val = "0"; + ensure("2: convertToS16 failed", LLStringUtil::convertToS16(str_val, value) && value == 0); + + str_val = "-32768"; + ensure("3: convertToS16 failed", LLStringUtil::convertToS16(str_val, value) && value == -32768); + + str_val = "32768"; + ensure("4: convertToS16 failed", !LLStringUtil::convertToS16(str_val, value)); + + str_val = "-32769"; + ensure("5: convertToS16 failed", !LLStringUtil::convertToS16(str_val, value)); + } + + template<> template<> + void string_index_object_t::test<21>() + { + U16 value; + std::string str_val("65535"); //0xFFFF + ensure("1: convertToU16 failed", LLStringUtil::convertToU16(str_val, value) && value == 65535); + + str_val = "0"; + ensure("2: convertToU16 failed", LLStringUtil::convertToU16(str_val, value) && value == 0); + + str_val = "-1"; + ensure("3: convertToU16 failed", !LLStringUtil::convertToU16(str_val, value)); + + str_val = "65536"; + ensure("4: convertToU16 failed", !LLStringUtil::convertToU16(str_val, value)); + } + + template<> template<> + void string_index_object_t::test<22>() + { + U32 value; + std::string str_val("4294967295"); //0xFFFFFFFF + ensure("1: convertToU32 failed", LLStringUtil::convertToU32(str_val, value) && value == 4294967295UL); + + str_val = "0"; + ensure("2: convertToU32 failed", LLStringUtil::convertToU32(str_val, value) && value == 0); + + str_val = "4294967296"; + ensure("3: convertToU32 failed", !LLStringUtil::convertToU32(str_val, value)); + } + + template<> template<> + void string_index_object_t::test<23>() + { + S32 value; + std::string str_val("2147483647"); //0x7FFFFFFF + ensure("1: convertToS32 failed", LLStringUtil::convertToS32(str_val, value) && value == 2147483647); + + str_val = "0"; + ensure("2: convertToS32 failed", LLStringUtil::convertToS32(str_val, value) && value == 0); + + // Avoid "unary minus operator applied to unsigned type" warning on VC++. JC + S32 min_val = -2147483647 - 1; + str_val = "-2147483648"; + ensure("3: convertToS32 failed", LLStringUtil::convertToS32(str_val, value) && value == min_val); + + str_val = "2147483648"; + ensure("4: convertToS32 failed", !LLStringUtil::convertToS32(str_val, value)); + + str_val = "-2147483649"; + ensure("5: convertToS32 failed", !LLStringUtil::convertToS32(str_val, value)); + } + + template<> template<> + void string_index_object_t::test<24>() + { + F32 value; + std::string str_val("2147483647"); //0x7FFFFFFF + ensure("1: convertToF32 failed", LLStringUtil::convertToF32(str_val, value) && value == 2147483647); + + str_val = "0"; + ensure("2: convertToF32 failed", LLStringUtil::convertToF32(str_val, value) && value == 0); + + /* Need to find max/min F32 values + str_val = "-2147483648"; + ensure("3: convertToF32 failed", LLStringUtil::convertToF32(str_val, value) && value == -2147483648); + + str_val = "2147483648"; + ensure("4: convertToF32 failed", !LLStringUtil::convertToF32(str_val, value)); + + str_val = "-2147483649"; + ensure("5: convertToF32 failed", !LLStringUtil::convertToF32(str_val, value)); + */ + } + + template<> template<> + void string_index_object_t::test<25>() + { + F64 value; + std::string str_val("9223372036854775807"); //0x7FFFFFFFFFFFFFFF + ensure("1: convertToF64 failed", LLStringUtil::convertToF64(str_val, value) && value == 9223372036854775807LL); + + str_val = "0"; + ensure("2: convertToF64 failed", LLStringUtil::convertToF64(str_val, value) && value == 0.0F); + + /* Need to find max/min F64 values + str_val = "-2147483648"; + ensure("3: convertToF32 failed", LLStringUtil::convertToF32(str_val, value) && value == -2147483648); + + str_val = "2147483648"; + ensure("4: convertToF32 failed", !LLStringUtil::convertToF32(str_val, value)); + + str_val = "-2147483649"; + ensure("5: convertToF32 failed", !LLStringUtil::convertToF32(str_val, value)); + */ + } + + template<> template<> + void string_index_object_t::test<26>() + { + const char* str1 = NULL; + const char* str2 = NULL; + + ensure("1: compareStrings failed", LLStringUtil::compareStrings(str1, str2) == 0); + str2 = "A"; + ensure("2: compareStrings failed", LLStringUtil::compareStrings(str1, str2) > 0); + ensure("3: compareStrings failed", LLStringUtil::compareStrings(str2, str1) < 0); + + str1 = "A is smaller than B"; + str2 = "B is greater than A"; + ensure("4: compareStrings failed", LLStringUtil::compareStrings(str1, str2) < 0); + + str2 = "A is smaller than B"; + ensure("5: compareStrings failed", LLStringUtil::compareStrings(str1, str2) == 0); + } + + template<> template<> + void string_index_object_t::test<27>() + { + const char* str1 = NULL; + const char* str2 = NULL; + + ensure("1: compareInsensitive failed", LLStringUtil::compareInsensitive(str1, str2) == 0); + str2 = "A"; + ensure("2: compareInsensitive failed", LLStringUtil::compareInsensitive(str1, str2) > 0); + ensure("3: compareInsensitive failed", LLStringUtil::compareInsensitive(str2, str1) < 0); + + str1 = "A is equal to a"; + str2 = "a is EQUAL to A"; + ensure("4: compareInsensitive failed", LLStringUtil::compareInsensitive(str1, str2) == 0); + } + + template<> template<> + void string_index_object_t::test<28>() + { + std::string lhs_str("PROgraM12files"); + std::string rhs_str("PROgram12Files"); + ensure("compareDict 1 failed", LLStringUtil::compareDict(lhs_str, rhs_str) < 0); + ensure("precedesDict 1 failed", LLStringUtil::precedesDict(lhs_str, rhs_str) == true); + + lhs_str = "PROgram12Files"; + rhs_str = "PROgram12Files"; + ensure("compareDict 2 failed", LLStringUtil::compareDict(lhs_str, rhs_str) == 0); + ensure("precedesDict 2 failed", LLStringUtil::precedesDict(lhs_str, rhs_str) == false); + + lhs_str = "PROgram12Files"; + rhs_str = "PROgRAM12FILES"; + ensure("compareDict 3 failed", LLStringUtil::compareDict(lhs_str, rhs_str) > 0); + ensure("precedesDict 3 failed", LLStringUtil::precedesDict(lhs_str, rhs_str) == false); + } + + template<> template<> + void string_index_object_t::test<29>() + { + char str1[] = "First String..."; + char str2[100]; + + LLStringUtil::copy(str2, str1, 100); + ensure("LLStringUtil::copy with enough dest length failed", strcmp(str2, str1) == 0); + LLStringUtil::copy(str2, str1, sizeof("First")); + ensure("LLStringUtil::copy with less dest length failed", strcmp(str2, "First") == 0); + } + + template<> template<> + void string_index_object_t::test<30>() + { + std::string str1 = "This is the sentence..."; + std::string str2 = "This is the "; + std::string str3 = "first "; + std::string str4 = "This is the first sentence..."; + std::string str5 = "This is the sentence...first "; + std::string dest; + + dest = str1; + LLStringUtil::copyInto(dest, str3, str2.length()); + ensure("LLStringUtil::copyInto insert failed", dest == str4); + + dest = str1; + LLStringUtil::copyInto(dest, str3, dest.length()); + ensure("LLStringUtil::copyInto append failed", dest == str5); + } + + template<> template<> + void string_index_object_t::test<31>() + { + std::string stripped; + + // Plain US ASCII text, including spaces and punctuation, + // should not be altered. + std::string simple_text = "Hello, world!"; + stripped = LLStringFn::strip_invalid_xml(simple_text); + ensure("Simple text passed unchanged", stripped == simple_text); + + // Control characters should be removed + // except for 0x09, 0x0a, 0x0d + std::string control_chars; + for (char c = 0x01; c < 0x20; c++) + { + control_chars.push_back(c); + } + std::string allowed_control_chars; + allowed_control_chars.push_back( (char)0x09 ); + allowed_control_chars.push_back( (char)0x0a ); + allowed_control_chars.push_back( (char)0x0d ); + + stripped = LLStringFn::strip_invalid_xml(control_chars); + ensure("Only tab, LF, CR control characters allowed", + stripped == allowed_control_chars); + + // UTF-8 should be passed intact, including high byte + // characters. Try Francais (with C squiggle cedilla) + std::string french = "Fran"; + french.push_back( (char)0xC3 ); + french.push_back( (char)0xA7 ); + french += "ais"; + stripped = LLStringFn::strip_invalid_xml( french ); + ensure("UTF-8 high byte text is allowed", french == stripped ); + } + + template<> template<> + void string_index_object_t::test<32>() + { + // Test LLStringUtil::format() string interpolation + LLStringUtil::format_map_t fmt_map; + std::string s; + int subcount; + + fmt_map["[TRICK1]"] = "[A]"; + fmt_map["[A]"] = "a"; + fmt_map["[B]"] = "b"; + fmt_map["[AAA]"] = "aaa"; + fmt_map["[BBB]"] = "bbb"; + fmt_map["[TRICK2]"] = "[A]"; + fmt_map["[EXPLOIT]"] = "!!!!!!!!!!!![EXPLOIT]!!!!!!!!!!!!"; + fmt_map["[KEYLONGER]"] = "short"; + fmt_map["[KEYSHORTER]"] = "Am I not a long string?"; + fmt_map["?"] = "?"; + fmt_map["[DELETE]"] = ""; + fmt_map["[]"] = "[]"; // doesn't do a substitution, but shouldn't crash either + + for (LLStringUtil::format_map_t::const_iterator iter = fmt_map.begin(); iter != fmt_map.end(); ++iter) + { + // Test when source string is entirely one key + std::string s1 = (std::string)iter->first; + std::string s2 = (std::string)iter->second; + subcount = LLStringUtil::format(s1, fmt_map); + ensure_equals("LLStringUtil::format: Raw interpolation result", s1, s2); + if (s1 == "?" || s1 == "[]") // no interp expected + { + ensure_equals("LLStringUtil::format: Raw interpolation result count", 0, subcount); + } + else + { + ensure_equals("LLStringUtil::format: Raw interpolation result count", 1, subcount); + } + } + + for (LLStringUtil::format_map_t::const_iterator iter = fmt_map.begin(); iter != fmt_map.end(); ++iter) + { + // Test when source string is one key, duplicated + std::string s1 = (std::string)iter->first; + std::string s2 = (std::string)iter->second; + s = s1 + s1 + s1 + s1; + subcount = LLStringUtil::format(s, fmt_map); + ensure_equals("LLStringUtil::format: Rawx4 interpolation result", s, s2 + s2 + s2 + s2); + if (s1 == "?" || s1 == "[]") // no interp expected + { + ensure_equals("LLStringUtil::format: Rawx4 interpolation result count", 0, subcount); + } + else + { + ensure_equals("LLStringUtil::format: Rawx4 interpolation result count", 4, subcount); + } + } + + // Test when source string has no keys + std::string srcs = "!!!!!!!!!!!!!!!!"; + s = srcs; + subcount = LLStringUtil::format(s, fmt_map); + ensure_equals("LLStringUtil::format: No key test result", s, srcs); + ensure_equals("LLStringUtil::format: No key test result count", 0, subcount); + + // Test when source string has no keys and is empty + std::string srcs3; + s = srcs3; + subcount = LLStringUtil::format(s, fmt_map); + ensure("LLStringUtil::format: No key test3 result", s.empty()); + ensure_equals("LLStringUtil::format: No key test3 result count", 0, subcount); + + // Test a substitution where a key is substituted with blankness + std::string srcs2 = "[DELETE]"; + s = srcs2; + subcount = LLStringUtil::format(s, fmt_map); + ensure("LLStringUtil::format: Delete key test2 result", s.empty()); + ensure_equals("LLStringUtil::format: Delete key test2 result count", 1, subcount); + + // Test an assorted substitution + std::string srcs4 = "[TRICK1][A][B][AAA][BBB][TRICK2][KEYLONGER][KEYSHORTER]?[DELETE]"; + s = srcs4; + subcount = LLStringUtil::format(s, fmt_map); + ensure_equals("LLStringUtil::format: Assorted Test1 result", s, "[A]abaaabbb[A]shortAm I not a long string??"); + ensure_equals("LLStringUtil::format: Assorted Test1 result count", 9, subcount); + + // Test an assorted substitution + std::string srcs5 = "[DELETE]?[KEYSHORTER][KEYLONGER][TRICK2][BBB][AAA][B][A][TRICK1]"; + s = srcs5; + subcount = LLStringUtil::format(s, fmt_map); + ensure_equals("LLStringUtil::format: Assorted Test2 result", s, "?Am I not a long string?short[A]bbbaaaba[A]"); + ensure_equals("LLStringUtil::format: Assorted Test2 result count", 9, subcount); + + // Test on nested brackets + std::string srcs6 = "[[TRICK1]][[A]][[B]][[AAA]][[BBB]][[TRICK2]][[KEYLONGER]][[KEYSHORTER]]?[[DELETE]]"; + s = srcs6; + subcount = LLStringUtil::format(s, fmt_map); + ensure_equals("LLStringUtil::format: Assorted Test2 result", s, "[[A]][a][b][aaa][bbb][[A]][short][Am I not a long string?]?[]"); + ensure_equals("LLStringUtil::format: Assorted Test2 result count", 9, subcount); + + + // Test an assorted substitution + std::string srcs8 = "foo[DELETE]bar?"; + s = srcs8; + subcount = LLStringUtil::format(s, fmt_map); + ensure_equals("LLStringUtil::format: Assorted Test3 result", s, "foobar?"); + ensure_equals("LLStringUtil::format: Assorted Test3 result count", 1, subcount); + } + + template<> template<> + void string_index_object_t::test<33>() + { + // Test LLStringUtil::format() string interpolation + LLStringUtil::format_map_t blank_fmt_map; + std::string s; + int subcount; + + // Test substituting out of a blank format_map + std::string srcs6 = "12345"; + s = srcs6; + subcount = LLStringUtil::format(s, blank_fmt_map); + ensure_equals("LLStringUtil::format: Blankfmt Test1 result", s, "12345"); + ensure_equals("LLStringUtil::format: Blankfmt Test1 result count", 0, subcount); + + // Test substituting a blank string out of a blank format_map + std::string srcs7; + s = srcs7; + subcount = LLStringUtil::format(s, blank_fmt_map); + ensure("LLStringUtil::format: Blankfmt Test2 result", s.empty()); + ensure_equals("LLStringUtil::format: Blankfmt Test2 result count", 0, subcount); + } + + template<> template<> + void string_index_object_t::test<34>() + { + // Test that incorrect LLStringUtil::format() use does not explode. + LLStringUtil::format_map_t nasty_fmt_map; + std::string s; + int subcount; + + nasty_fmt_map[""] = "never used"; // see, this is nasty. + + // Test substituting out of a nasty format_map + std::string srcs6 = "12345"; + s = srcs6; + subcount = LLStringUtil::format(s, nasty_fmt_map); + ensure_equals("LLStringUtil::format: Nastyfmt Test1 result", s, "12345"); + ensure_equals("LLStringUtil::format: Nastyfmt Test1 result count", 0, subcount); + + // Test substituting a blank string out of a nasty format_map + std::string srcs7; + s = srcs7; + subcount = LLStringUtil::format(s, nasty_fmt_map); + ensure("LLStringUtil::format: Nastyfmt Test2 result", s.empty()); + ensure_equals("LLStringUtil::format: Nastyfmt Test2 result count", 0, subcount); + } + + template<> template<> + void string_index_object_t::test<35>() + { + // Make sure startsWith works + std::string string("anybody in there?"); + std::string substr("anybody"); + ensure("startsWith works.", LLStringUtil::startsWith(string, substr)); + } + + template<> template<> + void string_index_object_t::test<36>() + { + // Make sure startsWith correctly fails + std::string string("anybody in there?"); + std::string substr("there"); + ensure("startsWith fails.", !LLStringUtil::startsWith(string, substr)); + } + + template<> template<> + void string_index_object_t::test<37>() + { + // startsWith fails on empty strings + std::string value("anybody in there?"); + std::string empty; + ensure("empty string.", !LLStringUtil::startsWith(value, empty)); + ensure("empty substr.", !LLStringUtil::startsWith(empty, value)); + ensure("empty everything.", !LLStringUtil::startsWith(empty, empty)); + } + + template<> template<> + void string_index_object_t::test<38>() + { + // Make sure endsWith works correctly + std::string string("anybody in there?"); + std::string substr("there?"); + ensure("endsWith works.", LLStringUtil::endsWith(string, substr)); + } + + template<> template<> + void string_index_object_t::test<39>() + { + // Make sure endsWith correctly fails + std::string string("anybody in there?"); + std::string substr("anybody"); + ensure("endsWith fails.", !LLStringUtil::endsWith(string, substr)); + substr = "there"; + ensure("endsWith fails.", !LLStringUtil::endsWith(string, substr)); + substr = "ther?"; + ensure("endsWith fails.", !LLStringUtil::endsWith(string, substr)); + } + + template<> template<> + void string_index_object_t::test<40>() + { + // endsWith fails on empty strings + std::string value("anybody in there?"); + std::string empty; + ensure("empty string.", !LLStringUtil::endsWith(value, empty)); + ensure("empty substr.", !LLStringUtil::endsWith(empty, value)); + ensure("empty everything.", !LLStringUtil::endsWith(empty, empty)); + } + + template<> template<> + void string_index_object_t::test<41>() + { + set_test_name("getTokens(\"delims\")"); + ensure_equals("empty string", LLStringUtil::getTokens("", " "), StringVec()); + ensure_equals("only delims", + LLStringUtil::getTokens(" \r\n ", " \r\n"), StringVec()); + ensure_equals("sequence of delims", + LLStringUtil::getTokens(",,, one ,,,", ","), list_of("one")); + // nat considers this a dubious implementation side effect, but I'd + // hate to change it now... + ensure_equals("noncontiguous tokens", + LLStringUtil::getTokens(", ,, , one ,,,", ","), list_of("")("")("one")); + ensure_equals("space-padded tokens", + LLStringUtil::getTokens(", one , two ,", ","), list_of("one")("two")); + ensure_equals("no delims", LLStringUtil::getTokens("one", ","), list_of("one")); + } + + // Shorthand for verifying that getTokens() behaves the same when you + // don't pass a string of escape characters, when you pass an empty string + // (different overloads), and when you pass a string of characters that + // aren't actually present. + void ensure_getTokens(const std::string& desc, + const std::string& string, + const std::string& drop_delims, + const std::string& keep_delims, + const std::string& quotes, + const std::vector<std::string>& expect) + { + ensure_equals(desc + " - no esc", + LLStringUtil::getTokens(string, drop_delims, keep_delims, quotes), + expect); + ensure_equals(desc + " - empty esc", + LLStringUtil::getTokens(string, drop_delims, keep_delims, quotes, ""), + expect); + ensure_equals(desc + " - unused esc", + LLStringUtil::getTokens(string, drop_delims, keep_delims, quotes, "!"), + expect); + } + + void ensure_getTokens(const std::string& desc, + const std::string& string, + const std::string& drop_delims, + const std::string& keep_delims, + const std::vector<std::string>& expect) + { + ensure_getTokens(desc, string, drop_delims, keep_delims, "", expect); + } + + template<> template<> + void string_index_object_t::test<42>() + { + set_test_name("getTokens(\"delims\", etc.)"); + // Signatures to test in this method: + // getTokens(string, drop_delims, keep_delims [, quotes [, escapes]]) + // If you omit keep_delims, you get the older function (test above). + + // cases like the getTokens(string, delims) tests above + ensure_getTokens("empty string", "", " ", "", StringVec()); + ensure_getTokens("only delims", + " \r\n ", " \r\n", "", StringVec()); + ensure_getTokens("sequence of delims", + ",,, one ,,,", ", ", "", list_of("one")); + // Note contrast with the case in the previous method + ensure_getTokens("noncontiguous tokens", + ", ,, , one ,,,", ", ", "", list_of("one")); + ensure_getTokens("space-padded tokens", + ", one , two ,", ", ", "", + list_of("one")("two")); + ensure_getTokens("no delims", "one", ",", "", list_of("one")); + + // drop_delims vs. keep_delims + ensure_getTokens("arithmetic", + " ab+def / xx* yy ", " ", "+-*/", + list_of("ab")("+")("def")("/")("xx")("*")("yy")); + + // quotes + ensure_getTokens("no quotes", + "She said, \"Don't go.\"", " ", ",", "", + list_of("She")("said")(",")("\"Don't")("go.\"")); + ensure_getTokens("quotes", + "She said, \"Don't go.\"", " ", ",", "\"", + list_of("She")("said")(",")("Don't go.")); + ensure_getTokens("quotes and delims", + "run c:/'Documents and Settings'/someone", " ", "", "'", + list_of("run")("c:/Documents and Settings/someone")); + ensure_getTokens("unmatched quote", + "baby don't leave", " ", "", "'", + list_of("baby")("don't")("leave")); + ensure_getTokens("adjacent quoted", + "abc'def \"ghi'\"jkl' mno\"pqr", " ", "", "\"'", + list_of("abcdef \"ghijkl' mnopqr")); + ensure_getTokens("quoted empty string", + "--set SomeVar ''", " ", "", "'", + list_of("--set")("SomeVar")("")); + + // escapes + // Don't use backslash as an escape for these tests -- you'll go nuts + // between the C++ string scanner and getTokens() escapes. Test with + // something else! + ensure_equals("escaped delims", + LLStringUtil::getTokens("^ a - dog^-gone^ phrase", " ", "-", "", "^"), + list_of(" a")("-")("dog-gone phrase")); + ensure_equals("escaped quotes", + LLStringUtil::getTokens("say: 'this isn^'t w^orking'.", " ", "", "'", "^"), + list_of("say:")("this isn't working.")); + ensure_equals("escaped escape", + LLStringUtil::getTokens("want x^^2", " ", "", "", "^"), + list_of("want")("x^2")); + ensure_equals("escape at end", + LLStringUtil::getTokens("it's^ up there^", " ", "", "'", "^"), + list_of("it's up")("there^")); + } +} |