blob: d78db0d395d7e017e774c1afec7e8e3598465054 [file] [log] [blame]
//
// Copyright 2015 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// string_utils_unittests:
// Unit tests for the string utils.
//
#include "string_utils.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
using namespace angle;
namespace
{
// Basic SplitString tests
TEST(StringUtilsTest, SplitString_Basics)
{
std::vector<std::string> r;
r = SplitString(std::string(), ",:;", KEEP_WHITESPACE, SPLIT_WANT_ALL);
EXPECT_TRUE(r.empty());
// Empty separator list
r = SplitString("hello, world", "", KEEP_WHITESPACE, SPLIT_WANT_ALL);
ASSERT_EQ(1u, r.size());
EXPECT_EQ("hello, world", r[0]);
// Should split on any of the separators.
r = SplitString("::,,;;", ",:;", KEEP_WHITESPACE, SPLIT_WANT_ALL);
ASSERT_EQ(7u, r.size());
for (auto str : r)
ASSERT_TRUE(str.empty());
r = SplitString("red, green; blue:", ",:;", TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY);
ASSERT_EQ(3u, r.size());
EXPECT_EQ("red", r[0]);
EXPECT_EQ("green", r[1]);
EXPECT_EQ("blue", r[2]);
// Want to split a string along whitespace sequences.
r = SplitString(" red green \tblue\n", " \t\n", TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY);
ASSERT_EQ(3u, r.size());
EXPECT_EQ("red", r[0]);
EXPECT_EQ("green", r[1]);
EXPECT_EQ("blue", r[2]);
// Weird case of splitting on spaces but not trimming.
r = SplitString(" red ", " ", TRIM_WHITESPACE, SPLIT_WANT_ALL);
ASSERT_EQ(3u, r.size());
EXPECT_EQ("", r[0]); // Before the first space.
EXPECT_EQ("red", r[1]);
EXPECT_EQ("", r[2]); // After the last space.
}
// Check different whitespace and result types for SplitString
TEST(StringUtilsTest, SplitString_WhitespaceAndResultType)
{
std::vector<std::string> r;
// Empty input handling.
r = SplitString(std::string(), ",", KEEP_WHITESPACE, SPLIT_WANT_ALL);
EXPECT_TRUE(r.empty());
r = SplitString(std::string(), ",", KEEP_WHITESPACE, SPLIT_WANT_NONEMPTY);
EXPECT_TRUE(r.empty());
// Input string is space and we're trimming.
r = SplitString(" ", ",", TRIM_WHITESPACE, SPLIT_WANT_ALL);
ASSERT_EQ(1u, r.size());
EXPECT_EQ("", r[0]);
r = SplitString(" ", ",", TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY);
EXPECT_TRUE(r.empty());
// Test all 4 combinations of flags on ", ,".
r = SplitString(", ,", ",", KEEP_WHITESPACE, SPLIT_WANT_ALL);
ASSERT_EQ(3u, r.size());
EXPECT_EQ("", r[0]);
EXPECT_EQ(" ", r[1]);
EXPECT_EQ("", r[2]);
r = SplitString(", ,", ",", KEEP_WHITESPACE, SPLIT_WANT_NONEMPTY);
ASSERT_EQ(1u, r.size());
ASSERT_EQ(" ", r[0]);
r = SplitString(", ,", ",", TRIM_WHITESPACE, SPLIT_WANT_ALL);
ASSERT_EQ(3u, r.size());
EXPECT_EQ("", r[0]);
EXPECT_EQ("", r[1]);
EXPECT_EQ("", r[2]);
r = SplitString(", ,", ",", TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY);
ASSERT_TRUE(r.empty());
}
// Tests for SplitStringAlongWhitespace
TEST(StringUtilsTest, SplitStringAlongWhitespace)
{
{
// No whitespace.
std::vector<std::string> r;
SplitStringAlongWhitespace("abcd", &r);
ASSERT_THAT(r, testing::ElementsAre("abcd"));
}
{
// Just whitespace.
std::vector<std::string> r;
SplitStringAlongWhitespace(" \t", &r);
ASSERT_THAT(r, testing::ElementsAre());
}
{
// Consecutive whitespace of same type.
std::vector<std::string> r;
SplitStringAlongWhitespace("a b", &r);
ASSERT_THAT(r, testing::ElementsAre("a", "b"));
}
{
// Consecutive whitespace of different types.
std::vector<std::string> r;
SplitStringAlongWhitespace("ab \tcd", &r);
ASSERT_THAT(r, testing::ElementsAre("ab", "cd"));
}
{
// Non-empty output std::vector.
std::vector<std::string> r;
r.push_back("z");
SplitStringAlongWhitespace("abc", &r);
ASSERT_THAT(r, testing::ElementsAre("z", "abc"));
}
}
// Tests for TrimString
TEST(StringUtilsTest, TrimString)
{
// Basic tests
EXPECT_EQ("a", TrimString("a", kWhitespaceASCII));
EXPECT_EQ("a", TrimString(" a", kWhitespaceASCII));
EXPECT_EQ("a", TrimString("a ", kWhitespaceASCII));
EXPECT_EQ("a", TrimString(" a ", kWhitespaceASCII));
// Tests with empty strings
EXPECT_EQ("", TrimString("", kWhitespaceASCII));
EXPECT_EQ("", TrimString(" \n\r\t", kWhitespaceASCII));
EXPECT_EQ(" foo ", TrimString(" foo ", ""));
// Tests it doesn't removes characters in the middle
EXPECT_EQ("foo bar", TrimString(" foo bar ", kWhitespaceASCII));
// Test with non-whitespace trimChars
EXPECT_EQ(" ", TrimString("foo bar", "abcdefghijklmnopqrstuvwxyz"));
}
// Basic functionality tests for HexStringToUInt
TEST(StringUtilsTest, HexStringToUIntBasic)
{
unsigned int uintValue;
std::string emptyString;
ASSERT_FALSE(HexStringToUInt(emptyString, &uintValue));
std::string testStringA("0xBADF00D");
ASSERT_TRUE(HexStringToUInt(testStringA, &uintValue));
EXPECT_EQ(0xBADF00Du, uintValue);
std::string testStringB("0xBADFOOD");
EXPECT_FALSE(HexStringToUInt(testStringB, &uintValue));
std::string testStringC("BADF00D");
EXPECT_TRUE(HexStringToUInt(testStringC, &uintValue));
EXPECT_EQ(0xBADF00Du, uintValue);
std::string testStringD("0x BADF00D");
EXPECT_FALSE(HexStringToUInt(testStringD, &uintValue));
}
// Tests for ToCamelCase
TEST(StringUtilsTest, ToCamelCase)
{
// No underscore in input; expect identical output
EXPECT_EQ("", ToCamelCase(""));
EXPECT_EQ("a", ToCamelCase("a"));
EXPECT_EQ("AbCdEfG", ToCamelCase("AbCdEfG"));
EXPECT_EQ("aBcDeFg", ToCamelCase("aBcDeFg"));
// Underscore should be removed and the next character turned upper case
EXPECT_EQ("", ToCamelCase("_"));
EXPECT_EQ("aB", ToCamelCase("a_b"));
EXPECT_EQ("aB", ToCamelCase("a_b"));
EXPECT_EQ("camelCase", ToCamelCase("camel_case"));
EXPECT_EQ("abCDeBEfG", ToCamelCase("abCDe_bEfG"));
// Multiple underscores
EXPECT_EQ("aBCDEFG", ToCamelCase("a_b_c_d_e_f_g"));
EXPECT_EQ("abCdEfGh", ToCamelCase("ab_cd_ef_gh"));
EXPECT_EQ("aShortName", ToCamelCase("a_short_name"));
EXPECT_EQ("someShortWords", ToCamelCase("some_short_words"));
EXPECT_EQ("bunchOLetters", ToCamelCase("bunch_o_letters"));
EXPECT_EQ("whatEndsInE", ToCamelCase("what_ends_in_e"));
EXPECT_EQ("adjustSrcDstRegionForBlitFramebuffer",
ToCamelCase("adjust_src_dst_region_for_BlitFramebuffer"));
// Uppercase after underscore
EXPECT_EQ("abCDEFGh", ToCamelCase("ab_CD_eF_Gh"));
EXPECT_EQ("IWasThere", ToCamelCase("I_was_there"));
EXPECT_EQ("whereDidTHATComeFrom", ToCamelCase("where_did_THAT_come_from"));
// Digits
EXPECT_EQ("ab123c4deF5gHi6J", ToCamelCase("ab1_2_3c_4de_f5g_hi6_j"));
EXPECT_EQ("maxSize16KB", ToCamelCase("max_size_16KB"));
EXPECT_EQ("supportRGBA8", ToCamelCase("support_RGBA8"));
}
// Basic functionality for NamesMatchWithWildcard.
TEST(StringUtilsTest, NamesMatchWithWildcard)
{
EXPECT_TRUE(NamesMatchWithWildcard("ASDF", "ASDF"));
EXPECT_TRUE(NamesMatchWithWildcard("A*", "ASDF"));
EXPECT_TRUE(NamesMatchWithWildcard("AS*", "ASDF"));
EXPECT_TRUE(NamesMatchWithWildcard("ASD*", "ASDF"));
EXPECT_TRUE(NamesMatchWithWildcard("ASDF*", "ASDF"));
EXPECT_TRUE(NamesMatchWithWildcard("*F", "ASDF"));
EXPECT_TRUE(NamesMatchWithWildcard("*DF", "ASDF"));
EXPECT_TRUE(NamesMatchWithWildcard("*SDF", "ASDF"));
EXPECT_TRUE(NamesMatchWithWildcard("*ASDF", "ASDF"));
EXPECT_TRUE(NamesMatchWithWildcard("AS**", "ASDF"));
EXPECT_TRUE(NamesMatchWithWildcard("AS***", "ASDF"));
EXPECT_TRUE(NamesMatchWithWildcard("**DF", "ASDF"));
EXPECT_TRUE(NamesMatchWithWildcard("***DF", "ASDF"));
EXPECT_TRUE(NamesMatchWithWildcard("A*F", "ASDF"));
EXPECT_TRUE(NamesMatchWithWildcard("A**F", "ASDF"));
EXPECT_TRUE(NamesMatchWithWildcard("*SD*", "ASDF"));
EXPECT_TRUE(NamesMatchWithWildcard("*S*D*", "ASDF"));
EXPECT_TRUE(NamesMatchWithWildcard("ASD*", "ASDF*"));
}
// Note: ReadFileToString is harder to test
class BeginsWithTest : public testing::Test
{
public:
BeginsWithTest() : mMode(TestMode::CHAR_ARRAY) {}
enum class TestMode
{
CHAR_ARRAY,
STRING_AND_CHAR_ARRAY,
STRING
};
void setMode(TestMode mode) { mMode = mode; }
bool runBeginsWith(const char *str, const char *prefix)
{
if (mMode == TestMode::CHAR_ARRAY)
{
return BeginsWith(str, prefix);
}
if (mMode == TestMode::STRING_AND_CHAR_ARRAY)
{
return BeginsWith(std::string(str), prefix);
}
return BeginsWith(std::string(str), std::string(prefix));
}
void runTest()
{
ASSERT_FALSE(runBeginsWith("foo", "bar"));
ASSERT_FALSE(runBeginsWith("", "foo"));
ASSERT_FALSE(runBeginsWith("foo", "foobar"));
ASSERT_TRUE(runBeginsWith("foobar", "foo"));
ASSERT_TRUE(runBeginsWith("foobar", ""));
ASSERT_TRUE(runBeginsWith("foo", "foo"));
ASSERT_TRUE(runBeginsWith("", ""));
}
private:
TestMode mMode;
};
// Test that BeginsWith works correctly for const char * arguments.
TEST_F(BeginsWithTest, CharArrays)
{
setMode(TestMode::CHAR_ARRAY);
runTest();
}
// Test that BeginsWith works correctly for std::string and const char * arguments.
TEST_F(BeginsWithTest, StringAndCharArray)
{
setMode(TestMode::STRING_AND_CHAR_ARRAY);
runTest();
}
// Test that BeginsWith works correctly for std::string arguments.
TEST_F(BeginsWithTest, Strings)
{
setMode(TestMode::STRING);
runTest();
}
class EndsWithTest : public testing::Test
{
public:
EndsWithTest() : mMode(TestMode::CHAR_ARRAY) {}
enum class TestMode
{
CHAR_ARRAY,
STRING_AND_CHAR_ARRAY,
STRING
};
void setMode(TestMode mode) { mMode = mode; }
bool runEndsWith(const char *str, const char *suffix)
{
if (mMode == TestMode::CHAR_ARRAY)
{
return EndsWith(str, suffix);
}
if (mMode == TestMode::STRING_AND_CHAR_ARRAY)
{
return EndsWith(std::string(str), suffix);
}
return EndsWith(std::string(str), std::string(suffix));
}
void runTest()
{
ASSERT_FALSE(EndsWith("foo", "bar"));
ASSERT_FALSE(EndsWith("", "bar"));
ASSERT_FALSE(EndsWith("foo", "foobar"));
ASSERT_TRUE(EndsWith("foobar", "bar"));
ASSERT_TRUE(EndsWith("foobar", ""));
ASSERT_TRUE(EndsWith("bar", "bar"));
ASSERT_TRUE(EndsWith("", ""));
}
private:
TestMode mMode;
};
// Test that EndsWith works correctly for const char * arguments.
TEST_F(EndsWithTest, CharArrays)
{
setMode(TestMode::CHAR_ARRAY);
runTest();
}
// Test that EndsWith works correctly for std::string and const char * arguments.
TEST_F(EndsWithTest, StringAndCharArray)
{
setMode(TestMode::STRING_AND_CHAR_ARRAY);
runTest();
}
// Test that EndsWith works correctly for std::string arguments.
TEST_F(EndsWithTest, Strings)
{
setMode(TestMode::STRING);
runTest();
}
} // anonymous namespace