subst_ut.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. #include "join.h"
  2. #include "subst.h"
  3. #include <string>
  4. #include <library/cpp/testing/unittest/registar.h>
  5. Y_UNIT_TEST_SUITE(TStringSubst) {
  6. static const size_t MIN_FROM_CTX = 4;
  7. static const TVector<TString> ALL_FROM{TString("F"), TString("FF")};
  8. static const TVector<TString> ALL_TO{TString(""), TString("T"), TString("TT"), TString("TTT")};
  9. static void AssertSubstGlobal(const TString& sFrom, const TString& sTo, const TString& from, const TString& to, const size_t fromPos, const size_t numSubst) {
  10. TString s = sFrom;
  11. size_t res = SubstGlobal(s, from, to, fromPos);
  12. UNIT_ASSERT_VALUES_EQUAL_C(res, numSubst,
  13. TStringBuilder() << "numSubst=" << numSubst << ", fromPos=" << fromPos << ", " << sFrom << " -> " << sTo);
  14. if (numSubst) {
  15. UNIT_ASSERT_STRINGS_EQUAL_C(s, sTo,
  16. TStringBuilder() << "numSubst=" << numSubst << ", fromPos=" << fromPos << ", " << sFrom << " -> " << sTo);
  17. } else {
  18. // ensure s didn't trigger copy-on-write
  19. UNIT_ASSERT_VALUES_EQUAL_C(s.c_str(), sFrom.c_str(),
  20. TStringBuilder() << "numSubst=" << numSubst << ", fromPos=" << fromPos << ", " << sFrom << " -> " << sTo);
  21. }
  22. }
  23. Y_UNIT_TEST(TestSubstGlobalNoSubstA) {
  24. for (const auto& from : ALL_FROM) {
  25. const size_t fromSz = from.size();
  26. const size_t minSz = fromSz;
  27. const size_t maxSz = fromSz + MIN_FROM_CTX;
  28. for (size_t sz = minSz; sz <= maxSz; ++sz) {
  29. for (size_t fromPos = 0; fromPos < sz; ++fromPos) {
  30. TString s{sz, '.'};
  31. for (const auto& to : ALL_TO) {
  32. AssertSubstGlobal(s, s, from, to, fromPos, 0);
  33. }
  34. }
  35. }
  36. }
  37. }
  38. Y_UNIT_TEST(TestSubstGlobalNoSubstB) {
  39. for (const auto& from : ALL_FROM) {
  40. const size_t fromSz = from.size();
  41. const size_t minSz = fromSz;
  42. const size_t maxSz = fromSz + MIN_FROM_CTX;
  43. for (size_t sz = minSz; sz <= maxSz; ++sz) {
  44. for (size_t fromPos = 0; fromPos <= sz - fromSz; ++fromPos) {
  45. for (size_t fromBeg = 0; fromBeg < fromPos; ++fromBeg) {
  46. const auto parts = {
  47. TString{fromBeg, '.'},
  48. TString{sz - fromSz - fromBeg, '.'}};
  49. TString s = JoinSeq(from, parts);
  50. for (const auto& to : ALL_TO) {
  51. AssertSubstGlobal(s, s, from, to, fromPos, 0);
  52. }
  53. }
  54. }
  55. }
  56. }
  57. }
  58. static void DoTestSubstGlobal(TVector<TString>& parts, const size_t minBeg, const size_t sz,
  59. const TString& from, const size_t fromPos, const size_t numSubst) {
  60. const size_t numLeft = numSubst - parts.size();
  61. for (size_t fromBeg = minBeg; fromBeg <= sz - numLeft * from.size(); ++fromBeg) {
  62. if (parts.empty()) {
  63. parts.emplace_back(fromBeg, '.');
  64. } else {
  65. parts.emplace_back(fromBeg - minBeg, '.');
  66. }
  67. if (numLeft == 1) {
  68. parts.emplace_back(sz - fromBeg - from.size(), '.');
  69. TString sFrom = JoinSeq(from, parts);
  70. UNIT_ASSERT_VALUES_EQUAL_C(sFrom.size(), sz, sFrom);
  71. for (const auto& to : ALL_TO) {
  72. TString sTo = JoinSeq(to, parts);
  73. AssertSubstGlobal(sFrom, sTo, from, to, fromPos, numSubst);
  74. }
  75. parts.pop_back();
  76. } else {
  77. DoTestSubstGlobal(parts, fromBeg + from.size(), sz, from, fromPos, numSubst);
  78. }
  79. parts.pop_back();
  80. }
  81. }
  82. static void DoTestSubstGlobal(size_t numSubst) {
  83. TVector<TString> parts;
  84. for (const auto& from : ALL_FROM) {
  85. const size_t fromSz = from.size();
  86. const size_t minSz = numSubst * fromSz;
  87. const size_t maxSz = numSubst * (fromSz + MIN_FROM_CTX);
  88. for (size_t sz = minSz; sz <= maxSz; ++sz) {
  89. const size_t maxPos = sz - numSubst * fromSz;
  90. for (size_t fromPos = 0; fromPos <= maxPos; ++fromPos) {
  91. DoTestSubstGlobal(parts, fromPos, sz, from, fromPos, numSubst);
  92. }
  93. }
  94. }
  95. }
  96. Y_UNIT_TEST(TestSubstGlobalSubst1) {
  97. DoTestSubstGlobal(1);
  98. }
  99. Y_UNIT_TEST(TestSubstGlobalSubst2) {
  100. DoTestSubstGlobal(2);
  101. }
  102. Y_UNIT_TEST(TestSubstGlobalSubst3) {
  103. DoTestSubstGlobal(3);
  104. }
  105. Y_UNIT_TEST(TestSubstGlobalSubst4) {
  106. DoTestSubstGlobal(4);
  107. }
  108. Y_UNIT_TEST(TestSubstGlobalOld) {
  109. TString s;
  110. s = "aaa";
  111. SubstGlobal(s, "a", "bb");
  112. UNIT_ASSERT_EQUAL(s, TString("bbbbbb"));
  113. s = "aaa";
  114. SubstGlobal(s, "a", "b");
  115. UNIT_ASSERT_EQUAL(s, TString("bbb"));
  116. s = "aaa";
  117. SubstGlobal(s, "a", "");
  118. UNIT_ASSERT_EQUAL(s, TString(""));
  119. s = "abcdefbcbcdfb";
  120. SubstGlobal(s, "bc", "bbc", 2);
  121. UNIT_ASSERT_EQUAL(s, TString("abcdefbbcbbcdfb"));
  122. s = "Москва ~ Париж";
  123. SubstGlobal(s, " ~ ", " ");
  124. UNIT_ASSERT_EQUAL(s, TString("Москва Париж"));
  125. }
  126. Y_UNIT_TEST(TestSubstGlobalOldRet) {
  127. const TString s1 = "aaa";
  128. const TString s2 = SubstGlobalCopy(s1, "a", "bb");
  129. UNIT_ASSERT_EQUAL(s2, TString("bbbbbb"));
  130. const TString s3 = "aaa";
  131. const TString s4 = SubstGlobalCopy(s3, "a", "b");
  132. UNIT_ASSERT_EQUAL(s4, TString("bbb"));
  133. const TString s5 = "aaa";
  134. const TString s6 = SubstGlobalCopy(s5, "a", "");
  135. UNIT_ASSERT_EQUAL(s6, TString(""));
  136. const TString s7 = "abcdefbcbcdfb";
  137. const TString s8 = SubstGlobalCopy(s7, "bc", "bbc", 2);
  138. UNIT_ASSERT_EQUAL(s8, TString("abcdefbbcbbcdfb"));
  139. const TString s9 = "Москва ~ Париж";
  140. const TString s10 = SubstGlobalCopy(s9, " ~ ", " ");
  141. UNIT_ASSERT_EQUAL(s10, TString("Москва Париж"));
  142. }
  143. Y_UNIT_TEST(TestSubstCharGlobal) {
  144. TUtf16String w = u"abcdabcd";
  145. SubstGlobal(w, wchar16('b'), wchar16('B'), 3);
  146. UNIT_ASSERT_EQUAL(w, u"abcdaBcd");
  147. TString s = "aaa";
  148. SubstGlobal(s, 'a', 'b', 1);
  149. UNIT_ASSERT_EQUAL(s, TString("abb"));
  150. }
  151. Y_UNIT_TEST(TestSubstCharGlobalRet) {
  152. const TUtf16String w1 = u"abcdabcd";
  153. const TUtf16String w2 = SubstGlobalCopy(w1, wchar16('b'), wchar16('B'), 3);
  154. UNIT_ASSERT_EQUAL(w2, u"abcdaBcd");
  155. const TString s1 = "aaa";
  156. const TString s2 = SubstGlobalCopy(s1, 'a', 'b', 1);
  157. UNIT_ASSERT_EQUAL(s2, TString("abb"));
  158. }
  159. Y_UNIT_TEST(TestSubstStdString) {
  160. std::string s = "aaa";
  161. SubstGlobal(s, "a", "b", 1);
  162. UNIT_ASSERT_EQUAL(s, "abb");
  163. }
  164. Y_UNIT_TEST(TestSubstStdStringRet) {
  165. const std::string s1 = "aaa";
  166. const std::string s2 = SubstGlobalCopy(s1, "a", "b", 1);
  167. UNIT_ASSERT_EQUAL(s2, "abb");
  168. }
  169. Y_UNIT_TEST(TestSubstGlobalChar) {
  170. {
  171. const TString s = "a";
  172. const TString st = "b";
  173. TString ss = s;
  174. UNIT_ASSERT_VALUES_EQUAL(s.size(), SubstGlobal(ss, 'a', 'b'));
  175. UNIT_ASSERT_VALUES_EQUAL(st, ss);
  176. }
  177. {
  178. const TString s = "aa";
  179. const TString st = "bb";
  180. TString ss = s;
  181. UNIT_ASSERT_VALUES_EQUAL(s.size(), SubstGlobal(ss, 'a', 'b'));
  182. UNIT_ASSERT_VALUES_EQUAL(st, ss);
  183. }
  184. {
  185. const TString s = "aaa";
  186. const TString st = "bbb";
  187. TString ss = s;
  188. UNIT_ASSERT_VALUES_EQUAL(s.size(), SubstGlobal(ss, 'a', 'b'));
  189. UNIT_ASSERT_VALUES_EQUAL(st, ss);
  190. }
  191. {
  192. const TString s = "aaaa";
  193. const TString st = "bbbb";
  194. TString ss = s;
  195. UNIT_ASSERT_VALUES_EQUAL(s.size(), SubstGlobal(ss, 'a', 'b'));
  196. UNIT_ASSERT_VALUES_EQUAL(st, ss);
  197. }
  198. {
  199. const TString s = "aaaaa";
  200. const TString st = "bbbbb";
  201. TString ss = s;
  202. UNIT_ASSERT_VALUES_EQUAL(s.size(), SubstGlobal(ss, 'a', 'b'));
  203. UNIT_ASSERT_VALUES_EQUAL(st, ss);
  204. }
  205. {
  206. const TString s = "aaaaaa";
  207. const TString st = "bbbbbb";
  208. TString ss = s;
  209. UNIT_ASSERT_VALUES_EQUAL(s.size(), SubstGlobal(ss, 'a', 'b'));
  210. UNIT_ASSERT_VALUES_EQUAL(st, ss);
  211. }
  212. {
  213. const TString s = "aaaaaaa";
  214. const TString st = "bbbbbbb";
  215. TString ss = s;
  216. UNIT_ASSERT_VALUES_EQUAL(s.size(), SubstGlobal(ss, 'a', 'b'));
  217. UNIT_ASSERT_VALUES_EQUAL(st, ss);
  218. }
  219. {
  220. const TString s = "aaaaaaaa";
  221. const TString st = "bbbbbbbb";
  222. TString ss = s;
  223. UNIT_ASSERT_VALUES_EQUAL(s.size(), SubstGlobal(ss, 'a', 'b'));
  224. UNIT_ASSERT_VALUES_EQUAL(st, ss);
  225. }
  226. }
  227. }