PageRenderTime 30ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llcommon/tests/llstring_test.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 753 lines | 561 code | 115 blank | 77 comment | 111 complexity | a921848495f9aba721a88f16205b373c MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llstring_test.cpp
  3. * @author Adroit, Steve Linden, Tofu Linden
  4. * @date 2006-12-24
  5. * @brief Test cases of llstring.cpp
  6. *
  7. * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  8. * Second Life Viewer Source Code
  9. * Copyright (C) 2010, Linden Research, Inc.
  10. *
  11. * This library is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU Lesser General Public
  13. * License as published by the Free Software Foundation;
  14. * version 2.1 of the License only.
  15. *
  16. * This library is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  19. * Lesser General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU Lesser General Public
  22. * License along with this library; if not, write to the Free Software
  23. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  24. *
  25. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  26. * $/LicenseInfo$
  27. */
  28. #include "linden_common.h"
  29. #include "../test/lltut.h"
  30. #include "../llstring.h"
  31. namespace tut
  32. {
  33. struct string_index
  34. {
  35. };
  36. typedef test_group<string_index> string_index_t;
  37. typedef string_index_t::object string_index_object_t;
  38. tut::string_index_t tut_string_index("LLString");
  39. template<> template<>
  40. void string_index_object_t::test<1>()
  41. {
  42. std::string llstr1;
  43. ensure("Empty std::string", (llstr1.size() == 0) && llstr1.empty());
  44. std::string llstr2("Hello");
  45. ensure("std::string = Hello", (!strcmp(llstr2.c_str(), "Hello")) && (llstr2.size() == 5) && !llstr2.empty());
  46. std::string llstr3(llstr2);
  47. ensure("std::string = std::string(std::string)", (!strcmp(llstr3.c_str(), "Hello")) && (llstr3.size() == 5) && !llstr3.empty());
  48. std::string str("Hello World");
  49. std::string llstr4(str, 6);
  50. ensure("std::string = std::string(s, size_type pos, size_type n = npos)", (!strcmp(llstr4.c_str(), "World")) && (llstr4.size() == 5) && !llstr4.empty());
  51. std::string llstr5(str, str.size());
  52. ensure("std::string = std::string(s, size_type pos, size_type n = npos)", (llstr5.size() == 0) && llstr5.empty());
  53. std::string llstr6(5, 'A');
  54. ensure("std::string = std::string(count, c)", (!strcmp(llstr6.c_str(), "AAAAA")) && (llstr6.size() == 5) && !llstr6.empty());
  55. std::string llstr7("Hello World", 5);
  56. ensure("std::string(s, n)", (!strcmp(llstr7.c_str(), "Hello")) && (llstr7.size() == 5) && !llstr7.empty());
  57. std::string llstr8("Hello World", 6, 5);
  58. ensure("std::string(s, n, count)", (!strcmp(llstr8.c_str(), "World")) && (llstr8.size() == 5) && !llstr8.empty());
  59. std::string llstr9("Hello World", sizeof("Hello World")-1, 5); // go past end
  60. ensure("std::string(s, n, count) goes past end", (llstr9.size() == 0) && llstr9.empty());
  61. }
  62. template<> template<>
  63. void string_index_object_t::test<3>()
  64. {
  65. std::string str("Len=5");
  66. ensure("isValidIndex failed", LLStringUtil::isValidIndex(str, 0) == TRUE &&
  67. LLStringUtil::isValidIndex(str, 5) == TRUE &&
  68. LLStringUtil::isValidIndex(str, 6) == FALSE);
  69. std::string str1;
  70. ensure("isValidIndex failed fo rempty string", LLStringUtil::isValidIndex(str1, 0) == FALSE);
  71. }
  72. template<> template<>
  73. void string_index_object_t::test<4>()
  74. {
  75. std::string str_val(" Testing the extra whitespaces ");
  76. LLStringUtil::trimHead(str_val);
  77. ensure_equals("1: trimHead failed", str_val, "Testing the extra whitespaces ");
  78. std::string str_val1("\n\t\r\n Testing the extra whitespaces ");
  79. LLStringUtil::trimHead(str_val1);
  80. ensure_equals("2: trimHead failed", str_val1, "Testing the extra whitespaces ");
  81. }
  82. template<> template<>
  83. void string_index_object_t::test<5>()
  84. {
  85. std::string str_val(" Testing the extra whitespaces ");
  86. LLStringUtil::trimTail(str_val);
  87. ensure_equals("1: trimTail failed", str_val, " Testing the extra whitespaces");
  88. std::string str_val1("\n Testing the extra whitespaces \n\t\r\n ");
  89. LLStringUtil::trimTail(str_val1);
  90. ensure_equals("2: trimTail failed", str_val1, "\n Testing the extra whitespaces");
  91. }
  92. template<> template<>
  93. void string_index_object_t::test<6>()
  94. {
  95. std::string str_val(" \t \r Testing the extra \r\n whitespaces \n \t ");
  96. LLStringUtil::trim(str_val);
  97. ensure_equals("1: trim failed", str_val, "Testing the extra \r\n whitespaces");
  98. }
  99. template<> template<>
  100. void string_index_object_t::test<7>()
  101. {
  102. std::string str("Second LindenLabs");
  103. LLStringUtil::truncate(str, 6);
  104. ensure_equals("1: truncate", str, "Second");
  105. // further truncate more than the length
  106. LLStringUtil::truncate(str, 0);
  107. ensure_equals("2: truncate", str, "");
  108. }
  109. template<> template<>
  110. void string_index_object_t::test<8>()
  111. {
  112. std::string str_val("SecondLife Source");
  113. LLStringUtil::toUpper(str_val);
  114. ensure_equals("toUpper failed", str_val, "SECONDLIFE SOURCE");
  115. }
  116. template<> template<>
  117. void string_index_object_t::test<9>()
  118. {
  119. std::string str_val("SecondLife Source");
  120. LLStringUtil::toLower(str_val);
  121. ensure_equals("toLower failed", str_val, "secondlife source");
  122. }
  123. template<> template<>
  124. void string_index_object_t::test<10>()
  125. {
  126. std::string str_val("Second");
  127. ensure("1. isHead failed", LLStringUtil::isHead(str_val, "SecondLife Source") == TRUE);
  128. ensure("2. isHead failed", LLStringUtil::isHead(str_val, " SecondLife Source") == FALSE);
  129. std::string str_val2("");
  130. ensure("3. isHead failed", LLStringUtil::isHead(str_val2, "") == FALSE);
  131. }
  132. template<> template<>
  133. void string_index_object_t::test<11>()
  134. {
  135. std::string str_val("Hello.\n\n Lindenlabs. \n This is \na simple test.\n");
  136. std::string orig_str_val(str_val);
  137. LLStringUtil::addCRLF(str_val);
  138. ensure_equals("addCRLF failed", str_val, "Hello.\r\n\r\n Lindenlabs. \r\n This is \r\na simple test.\r\n");
  139. LLStringUtil::removeCRLF(str_val);
  140. ensure_equals("removeCRLF failed", str_val, orig_str_val);
  141. }
  142. template<> template<>
  143. void string_index_object_t::test<12>()
  144. {
  145. std::string str_val("Hello.\n\n\t \t Lindenlabs. \t\t");
  146. std::string orig_str_val(str_val);
  147. LLStringUtil::replaceTabsWithSpaces(str_val, 1);
  148. ensure_equals("replaceTabsWithSpaces failed", str_val, "Hello.\n\n Lindenlabs. ");
  149. LLStringUtil::replaceTabsWithSpaces(orig_str_val, 0);
  150. ensure_equals("replaceTabsWithSpaces failed for 0", orig_str_val, "Hello.\n\n Lindenlabs. ");
  151. str_val = "\t\t\t\t";
  152. LLStringUtil::replaceTabsWithSpaces(str_val, 0);
  153. ensure_equals("replaceTabsWithSpaces failed for all tabs", str_val, "");
  154. }
  155. template<> template<>
  156. void string_index_object_t::test<13>()
  157. {
  158. std::string str_val("Hello.\n\n\t\t\r\nLindenlabsX.");
  159. LLStringUtil::replaceNonstandardASCII(str_val, 'X');
  160. ensure_equals("replaceNonstandardASCII failed", str_val, "Hello.\n\nXXX\nLindenlabsX.");
  161. }
  162. template<> template<>
  163. void string_index_object_t::test<14>()
  164. {
  165. std::string str_val("Hello.\n\t\r\nABCDEFGHIABABAB");
  166. LLStringUtil::replaceChar(str_val, 'A', 'X');
  167. ensure_equals("1: replaceChar failed", str_val, "Hello.\n\t\r\nXBCDEFGHIXBXBXB");
  168. std::string str_val1("Hello.\n\t\r\nABCDEFGHIABABAB");
  169. }
  170. template<> template<>
  171. void string_index_object_t::test<15>()
  172. {
  173. std::string str_val("Hello.\n\r\t");
  174. ensure("containsNonprintable failed", LLStringUtil::containsNonprintable(str_val) == TRUE);
  175. str_val = "ABC ";
  176. ensure("containsNonprintable failed", LLStringUtil::containsNonprintable(str_val) == FALSE);
  177. }
  178. template<> template<>
  179. void string_index_object_t::test<16>()
  180. {
  181. std::string str_val("Hello.\n\r\t Again!");
  182. LLStringUtil::stripNonprintable(str_val);
  183. ensure_equals("stripNonprintable failed", str_val, "Hello. Again!");
  184. str_val = "\r\n\t\t";
  185. LLStringUtil::stripNonprintable(str_val);
  186. ensure_equals("stripNonprintable resulting in empty string failed", str_val, "");
  187. str_val = "";
  188. LLStringUtil::stripNonprintable(str_val);
  189. ensure_equals("stripNonprintable of empty string resulting in empty string failed", str_val, "");
  190. }
  191. template<> template<>
  192. void string_index_object_t::test<17>()
  193. {
  194. BOOL value;
  195. std::string str_val("1");
  196. ensure("convertToBOOL 1 failed", LLStringUtil::convertToBOOL(str_val, value) && value);
  197. str_val = "T";
  198. ensure("convertToBOOL T failed", LLStringUtil::convertToBOOL(str_val, value) && value);
  199. str_val = "t";
  200. ensure("convertToBOOL t failed", LLStringUtil::convertToBOOL(str_val, value) && value);
  201. str_val = "TRUE";
  202. ensure("convertToBOOL TRUE failed", LLStringUtil::convertToBOOL(str_val, value) && value);
  203. str_val = "True";
  204. ensure("convertToBOOL True failed", LLStringUtil::convertToBOOL(str_val, value) && value);
  205. str_val = "true";
  206. ensure("convertToBOOL true failed", LLStringUtil::convertToBOOL(str_val, value) && value);
  207. str_val = "0";
  208. ensure("convertToBOOL 0 failed", LLStringUtil::convertToBOOL(str_val, value) && !value);
  209. str_val = "F";
  210. ensure("convertToBOOL F failed", LLStringUtil::convertToBOOL(str_val, value) && !value);
  211. str_val = "f";
  212. ensure("convertToBOOL f failed", LLStringUtil::convertToBOOL(str_val, value) && !value);
  213. str_val = "FALSE";
  214. ensure("convertToBOOL FASLE failed", LLStringUtil::convertToBOOL(str_val, value) && !value);
  215. str_val = "False";
  216. ensure("convertToBOOL False failed", LLStringUtil::convertToBOOL(str_val, value) && !value);
  217. str_val = "false";
  218. ensure("convertToBOOL false failed", LLStringUtil::convertToBOOL(str_val, value) && !value);
  219. str_val = "Tblah";
  220. ensure("convertToBOOL false failed", !LLStringUtil::convertToBOOL(str_val, value));
  221. }
  222. template<> template<>
  223. void string_index_object_t::test<18>()
  224. {
  225. U8 value;
  226. std::string str_val("255");
  227. ensure("1: convertToU8 failed", LLStringUtil::convertToU8(str_val, value) && value == 255);
  228. str_val = "0";
  229. ensure("2: convertToU8 failed", LLStringUtil::convertToU8(str_val, value) && value == 0);
  230. str_val = "-1";
  231. ensure("3: convertToU8 failed", !LLStringUtil::convertToU8(str_val, value));
  232. str_val = "256"; // bigger than MAX_U8
  233. ensure("4: convertToU8 failed", !LLStringUtil::convertToU8(str_val, value));
  234. }
  235. template<> template<>
  236. void string_index_object_t::test<19>()
  237. {
  238. S8 value;
  239. std::string str_val("127");
  240. ensure("1: convertToS8 failed", LLStringUtil::convertToS8(str_val, value) && value == 127);
  241. str_val = "0";
  242. ensure("2: convertToS8 failed", LLStringUtil::convertToS8(str_val, value) && value == 0);
  243. str_val = "-128";
  244. ensure("3: convertToS8 failed", LLStringUtil::convertToS8(str_val, value) && value == -128);
  245. str_val = "128"; // bigger than MAX_S8
  246. ensure("4: convertToS8 failed", !LLStringUtil::convertToS8(str_val, value));
  247. str_val = "-129";
  248. ensure("5: convertToS8 failed", !LLStringUtil::convertToS8(str_val, value));
  249. }
  250. template<> template<>
  251. void string_index_object_t::test<20>()
  252. {
  253. S16 value;
  254. std::string str_val("32767");
  255. ensure("1: convertToS16 failed", LLStringUtil::convertToS16(str_val, value) && value == 32767);
  256. str_val = "0";
  257. ensure("2: convertToS16 failed", LLStringUtil::convertToS16(str_val, value) && value == 0);
  258. str_val = "-32768";
  259. ensure("3: convertToS16 failed", LLStringUtil::convertToS16(str_val, value) && value == -32768);
  260. str_val = "32768";
  261. ensure("4: convertToS16 failed", !LLStringUtil::convertToS16(str_val, value));
  262. str_val = "-32769";
  263. ensure("5: convertToS16 failed", !LLStringUtil::convertToS16(str_val, value));
  264. }
  265. template<> template<>
  266. void string_index_object_t::test<21>()
  267. {
  268. U16 value;
  269. std::string str_val("65535"); //0xFFFF
  270. ensure("1: convertToU16 failed", LLStringUtil::convertToU16(str_val, value) && value == 65535);
  271. str_val = "0";
  272. ensure("2: convertToU16 failed", LLStringUtil::convertToU16(str_val, value) && value == 0);
  273. str_val = "-1";
  274. ensure("3: convertToU16 failed", !LLStringUtil::convertToU16(str_val, value));
  275. str_val = "65536";
  276. ensure("4: convertToU16 failed", !LLStringUtil::convertToU16(str_val, value));
  277. }
  278. template<> template<>
  279. void string_index_object_t::test<22>()
  280. {
  281. U32 value;
  282. std::string str_val("4294967295"); //0xFFFFFFFF
  283. ensure("1: convertToU32 failed", LLStringUtil::convertToU32(str_val, value) && value == 4294967295UL);
  284. str_val = "0";
  285. ensure("2: convertToU32 failed", LLStringUtil::convertToU32(str_val, value) && value == 0);
  286. str_val = "4294967296";
  287. ensure("3: convertToU32 failed", !LLStringUtil::convertToU32(str_val, value));
  288. }
  289. template<> template<>
  290. void string_index_object_t::test<23>()
  291. {
  292. S32 value;
  293. std::string str_val("2147483647"); //0x7FFFFFFF
  294. ensure("1: convertToS32 failed", LLStringUtil::convertToS32(str_val, value) && value == 2147483647);
  295. str_val = "0";
  296. ensure("2: convertToS32 failed", LLStringUtil::convertToS32(str_val, value) && value == 0);
  297. // Avoid "unary minus operator applied to unsigned type" warning on VC++. JC
  298. S32 min_val = -2147483647 - 1;
  299. str_val = "-2147483648";
  300. ensure("3: convertToS32 failed", LLStringUtil::convertToS32(str_val, value) && value == min_val);
  301. str_val = "2147483648";
  302. ensure("4: convertToS32 failed", !LLStringUtil::convertToS32(str_val, value));
  303. str_val = "-2147483649";
  304. ensure("5: convertToS32 failed", !LLStringUtil::convertToS32(str_val, value));
  305. }
  306. template<> template<>
  307. void string_index_object_t::test<24>()
  308. {
  309. F32 value;
  310. std::string str_val("2147483647"); //0x7FFFFFFF
  311. ensure("1: convertToF32 failed", LLStringUtil::convertToF32(str_val, value) && value == 2147483647);
  312. str_val = "0";
  313. ensure("2: convertToF32 failed", LLStringUtil::convertToF32(str_val, value) && value == 0);
  314. /* Need to find max/min F32 values
  315. str_val = "-2147483648";
  316. ensure("3: convertToF32 failed", LLStringUtil::convertToF32(str_val, value) && value == -2147483648);
  317. str_val = "2147483648";
  318. ensure("4: convertToF32 failed", !LLStringUtil::convertToF32(str_val, value));
  319. str_val = "-2147483649";
  320. ensure("5: convertToF32 failed", !LLStringUtil::convertToF32(str_val, value));
  321. */
  322. }
  323. template<> template<>
  324. void string_index_object_t::test<25>()
  325. {
  326. F64 value;
  327. std::string str_val("9223372036854775807"); //0x7FFFFFFFFFFFFFFF
  328. ensure("1: convertToF64 failed", LLStringUtil::convertToF64(str_val, value) && value == 9223372036854775807LL);
  329. str_val = "0";
  330. ensure("2: convertToF64 failed", LLStringUtil::convertToF64(str_val, value) && value == 0.0F);
  331. /* Need to find max/min F64 values
  332. str_val = "-2147483648";
  333. ensure("3: convertToF32 failed", LLStringUtil::convertToF32(str_val, value) && value == -2147483648);
  334. str_val = "2147483648";
  335. ensure("4: convertToF32 failed", !LLStringUtil::convertToF32(str_val, value));
  336. str_val = "-2147483649";
  337. ensure("5: convertToF32 failed", !LLStringUtil::convertToF32(str_val, value));
  338. */
  339. }
  340. template<> template<>
  341. void string_index_object_t::test<26>()
  342. {
  343. const char* str1 = NULL;
  344. const char* str2 = NULL;
  345. ensure("1: compareStrings failed", LLStringUtil::compareStrings(str1, str2) == 0);
  346. str2 = "A";
  347. ensure("2: compareStrings failed", LLStringUtil::compareStrings(str1, str2) > 0);
  348. ensure("3: compareStrings failed", LLStringUtil::compareStrings(str2, str1) < 0);
  349. str1 = "A is smaller than B";
  350. str2 = "B is greater than A";
  351. ensure("4: compareStrings failed", LLStringUtil::compareStrings(str1, str2) < 0);
  352. str2 = "A is smaller than B";
  353. ensure("5: compareStrings failed", LLStringUtil::compareStrings(str1, str2) == 0);
  354. }
  355. template<> template<>
  356. void string_index_object_t::test<27>()
  357. {
  358. const char* str1 = NULL;
  359. const char* str2 = NULL;
  360. ensure("1: compareInsensitive failed", LLStringUtil::compareInsensitive(str1, str2) == 0);
  361. str2 = "A";
  362. ensure("2: compareInsensitive failed", LLStringUtil::compareInsensitive(str1, str2) > 0);
  363. ensure("3: compareInsensitive failed", LLStringUtil::compareInsensitive(str2, str1) < 0);
  364. str1 = "A is equal to a";
  365. str2 = "a is EQUAL to A";
  366. ensure("4: compareInsensitive failed", LLStringUtil::compareInsensitive(str1, str2) == 0);
  367. }
  368. template<> template<>
  369. void string_index_object_t::test<28>()
  370. {
  371. std::string lhs_str("PROgraM12files");
  372. std::string rhs_str("PROgram12Files");
  373. ensure("compareDict 1 failed", LLStringUtil::compareDict(lhs_str, rhs_str) < 0);
  374. ensure("precedesDict 1 failed", LLStringUtil::precedesDict(lhs_str, rhs_str) == TRUE);
  375. lhs_str = "PROgram12Files";
  376. rhs_str = "PROgram12Files";
  377. ensure("compareDict 2 failed", LLStringUtil::compareDict(lhs_str, rhs_str) == 0);
  378. ensure("precedesDict 2 failed", LLStringUtil::precedesDict(lhs_str, rhs_str) == FALSE);
  379. lhs_str = "PROgram12Files";
  380. rhs_str = "PROgRAM12FILES";
  381. ensure("compareDict 3 failed", LLStringUtil::compareDict(lhs_str, rhs_str) > 0);
  382. ensure("precedesDict 3 failed", LLStringUtil::precedesDict(lhs_str, rhs_str) == FALSE);
  383. }
  384. template<> template<>
  385. void string_index_object_t::test<29>()
  386. {
  387. char str1[] = "First String...";
  388. char str2[100];
  389. LLStringUtil::copy(str2, str1, 100);
  390. ensure("LLStringUtil::copy with enough dest length failed", strcmp(str2, str1) == 0);
  391. LLStringUtil::copy(str2, str1, sizeof("First"));
  392. ensure("LLStringUtil::copy with less dest length failed", strcmp(str2, "First") == 0);
  393. }
  394. template<> template<>
  395. void string_index_object_t::test<30>()
  396. {
  397. std::string str1 = "This is the sentence...";
  398. std::string str2 = "This is the ";
  399. std::string str3 = "first ";
  400. std::string str4 = "This is the first sentence...";
  401. std::string str5 = "This is the sentence...first ";
  402. std::string dest;
  403. dest = str1;
  404. LLStringUtil::copyInto(dest, str3, str2.length());
  405. ensure("LLStringUtil::copyInto insert failed", dest == str4);
  406. dest = str1;
  407. LLStringUtil::copyInto(dest, str3, dest.length());
  408. ensure("LLStringUtil::copyInto append failed", dest == str5);
  409. }
  410. template<> template<>
  411. void string_index_object_t::test<31>()
  412. {
  413. std::string stripped;
  414. // Plain US ASCII text, including spaces and punctuation,
  415. // should not be altered.
  416. std::string simple_text = "Hello, world!";
  417. stripped = LLStringFn::strip_invalid_xml(simple_text);
  418. ensure("Simple text passed unchanged", stripped == simple_text);
  419. // Control characters should be removed
  420. // except for 0x09, 0x0a, 0x0d
  421. std::string control_chars;
  422. for (char c = 0x01; c < 0x20; c++)
  423. {
  424. control_chars.push_back(c);
  425. }
  426. std::string allowed_control_chars;
  427. allowed_control_chars.push_back( (char)0x09 );
  428. allowed_control_chars.push_back( (char)0x0a );
  429. allowed_control_chars.push_back( (char)0x0d );
  430. stripped = LLStringFn::strip_invalid_xml(control_chars);
  431. ensure("Only tab, LF, CR control characters allowed",
  432. stripped == allowed_control_chars);
  433. // UTF-8 should be passed intact, including high byte
  434. // characters. Try Francais (with C squiggle cedilla)
  435. std::string french = "Fran";
  436. french.push_back( (char)0xC3 );
  437. french.push_back( (char)0xA7 );
  438. french += "ais";
  439. stripped = LLStringFn::strip_invalid_xml( french );
  440. ensure("UTF-8 high byte text is allowed", french == stripped );
  441. }
  442. template<> template<>
  443. void string_index_object_t::test<32>()
  444. {
  445. // Test LLStringUtil::format() string interpolation
  446. LLStringUtil::format_map_t fmt_map;
  447. std::string s;
  448. int subcount;
  449. fmt_map["[TRICK1]"] = "[A]";
  450. fmt_map["[A]"] = "a";
  451. fmt_map["[B]"] = "b";
  452. fmt_map["[AAA]"] = "aaa";
  453. fmt_map["[BBB]"] = "bbb";
  454. fmt_map["[TRICK2]"] = "[A]";
  455. fmt_map["[EXPLOIT]"] = "!!!!!!!!!!!![EXPLOIT]!!!!!!!!!!!!";
  456. fmt_map["[KEYLONGER]"] = "short";
  457. fmt_map["[KEYSHORTER]"] = "Am I not a long string?";
  458. fmt_map["?"] = "?";
  459. fmt_map["[DELETE]"] = "";
  460. fmt_map["[]"] = "[]"; // doesn't do a substitution, but shouldn't crash either
  461. for (LLStringUtil::format_map_t::const_iterator iter = fmt_map.begin(); iter != fmt_map.end(); ++iter)
  462. {
  463. // Test when source string is entirely one key
  464. std::string s1 = (std::string)iter->first;
  465. std::string s2 = (std::string)iter->second;
  466. subcount = LLStringUtil::format(s1, fmt_map);
  467. ensure_equals("LLStringUtil::format: Raw interpolation result", s1, s2);
  468. if (s1 == "?" || s1 == "[]") // no interp expected
  469. {
  470. ensure_equals("LLStringUtil::format: Raw interpolation result count", 0, subcount);
  471. }
  472. else
  473. {
  474. ensure_equals("LLStringUtil::format: Raw interpolation result count", 1, subcount);
  475. }
  476. }
  477. for (LLStringUtil::format_map_t::const_iterator iter = fmt_map.begin(); iter != fmt_map.end(); ++iter)
  478. {
  479. // Test when source string is one key, duplicated
  480. std::string s1 = (std::string)iter->first;
  481. std::string s2 = (std::string)iter->second;
  482. s = s1 + s1 + s1 + s1;
  483. subcount = LLStringUtil::format(s, fmt_map);
  484. ensure_equals("LLStringUtil::format: Rawx4 interpolation result", s, s2 + s2 + s2 + s2);
  485. if (s1 == "?" || s1 == "[]") // no interp expected
  486. {
  487. ensure_equals("LLStringUtil::format: Rawx4 interpolation result count", 0, subcount);
  488. }
  489. else
  490. {
  491. ensure_equals("LLStringUtil::format: Rawx4 interpolation result count", 4, subcount);
  492. }
  493. }
  494. // Test when source string has no keys
  495. std::string srcs = "!!!!!!!!!!!!!!!!";
  496. s = srcs;
  497. subcount = LLStringUtil::format(s, fmt_map);
  498. ensure_equals("LLStringUtil::format: No key test result", s, srcs);
  499. ensure_equals("LLStringUtil::format: No key test result count", 0, subcount);
  500. // Test when source string has no keys and is empty
  501. std::string srcs3;
  502. s = srcs3;
  503. subcount = LLStringUtil::format(s, fmt_map);
  504. ensure("LLStringUtil::format: No key test3 result", s.empty());
  505. ensure_equals("LLStringUtil::format: No key test3 result count", 0, subcount);
  506. // Test a substitution where a key is substituted with blankness
  507. std::string srcs2 = "[DELETE]";
  508. s = srcs2;
  509. subcount = LLStringUtil::format(s, fmt_map);
  510. ensure("LLStringUtil::format: Delete key test2 result", s.empty());
  511. ensure_equals("LLStringUtil::format: Delete key test2 result count", 1, subcount);
  512. // Test an assorted substitution
  513. std::string srcs4 = "[TRICK1][A][B][AAA][BBB][TRICK2][KEYLONGER][KEYSHORTER]?[DELETE]";
  514. s = srcs4;
  515. subcount = LLStringUtil::format(s, fmt_map);
  516. ensure_equals("LLStringUtil::format: Assorted Test1 result", s, "[A]abaaabbb[A]shortAm I not a long string??");
  517. ensure_equals("LLStringUtil::format: Assorted Test1 result count", 9, subcount);
  518. // Test an assorted substitution
  519. std::string srcs5 = "[DELETE]?[KEYSHORTER][KEYLONGER][TRICK2][BBB][AAA][B][A][TRICK1]";
  520. s = srcs5;
  521. subcount = LLStringUtil::format(s, fmt_map);
  522. ensure_equals("LLStringUtil::format: Assorted Test2 result", s, "?Am I not a long string?short[A]bbbaaaba[A]");
  523. ensure_equals("LLStringUtil::format: Assorted Test2 result count", 9, subcount);
  524. // Test on nested brackets
  525. std::string srcs6 = "[[TRICK1]][[A]][[B]][[AAA]][[BBB]][[TRICK2]][[KEYLONGER]][[KEYSHORTER]]?[[DELETE]]";
  526. s = srcs6;
  527. subcount = LLStringUtil::format(s, fmt_map);
  528. ensure_equals("LLStringUtil::format: Assorted Test2 result", s, "[[A]][a][b][aaa][bbb][[A]][short][Am I not a long string?]?[]");
  529. ensure_equals("LLStringUtil::format: Assorted Test2 result count", 9, subcount);
  530. // Test an assorted substitution
  531. std::string srcs8 = "foo[DELETE]bar?";
  532. s = srcs8;
  533. subcount = LLStringUtil::format(s, fmt_map);
  534. ensure_equals("LLStringUtil::format: Assorted Test3 result", s, "foobar?");
  535. ensure_equals("LLStringUtil::format: Assorted Test3 result count", 1, subcount);
  536. }
  537. template<> template<>
  538. void string_index_object_t::test<33>()
  539. {
  540. // Test LLStringUtil::format() string interpolation
  541. LLStringUtil::format_map_t blank_fmt_map;
  542. std::string s;
  543. int subcount;
  544. // Test substituting out of a blank format_map
  545. std::string srcs6 = "12345";
  546. s = srcs6;
  547. subcount = LLStringUtil::format(s, blank_fmt_map);
  548. ensure_equals("LLStringUtil::format: Blankfmt Test1 result", s, "12345");
  549. ensure_equals("LLStringUtil::format: Blankfmt Test1 result count", 0, subcount);
  550. // Test substituting a blank string out of a blank format_map
  551. std::string srcs7;
  552. s = srcs7;
  553. subcount = LLStringUtil::format(s, blank_fmt_map);
  554. ensure("LLStringUtil::format: Blankfmt Test2 result", s.empty());
  555. ensure_equals("LLStringUtil::format: Blankfmt Test2 result count", 0, subcount);
  556. }
  557. template<> template<>
  558. void string_index_object_t::test<34>()
  559. {
  560. // Test that incorrect LLStringUtil::format() use does not explode.
  561. LLStringUtil::format_map_t nasty_fmt_map;
  562. std::string s;
  563. int subcount;
  564. nasty_fmt_map[""] = "never used"; // see, this is nasty.
  565. // Test substituting out of a nasty format_map
  566. std::string srcs6 = "12345";
  567. s = srcs6;
  568. subcount = LLStringUtil::format(s, nasty_fmt_map);
  569. ensure_equals("LLStringUtil::format: Nastyfmt Test1 result", s, "12345");
  570. ensure_equals("LLStringUtil::format: Nastyfmt Test1 result count", 0, subcount);
  571. // Test substituting a blank string out of a nasty format_map
  572. std::string srcs7;
  573. s = srcs7;
  574. subcount = LLStringUtil::format(s, nasty_fmt_map);
  575. ensure("LLStringUtil::format: Nastyfmt Test2 result", s.empty());
  576. ensure_equals("LLStringUtil::format: Nastyfmt Test2 result count", 0, subcount);
  577. }
  578. template<> template<>
  579. void string_index_object_t::test<35>()
  580. {
  581. // Make sure startsWith works
  582. std::string string("anybody in there?");
  583. std::string substr("anybody");
  584. ensure("startsWith works.", LLStringUtil::startsWith(string, substr));
  585. }
  586. template<> template<>
  587. void string_index_object_t::test<36>()
  588. {
  589. // Make sure startsWith correctly fails
  590. std::string string("anybody in there?");
  591. std::string substr("there");
  592. ensure("startsWith fails.", !LLStringUtil::startsWith(string, substr));
  593. }
  594. template<> template<>
  595. void string_index_object_t::test<37>()
  596. {
  597. // startsWith fails on empty strings
  598. std::string value("anybody in there?");
  599. std::string empty;
  600. ensure("empty string.", !LLStringUtil::startsWith(value, empty));
  601. ensure("empty substr.", !LLStringUtil::startsWith(empty, value));
  602. ensure("empty everything.", !LLStringUtil::startsWith(empty, empty));
  603. }
  604. template<> template<>
  605. void string_index_object_t::test<38>()
  606. {
  607. // Make sure endsWith works correctly
  608. std::string string("anybody in there?");
  609. std::string substr("there?");
  610. ensure("endsWith works.", LLStringUtil::endsWith(string, substr));
  611. }
  612. template<> template<>
  613. void string_index_object_t::test<39>()
  614. {
  615. // Make sure endsWith correctly fails
  616. std::string string("anybody in there?");
  617. std::string substr("anybody");
  618. ensure("endsWith fails.", !LLStringUtil::endsWith(string, substr));
  619. substr = "there";
  620. ensure("endsWith fails.", !LLStringUtil::endsWith(string, substr));
  621. substr = "ther?";
  622. ensure("endsWith fails.", !LLStringUtil::endsWith(string, substr));
  623. }
  624. template<> template<>
  625. void string_index_object_t::test<40>()
  626. {
  627. // endsWith fails on empty strings
  628. std::string value("anybody in there?");
  629. std::string empty;
  630. ensure("empty string.", !LLStringUtil::endsWith(value, empty));
  631. ensure("empty substr.", !LLStringUtil::endsWith(empty, value));
  632. ensure("empty everything.", !LLStringUtil::endsWith(empty, empty));
  633. }
  634. }