2 * Copyright 2012 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"
36 using namespace folly;
38 static const int seed = folly::randomNumberSeed();
39 typedef boost::mt19937 RandomT;
40 static RandomT rng(seed);
41 static const size_t maxString = 100;
42 static const bool avoidAliasing = true;
44 template <class Integral1, class Integral2>
45 Integral2 random(Integral1 low, Integral2 up) {
46 boost::uniform_int<> range(low, up);
50 template <class String>
51 void randomString(String* toFill, unsigned int maxSize = 1000) {
53 toFill->resize(random(0, maxSize));
54 FOR_EACH (i, *toFill) {
55 *i = random('a', 'z');
59 template <class String, class Integral>
60 void Num2String(String& str, Integral n) {
62 sprintf(&str[0], "%lu", static_cast<unsigned long>(n));
63 str.resize(strlen(str.c_str()));
66 std::list<char> RandomList(unsigned int maxSize) {
67 std::list<char> lst(random(0u, maxSize));
68 std::list<char>::iterator i = lst.begin();
69 for (; i != lst.end(); ++i) {
70 *i = random('a', 'z');
75 ////////////////////////////////////////////////////////////////////////////////
77 ////////////////////////////////////////////////////////////////////////////////
79 template <class String> void clause_21_3_1_a(String & test) {
80 test.String::~String();
83 template <class String> void clause_21_3_1_b(String & test) {
85 const size_t pos = random(0, test.size());
86 String s(test, pos, random(0, (size_t)(test.size() - pos)));
89 template <class String> void clause_21_3_1_c(String & test) {
90 // Constructor from char*, size_t
92 pos = random(0, test.size()),
93 n = random(0, test.size() - pos);
94 std::string before(test.data(), test.size());
95 String s(test.c_str() + pos, n);
96 std::string after(test.data(), test.size());
97 EXPECT_EQ(before, after);
99 // Constructor from char*, char*
100 String s1(test.begin(), test.end());
102 String s2(test.data(), test.data() + test.size());
105 // Constructor from iterators
107 for (auto c : test) lst.push_back(c);
108 String s3(lst.begin(), lst.end());
111 // Constructor from wchar_t iterators
112 std::list<wchar_t> lst1;
113 for (auto c : test) lst1.push_back(c);
114 String s4(lst1.begin(), lst1.end());
117 // Constructor from wchar_t pointers
121 String s5(t, t + 2);;
126 template <class String> void clause_21_3_1_d(String & test) {
128 auto size = random(0, 2000);
129 String s(size, '\0');
130 EXPECT_EQ(s.size(), size);
131 FOR_EACH_RANGE (i, 0, s.size()) {
132 s[i] = random('a', 'z');
136 template <class String> void clause_21_3_1_e(String & test) {
137 // Assignment from char*
138 String s(random(0, 1000), '\0');
140 for (; i != s.size(); ++i) {
141 s[i] = random('a', 'z');
145 template <class String> void clause_21_3_1_f(String & test) {
147 const size_t pos = random(0, test.size());
149 test = String(test.c_str() + pos);
151 test = test.c_str() + pos;
154 template <class String> void clause_21_3_1_g(String & test) {
155 // Assignment from char
156 test = random('a', 'z');
159 template <class String> void clause_21_3_2(String & test) {
160 // Iterators. The code below should leave test unchanged
161 EXPECT_EQ(test.size(), test.end() - test.begin());
162 EXPECT_EQ(test.size(), test.rend() - test.rbegin());
164 auto s = test.size();
165 test.resize(test.end() - test.begin());
166 EXPECT_EQ(s, test.size());
167 test.resize(test.rend() - test.rbegin());
168 EXPECT_EQ(s, test.size());
171 template <class String> void clause_21_3_3(String & test) {
172 // exercise capacity, size, max_size
173 EXPECT_EQ(test.size(), test.length());
174 EXPECT_LE(test.size(), test.max_size());
175 EXPECT_LE(test.capacity(), test.max_size());
176 EXPECT_LE(test.size(), test.capacity());
178 if (test.empty()) test = "empty";
179 else test = "not empty";
182 template <class String> void clause_21_3_4(String & test) {
183 // exercise element access 21.3.4
185 auto const i = random(0, test.size() - 1);
186 EXPECT_EQ(test[i], test.at(i));
191 template <class String> void clause_21_3_5_a(String & test) {
192 // 21.3.5 modifiers (+=)
194 randomString(&test1);
195 assert(test1.size() == strlen(test1.c_str()));
196 auto len = test.size();
198 EXPECT_EQ(test.size(), test1.size() + len);
199 FOR_EACH_RANGE (i, 0, test1.size()) {
200 EXPECT_EQ(test[len + i], test1[i]);
202 // aliasing modifiers
204 auto dt = test2.data();
205 auto sz = test.c_str();
207 EXPECT_EQ(memcmp(sz, dt, len), 0);
208 String copy(test.data(), test.size());
209 EXPECT_EQ(strlen(test.c_str()), len);
212 EXPECT_EQ(test.size(), 2 * len);
213 EXPECT_EQ(strlen(test.c_str()), 2 * len);
214 FOR_EACH_RANGE (i, 0, len) {
215 EXPECT_EQ(test[i], copy[i]);
216 EXPECT_EQ(test[i], test[len + i]);
219 EXPECT_EQ(strlen(test.c_str()), len);
221 auto const pos = random(0, test.size());
222 EXPECT_EQ(strlen(test.c_str() + pos), len - pos);
224 String addMe(test.c_str() + pos);
225 EXPECT_EQ(addMe.size(), len - pos);
228 test += test.c_str() + pos;
230 EXPECT_EQ(test.size(), 2 * len - pos);
233 test += random('a', 'z');
234 EXPECT_EQ(test.size(), len + 1);
237 template <class String> void clause_21_3_5_b(String & test) {
238 // 21.3.5 modifiers (append, push_back)
241 // Test with a small string first
242 char c = random('a', 'z');
244 EXPECT_EQ(s[s.size() - 1], c);
245 EXPECT_EQ(s.size(), 1);
246 s.resize(s.size() - 1);
248 randomString(&s, maxString);
250 randomString(&s, maxString);
251 test.append(s, random(0, s.size()), random(0, maxString));
252 randomString(&s, maxString);
253 test.append(s.c_str(), random(0, s.size()));
254 randomString(&s, maxString);
255 test.append(s.c_str());
256 test.append(random(0, maxString), random('a', 'z'));
257 std::list<char> lst(RandomList(maxString));
258 test.append(lst.begin(), lst.end());
259 c = random('a', 'z');
261 EXPECT_EQ(test[test.size() - 1], c);
264 template <class String> void clause_21_3_5_c(String & test) {
271 template <class String> void clause_21_3_5_d(String & test) {
274 randomString(&s, maxString);
275 test.assign(s, random(0, s.size()), random(0, maxString));
278 template <class String> void clause_21_3_5_e(String & test) {
281 randomString(&s, maxString);
282 test.assign(s.c_str(), random(0, s.size()));
285 template <class String> void clause_21_3_5_f(String & test) {
288 randomString(&s, maxString);
289 test.assign(s.c_str());
292 template <class String> void clause_21_3_5_g(String & test) {
295 randomString(&s, maxString);
296 test.assign(random(0, maxString), random('a', 'z'));
299 template <class String> void clause_21_3_5_h(String & test) {
300 // assign from bidirectional iterator
301 std::list<char> lst(RandomList(maxString));
302 test.assign(lst.begin(), lst.end());
305 template <class String> void clause_21_3_5_i(String & test) {
306 // assign from aliased source
310 template <class String> void clause_21_3_5_j(String & test) {
311 // assign from aliased source
312 test.assign(test, random(0, test.size()), random(0, maxString));
315 template <class String> void clause_21_3_5_k(String & test) {
316 // assign from aliased source
317 test.assign(test.c_str(), random(0, test.size()));
320 template <class String> void clause_21_3_5_l(String & test) {
321 // assign from aliased source
322 test.assign(test.c_str());
325 template <class String> void clause_21_3_5_m(String & test) {
328 randomString(&s, maxString);
329 test.insert(random(0, test.size()), s);
330 randomString(&s, maxString);
331 test.insert(random(0, test.size()),
332 s, random(0, s.size()),
333 random(0, maxString));
334 randomString(&s, maxString);
335 test.insert(random(0, test.size()),
336 s.c_str(), random(0, s.size()));
337 randomString(&s, maxString);
338 test.insert(random(0, test.size()), s.c_str());
339 test.insert(random(0, test.size()),
340 random(0, maxString), random('a', 'z'));
341 test.insert(test.begin() + random(0, test.size()),
343 std::list<char> lst(RandomList(maxString));
344 test.insert(test.begin() + random(0, test.size()),
345 lst.begin(), lst.end());
348 template <class String> void clause_21_3_5_n(String & test) {
351 test.erase(random(0, test.size()), random(0, maxString));
354 // TODO: is erase(end()) allowed?
355 test.erase(test.begin() + random(0, test.size() - 1));
358 auto const i = test.begin() + random(0, test.size());
359 if (i != test.end()) {
360 test.erase(i, i + random(0, size_t(test.end() - i)));
365 template <class String> void clause_21_3_5_o(String & test) {
366 auto pos = random(0, test.size());
368 test.replace(pos, random(0, test.size() - pos),
371 test.replace(pos, random(0, test.size() - pos), test);
373 pos = random(0, test.size());
375 randomString(&s, maxString);
376 test.replace(pos, pos + random(0, test.size() - pos), s);
377 auto pos1 = random(0, test.size());
378 auto pos2 = random(0, test.size());
380 test.replace(pos1, pos1 + random(0, test.size() - pos1),
382 pos2, pos2 + random(0, test.size() - pos2));
384 test.replace(pos1, pos1 + random(0, test.size() - pos1),
385 test, pos2, pos2 + random(0, test.size() - pos2));
387 pos1 = random(0, test.size());
389 randomString(&str, maxString);
390 pos2 = random(0, str.size());
391 test.replace(pos1, pos1 + random(0, test.size() - pos1),
392 str, pos2, pos2 + random(0, str.size() - pos2));
393 pos = random(0, test.size());
395 test.replace(pos, random(0, test.size() - pos),
396 String(test).c_str(), test.size());
398 test.replace(pos, random(0, test.size() - pos),
399 test.c_str(), test.size());
401 pos = random(0, test.size());
402 randomString(&str, maxString);
403 test.replace(pos, pos + random(0, test.size() - pos),
404 str.c_str(), str.size());
405 pos = random(0, test.size());
406 randomString(&str, maxString);
407 test.replace(pos, pos + random(0, test.size() - pos),
409 pos = random(0, test.size());
410 test.replace(pos, random(0, test.size() - pos),
411 random(0, maxString), random('a', 'z'));
412 pos = random(0, test.size());
416 test.begin() + pos + random(0, test.size() - pos),
421 test.begin() + pos + random(0, test.size() - pos),
424 pos = random(0, test.size());
428 test.begin() + pos + random(0, test.size() - pos),
429 String(test).c_str(),
430 test.size() - random(0, test.size()));
434 test.begin() + pos + random(0, test.size() - pos),
436 test.size() - random(0, test.size()));
438 pos = random(0, test.size());
439 auto const n = random(0, test.size() - pos);
440 typename String::iterator b = test.begin();
442 randomString(&str1, maxString);
443 const String & str3 = str1;
444 const typename String::value_type* ss = str3.c_str();
449 pos = random(0, test.size());
452 test.begin() + pos + random(0, test.size() - pos),
453 random(0, maxString), random('a', 'z'));
456 template <class String> void clause_21_3_5_p(String & test) {
457 std::vector<typename String::value_type>
458 vec(random(0, maxString));
462 random(0, test.size()));
465 template <class String> void clause_21_3_5_q(String & test) {
467 randomString(&s, maxString);
471 template <class String> void clause_21_3_6_a(String & test) {
472 // 21.3.6 string operations
473 // exercise c_str() and data()
474 assert(test.c_str() == test.data());
475 // exercise get_allocator()
477 randomString(&s, maxString);
478 assert(test.get_allocator() == s.get_allocator());
481 template <class String> void clause_21_3_6_b(String & test) {
482 String str = test.substr(
483 random(0, test.size()),
484 random(0, test.size()));
485 Num2String(test, test.find(str, random(0, test.size())));
488 template <class String> void clause_21_3_6_c(String & test) {
489 auto from = random(0, test.size());
490 auto length = random(0, test.size() - from);
491 String str = test.substr(from, length);
492 Num2String(test, test.find(str.c_str(),
493 random(0, test.size()),
494 random(0, str.size())));
497 template <class String> void clause_21_3_6_d(String & test) {
498 String str = test.substr(
499 random(0, test.size()),
500 random(0, test.size()));
501 Num2String(test, test.find(str.c_str(),
502 random(0, test.size())));
505 template <class String> void clause_21_3_6_e(String & test) {
506 Num2String(test, test.find(
508 random(0, test.size())));
511 template <class String> void clause_21_3_6_f(String & test) {
512 String str = test.substr(
513 random(0, test.size()),
514 random(0, test.size()));
515 Num2String(test, test.rfind(str, random(0, test.size())));
518 template <class String> void clause_21_3_6_g(String & test) {
519 String str = test.substr(
520 random(0, test.size()),
521 random(0, test.size()));
522 Num2String(test, test.rfind(str.c_str(),
523 random(0, test.size()),
524 random(0, str.size())));
527 template <class String> void clause_21_3_6_h(String & test) {
528 String str = test.substr(
529 random(0, test.size()),
530 random(0, test.size()));
531 Num2String(test, test.rfind(str.c_str(),
532 random(0, test.size())));
535 template <class String> void clause_21_3_6_i(String & test) {
536 Num2String(test, test.rfind(
538 random(0, test.size())));
541 template <class String> void clause_21_3_6_j(String & test) {
543 randomString(&str, maxString);
544 Num2String(test, test.find_first_of(str,
545 random(0, test.size())));
548 template <class String> void clause_21_3_6_k(String & test) {
550 randomString(&str, maxString);
551 Num2String(test, test.find_first_of(str.c_str(),
552 random(0, test.size()),
553 random(0, str.size())));
556 template <class String> void clause_21_3_6_l(String & test) {
558 randomString(&str, maxString);
559 Num2String(test, test.find_first_of(str.c_str(),
560 random(0, test.size())));
563 template <class String> void clause_21_3_6_m(String & test) {
564 Num2String(test, test.find_first_of(
566 random(0, test.size())));
569 template <class String> void clause_21_3_6_n(String & test) {
571 randomString(&str, maxString);
572 Num2String(test, test.find_last_of(str,
573 random(0, test.size())));
576 template <class String> void clause_21_3_6_o(String & test) {
578 randomString(&str, maxString);
579 Num2String(test, test.find_last_of(str.c_str(),
580 random(0, test.size()),
581 random(0, str.size())));
584 template <class String> void clause_21_3_6_p(String & test) {
586 randomString(&str, maxString);
587 Num2String(test, test.find_last_of(str.c_str(),
588 random(0, test.size())));
591 template <class String> void clause_21_3_6_q(String & test) {
592 Num2String(test, test.find_last_of(
594 random(0, test.size())));
597 template <class String> void clause_21_3_6_r(String & test) {
599 randomString(&str, maxString);
600 Num2String(test, test.find_first_not_of(str,
601 random(0, test.size())));
604 template <class String> void clause_21_3_6_s(String & test) {
606 randomString(&str, maxString);
607 Num2String(test, test.find_first_not_of(str.c_str(),
608 random(0, test.size()),
609 random(0, str.size())));
612 template <class String> void clause_21_3_6_t(String & test) {
614 randomString(&str, maxString);
615 Num2String(test, test.find_first_not_of(str.c_str(),
616 random(0, test.size())));
619 template <class String> void clause_21_3_6_u(String & test) {
620 Num2String(test, test.find_first_not_of(
622 random(0, test.size())));
625 template <class String> void clause_21_3_6_v(String & test) {
627 randomString(&str, maxString);
628 Num2String(test, test.find_last_not_of(str,
629 random(0, test.size())));
632 template <class String> void clause_21_3_6_w(String & test) {
634 randomString(&str, maxString);
635 Num2String(test, test.find_last_not_of(str.c_str(),
636 random(0, test.size()),
637 random(0, str.size())));
640 template <class String> void clause_21_3_6_x(String & test) {
642 randomString(&str, maxString);
643 Num2String(test, test.find_last_not_of(str.c_str(),
644 random(0, test.size())));
647 template <class String> void clause_21_3_6_y(String & test) {
648 Num2String(test, test.find_last_not_of(
650 random(0, test.size())));
653 template <class String> void clause_21_3_6_z(String & test) {
654 test = test.substr(random(0, test.size()), random(0, test.size()));
657 template <class String> void clause_21_3_7_a(String & test) {
659 randomString(&s, maxString);
660 int tristate = test.compare(s);
661 if (tristate > 0) tristate = 1;
662 else if (tristate < 0) tristate = 2;
663 Num2String(test, tristate);
666 template <class String> void clause_21_3_7_b(String & test) {
668 randomString(&s, maxString);
669 int tristate = test.compare(
670 random(0, test.size()),
671 random(0, test.size()),
673 if (tristate > 0) tristate = 1;
674 else if (tristate < 0) tristate = 2;
675 Num2String(test, tristate);
678 template <class String> void clause_21_3_7_c(String & test) {
680 randomString(&str, maxString);
681 int tristate = test.compare(
682 random(0, test.size()),
683 random(0, test.size()),
685 random(0, str.size()),
686 random(0, str.size()));
687 if (tristate > 0) tristate = 1;
688 else if (tristate < 0) tristate = 2;
689 Num2String(test, tristate);
692 template <class String> void clause_21_3_7_d(String & test) {
694 randomString(&s, maxString);
695 int tristate = test.compare(s.c_str());
696 if (tristate > 0) tristate = 1;
697 else if (tristate < 0) tristate = 2;
698 Num2String(test, tristate);
701 template <class String> void clause_21_3_7_e(String & test) {
703 randomString(&str, maxString);
704 int tristate = test.compare(
705 random(0, test.size()),
706 random(0, test.size()),
708 random(0, str.size()));
709 if (tristate > 0) tristate = 1;
710 else if (tristate < 0) tristate = 2;
711 Num2String(test, tristate);
714 template <class String> void clause_21_3_7_f(String & test) {
716 randomString(&s1, maxString);
718 randomString(&s2, maxString);
722 template <class String> void clause_21_3_7_g(String & test) {
724 randomString(&s, maxString);
726 randomString(&s1, maxString);
727 test = s.c_str() + s1;
730 template <class String> void clause_21_3_7_h(String & test) {
732 randomString(&s, maxString);
733 test = typename String::value_type(random('a', 'z')) + s;
736 template <class String> void clause_21_3_7_i(String & test) {
738 randomString(&s, maxString);
740 randomString(&s1, maxString);
741 test = s + s1.c_str();
744 template <class String> void clause_21_3_7_j(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_k(String & test) {
754 randomString(&s, maxString);
755 test = s + typename String::value_type(random('a', 'z'));
758 // Numbering here is from C++11
759 template <class String> void clause_21_4_8_9_a(String & test) {
760 stringstream s("asd asdfjhuhdf asdfasdf\tasdsdf");
768 TEST(FBString, testAllClauses) {
769 EXPECT_TRUE(1) << "Starting with seed: " << seed;
772 #define TEST_CLAUSE(x) \
774 if (1) {} else EXPECT_TRUE(1) << "Testing clause " << #x; \
778 auto localSeed = seed + count; \
779 rng = RandomT(localSeed); \
781 rng = RandomT(localSeed); \
784 << "Lengths: " << r.size() << " vs. " << c.size() \
785 << "\nReference: '" << r << "'" \
786 << "\nActual: '" << c.data()[0] << "'"; \
787 } while (++count % 100 != 0)
790 TEST_CLAUSE(21_3_1_a);
791 TEST_CLAUSE(21_3_1_b);
792 TEST_CLAUSE(21_3_1_c);
793 TEST_CLAUSE(21_3_1_d);
794 TEST_CLAUSE(21_3_1_e);
795 TEST_CLAUSE(21_3_1_f);
796 TEST_CLAUSE(21_3_1_g);
801 TEST_CLAUSE(21_3_5_a);
802 TEST_CLAUSE(21_3_5_b);
803 TEST_CLAUSE(21_3_5_c);
804 TEST_CLAUSE(21_3_5_d);
805 TEST_CLAUSE(21_3_5_e);
806 TEST_CLAUSE(21_3_5_f);
807 TEST_CLAUSE(21_3_5_g);
808 TEST_CLAUSE(21_3_5_h);
809 TEST_CLAUSE(21_3_5_i);
810 TEST_CLAUSE(21_3_5_j);
811 TEST_CLAUSE(21_3_5_k);
812 TEST_CLAUSE(21_3_5_l);
813 TEST_CLAUSE(21_3_5_m);
814 TEST_CLAUSE(21_3_5_n);
815 TEST_CLAUSE(21_3_5_o);
816 TEST_CLAUSE(21_3_5_p);
818 TEST_CLAUSE(21_3_6_a);
819 TEST_CLAUSE(21_3_6_b);
820 TEST_CLAUSE(21_3_6_c);
821 TEST_CLAUSE(21_3_6_d);
822 TEST_CLAUSE(21_3_6_e);
823 TEST_CLAUSE(21_3_6_f);
824 TEST_CLAUSE(21_3_6_g);
825 TEST_CLAUSE(21_3_6_h);
826 TEST_CLAUSE(21_3_6_i);
827 TEST_CLAUSE(21_3_6_j);
828 TEST_CLAUSE(21_3_6_k);
829 TEST_CLAUSE(21_3_6_l);
830 TEST_CLAUSE(21_3_6_m);
831 TEST_CLAUSE(21_3_6_n);
832 TEST_CLAUSE(21_3_6_o);
833 TEST_CLAUSE(21_3_6_p);
834 TEST_CLAUSE(21_3_6_q);
835 TEST_CLAUSE(21_3_6_r);
836 TEST_CLAUSE(21_3_6_s);
837 TEST_CLAUSE(21_3_6_t);
838 TEST_CLAUSE(21_3_6_u);
839 TEST_CLAUSE(21_3_6_v);
840 TEST_CLAUSE(21_3_6_w);
841 TEST_CLAUSE(21_3_6_x);
842 TEST_CLAUSE(21_3_6_y);
843 TEST_CLAUSE(21_3_6_z);
845 TEST_CLAUSE(21_3_7_a);
846 TEST_CLAUSE(21_3_7_b);
847 TEST_CLAUSE(21_3_7_c);
848 TEST_CLAUSE(21_3_7_d);
849 TEST_CLAUSE(21_3_7_e);
850 TEST_CLAUSE(21_3_7_f);
851 TEST_CLAUSE(21_3_7_g);
852 TEST_CLAUSE(21_3_7_h);
853 TEST_CLAUSE(21_3_7_i);
854 TEST_CLAUSE(21_3_7_j);
855 TEST_CLAUSE(21_3_7_k);
857 TEST_CLAUSE(21_4_8_9_a);
860 TEST(FBString, testGetline) {
862 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras accumsan \n\
863 elit ut urna consectetur in sagittis mi auctor. Nulla facilisi. In nec \n\
864 dolor leo, vitae imperdiet neque. Donec ut erat mauris, a faucibus \n\
865 elit. Integer consectetur gravida augue, sit amet mattis mauris auctor \n\
866 sed. Morbi congue libero eu nunc sodales adipiscing. In lectus nunc, \n\
867 vulputate a fringilla at, venenatis quis justo. Proin eu velit \n\
868 nibh. Maecenas vitae tellus eros. Pellentesque habitant morbi \n\
869 tristique senectus et netus et malesuada fames ac turpis \n\
870 egestas. Vivamus faucibus feugiat consequat. Donec fermentum neque sit \n\
871 amet ligula suscipit porta. Phasellus facilisis felis in purus luctus \n\
872 quis posuere leo tempor. Nam nunc purus, luctus a pharetra ut, \n\
873 placerat at dui. Donec imperdiet, diam quis convallis pulvinar, dui \n\
874 est commodo lorem, ut tincidunt diam nibh et nibh. Maecenas nec velit \n\
875 massa, ut accumsan magna. Donec imperdiet tempor nisi et \n\
876 laoreet. Phasellus lectus quam, ultricies ut tincidunt in, dignissim \n\
877 id eros. Mauris vulputate tortor nec neque pellentesque sagittis quis \n\
878 sed nisl. In diam lacus, lobortis ut posuere nec, ornare id quam.";
879 char f[] = "/tmp/fbstring_testing.XXXXXX";
884 std::ofstream out(f);
886 EXPECT_TRUE(0) << "Couldn't write to temp file.";
891 boost::split(v, s1, boost::is_any_of("\n"));
896 EXPECT_TRUE(getline(input, line));
903 TEST(FBString, testMoveCtor) {
904 // Move constructor. Make sure we allocate a large string, so the
905 // small string optimization doesn't kick in.
906 auto size = random(100, 2000);
907 fbstring s(size, 'a');
908 fbstring test = std::move(s);
909 EXPECT_TRUE(s.empty());
910 EXPECT_EQ(size, test.size());
913 TEST(FBString, testMoveAssign) {
914 // Move constructor. Make sure we allocate a large string, so the
915 // small string optimization doesn't kick in.
916 auto size = random(100, 2000);
917 fbstring s(size, 'a');
920 EXPECT_TRUE(s.empty());
921 EXPECT_EQ(size, test.size());
924 TEST(FBString, testMoveOperatorPlusLhs) {
925 // Make sure we allocate a large string, so the
926 // small string optimization doesn't kick in.
927 auto size1 = random(100, 2000);
928 auto size2 = random(100, 2000);
929 fbstring s1(size1, 'a');
930 fbstring s2(size2, 'b');
932 test = std::move(s1) + s2;
933 EXPECT_TRUE(s1.empty());
934 EXPECT_EQ(size1 + size2, test.size());
937 TEST(FBString, testMoveOperatorPlusRhs) {
938 // Make sure we allocate a large string, so the
939 // small string optimization doesn't kick in.
940 auto size1 = random(100, 2000);
941 auto size2 = random(100, 2000);
942 fbstring s1(size1, 'a');
943 fbstring s2(size2, 'b');
945 test = s1 + std::move(s2);
946 EXPECT_EQ(size1 + size2, test.size());
949 TEST(FBString, testConstructionFromLiteralZero) {
953 } catch (const std::logic_error&) {
961 } catch (const std::logic_error& e) {
967 TEST(FBString, testFixedBugs) {
969 fbstring str(1337, 'f');
973 EXPECT_EQ(str.front(), 'f');
975 { // D481173, --extra-cxxflags=-DFBSTRING_CONSERVATIVE
976 fbstring str(1337, 'f');
977 for (int i = 0; i < 2; ++i) {
980 EXPECT_EQ(cp.c_str()[cp.size()], '\0');
986 fbstring str(1337, 'f');
991 fbstring str(1337, 'f');
998 int main(int argc, char** argv) {
999 testing::InitGoogleTest(&argc, argv);
1000 google::ParseCommandLineFlags(&argc, &argv, true);
1001 return RUN_ALL_TESTS();