blob: 82c97c896966a2ee154ec33682090ce5d0d08163 [file] [log] [blame]
/* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
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 "tensorflow/core/lib/strings/str_util.h"
#include <vector>
#include "tensorflow/core/platform/test.h"
namespace tensorflow {
TEST(CEscape, Basic) {
EXPECT_EQ(str_util::CEscape("hello"), "hello");
EXPECT_EQ(str_util::CEscape("hello\n"), "hello\\n");
EXPECT_EQ(str_util::CEscape("hello\r"), "hello\\r");
EXPECT_EQ(str_util::CEscape("\t\r\"'"), "\\t\\r\\\"\\'");
EXPECT_EQ(str_util::CEscape("\320hi\200"), "\\320hi\\200");
}
string ExpectCUnescapeSuccess(StringPiece source) {
string dest;
string error;
EXPECT_TRUE(str_util::CUnescape(source, &dest, &error)) << error;
return dest;
}
TEST(CUnescape, Basic) {
EXPECT_EQ("hello", ExpectCUnescapeSuccess("hello"));
EXPECT_EQ("hello\n", ExpectCUnescapeSuccess("hello\\n"));
EXPECT_EQ("hello\r", ExpectCUnescapeSuccess("hello\\r"));
EXPECT_EQ("\t\r\"'", ExpectCUnescapeSuccess("\\t\\r\\\"\\'"));
EXPECT_EQ("\320hi\200", ExpectCUnescapeSuccess("\\320hi\\200"));
}
TEST(CUnescape, HandlesCopyOnWriteStrings) {
string dest = "hello";
string read = dest;
// For std::string, read and dest now share the same buffer.
string error;
StringPiece source = "llohe";
// CUnescape is going to write "llohe" to dest, so dest's buffer will be
// reallocated, and read's buffer remains untouched.
EXPECT_TRUE(str_util::CUnescape(source, &dest, &error));
EXPECT_EQ("hello", read);
}
TEST(StripTrailingWhitespace, Basic) {
string test;
test = "hello";
str_util::StripTrailingWhitespace(&test);
EXPECT_EQ(test, "hello");
test = "foo ";
str_util::StripTrailingWhitespace(&test);
EXPECT_EQ(test, "foo");
test = " ";
str_util::StripTrailingWhitespace(&test);
EXPECT_EQ(test, "");
test = "";
str_util::StripTrailingWhitespace(&test);
EXPECT_EQ(test, "");
test = " abc\t";
str_util::StripTrailingWhitespace(&test);
EXPECT_EQ(test, " abc");
}
TEST(RemoveLeadingWhitespace, Basic) {
string text = " \t \n \r Quick\t";
StringPiece data(text);
// check that all whitespace is removed
EXPECT_EQ(str_util::RemoveLeadingWhitespace(&data), 11);
EXPECT_EQ(data, StringPiece("Quick\t"));
// check that non-whitespace is not removed
EXPECT_EQ(str_util::RemoveLeadingWhitespace(&data), 0);
EXPECT_EQ(data, StringPiece("Quick\t"));
}
TEST(RemoveLeadingWhitespace, TerminationHandling) {
// check termination handling
string text = "\t";
StringPiece data(text);
EXPECT_EQ(str_util::RemoveLeadingWhitespace(&data), 1);
EXPECT_EQ(data, StringPiece(""));
// check termination handling again
EXPECT_EQ(str_util::RemoveLeadingWhitespace(&data), 0);
EXPECT_EQ(data, StringPiece(""));
}
TEST(RemoveTrailingWhitespace, Basic) {
string text = " \t \n \r Quick \t";
StringPiece data(text);
// check that all whitespace is removed
EXPECT_EQ(str_util::RemoveTrailingWhitespace(&data), 2);
EXPECT_EQ(data, StringPiece(" \t \n \r Quick"));
// check that non-whitespace is not removed
EXPECT_EQ(str_util::RemoveTrailingWhitespace(&data), 0);
EXPECT_EQ(data, StringPiece(" \t \n \r Quick"));
}
TEST(RemoveTrailingWhitespace, TerminationHandling) {
// check termination handling
string text = "\t";
StringPiece data(text);
EXPECT_EQ(str_util::RemoveTrailingWhitespace(&data), 1);
EXPECT_EQ(data, StringPiece(""));
// check termination handling again
EXPECT_EQ(str_util::RemoveTrailingWhitespace(&data), 0);
EXPECT_EQ(data, StringPiece(""));
}
TEST(RemoveWhitespaceContext, Basic) {
string text = " \t \n \r Quick \t";
StringPiece data(text);
// check that all whitespace is removed
EXPECT_EQ(str_util::RemoveWhitespaceContext(&data), 13);
EXPECT_EQ(data, StringPiece("Quick"));
// check that non-whitespace is not removed
EXPECT_EQ(str_util::RemoveWhitespaceContext(&data), 0);
EXPECT_EQ(data, StringPiece("Quick"));
// Test empty string
text = "";
data = text;
EXPECT_EQ(str_util::RemoveWhitespaceContext(&data), 0);
EXPECT_EQ(data, StringPiece(""));
}
void TestConsumeLeadingDigits(StringPiece s, int64 expected,
StringPiece remaining) {
uint64 v;
StringPiece input(s);
if (str_util::ConsumeLeadingDigits(&input, &v)) {
EXPECT_EQ(v, static_cast<uint64>(expected));
EXPECT_EQ(input, remaining);
} else {
EXPECT_LT(expected, 0);
EXPECT_EQ(input, remaining);
}
}
TEST(ConsumeLeadingDigits, Basic) {
using str_util::ConsumeLeadingDigits;
TestConsumeLeadingDigits("123", 123, "");
TestConsumeLeadingDigits("a123", -1, "a123");
TestConsumeLeadingDigits("9_", 9, "_");
TestConsumeLeadingDigits("11111111111xyz", 11111111111ll, "xyz");
// Overflow case
TestConsumeLeadingDigits("1111111111111111111111111111111xyz", -1,
"1111111111111111111111111111111xyz");
// 2^64
TestConsumeLeadingDigits("18446744073709551616xyz", -1,
"18446744073709551616xyz");
// 2^64-1
TestConsumeLeadingDigits("18446744073709551615xyz", 18446744073709551615ull,
"xyz");
// (2^64-1)*10+9
TestConsumeLeadingDigits("184467440737095516159yz", -1,
"184467440737095516159yz");
}
void TestConsumeNonWhitespace(StringPiece s, StringPiece expected,
StringPiece remaining) {
StringPiece v;
StringPiece input(s);
if (str_util::ConsumeNonWhitespace(&input, &v)) {
EXPECT_EQ(v, expected);
EXPECT_EQ(input, remaining);
} else {
EXPECT_EQ(expected, "");
EXPECT_EQ(input, remaining);
}
}
TEST(ConsumeNonWhitespace, Basic) {
TestConsumeNonWhitespace("", "", "");
TestConsumeNonWhitespace(" ", "", " ");
TestConsumeNonWhitespace("abc", "abc", "");
TestConsumeNonWhitespace("abc ", "abc", " ");
}
TEST(ConsumePrefix, Basic) {
string s("abcdef");
StringPiece input(s);
EXPECT_FALSE(str_util::ConsumePrefix(&input, "abcdefg"));
EXPECT_EQ(input, "abcdef");
EXPECT_FALSE(str_util::ConsumePrefix(&input, "abce"));
EXPECT_EQ(input, "abcdef");
EXPECT_TRUE(str_util::ConsumePrefix(&input, ""));
EXPECT_EQ(input, "abcdef");
EXPECT_FALSE(str_util::ConsumePrefix(&input, "abcdeg"));
EXPECT_EQ(input, "abcdef");
EXPECT_TRUE(str_util::ConsumePrefix(&input, "abcdef"));
EXPECT_EQ(input, "");
input = s;
EXPECT_TRUE(str_util::ConsumePrefix(&input, "abcde"));
EXPECT_EQ(input, "f");
}
TEST(JoinStrings, Basic) {
std::vector<string> s;
s = {"hi"};
EXPECT_EQ(str_util::Join(s, " "), "hi");
s = {"hi", "there", "strings"};
EXPECT_EQ(str_util::Join(s, " "), "hi there strings");
std::vector<StringPiece> sp;
sp = {"hi"};
EXPECT_EQ(str_util::Join(sp, ",,"), "hi");
sp = {"hi", "there", "strings"};
EXPECT_EQ(str_util::Join(sp, "--"), "hi--there--strings");
}
TEST(JoinStrings, Join3) {
std::vector<string> s;
s = {"hi"};
auto l1 = [](string* out, string s) { *out += s; };
EXPECT_EQ(str_util::Join(s, " ", l1), "hi");
s = {"hi", "there", "strings"};
auto l2 = [](string* out, string s) { *out += s[0]; };
EXPECT_EQ(str_util::Join(s, " ", l2), "h t s");
}
TEST(Split, Basic) {
EXPECT_TRUE(str_util::Split("", ',').empty());
EXPECT_EQ(str_util::Join(str_util::Split("a", ','), "|"), "a");
EXPECT_EQ(str_util::Join(str_util::Split(",", ','), "|"), "|");
EXPECT_EQ(str_util::Join(str_util::Split("a,b,c", ','), "|"), "a|b|c");
EXPECT_EQ(str_util::Join(str_util::Split("a,,,b,,c,", ','), "|"),
"a|||b||c|");
EXPECT_EQ(str_util::Join(str_util::Split("a!,!b,!c,", ",!"), "|"),
"a|||b||c|");
EXPECT_EQ(str_util::Join(
str_util::Split("a,,,b,,c,", ',', str_util::SkipEmpty()), "|"),
"a|b|c");
EXPECT_EQ(
str_util::Join(
str_util::Split("a, ,b,,c,", ',', str_util::SkipWhitespace()), "|"),
"a|b|c");
EXPECT_EQ(str_util::Join(str_util::Split("a. !b,;c,", ".,;!",
str_util::SkipWhitespace()),
"|"),
"a|b|c");
}
TEST(SplitAndParseAsInts, Int32) {
std::vector<int32> nums;
EXPECT_TRUE(str_util::SplitAndParseAsInts("", ',', &nums));
EXPECT_EQ(nums.size(), 0);
EXPECT_TRUE(str_util::SplitAndParseAsInts("134", ',', &nums));
EXPECT_EQ(nums.size(), 1);
EXPECT_EQ(nums[0], 134);
EXPECT_TRUE(str_util::SplitAndParseAsInts("134,2,13,-5", ',', &nums));
EXPECT_EQ(nums.size(), 4);
EXPECT_EQ(nums[0], 134);
EXPECT_EQ(nums[1], 2);
EXPECT_EQ(nums[2], 13);
EXPECT_EQ(nums[3], -5);
EXPECT_FALSE(str_util::SplitAndParseAsInts("abc", ',', &nums));
EXPECT_FALSE(str_util::SplitAndParseAsInts("-13,abc", ',', &nums));
EXPECT_FALSE(str_util::SplitAndParseAsInts("13,abc,5", ',', &nums));
}
TEST(SplitAndParseAsInts, Int64) {
std::vector<int64> nums;
EXPECT_TRUE(str_util::SplitAndParseAsInts("", ',', &nums));
EXPECT_EQ(nums.size(), 0);
EXPECT_TRUE(str_util::SplitAndParseAsInts("134", ',', &nums));
EXPECT_EQ(nums.size(), 1);
EXPECT_EQ(nums[0], 134);
EXPECT_TRUE(
str_util::SplitAndParseAsInts("134,2,13,-4000000000", ',', &nums));
EXPECT_EQ(nums.size(), 4);
EXPECT_EQ(nums[0], 134);
EXPECT_EQ(nums[1], 2);
EXPECT_EQ(nums[2], 13);
EXPECT_EQ(nums[3], static_cast<int64>(-4000000000ull));
EXPECT_FALSE(str_util::SplitAndParseAsInts("abc", ',', &nums));
EXPECT_FALSE(str_util::SplitAndParseAsInts("-13,abc", ',', &nums));
EXPECT_FALSE(str_util::SplitAndParseAsInts("13,abc,5", ',', &nums));
}
TEST(Lowercase, Basic) {
EXPECT_EQ("", str_util::Lowercase(""));
EXPECT_EQ("hello", str_util::Lowercase("hello"));
EXPECT_EQ("hello world", str_util::Lowercase("Hello World"));
}
TEST(Uppercase, Basic) {
EXPECT_EQ("", str_util::Uppercase(""));
EXPECT_EQ("HELLO", str_util::Uppercase("hello"));
EXPECT_EQ("HELLO WORLD", str_util::Uppercase("Hello World"));
}
TEST(SnakeCase, Basic) {
EXPECT_EQ("", str_util::ArgDefCase(""));
EXPECT_EQ("", str_util::ArgDefCase("!"));
EXPECT_EQ("", str_util::ArgDefCase("5"));
EXPECT_EQ("", str_util::ArgDefCase("!:"));
EXPECT_EQ("", str_util::ArgDefCase("5-5"));
EXPECT_EQ("", str_util::ArgDefCase("_!"));
EXPECT_EQ("", str_util::ArgDefCase("_5"));
EXPECT_EQ("a", str_util::ArgDefCase("_a"));
EXPECT_EQ("a", str_util::ArgDefCase("_A"));
EXPECT_EQ("i", str_util::ArgDefCase("I"));
EXPECT_EQ("i", str_util::ArgDefCase("i"));
EXPECT_EQ("i_", str_util::ArgDefCase("I%"));
EXPECT_EQ("i_", str_util::ArgDefCase("i%"));
EXPECT_EQ("i", str_util::ArgDefCase("%I"));
EXPECT_EQ("i", str_util::ArgDefCase("-i"));
EXPECT_EQ("i", str_util::ArgDefCase("3i"));
EXPECT_EQ("i", str_util::ArgDefCase("32i"));
EXPECT_EQ("i3", str_util::ArgDefCase("i3"));
EXPECT_EQ("i_a3", str_util::ArgDefCase("i_A3"));
EXPECT_EQ("i_i", str_util::ArgDefCase("II"));
EXPECT_EQ("i_i", str_util::ArgDefCase("I_I"));
EXPECT_EQ("i__i", str_util::ArgDefCase("I__I"));
EXPECT_EQ("i_i_32", str_util::ArgDefCase("II-32"));
EXPECT_EQ("ii_32", str_util::ArgDefCase("Ii-32"));
EXPECT_EQ("hi_there", str_util::ArgDefCase("HiThere"));
EXPECT_EQ("hi_hi", str_util::ArgDefCase("Hi!Hi"));
EXPECT_EQ("hi_hi", str_util::ArgDefCase("HiHi"));
EXPECT_EQ("hihi", str_util::ArgDefCase("Hihi"));
EXPECT_EQ("hi_hi", str_util::ArgDefCase("Hi_Hi"));
}
TEST(TitlecaseString, Basic) {
string s = "sparse_lookup";
str_util::TitlecaseString(&s, "_");
ASSERT_EQ(s, "Sparse_Lookup");
s = "sparse_lookup";
str_util::TitlecaseString(&s, " ");
ASSERT_EQ(s, "Sparse_lookup");
s = "dense";
str_util::TitlecaseString(&s, " ");
ASSERT_EQ(s, "Dense");
}
TEST(StringReplace, Basic) {
EXPECT_EQ("XYZ_XYZ_XYZ", str_util::StringReplace("ABC_ABC_ABC", "ABC", "XYZ",
/*replace_all=*/true));
}
TEST(StringReplace, OnlyFirst) {
EXPECT_EQ("XYZ_ABC_ABC", str_util::StringReplace("ABC_ABC_ABC", "ABC", "XYZ",
/*replace_all=*/false));
}
TEST(StringReplace, IncreaseLength) {
EXPECT_EQ("a b c",
str_util::StringReplace("abc", "b", " b ", /*replace_all=*/true));
}
TEST(StringReplace, IncreaseLengthMultipleMatches) {
EXPECT_EQ("a b b c",
str_util::StringReplace("abbc", "b", " b ", /*replace_all=*/true));
}
TEST(StringReplace, NoChange) {
EXPECT_EQ("abc",
str_util::StringReplace("abc", "d", "X", /*replace_all=*/true));
}
TEST(StringReplace, EmptyStringReplaceFirst) {
EXPECT_EQ("", str_util::StringReplace("", "a", "X", /*replace_all=*/false));
}
TEST(StringReplace, EmptyStringReplaceAll) {
EXPECT_EQ("", str_util::StringReplace("", "a", "X", /*replace_all=*/true));
}
TEST(Strnlen, Basic) {
EXPECT_EQ(0, str_util::Strnlen("ab", 0));
EXPECT_EQ(1, str_util::Strnlen("a", 1));
EXPECT_EQ(2, str_util::Strnlen("abcd", 2));
EXPECT_EQ(3, str_util::Strnlen("abc", 10));
EXPECT_EQ(4, str_util::Strnlen("a \t\n", 10));
}
} // namespace tensorflow