blob: 76799984bcc59858fc6c48c62880d6ccc546e8bc [file] [log] [blame]
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "android/base/misc/StringUtils.h"
#include <gtest/gtest.h>
#include <list>
#include <string>
#include <vector>
namespace android {
namespace base {
#ifdef _WIN32
TEST(StringUtils, memmem) {
auto src = "string";
// basic cases - when the substring is there
EXPECT_EQ(src + 2, memmem(src, strlen(src), "ring", 4));
EXPECT_EQ(src + 1, memmem(src, strlen(src), "tri", 3));
// no substring
EXPECT_EQ(nullptr, memmem(src, strlen(src), "123", 3));
EXPECT_EQ(nullptr, memmem(src, strlen(src), "strings", 7));
// make sure it's looking at lengths, and not at the null-terminator
EXPECT_EQ(src + 2, memmem(src, strlen(src), "ringer", 4));
EXPECT_EQ(nullptr, memmem(src, 2, "tr", 2));
// corner cases - empty/single char and the needle same as haystack
EXPECT_EQ(src, memmem(src, strlen(src), "", 0));
EXPECT_EQ(src, memmem(src, strlen(src), "s", 1));
EXPECT_EQ(src, memmem(src, 1, "s", 1));
EXPECT_EQ(nullptr, memmem("", 0, "s", 1));
EXPECT_EQ(nullptr, memmem("", 0, "", 0));
EXPECT_EQ(src, memmem(src, strlen(src), src, strlen(src)));
// null input parameters
EXPECT_EQ(nullptr, memmem(src, strlen(src), nullptr, 2));
EXPECT_EQ(nullptr, memmem(nullptr, 10, "asdf", 4));
EXPECT_EQ(nullptr, memmem(nullptr, 10, nullptr, 1));
}
#endif // _WIN32
TEST(StringUtils, strDupWithStringView) {
StringView view("Hello World");
char* s = strDup(view);
EXPECT_TRUE(s);
EXPECT_STREQ(view.c_str(), s);
EXPECT_NE(view.c_str(), s);
free(s);
}
TEST(StringUtils, strDupWithStdString) {
std::string str("Hello World");
char* s = strDup(str);
EXPECT_TRUE(s);
EXPECT_STREQ(str.c_str(), s);
EXPECT_NE(str.c_str(), s);
free(s);
}
TEST(StringUtils, strContainsWithStringView) {
StringView haystack("This is a long string to search for stuff");
EXPECT_FALSE(strContains(haystack, "needle"));
EXPECT_FALSE(strContains(haystack, "stuffy"));
EXPECT_TRUE(strContains(haystack, "stuf"));
EXPECT_TRUE(strContains(haystack, "stuff"));
EXPECT_FALSE(strContains(haystack, "This is a short phrase"));
EXPECT_TRUE(strContains(haystack, "a long string"));
}
TEST(StringUtils, strContainsWithStdString) {
std::string haystack("This is a long string to search for stuff");
EXPECT_FALSE(strContains(haystack, "needle"));
EXPECT_FALSE(strContains(haystack, "stuffy"));
EXPECT_TRUE(strContains(haystack, "stuff"));
EXPECT_FALSE(strContains(haystack, "This is a short phrase"));
EXPECT_TRUE(strContains(haystack, "a long string"));
}
TEST(StringUtils, join) {
using android::base::join;
EXPECT_STREQ("", join(std::vector<int>{}).c_str());
EXPECT_STREQ("aa", join(std::vector<std::string>{"aa"}).c_str());
EXPECT_STREQ("aa,bb", join(std::list<const char*>{"aa", "bb"}).c_str());
EXPECT_STREQ("1,2,3", join(std::vector<int>{1, 2, 3}).c_str());
EXPECT_STREQ("1|2|3", join(std::vector<int>{1, 2, 3}, '|').c_str());
EXPECT_STREQ("1<|>2<|>sd",
join(std::vector<const char*>{"1", "2", "sd"}, "<|>").c_str());
EXPECT_STREQ("...---...",
join(std::vector<const char*>{"...", "..."}, "---").c_str());
EXPECT_STREQ("...---...",
join(std::vector<const char*>{"...", "---", "..."}, "").c_str());
// check some special cases - lvalue modifiable and const references
using StringVec = std::vector<std::string>;
StringVec src = { "1", "a", "foo" };
EXPECT_STREQ("1,a,foo", join(src).c_str());
EXPECT_STREQ("1, a, foo", join(src, ", ").c_str());
EXPECT_STREQ("1,a,foo", join(const_cast<const StringVec&>(src)).c_str());
EXPECT_STREQ("1, a, foo",
join(const_cast<const StringVec&>(src), ", ").c_str());
}
TEST(StringUtils, trim) {
struct {
const char* before;
const char* after;
} test_data[] = {
{"no change", "no change"},
{"", ""},
{" left", "left"},
{"right ", "right"},
{"\nnewline\r", "newline"},
{" \r\n\tmulti \t\r\n", "multi"},
};
size_t TEST_DATA_COUNT = sizeof(test_data) / sizeof(test_data[0]);
for (size_t i = 0; i < TEST_DATA_COUNT; i++) {
std::string before(test_data[i].before);
std::string after = trim(before);
EXPECT_STREQ(test_data[i].after, after.c_str());
}
}
} // namespace base
} // namespace android