blob: 69719fb49c7c9172b2a8a72b9d79835346b1165b [file] [log] [blame]
// Copyright 2014 The Android Open Source Project
//
// This software is licensed under the terms of the GNU General Public
// License version 2, as published by the Free Software Foundation, and
// may be copied, distributed, and modified under those terms.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
#include "android/base/String.h"
#include "android/base/StringView.h"
#include <gtest/gtest.h>
namespace android {
namespace base {
TEST(String, DefaultConstructor) {
String s;
EXPECT_EQ(0U, s.size());
EXPECT_TRUE(s.empty());
}
TEST(String, SimpleConstructor) {
static const char kString[] = "hello you";
const size_t kStringLen = sizeof(kString) - 1U;
String s(kString);
EXPECT_NE(kString, s.c_str());
EXPECT_EQ(kStringLen, s.size());
EXPECT_FALSE(s.empty());
EXPECT_STREQ(kString, s.c_str());
}
TEST(String, SimpleConstructorWithLongString) {
static const char kString[] =
"this is a long string that should exceed the "
"small-string-optimization capacity";
const size_t kStringLen = sizeof(kString) - 1U;
String s(kString);
EXPECT_NE(kString, s.c_str());
EXPECT_EQ(kStringLen, s.size());
EXPECT_FALSE(s.empty());
EXPECT_STREQ(kString, s.c_str());
}
TEST(String, CopyConstructor) {
String s1("Hello World!");
String s2(s1);
EXPECT_EQ(s1.size(), s2.size());
EXPECT_STREQ(s1.c_str(), s2.c_str());
}
TEST(String, ConstructorFromStringView) {
StringView view("Hello Cowboys");
String s(view);
EXPECT_NE(view.str(), s.c_str());
EXPECT_EQ(view.size(), s.size());
EXPECT_STREQ(view.str(), s.c_str());
}
TEST(String, ConstructorWithCountAndFill) {
const size_t kCount = 1024;
const char kFill = 0x42;
String s(kCount, kFill);
EXPECT_EQ(kCount, s.size());
for (size_t n = 0; n < kCount; ++n)
EXPECT_EQ(kFill, s[n]);
}
TEST(String, empty) {
String s1("");
EXPECT_TRUE(s1.empty());
String s2("foo");
EXPECT_FALSE(s2.empty());
}
TEST(String, size) {
const size_t kCount = 4096;
String s;
for (size_t n = 0; n < kCount; ++n) {
EXPECT_EQ(n, s.size());
s += 'x';
}
EXPECT_EQ(kCount, s.size());
}
TEST(String, clear) {
String s("foo bar");
EXPECT_FALSE(s.empty());
s.clear();
EXPECT_TRUE(s.empty());
EXPECT_EQ(0U, s.size());
}
TEST(String, IndexedAccess) {
String s("foobar");
EXPECT_EQ('f', s[0]);
EXPECT_EQ('o', s[1]);
EXPECT_EQ('o', s[2]);
EXPECT_EQ('b', s[3]);
EXPECT_EQ('a', s[4]);
EXPECT_EQ('r', s[5]);
EXPECT_EQ('\0', s[6]);
}
TEST(String, AssignOperatorWithCString) {
static const char kString[] = "Hello 10234";
const size_t kStringLen = sizeof(kString) - 1U;
String s;
s = kString;
EXPECT_NE(kString, s.c_str());
EXPECT_EQ(kStringLen, s.size());
EXPECT_STREQ(kString, s.c_str());
}
TEST(String, AssignOperatorWithOtherString) {
String s0("A fish named Wanda");
String s;
s = s0;
EXPECT_EQ(s0.size(), s.size());
EXPECT_STREQ(s0.c_str(), s.c_str());
}
TEST(String, AssignOperatorWithStringView) {
StringView v0("What a beautiful world");
String s;
s = v0;
EXPECT_EQ(v0.size(), s.size());
EXPECT_STREQ(v0.str(), s.c_str());
}
TEST(String, AssignOperatorWithChar) {
String s;
s = 'f';
EXPECT_EQ(1U, s.size());
EXPECT_EQ('f', s[0]);
}
TEST(String, assignWithCString) {
static const char kString[] = "Hello";
const size_t kStringLen = sizeof(kString) - 1U;
String s;
s.assign(kString);
EXPECT_EQ(kStringLen, s.size());
EXPECT_STREQ(kString, s.c_str());
}
TEST(String, assignWithString) {
String s0("Input string");
String s;
s.assign(s0);
EXPECT_EQ(s0.size(), s.size());
EXPECT_STREQ(s0.c_str(), s.c_str());
}
TEST(String, assignWithStringAndLen) {
static const char kString[] = "Who you're gonna call?";
const size_t kStringLen = sizeof(kString) - 1U;
String s;
s.assign(kString, kStringLen);
EXPECT_NE(kString, s.c_str());
EXPECT_EQ(kStringLen, s.size());
EXPECT_STREQ(kString, s.c_str());
}
TEST(String, assignWithCountAndFill) {
const size_t kCount = 1024;
const char kFill = '\x7f';
String s;
s.assign(kCount, kFill);
EXPECT_EQ(kCount, s.size());
for (size_t n = 0; n < kCount; ++n) {
EXPECT_EQ(kFill, s[n]) << "At index " << n;
}
}
TEST(String, assignWithStringView) {
StringView v0("Input string view");
String s;
s.assign(v0);
EXPECT_EQ(v0.size(), s.size());
EXPECT_STREQ(v0.str(), s.c_str());
}
TEST(String, assignWithChar) {
String s;
s.assign('f');
EXPECT_EQ(1U, s.size());
EXPECT_STREQ("f", s.c_str());
}
typedef struct {
const char* s1;
const char* s2;
int expected;
} Comparison;
static const Comparison kComparisons[] = {
{ "", "", 0 },
{ "", "foo", -1 },
{ "foo", "", +1 },
{ "foo", "zoo", -1 },
{ "foo", "foo", 0 },
{ "foo", "fo", +1 },
{ "foo", "fooo", -1 },
{ "foo", "fop", -1 },
{ "foo", "fon", +1 },
};
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
TEST(String, compareWithCString) {
for (size_t n = 0; n < ARRAY_SIZE(kComparisons); ++n) {
const Comparison& comp = kComparisons[n];
String s(comp.s1);
EXPECT_EQ(comp.expected, s.compare(comp.s2))
<< "Comparing '" << comp.s1 << "' with '"
<< comp.s2 << "'";
}
}
TEST(String, compareWithCStringWithLen) {
for (size_t n = 0; n < ARRAY_SIZE(kComparisons); ++n) {
const Comparison& comp = kComparisons[n];
String s(comp.s1);
size_t len2 = ::strlen(comp.s2);
EXPECT_EQ(comp.expected, s.compare(comp.s2, len2))
<< "Comparing '" << comp.s1 << "' with '"
<< comp.s2 << "'";
}
}
TEST(String, compareWithString) {
for (size_t n = 0; n < ARRAY_SIZE(kComparisons); ++n) {
const Comparison& comp = kComparisons[n];
String s1(comp.s1);
String s2(comp.s2);
EXPECT_EQ(comp.expected, s1.compare(s2))
<< "Comparing '" << comp.s1 << "' with '"
<< comp.s2 << "'";
}
}
TEST(String, compareWithStringView) {
for (size_t n = 0; n < ARRAY_SIZE(kComparisons); ++n) {
const Comparison& comp = kComparisons[n];
String s1(comp.s1);
StringView s2(comp.s2);
EXPECT_EQ(comp.expected, s1.compare(s2))
<< "Comparing '" << comp.s1 << "' with '"
<< comp.s2 << "'";
}
}
TEST(String, equalsWithCString) {
for (size_t n = 0; n < ARRAY_SIZE(kComparisons); ++n) {
const Comparison& comp = kComparisons[n];
String s(comp.s1);
EXPECT_EQ(!comp.expected, s.equals(comp.s2))
<< "Comparing '" << comp.s1 << "' with '"
<< comp.s2 << "'";
}
}
TEST(String, equalsWithCStringWithLen) {
for (size_t n = 0; n < ARRAY_SIZE(kComparisons); ++n) {
const Comparison& comp = kComparisons[n];
String s(comp.s1);
size_t len2 = ::strlen(comp.s2);
EXPECT_EQ(!comp.expected, s.equals(comp.s2, len2))
<< "Comparing '" << comp.s1 << "' with '"
<< comp.s2 << "'";
}
}
TEST(String, equalsWithString) {
for (size_t n = 0; n < ARRAY_SIZE(kComparisons); ++n) {
const Comparison& comp = kComparisons[n];
String s1(comp.s1);
String s2(comp.s2);
EXPECT_EQ(!comp.expected, s1.equals(s2))
<< "Comparing '" << comp.s1 << "' with '"
<< comp.s2 << "'";
}
}
TEST(String, equalsWithStringView) {
for (size_t n = 0; n < ARRAY_SIZE(kComparisons); ++n) {
const Comparison& comp = kComparisons[n];
String s1(comp.s1);
StringView s2(comp.s2);
EXPECT_EQ(!comp.expected, s1.equals(s2))
<< "Comparing '" << comp.s1 << "' with '"
<< comp.s2 << "'";
}
}
TEST(String, EqualsOperatorWithCString) {
for (size_t n = 0; n < ARRAY_SIZE(kComparisons); ++n) {
const Comparison& comp = kComparisons[n];
String s(comp.s1);
EXPECT_EQ(!comp.expected, s == comp.s2)
<< "Comparing '" << comp.s1 << "' with '"
<< comp.s2 << "'";
}
}
TEST(String, EqualsOperatorWithString) {
for (size_t n = 0; n < ARRAY_SIZE(kComparisons); ++n) {
const Comparison& comp = kComparisons[n];
String s1(comp.s1);
String s2(comp.s2);
EXPECT_EQ(!comp.expected, s1 == s2)
<< "Comparing '" << comp.s1 << "' with '"
<< comp.s2 << "'";
}
}
TEST(String, EqualsOperatorWithStringView) {
for (size_t n = 0; n < ARRAY_SIZE(kComparisons); ++n) {
const Comparison& comp = kComparisons[n];
String s1(comp.s1);
StringView s2(comp.s2);
EXPECT_EQ(!comp.expected, s1 == s2)
<< "Comparing '" << comp.s1 << "' with '"
<< comp.s2 << "'";
}
}
TEST(String, Reserve0OnEmptyString) {
String s;
// This is really to check that this doesn't crash.
::memset(&s, 0, sizeof(s));
s.reserve(0U);
}
TEST(String, Swap) {
const String kShortString1("Hello World!");
const String kLongString1("A very long string that will likely "
"exceed the small string optimization storage buffer");
const String kShortString2("Menthe a l'eau");
const String kLongString2("Harold Ramis, Chicago actor, writer "
"and director, dead at 69");
// Swap two short strings.
{
String sa = kShortString1;
String sb = kShortString2;
sa.swap(&sb);
EXPECT_EQ(kShortString2, sa);
EXPECT_EQ(kShortString1, sb);
}
// Swap one short + one long string.
{
String sa = kShortString1;
String sb = kLongString1;
sa.swap(&sb);
EXPECT_EQ(kLongString1, sa);
EXPECT_EQ(kShortString1, sb);
}
// Swap one long + one short string.
{
String sa = kLongString1;
String sb = kLongString2;
sa.swap(&sb);
EXPECT_EQ(kLongString2, sa);
EXPECT_EQ(kLongString1, sb);
}
}
} // namespace base
} // namespace android