2 * Copyright 2013 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 // Author: andrei.alexandrescu@fb.com
20 #include "folly/FBString.h"
26 #include <boost/algorithm/string.hpp>
27 #include <boost/random.hpp>
28 #include <gtest/gtest.h>
30 #include <gflags/gflags.h>
32 #include "folly/Foreach.h"
33 #include "folly/Random.h"
34 #include "folly/Conv.h"
37 using namespace folly;
39 static const int seed = folly::randomNumberSeed();
40 typedef boost::mt19937 RandomT;
41 static RandomT rng(seed);
42 static const size_t maxString = 100;
43 static const bool avoidAliasing = true;
45 template <class Integral1, class Integral2>
46 Integral2 random(Integral1 low, Integral2 up) {
47 boost::uniform_int<> range(low, up);
51 template <class String>
52 void randomString(String* toFill, unsigned int maxSize = 1000) {
54 toFill->resize(random(0, maxSize));
55 FOR_EACH (i, *toFill) {
56 *i = random('a', 'z');
60 template <class String, class Integral>
61 void Num2String(String& str, Integral n) {
63 std::string tmp = folly::to<std::string>(n);
64 str = String(tmp.begin(), tmp.end());
67 std::list<char> RandomList(unsigned int maxSize) {
68 std::list<char> lst(random(0u, maxSize));
69 std::list<char>::iterator i = lst.begin();
70 for (; i != lst.end(); ++i) {
71 *i = random('a', 'z');
76 ////////////////////////////////////////////////////////////////////////////////
78 ////////////////////////////////////////////////////////////////////////////////
80 template <class String> void clause_21_3_1_a(String & test) {
81 test.String::~String();
84 template <class String> void clause_21_3_1_b(String & test) {
86 const size_t pos = random(0, test.size());
87 String s(test, pos, random(0, (size_t)(test.size() - pos)));
90 template <class String> void clause_21_3_1_c(String & test) {
91 // Constructor from char*, size_t
93 pos = random(0, test.size()),
94 n = random(0, test.size() - pos);
95 String before(test.data(), test.size());
96 String s(test.c_str() + pos, n);
97 String after(test.data(), test.size());
98 EXPECT_EQ(before, after);
100 // Constructor from char*, char*
101 String s1(test.begin(), test.end());
103 String s2(test.data(), test.data() + test.size());
106 // Constructor from iterators
108 for (auto c : test) lst.push_back(c);
109 String s3(lst.begin(), lst.end());
112 // Constructor from wchar_t iterators
113 std::list<wchar_t> lst1;
114 for (auto c : test) lst1.push_back(c);
115 String s4(lst1.begin(), lst1.end());
118 // Constructor from wchar_t pointers
122 fbstring s5(t, t + 2);;
127 template <class String> void clause_21_3_1_d(String & test) {
129 auto size = random(0, 2000);
130 String s(size, '\0');
131 EXPECT_EQ(s.size(), size);
132 FOR_EACH_RANGE (i, 0, s.size()) {
133 s[i] = random('a', 'z');
137 template <class String> void clause_21_3_1_e(String & test) {
138 // Assignment from char*
139 String s(random(0, 1000), '\0');
141 for (; i != s.size(); ++i) {
142 s[i] = random('a', 'z');
146 template <class String> void clause_21_3_1_f(String & test) {
148 const size_t pos = random(0, test.size());
150 test = String(test.c_str() + pos);
152 test = test.c_str() + pos;
155 template <class String> void clause_21_3_1_g(String & test) {
156 // Assignment from char
157 test = random('a', 'z');
160 template <class String> void clause_21_3_2(String & test) {
161 // Iterators. The code below should leave test unchanged
162 EXPECT_EQ(test.size(), test.end() - test.begin());
163 EXPECT_EQ(test.size(), test.rend() - test.rbegin());
165 auto s = test.size();
166 test.resize(test.end() - test.begin());
167 EXPECT_EQ(s, test.size());
168 test.resize(test.rend() - test.rbegin());
169 EXPECT_EQ(s, test.size());
172 template <class String> void clause_21_3_3(String & test) {
173 // exercise capacity, size, max_size
174 EXPECT_EQ(test.size(), test.length());
175 EXPECT_LE(test.size(), test.max_size());
176 EXPECT_LE(test.capacity(), test.max_size());
177 EXPECT_LE(test.size(), test.capacity());
179 string empty("empty");
180 string notempty("not empty");
181 if (test.empty()) test = String(empty.begin(), empty.end());
182 else test = String(notempty.begin(), notempty.end());
185 template <class String> void clause_21_3_4(String & test) {
186 // exercise element access 21.3.4
188 auto const i = random(0, test.size() - 1);
189 EXPECT_EQ(test[i], test.at(i));
194 template <class String> void clause_21_3_5_a(String & test) {
195 // 21.3.5 modifiers (+=)
197 randomString(&test1);
198 assert(test1.size() == char_traits
199 <typename String::value_type>::length(test1.c_str()));
200 auto len = test.size();
202 EXPECT_EQ(test.size(), test1.size() + len);
203 FOR_EACH_RANGE (i, 0, test1.size()) {
204 EXPECT_EQ(test[len + i], test1[i]);
206 // aliasing modifiers
208 auto dt = test2.data();
209 auto sz = test.c_str();
211 EXPECT_EQ(memcmp(sz, dt, len), 0);
212 String copy(test.data(), test.size());
213 EXPECT_EQ(char_traits
214 <typename String::value_type>::length(test.c_str()), len);
217 EXPECT_EQ(test.size(), 2 * len);
218 EXPECT_EQ(char_traits
219 <typename String::value_type>::length(test.c_str()), 2 * len);
220 FOR_EACH_RANGE (i, 0, len) {
221 EXPECT_EQ(test[i], copy[i]);
222 EXPECT_EQ(test[i], test[len + i]);
225 EXPECT_EQ(char_traits
226 <typename String::value_type>::length(test.c_str()), len);
228 auto const pos = random(0, test.size());
229 EXPECT_EQ(char_traits
230 <typename String::value_type>::length(test.c_str() + pos), len - pos);
232 String addMe(test.c_str() + pos);
233 EXPECT_EQ(addMe.size(), len - pos);
236 test += test.c_str() + pos;
238 EXPECT_EQ(test.size(), 2 * len - pos);
241 test += random('a', 'z');
242 EXPECT_EQ(test.size(), len + 1);
245 template <class String> void clause_21_3_5_b(String & test) {
246 // 21.3.5 modifiers (append, push_back)
249 // Test with a small string first
250 char c = random('a', 'z');
252 EXPECT_EQ(s[s.size() - 1], c);
253 EXPECT_EQ(s.size(), 1);
254 s.resize(s.size() - 1);
256 randomString(&s, maxString);
258 randomString(&s, maxString);
259 test.append(s, random(0, s.size()), random(0, maxString));
260 randomString(&s, maxString);
261 test.append(s.c_str(), random(0, s.size()));
262 randomString(&s, maxString);
263 test.append(s.c_str());
264 test.append(random(0, maxString), random('a', 'z'));
265 std::list<char> lst(RandomList(maxString));
266 test.append(lst.begin(), lst.end());
267 c = random('a', 'z');
269 EXPECT_EQ(test[test.size() - 1], c);
272 template <class String> void clause_21_3_5_c(String & test) {
279 template <class String> void clause_21_3_5_d(String & test) {
282 randomString(&s, maxString);
283 test.assign(s, random(0, s.size()), random(0, maxString));
286 template <class String> void clause_21_3_5_e(String & test) {
289 randomString(&s, maxString);
290 test.assign(s.c_str(), random(0, s.size()));
293 template <class String> void clause_21_3_5_f(String & test) {
296 randomString(&s, maxString);
297 test.assign(s.c_str());
300 template <class String> void clause_21_3_5_g(String & test) {
303 randomString(&s, maxString);
304 test.assign(random(0, maxString), random('a', 'z'));
307 template <class String> void clause_21_3_5_h(String & test) {
308 // assign from bidirectional iterator
309 std::list<char> lst(RandomList(maxString));
310 test.assign(lst.begin(), lst.end());
313 template <class String> void clause_21_3_5_i(String & test) {
314 // assign from aliased source
318 template <class String> void clause_21_3_5_j(String & test) {
319 // assign from aliased source
320 test.assign(test, random(0, test.size()), random(0, maxString));
323 template <class String> void clause_21_3_5_k(String & test) {
324 // assign from aliased source
325 test.assign(test.c_str(), random(0, test.size()));
328 template <class String> void clause_21_3_5_l(String & test) {
329 // assign from aliased source
330 test.assign(test.c_str());
333 template <class String> void clause_21_3_5_m(String & test) {
336 randomString(&s, maxString);
337 test.insert(random(0, test.size()), s);
338 randomString(&s, maxString);
339 test.insert(random(0, test.size()),
340 s, random(0, s.size()),
341 random(0, maxString));
342 randomString(&s, maxString);
343 test.insert(random(0, test.size()),
344 s.c_str(), random(0, s.size()));
345 randomString(&s, maxString);
346 test.insert(random(0, test.size()), s.c_str());
347 test.insert(random(0, test.size()),
348 random(0, maxString), random('a', 'z'));
349 test.insert(test.begin() + random(0, test.size()),
351 std::list<char> lst(RandomList(maxString));
352 test.insert(test.begin() + random(0, test.size()),
353 lst.begin(), lst.end());
356 template <class String> void clause_21_3_5_n(String & test) {
359 test.erase(random(0, test.size()), random(0, maxString));
362 // TODO: is erase(end()) allowed?
363 test.erase(test.begin() + random(0, test.size() - 1));
366 auto const i = test.begin() + random(0, test.size());
367 if (i != test.end()) {
368 test.erase(i, i + random(0, size_t(test.end() - i)));
373 template <class String> void clause_21_3_5_o(String & test) {
374 auto pos = random(0, test.size());
376 test.replace(pos, random(0, test.size() - pos),
379 test.replace(pos, random(0, test.size() - pos), test);
381 pos = random(0, test.size());
383 randomString(&s, maxString);
384 test.replace(pos, pos + random(0, test.size() - pos), s);
385 auto pos1 = random(0, test.size());
386 auto pos2 = random(0, test.size());
388 test.replace(pos1, pos1 + random(0, test.size() - pos1),
390 pos2, pos2 + random(0, test.size() - pos2));
392 test.replace(pos1, pos1 + random(0, test.size() - pos1),
393 test, pos2, pos2 + random(0, test.size() - pos2));
395 pos1 = random(0, test.size());
397 randomString(&str, maxString);
398 pos2 = random(0, str.size());
399 test.replace(pos1, pos1 + random(0, test.size() - pos1),
400 str, pos2, pos2 + random(0, str.size() - pos2));
401 pos = random(0, test.size());
403 test.replace(pos, random(0, test.size() - pos),
404 String(test).c_str(), test.size());
406 test.replace(pos, random(0, test.size() - pos),
407 test.c_str(), test.size());
409 pos = random(0, test.size());
410 randomString(&str, maxString);
411 test.replace(pos, pos + random(0, test.size() - pos),
412 str.c_str(), str.size());
413 pos = random(0, test.size());
414 randomString(&str, maxString);
415 test.replace(pos, pos + random(0, test.size() - pos),
417 pos = random(0, test.size());
418 test.replace(pos, random(0, test.size() - pos),
419 random(0, maxString), random('a', 'z'));
420 pos = random(0, test.size());
424 test.begin() + pos + random(0, test.size() - pos),
429 test.begin() + pos + random(0, test.size() - pos),
432 pos = random(0, test.size());
436 test.begin() + pos + random(0, test.size() - pos),
437 String(test).c_str(),
438 test.size() - random(0, test.size()));
442 test.begin() + pos + random(0, test.size() - pos),
444 test.size() - random(0, test.size()));
446 pos = random(0, test.size());
447 auto const n = random(0, test.size() - pos);
448 typename String::iterator b = test.begin();
450 randomString(&str1, maxString);
451 const String & str3 = str1;
452 const typename String::value_type* ss = str3.c_str();
457 pos = random(0, test.size());
460 test.begin() + pos + random(0, test.size() - pos),
461 random(0, maxString), random('a', 'z'));
464 template <class String> void clause_21_3_5_p(String & test) {
465 std::vector<typename String::value_type>
466 vec(random(0, maxString));
470 random(0, test.size()));
473 template <class String> void clause_21_3_5_q(String & test) {
475 randomString(&s, maxString);
479 template <class String> void clause_21_3_6_a(String & test) {
480 // 21.3.6 string operations
481 // exercise c_str() and data()
482 assert(test.c_str() == test.data());
483 // exercise get_allocator()
485 randomString(&s, maxString);
486 assert(test.get_allocator() == s.get_allocator());
489 template <class String> void clause_21_3_6_b(String & test) {
490 String str = test.substr(
491 random(0, test.size()),
492 random(0, test.size()));
493 Num2String(test, test.find(str, random(0, test.size())));
496 template <class String> void clause_21_3_6_c(String & test) {
497 auto from = random(0, test.size());
498 auto length = random(0, test.size() - from);
499 String str = test.substr(from, length);
500 Num2String(test, test.find(str.c_str(),
501 random(0, test.size()),
502 random(0, str.size())));
505 template <class String> void clause_21_3_6_d(String & test) {
506 String str = test.substr(
507 random(0, test.size()),
508 random(0, test.size()));
509 Num2String(test, test.find(str.c_str(),
510 random(0, test.size())));
513 template <class String> void clause_21_3_6_e(String & test) {
514 Num2String(test, test.find(
516 random(0, test.size())));
519 template <class String> void clause_21_3_6_f(String & test) {
520 String str = test.substr(
521 random(0, test.size()),
522 random(0, test.size()));
523 Num2String(test, test.rfind(str, random(0, test.size())));
526 template <class String> void clause_21_3_6_g(String & test) {
527 String str = test.substr(
528 random(0, test.size()),
529 random(0, test.size()));
530 Num2String(test, test.rfind(str.c_str(),
531 random(0, test.size()),
532 random(0, str.size())));
535 template <class String> void clause_21_3_6_h(String & test) {
536 String str = test.substr(
537 random(0, test.size()),
538 random(0, test.size()));
539 Num2String(test, test.rfind(str.c_str(),
540 random(0, test.size())));
543 template <class String> void clause_21_3_6_i(String & test) {
544 Num2String(test, test.rfind(
546 random(0, test.size())));
549 template <class String> void clause_21_3_6_j(String & test) {
551 randomString(&str, maxString);
552 Num2String(test, test.find_first_of(str,
553 random(0, test.size())));
556 template <class String> void clause_21_3_6_k(String & test) {
558 randomString(&str, maxString);
559 Num2String(test, test.find_first_of(str.c_str(),
560 random(0, test.size()),
561 random(0, str.size())));
564 template <class String> void clause_21_3_6_l(String & test) {
566 randomString(&str, maxString);
567 Num2String(test, test.find_first_of(str.c_str(),
568 random(0, test.size())));
571 template <class String> void clause_21_3_6_m(String & test) {
572 Num2String(test, test.find_first_of(
574 random(0, test.size())));
577 template <class String> void clause_21_3_6_n(String & test) {
579 randomString(&str, maxString);
580 Num2String(test, test.find_last_of(str,
581 random(0, test.size())));
584 template <class String> void clause_21_3_6_o(String & test) {
586 randomString(&str, maxString);
587 Num2String(test, test.find_last_of(str.c_str(),
588 random(0, test.size()),
589 random(0, str.size())));
592 template <class String> void clause_21_3_6_p(String & test) {
594 randomString(&str, maxString);
595 Num2String(test, test.find_last_of(str.c_str(),
596 random(0, test.size())));
599 template <class String> void clause_21_3_6_q(String & test) {
600 Num2String(test, test.find_last_of(
602 random(0, test.size())));
605 template <class String> void clause_21_3_6_r(String & test) {
607 randomString(&str, maxString);
608 Num2String(test, test.find_first_not_of(str,
609 random(0, test.size())));
612 template <class String> void clause_21_3_6_s(String & test) {
614 randomString(&str, maxString);
615 Num2String(test, test.find_first_not_of(str.c_str(),
616 random(0, test.size()),
617 random(0, str.size())));
620 template <class String> void clause_21_3_6_t(String & test) {
622 randomString(&str, maxString);
623 Num2String(test, test.find_first_not_of(str.c_str(),
624 random(0, test.size())));
627 template <class String> void clause_21_3_6_u(String & test) {
628 Num2String(test, test.find_first_not_of(
630 random(0, test.size())));
633 template <class String> void clause_21_3_6_v(String & test) {
635 randomString(&str, maxString);
636 Num2String(test, test.find_last_not_of(str,
637 random(0, test.size())));
640 template <class String> void clause_21_3_6_w(String & test) {
642 randomString(&str, maxString);
643 Num2String(test, test.find_last_not_of(str.c_str(),
644 random(0, test.size()),
645 random(0, str.size())));
648 template <class String> void clause_21_3_6_x(String & test) {
650 randomString(&str, maxString);
651 Num2String(test, test.find_last_not_of(str.c_str(),
652 random(0, test.size())));
655 template <class String> void clause_21_3_6_y(String & test) {
656 Num2String(test, test.find_last_not_of(
658 random(0, test.size())));
661 template <class String> void clause_21_3_6_z(String & test) {
662 test = test.substr(random(0, test.size()), random(0, test.size()));
665 template <class String> void clause_21_3_7_a(String & test) {
667 randomString(&s, maxString);
668 int tristate = test.compare(s);
669 if (tristate > 0) tristate = 1;
670 else if (tristate < 0) tristate = 2;
671 Num2String(test, tristate);
674 template <class String> void clause_21_3_7_b(String & test) {
676 randomString(&s, maxString);
677 int tristate = test.compare(
678 random(0, test.size()),
679 random(0, test.size()),
681 if (tristate > 0) tristate = 1;
682 else if (tristate < 0) tristate = 2;
683 Num2String(test, tristate);
686 template <class String> void clause_21_3_7_c(String & test) {
688 randomString(&str, maxString);
689 int tristate = test.compare(
690 random(0, test.size()),
691 random(0, test.size()),
693 random(0, str.size()),
694 random(0, str.size()));
695 if (tristate > 0) tristate = 1;
696 else if (tristate < 0) tristate = 2;
697 Num2String(test, tristate);
700 template <class String> void clause_21_3_7_d(String & test) {
702 randomString(&s, maxString);
703 int tristate = test.compare(s.c_str());
704 if (tristate > 0) tristate = 1;
705 else if (tristate < 0) tristate = 2;
706 Num2String(test, tristate);
709 template <class String> void clause_21_3_7_e(String & test) {
711 randomString(&str, maxString);
712 int tristate = test.compare(
713 random(0, test.size()),
714 random(0, test.size()),
716 random(0, str.size()));
717 if (tristate > 0) tristate = 1;
718 else if (tristate < 0) tristate = 2;
719 Num2String(test, tristate);
722 template <class String> void clause_21_3_7_f(String & test) {
724 randomString(&s1, maxString);
726 randomString(&s2, maxString);
730 template <class String> void clause_21_3_7_g(String & test) {
732 randomString(&s, maxString);
734 randomString(&s1, maxString);
735 test = s.c_str() + s1;
738 template <class String> void clause_21_3_7_h(String & test) {
740 randomString(&s, maxString);
741 test = typename String::value_type(random('a', 'z')) + s;
744 template <class String> void clause_21_3_7_i(String & test) {
746 randomString(&s, maxString);
748 randomString(&s1, maxString);
749 test = s + s1.c_str();
752 template <class String> void clause_21_3_7_j(String & test) {
754 randomString(&s, maxString);
756 randomString(&s1, maxString);
757 test = s + s1.c_str();
760 template <class String> void clause_21_3_7_k(String & test) {
762 randomString(&s, maxString);
763 test = s + typename String::value_type(random('a', 'z'));
766 // Numbering here is from C++11
767 template <class String> void clause_21_4_8_9_a(String & test) {
768 basic_stringstream<typename String::value_type> stst(test.c_str());
776 TEST(FBString, testAllClauses) {
777 EXPECT_TRUE(1) << "Starting with seed: " << seed;
781 folly::basic_fbstring<wchar_t> wc;
782 #define TEST_CLAUSE(x) \
784 if (1) {} else EXPECT_TRUE(1) << "Testing clause " << #x; \
788 wr = std::wstring(r.begin(), r.end()); \
789 wc = folly::basic_fbstring<wchar_t>(wr.c_str()); \
790 auto localSeed = seed + count; \
791 rng = RandomT(localSeed); \
793 rng = RandomT(localSeed); \
796 << "Lengths: " << r.size() << " vs. " << c.size() \
797 << "\nReference: '" << r << "'" \
798 << "\nActual: '" << c.data()[0] << "'"; \
799 rng = RandomT(localSeed); \
801 int wret = wcslen(wc.c_str()); \
803 int ret = wcstombs(mb, wc.c_str(), sizeof(mb)); \
804 if (ret == wret) mb[wret] = '\0'; \
805 const char *mc = c.c_str(); \
806 std::string one(mb); \
807 std::string two(mc); \
808 EXPECT_EQ(one, two); \
809 } while (++count % 100 != 0)
812 TEST_CLAUSE(21_3_1_a);
813 TEST_CLAUSE(21_3_1_b);
814 TEST_CLAUSE(21_3_1_c);
815 TEST_CLAUSE(21_3_1_d);
816 TEST_CLAUSE(21_3_1_e);
817 TEST_CLAUSE(21_3_1_f);
818 TEST_CLAUSE(21_3_1_g);
823 TEST_CLAUSE(21_3_5_a);
824 TEST_CLAUSE(21_3_5_b);
825 TEST_CLAUSE(21_3_5_c);
826 TEST_CLAUSE(21_3_5_d);
827 TEST_CLAUSE(21_3_5_e);
828 TEST_CLAUSE(21_3_5_f);
829 TEST_CLAUSE(21_3_5_g);
830 TEST_CLAUSE(21_3_5_h);
831 TEST_CLAUSE(21_3_5_i);
832 TEST_CLAUSE(21_3_5_j);
833 TEST_CLAUSE(21_3_5_k);
834 TEST_CLAUSE(21_3_5_l);
835 TEST_CLAUSE(21_3_5_m);
836 TEST_CLAUSE(21_3_5_n);
837 TEST_CLAUSE(21_3_5_o);
838 TEST_CLAUSE(21_3_5_p);
840 TEST_CLAUSE(21_3_6_a);
841 TEST_CLAUSE(21_3_6_b);
842 TEST_CLAUSE(21_3_6_c);
843 TEST_CLAUSE(21_3_6_d);
844 TEST_CLAUSE(21_3_6_e);
845 TEST_CLAUSE(21_3_6_f);
846 TEST_CLAUSE(21_3_6_g);
847 TEST_CLAUSE(21_3_6_h);
848 TEST_CLAUSE(21_3_6_i);
849 TEST_CLAUSE(21_3_6_j);
850 TEST_CLAUSE(21_3_6_k);
851 TEST_CLAUSE(21_3_6_l);
852 TEST_CLAUSE(21_3_6_m);
853 TEST_CLAUSE(21_3_6_n);
854 TEST_CLAUSE(21_3_6_o);
855 TEST_CLAUSE(21_3_6_p);
856 TEST_CLAUSE(21_3_6_q);
857 TEST_CLAUSE(21_3_6_r);
858 TEST_CLAUSE(21_3_6_s);
859 TEST_CLAUSE(21_3_6_t);
860 TEST_CLAUSE(21_3_6_u);
861 TEST_CLAUSE(21_3_6_v);
862 TEST_CLAUSE(21_3_6_w);
863 TEST_CLAUSE(21_3_6_x);
864 TEST_CLAUSE(21_3_6_y);
865 TEST_CLAUSE(21_3_6_z);
867 TEST_CLAUSE(21_3_7_a);
868 TEST_CLAUSE(21_3_7_b);
869 TEST_CLAUSE(21_3_7_c);
870 TEST_CLAUSE(21_3_7_d);
871 TEST_CLAUSE(21_3_7_e);
872 TEST_CLAUSE(21_3_7_f);
873 TEST_CLAUSE(21_3_7_g);
874 TEST_CLAUSE(21_3_7_h);
875 TEST_CLAUSE(21_3_7_i);
876 TEST_CLAUSE(21_3_7_j);
877 TEST_CLAUSE(21_3_7_k);
879 TEST_CLAUSE(21_4_8_9_a);
882 TEST(FBString, testGetline) {
884 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras accumsan \n\
885 elit ut urna consectetur in sagittis mi auctor. Nulla facilisi. In nec \n\
886 dolor leo, vitae imperdiet neque. Donec ut erat mauris, a faucibus \n\
887 elit. Integer consectetur gravida augue, sit amet mattis mauris auctor \n\
888 sed. Morbi congue libero eu nunc sodales adipiscing. In lectus nunc, \n\
889 vulputate a fringilla at, venenatis quis justo. Proin eu velit \n\
890 nibh. Maecenas vitae tellus eros. Pellentesque habitant morbi \n\
891 tristique senectus et netus et malesuada fames ac turpis \n\
892 egestas. Vivamus faucibus feugiat consequat. Donec fermentum neque sit \n\
893 amet ligula suscipit porta. Phasellus facilisis felis in purus luctus \n\
894 quis posuere leo tempor. Nam nunc purus, luctus a pharetra ut, \n\
895 placerat at dui. Donec imperdiet, diam quis convallis pulvinar, dui \n\
896 est commodo lorem, ut tincidunt diam nibh et nibh. Maecenas nec velit \n\
897 massa, ut accumsan magna. Donec imperdiet tempor nisi et \n\
898 laoreet. Phasellus lectus quam, ultricies ut tincidunt in, dignissim \n\
899 id eros. Mauris vulputate tortor nec neque pellentesque sagittis quis \n\
900 sed nisl. In diam lacus, lobortis ut posuere nec, ornare id quam.";
901 char f[] = "/tmp/fbstring_testing.XXXXXX";
906 std::ofstream out(f);
908 EXPECT_TRUE(0) << "Couldn't write to temp file.";
913 boost::split(v, s1, boost::is_any_of("\n"));
918 EXPECT_TRUE(getline(input, line));
925 TEST(FBString, testMoveCtor) {
926 // Move constructor. Make sure we allocate a large string, so the
927 // small string optimization doesn't kick in.
928 auto size = random(100, 2000);
929 fbstring s(size, 'a');
930 fbstring test = std::move(s);
931 EXPECT_TRUE(s.empty());
932 EXPECT_EQ(size, test.size());
935 TEST(FBString, testMoveAssign) {
936 // Move constructor. Make sure we allocate a large string, so the
937 // small string optimization doesn't kick in.
938 auto size = random(100, 2000);
939 fbstring s(size, 'a');
942 EXPECT_TRUE(s.empty());
943 EXPECT_EQ(size, test.size());
946 TEST(FBString, testMoveOperatorPlusLhs) {
947 // Make sure we allocate a large string, so the
948 // small string optimization doesn't kick in.
949 auto size1 = random(100, 2000);
950 auto size2 = random(100, 2000);
951 fbstring s1(size1, 'a');
952 fbstring s2(size2, 'b');
954 test = std::move(s1) + s2;
955 EXPECT_TRUE(s1.empty());
956 EXPECT_EQ(size1 + size2, test.size());
959 TEST(FBString, testMoveOperatorPlusRhs) {
960 // Make sure we allocate a large string, so the
961 // small string optimization doesn't kick in.
962 auto size1 = random(100, 2000);
963 auto size2 = random(100, 2000);
964 fbstring s1(size1, 'a');
965 fbstring s2(size2, 'b');
967 test = s1 + std::move(s2);
968 EXPECT_EQ(size1 + size2, test.size());
971 TEST(FBString, testConstructionFromLiteralZero) {
975 } catch (const std::logic_error&) {
983 } catch (const std::logic_error& e) {
989 TEST(FBString, testFixedBugs) {
991 fbstring str(1337, 'f');
995 EXPECT_EQ(str.front(), 'f');
997 { // D481173, --extra-cxxflags=-DFBSTRING_CONSERVATIVE
998 fbstring str(1337, 'f');
999 for (int i = 0; i < 2; ++i) {
1002 EXPECT_EQ(cp.c_str()[cp.size()], '\0');
1008 fbstring str(1337, 'f');
1013 fbstring str(1337, 'f');
1020 folly::basic_fbstring<wchar_t> s;
1021 EXPECT_EQ(0, s.size());
1026 TEST(FBString, testHash) {
1033 std::hash<fbstring> hashfunc;
1034 EXPECT_NE(hashfunc(a), hashfunc(b));
1037 TEST(FBString, testFrontBack) {
1038 fbstring str("hello");
1039 EXPECT_EQ(str.front(), 'h');
1040 EXPECT_EQ(str.back(), 'o');
1042 EXPECT_EQ(str.front(), 'H');
1044 EXPECT_EQ(str.back(), 'O');
1045 EXPECT_EQ(str, "HellO");
1048 int main(int argc, char** argv) {
1049 testing::InitGoogleTest(&argc, argv);
1050 google::ParseCommandLineFlags(&argc, &argv, true);
1051 return RUN_ALL_TESTS();