StringTest.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. 
  2. #include "../testTools.h"
  3. #include "../../DFPSR/api/stringAPI.h"
  4. void fooInPlace(dsr::String& target, const dsr::ReadableString& a, const dsr::ReadableString& b) {
  5. string_clear(target);
  6. string_append(target, U"Foo(");
  7. string_append(target, a);
  8. string_appendChar(target, U',');
  9. string_append(target, b);
  10. string_appendChar(target, U')');
  11. }
  12. dsr::String foo(const dsr::ReadableString& a, const dsr::ReadableString& b) {
  13. dsr::String result;
  14. string_reserve(result, string_length(a) + string_length(b) + 6);
  15. fooInPlace(result, a, b);
  16. return result;
  17. }
  18. START_TEST(String)
  19. { // Length
  20. ASSERT_EQUAL(string_length(dsr::String()), 0);
  21. ASSERT_EQUAL(string_length(U""), 0);
  22. ASSERT_EQUAL(string_length(U"a"), 1);
  23. ASSERT_EQUAL(string_length(U"ab"), 2);
  24. ASSERT_EQUAL(string_length(U"abc"), 3);
  25. ASSERT_EQUAL(string_length(U"0123456789"), 10);
  26. }
  27. { // Reading characters
  28. ASSERT_EQUAL(dsr::ReadableString(U"ABC")[0], U'A');
  29. ASSERT_EQUAL(dsr::ReadableString(U"ABC")[1], U'B');
  30. ASSERT_EQUAL(dsr::ReadableString(U"ABC")[2], U'C');
  31. ASSERT_EQUAL(dsr::ReadableString(U"ABC")[3], U'\0');
  32. ASSERT_EQUAL(dsr::ReadableString(U"ABC")[10], U'\0');
  33. ASSERT_EQUAL(dsr::ReadableString(U"ABC")[1000000], U'\0');
  34. ASSERT_EQUAL(dsr::ReadableString(U"ABC")[-1], U'\0');
  35. ASSERT_EQUAL(dsr::ReadableString(U"ABC")[-1000000], U'\0');
  36. ASSERT_EQUAL(dsr::ReadableString(U"")[-1], U'\0');
  37. ASSERT_EQUAL(dsr::ReadableString(U"")[0], U'\0');
  38. ASSERT_EQUAL(dsr::ReadableString(U"")[1], U'\0');
  39. }
  40. { // Comparison
  41. dsr::ReadableString litA = U"Testing \u0444";
  42. dsr::ReadableString litB = U"Testing ф";
  43. ASSERT(string_match(litA, litB));
  44. ASSERT(!string_match(litA, U"wrong"));
  45. ASSERT(!string_match(U"wrong", litB));
  46. ASSERT(dsr::string_caseInsensitiveMatch(U"abc 123!", U"ABC 123!"));
  47. ASSERT(!dsr::string_caseInsensitiveMatch(U"abc 123!", U"ABD 123!"));
  48. ASSERT(dsr::string_match(U"aBc 123!", U"aBc 123!"));
  49. ASSERT(!dsr::string_match(U"abc 123!", U"ABC 123!"));
  50. }
  51. { // Concatenation
  52. dsr::String ab = dsr::string_combine(U"a", U"b");
  53. ASSERT_EQUAL(ab, U"ab");
  54. dsr::String cd = dsr::string_combine(U"c", U"d");
  55. ASSERT_EQUAL(cd, U"cd");
  56. cd = dsr::string_combine(U"c", U"d");
  57. ASSERT_EQUAL(cd, U"cd");
  58. auto abcd = ab + cd;
  59. ASSERT_EQUAL(abcd, U"abcd");
  60. ASSERT_EQUAL(dsr::string_combine(U"a", U"b", U"c", "d"), U"abcd");
  61. }
  62. { // Sub-strings
  63. dsr::ReadableString abcd = U"abcd";
  64. dsr::String efgh = U"efgh";
  65. ASSERT_EQUAL(dsr::string_inclusiveRange(abcd, 0, 3), U"abcd");
  66. ASSERT_EQUAL(dsr::string_exclusiveRange(abcd, 1, 2), U"b");
  67. ASSERT_EQUAL(dsr::string_inclusiveRange(efgh, 2, 3), U"gh");
  68. ASSERT_EQUAL(dsr::string_exclusiveRange(efgh, 3, 4), U"h");
  69. ASSERT_EQUAL(dsr::string_combine(string_from(abcd, 2), string_before(efgh, 2)), U"cdef");
  70. ASSERT_EQUAL(dsr::string_exclusiveRange(abcd, 0, 0), U""); // No size returns nothing
  71. ASSERT_EQUAL(dsr::string_exclusiveRange(abcd, -670214452, 2), U"ab"); // Reading out of bound is clamped
  72. ASSERT_EQUAL(dsr::string_exclusiveRange(abcd, 2, 985034841), U"cd"); // Reading out of bound is clamped
  73. ASSERT_EQUAL(dsr::string_exclusiveRange(abcd, 4, 764), U""); // Completely ous of bound returns nothing
  74. ASSERT_EQUAL(dsr::string_exclusiveRange(abcd, -631, 0), U""); // Completely ous of bound returns nothing
  75. }
  76. { // Processing
  77. dsr::String buffer = U"Garbage";
  78. ASSERT_EQUAL(buffer, U"Garbage");
  79. buffer = foo(U"Ball", U"åäöÅÄÖ");
  80. ASSERT_EQUAL(buffer, U"Foo(Ball,åäöÅÄÖ)");
  81. fooInPlace(buffer, U"Å", U"ф");
  82. ASSERT_EQUAL(buffer, U"Foo(Å,ф)");
  83. }
  84. { // Numbers
  85. uint32_t x = 0;
  86. int32_t y = -123456;
  87. int64_t z = 100200300400500600ULL;
  88. dsr::String values = dsr::string_combine(U"x = ", x, U", y = ", y, U", z = ", z);
  89. ASSERT_EQUAL(values, U"x = 0, y = -123456, z = 100200300400500600");
  90. }
  91. { // Identifying numbers
  92. ASSERT_EQUAL(dsr::character_isDigit(U'0' - 1), false);
  93. ASSERT_EQUAL(dsr::character_isDigit(U'0'), true);
  94. ASSERT_EQUAL(dsr::character_isDigit(U'1'), true);
  95. ASSERT_EQUAL(dsr::character_isDigit(U'2'), true);
  96. ASSERT_EQUAL(dsr::character_isDigit(U'3'), true);
  97. ASSERT_EQUAL(dsr::character_isDigit(U'4'), true);
  98. ASSERT_EQUAL(dsr::character_isDigit(U'5'), true);
  99. ASSERT_EQUAL(dsr::character_isDigit(U'6'), true);
  100. ASSERT_EQUAL(dsr::character_isDigit(U'7'), true);
  101. ASSERT_EQUAL(dsr::character_isDigit(U'8'), true);
  102. ASSERT_EQUAL(dsr::character_isDigit(U'9'), true);
  103. ASSERT_EQUAL(dsr::character_isDigit(U'9' + 1), false);
  104. ASSERT_EQUAL(dsr::character_isDigit(U'a'), false);
  105. ASSERT_EQUAL(dsr::character_isDigit(U' '), false);
  106. ASSERT_EQUAL(dsr::character_isIntegerCharacter(U'-'), true);
  107. ASSERT_EQUAL(dsr::character_isIntegerCharacter(U'0' - 1), false);
  108. ASSERT_EQUAL(dsr::character_isIntegerCharacter(U'0'), true);
  109. ASSERT_EQUAL(dsr::character_isIntegerCharacter(U'9'), true);
  110. ASSERT_EQUAL(dsr::character_isIntegerCharacter(U'9' + 1), false);
  111. ASSERT_EQUAL(dsr::character_isIntegerCharacter(U'a'), false);
  112. ASSERT_EQUAL(dsr::character_isIntegerCharacter(U' '), false);
  113. ASSERT_EQUAL(dsr::character_isValueCharacter(U'-'), true);
  114. ASSERT_EQUAL(dsr::character_isValueCharacter(U'.'), true);
  115. ASSERT_EQUAL(dsr::character_isValueCharacter(U'0' - 1), false);
  116. ASSERT_EQUAL(dsr::character_isValueCharacter(U'0'), true);
  117. ASSERT_EQUAL(dsr::character_isValueCharacter(U'9'), true);
  118. ASSERT_EQUAL(dsr::character_isValueCharacter(U'9' + 1), false);
  119. ASSERT_EQUAL(dsr::character_isValueCharacter(U'a'), false);
  120. ASSERT_EQUAL(dsr::character_isValueCharacter(U' '), false);
  121. ASSERT_EQUAL(dsr::character_isWhiteSpace(U' '), true);
  122. ASSERT_EQUAL(dsr::character_isWhiteSpace(U'\t'), true);
  123. ASSERT_EQUAL(dsr::character_isWhiteSpace(U'\r'), true);
  124. ASSERT_EQUAL(dsr::character_isWhiteSpace(U'\0'), false);
  125. ASSERT_EQUAL(dsr::character_isWhiteSpace(U'a'), false);
  126. ASSERT_EQUAL(dsr::character_isWhiteSpace(U'1'), false);
  127. ASSERT_EQUAL(dsr::character_isWhiteSpace(U'('), false);
  128. ASSERT_EQUAL(dsr::character_isWhiteSpace(U')'), false);
  129. ASSERT_EQUAL(dsr::character_isWhiteSpace(U'.'), false);
  130. ASSERT_EQUAL(dsr::character_isWhiteSpace(U','), false);
  131. ASSERT_EQUAL(dsr::character_isWhiteSpace(U'-'), false);
  132. ASSERT_EQUAL(dsr::character_isWhiteSpace(U'_'), false);
  133. ASSERT_EQUAL(dsr::character_isWhiteSpace(U'|'), false);
  134. ASSERT_EQUAL(dsr::string_isInteger(U"0"), true);
  135. ASSERT_EQUAL(dsr::string_isInteger(U"1"), true);
  136. ASSERT_EQUAL(dsr::string_isInteger(U"-0"), true);
  137. ASSERT_EQUAL(dsr::string_isInteger(U"-1"), true);
  138. ASSERT_EQUAL(dsr::string_isInteger(U"0", false), true);
  139. ASSERT_EQUAL(dsr::string_isInteger(U" 0 "), true);
  140. ASSERT_EQUAL(dsr::string_isInteger(U" 0 ", false), false);
  141. ASSERT_EQUAL(dsr::string_isInteger(U" 123"), true);
  142. ASSERT_EQUAL(dsr::string_isInteger(U"-123"), true);
  143. ASSERT_EQUAL(dsr::string_isInteger(U""), false);
  144. ASSERT_EQUAL(dsr::string_isInteger(U"85x"), false);
  145. ASSERT_EQUAL(dsr::string_isInteger(U"F15"), false);
  146. ASSERT_EQUAL(dsr::string_isInteger(U" 14"), true);
  147. ASSERT_EQUAL(dsr::string_isInteger(U"8 "), true);
  148. ASSERT_EQUAL(dsr::string_isInteger(U" 100"), true);
  149. ASSERT_EQUAL(dsr::string_isInteger(U"100 "), true);
  150. ASSERT_EQUAL(dsr::string_isInteger(U"10 10"), false);
  151. ASSERT_EQUAL(dsr::string_isInteger(U"10 10"), false);
  152. ASSERT_EQUAL(dsr::string_isInteger(U" 10 10 "), false);
  153. ASSERT_EQUAL(dsr::string_isDouble(U"0"), true);
  154. ASSERT_EQUAL(dsr::string_isDouble(U"-0"), true);
  155. ASSERT_EQUAL(dsr::string_isDouble(U"1"), true);
  156. ASSERT_EQUAL(dsr::string_isDouble(U"-1"), true);
  157. ASSERT_EQUAL(dsr::string_isDouble(U"1.1"), true);
  158. ASSERT_EQUAL(dsr::string_isDouble(U"-1.1"), true);
  159. ASSERT_EQUAL(dsr::string_isDouble(U".1"), true);
  160. ASSERT_EQUAL(dsr::string_isDouble(U"-.1"), true);
  161. ASSERT_EQUAL(dsr::string_isDouble(U"0", false), true);
  162. ASSERT_EQUAL(dsr::string_isDouble(U" 0 "), true);
  163. ASSERT_EQUAL(dsr::string_isDouble(U" 0 ", false), false);
  164. ASSERT_EQUAL(dsr::string_isDouble(U" 123"), true);
  165. ASSERT_EQUAL(dsr::string_isDouble(U"-123"), true);
  166. ASSERT_EQUAL(dsr::string_isDouble(U"0.5"), true);
  167. ASSERT_EQUAL(dsr::string_isDouble(U"-0.5"), true);
  168. ASSERT_EQUAL(dsr::string_isDouble(U".5"), true);
  169. ASSERT_EQUAL(dsr::string_isDouble(U"-.5"), true);
  170. ASSERT_EQUAL(dsr::string_isDouble(U"0.54321"), true);
  171. ASSERT_EQUAL(dsr::string_isDouble(U"-0.54321"), true);
  172. ASSERT_EQUAL(dsr::string_isDouble(U""), false);
  173. ASSERT_EQUAL(dsr::string_isDouble(U"0..0"), false);
  174. ASSERT_EQUAL(dsr::string_isDouble(U"M0.0"), false);
  175. ASSERT_EQUAL(dsr::string_isDouble(U"0.0x"), false);
  176. ASSERT_EQUAL(dsr::string_isDouble(U"T0.0q"), false);
  177. }
  178. // Upper case
  179. ASSERT_EQUAL(dsr::string_upperCase(U"a"), U"A");
  180. ASSERT_EQUAL(dsr::string_upperCase(U"aB"), U"AB");
  181. ASSERT_EQUAL(dsr::string_upperCase(U"abc"), U"ABC");
  182. ASSERT_EQUAL(dsr::string_upperCase(U"abc1"), U"ABC1");
  183. ASSERT_EQUAL(dsr::string_upperCase(U"Abc12"), U"ABC12");
  184. ASSERT_EQUAL(dsr::string_upperCase(U"ABC123"), U"ABC123");
  185. ASSERT_EQUAL(dsr::string_upperCase(U"!%& abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ"), U"!%& ABCDEFGHIJKLMNOPQRSTUVWXYZ ABCDEFGHIJKLMNOPQRSTUVWXYZ");
  186. ASSERT_EQUAL(dsr::string_upperCase(U"àáâãäåæçèéêëìíîïðñòóôõöÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ"), U"ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ");
  187. ASSERT_EQUAL(dsr::string_upperCase(U"ÿøùúûüýþŸØÙÚÛÜÝÞ"), U"ŸØÙÚÛÜÝÞŸØÙÚÛÜÝÞ");
  188. ASSERT_EQUAL(dsr::string_upperCase(U"āăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıijĵķ ĸ ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮİIJĴĶ"), U"ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮİIJĴĶ ĸ ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮİIJĴĶ");
  189. ASSERT_EQUAL(dsr::string_upperCase(U"313..328 ĺļľŀłńņň ĹĻĽĿŁŃŅŇ"), U"313..328 ĹĻĽĿŁŃŅŇ ĹĻĽĿŁŃŅŇ");
  190. ASSERT_EQUAL(dsr::string_upperCase(U"330..375 ŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷ ŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶ"), U"330..375 ŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶ ŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶ");
  191. ASSERT_EQUAL(dsr::string_upperCase(U"377..382 źżž ŹŻŽ"), U"377..382 ŹŻŽ ŹŻŽ");
  192. ASSERT_EQUAL(dsr::string_upperCase(U"461..476 ǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜ"), U"461..476 ǍǍǏǏǑǑǓǓǕǕǗǗǙǙǛǛ");
  193. // Lower case
  194. ASSERT_EQUAL(dsr::string_lowerCase(U"a"), U"a");
  195. ASSERT_EQUAL(dsr::string_lowerCase(U"aB"), U"ab");
  196. ASSERT_EQUAL(dsr::string_lowerCase(U"abc"), U"abc");
  197. ASSERT_EQUAL(dsr::string_lowerCase(U"abc1"), U"abc1");
  198. ASSERT_EQUAL(dsr::string_lowerCase(U"Abc12"), U"abc12");
  199. ASSERT_EQUAL(dsr::string_lowerCase(U"ABC123"), U"abc123");
  200. ASSERT_EQUAL(dsr::string_lowerCase(U"!%& abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ"), U"!%& abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz");
  201. ASSERT_EQUAL(dsr::string_lowerCase(U"àáâãäåæçèéêëìíîïðñòóôõöÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ"), U"àáâãäåæçèéêëìíîïðñòóôõöàáâãäåæçèéêëìíîïðñòóôõö");
  202. ASSERT_EQUAL(dsr::string_lowerCase(U"ÿøùúûüýþŸØÙÚÛÜÝÞ"), U"ÿøùúûüýþÿøùúûüýþ");
  203. ASSERT_EQUAL(dsr::string_lowerCase(U"āăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıijĵķ ĸ ĀĂĄĆĈĊČĎĐĒĔĖĘĚĜĞĠĢĤĦĨĪĬĮİIJĴĶ"), U"āăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıijĵķ ĸ āăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıijĵķ");
  204. ASSERT_EQUAL(dsr::string_lowerCase(U"313..328 ĺļľŀłńņň ĹĻĽĿŁŃŅŇ"), U"313..328 ĺļľŀłńņň ĺļľŀłńņň");
  205. ASSERT_EQUAL(dsr::string_lowerCase(U"330..375 ŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷ ŊŌŎŐŒŔŖŘŚŜŞŠŢŤŦŨŪŬŮŰŲŴŶ"), U"330..375 ŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷ ŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷ");
  206. ASSERT_EQUAL(dsr::string_lowerCase(U"377..382 źżž ŹŻŽ"), U"377..382 źżž źżž");
  207. ASSERT_EQUAL(dsr::string_lowerCase(U"461..476 ǍǎǏǐǑǒǓǔǕǖǗǘǙǚǛǜ"), U"461..476 ǎǎǐǐǒǒǔǔǖǖǘǘǚǚǜǜ");
  208. // White space removal by pointing to a section of the original input
  209. ASSERT_EQUAL(dsr::string_removeOuterWhiteSpace(U" "), U"");
  210. ASSERT_EQUAL(dsr::string_removeOuterWhiteSpace(U" abc "), U"abc");
  211. ASSERT_EQUAL(dsr::string_removeOuterWhiteSpace(U" two words "), U"two words");
  212. ASSERT_EQUAL(dsr::string_removeOuterWhiteSpace(U" \" something quoted \" "), U"\" something quoted \"");
  213. // Quote mangling
  214. ASSERT_EQUAL(dsr::string_mangleQuote(U""), U"\"\"");
  215. ASSERT_EQUAL(dsr::string_mangleQuote(U"1"), U"\"1\"");
  216. ASSERT_EQUAL(dsr::string_mangleQuote(U"12"), U"\"12\"");
  217. ASSERT_EQUAL(dsr::string_mangleQuote(U"123"), U"\"123\"");
  218. ASSERT_EQUAL(dsr::string_mangleQuote(U"abc"), U"\"abc\"");
  219. // Not enough quote signs
  220. ASSERT_CRASH(dsr::string_unmangleQuote(U""), U"Cannot unmangle using string_unmangleQuote without beginning and ending with quote signs!");
  221. ASSERT_CRASH(dsr::string_unmangleQuote(U" "), U"Cannot unmangle using string_unmangleQuote without beginning and ending with quote signs!");
  222. ASSERT_CRASH(dsr::string_unmangleQuote(U"ab\"cd"), U"Cannot unmangle using string_unmangleQuote without beginning and ending with quote signs!");
  223. // Too many quote signs
  224. ASSERT_CRASH(dsr::string_unmangleQuote(U"ab\"cd\"ef\"gh"), U"Unmangled double quote sign detected in string_unmangleQuote!");
  225. // Basic quote
  226. ASSERT_EQUAL(dsr::string_unmangleQuote(U"\"ab\""), U"ab");
  227. // Surrounded quote
  228. ASSERT_EQUAL(dsr::string_unmangleQuote(U"\"ab\"cd"), U"ab");
  229. ASSERT_EQUAL(dsr::string_unmangleQuote(U"ab\"cd\""), U"cd");
  230. ASSERT_EQUAL(dsr::string_unmangleQuote(U"ab\"cd\"ef"), U"cd");
  231. // Mangled quote inside of quote
  232. ASSERT_EQUAL(dsr::string_unmangleQuote(U"ab\"c\\\"d\"ef"), U"c\"d");
  233. ASSERT_EQUAL(dsr::string_unmangleQuote(dsr::string_mangleQuote(U"c\"d")), U"c\"d");
  234. // Mangle things
  235. dsr::String randomText;
  236. string_reserve(randomText, 100);
  237. for (int i = 1; i < 100; i++) {
  238. // Randomize previous characters
  239. for (int j = 1; j < i - 1; j++) {
  240. string_appendChar(randomText, (DsrChar)((i * 21 + j * 49 + 136) % 1024));
  241. }
  242. // Add a new random character
  243. string_appendChar(randomText, (i * 21 + 136) % 256);
  244. ASSERT_EQUAL(dsr::string_unmangleQuote(dsr::string_mangleQuote(randomText)), randomText);
  245. }
  246. // Number serialization
  247. ASSERT_EQUAL(dsr::string_combine(0, U" ", 1), U"0 1");
  248. ASSERT_EQUAL(dsr::string_combine(14, U"x", 135), U"14x135");
  249. ASSERT_EQUAL(dsr::string_combine(-135), U"-135");
  250. ASSERT_EQUAL(dsr::string_combine(-14), U"-14");
  251. ASSERT_EQUAL(dsr::string_combine(-1), U"-1");
  252. ASSERT_EQUAL(dsr::string_combine(0u), U"0");
  253. ASSERT_EQUAL(dsr::string_combine(1u), U"1");
  254. ASSERT_EQUAL(dsr::string_combine(14u), U"14");
  255. ASSERT_EQUAL(dsr::string_combine(135u), U"135");
  256. ASSERT_EQUAL(dsr::string_combine(0.0), U"0.0");
  257. ASSERT_EQUAL(dsr::string_combine(-0.0), U"0.0");
  258. ASSERT_EQUAL(dsr::string_combine(1.0), U"1.0");
  259. ASSERT_EQUAL(dsr::string_combine(10.0), U"10.0");
  260. ASSERT_EQUAL(dsr::string_combine(100.0), U"100.0");
  261. ASSERT_EQUAL(dsr::string_combine(1000.0), U"1000.0");
  262. ASSERT_EQUAL(dsr::string_combine(10000.0), U"10000.0");
  263. ASSERT_EQUAL(dsr::string_combine(100000.0), U"100000.0");
  264. ASSERT_EQUAL(dsr::string_combine(1000000.0), U"1000000.0");
  265. ASSERT_EQUAL(dsr::string_combine(-1.0), U"-1.0");
  266. ASSERT_EQUAL(dsr::string_combine(-10.0), U"-10.0");
  267. ASSERT_EQUAL(dsr::string_combine(-100.0), U"-100.0");
  268. ASSERT_EQUAL(dsr::string_combine(-1000.0), U"-1000.0");
  269. ASSERT_EQUAL(dsr::string_combine(-10000.0), U"-10000.0");
  270. ASSERT_EQUAL(dsr::string_combine(-100000.0), U"-100000.0");
  271. ASSERT_EQUAL(dsr::string_combine(-1000000.0), U"-1000000.0");
  272. ASSERT_EQUAL(dsr::string_combine(0.5), U"0.5");
  273. ASSERT_EQUAL(dsr::string_combine(-0.5), U"-0.5");
  274. ASSERT_EQUAL(dsr::string_combine(789.123456), U"789.123456");
  275. ASSERT_EQUAL(dsr::string_combine(-789.123456), U"-789.123456");
  276. // Manual number serialization
  277. String serializedNumber;
  278. // Check that epsilon does not overflow the fraction
  279. serializedNumber = U""; dsr::string_fromDouble(serializedNumber, 123.0 ); ASSERT_EQUAL(serializedNumber, U"123.0");
  280. serializedNumber = U""; dsr::string_fromDouble(serializedNumber, 123.0 + 0.0000000000000000001); ASSERT_EQUAL(serializedNumber, U"123.0");
  281. serializedNumber = U""; dsr::string_fromDouble(serializedNumber, 123.0 - 0.0000000000000000001); ASSERT_EQUAL(serializedNumber, U"123.0");
  282. serializedNumber = U""; dsr::string_fromDouble(serializedNumber, 734.0 + 0.0000000000000000001); ASSERT_EQUAL(serializedNumber, U"734.0");
  283. serializedNumber = U""; dsr::string_fromDouble(serializedNumber, 734.0 - 0.0000000000000000001); ASSERT_EQUAL(serializedNumber, U"734.0");
  284. serializedNumber = U""; dsr::string_fromDouble(serializedNumber, -15.0 + 0.0000000000000000001); ASSERT_EQUAL(serializedNumber, U"-15.0");
  285. serializedNumber = U""; dsr::string_fromDouble(serializedNumber, -15.0 - 0.0000000000000000001); ASSERT_EQUAL(serializedNumber, U"-15.0");
  286. // Test different settings
  287. serializedNumber = U""; dsr::string_fromDouble(serializedNumber, 123.456789, -12); ASSERT_EQUAL(serializedNumber, U"123.5"); // At least one decimal
  288. serializedNumber = U""; dsr::string_fromDouble(serializedNumber, 123.456789, -1); ASSERT_EQUAL(serializedNumber, U"123.5"); // At least one decimal
  289. serializedNumber = U""; dsr::string_fromDouble(serializedNumber, 123.456789, 0); ASSERT_EQUAL(serializedNumber, U"123.5"); // At least one decimal
  290. serializedNumber = U""; dsr::string_fromDouble(serializedNumber, 123.456789, 1); ASSERT_EQUAL(serializedNumber, U"123.5"); // Good input
  291. serializedNumber = U""; dsr::string_fromDouble(serializedNumber, 123.456789, 2); ASSERT_EQUAL(serializedNumber, U"123.46"); // Rounded
  292. serializedNumber = U""; dsr::string_fromDouble(serializedNumber, 123.456789, 3); ASSERT_EQUAL(serializedNumber, U"123.457"); // Rounded
  293. serializedNumber = U""; dsr::string_fromDouble(serializedNumber, 123.456789, 4); ASSERT_EQUAL(serializedNumber, U"123.4568"); // Rounded
  294. serializedNumber = U""; dsr::string_fromDouble(serializedNumber, 123.456789, 5); ASSERT_EQUAL(serializedNumber, U"123.45679"); // Rounded
  295. serializedNumber = U""; dsr::string_fromDouble(serializedNumber, 123.456789, 6); ASSERT_EQUAL(serializedNumber, U"123.456789"); // All decimals included, so no need to round.
  296. serializedNumber = U""; dsr::string_fromDouble(serializedNumber, -123.456789, -12); ASSERT_EQUAL(serializedNumber, U"-123.5"); // At least one decimal
  297. serializedNumber = U""; dsr::string_fromDouble(serializedNumber, -123.456789, -1); ASSERT_EQUAL(serializedNumber, U"-123.5"); // At least one decimal
  298. serializedNumber = U""; dsr::string_fromDouble(serializedNumber, -123.456789, 0); ASSERT_EQUAL(serializedNumber, U"-123.5"); // At least one decimal
  299. serializedNumber = U""; dsr::string_fromDouble(serializedNumber, -123.456789, 1); ASSERT_EQUAL(serializedNumber, U"-123.5"); // Good input
  300. serializedNumber = U""; dsr::string_fromDouble(serializedNumber, -123.456789, 2); ASSERT_EQUAL(serializedNumber, U"-123.46"); // Rounded
  301. serializedNumber = U""; dsr::string_fromDouble(serializedNumber, -123.456789, 3); ASSERT_EQUAL(serializedNumber, U"-123.457"); // Rounded
  302. serializedNumber = U""; dsr::string_fromDouble(serializedNumber, -123.456789, 4); ASSERT_EQUAL(serializedNumber, U"-123.4568"); // Rounded
  303. serializedNumber = U""; dsr::string_fromDouble(serializedNumber, -123.456789, 5); ASSERT_EQUAL(serializedNumber, U"-123.45679"); // Rounded
  304. serializedNumber = U""; dsr::string_fromDouble(serializedNumber, -123.456789, 6); ASSERT_EQUAL(serializedNumber, U"-123.456789"); // All decimals included, so no need to round.
  305. // Test nearest rounding while returning by value.
  306. ASSERT_EQUAL(dsr::string_fromDouble(1.00, 1), U"1.0");
  307. ASSERT_EQUAL(dsr::string_fromDouble(1.01, 1), U"1.0");
  308. ASSERT_EQUAL(dsr::string_fromDouble(1.02, 1), U"1.0");
  309. ASSERT_EQUAL(dsr::string_fromDouble(1.03, 1), U"1.0");
  310. ASSERT_EQUAL(dsr::string_fromDouble(1.04, 1), U"1.0");
  311. ASSERT_EQUAL(dsr::string_fromDouble(1.049, 1), U"1.0");
  312. ASSERT_EQUAL(dsr::string_fromDouble(1.0499, 1), U"1.0");
  313. ASSERT_EQUAL(dsr::string_fromDouble(1.04999, 1), U"1.0");
  314. ASSERT_EQUAL(dsr::string_fromDouble(1.049999, 1), U"1.0");
  315. ASSERT_EQUAL(dsr::string_fromDouble(1.0499999, 1), U"1.0");
  316. ASSERT_EQUAL(dsr::string_fromDouble(1.04999999, 1), U"1.0");
  317. ASSERT_EQUAL(dsr::string_fromDouble(1.049999999, 1), U"1.0");
  318. ASSERT_EQUAL(dsr::string_fromDouble(1.050000001, 1), U"1.1");
  319. ASSERT_EQUAL(dsr::string_fromDouble(1.05000001, 1), U"1.1");
  320. ASSERT_EQUAL(dsr::string_fromDouble(1.0500001, 1), U"1.1");
  321. ASSERT_EQUAL(dsr::string_fromDouble(1.050001, 1), U"1.1");
  322. ASSERT_EQUAL(dsr::string_fromDouble(1.05001, 1), U"1.1");
  323. ASSERT_EQUAL(dsr::string_fromDouble(1.0501, 1), U"1.1");
  324. ASSERT_EQUAL(dsr::string_fromDouble(1.051, 1), U"1.1");
  325. ASSERT_EQUAL(dsr::string_fromDouble(1.06, 1), U"1.1");
  326. ASSERT_EQUAL(dsr::string_fromDouble(1.07, 1), U"1.1");
  327. ASSERT_EQUAL(dsr::string_fromDouble(1.08, 1), U"1.1");
  328. ASSERT_EQUAL(dsr::string_fromDouble(1.09, 1), U"1.1");
  329. ASSERT_EQUAL(dsr::string_fromDouble(1.10, 1), U"1.1");
  330. // Not removing trailing zeroes.
  331. ASSERT_EQUAL(dsr::string_fromDouble(1.0, 0, false), U"1.0");
  332. ASSERT_EQUAL(dsr::string_fromDouble(1.0, 1, false), U"1.0");
  333. ASSERT_EQUAL(dsr::string_fromDouble(1.0, 2, false), U"1.00");
  334. ASSERT_EQUAL(dsr::string_fromDouble(1.0, 3, false), U"1.000");
  335. ASSERT_EQUAL(dsr::string_fromDouble(1.0, 4, false), U"1.0000");
  336. ASSERT_EQUAL(dsr::string_fromDouble(1.0, 5, false), U"1.00000");
  337. ASSERT_EQUAL(dsr::string_fromDouble(1.0, 6, false), U"1.000000");
  338. ASSERT_EQUAL(dsr::string_fromDouble(1.0, 7, false), U"1.0000000");
  339. ASSERT_EQUAL(dsr::string_fromDouble(1.0, 8, false), U"1.00000000");
  340. ASSERT_EQUAL(dsr::string_fromDouble(1.0, 9, false), U"1.000000000");
  341. ASSERT_EQUAL(dsr::string_fromDouble(1.0, 10, false), U"1.0000000000");
  342. ASSERT_EQUAL(dsr::string_fromDouble(1.0, 11, false), U"1.00000000000");
  343. ASSERT_EQUAL(dsr::string_fromDouble(1.0, 12, false), U"1.000000000000");
  344. ASSERT_EQUAL(dsr::string_fromDouble(1.0, 13, false), U"1.0000000000000");
  345. ASSERT_EQUAL(dsr::string_fromDouble(1.0, 14, false), U"1.00000000000000");
  346. ASSERT_EQUAL(dsr::string_fromDouble(1.0, 15, false), U"1.000000000000000");
  347. ASSERT_EQUAL(dsr::string_fromDouble(1.0, 16, false), U"1.0000000000000000");
  348. ASSERT_EQUAL(dsr::string_fromDouble(1.0, 17, false), U"1.0000000000000000");
  349. ASSERT_EQUAL(dsr::string_fromDouble(1.0, 18, false), U"1.0000000000000000");
  350. // Special characters.
  351. ASSERT_EQUAL(dsr::string_fromDouble(-1.0, 2, false, U',', U'~'), U"~1,00");
  352. // Number parsing
  353. ASSERT_EQUAL(string_toInteger(U"0"), 0);
  354. ASSERT_EQUAL(string_toInteger(U"-0"), 0);
  355. ASSERT_EQUAL(string_toInteger(U"No digits here."), 0);
  356. ASSERT_EQUAL(string_toInteger(U" (12 garbage 34) "), 1234); // You are supposed to catch these errors before converting to an integer
  357. ASSERT_EQUAL(string_toInteger(U""), 0);
  358. ASSERT_EQUAL(string_toInteger(U"1"), 1);
  359. ASSERT_EQUAL(string_toInteger(U"-1"), -1);
  360. ASSERT_EQUAL(string_toInteger(U"1024"), 1024);
  361. ASSERT_EQUAL(string_toInteger(U"-1024"), -1024);
  362. ASSERT_EQUAL(string_toInteger(U"1000000"), 1000000);
  363. ASSERT_EQUAL(string_toInteger(U"-1000000"), -1000000);
  364. ASSERT_EQUAL(string_toInteger(U"123"), 123);
  365. ASSERT_NEAR(string_toDouble(U"123"), 123.0);
  366. ASSERT_NEAR(string_toDouble(U"123.456"), 123.456);
  367. ASSERT_NEAR(string_toDouble(U"123.456e-3"), 0.123456);
  368. ASSERT_NEAR(string_toDouble(U"123.456e-2"), 1.23456);
  369. ASSERT_NEAR(string_toDouble(U"123.456e-1"), 12.3456);
  370. ASSERT_NEAR(string_toDouble(U"123.456e0"), 123.456);
  371. ASSERT_NEAR(string_toDouble(U"123.456e1"), 1234.56);
  372. ASSERT_NEAR(string_toDouble(U"123.456e2"), 12345.6);
  373. ASSERT_NEAR(string_toDouble(U"123.456e3"), 123456.0);
  374. { // Assigning strings using reference counting
  375. String a = U"Some text";
  376. ASSERT_EQUAL(string_getBufferUseCount(a), 1);
  377. String b = a;
  378. ASSERT_EQUAL(string_getBufferUseCount(a), 2);
  379. ASSERT_EQUAL(string_getBufferUseCount(b), 2);
  380. String c = b;
  381. ASSERT_EQUAL(string_getBufferUseCount(a), 3);
  382. ASSERT_EQUAL(string_getBufferUseCount(b), 3);
  383. ASSERT_EQUAL(string_getBufferUseCount(c), 3);
  384. }
  385. { // String splitting by shared reference counted buffer
  386. String source = U" a . b . c . d ";
  387. String source2 = U" a . b .\tc ";
  388. ASSERT_EQUAL(string_getBufferUseCount(source), 1);
  389. ASSERT_EQUAL(string_getBufferUseCount(source2), 1);
  390. List<String> result;
  391. result = string_split(source, U'.', false);
  392. ASSERT_EQUAL(result.length(), 4);
  393. ASSERT_EQUAL(result[0], U" a ");
  394. ASSERT_EQUAL(result[1], U" b ");
  395. ASSERT_EQUAL(result[2], U" c ");
  396. ASSERT_EQUAL(result[3], U" d ");
  397. ASSERT_EQUAL(string_getBufferUseCount(source), 5);
  398. ASSERT_EQUAL(string_getBufferUseCount(source2), 1);
  399. result = string_split(source2, U'.', true);
  400. ASSERT_EQUAL(result.length(), 3);
  401. ASSERT_EQUAL(result[0], U"a");
  402. ASSERT_EQUAL(result[1], U"b");
  403. ASSERT_EQUAL(result[2], U"c");
  404. ASSERT_EQUAL(string_getBufferUseCount(source), 1);
  405. ASSERT_EQUAL(string_getBufferUseCount(source2), 4);
  406. }
  407. { // Automatically allocating a shared buffer for many elements
  408. // Splitting String shares memory.
  409. String original = U" a . b . c . d ";
  410. List<String> result = string_split(original, U'.', true);
  411. ASSERT_EQUAL(result[0], U"a");
  412. ASSERT_EQUAL(result[1], U"b");
  413. ASSERT_EQUAL(result[2], U"c");
  414. ASSERT_EQUAL(result[3], U"d");
  415. ASSERT_EQUAL(string_getBufferUseCount(original), 5);
  416. ASSERT_EQUAL(string_getBufferUseCount(result[0]), 5);
  417. ASSERT_EQUAL(string_getBufferUseCount(result[1]), 5);
  418. ASSERT_EQUAL(string_getBufferUseCount(result[2]), 5);
  419. ASSERT_EQUAL(string_getBufferUseCount(result[3]), 5);
  420. // Splitting a literal allocates no string buffers.
  421. result = string_split(U" a . b . c ", U'.', false);
  422. ASSERT_EQUAL(result[0], U" a ");
  423. ASSERT_EQUAL(result[1], U" b ");
  424. ASSERT_EQUAL(result[2], U" c ");
  425. ASSERT_EQUAL(string_getBufferUseCount(result[0]), 0);
  426. ASSERT_EQUAL(string_getBufferUseCount(result[1]), 0);
  427. ASSERT_EQUAL(string_getBufferUseCount(result[2]), 0);
  428. }
  429. { // Callback splitting
  430. String numbers = U"1, 3, 5, 7, 9";
  431. List<int> result;
  432. string_split_callback([&numbers, &result](ReadableString section) {
  433. result.push(string_toInteger(section));
  434. }, numbers, U',');
  435. ASSERT_EQUAL(result.length(), 5);
  436. ASSERT_EQUAL(result[0], 1);
  437. ASSERT_EQUAL(result[1], 3);
  438. ASSERT_EQUAL(result[2], 5);
  439. ASSERT_EQUAL(result[3], 7);
  440. ASSERT_EQUAL(result[4], 9);
  441. }
  442. // TODO: Test taking a part of a parent string with a start offset, leaving the parent scope,
  443. // and expanding with append while the buffer isn't shared but has an offset from buffer start.
  444. // TODO: Test sharing the same buffer between strings, then clear and append more text without overwriting other strings.
  445. // TODO: Assert that buffers are shared when they should, but prevents side-effects when one is being written to.
  446. END_TEST