string_ut.cpp 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270
  1. #include "deque.h"
  2. #include "strbuf.h"
  3. #include "string_ut.h"
  4. #include "vector.h"
  5. #include "yexception.h"
  6. #include <util/charset/wide.h>
  7. #include <util/str_stl.h>
  8. #include <util/stream/output.h>
  9. #include <util/string/subst.h>
  10. #include <string>
  11. #include <sstream>
  12. #include <algorithm>
  13. #include <stdexcept>
  14. #ifdef TSTRING_IS_STD_STRING
  15. static_assert(sizeof(TString) == sizeof(std::string), "expect sizeof(TString) == sizeof(std::string)");
  16. #else
  17. static_assert(sizeof(TString) == sizeof(const char*), "expect sizeof(TString) == sizeof(const char*)");
  18. #endif
  19. class TStringTestZero: public TTestBase {
  20. UNIT_TEST_SUITE(TStringTestZero);
  21. UNIT_TEST(TestZero);
  22. UNIT_TEST_SUITE_END();
  23. public:
  24. void TestZero() {
  25. const char data[] = "abc\0def\0";
  26. TString s(data, sizeof(data));
  27. UNIT_ASSERT(s.size() == sizeof(data));
  28. UNIT_ASSERT(s.StartsWith(s));
  29. UNIT_ASSERT(s.EndsWith(s));
  30. UNIT_ASSERT(s.Contains('\0'));
  31. const char raw_def[] = "def";
  32. const char raw_zero[] = "\0";
  33. TString def(raw_def, sizeof(raw_def) - 1);
  34. TString zero(raw_zero, sizeof(raw_zero) - 1);
  35. UNIT_ASSERT_EQUAL(4, s.find(raw_def));
  36. UNIT_ASSERT_EQUAL(4, s.find(def));
  37. UNIT_ASSERT_EQUAL(4, s.find_first_of(raw_def));
  38. UNIT_ASSERT_EQUAL(3, s.find_first_of(zero));
  39. UNIT_ASSERT_EQUAL(7, s.find_first_not_of(def, 4));
  40. const char nonSubstring[] = "def\0ghi";
  41. UNIT_ASSERT_EQUAL(TString::npos, s.find(TString(nonSubstring, sizeof(nonSubstring))));
  42. TString copy = s;
  43. copy.replace(copy.size() - 1, 1, "z");
  44. UNIT_ASSERT(s != copy);
  45. copy.replace(copy.size() - 1, 1, "\0", 0, 1);
  46. UNIT_ASSERT(s == copy);
  47. TString prefix(data, 5);
  48. UNIT_ASSERT(s.StartsWith(prefix));
  49. UNIT_ASSERT(s != prefix);
  50. UNIT_ASSERT(s > prefix);
  51. UNIT_ASSERT(s > s.data());
  52. UNIT_ASSERT(s == TString(s.data(), s.size()));
  53. UNIT_ASSERT(data < s);
  54. s.remove(5);
  55. UNIT_ASSERT(s == prefix);
  56. }
  57. };
  58. UNIT_TEST_SUITE_REGISTRATION(TStringTestZero);
  59. template <typename TStringType, typename TTestData>
  60. class TStringStdTestImpl {
  61. using TChar = typename TStringType::char_type;
  62. using TTraits = typename TStringType::traits_type;
  63. using TView = std::basic_string_view<TChar, TTraits>;
  64. TTestData Data_;
  65. protected:
  66. void Constructor() {
  67. // @todo use UNIT_TEST_EXCEPTION
  68. try {
  69. TStringType s((size_t)-1, *Data_.a());
  70. UNIT_ASSERT(false);
  71. } catch (const std::length_error&) {
  72. UNIT_ASSERT(true);
  73. } catch (...) {
  74. //Expected exception is length_error:
  75. UNIT_ASSERT(false);
  76. }
  77. }
  78. void reserve() {
  79. #if 0
  80. TStringType s;
  81. // @todo use UNIT_TEST_EXCEPTION
  82. try {
  83. s.reserve(s.max_size() + 1);
  84. UNIT_ASSERT(false);
  85. } catch (const std::length_error&) {
  86. UNIT_ASSERT(true);
  87. } catch (...) {
  88. //Expected exception is length_error:
  89. UNIT_ASSERT(false);
  90. }
  91. // Non-shared behaviour - never shrink
  92. s.reserve(256);
  93. #ifndef TSTRING_IS_STD_STRING
  94. const auto* data = s.data();
  95. UNIT_ASSERT(s.capacity() >= 256);
  96. s.reserve(128);
  97. UNIT_ASSERT(s.capacity() >= 256 && s.data() == data);
  98. #endif
  99. s.resize(64, 'x');
  100. s.reserve(10);
  101. #ifdef TSTRING_IS_STD_STRING
  102. UNIT_ASSERT(s.capacity() >= 64);
  103. #else
  104. UNIT_ASSERT(s.capacity() >= 256 && s.data() == data);
  105. #endif
  106. #ifndef TSTRING_IS_STD_STRING
  107. // Shared behaviour - always reallocate, just as much as requisted
  108. TStringType holder = s;
  109. UNIT_ASSERT(s.capacity() >= 256);
  110. s.reserve(128);
  111. UNIT_ASSERT(s.capacity() >= 128 && s.capacity() < 256 && s.data() != data);
  112. UNIT_ASSERT(s.IsDetached());
  113. s.resize(64, 'x');
  114. data = s.data();
  115. holder = s;
  116. s.reserve(10);
  117. UNIT_ASSERT(s.capacity() >= 64 && s.capacity() < 128 && s.data() != data);
  118. UNIT_ASSERT(s.IsDetached());
  119. #endif
  120. #endif
  121. }
  122. void short_string() {
  123. TStringType const ref_short_str1(Data_.str1()), ref_short_str2(Data_.str2());
  124. TStringType short_str1(ref_short_str1), short_str2(ref_short_str2);
  125. TStringType const ref_long_str1(Data_.str__________________________________________________1());
  126. TStringType const ref_long_str2(Data_.str__________________________________________________2());
  127. TStringType long_str1(ref_long_str1), long_str2(ref_long_str2);
  128. UNIT_ASSERT(short_str1 == ref_short_str1);
  129. UNIT_ASSERT(long_str1 == ref_long_str1);
  130. {
  131. TStringType str1(short_str1);
  132. str1 = long_str1;
  133. UNIT_ASSERT(str1 == ref_long_str1);
  134. }
  135. {
  136. TStringType str1(long_str1);
  137. str1 = short_str1;
  138. UNIT_ASSERT(str1 == ref_short_str1);
  139. }
  140. {
  141. short_str1.swap(short_str2);
  142. UNIT_ASSERT((short_str1 == ref_short_str2) && (short_str2 == ref_short_str1));
  143. short_str1.swap(short_str2);
  144. }
  145. {
  146. long_str1.swap(long_str2);
  147. UNIT_ASSERT((long_str1 == ref_long_str2) && (long_str2 == ref_long_str1));
  148. long_str1.swap(long_str2);
  149. }
  150. {
  151. short_str1.swap(long_str1);
  152. UNIT_ASSERT((short_str1 == ref_long_str1) && (long_str1 == ref_short_str1));
  153. short_str1.swap(long_str1);
  154. }
  155. {
  156. long_str1.swap(short_str1);
  157. UNIT_ASSERT((short_str1 == ref_long_str1) && (long_str1 == ref_short_str1));
  158. long_str1.swap(short_str1);
  159. }
  160. {
  161. //This is to test move constructor
  162. TVector<TStringType> str_vect;
  163. str_vect.push_back(short_str1);
  164. str_vect.push_back(long_str1);
  165. str_vect.push_back(short_str2);
  166. str_vect.push_back(long_str2);
  167. UNIT_ASSERT(str_vect[0] == ref_short_str1);
  168. UNIT_ASSERT(str_vect[1] == ref_long_str1);
  169. UNIT_ASSERT(str_vect[2] == ref_short_str2);
  170. UNIT_ASSERT(str_vect[3] == ref_long_str2);
  171. }
  172. }
  173. void erase() {
  174. TChar const* c_str = Data_.Hello_World();
  175. TStringType str(c_str);
  176. UNIT_ASSERT(str == c_str);
  177. str.erase(str.begin() + 1, str.end() - 1); // Erase all but first and last.
  178. size_t i;
  179. for (i = 0; i < str.size(); ++i) {
  180. switch (i) {
  181. case 0:
  182. UNIT_ASSERT(str[i] == *Data_.H());
  183. break;
  184. case 1:
  185. UNIT_ASSERT(str[i] == *Data_.d());
  186. break;
  187. default:
  188. UNIT_ASSERT(false);
  189. }
  190. }
  191. str.insert(1, c_str);
  192. str.erase(str.begin()); // Erase first element.
  193. str.erase(str.end() - 1); // Erase last element.
  194. UNIT_ASSERT(str == c_str);
  195. str.clear(); // Erase all.
  196. UNIT_ASSERT(str.empty());
  197. str = c_str;
  198. UNIT_ASSERT(str == c_str);
  199. str.erase(1, str.size() - 1); // Erase all but first and last.
  200. for (i = 0; i < str.size(); i++) {
  201. switch (i) {
  202. case 0:
  203. UNIT_ASSERT(str[i] == *Data_.H());
  204. break;
  205. case 1:
  206. UNIT_ASSERT(str[i] == *Data_.d());
  207. break;
  208. default:
  209. UNIT_ASSERT(false);
  210. }
  211. }
  212. str.erase(1);
  213. UNIT_ASSERT(str == Data_.H());
  214. }
  215. void data() {
  216. TStringType xx;
  217. // ISO-IEC-14882:1998(E), 21.3.6, paragraph 3
  218. UNIT_ASSERT(xx.data() != nullptr);
  219. }
  220. void c_str() {
  221. TStringType low(Data_._2004_01_01());
  222. TStringType xx;
  223. TStringType yy;
  224. // ISO-IEC-14882:1998(E), 21.3.6, paragraph 1
  225. UNIT_ASSERT(*(yy.c_str()) == 0);
  226. // Blocks A and B should follow each other.
  227. // Block A:
  228. xx = Data_._123456();
  229. xx += low;
  230. UNIT_ASSERT(xx.c_str() == TView(Data_._1234562004_01_01()));
  231. // End of block A
  232. // Block B:
  233. xx = Data_._1234();
  234. xx += Data_._5();
  235. UNIT_ASSERT(xx.c_str() == TView(Data_._12345()));
  236. // End of block B
  237. }
  238. void null_char_of_empty() {
  239. const TStringType s;
  240. UNIT_ASSERT(s[s.size()] == 0);
  241. }
  242. void null_char() {
  243. // ISO/IEC 14882:1998(E), ISO/IEC 14882:2003(E), 21.3.4 ('... the const version')
  244. const TStringType s(Data_._123456());
  245. UNIT_ASSERT(s[s.size()] == 0);
  246. }
  247. // Allowed since C++17, see http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2475
  248. void null_char_assignment_to_subscript_of_empty() {
  249. TStringType s;
  250. #ifdef TSTRING_IS_STD_STRING
  251. using reference = volatile typename TStringType::value_type&;
  252. #else
  253. using reference = typename TStringType::reference;
  254. #endif
  255. reference trailing_zero = s[s.size()];
  256. trailing_zero = 0;
  257. UNIT_ASSERT(trailing_zero == 0);
  258. }
  259. // Allowed since C++17, see http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2475
  260. void null_char_assignment_to_subscript_of_nonempty() {
  261. TStringType s(Data_._123456());
  262. #ifdef TSTRING_IS_STD_STRING
  263. using reference = volatile typename TStringType::value_type&;
  264. #else
  265. using reference = typename TStringType::reference;
  266. #endif
  267. reference trailing_zero = s[s.size()];
  268. trailing_zero = 0;
  269. UNIT_ASSERT(trailing_zero == 0);
  270. }
  271. #ifndef TSTRING_IS_STD_STRING
  272. // Dereferencing string end() is not allowed by C++ standard as of C++20, avoid using in real code.
  273. void null_char_assignment_to_end_of_empty() {
  274. TStringType s;
  275. volatile auto& trailing_zero = *(s.begin() + s.size());
  276. trailing_zero = 0;
  277. UNIT_ASSERT(trailing_zero == 0);
  278. }
  279. // Dereferencing string end() is not allowed by C++ standard as of C++20, avoid using in real code.
  280. void null_char_assignment_to_end_of_nonempty() {
  281. TStringType s(Data_._123456());
  282. volatile auto& trailing_zero = *(s.begin() + s.size());
  283. trailing_zero = 0;
  284. UNIT_ASSERT(trailing_zero == 0);
  285. }
  286. #endif
  287. void insert() {
  288. TStringType strorg = Data_.This_is_test_string_for_string_calls();
  289. TStringType str;
  290. // In case of reallocation there is no auto reference problem
  291. // so we reserve a big enough TStringType to be sure to test this
  292. // particular point.
  293. str.reserve(100);
  294. str = strorg;
  295. //test self insertion:
  296. str.insert(10, str.c_str() + 5, 15);
  297. UNIT_ASSERT(str == Data_.This_is_teis_test_string_st_string_for_string_calls());
  298. str = strorg;
  299. str.insert(15, str.c_str() + 5, 25);
  300. UNIT_ASSERT(str == Data_.This_is_test_stis_test_string_for_stringring_for_string_calls());
  301. str = strorg;
  302. str.insert(0, str.c_str() + str.size() - 4, 4);
  303. UNIT_ASSERT(str == Data_.allsThis_is_test_string_for_string_calls());
  304. str = strorg;
  305. str.insert(0, str.c_str() + str.size() / 2 - 1, str.size() / 2 + 1);
  306. UNIT_ASSERT(str == Data_.ng_for_string_callsThis_is_test_string_for_string_calls());
  307. str = strorg;
  308. typename TStringType::iterator b = str.begin();
  309. typename TStringType::const_iterator s = str.begin() + str.size() / 2 - 1;
  310. typename TStringType::const_iterator e = str.end();
  311. str.insert(b, s, e);
  312. UNIT_ASSERT(str == Data_.ng_for_string_callsThis_is_test_string_for_string_calls());
  313. #if 0
  314. // AV
  315. str = strorg;
  316. str.insert(str.begin(), str.begin() + str.size() / 2 - 1, str.end());
  317. UNIT_ASSERT(str == Data.ng_for_string_callsThis_is_test_string_for_string_calls());
  318. #endif
  319. TStringType str0;
  320. str0.insert(str0.begin(), 5, *Data_._0());
  321. UNIT_ASSERT(str0 == Data_._00000());
  322. TStringType str1;
  323. {
  324. typename TStringType::size_type pos = 0, nb = 2;
  325. str1.insert(pos, nb, *Data_._1());
  326. }
  327. UNIT_ASSERT(str1 == Data_._11());
  328. str0.insert(0, str1);
  329. UNIT_ASSERT(str0 == Data_._1100000());
  330. TStringType str2(Data_._2345());
  331. str0.insert(str0.size(), str2, 1, 2);
  332. UNIT_ASSERT(str0 == Data_._110000034());
  333. str1.insert(str1.begin() + 1, 2, *Data_._2());
  334. UNIT_ASSERT(str1 == Data_._1221());
  335. str1.insert(2, Data_._333333(), 3);
  336. UNIT_ASSERT(str1 == Data_._1233321());
  337. str1.insert(4, Data_._4444());
  338. UNIT_ASSERT(str1 == Data_._12334444321());
  339. str1.insert(str1.begin() + 6, *Data_._5());
  340. UNIT_ASSERT(str1 == Data_._123344544321());
  341. }
  342. void resize() {
  343. TStringType s;
  344. s.resize(0);
  345. UNIT_ASSERT(*s.c_str() == 0);
  346. s = Data_._1234567();
  347. s.resize(0);
  348. UNIT_ASSERT(*s.c_str() == 0);
  349. s = Data_._1234567();
  350. s.resize(1);
  351. UNIT_ASSERT(s.size() == 1);
  352. UNIT_ASSERT(*s.c_str() == *Data_._1());
  353. UNIT_ASSERT(*(s.c_str() + 1) == 0);
  354. s = Data_._1234567();
  355. #if 0
  356. s.resize(10);
  357. #else
  358. s.resize(10, 0);
  359. #endif
  360. UNIT_ASSERT(s.size() == 10);
  361. UNIT_ASSERT(s[6] == *Data_._7());
  362. UNIT_ASSERT(s[7] == 0);
  363. UNIT_ASSERT(s[8] == 0);
  364. UNIT_ASSERT(s[9] == 0);
  365. }
  366. void find() {
  367. TStringType s(Data_.one_two_three_one_two_three());
  368. UNIT_ASSERT(s.find(Data_.one()) == 0);
  369. UNIT_ASSERT(s.find(*Data_.t()) == 4);
  370. UNIT_ASSERT(s.find(*Data_.t(), 5) == 8);
  371. UNIT_ASSERT(s.find(Data_.four()) == TStringType::npos);
  372. UNIT_ASSERT(s.find(Data_.one(), TStringType::npos) == TStringType::npos);
  373. UNIT_ASSERT(s.find_first_of(Data_.abcde()) == 2);
  374. UNIT_ASSERT(s.find_first_not_of(Data_.enotw_()) == 9);
  375. }
  376. void capacity() {
  377. TStringType s;
  378. UNIT_ASSERT(s.capacity() < s.max_size());
  379. UNIT_ASSERT(s.capacity() >= s.size());
  380. for (int i = 0; i < 18; ++i) {
  381. s += ' ';
  382. UNIT_ASSERT(s.capacity() > 0);
  383. UNIT_ASSERT(s.capacity() < s.max_size());
  384. UNIT_ASSERT(s.capacity() >= s.size());
  385. }
  386. }
  387. void assign() {
  388. TStringType s;
  389. TChar const* cstr = Data_.test_string_for_assign();
  390. s.assign(cstr, cstr + 22);
  391. UNIT_ASSERT(s == Data_.test_string_for_assign());
  392. TStringType s2(Data_.other_test_string());
  393. s.assign(s2);
  394. UNIT_ASSERT(s == s2);
  395. static TStringType str1;
  396. static TStringType str2;
  397. // short TStringType optim:
  398. str1 = Data_._123456();
  399. // longer than short TStringType:
  400. str2 = Data_._1234567890123456789012345678901234567890();
  401. UNIT_ASSERT(str1[5] == *Data_._6());
  402. UNIT_ASSERT(str2[29] == *Data_._0());
  403. }
  404. void copy() {
  405. TStringType s(Data_.foo());
  406. TChar dest[4];
  407. dest[0] = dest[1] = dest[2] = dest[3] = 1;
  408. s.copy(dest, 4);
  409. int pos = 0;
  410. UNIT_ASSERT(dest[pos++] == *Data_.f());
  411. UNIT_ASSERT(dest[pos++] == *Data_.o());
  412. UNIT_ASSERT(dest[pos++] == *Data_.o());
  413. UNIT_ASSERT(dest[pos++] == 1);
  414. dest[0] = dest[1] = dest[2] = dest[3] = 1;
  415. s.copy(dest, 4, 2);
  416. pos = 0;
  417. UNIT_ASSERT(dest[pos++] == *Data_.o());
  418. UNIT_ASSERT(dest[pos++] == 1);
  419. // @todo use UNIT_TEST_EXCEPTION
  420. try {
  421. s.copy(dest, 4, 5);
  422. UNIT_ASSERT(!"expected std::out_of_range");
  423. } catch (const std::out_of_range&) {
  424. UNIT_ASSERT(true);
  425. } catch (...) {
  426. UNIT_ASSERT(!"expected std::out_of_range");
  427. }
  428. }
  429. void cbegin_cend() {
  430. const char helloThere[] = "Hello there";
  431. TString s = helloThere;
  432. size_t index = 0;
  433. for (auto it = s.cbegin(); s.cend() != it; ++it, ++index) {
  434. UNIT_ASSERT_VALUES_EQUAL(helloThere[index], *it);
  435. }
  436. }
  437. void compare() {
  438. TStringType str1(Data_.abcdef());
  439. TStringType str2;
  440. str2 = Data_.abcdef();
  441. UNIT_ASSERT(str1.compare(str2) == 0);
  442. UNIT_ASSERT(str1.compare(str2.data(), str2.size()) == 0);
  443. str2 = Data_.abcde();
  444. UNIT_ASSERT(str1.compare(str2) > 0);
  445. UNIT_ASSERT(str1.compare(str2.data(), str2.size()) > 0);
  446. str2 = Data_.abcdefg();
  447. UNIT_ASSERT(str1.compare(str2) < 0);
  448. UNIT_ASSERT(str1.compare(str2.data(), str2.size()) < 0);
  449. UNIT_ASSERT(str1.compare(Data_.abcdef()) == 0);
  450. UNIT_ASSERT(str1.compare(Data_.abcde()) > 0);
  451. UNIT_ASSERT(str1.compare(Data_.abcdefg()) < 0);
  452. str2 = Data_.cde();
  453. UNIT_ASSERT(str1.compare(2, 3, str2) == 0);
  454. str2 = Data_.cd();
  455. UNIT_ASSERT(str1.compare(2, 3, str2) > 0);
  456. str2 = Data_.cdef();
  457. UNIT_ASSERT(str1.compare(2, 3, str2) < 0);
  458. str2 = Data_.abcdef();
  459. UNIT_ASSERT(str1.compare(2, 3, str2, 2, 3) == 0);
  460. UNIT_ASSERT(str1.compare(2, 3, str2, 2, 2) > 0);
  461. UNIT_ASSERT(str1.compare(2, 3, str2, 2, 4) < 0);
  462. UNIT_ASSERT(str1.compare(2, 3, Data_.cdefgh(), 3) == 0);
  463. UNIT_ASSERT(str1.compare(2, 3, Data_.cdefgh(), 2) > 0);
  464. UNIT_ASSERT(str1.compare(2, 3, Data_.cdefgh(), 4) < 0);
  465. }
  466. void find_last_of() {
  467. // 21.3.6.4
  468. TStringType s(Data_.one_two_three_one_two_three());
  469. UNIT_ASSERT(s.find_last_of(Data_.abcde()) == 26);
  470. UNIT_ASSERT(s.find_last_of(TStringType(Data_.abcde())) == 26);
  471. TStringType test(Data_.aba());
  472. UNIT_ASSERT(test.find_last_of(Data_.a(), 2, 1) == 2);
  473. UNIT_ASSERT(test.find_last_of(Data_.a(), 1, 1) == 0);
  474. UNIT_ASSERT(test.find_last_of(Data_.a(), 0, 1) == 0);
  475. UNIT_ASSERT(test.find_last_of(*Data_.a(), 2) == 2);
  476. UNIT_ASSERT(test.find_last_of(*Data_.a(), 1) == 0);
  477. UNIT_ASSERT(test.find_last_of(*Data_.a(), 0) == 0);
  478. }
  479. #if 0
  480. void rfind() {
  481. // 21.3.6.2
  482. TStringType s(Data.one_two_three_one_two_three());
  483. UNIT_ASSERT(s.rfind(Data.two()) == 18);
  484. UNIT_ASSERT(s.rfind(Data.two(), 0) == TStringType::npos);
  485. UNIT_ASSERT(s.rfind(Data.two(), 11) == 4);
  486. UNIT_ASSERT(s.rfind(*Data.w()) == 19);
  487. TStringType test(Data.aba());
  488. UNIT_ASSERT(test.rfind(Data.a(), 2, 1) == 2);
  489. UNIT_ASSERT(test.rfind(Data.a(), 1, 1) == 0);
  490. UNIT_ASSERT(test.rfind(Data.a(), 0, 1) == 0);
  491. UNIT_ASSERT(test.rfind(*Data.a(), 2) == 2);
  492. UNIT_ASSERT(test.rfind(*Data.a(), 1) == 0);
  493. UNIT_ASSERT(test.rfind(*Data.a(), 0) == 0);
  494. }
  495. #endif
  496. void find_last_not_of() {
  497. // 21.3.6.6
  498. TStringType s(Data_.one_two_three_one_two_three());
  499. UNIT_ASSERT(s.find_last_not_of(Data_.ehortw_()) == 15);
  500. TStringType test(Data_.aba());
  501. UNIT_ASSERT(test.find_last_not_of(Data_.a(), 2, 1) == 1);
  502. UNIT_ASSERT(test.find_last_not_of(Data_.b(), 2, 1) == 2);
  503. UNIT_ASSERT(test.find_last_not_of(Data_.a(), 1, 1) == 1);
  504. UNIT_ASSERT(test.find_last_not_of(Data_.b(), 1, 1) == 0);
  505. UNIT_ASSERT(test.find_last_not_of(Data_.a(), 0, 1) == TStringType::npos);
  506. UNIT_ASSERT(test.find_last_not_of(Data_.b(), 0, 1) == 0);
  507. UNIT_ASSERT(test.find_last_not_of(*Data_.a(), 2) == 1);
  508. UNIT_ASSERT(test.find_last_not_of(*Data_.b(), 2) == 2);
  509. UNIT_ASSERT(test.find_last_not_of(*Data_.a(), 1) == 1);
  510. UNIT_ASSERT(test.find_last_not_of(*Data_.b(), 1) == 0);
  511. UNIT_ASSERT(test.find_last_not_of(*Data_.a(), 0) == TStringType::npos);
  512. UNIT_ASSERT(test.find_last_not_of(*Data_.b(), 0) == 0);
  513. }
  514. #if 0
  515. void replace() {
  516. // This test case is for the non template basic_TString::replace method,
  517. // this is why we play with the const iterators and reference to guaranty
  518. // that the right method is called.
  519. const TStringType v(Data._78());
  520. TStringType s(Data._123456());
  521. TStringType const& cs = s;
  522. typename TStringType::iterator i = s.begin() + 1;
  523. s.replace(i, i + 3, v.begin(), v.end());
  524. UNIT_ASSERT(s == Data._17856());
  525. s = Data._123456();
  526. i = s.begin() + 1;
  527. s.replace(i, i + 1, v.begin(), v.end());
  528. UNIT_ASSERT(s == Data._1783456());
  529. s = Data._123456();
  530. i = s.begin() + 1;
  531. typename TStringType::const_iterator ci = s.begin() + 1;
  532. s.replace(i, i + 3, ci + 3, cs.end());
  533. UNIT_ASSERT(s == Data._15656());
  534. s = Data._123456();
  535. i = s.begin() + 1;
  536. ci = s.begin() + 1;
  537. s.replace(i, i + 3, ci, ci + 2);
  538. UNIT_ASSERT(s == Data._12356());
  539. s = Data._123456();
  540. i = s.begin() + 1;
  541. ci = s.begin() + 1;
  542. s.replace(i, i + 3, ci + 1, cs.end());
  543. UNIT_ASSERT(s == Data._1345656());
  544. s = Data._123456();
  545. i = s.begin();
  546. ci = s.begin() + 1;
  547. s.replace(i, i, ci, ci + 1);
  548. UNIT_ASSERT(s == Data._2123456());
  549. s = Data._123456();
  550. s.replace(s.begin() + 4, s.end(), cs.begin(), cs.end());
  551. UNIT_ASSERT(s == Data._1234123456());
  552. // This is the test for the template replace method.
  553. s = Data._123456();
  554. typename TStringType::iterator b = s.begin() + 4;
  555. typename TStringType::iterator e = s.end();
  556. typename TStringType::const_iterator rb = s.begin();
  557. typename TStringType::const_iterator re = s.end();
  558. s.replace(b, e, rb, re);
  559. UNIT_ASSERT(s == Data._1234123456());
  560. s = Data._123456();
  561. s.replace(s.begin() + 4, s.end(), s.begin(), s.end());
  562. UNIT_ASSERT(s == Data._1234123456());
  563. TStringType strorg(Data.This_is_test_StringT_for_StringT_calls());
  564. TStringType str = strorg;
  565. str.replace(5, 15, str.c_str(), 10);
  566. UNIT_ASSERT(str == Data.This_This_is_tefor_StringT_calls());
  567. str = strorg;
  568. str.replace(5, 5, str.c_str(), 10);
  569. UNIT_ASSERT(str == Data.This_This_is_test_StringT_for_StringT_calls());
  570. #if !defined(STLPORT) || defined(_STLP_MEMBER_TEMPLATES)
  571. deque<TChar> cdeque;
  572. cdeque.push_back(*Data.I());
  573. str.replace(str.begin(), str.begin() + 11, cdeque.begin(), cdeque.end());
  574. UNIT_ASSERT(str == Data.Is_test_StringT_for_StringT_calls());
  575. #endif
  576. }
  577. #endif
  578. }; // TStringStdTestImpl
  579. class TStringTest: public TTestBase, private TStringTestImpl<TString, TTestData<char>> {
  580. public:
  581. UNIT_TEST_SUITE(TStringTest);
  582. UNIT_TEST(TestMaxSize);
  583. UNIT_TEST(TestConstructors);
  584. UNIT_TEST(TestReplace);
  585. #ifndef TSTRING_IS_STD_STRING
  586. UNIT_TEST(TestRefCount);
  587. #endif
  588. UNIT_TEST(TestFind);
  589. UNIT_TEST(TestContains);
  590. UNIT_TEST(TestOperators);
  591. UNIT_TEST(TestMulOperators);
  592. UNIT_TEST(TestFuncs);
  593. UNIT_TEST(TestUtils);
  594. UNIT_TEST(TestEmpty);
  595. UNIT_TEST(TestJoin);
  596. UNIT_TEST(TestCopy);
  597. UNIT_TEST(TestStrCpy);
  598. UNIT_TEST(TestPrefixSuffix);
  599. #ifndef TSTRING_IS_STD_STRING
  600. UNIT_TEST(TestCharRef);
  601. #endif
  602. UNIT_TEST(TestBack)
  603. UNIT_TEST(TestFront)
  604. UNIT_TEST(TestIterators);
  605. UNIT_TEST(TestReverseIterators);
  606. UNIT_TEST(TestAppendUtf16)
  607. UNIT_TEST(TestFillingAssign)
  608. UNIT_TEST(TestStdStreamApi)
  609. //UNIT_TEST(TestOperatorsCI); must fail
  610. UNIT_TEST_SUITE_END();
  611. void TestAppendUtf16() {
  612. TString appended = TString("А роза упала").AppendUtf16(u" на лапу Азора");
  613. UNIT_ASSERT(appended == "А роза упала на лапу Азора");
  614. }
  615. void TestFillingAssign() {
  616. TString s("abc");
  617. s.assign(5, 'a');
  618. UNIT_ASSERT_VALUES_EQUAL(s, "aaaaa");
  619. }
  620. void TestStdStreamApi() {
  621. const TString data = "abracadabra";
  622. std::stringstream ss;
  623. ss << data;
  624. UNIT_ASSERT_VALUES_EQUAL(data, ss.str());
  625. ss << '\n'
  626. << data << std::endl;
  627. TString read = "xxx";
  628. ss >> read;
  629. UNIT_ASSERT_VALUES_EQUAL(read, data);
  630. }
  631. };
  632. UNIT_TEST_SUITE_REGISTRATION(TStringTest);
  633. class TWideStringTest: public TTestBase, private TStringTestImpl<TUtf16String, TTestData<wchar16>> {
  634. public:
  635. UNIT_TEST_SUITE(TWideStringTest);
  636. UNIT_TEST(TestConstructors);
  637. UNIT_TEST(TestReplace);
  638. #ifndef TSTRING_IS_STD_STRING
  639. UNIT_TEST(TestRefCount);
  640. #endif
  641. UNIT_TEST(TestFind);
  642. UNIT_TEST(TestContains);
  643. UNIT_TEST(TestOperators);
  644. UNIT_TEST(TestLetOperator)
  645. UNIT_TEST(TestMulOperators);
  646. UNIT_TEST(TestFuncs);
  647. UNIT_TEST(TestUtils);
  648. UNIT_TEST(TestEmpty);
  649. UNIT_TEST(TestJoin);
  650. UNIT_TEST(TestCopy);
  651. UNIT_TEST(TestStrCpy);
  652. UNIT_TEST(TestPrefixSuffix);
  653. #ifndef TSTRING_IS_STD_STRING
  654. UNIT_TEST(TestCharRef);
  655. #endif
  656. UNIT_TEST(TestBack);
  657. UNIT_TEST(TestFront)
  658. UNIT_TEST(TestDecodingMethods);
  659. UNIT_TEST(TestIterators);
  660. UNIT_TEST(TestReverseIterators);
  661. UNIT_TEST(TestStringLiterals);
  662. UNIT_TEST_SUITE_END();
  663. private:
  664. void TestDecodingMethods() {
  665. UNIT_ASSERT(TUtf16String::FromAscii("").empty());
  666. UNIT_ASSERT(TUtf16String::FromAscii("abc") == ASCIIToWide("abc"));
  667. const char* text = "123kx83abcd ej)#$%ddja&%J&";
  668. TUtf16String wtext = ASCIIToWide(text);
  669. UNIT_ASSERT(wtext == TUtf16String::FromAscii(text));
  670. TString strtext(text);
  671. UNIT_ASSERT(wtext == TUtf16String::FromAscii(strtext));
  672. TStringBuf strbuftext(text);
  673. UNIT_ASSERT(wtext == TUtf16String::FromAscii(strbuftext));
  674. UNIT_ASSERT(wtext.substr(5) == TUtf16String::FromAscii(text + 5));
  675. const wchar16 wideCyrillicAlphabet[] = {
  676. 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
  677. 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
  678. 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
  679. 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
  680. 0x00};
  681. TUtf16String strWide(wideCyrillicAlphabet);
  682. TString strUtf8 = WideToUTF8(strWide);
  683. UNIT_ASSERT(strWide == TUtf16String::FromUtf8(strUtf8.c_str()));
  684. UNIT_ASSERT(strWide == TUtf16String::FromUtf8(strUtf8));
  685. UNIT_ASSERT(strWide == TUtf16String::FromUtf8(TStringBuf(strUtf8)));
  686. // assign
  687. TUtf16String s1;
  688. s1.AssignAscii("1234");
  689. UNIT_ASSERT(s1 == ASCIIToWide("1234"));
  690. s1.AssignUtf8(strUtf8);
  691. UNIT_ASSERT(s1 == strWide);
  692. s1.AssignAscii(text);
  693. UNIT_ASSERT(s1 == wtext);
  694. // append
  695. TUtf16String s2;
  696. TUtf16String testAppend = strWide;
  697. s2.AppendUtf8(strUtf8);
  698. UNIT_ASSERT(testAppend == s2);
  699. testAppend += ' ';
  700. s2.AppendAscii(" ");
  701. UNIT_ASSERT(testAppend == s2);
  702. testAppend += '_';
  703. s2.AppendUtf8("_");
  704. UNIT_ASSERT(testAppend == s2);
  705. testAppend += wtext;
  706. s2.AppendAscii(text);
  707. UNIT_ASSERT(testAppend == s2);
  708. testAppend += wtext;
  709. s2.AppendUtf8(text);
  710. UNIT_ASSERT(testAppend == s2);
  711. }
  712. void TestLetOperator() {
  713. TUtf16String str;
  714. str = wchar16('X');
  715. UNIT_ASSERT(str == TUtf16String::FromAscii("X"));
  716. const TUtf16String hello = TUtf16String::FromAscii("hello");
  717. str = hello.data();
  718. UNIT_ASSERT(str == hello);
  719. str = hello;
  720. UNIT_ASSERT(str == hello);
  721. }
  722. void TestStringLiterals() {
  723. TUtf16String s1 = u"hello";
  724. UNIT_ASSERT_VALUES_EQUAL(s1, TUtf16String::FromAscii("hello"));
  725. TUtf16String s2 = u"привет";
  726. UNIT_ASSERT_VALUES_EQUAL(s2, TUtf16String::FromUtf8("привет"));
  727. }
  728. };
  729. UNIT_TEST_SUITE_REGISTRATION(TWideStringTest);
  730. class TUtf32StringTest: public TTestBase, private TStringTestImpl<TUtf32String, TTestData<wchar32>> {
  731. public:
  732. UNIT_TEST_SUITE(TUtf32StringTest);
  733. UNIT_TEST(TestConstructors);
  734. UNIT_TEST(TestReplace);
  735. #ifndef TSTRING_IS_STD_STRING
  736. UNIT_TEST(TestRefCount);
  737. #endif
  738. UNIT_TEST(TestFind);
  739. UNIT_TEST(TestContains);
  740. UNIT_TEST(TestOperators);
  741. UNIT_TEST(TestLetOperator)
  742. UNIT_TEST(TestMulOperators);
  743. UNIT_TEST(TestFuncs);
  744. UNIT_TEST(TestUtils);
  745. UNIT_TEST(TestEmpty);
  746. UNIT_TEST(TestJoin);
  747. UNIT_TEST(TestCopy);
  748. UNIT_TEST(TestStrCpy);
  749. UNIT_TEST(TestPrefixSuffix);
  750. #ifndef TSTRING_IS_STD_STRING
  751. UNIT_TEST(TestCharRef);
  752. #endif
  753. UNIT_TEST(TestBack);
  754. UNIT_TEST(TestFront)
  755. UNIT_TEST(TestDecodingMethods);
  756. UNIT_TEST(TestDecodingMethodsMixedStr);
  757. UNIT_TEST(TestIterators);
  758. UNIT_TEST(TestReverseIterators);
  759. UNIT_TEST(TestStringLiterals);
  760. UNIT_TEST_SUITE_END();
  761. private:
  762. void TestDecodingMethods() {
  763. UNIT_ASSERT(TUtf32String::FromAscii("").empty());
  764. UNIT_ASSERT(TUtf32String::FromAscii("abc") == ASCIIToUTF32("abc"));
  765. const char* text = "123kx83abcd ej)#$%ddja&%J&";
  766. TUtf32String wtext = ASCIIToUTF32(text);
  767. UNIT_ASSERT(wtext == TUtf32String::FromAscii(text));
  768. TString strtext(text);
  769. UNIT_ASSERT(wtext == TUtf32String::FromAscii(strtext));
  770. TStringBuf strbuftext(text);
  771. UNIT_ASSERT(wtext == TUtf32String::FromAscii(strbuftext));
  772. UNIT_ASSERT(wtext.substr(5) == TUtf32String::FromAscii(text + 5));
  773. const wchar32 wideCyrillicAlphabet[] = {
  774. 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
  775. 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
  776. 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
  777. 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
  778. 0x00};
  779. TUtf32String strWide(wideCyrillicAlphabet);
  780. TString strUtf8 = WideToUTF8(strWide);
  781. UNIT_ASSERT(strWide == TUtf32String::FromUtf8(strUtf8.c_str()));
  782. UNIT_ASSERT(strWide == TUtf32String::FromUtf8(strUtf8));
  783. UNIT_ASSERT(strWide == TUtf32String::FromUtf8(TStringBuf(strUtf8)));
  784. // assign
  785. TUtf32String s1;
  786. s1.AssignAscii("1234");
  787. UNIT_ASSERT(s1 == ASCIIToUTF32("1234"));
  788. s1.AssignUtf8(strUtf8);
  789. UNIT_ASSERT(s1 == strWide);
  790. s1.AssignAscii(text);
  791. UNIT_ASSERT(s1 == wtext);
  792. // append
  793. TUtf32String s2;
  794. TUtf32String testAppend = strWide;
  795. s2.AppendUtf8(strUtf8);
  796. UNIT_ASSERT(testAppend == s2);
  797. testAppend += ' ';
  798. s2.AppendAscii(" ");
  799. UNIT_ASSERT(testAppend == s2);
  800. testAppend += '_';
  801. s2.AppendUtf8("_");
  802. UNIT_ASSERT(testAppend == s2);
  803. testAppend += wtext;
  804. s2.AppendAscii(text);
  805. UNIT_ASSERT(testAppend == s2);
  806. testAppend += wtext;
  807. s2.AppendUtf8(text);
  808. UNIT_ASSERT(testAppend == s2);
  809. }
  810. void TestDecodingMethodsMixedStr() {
  811. UNIT_ASSERT(TUtf32String::FromAscii("").empty());
  812. UNIT_ASSERT(TUtf32String::FromAscii("abc") == ASCIIToUTF32("abc"));
  813. const char* text = "123kx83abcd ej)#$%ddja&%J&";
  814. TUtf32String wtext = ASCIIToUTF32(text);
  815. UNIT_ASSERT(wtext == TUtf32String::FromAscii(text));
  816. TString strtext(text);
  817. UNIT_ASSERT(wtext == TUtf32String::FromAscii(strtext));
  818. TStringBuf strbuftext(text);
  819. UNIT_ASSERT(wtext == TUtf32String::FromAscii(strbuftext));
  820. UNIT_ASSERT(wtext.substr(5) == TUtf32String::FromAscii(text + 5));
  821. const wchar32 cyrilicAndLatinWide[] = {
  822. 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
  823. 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
  824. 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
  825. wchar32('z'),
  826. 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
  827. wchar32('z'),
  828. 0x00};
  829. TUtf32String strWide(cyrilicAndLatinWide);
  830. TString strUtf8 = WideToUTF8(strWide);
  831. UNIT_ASSERT(strWide == TUtf32String::FromUtf8(strUtf8.c_str()));
  832. UNIT_ASSERT(strWide == TUtf32String::FromUtf8(strUtf8));
  833. UNIT_ASSERT(strWide == UTF8ToUTF32<true>(strUtf8));
  834. UNIT_ASSERT(strWide == UTF8ToUTF32<false>(strUtf8));
  835. UNIT_ASSERT(strWide == TUtf32String::FromUtf8(TStringBuf(strUtf8)));
  836. // assign
  837. TUtf32String s1;
  838. s1.AssignAscii("1234");
  839. UNIT_ASSERT(s1 == ASCIIToUTF32("1234"));
  840. s1.AssignUtf8(strUtf8);
  841. UNIT_ASSERT(s1 == strWide);
  842. s1.AssignAscii(text);
  843. UNIT_ASSERT(s1 == wtext);
  844. // append
  845. TUtf32String s2;
  846. TUtf32String testAppend = strWide;
  847. s2.AppendUtf16(UTF8ToWide(strUtf8));
  848. UNIT_ASSERT(testAppend == s2);
  849. testAppend += ' ';
  850. s2.AppendAscii(" ");
  851. UNIT_ASSERT(testAppend == s2);
  852. testAppend += '_';
  853. s2.AppendUtf8("_");
  854. UNIT_ASSERT(testAppend == s2);
  855. testAppend += wtext;
  856. s2.AppendAscii(text);
  857. UNIT_ASSERT(testAppend == s2);
  858. testAppend += wtext;
  859. s2.AppendUtf8(text);
  860. UNIT_ASSERT(testAppend == s2);
  861. }
  862. void TestLetOperator() {
  863. TUtf32String str;
  864. str = wchar32('X');
  865. UNIT_ASSERT(str == TUtf32String::FromAscii("X"));
  866. const TUtf32String hello = TUtf32String::FromAscii("hello");
  867. str = hello.data();
  868. UNIT_ASSERT(str == hello);
  869. str = hello;
  870. UNIT_ASSERT(str == hello);
  871. }
  872. void TestStringLiterals() {
  873. TUtf32String s1 = U"hello";
  874. UNIT_ASSERT_VALUES_EQUAL(s1, TUtf32String::FromAscii("hello"));
  875. TUtf32String s2 = U"привет";
  876. UNIT_ASSERT_VALUES_EQUAL(s2, TUtf32String::FromUtf8("привет"));
  877. }
  878. };
  879. UNIT_TEST_SUITE_REGISTRATION(TUtf32StringTest);
  880. class TStringStdTest: public TTestBase, private TStringStdTestImpl<TString, TTestData<char>> {
  881. public:
  882. UNIT_TEST_SUITE(TStringStdTest);
  883. UNIT_TEST(Constructor);
  884. UNIT_TEST(reserve);
  885. UNIT_TEST(short_string);
  886. UNIT_TEST(erase);
  887. UNIT_TEST(data);
  888. UNIT_TEST(c_str);
  889. UNIT_TEST(null_char_of_empty);
  890. UNIT_TEST(null_char);
  891. UNIT_TEST(null_char_assignment_to_subscript_of_empty);
  892. UNIT_TEST(null_char_assignment_to_subscript_of_nonempty);
  893. #ifndef TSTRING_IS_STD_STRING
  894. UNIT_TEST(null_char_assignment_to_end_of_empty);
  895. UNIT_TEST(null_char_assignment_to_end_of_nonempty);
  896. #endif
  897. UNIT_TEST(insert);
  898. UNIT_TEST(resize);
  899. UNIT_TEST(find);
  900. UNIT_TEST(capacity);
  901. UNIT_TEST(assign);
  902. UNIT_TEST(copy);
  903. UNIT_TEST(cbegin_cend);
  904. UNIT_TEST(compare);
  905. UNIT_TEST(find_last_of);
  906. #if 0
  907. UNIT_TEST(rfind);
  908. UNIT_TEST(replace);
  909. #endif
  910. UNIT_TEST(find_last_not_of);
  911. UNIT_TEST_SUITE_END();
  912. };
  913. UNIT_TEST_SUITE_REGISTRATION(TStringStdTest);
  914. class TWideStringStdTest: public TTestBase, private TStringStdTestImpl<TUtf16String, TTestData<wchar16>> {
  915. public:
  916. UNIT_TEST_SUITE(TWideStringStdTest);
  917. UNIT_TEST(Constructor);
  918. UNIT_TEST(reserve);
  919. UNIT_TEST(short_string);
  920. UNIT_TEST(erase);
  921. UNIT_TEST(data);
  922. UNIT_TEST(c_str);
  923. UNIT_TEST(null_char_of_empty);
  924. UNIT_TEST(null_char);
  925. UNIT_TEST(null_char_assignment_to_subscript_of_empty);
  926. UNIT_TEST(null_char_assignment_to_subscript_of_nonempty);
  927. #ifndef TSTRING_IS_STD_STRING
  928. UNIT_TEST(null_char_assignment_to_end_of_empty);
  929. UNIT_TEST(null_char_assignment_to_end_of_nonempty);
  930. #endif
  931. UNIT_TEST(insert);
  932. UNIT_TEST(resize);
  933. UNIT_TEST(find);
  934. UNIT_TEST(capacity);
  935. UNIT_TEST(assign);
  936. UNIT_TEST(copy);
  937. UNIT_TEST(cbegin_cend);
  938. UNIT_TEST(compare);
  939. UNIT_TEST(find_last_of);
  940. #if 0
  941. UNIT_TEST(rfind);
  942. UNIT_TEST(replace);
  943. #endif
  944. UNIT_TEST(find_last_not_of);
  945. UNIT_TEST_SUITE_END();
  946. };
  947. UNIT_TEST_SUITE_REGISTRATION(TWideStringStdTest);
  948. Y_UNIT_TEST_SUITE(TStringConversionTest) {
  949. Y_UNIT_TEST(ConversionToStdStringTest) {
  950. TString abra = "cadabra";
  951. std::string stdAbra = abra;
  952. UNIT_ASSERT_VALUES_EQUAL(stdAbra, "cadabra");
  953. }
  954. Y_UNIT_TEST(ConversionToStdStringViewTest) {
  955. TString abra = "cadabra";
  956. std::string_view stdAbra = abra;
  957. UNIT_ASSERT_VALUES_EQUAL(stdAbra, "cadabra");
  958. }
  959. }
  960. Y_UNIT_TEST_SUITE(HashFunctorTests) {
  961. Y_UNIT_TEST(TestTransparency) {
  962. THash<TString> h;
  963. const char* ptr = "a";
  964. const TStringBuf strbuf = ptr;
  965. const TString str = ptr;
  966. const std::string stdStr = ptr;
  967. UNIT_ASSERT_VALUES_EQUAL(h(ptr), h(strbuf));
  968. UNIT_ASSERT_VALUES_EQUAL(h(ptr), h(str));
  969. UNIT_ASSERT_VALUES_EQUAL(h(ptr), h(stdStr));
  970. }
  971. }
  972. #if !defined(TSTRING_IS_STD_STRING)
  973. Y_UNIT_TEST_SUITE(StdNonConformant) {
  974. Y_UNIT_TEST(TestEraseNoThrow) {
  975. TString x;
  976. LegacyErase(x, 10);
  977. }
  978. Y_UNIT_TEST(TestReplaceNoThrow) {
  979. TString x;
  980. LegacyReplace(x, 0, 0, "1");
  981. UNIT_ASSERT_VALUES_EQUAL(x, "1");
  982. LegacyReplace(x, 10, 0, "1");
  983. UNIT_ASSERT_VALUES_EQUAL(x, "1");
  984. }
  985. Y_UNIT_TEST(TestNoAlias) {
  986. TString s = "x";
  987. s.AppendNoAlias("abc", 3);
  988. UNIT_ASSERT_VALUES_EQUAL(s, "xabc");
  989. UNIT_ASSERT_VALUES_EQUAL(TString(s.c_str()), "xabc");
  990. }
  991. }
  992. #endif
  993. Y_UNIT_TEST_SUITE(Interop) {
  994. static void Mutate(std::string& s) {
  995. s += "y";
  996. }
  997. static void Mutate(TString& s) {
  998. Mutate(MutRef(s));
  999. }
  1000. Y_UNIT_TEST(TestMutate) {
  1001. TString x = "x";
  1002. Mutate(x);
  1003. UNIT_ASSERT_VALUES_EQUAL(x, "xy");
  1004. }
  1005. static std::string TransformStd(const std::string& s) {
  1006. return s + "y";
  1007. }
  1008. static TString Transform(const TString& s) {
  1009. return TransformStd(s);
  1010. }
  1011. Y_UNIT_TEST(TestTransform) {
  1012. UNIT_ASSERT_VALUES_EQUAL(Transform(TString("x")), "xy");
  1013. }
  1014. Y_UNIT_TEST(TestTemp) {
  1015. UNIT_ASSERT_VALUES_EQUAL("x" + ConstRef(TString("y")), "xy");
  1016. }
  1017. }