blob: 3360ca035ec70e55cacd6490bc865f4434c34042 [file] [log] [blame]
// Copyright 2014 The Bazel 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 "src/main/cpp/util/strings.h"
#include <wchar.h>
#include <memory>
#include <string>
#include <vector>
#include "googletest/include/gtest/gtest.h"
namespace blaze_util {
using std::string;
using std::vector;
TEST(BlazeUtil, JoinStrings) {
vector<string> pieces;
string output;
JoinStrings(pieces, ' ', &output);
ASSERT_EQ("", output);
pieces.push_back("abc");
JoinStrings(pieces, ' ', &output);
ASSERT_EQ("abc", output);
pieces.push_back("");
JoinStrings(pieces, ' ', &output);
ASSERT_EQ("abc ", output);
pieces.push_back("def");
JoinStrings(pieces, ' ', &output);
ASSERT_EQ("abc def", output);
}
TEST(BlazeUtil, Split) {
string lines = "";
vector<string> pieces = Split(lines, '\n');
ASSERT_EQ(size_t(0), pieces.size());
lines = "foo";
pieces = Split(lines, '\n');
ASSERT_EQ(size_t(1), pieces.size());
ASSERT_EQ("foo", pieces[0]);
lines = "\nfoo";
pieces = Split(lines, '\n');
ASSERT_EQ(size_t(1), pieces.size());
ASSERT_EQ("foo", pieces[0]);
lines = "\n\n\nfoo";
pieces = Split(lines, '\n');
ASSERT_EQ(size_t(1), pieces.size());
ASSERT_EQ("foo", pieces[0]);
lines = "foo\n";
pieces = Split(lines, '\n');
ASSERT_EQ(size_t(1), pieces.size());
ASSERT_EQ("foo", pieces[0]);
lines = "foo\n\n\n";
pieces = Split(lines, '\n');
ASSERT_EQ(size_t(1), pieces.size());
ASSERT_EQ("foo", pieces[0]);
lines = "foo\nbar";
pieces = Split(lines, '\n');
ASSERT_EQ(size_t(2), pieces.size());
ASSERT_EQ("foo", pieces[0]);
ASSERT_EQ("bar", pieces[1]);
lines = "foo\n\nbar";
pieces = Split(lines, '\n');
ASSERT_EQ(size_t(2), pieces.size());
ASSERT_EQ("foo", pieces[0]);
ASSERT_EQ("bar", pieces[1]);
}
TEST(BlazeUtil, Replace) {
string line = "foo\\\nbar\nbaz";
Replace("\\\n", "", &line);
ASSERT_EQ("foobar\nbaz", line);
line = "foo\\\n\\\nbar";
Replace("\\\n", "", &line);
ASSERT_EQ("foobar", line);
line = "foo\\\r\nbar";
Replace("\\\r\n", "", &line);
ASSERT_EQ("foobar", line);
line = "\\\n\\\r\n";
Replace("\\\n", "", &line);
Replace("\\\r\n", "", &line);
ASSERT_EQ("", line);
line = "x:y:z";
Replace(":", "_C", &line);
ASSERT_EQ("x_Cy_Cz", line);
line = "x_::y_:__z";
Replace("_", "_U", &line);
Replace(":", "_C", &line);
ASSERT_EQ("x_U_C_Cy_U_C_U_Uz", line);
}
TEST(BlazeUtil, StripWhitespace) {
string str = " ";
StripWhitespace(&str);
ASSERT_EQ("", str);
str = " abc ";
StripWhitespace(&str);
ASSERT_EQ("abc", str);
str = "abc";
StripWhitespace(&str);
ASSERT_EQ("abc", str);
}
TEST(BlazeUtil, Tokenize) {
vector<string> result;
string str = "a b c";
Tokenize(str, '#', &result);
ASSERT_EQ(size_t(3), result.size());
EXPECT_EQ("a", result[0]);
EXPECT_EQ("b", result[1]);
EXPECT_EQ("c", result[2]);
str = "a 'b c'";
Tokenize(str, '#', &result);
ASSERT_EQ(size_t(2), result.size());
EXPECT_EQ("a", result[0]);
EXPECT_EQ("b c", result[1]);
str = "foo# bar baz";
Tokenize(str, '#', &result);
ASSERT_EQ(size_t(1), result.size());
EXPECT_EQ("foo", result[0]);
str = "foo # bar baz";
Tokenize(str, '#', &result);
ASSERT_EQ(size_t(1), result.size());
EXPECT_EQ("foo", result[0]);
str = "#bar baz";
Tokenize(str, '#', &result);
ASSERT_EQ(size_t(0), result.size());
str = "#";
Tokenize(str, '#', &result);
ASSERT_EQ(size_t(0), result.size());
str = " \tfirst second / ";
Tokenize(str, 0, &result);
ASSERT_EQ(size_t(3), result.size());
EXPECT_EQ("first", result[0]);
EXPECT_EQ("second", result[1]);
EXPECT_EQ("/", result[2]);
str = " \tfirst second / ";
Tokenize(str, '/', &result);
ASSERT_EQ(size_t(2), result.size());
EXPECT_EQ("first", result[0]);
EXPECT_EQ("second", result[1]);
str = "first \"second' third\" fourth";
Tokenize(str, '/', &result);
ASSERT_EQ(size_t(3), result.size());
EXPECT_EQ("first", result[0]);
EXPECT_EQ("second' third", result[1]);
EXPECT_EQ("fourth", result[2]);
str = "first 'second\" third' fourth";
Tokenize(str, '/', &result);
ASSERT_EQ(size_t(3), result.size());
EXPECT_EQ("first", result[0]);
EXPECT_EQ("second\" third", result[1]);
EXPECT_EQ("fourth", result[2]);
str = "\\ this\\ is\\ one\\'\\ token";
Tokenize(str, 0, &result);
ASSERT_EQ(size_t(1), result.size());
EXPECT_EQ(" this is one' token", result[0]);
str = "\\ this\\ is\\ one\\'\\ token\\";
Tokenize(str, 0, &result);
ASSERT_EQ(size_t(1), result.size());
EXPECT_EQ(" this is one' token", result[0]);
str = "unterminated \" runs to end of line";
Tokenize(str, 0, &result);
ASSERT_EQ(size_t(2), result.size());
EXPECT_EQ("unterminated", result[0]);
EXPECT_EQ(" runs to end of line", result[1]);
str = "";
Tokenize(str, 0, &result);
ASSERT_EQ(size_t(0), result.size());
str = "one two\'s three";
Tokenize(str, 0, &result);
ASSERT_EQ(size_t(2), result.size());
EXPECT_EQ("one", result[0]);
EXPECT_EQ("twos three", result[1]);
str = "one \'two three";
Tokenize(str, 0, &result);
ASSERT_EQ(size_t(2), result.size());
EXPECT_EQ("one", result[0]);
EXPECT_EQ("two three", result[1]);
}
static vector<string> SplitQuoted(const string &contents,
const char delimiter) {
vector<string> result;
SplitQuotedStringUsing(contents, delimiter, &result);
return result;
}
TEST(BlazeUtil, SplitQuoted) {
string lines = "";
vector<string> pieces = SplitQuoted(lines, '\n');
ASSERT_EQ(size_t(0), pieces.size());
// Same behaviour without quotes as Split
lines = "foo";
pieces = SplitQuoted(lines, ' ');
ASSERT_EQ(size_t(1), pieces.size());
ASSERT_EQ("foo", pieces[0]);
lines = " foo";
pieces = SplitQuoted(lines, ' ');
ASSERT_EQ(size_t(1), pieces.size());
ASSERT_EQ("foo", pieces[0]);
lines = " foo";
pieces = SplitQuoted(lines, ' ');
ASSERT_EQ(size_t(1), pieces.size());
ASSERT_EQ("foo", pieces[0]);
lines = "foo ";
pieces = SplitQuoted(lines, ' ');
ASSERT_EQ(size_t(1), pieces.size());
ASSERT_EQ("foo", pieces[0]);
lines = "foo ";
pieces = SplitQuoted(lines, ' ');
ASSERT_EQ(size_t(1), pieces.size());
ASSERT_EQ("foo", pieces[0]);
lines = "foo bar";
pieces = SplitQuoted(lines, ' ');
ASSERT_EQ(size_t(2), pieces.size());
ASSERT_EQ("foo", pieces[0]);
ASSERT_EQ("bar", pieces[1]);
lines = "foo bar";
pieces = SplitQuoted(lines, ' ');
ASSERT_EQ(size_t(2), pieces.size());
ASSERT_EQ("foo", pieces[0]);
ASSERT_EQ("bar", pieces[1]);
// Test with quotes
lines = "' 'foo";
pieces = SplitQuoted(lines, ' ');
ASSERT_EQ(size_t(1), pieces.size());
ASSERT_EQ("' 'foo", pieces[0]);
lines = " ' ' foo";
pieces = SplitQuoted(lines, ' ');
ASSERT_EQ(size_t(2), pieces.size());
ASSERT_EQ("' '", pieces[0]);
ASSERT_EQ("foo", pieces[1]);
lines = "foo' \\' ' ";
pieces = SplitQuoted(lines, ' ');
ASSERT_EQ(size_t(1), pieces.size());
ASSERT_EQ("foo' \\' '", pieces[0]);
lines = "foo'\\'\" ' ";
pieces = SplitQuoted(lines, ' ');
ASSERT_EQ(size_t(1), pieces.size());
ASSERT_EQ("foo'\\'\" '", pieces[0]);
}
TEST(BlazeUtil, StringPrintf) {
string out;
StringPrintf(&out, "%s %s", "a", "b");
EXPECT_EQ("a b", out);
}
TEST(BlazeUtil, EndsWithTest) {
ASSERT_TRUE(ends_with("", ""));
ASSERT_TRUE(ends_with(L"", L""));
ASSERT_TRUE(ends_with("abc", "bc"));
ASSERT_TRUE(ends_with(L"abc", L"bc"));
// prefix matches but suffix doesn't
ASSERT_FALSE(ends_with("abc", "bd"));
ASSERT_FALSE(ends_with(L"abc", L"bd"));
// suffix matches but prefix doesn't
ASSERT_FALSE(ends_with("abc", "dc"));
ASSERT_FALSE(ends_with(L"abc", L"dc"));
// full match
ASSERT_TRUE(ends_with("abc", "abc"));
ASSERT_TRUE(ends_with(L"abc", L"abc"));
// bigger "needle" than "haystack"
ASSERT_FALSE(ends_with("bc", "abc"));
ASSERT_FALSE(ends_with(L"bc", L"abc"));
ASSERT_FALSE(ends_with("bc", "def"));
ASSERT_FALSE(ends_with(L"bc", L"def"));
}
} // namespace blaze_util