blob: 682c4abfa4945f65e2d057839e98eab37033e395 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include <lib/unittest/unittest.h>
#include <string.h>
#include <ktl/limits.h>
#include <ktl/string_view.h>
#include <ktl/enforce.h>
namespace {
bool CreateFromCArray() {
BEGIN_TEST;
constexpr char kStr[] = "1";
ktl::string_view v_str(kStr);
EXPECT_FALSE(v_str.empty());
EXPECT_EQ(kStr, v_str.data());
EXPECT_EQ(strlen(kStr), v_str.length());
END_TEST;
}
bool CreateFromConstChar() {
BEGIN_TEST;
const char* kStr = "1";
ktl::string_view v_str(kStr);
EXPECT_FALSE(v_str.empty());
EXPECT_EQ(kStr, v_str.data());
EXPECT_EQ(strlen(kStr), v_str.length());
END_TEST;
}
bool CreateFromStringView() {
BEGIN_TEST;
ktl::string_view str_view("12345");
ktl::string_view v_str(str_view);
EXPECT_FALSE(v_str.empty());
EXPECT_EQ(str_view.data(), v_str.data());
EXPECT_EQ(str_view.length(), v_str.length());
END_TEST;
}
bool CreateFromConstexprStringView() {
BEGIN_TEST;
constexpr ktl::string_view kLiteral = "12345";
ktl::string_view v_str(kLiteral);
EXPECT_EQ(kLiteral.data(), v_str.data());
EXPECT_EQ(kLiteral.length(), v_str.length());
END_TEST;
}
bool CreateFromConstexprStringViewConstructor() {
BEGIN_TEST;
constexpr ktl::string_view kLiteral("12345");
EXPECT_EQ(size_t{5}, kLiteral.size());
EXPECT_EQ(size_t{5}, kLiteral.length());
END_TEST;
}
bool CreateFromStringViewLiteral() {
BEGIN_TEST;
constexpr ktl::string_view kLiteral = "12345"sv;
EXPECT_EQ(size_t{5}, kLiteral.size());
EXPECT_EQ(size_t{5}, kLiteral.length());
END_TEST;
}
bool SizeIsSameAsLength() {
BEGIN_TEST;
constexpr ktl::string_view kLiteral = "12345";
EXPECT_EQ(size_t{5}, kLiteral.size());
EXPECT_EQ(size_t{5}, kLiteral.length());
END_TEST;
}
bool ArrayAccessOperator() {
BEGIN_TEST;
// Need static duration to enforce subobject constexpr, otherwise it is not allowed.
constexpr static char const kLiteral[] = "12345";
constexpr ktl::string_view kSvLiteral(kLiteral);
for (size_t i = 0; i < kSvLiteral.size(); ++i) {
EXPECT_EQ(kLiteral[i], kSvLiteral[i], "Array access returned wrong value.");
EXPECT_EQ(&kLiteral[i], &kSvLiteral[i], "Array access returned value at different address.");
}
END_TEST;
}
bool BeginPointsToFirstElement() {
BEGIN_TEST;
constexpr ktl::string_view kLiteral = "12345";
EXPECT_EQ(&kLiteral[0], &(*kLiteral.begin()));
EXPECT_EQ(&kLiteral[4], &(*kLiteral.rbegin()));
END_TEST;
}
bool EndPointsOnePastLastElement() {
BEGIN_TEST;
constexpr ktl::string_view kLiteral = "12345";
EXPECT_EQ(&kLiteral[4], &(*(kLiteral.end() - 1)));
EXPECT_EQ(&kLiteral[0], &(*(kLiteral.rend() - 1)));
END_TEST;
}
bool EndPointsPastLastElement() {
BEGIN_TEST;
constexpr ktl::string_view kLiteral = "12345";
EXPECT_EQ(kLiteral.begin() + 5, kLiteral.end());
EXPECT_TRUE(kLiteral.rbegin() + 5 == kLiteral.rend());
END_TEST;
}
bool WhenEmptyBeginIsSameAsEnd() {
BEGIN_TEST;
constexpr ktl::string_view kLiteral = "";
EXPECT_EQ(kLiteral.begin(), kLiteral.end());
EXPECT_TRUE(kLiteral.rbegin() == kLiteral.rend());
END_TEST;
}
bool FrontReturnsRefToFirstElement() {
BEGIN_TEST;
constexpr ktl::string_view kLiteral = "12345";
EXPECT_EQ(&(*kLiteral.begin()), &kLiteral.front());
END_TEST;
}
bool BackReturnsRefToLastElement() {
BEGIN_TEST;
constexpr ktl::string_view kLiteral = "12345";
EXPECT_EQ(&(*(kLiteral.begin() + 4)), &kLiteral.back());
END_TEST;
}
bool EmptyIsTrueForEmptyString() {
BEGIN_TEST;
constexpr ktl::string_view kStr;
ASSERT_TRUE(kStr.empty());
ASSERT_EQ(size_t{0}, kStr.size());
ASSERT_EQ(size_t{0}, kStr.length());
END_TEST;
}
bool AtReturnsElementAtIndex() {
BEGIN_TEST;
// Need static duration to enforce subobject constexpr, otherwise it is not allowed.
constexpr static char const kLiteral[] = "12345";
constexpr ktl::string_view kSvLiteral(kLiteral);
for (size_t i = 0; i < kSvLiteral.size(); ++i) {
EXPECT_EQ(kLiteral[i], kSvLiteral.at(i), "Array access returned wrong value.");
EXPECT_EQ(&kLiteral[i], &kSvLiteral.at(i), "Array access returned value at different address.");
}
END_TEST;
}
#if DEATH_TESTS
bool AtThrowsExceptionWhenIndexIsOOR() {
BEGIN_TEST;
ASSERT_DEATH([] {
constexpr ktl::string_view kSvLiteral("12345");
kSvLiteral.at(5);
});
END_TEST;
}
#endif
// Even though we use a custom compare implementation, because we lack a constexpr compare
// function, we use this test to verify that the expectations are equivalent.
bool CompareVerification() {
BEGIN_TEST;
constexpr ktl::string_view kStr1 = "1234";
// Same string
{
constexpr ktl::string_view kStr2 = "1234";
constexpr ktl::string_view kStr3 = "01234";
EXPECT_EQ(0, ktl::string_view::traits_type::compare(kStr1.data(), kStr2.data(), 4));
EXPECT_EQ(0, kStr1.compare(kStr2));
EXPECT_EQ(0, kStr3.compare(1, kStr3.length() - 1, kStr2));
EXPECT_EQ(0, kStr1.compare(1, kStr1.length() - 2, kStr2, 1, kStr2.length() - 2));
EXPECT_EQ(0, kStr1.compare("1234"));
EXPECT_EQ(0, kStr1.compare(1, kStr1.length() - 1, "234"));
EXPECT_EQ(0, kStr1.compare(2, kStr1.length() - 2, "234", 1, 2));
}
// Same Length higher character
{
constexpr ktl::string_view kStr2 = "1235";
EXPECT_LT(ktl::string_view::traits_type::compare(kStr1.data(), kStr2.data(), 4), 0);
EXPECT_LT(kStr1.compare(kStr2), 0);
EXPECT_LT(kStr1.compare(0, kStr1.length(), kStr2), 0);
EXPECT_LT(kStr1.compare(1, kStr1.length() - 2, kStr2, 1, kStr2.length() - 1), 0);
EXPECT_LT(kStr1.compare("1235"), 0);
EXPECT_LT(kStr1.compare(1, kStr1.length() - 1, "235"), 0);
EXPECT_LT(kStr1.compare(1, kStr1.length() - 2, "1235", 1, 3), 0);
}
// Same Length lower character
{
constexpr ktl::string_view kStr2 = "1232";
EXPECT_GT(ktl::string_view::traits_type::compare(kStr1.data(), kStr2.data(), 4), 0);
EXPECT_GT(kStr1.compare(kStr2), 0);
EXPECT_GT(kStr2.compare(1, kStr2.length() - 1, kStr1), 0);
EXPECT_GT(kStr1.compare(1, kStr1.length() - 1, kStr2, 1, kStr2.length() - 1), 0);
EXPECT_GT(kStr1.compare("1232"), 0);
EXPECT_GT(kStr1.compare(1, kStr1.length() - 1, "232"), 0);
EXPECT_GT(kStr1.compare(1, kStr1.length() - 2, "22", 1, kStr2.length() - 2), 0);
}
// Greater Length
{
constexpr ktl::string_view kStr2 = "12345";
constexpr ktl::string_view kStr3 = "2345";
EXPECT_LT(kStr1.compare(kStr2), 0);
EXPECT_LT(kStr1.compare(1, kStr1.length() - 1, kStr3), 0);
EXPECT_LT(kStr1.compare(1, kStr1.length() - 1, kStr2, 1, kStr2.length() - 1), 0);
EXPECT_LT(kStr1.compare(kStr2.data()), 0);
EXPECT_LT(kStr1.compare(1, kStr1.length() - 1, kStr3.data()), 0);
EXPECT_LT(kStr1.compare(1, kStr1.length() - 1, kStr2.data(), 1, kStr2.length() - 1), 0);
}
// Shorter Length
{
constexpr ktl::string_view kStr2 = "123";
constexpr ktl::string_view kStr3 = "23";
EXPECT_GT(kStr1.compare(kStr2), 0);
EXPECT_GT(kStr1.compare(1, kStr1.length() - 1, kStr3), 0);
EXPECT_GT(kStr1.compare(1, kStr1.length() - 1, kStr2, 1, kStr2.length() - 1), 0);
EXPECT_GT(kStr1.compare(kStr2.data()), 0);
EXPECT_GT(kStr1.compare(1, kStr1.length() - 1, kStr3.data()), 0);
EXPECT_GT(kStr1.compare(1, kStr1.length() - 1, kStr2.data(), 1, kStr2.length() - 1), 0);
}
END_TEST;
}
// Check that they calls are equivalent to what the standard expects.
bool CompareOverloadCheck() {
BEGIN_TEST;
constexpr ktl::string_view kString1 = "123";
constexpr ktl::string_view kString2 = "1234";
{
ktl::string_view expected = kString1.substr(1, 2);
EXPECT_EQ(kString1.substr(1, 2).compare(expected), kString1.compare(1, 2, expected));
}
{
EXPECT_EQ(kString1.substr(1, 2).compare(kString2.substr(1, 2)),
kString1.compare(1, 2, kString2, 1, 2));
}
{ EXPECT_EQ(kString1.compare(ktl::string_view("123")), kString1.compare("123")); }
{
EXPECT_EQ(kString1.substr(1, 2).compare(ktl::string_view("123")),
kString1.compare(1, 2, "123"));
}
{
EXPECT_EQ(kString1.substr(1, 2).compare(ktl::string_view("123")),
kString1.compare(1, 2, "123"));
}
END_TEST;
}
bool OperatorEq() {
BEGIN_TEST;
constexpr ktl::string_view kStrView = "Self1234";
EXPECT_TRUE(kStrView == kStrView);
EXPECT_TRUE(kStrView == ktl::string_view("Self1234"));
EXPECT_TRUE(kStrView == ktl::string_view("Self12345").substr(0, kStrView.length()));
EXPECT_TRUE(kStrView == "Self1234");
EXPECT_TRUE("Self1234" == kStrView);
END_TEST;
}
bool OperatorNe() {
BEGIN_TEST;
constexpr ktl::string_view kStrView = "Self1234";
EXPECT_TRUE(kStrView != ktl::string_view());
EXPECT_TRUE(kStrView != ktl::string_view("Self12345"));
EXPECT_TRUE(kStrView != "Self12345");
EXPECT_TRUE("Self12345" != kStrView);
END_TEST;
}
bool OperatorLess() {
BEGIN_TEST;
constexpr ktl::string_view kStrView = "Self1234";
EXPECT_TRUE(kStrView < "Self12345");
EXPECT_TRUE("Self123" < kStrView);
EXPECT_TRUE(kStrView < ktl::string_view("Self12345"));
END_TEST;
}
bool OperatorLessOrEq() {
BEGIN_TEST;
constexpr ktl::string_view kStrView = "Self1234";
EXPECT_TRUE(kStrView <= "Self12345");
EXPECT_TRUE("Self123" <= kStrView);
EXPECT_TRUE(kStrView <= ktl::string_view("Self12345"));
EXPECT_TRUE(kStrView <= ktl::string_view("Self1234"));
END_TEST;
}
bool OperatorGreater() {
BEGIN_TEST;
constexpr ktl::string_view kStrView = "Self1234";
EXPECT_TRUE(kStrView > "Self123");
EXPECT_TRUE("Self12345" > kStrView);
EXPECT_TRUE(kStrView > ktl::string_view("Self123"));
END_TEST;
}
bool OperatorGreaterOrEq() {
BEGIN_TEST;
constexpr ktl::string_view kStrView = "Self1234";
EXPECT_TRUE(kStrView >= "Self123");
EXPECT_TRUE("Self12345" >= kStrView);
EXPECT_TRUE(kStrView >= ktl::string_view("Self123"));
EXPECT_TRUE(kStrView >= ktl::string_view("Self1234"));
END_TEST;
}
bool RemovePrefix() {
BEGIN_TEST;
constexpr ktl::string_view kPrefixWithSuffix = "PrefixSuffix";
ktl::string_view str_view = kPrefixWithSuffix;
str_view.remove_prefix(6);
EXPECT_EQ(kPrefixWithSuffix.length() - 6, str_view.length());
auto no_suffix = kPrefixWithSuffix.substr(6, kPrefixWithSuffix.length() - 6);
EXPECT_TRUE(no_suffix == str_view);
EXPECT_TRUE("Suffix" == str_view);
END_TEST;
}
bool RemoveSuffix() {
BEGIN_TEST;
constexpr ktl::string_view kPrefixWithSuffix = "PrefixSuffix";
ktl::string_view str_view = kPrefixWithSuffix;
str_view.remove_suffix(6);
EXPECT_EQ(kPrefixWithSuffix.length() - 6, str_view.length());
auto no_suffix = kPrefixWithSuffix.substr(0, kPrefixWithSuffix.length() - 6);
EXPECT_TRUE(no_suffix == str_view);
EXPECT_TRUE("Prefix" == str_view);
END_TEST;
}
bool SubstrNoArgsAreEqual() {
BEGIN_TEST;
constexpr ktl::string_view kLiteral = "12345";
EXPECT_TRUE(kLiteral == kLiteral.substr());
END_TEST;
}
bool SubstrWithPosIsMatchesSubstring() {
BEGIN_TEST;
constexpr ktl::string_view kLiteral = "12345";
constexpr ktl::string_view kExpectedLiteral = "345";
EXPECT_TRUE(kExpectedLiteral == kLiteral.substr(2));
END_TEST;
}
bool SubstrWithPosAndCountIsMatchesSubstring() {
BEGIN_TEST;
constexpr ktl::string_view kLiteral = "12345";
constexpr ktl::string_view kExpectedLiteral = "34";
EXPECT_TRUE(kExpectedLiteral == kLiteral.substr(2, 2));
END_TEST;
}
bool Swap() {
BEGIN_TEST;
ktl::string_view str_1 = "12345";
ktl::string_view str_2 = "34";
str_1.swap(str_2);
EXPECT_TRUE("34" == str_1);
EXPECT_TRUE("12345" == str_2);
END_TEST;
}
bool Copy() {
BEGIN_TEST;
constexpr ktl::string_view kBase = "Base";
constexpr ktl::string_view::size_type kSize = 2;
ktl::string_view::value_type dest[kSize + 1] = {'\0'};
ktl::string_view::value_type dest_traits[kSize + 1] = {'\0'};
EXPECT_EQ(kSize, kBase.copy(dest, kSize, 0));
EXPECT_EQ(dest_traits, ktl::string_view::traits_type::copy(dest_traits, kBase.data(), kSize));
EXPECT_EQ(0, strcmp(dest_traits, dest));
END_TEST;
}
#if DEATH_TESTS
bool CopyThrowsExceptionOnOOR() {
BEGIN_TEST;
ASSERT_DEATH([]() {
constexpr ktl::string_view v_str = "Base";
ktl::string_view::value_type dest[v_str.length() + 2] = {};
memset(dest, '\0', v_str.length() + 1);
v_str.copy(dest, v_str.length(), v_str.length());
});
END_TEST;
}
#endif
bool MaxSizeIsMaxAddressableSize() {
BEGIN_TEST;
ktl::string_view str_view("12345");
EXPECT_EQ(ktl::numeric_limits<ktl::string_view::size_type>::max(), str_view.max_size());
END_TEST;
}
bool FindReturnsFirstCharTypeMatch() {
BEGIN_TEST;
constexpr ktl::string_view kString = "12345678901234567890";
EXPECT_EQ(size_t{0}, kString.find('1'));
EXPECT_EQ(size_t{1}, kString.find('2'));
EXPECT_EQ(size_t{2}, kString.find('3'));
EXPECT_EQ(size_t{3}, kString.find('4'));
EXPECT_EQ(size_t{4}, kString.find('5'));
EXPECT_EQ(size_t{5}, kString.find('6'));
EXPECT_EQ(size_t{6}, kString.find('7'));
EXPECT_EQ(size_t{7}, kString.find('8'));
EXPECT_EQ(size_t{8}, kString.find('9'));
EXPECT_EQ(size_t{9}, kString.find('0'));
END_TEST;
}
bool FindWithPosReturnsFirstCharTypeMatch() {
BEGIN_TEST;
constexpr ktl::string_view kString = "12345678901234567890";
EXPECT_EQ(size_t{10}, kString.find('1', 10));
EXPECT_EQ(size_t{11}, kString.find('2', 10));
EXPECT_EQ(size_t{12}, kString.find('3', 10));
EXPECT_EQ(size_t{13}, kString.find('4', 10));
EXPECT_EQ(size_t{14}, kString.find('5', 10));
EXPECT_EQ(size_t{15}, kString.find('6', 10));
EXPECT_EQ(size_t{16}, kString.find('7', 10));
EXPECT_EQ(size_t{17}, kString.find('8', 10));
EXPECT_EQ(size_t{18}, kString.find('9', 10));
EXPECT_EQ(size_t{19}, kString.find('0', 10));
END_TEST;
}
bool FindReturnsNposWhenNoCharTypeMatch() {
BEGIN_TEST;
constexpr ktl::string_view kString = "123456789123456789";
EXPECT_EQ(ktl::string_view::npos, kString.find('0'));
END_TEST;
}
bool FindReturnsFirstMatch() {
BEGIN_TEST;
constexpr ktl::string_view kString = "12345678901234567890";
EXPECT_EQ(size_t{0}, kString.find(""));
EXPECT_EQ(size_t{0}, kString.find("12"));
EXPECT_EQ(size_t{1}, kString.find("23"));
EXPECT_EQ(size_t{2}, kString.find("34"));
EXPECT_EQ(size_t{3}, kString.find("45"));
EXPECT_EQ(size_t{4}, kString.find("56"));
EXPECT_EQ(size_t{5}, kString.find("67"));
EXPECT_EQ(size_t{6}, kString.find("78"));
EXPECT_EQ(size_t{7}, kString.find("89"));
EXPECT_EQ(size_t{8}, kString.find("90"));
EXPECT_EQ(size_t{9}, kString.find("01"));
EXPECT_EQ(size_t{9}, kString.find("01234"));
END_TEST;
}
bool FindWithPosReturnsFirstMatch() {
BEGIN_TEST;
constexpr ktl::string_view kString = "12345678901234567890";
EXPECT_EQ(size_t{10}, kString.find("", 10));
EXPECT_EQ(size_t{10}, kString.find("1", 10));
EXPECT_EQ(size_t{11}, kString.find("2", 10));
EXPECT_EQ(size_t{12}, kString.find("3", 10));
EXPECT_EQ(size_t{13}, kString.find("4", 10));
EXPECT_EQ(size_t{14}, kString.find("5", 10));
EXPECT_EQ(size_t{15}, kString.find("6", 10));
EXPECT_EQ(size_t{16}, kString.find("7", 10));
EXPECT_EQ(size_t{17}, kString.find("8", 10));
EXPECT_EQ(size_t{18}, kString.find("9", 10));
EXPECT_EQ(size_t{19}, kString.find("0", 10));
// String of size > 1.
EXPECT_EQ(size_t{13}, kString.find("456", 10));
END_TEST;
}
bool FindReturnsNposWhenNoMatch() {
BEGIN_TEST;
constexpr ktl::string_view kString = "12345678901234567890";
// String of size > 1.
EXPECT_EQ(ktl::string_view::npos, kString.find("A"));
EXPECT_EQ(ktl::string_view::npos, kString.find("02"));
EXPECT_EQ(ktl::string_view::npos, kString.find("42321"));
END_TEST;
}
bool FindReturnsNposWhenNeedleIsBiggerThanHaystack() {
BEGIN_TEST;
constexpr ktl::string_view kString = "123";
// String of size > 1.
EXPECT_EQ(ktl::string_view::npos, kString.find("1234"));
END_TEST;
}
bool RrfindReturnsFirstCharTypeMatch() {
BEGIN_TEST;
constexpr ktl::string_view kString = "12345678901234567890";
EXPECT_EQ(size_t{10}, kString.rfind('1'));
EXPECT_EQ(size_t{11}, kString.rfind('2'));
EXPECT_EQ(size_t{12}, kString.rfind('3'));
EXPECT_EQ(size_t{13}, kString.rfind('4'));
EXPECT_EQ(size_t{14}, kString.rfind('5'));
EXPECT_EQ(size_t{15}, kString.rfind('6'));
EXPECT_EQ(size_t{16}, kString.rfind('7'));
EXPECT_EQ(size_t{17}, kString.rfind('8'));
EXPECT_EQ(size_t{18}, kString.rfind('9'));
EXPECT_EQ(size_t{19}, kString.rfind('0'));
END_TEST;
}
bool RrfindWithPosReturnsFirstCharTypeMatch() {
BEGIN_TEST;
constexpr ktl::string_view kString = "12345678901234567890";
EXPECT_EQ(size_t{10}, kString.rfind('1', 10));
EXPECT_EQ(size_t{11}, kString.rfind('2', 11));
EXPECT_EQ(size_t{12}, kString.rfind('3', 12));
EXPECT_EQ(size_t{13}, kString.rfind('4', 13));
EXPECT_EQ(size_t{14}, kString.rfind('5', 14));
EXPECT_EQ(size_t{15}, kString.rfind('6', 15));
EXPECT_EQ(size_t{16}, kString.rfind('7', 16));
EXPECT_EQ(size_t{17}, kString.rfind('8', 17));
EXPECT_EQ(size_t{18}, kString.rfind('9', 18));
EXPECT_EQ(size_t{19}, kString.rfind('0', 19));
END_TEST;
}
bool RrfindReturnsNposWhenNoCharTypeMatch() {
BEGIN_TEST;
constexpr ktl::string_view kString = "123456789123456789";
EXPECT_EQ(ktl::string_view::npos, kString.rfind('0'));
END_TEST;
}
bool RrfindReturnsFirstMatch() {
BEGIN_TEST;
constexpr ktl::string_view kString = "12345678901234567890";
EXPECT_EQ(size_t{10}, kString.rfind("12"));
EXPECT_EQ(size_t{11}, kString.rfind("23"));
EXPECT_EQ(size_t{12}, kString.rfind("34"));
EXPECT_EQ(size_t{13}, kString.rfind("45"));
EXPECT_EQ(size_t{14}, kString.rfind("56"));
EXPECT_EQ(size_t{15}, kString.rfind("67"));
EXPECT_EQ(size_t{16}, kString.rfind("78"));
EXPECT_EQ(size_t{17}, kString.rfind("89"));
EXPECT_EQ(size_t{18}, kString.rfind("90"));
EXPECT_EQ(size_t{9}, kString.rfind("01"));
EXPECT_EQ(size_t{9}, kString.rfind("01234"));
END_TEST;
}
bool RrfindWithPosReturnsFirstMatch() {
BEGIN_TEST;
constexpr ktl::string_view kString = "12345678901234567890";
EXPECT_EQ(size_t{10}, kString.rfind("1", 10));
EXPECT_EQ(size_t{11}, kString.rfind("2", 11));
EXPECT_EQ(size_t{12}, kString.rfind("3", 12));
EXPECT_EQ(size_t{13}, kString.rfind("4", 13));
EXPECT_EQ(size_t{14}, kString.rfind("5", 14));
EXPECT_EQ(size_t{15}, kString.rfind("6", 15));
EXPECT_EQ(size_t{16}, kString.rfind("7", 16));
EXPECT_EQ(size_t{17}, kString.rfind("8", 17));
EXPECT_EQ(size_t{18}, kString.rfind("9", 18));
EXPECT_EQ(size_t{19}, kString.rfind("0", 19));
// String of size > 1.
EXPECT_EQ(size_t{13}, kString.rfind("456", 13));
END_TEST;
}
bool RrfindReturnsNposWhenNoMatch() {
BEGIN_TEST;
constexpr ktl::string_view kString = "12345678901234567890";
EXPECT_EQ(ktl::string_view::npos, kString.rfind("A"));
EXPECT_EQ(ktl::string_view::npos, kString.rfind("02"));
EXPECT_EQ(ktl::string_view::npos, kString.rfind("42321"));
EXPECT_EQ(ktl::string_view::npos, kString.rfind('A'));
END_TEST;
}
bool RfindReturnsNposWhenNeedleIsBiggerThanHaystack() {
BEGIN_TEST;
constexpr ktl::string_view kString = "123";
// String of size > 1.
EXPECT_EQ(ktl::string_view::npos, kString.rfind("1234"));
EXPECT_EQ(ktl::string_view::npos, ktl::string_view().find('1'));
END_TEST;
}
bool FindFirstOfReturnsFirstMatch() {
BEGIN_TEST;
constexpr ktl::string_view kString = "ABCDE1234ABCDE1234";
constexpr ktl::string_view kMatchers = "123";
// Verify that order of chartacters in |s| does not change first match.
EXPECT_EQ(size_t{5}, kString.find_first_of("321"));
EXPECT_EQ(size_t{5}, kString.find_first_of("123"));
EXPECT_EQ(size_t{5}, kString.find_first_of("231"));
EXPECT_EQ(size_t{5}, kString.find_first_of("213"));
EXPECT_EQ(size_t{5}, kString.find_first_of(kMatchers));
EXPECT_EQ(size_t{6}, kString.find_first_of('2'));
END_TEST;
}
bool FindFirstOfWithPosReturnsFirstMatch() {
BEGIN_TEST;
constexpr ktl::string_view kString = "ABCDE1234ABCDE1234";
constexpr ktl::string_view kMatchers = "123";
// Verify that order of chartacters in |s| does not change first match.
EXPECT_EQ(size_t{14}, kString.find_first_of("321", 9));
EXPECT_EQ(size_t{14}, kString.find_first_of("123", 9));
EXPECT_EQ(size_t{14}, kString.find_first_of("231", 9));
EXPECT_EQ(size_t{14}, kString.find_first_of("213", 9));
EXPECT_EQ(size_t{14}, kString.find_first_of(kMatchers, 9));
EXPECT_EQ(size_t{5}, kString.find_first_of('1'));
END_TEST;
}
bool FindFirstOfWithPosAndCountReturnsFirstMatch() {
BEGIN_TEST;
constexpr ktl::string_view kString = "ABCDE1234ABCDE1234";
// Verify that order of chartacters in |s| does not change first match.
EXPECT_EQ(size_t{14}, kString.find_first_of("123", 9, 1));
EXPECT_EQ(size_t{15}, kString.find_first_of("231", 9, 1));
EXPECT_EQ(size_t{15}, kString.find_first_of("213", 9, 1));
EXPECT_EQ(size_t{16}, kString.find_first_of("321", 9, 1));
END_TEST;
}
bool FindFirstOfReturnsNposWhenNoMatch() {
BEGIN_TEST;
constexpr ktl::string_view kString = "ABCDE1234ABCDE1234";
// Verify that order of chartacters in |s| does not change first match.
EXPECT_EQ(ktl::string_view::npos, kString.find_first_of("GHIJK"));
EXPECT_EQ(ktl::string_view::npos, kString.find_first_of("G"));
EXPECT_EQ(ktl::string_view::npos, kString.find_first_of('G'));
END_TEST;
}
bool FindLastOfReturnsLastMatch() {
BEGIN_TEST;
constexpr ktl::string_view kString = "ABCDE1234ABCDE1234";
constexpr ktl::string_view kMatchers = "123";
// Verify that order of chartacters in |s| does not change last match.
EXPECT_EQ(size_t{16}, kString.find_last_of("321"));
EXPECT_EQ(size_t{16}, kString.find_last_of("123"));
EXPECT_EQ(size_t{16}, kString.find_last_of("231"));
EXPECT_EQ(size_t{16}, kString.find_last_of("213"));
EXPECT_EQ(size_t{16}, kString.find_last_of(kMatchers));
EXPECT_EQ(size_t{15}, kString.find_last_of('2'));
END_TEST;
}
bool FindLastOfWithPosReturnsLastMatch() {
BEGIN_TEST;
constexpr ktl::string_view kString = "ABCDE1234ABCDE1234";
constexpr ktl::string_view kMatchers = "123";
// Verify that order of chartacters in |s| does not change last match.
EXPECT_EQ(size_t{7}, kString.find_last_of("321", 9));
EXPECT_EQ(size_t{7}, kString.find_last_of("123", 9));
EXPECT_EQ(size_t{7}, kString.find_last_of("231", 9));
EXPECT_EQ(size_t{7}, kString.find_last_of("213", 9));
EXPECT_EQ(size_t{7}, kString.find_last_of(kMatchers, 9));
EXPECT_EQ(size_t{5}, kString.find_last_of('1', 9));
END_TEST;
}
bool FindLastOfWithPosAndCountReturnsLastMatch() {
BEGIN_TEST;
constexpr ktl::string_view kString = "ABCDE1234ABCDE1234";
// Verify that order of chartacters in |s| does not change last match.
EXPECT_EQ(size_t{5}, kString.find_last_of("123", 9, 1));
EXPECT_EQ(size_t{6}, kString.find_last_of("231", 9, 1));
EXPECT_EQ(size_t{6}, kString.find_last_of("213", 9, 1));
EXPECT_EQ(size_t{7}, kString.find_last_of("321", 9, 1));
END_TEST;
}
bool FindLastOfReturnsNposWhenNoMatch() {
BEGIN_TEST;
constexpr ktl::string_view kString = "ABCDE1234ABCDE1234";
// Verify that order of chartacters in |s| does not change last match.
EXPECT_EQ(ktl::string_view::npos, kString.find_last_of("GHIJK"));
EXPECT_EQ(ktl::string_view::npos, kString.find_last_of("G"));
EXPECT_EQ(ktl::string_view::npos, kString.find_last_of('G'));
END_TEST;
}
bool FindFirstNofOfReturnsFirstNonMatch() {
BEGIN_TEST;
constexpr ktl::string_view kString = "123ABC123";
constexpr ktl::string_view kMatchers = "123";
// Verify that order of chartacters in |s| does not change first match.
EXPECT_EQ(size_t{0}, kString.find_first_not_of(""));
EXPECT_EQ(size_t{3}, kString.find_first_not_of("321"));
EXPECT_EQ(size_t{3}, kString.find_first_not_of("123"));
EXPECT_EQ(size_t{3}, kString.find_first_not_of("231"));
EXPECT_EQ(size_t{3}, kString.find_first_not_of("213"));
EXPECT_EQ(size_t{3}, kString.find_first_not_of(kMatchers));
EXPECT_EQ(size_t{1}, kString.find_first_not_of('1'));
END_TEST;
}
bool FindFirstNofOfWithPosReturnsFirstNonMatch() {
BEGIN_TEST;
constexpr ktl::string_view kString = "123ABC123A";
constexpr ktl::string_view kMatchers = "123";
// Verify that order of chartacters in |s| does not change first match.
EXPECT_EQ(size_t{6}, kString.find_first_not_of("", 6));
EXPECT_EQ(size_t{9}, kString.find_first_not_of("321", 6));
EXPECT_EQ(size_t{9}, kString.find_first_not_of("123", 6));
EXPECT_EQ(size_t{9}, kString.find_first_not_of("231", 6));
EXPECT_EQ(size_t{9}, kString.find_first_not_of("213", 6));
EXPECT_EQ(size_t{9}, kString.find_first_not_of(kMatchers, 9));
EXPECT_EQ(size_t{7}, kString.find_first_not_of('1', 6));
END_TEST;
}
bool FindFirstNofOfWithPosAndCountReturnsFirstNofMatch() {
BEGIN_TEST;
constexpr ktl::string_view kString = "123ABC123A";
// Verify that order of chartacters in |s| does not change first match.
EXPECT_EQ(size_t{7}, kString.find_first_not_of("123", 6, 1));
EXPECT_EQ(size_t{6}, kString.find_first_not_of("231", 6, 1));
EXPECT_EQ(size_t{6}, kString.find_first_not_of("213", 6, 1));
EXPECT_EQ(size_t{6}, kString.find_first_not_of("321", 6, 1));
END_TEST;
}
bool FindFirstNofOfReturnsNposWhenNoMatch() {
BEGIN_TEST;
constexpr ktl::string_view kString = "GGGGGGGGGGGGG";
// Verify that order of chartacters in |s| does not change first match.
EXPECT_EQ(ktl::string_view::npos, kString.find_first_not_of("ABCG"));
EXPECT_EQ(ktl::string_view::npos, kString.find_first_not_of("G"));
EXPECT_EQ(ktl::string_view::npos, kString.find_first_not_of('G'));
END_TEST;
}
bool FindLastNotOfReturnsLastMatch() {
BEGIN_TEST;
constexpr ktl::string_view kString = "ABCDE1234ABCDE1234";
constexpr ktl::string_view kMatchers = "1234";
// Verify that order of chartacters in |s| does not change last_not match.
EXPECT_EQ(size_t{13}, kString.find_last_not_of("3214"));
EXPECT_EQ(size_t{13}, kString.find_last_not_of("1234"));
EXPECT_EQ(size_t{13}, kString.find_last_not_of("2314"));
EXPECT_EQ(size_t{13}, kString.find_last_not_of("2134"));
EXPECT_EQ(size_t{13}, kString.find_last_not_of(kMatchers));
EXPECT_EQ(size_t{16}, kString.find_last_not_of('4'));
END_TEST;
}
bool FindLastNotOfWithPosReturnsLastMatch() {
BEGIN_TEST;
constexpr ktl::string_view kString = "ABCDE1234ABCDE1234";
constexpr ktl::string_view kMatchers = "1234";
// Verify that order of chartacters in |s| does not change last_not match.
EXPECT_EQ(size_t{4}, kString.find_last_not_of("3214", 8));
EXPECT_EQ(size_t{4}, kString.find_last_not_of("1234", 8));
EXPECT_EQ(size_t{4}, kString.find_last_not_of("2314", 8));
EXPECT_EQ(size_t{4}, kString.find_last_not_of("2134", 8));
EXPECT_EQ(size_t{4}, kString.find_last_not_of(kMatchers, 8));
EXPECT_EQ(size_t{7}, kString.find_last_not_of('4', 8));
END_TEST;
}
bool FindLastNotOfWithPosAndCountReturnsLastMatch() {
BEGIN_TEST;
constexpr ktl::string_view kString = "ABCDE1234ABCDE1234";
// Verify that order of chartacters in |s| does not change last_not match.
EXPECT_EQ(size_t{8}, kString.find_last_not_of("1234", 8, 1));
EXPECT_EQ(size_t{8}, kString.find_last_not_of("2314", 8, 2));
EXPECT_EQ(size_t{5}, kString.find_last_not_of("4321", 8, 3));
EXPECT_EQ(size_t{4}, kString.find_last_not_of("3214", 8, 4));
END_TEST;
}
bool FindLastNotOfReturnsNposWhenNoMatch() {
BEGIN_TEST;
constexpr ktl::string_view kString = "GGGGGGG";
// Verify that order of chartacters in |s| does not change last_not match.
EXPECT_EQ(ktl::string_view::npos, kString.find_last_not_of("GHIJK"));
EXPECT_EQ(ktl::string_view::npos, kString.find_last_not_of("G"));
EXPECT_EQ(ktl::string_view::npos, kString.find_last_not_of('G'));
END_TEST;
}
bool StartsWith() {
BEGIN_TEST;
constexpr ktl::string_view kString = "foobar";
// string_view argument.
EXPECT_TRUE(ktl::starts_with(kString, "foo"sv));
EXPECT_FALSE(ktl::starts_with(kString, "bar"sv));
// char argument.
EXPECT_TRUE(ktl::starts_with(kString, 'f'));
EXPECT_FALSE(ktl::starts_with(kString, 'b'));
// C string (const char*) argument.
EXPECT_TRUE(ktl::starts_with(kString, "foo"));
EXPECT_FALSE(ktl::starts_with(kString, "bar"));
END_TEST;
}
bool EndsWith() {
BEGIN_TEST;
constexpr ktl::string_view kString = "foobar";
// string_view argument.
EXPECT_TRUE(ktl::ends_with(kString, "bar"sv));
EXPECT_FALSE(ktl::ends_with(kString, "foo"sv));
// char argument.
EXPECT_TRUE(ktl::ends_with(kString, 'r'));
EXPECT_FALSE(ktl::ends_with(kString, 'f'));
// C string (const char*) argument.
EXPECT_TRUE(ktl::ends_with(kString, "bar"));
EXPECT_FALSE(ktl::ends_with(kString, "foo"));
END_TEST;
}
} // namespace
UNITTEST_START_TESTCASE(string_view_tests)
UNITTEST("CreateFromCArray", CreateFromCArray)
UNITTEST("CreateFromConstChar", CreateFromConstChar)
UNITTEST("CreateFromStringView", CreateFromStringView)
UNITTEST("CreateFromConstexprStringView", CreateFromConstexprStringView)
UNITTEST("CreateFromConstexprStringViewConstructor", CreateFromConstexprStringViewConstructor)
UNITTEST("CreateFromStringViewLiteral", CreateFromStringViewLiteral)
UNITTEST("SizeIsSameAsLength", SizeIsSameAsLength)
UNITTEST("ArrayAccessOperator", ArrayAccessOperator)
UNITTEST("BeginPointsToFirstElement", BeginPointsToFirstElement)
UNITTEST("EndPointsOnePastLastElement", EndPointsOnePastLastElement)
UNITTEST("EndPointsPastLastElement", EndPointsPastLastElement)
UNITTEST("WhenEmptyBeginIsSameAsEnd", WhenEmptyBeginIsSameAsEnd)
UNITTEST("FrontReturnsRefToFirstElement", FrontReturnsRefToFirstElement)
UNITTEST("BackReturnsRefToLastElement", BackReturnsRefToLastElement)
UNITTEST("EmptyIsTrueForEmptyString", EmptyIsTrueForEmptyString)
UNITTEST("AtReturnsElementAtIndex", AtReturnsElementAtIndex)
UNITTEST("CompareVerification", CompareVerification)
UNITTEST("CompareOverloadCheck", CompareOverloadCheck)
UNITTEST("OperatorEq", OperatorEq)
UNITTEST("OperatorNe", OperatorNe)
UNITTEST("OperatorLess", OperatorLess)
UNITTEST("OperatorLessOrEq", OperatorLessOrEq)
UNITTEST("OperatorGreater", OperatorGreater)
UNITTEST("OperatorGreaterOrEq", OperatorGreaterOrEq)
UNITTEST("RemovePrefix", RemovePrefix)
UNITTEST("RemoveSuffix", RemoveSuffix)
UNITTEST("SubstrNoArgsAreEqual", SubstrNoArgsAreEqual)
UNITTEST("SubstrWithPosIsMatchesSubstring", SubstrWithPosIsMatchesSubstring)
UNITTEST("SubstrWithPosAndCountIsMatchesSubstring", SubstrWithPosAndCountIsMatchesSubstring)
UNITTEST("Swap", Swap)
UNITTEST("Copy", Copy)
UNITTEST("MaxSizeIsMaxAddressableSize", MaxSizeIsMaxAddressableSize)
UNITTEST("FindReturnsFirstCharTypeMatch", FindReturnsFirstCharTypeMatch)
UNITTEST("FindWithPosReturnsFirstCharTypeMatch", FindWithPosReturnsFirstCharTypeMatch)
UNITTEST("FindReturnsNposWhenNoCharTypeMatch", FindReturnsNposWhenNoCharTypeMatch)
UNITTEST("FindReturnsFirstMatch", FindReturnsFirstMatch)
UNITTEST("FindWithPosReturnsFirstMatch", FindWithPosReturnsFirstMatch)
UNITTEST("FindReturnsNposWhenNoMatch", FindReturnsNposWhenNoMatch)
UNITTEST("FindReturnsNposWhenNeedleIsBiggerThanHaystack",
FindReturnsNposWhenNeedleIsBiggerThanHaystack)
UNITTEST("RrfindReturnsFirstCharTypeMatch", RrfindReturnsFirstCharTypeMatch)
UNITTEST("RrfindWithPosReturnsFirstCharTypeMatch", RrfindWithPosReturnsFirstCharTypeMatch)
UNITTEST("RrfindReturnsNposWhenNoCharTypeMatch", RrfindReturnsNposWhenNoCharTypeMatch)
UNITTEST("RrfindReturnsFirstMatch", RrfindReturnsFirstMatch)
UNITTEST("RrfindWithPosReturnsFirstMatch", RrfindWithPosReturnsFirstMatch)
UNITTEST("RrfindReturnsNposWhenNoMatch", RrfindReturnsNposWhenNoMatch)
UNITTEST("RfindReturnsNposWhenNeedleIsBiggerThanHaystack",
RfindReturnsNposWhenNeedleIsBiggerThanHaystack)
UNITTEST("FindFirstOfReturnsFirstMatch", FindFirstOfReturnsFirstMatch)
UNITTEST("FindFirstOfWithPosReturnsFirstMatch", FindFirstOfWithPosReturnsFirstMatch)
UNITTEST("FindFirstOfWithPosAndCountReturnsFirstMatch", FindFirstOfWithPosAndCountReturnsFirstMatch)
UNITTEST("FindFirstOfReturnsNposWhenNoMatch", FindFirstOfReturnsNposWhenNoMatch)
UNITTEST("FindLastOfReturnsLastMatch", FindLastOfReturnsLastMatch)
UNITTEST("FindLastOfWithPosReturnsLastMatch", FindLastOfWithPosReturnsLastMatch)
UNITTEST("FindLastOfWithPosAndCountReturnsLastMatch", FindLastOfWithPosAndCountReturnsLastMatch)
UNITTEST("FindLastOfReturnsNposWhenNoMatch", FindLastOfReturnsNposWhenNoMatch)
UNITTEST("FindFirstNofOfReturnsFirstNonMatch", FindFirstNofOfReturnsFirstNonMatch)
UNITTEST("FindFirstNofOfWithPosReturnsFirstNonMatch", FindFirstNofOfWithPosReturnsFirstNonMatch)
UNITTEST("FindFirstNofOfWithPosAndCountReturnsFirstNofMatch",
FindFirstNofOfWithPosAndCountReturnsFirstNofMatch)
UNITTEST("FindFirstNofOfReturnsNposWhenNoMatch", FindFirstNofOfReturnsNposWhenNoMatch)
UNITTEST("FindLastNotOfReturnsLastMatch", FindLastNotOfReturnsLastMatch)
UNITTEST("FindLastNotOfWithPosReturnsLastMatch", FindLastNotOfWithPosReturnsLastMatch)
UNITTEST("FindLastNotOfWithPosAndCountReturnsLastMatch",
FindLastNotOfWithPosAndCountReturnsLastMatch)
UNITTEST("FindLastNotOfReturnsNposWhenNoMatch", FindLastNotOfReturnsNposWhenNoMatch)
UNITTEST("StartsWith", StartsWith)
UNITTEST("EndsWith", EndsWith)
UNITTEST_END_TESTCASE(string_view_tests, "string_view", "ktl::string_view tests")