| // Copyright 2017 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <iterator> |
| #include <string_view> |
| #include <utility> |
| |
| #include <fbl/algorithm.h> |
| #include <fbl/string.h> |
| #include <zxtest/zxtest.h> |
| |
| namespace fbl { |
| namespace tests { |
| struct StringTestHelper { |
| static unsigned int GetRefCount(const String& str) { return str.ref_count(); } |
| }; |
| } // namespace tests |
| } // namespace fbl |
| |
| using fbl::tests::StringTestHelper; |
| |
| namespace { |
| |
| TEST(StringTest, Empty) { |
| { |
| fbl::String empty; |
| |
| EXPECT_STR_EQ("", empty.data()); |
| EXPECT_STR_EQ("", empty.c_str()); |
| |
| EXPECT_EQ(0u, empty.length()); |
| EXPECT_EQ(0u, empty.size()); |
| EXPECT_TRUE(empty.empty()); |
| |
| EXPECT_STR_EQ("", empty.begin()); |
| EXPECT_EQ(0u, empty.end() - empty.begin()); |
| EXPECT_STR_EQ("", empty.cbegin()); |
| EXPECT_EQ(0u, empty.cend() - empty.cbegin()); |
| |
| EXPECT_EQ(0, empty[0u]); |
| } |
| |
| { |
| fbl::String empty(""); |
| |
| EXPECT_STR_EQ("", empty.data()); |
| EXPECT_STR_EQ("", empty.c_str()); |
| |
| EXPECT_EQ(0u, empty.length()); |
| EXPECT_EQ(0u, empty.size()); |
| EXPECT_TRUE(empty.empty()); |
| |
| EXPECT_STR_EQ("", empty.begin()); |
| EXPECT_EQ(0u, empty.end() - empty.begin()); |
| EXPECT_STR_EQ("", empty.cbegin()); |
| EXPECT_EQ(0u, empty.cend() - empty.cbegin()); |
| |
| EXPECT_EQ(0, empty[0u]); |
| } |
| |
| { |
| fbl::String empty("abcde", size_t(0u)); |
| |
| EXPECT_STR_EQ("", empty.data()); |
| EXPECT_STR_EQ("", empty.c_str()); |
| |
| EXPECT_EQ(0u, empty.length()); |
| EXPECT_EQ(0u, empty.size()); |
| EXPECT_TRUE(empty.empty()); |
| |
| EXPECT_STR_EQ("", empty.begin()); |
| EXPECT_EQ(0u, empty.end() - empty.begin()); |
| EXPECT_STR_EQ("", empty.cbegin()); |
| EXPECT_EQ(0u, empty.cend() - empty.cbegin()); |
| |
| EXPECT_EQ(0, empty[0u]); |
| } |
| |
| { |
| fbl::String empty(0u, 'x'); |
| |
| EXPECT_STR_EQ("", empty.data()); |
| EXPECT_STR_EQ("", empty.c_str()); |
| |
| EXPECT_EQ(0u, empty.length()); |
| EXPECT_EQ(0u, empty.size()); |
| EXPECT_TRUE(empty.empty()); |
| |
| EXPECT_STR_EQ("", empty.begin()); |
| EXPECT_EQ(0u, empty.end() - empty.begin()); |
| EXPECT_STR_EQ("", empty.cbegin()); |
| EXPECT_EQ(0u, empty.cend() - empty.cbegin()); |
| |
| EXPECT_EQ(0, empty[0u]); |
| } |
| |
| { |
| fbl::String empty(std::string_view("abcde", 0u)); |
| |
| EXPECT_STR_EQ("", empty.data()); |
| EXPECT_STR_EQ("", empty.c_str()); |
| |
| EXPECT_EQ(0u, empty.length()); |
| EXPECT_EQ(0u, empty.size()); |
| EXPECT_TRUE(empty.empty()); |
| |
| EXPECT_STR_EQ("", empty.begin()); |
| EXPECT_EQ(0u, empty.end() - empty.begin()); |
| EXPECT_STR_EQ("", empty.cbegin()); |
| EXPECT_EQ(0u, empty.cend() - empty.cbegin()); |
| |
| EXPECT_EQ(0, empty[0u]); |
| } |
| } |
| |
| TEST(StringTest, NonEmpty) { |
| { |
| fbl::String str("abc"); |
| |
| EXPECT_STR_EQ("abc", str.data()); |
| |
| EXPECT_EQ(3u, str.length()); |
| EXPECT_EQ(3u, str.size()); |
| EXPECT_FALSE(str.empty()); |
| |
| EXPECT_STR_EQ("abc", str.begin()); |
| EXPECT_EQ(3u, str.end() - str.begin()); |
| EXPECT_STR_EQ("abc", str.cbegin()); |
| EXPECT_EQ(3u, str.cend() - str.cbegin()); |
| |
| EXPECT_EQ('b', str[1u]); |
| } |
| |
| { |
| fbl::String str("abc", 2u); |
| |
| EXPECT_STR_EQ("ab", str.data()); |
| |
| EXPECT_EQ(2u, str.length()); |
| EXPECT_EQ(2u, str.size()); |
| EXPECT_FALSE(str.empty()); |
| |
| EXPECT_STR_EQ("ab", str.begin()); |
| EXPECT_EQ(2u, str.end() - str.begin()); |
| EXPECT_STR_EQ("ab", str.cbegin()); |
| EXPECT_EQ(2u, str.cend() - str.cbegin()); |
| |
| EXPECT_EQ('b', str[1u]); |
| } |
| |
| { |
| fbl::String str(10u, 'x'); |
| |
| EXPECT_STR_EQ("xxxxxxxxxx", str.data()); |
| |
| EXPECT_EQ(10u, str.length()); |
| EXPECT_EQ(10u, str.size()); |
| EXPECT_FALSE(str.empty()); |
| |
| EXPECT_STR_EQ("xxxxxxxxxx", str.begin()); |
| EXPECT_EQ(10u, str.end() - str.begin()); |
| EXPECT_STR_EQ("xxxxxxxxxx", str.cbegin()); |
| EXPECT_EQ(10u, str.cend() - str.cbegin()); |
| |
| EXPECT_EQ('x', str[1u]); |
| } |
| |
| { |
| fbl::String str(std::string_view("abcdef", 2u)); |
| |
| EXPECT_STR_EQ("ab", str.data()); |
| |
| EXPECT_EQ(2u, str.length()); |
| EXPECT_EQ(2u, str.size()); |
| EXPECT_FALSE(str.empty()); |
| |
| EXPECT_STR_EQ("ab", str.begin()); |
| EXPECT_EQ(2u, str.end() - str.begin()); |
| EXPECT_STR_EQ("ab", str.cbegin()); |
| EXPECT_EQ(2u, str.cend() - str.cbegin()); |
| |
| EXPECT_EQ('b', str[1u]); |
| } |
| } |
| |
| TEST(StringTest, CopyMoveAndAssignment) { |
| { |
| fbl::String abc("abc"); |
| fbl::String copy(abc); |
| EXPECT_STR_EQ("abc", abc.data()); |
| EXPECT_EQ(abc.data(), copy.data()); |
| EXPECT_EQ(3u, copy.length()); |
| } |
| |
| { |
| fbl::String abc("abc"); |
| fbl::String copy(abc); |
| fbl::String move(std::move(copy)); |
| EXPECT_STR_EQ("abc", abc.data()); |
| EXPECT_STR_EQ("", copy.data()); |
| EXPECT_EQ(abc.data(), move.data()); |
| EXPECT_EQ(3u, move.length()); |
| } |
| |
| { |
| fbl::String abc("abc"); |
| fbl::String str; |
| str = abc; |
| EXPECT_STR_EQ("abc", abc.data()); |
| EXPECT_EQ(abc.data(), str.data()); |
| EXPECT_EQ(3u, str.length()); |
| } |
| |
| { |
| fbl::String abc("abc"); |
| fbl::String copy(abc); |
| fbl::String str; |
| str = std::move(copy); |
| EXPECT_STR_EQ("abc", abc.data()); |
| EXPECT_STR_EQ("", copy.data()); |
| EXPECT_EQ(abc.data(), str.data()); |
| EXPECT_EQ(3u, str.length()); |
| } |
| |
| { |
| fbl::String str; |
| str = "abc"; |
| EXPECT_STR_EQ("abc", str.data()); |
| EXPECT_EQ(3u, str.length()); |
| |
| str = ""; |
| EXPECT_STR_EQ("", str.data()); |
| EXPECT_EQ(0u, str.length()); |
| |
| fbl::String copy(str); |
| EXPECT_STR_EQ("", copy.data()); |
| EXPECT_EQ(0u, copy.length()); |
| |
| fbl::String move(copy); |
| EXPECT_STR_EQ("", copy.data()); |
| EXPECT_EQ(0u, copy.length()); |
| EXPECT_STR_EQ("", move.data()); |
| EXPECT_EQ(0u, move.length()); |
| } |
| } |
| |
| TEST(StringTest, Clear) { |
| fbl::String str = "abc"; |
| EXPECT_STR_EQ("abc", str.data()); |
| EXPECT_EQ(3u, str.length()); |
| |
| str.clear(); |
| EXPECT_STR_EQ("", str.data()); |
| EXPECT_EQ(0u, str.length()); |
| } |
| |
| TEST(StringTest, Compare) { |
| const char data[] = "abc"; |
| fbl::String empty; |
| fbl::String a(data, 1); |
| fbl::String ab(data, 2); |
| fbl::String b(data + 1, 1); |
| fbl::String bc(data + 1, 2); |
| |
| EXPECT_EQ(0, empty.compare(empty)); |
| EXPECT_LT(empty.compare(a), 0); |
| EXPECT_GT(a.compare(empty), 0); |
| |
| EXPECT_EQ(0, a.compare(a)); |
| EXPECT_EQ(0, ab.compare(ab)); |
| EXPECT_LT(a.compare(ab), 0); |
| EXPECT_GT(ab.compare(a), 0); |
| EXPECT_LT(ab.compare(bc), 0); |
| EXPECT_GT(bc.compare(ab), 0); |
| |
| EXPECT_TRUE(empty == empty); |
| EXPECT_TRUE(empty <= empty); |
| EXPECT_TRUE(empty >= empty); |
| EXPECT_FALSE(empty != empty); |
| EXPECT_FALSE(empty < empty); |
| EXPECT_FALSE(empty > empty); |
| EXPECT_TRUE(empty < a); |
| EXPECT_TRUE(a > empty); |
| |
| EXPECT_TRUE(a == a); |
| EXPECT_TRUE(ab == ab); |
| EXPECT_TRUE(a != ab); |
| EXPECT_TRUE(a != b); |
| EXPECT_TRUE(ab != a); |
| |
| EXPECT_FALSE(a < a); |
| EXPECT_FALSE(a > a); |
| EXPECT_TRUE(a >= a); |
| EXPECT_TRUE(a <= a); |
| |
| EXPECT_TRUE(a < ab); |
| EXPECT_FALSE(a > ab); |
| EXPECT_FALSE(a >= ab); |
| EXPECT_TRUE(a <= ab); |
| |
| EXPECT_FALSE(ab < a); |
| EXPECT_TRUE(ab > a); |
| EXPECT_TRUE(ab >= a); |
| EXPECT_FALSE(ab <= a); |
| |
| EXPECT_TRUE(a < b); |
| EXPECT_FALSE(a > b); |
| EXPECT_FALSE(a >= b); |
| EXPECT_TRUE(a <= b); |
| |
| EXPECT_FALSE(b < a); |
| EXPECT_TRUE(b > a); |
| EXPECT_TRUE(b >= a); |
| EXPECT_FALSE(b <= a); |
| |
| EXPECT_TRUE(a < bc); |
| EXPECT_FALSE(a > bc); |
| EXPECT_FALSE(a >= bc); |
| EXPECT_TRUE(a <= bc); |
| |
| EXPECT_FALSE(bc < a); |
| EXPECT_TRUE(bc > a); |
| EXPECT_TRUE(bc >= a); |
| EXPECT_FALSE(bc <= a); |
| } |
| |
| TEST(StringTest, Concat) { |
| { |
| fbl::String empty = fbl::String::Concat({}); |
| EXPECT_STR_EQ("", empty.c_str()); |
| EXPECT_EQ(0u, empty.length()); |
| } |
| |
| { |
| fbl::String empty = fbl::String::Concat({""}); |
| EXPECT_STR_EQ("", empty.c_str()); |
| EXPECT_EQ(0u, empty.length()); |
| } |
| |
| { |
| fbl::String empty = fbl::String::Concat({"", "", "", ""}); |
| EXPECT_STR_EQ("", empty.c_str()); |
| EXPECT_EQ(0u, empty.length()); |
| } |
| |
| { |
| fbl::String str = fbl::String::Concat({"abc"}); |
| EXPECT_STR_EQ("abc", str.c_str()); |
| EXPECT_EQ(3u, str.length()); |
| } |
| |
| { |
| fbl::String str = fbl::String::Concat({"abc", "def"}); |
| EXPECT_STR_EQ("abcdef", str.c_str()); |
| EXPECT_EQ(6u, str.length()); |
| } |
| |
| { |
| fbl::String str = fbl::String::Concat({"abc", "", "def"}); |
| EXPECT_STR_EQ("abcdef", str.c_str()); |
| EXPECT_EQ(6u, str.length()); |
| } |
| |
| { |
| fbl::String str = fbl::String::Concat({"abc", "def", ""}); |
| EXPECT_STR_EQ("abcdef", str.c_str()); |
| EXPECT_EQ(6u, str.length()); |
| } |
| |
| { |
| fbl::String str = fbl::String::Concat({"", "abc", "def"}); |
| EXPECT_STR_EQ("abcdef", str.c_str()); |
| EXPECT_EQ(6u, str.length()); |
| } |
| |
| { |
| fbl::String str = fbl::String::Concat({"abc", "def", "g", "hi", "jklmnop"}); |
| EXPECT_STR_EQ("abcdefghijklmnop", str.c_str()); |
| EXPECT_EQ(16u, str.length()); |
| } |
| } |
| |
| TEST(StringTest, ToString) { |
| { |
| fbl::String empty; |
| std::string_view piece(empty); |
| EXPECT_EQ(empty.data(), piece.data()); |
| EXPECT_EQ(0u, piece.length()); |
| } |
| |
| { |
| fbl::String str("abc"); |
| std::string_view piece(str); |
| EXPECT_EQ(str.data(), piece.data()); |
| EXPECT_EQ(3u, piece.length()); |
| } |
| } |
| |
| TEST(StringTest, ToStringPiece) { |
| { |
| fbl::String empty; |
| std::string_view view(empty); |
| EXPECT_EQ(empty.data(), view.data()); |
| EXPECT_EQ(0u, view.length()); |
| } |
| |
| { |
| fbl::String str("abc"); |
| std::string_view view(str); |
| EXPECT_EQ(str.data(), view.data()); |
| EXPECT_EQ(3u, view.length()); |
| } |
| } |
| |
| TEST(StringTest, Swap) { |
| fbl::String empty; |
| fbl::String abc("abc"); |
| fbl::String def("def"); |
| |
| abc.swap(def); |
| empty.swap(abc); |
| |
| EXPECT_STR_EQ("def", empty.data()); |
| EXPECT_STR_EQ("", abc.data()); |
| EXPECT_STR_EQ("abc", def.data()); |
| } |
| |
| TEST(StringTest, RefCount) { |
| // Empty strings |
| |
| { |
| fbl::String empty; |
| unsigned int initial_ref_count = StringTestHelper::GetRefCount(empty); |
| EXPECT_GT(initial_ref_count, 1u); |
| { |
| fbl::String copy(empty); |
| EXPECT_EQ(empty.data(), copy.data()); |
| EXPECT_EQ(initial_ref_count + 1u, StringTestHelper::GetRefCount(empty)); |
| { |
| fbl::String another_empty(""); |
| EXPECT_EQ(empty.data(), another_empty.data()); |
| EXPECT_EQ(initial_ref_count + 2u, StringTestHelper::GetRefCount(empty)); |
| { |
| fbl::String assigned_from_empty = another_empty; |
| EXPECT_EQ(empty.data(), assigned_from_empty.data()); |
| EXPECT_EQ(initial_ref_count + 3u, StringTestHelper::GetRefCount(empty)); |
| |
| assigned_from_empty = ""; |
| EXPECT_EQ(empty.data(), assigned_from_empty.data()); |
| EXPECT_EQ(initial_ref_count + 3u, StringTestHelper::GetRefCount(empty)); |
| |
| assigned_from_empty = empty; |
| EXPECT_EQ(empty.data(), assigned_from_empty.data()); |
| EXPECT_EQ(initial_ref_count + 3u, StringTestHelper::GetRefCount(empty)); |
| |
| assigned_from_empty.clear(); |
| EXPECT_EQ(empty.data(), assigned_from_empty.data()); |
| EXPECT_EQ(initial_ref_count + 3u, StringTestHelper::GetRefCount(empty)); |
| } |
| EXPECT_EQ(initial_ref_count + 2u, StringTestHelper::GetRefCount(empty)); |
| } |
| EXPECT_EQ(initial_ref_count + 1u, StringTestHelper::GetRefCount(empty)); |
| } |
| EXPECT_EQ(initial_ref_count, StringTestHelper::GetRefCount(empty)); |
| } |
| |
| // C-string initialized strings. |
| |
| { |
| fbl::String abc("abc"); |
| EXPECT_EQ(1u, StringTestHelper::GetRefCount(abc)); |
| { |
| fbl::String copy1(abc); |
| EXPECT_EQ(abc.data(), copy1.data()); |
| EXPECT_EQ(2u, StringTestHelper::GetRefCount(abc)); |
| { |
| fbl::String copy2(abc); |
| EXPECT_EQ(abc.data(), copy2.data()); |
| EXPECT_EQ(3u, StringTestHelper::GetRefCount(abc)); |
| { |
| fbl::String assigned_from_abc = abc; |
| EXPECT_EQ(abc.data(), assigned_from_abc.data()); |
| EXPECT_EQ(4u, StringTestHelper::GetRefCount(abc)); |
| |
| assigned_from_abc = ""; |
| EXPECT_STR_EQ("", assigned_from_abc.data()); |
| EXPECT_EQ(3u, StringTestHelper::GetRefCount(abc)); |
| |
| assigned_from_abc = abc; |
| EXPECT_EQ(abc.data(), assigned_from_abc.data()); |
| EXPECT_EQ(4u, StringTestHelper::GetRefCount(abc)); |
| |
| assigned_from_abc.clear(); |
| EXPECT_STR_EQ("", assigned_from_abc.data()); |
| EXPECT_EQ(3u, StringTestHelper::GetRefCount(abc)); |
| } |
| EXPECT_EQ(3u, StringTestHelper::GetRefCount(abc)); |
| } |
| EXPECT_EQ(2u, StringTestHelper::GetRefCount(abc)); |
| } |
| EXPECT_EQ(1u, StringTestHelper::GetRefCount(abc)); |
| } |
| |
| // Repeated character initialized strings. |
| |
| { |
| fbl::String xs(10u, 'x'); |
| EXPECT_EQ(1u, StringTestHelper::GetRefCount(xs)); |
| { |
| fbl::String copy1(xs); |
| EXPECT_EQ(xs.data(), copy1.data()); |
| EXPECT_EQ(2u, StringTestHelper::GetRefCount(xs)); |
| { |
| fbl::String copy2(xs); |
| EXPECT_EQ(xs.data(), copy2.data()); |
| EXPECT_EQ(3u, StringTestHelper::GetRefCount(xs)); |
| { |
| fbl::String assigned_from_xs = xs; |
| EXPECT_EQ(xs.data(), assigned_from_xs.data()); |
| EXPECT_EQ(4u, StringTestHelper::GetRefCount(xs)); |
| |
| assigned_from_xs = ""; |
| EXPECT_STR_EQ("", assigned_from_xs.data()); |
| EXPECT_EQ(3u, StringTestHelper::GetRefCount(xs)); |
| |
| assigned_from_xs = xs; |
| EXPECT_EQ(xs.data(), assigned_from_xs.data()); |
| EXPECT_EQ(4u, StringTestHelper::GetRefCount(xs)); |
| |
| assigned_from_xs.clear(); |
| EXPECT_STR_EQ("", assigned_from_xs.data()); |
| EXPECT_EQ(3u, StringTestHelper::GetRefCount(xs)); |
| } |
| EXPECT_EQ(3u, StringTestHelper::GetRefCount(xs)); |
| } |
| EXPECT_EQ(2u, StringTestHelper::GetRefCount(xs)); |
| } |
| EXPECT_EQ(1u, StringTestHelper::GetRefCount(xs)); |
| } |
| } |
| |
| } // namespace |