summaryrefslogtreecommitdiffstats
path: root/util/generic/strbuf_ut.cpp
diff options
context:
space:
mode:
authorDevtools Arcadia <[email protected]>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <[email protected]>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /util/generic/strbuf_ut.cpp
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'util/generic/strbuf_ut.cpp')
-rw-r--r--util/generic/strbuf_ut.cpp373
1 files changed, 373 insertions, 0 deletions
diff --git a/util/generic/strbuf_ut.cpp b/util/generic/strbuf_ut.cpp
new file mode 100644
index 00000000000..69cde785af0
--- /dev/null
+++ b/util/generic/strbuf_ut.cpp
@@ -0,0 +1,373 @@
+#include "strbuf.h"
+
+#include <library/cpp/testing/unittest/registar.h>
+
+#include <string_view>
+
+Y_UNIT_TEST_SUITE(TStrBufTest) {
+ Y_UNIT_TEST(TestConstructorsAndOperators) {
+ TStringBuf str("qwerty");
+
+ UNIT_ASSERT_EQUAL(*str.data(), 'q');
+ UNIT_ASSERT_EQUAL(str.size(), 6);
+
+ TStringBuf str1("qwe\0rty"sv);
+ TStringBuf str2(str1.data());
+ UNIT_ASSERT_VALUES_UNEQUAL(str1, str2);
+ UNIT_ASSERT_VALUES_EQUAL(str1.size(), 7);
+ UNIT_ASSERT_VALUES_EQUAL(str2.size(), 3);
+
+ std::string_view helloWorld("Hello, World!");
+ TStringBuf fromStringView(helloWorld);
+ UNIT_ASSERT_EQUAL(fromStringView.data(), helloWorld.data());
+ UNIT_ASSERT_EQUAL(fromStringView.size(), helloWorld.size());
+
+ std::string_view fromStringBuf = fromStringView;
+ UNIT_ASSERT_EQUAL(helloWorld.data(), fromStringBuf.data());
+ UNIT_ASSERT_EQUAL(helloWorld.size(), fromStringBuf.size());
+ }
+
+ Y_UNIT_TEST(TestConstExpr) {
+ static constexpr TStringBuf str1("qwe\0rty", 7);
+ static constexpr TStringBuf str2(str1.data(), str1.size());
+ static constexpr TStringBuf str3 = "qwe\0rty"sv;
+
+ UNIT_ASSERT_VALUES_EQUAL(str1.size(), 7);
+
+ UNIT_ASSERT_VALUES_EQUAL(str1, str2);
+ UNIT_ASSERT_VALUES_EQUAL(str2, str3);
+ UNIT_ASSERT_VALUES_EQUAL(str1, str3);
+
+ static constexpr std::string_view view1(str1);
+ UNIT_ASSERT_VALUES_EQUAL(str1, view1);
+ static_assert(str1.data() == view1.data());
+ static_assert(str1.size() == view1.size());
+
+ static constexpr TStringBuf str4(view1);
+ UNIT_ASSERT_VALUES_EQUAL(str1, str4);
+ static_assert(str1.data() == str4.data());
+ static_assert(str1.size() == str4.size());
+ }
+
+ Y_UNIT_TEST(TestAfter) {
+ TStringBuf str("qwerty");
+
+ UNIT_ASSERT_VALUES_EQUAL(str.After('w'), TStringBuf("erty"));
+ UNIT_ASSERT_VALUES_EQUAL(str.After('x'), TStringBuf("qwerty"));
+ UNIT_ASSERT_VALUES_EQUAL(str.After('y'), TStringBuf());
+ UNIT_ASSERT_STRINGS_EQUAL(str.After('='), str);
+
+ // Also works properly on empty strings
+ TStringBuf empty;
+ UNIT_ASSERT_STRINGS_EQUAL(empty.After('x'), empty);
+ }
+
+ Y_UNIT_TEST(TestBefore) {
+ TStringBuf str("qwerty");
+
+ UNIT_ASSERT_VALUES_EQUAL(str.Before('w'), TStringBuf("q"));
+ UNIT_ASSERT_VALUES_EQUAL(str.Before('x'), TStringBuf("qwerty"));
+ UNIT_ASSERT_VALUES_EQUAL(str.Before('y'), TStringBuf("qwert"));
+ UNIT_ASSERT_VALUES_EQUAL(str.Before('q'), TStringBuf());
+ }
+
+ Y_UNIT_TEST(TestRAfterBefore) {
+ TStringBuf str("a/b/c");
+ UNIT_ASSERT_STRINGS_EQUAL(str.RAfter('/'), "c");
+ UNIT_ASSERT_STRINGS_EQUAL(str.RAfter('_'), str);
+ UNIT_ASSERT_STRINGS_EQUAL(str.RAfter('a'), "/b/c");
+ UNIT_ASSERT_STRINGS_EQUAL(str.RBefore('/'), "a/b");
+ UNIT_ASSERT_STRINGS_EQUAL(str.RBefore('_'), str);
+ UNIT_ASSERT_STRINGS_EQUAL(str.RBefore('a'), "");
+ }
+
+ Y_UNIT_TEST(TestAfterPrefix) {
+ TStringBuf str("cat_dog");
+
+ TStringBuf r = "the_same";
+ UNIT_ASSERT(!str.AfterPrefix("dog", r));
+ UNIT_ASSERT_EQUAL(r, "the_same");
+ UNIT_ASSERT(str.AfterPrefix("cat_", r));
+ UNIT_ASSERT_EQUAL(r, "dog");
+
+ //example:
+ str = "http://ya.ru";
+ if (str.AfterPrefix("http://", r)) {
+ UNIT_ASSERT_EQUAL(r, "ya.ru");
+ }
+
+ // SkipPrefix()
+ TStringBuf a = "abcdef";
+ UNIT_ASSERT(a.SkipPrefix("a") && a == "bcdef");
+ UNIT_ASSERT(a.SkipPrefix("bc") && a == "def");
+ UNIT_ASSERT(a.SkipPrefix("") && a == "def");
+ UNIT_ASSERT(!a.SkipPrefix("xyz") && a == "def");
+ UNIT_ASSERT(!a.SkipPrefix("defg") && a == "def");
+ UNIT_ASSERT(a.SkipPrefix("def") && a == "");
+ UNIT_ASSERT(a.SkipPrefix("") && a == "");
+ UNIT_ASSERT(!a.SkipPrefix("def") && a == "");
+ }
+
+ Y_UNIT_TEST(TestBeforeSuffix) {
+ TStringBuf str("cat_dog");
+
+ TStringBuf r = "the_same";
+ UNIT_ASSERT(!str.BeforeSuffix("cat", r));
+ UNIT_ASSERT_EQUAL(r, "the_same");
+ UNIT_ASSERT(str.BeforeSuffix("_dog", r));
+ UNIT_ASSERT_EQUAL(r, "cat");
+
+ //example:
+ str = "maps.yandex.com.ua";
+ if (str.BeforeSuffix(".ru", r)) {
+ UNIT_ASSERT_EQUAL(r, "maps.yandex");
+ }
+
+ // ChopSuffix()
+ TStringBuf a = "abcdef";
+ UNIT_ASSERT(a.ChopSuffix("f") && a == "abcde");
+ UNIT_ASSERT(a.ChopSuffix("de") && a == "abc");
+ UNIT_ASSERT(a.ChopSuffix("") && a == "abc");
+ UNIT_ASSERT(!a.ChopSuffix("xyz") && a == "abc");
+ UNIT_ASSERT(!a.ChopSuffix("abcd") && a == "abc");
+ UNIT_ASSERT(a.ChopSuffix("abc") && a == "");
+ UNIT_ASSERT(a.ChopSuffix("") && a == "");
+ UNIT_ASSERT(!a.ChopSuffix("abc") && a == "");
+ }
+
+ Y_UNIT_TEST(TestEmpty) {
+ UNIT_ASSERT(TStringBuf().empty());
+ UNIT_ASSERT(!TStringBuf("q").empty());
+ }
+
+ Y_UNIT_TEST(TestShift) {
+ TStringBuf qw("qwerty");
+ TStringBuf str;
+
+ str = qw;
+ str.Chop(10);
+ UNIT_ASSERT(str.empty());
+
+ str = qw;
+ UNIT_ASSERT_EQUAL(str.SubStr(2), TStringBuf("erty"));
+ UNIT_ASSERT_EQUAL(str.Skip(3), qw.SubStr(3));
+ str.Chop(1);
+ UNIT_ASSERT_EQUAL(str, TStringBuf("rt"));
+ }
+
+ Y_UNIT_TEST(TestSplit) {
+ TStringBuf qw("qwerty");
+ TStringBuf lt, rt;
+
+ rt = qw;
+ lt = rt.NextTok('r');
+ UNIT_ASSERT_EQUAL(lt, TStringBuf("qwe"));
+ UNIT_ASSERT_EQUAL(rt, TStringBuf("ty"));
+
+ lt = qw;
+ rt = lt.SplitOff('r');
+ UNIT_ASSERT_EQUAL(lt, TStringBuf("qwe"));
+ UNIT_ASSERT_EQUAL(rt, TStringBuf("ty"));
+
+ rt = qw;
+ lt = rt.NextTok('r');
+ TStringBuf ty = rt.NextTok('r'); // no 'r' in "ty"
+ UNIT_ASSERT_EQUAL(rt.size(), 0);
+ UNIT_ASSERT_EQUAL(ty, TStringBuf("ty"));
+ }
+
+ Y_UNIT_TEST(TestNextTok) {
+ TStringBuf buf("12q45q");
+ TStringBuf tok;
+
+ UNIT_ASSERT(buf.NextTok('q', tok) && tok == "12");
+ UNIT_ASSERT(buf.NextTok('q', tok) && tok == "45");
+ UNIT_ASSERT(!buf.NextTok('q', tok));
+ }
+
+ Y_UNIT_TEST(TestNextStringTok) {
+ TStringBuf buf1("a@@b@@c");
+ UNIT_ASSERT_EQUAL(buf1.NextTok("@@"), TStringBuf("a"));
+ UNIT_ASSERT_EQUAL(buf1.NextTok("@@"), TStringBuf("b"));
+ UNIT_ASSERT_EQUAL(buf1.NextTok("@@"), TStringBuf("c"));
+ UNIT_ASSERT_EQUAL(buf1, TStringBuf());
+
+ TStringBuf buf2("a@@b@@c");
+ UNIT_ASSERT_EQUAL(buf2.RNextTok("@@"), TStringBuf("c"));
+ UNIT_ASSERT_EQUAL(buf2.RNextTok("@@"), TStringBuf("b"));
+ UNIT_ASSERT_EQUAL(buf2.RNextTok("@@"), TStringBuf("a"));
+ UNIT_ASSERT_EQUAL(buf2, TStringBuf());
+
+ TStringBuf buf3("a@@b@@c");
+ UNIT_ASSERT_EQUAL(buf3.RNextTok("@@@"), TStringBuf("a@@b@@c"));
+ UNIT_ASSERT_EQUAL(buf3, TStringBuf());
+ }
+
+ Y_UNIT_TEST(TestReadLine) {
+ TStringBuf buf("12\n45\r\n\r\n23");
+ TStringBuf tok;
+
+ buf.ReadLine(tok);
+ UNIT_ASSERT_VALUES_EQUAL(tok, "12");
+
+ buf.ReadLine(tok);
+ UNIT_ASSERT_VALUES_EQUAL(tok, "45");
+
+ buf.ReadLine(tok);
+ UNIT_ASSERT_VALUES_EQUAL(tok, "");
+
+ buf.ReadLine(tok);
+ UNIT_ASSERT_VALUES_EQUAL(tok, "23");
+
+ UNIT_ASSERT(!buf.ReadLine(tok));
+ }
+
+ Y_UNIT_TEST(TestRFind) {
+ TStringBuf buf1 = "123123456";
+ UNIT_ASSERT_EQUAL(buf1.rfind('3'), 5);
+ UNIT_ASSERT_EQUAL(buf1.rfind('4'), 6);
+ UNIT_ASSERT_EQUAL(buf1.rfind('7'), TStringBuf::npos);
+
+ TStringBuf buf2;
+ UNIT_ASSERT_EQUAL(buf2.rfind('3'), TStringBuf::npos);
+
+ TStringBuf buf3 = TStringBuf("123123456", 6);
+ UNIT_ASSERT_EQUAL(buf3.rfind('3'), 5);
+ UNIT_ASSERT_EQUAL(buf3.rfind('4'), TStringBuf::npos);
+ UNIT_ASSERT_EQUAL(buf3.rfind('7'), TStringBuf::npos);
+
+ TStringBuf buf4 = TStringBuf("123123456", 5);
+ UNIT_ASSERT_EQUAL(buf4.rfind('3'), 2);
+ }
+
+ Y_UNIT_TEST(TestRNextTok) {
+ TStringBuf buf1("a.b.c");
+ UNIT_ASSERT_EQUAL(buf1.RNextTok('.'), TStringBuf("c"));
+ UNIT_ASSERT_EQUAL(buf1, TStringBuf("a.b"));
+
+ TStringBuf buf2("a");
+ UNIT_ASSERT_EQUAL(buf2.RNextTok('.'), TStringBuf("a"));
+ UNIT_ASSERT_EQUAL(buf2, TStringBuf());
+
+ TStringBuf buf3("ab cd ef"), tok;
+ UNIT_ASSERT(buf3.RNextTok(' ', tok) && tok == "ef" && buf3 == "ab cd");
+ UNIT_ASSERT(buf3.RNextTok(' ', tok) && tok == "cd" && buf3 == "ab");
+ UNIT_ASSERT(buf3.RNextTok(' ', tok) && tok == "ab" && buf3 == "");
+ UNIT_ASSERT(!buf3.RNextTok(' ', tok) && tok == "ab" && buf3 == ""); // not modified
+ }
+
+ Y_UNIT_TEST(TestRSplitOff) {
+ TStringBuf buf1("a.b.c");
+ UNIT_ASSERT_EQUAL(buf1.RSplitOff('.'), TStringBuf("a.b"));
+ UNIT_ASSERT_EQUAL(buf1, TStringBuf("c"));
+
+ TStringBuf buf2("a");
+ UNIT_ASSERT_EQUAL(buf2.RSplitOff('.'), TStringBuf());
+ UNIT_ASSERT_EQUAL(buf2, TStringBuf("a"));
+ }
+
+ Y_UNIT_TEST(TestCBeginCEnd) {
+ const char helloThere[] = "Hello there";
+ TStringBuf s{helloThere};
+
+ size_t index = 0;
+ for (auto it = s.cbegin(); s.cend() != it; ++it, ++index) {
+ UNIT_ASSERT_VALUES_EQUAL(helloThere[index], *it);
+ }
+ }
+
+ Y_UNIT_TEST(TestSplitOnAt) {
+ TStringBuf s = "abcabc";
+ TStringBuf l, r;
+
+ size_t pos = s.find('a');
+ UNIT_ASSERT(s.TrySplitOn(pos, l, r));
+ UNIT_ASSERT(l == "" && r == "bcabc");
+ UNIT_ASSERT(s.TrySplitAt(pos, l, r));
+ UNIT_ASSERT(l == "" && r == "abcabc");
+
+ pos = s.find("ca");
+ UNIT_ASSERT(s.TrySplitOn(pos, l, r));
+ UNIT_ASSERT(l == "ab" && r == "abc");
+ UNIT_ASSERT(s.TrySplitOn(pos, l, r, 2));
+ UNIT_ASSERT(l == "ab" && r == "bc");
+ UNIT_ASSERT(s.TrySplitAt(pos, l, r));
+ UNIT_ASSERT(l == "ab" && r == "cabc");
+
+ // out of range
+ pos = 100500;
+ UNIT_ASSERT(s.TrySplitOn(pos, l, r)); // still true
+ UNIT_ASSERT(l == "abcabc" && r == "");
+ l = "111";
+ r = "222";
+ UNIT_ASSERT(s.TrySplitAt(pos, l, r)); // still true
+ UNIT_ASSERT(l == "abcabc" && r == "");
+
+ // npos
+ pos = s.find("missing");
+ l = "111";
+ r = "222";
+ UNIT_ASSERT(!s.TrySplitOn(pos, l, r));
+ UNIT_ASSERT(l == "111" && r == "222"); // not modified
+ s.SplitOn(pos, l, r);
+ UNIT_ASSERT(l == "abcabc" && r == ""); // modified
+
+ l = "111";
+ r = "222";
+ UNIT_ASSERT(!s.TrySplitAt(pos, l, r));
+ UNIT_ASSERT(l == "111" && r == "222"); // not modified
+ s.SplitAt(pos, l, r);
+ UNIT_ASSERT(l == "abcabc" && r == ""); // modified
+ }
+
+ template <class T>
+ void PassByConstReference(const T& val) {
+ // In https://st.yandex-team.ru/IGNIETFERRO-294 was assumed that `const char[]` types are compile time strings
+ // and that CharTraits::Length may not be called for them. Unfortunately that is not true, `char[]` types
+ // are easily converted to `const char[]` if they are passed to a function accepting `const T&`.
+ UNIT_ASSERT(TStringBuf(val).size() == 5);
+ }
+
+ Y_UNIT_TEST(TestPassingArraysByConstReference) {
+ char data[] = "Hello\0word";
+ PassByConstReference(data);
+ }
+
+ Y_UNIT_TEST(TestTruncate) {
+ TStringBuf s = "123";
+ s.Trunc(5);
+ UNIT_ASSERT_STRINGS_EQUAL(s, "123");
+ s.Trunc(3);
+ UNIT_ASSERT_STRINGS_EQUAL(s, "123");
+ s.Trunc(1);
+ UNIT_ASSERT_STRINGS_EQUAL(s, "1");
+ s.Trunc(0);
+ UNIT_ASSERT_STRINGS_EQUAL(s, "");
+ s.Trunc(0);
+ UNIT_ASSERT_STRINGS_EQUAL(s, "");
+ }
+}
+
+Y_UNIT_TEST_SUITE(TWtrBufTest) {
+ Y_UNIT_TEST(TestConstExpr) {
+ static constexpr TWtringBuf str1(u"qwe\0rty", 7);
+ static constexpr TWtringBuf str2(str1.data(), str1.size());
+ static constexpr TWtringBuf str3 = u"qwe\0rty"sv;
+
+ UNIT_ASSERT_VALUES_EQUAL(str1.size(), 7);
+
+ UNIT_ASSERT_VALUES_EQUAL(str1, str2);
+ UNIT_ASSERT_VALUES_EQUAL(str2, str3);
+ UNIT_ASSERT_VALUES_EQUAL(str1, str3);
+
+ static constexpr std::u16string_view view1(str1);
+ UNIT_ASSERT_VALUES_EQUAL(str1, view1);
+ static_assert(str1.data() == view1.data());
+ static_assert(str1.size() == view1.size());
+
+ static constexpr TWtringBuf str4(view1);
+ UNIT_ASSERT_VALUES_EQUAL(str1, str4);
+ static_assert(str1.data() == str4.data());
+ static_assert(str1.size() == str4.size());
+ }
+}