+TEST(String, whitespace) {
+ // trimWhitespace:
+ EXPECT_EQ("kavabanga",
+ trimWhitespace("kavabanga"));
+ EXPECT_EQ("kavabanga",
+ trimWhitespace("kavabanga \t \n "));
+ EXPECT_EQ("kavabanga",
+ trimWhitespace(" \t \r \n \n kavabanga"));
+ EXPECT_EQ("kavabanga",
+ trimWhitespace("\t \r \n kavabanga \t \n "));
+ EXPECT_EQ("kavabanga",
+ trimWhitespace(" \t \r \n \n kavabanga"));
+ EXPECT_EQ("kavabanga",
+ trimWhitespace("\t \r \n kavabanga \t \n "));
+ EXPECT_EQ(
+ ltrimWhitespace(rtrimWhitespace("kavabanga")),
+ rtrimWhitespace(ltrimWhitespace("kavabanga")));
+ EXPECT_EQ(
+ ltrimWhitespace(rtrimWhitespace("kavabanga \r\t\n")),
+ rtrimWhitespace(ltrimWhitespace("kavabanga \r\t\n")));
+ EXPECT_EQ("", trimWhitespace("\t \r \n \t \n "));
+ EXPECT_EQ("", trimWhitespace(""));
+ EXPECT_EQ("", trimWhitespace("\t"));
+ EXPECT_EQ("", trimWhitespace("\r"));
+ EXPECT_EQ("", trimWhitespace("\n"));
+ EXPECT_EQ("", trimWhitespace("\t "));
+ EXPECT_EQ("", trimWhitespace("\r "));
+ EXPECT_EQ("", trimWhitespace("\n "));
+ EXPECT_EQ("", trimWhitespace(" \t"));
+ EXPECT_EQ("", trimWhitespace(" \r"));
+ EXPECT_EQ("", trimWhitespace(" \n"));
+
+ // ltrimWhitespace:
+ EXPECT_EQ("kavabanga", ltrimWhitespace("\t kavabanga"));
+ EXPECT_EQ("kavabanga \r\n", ltrimWhitespace("\t kavabanga \r\n"));
+ EXPECT_EQ("", ltrimWhitespace("\r "));
+ EXPECT_EQ("", ltrimWhitespace("\n "));
+ EXPECT_EQ("", ltrimWhitespace("\r "));
+
+ // rtrimWhitespace:
+ EXPECT_EQ("\t kavabanga", rtrimWhitespace("\t kavabanga"));
+ EXPECT_EQ("\t kavabanga", rtrimWhitespace("\t kavabanga \r\n"));
+ EXPECT_EQ("", rtrimWhitespace("\r "));
+ EXPECT_EQ("", rtrimWhitespace("\n "));
+ EXPECT_EQ("", rtrimWhitespace("\r "));
+}
+
+TEST(String, stripLeftMargin_really_empty) {
+ auto input = "";
+ auto expected = "";
+ EXPECT_EQ(expected, stripLeftMargin(input));
+}
+
+TEST(String, stripLeftMargin_empty) {
+ auto input = R"TEXT(
+ )TEXT";
+ auto expected = "";
+ EXPECT_EQ(expected, stripLeftMargin(input));
+}
+
+TEST(String, stripLeftMargin_only_whitespace) {
+ // using ~ as a marker
+ string input = R"TEXT(
+ ~
+ )TEXT";
+ input = boost::regex_replace(input, boost::regex("~"), "");
+ EXPECT_EQ("\n \n ", input);
+ auto expected = "\n";
+ EXPECT_EQ(expected, stripLeftMargin(input));
+}
+
+TEST(String, stripLeftMargin_only_uneven_whitespace) {
+ // using ~ as a marker1
+ string input = R"TEXT(
+ ~
+ ~
+ )TEXT";
+ input = boost::regex_replace(input, boost::regex("~"), "");
+ EXPECT_EQ("\n \n \n ", input);
+ auto expected = "\n\n";
+
+ EXPECT_EQ(expected, stripLeftMargin(input));
+}
+
+TEST(String, stripLeftMargin_one_line) {
+ auto input = R"TEXT(
+ hi there bob!
+ )TEXT";
+ auto expected = "hi there bob!\n";
+ EXPECT_EQ(expected, stripLeftMargin(input));
+}
+
+TEST(String, stripLeftMargin_two_lines) {
+ auto input = R"TEXT(
+ hi there bob!
+ nice weather today!
+ )TEXT";
+ auto expected = "hi there bob!\nnice weather today!\n";
+ EXPECT_EQ(expected, stripLeftMargin(input));
+}
+
+TEST(String, stripLeftMargin_three_lines_uneven) {
+ auto input = R"TEXT(
+ hi there bob!
+ nice weather today!
+ so long!
+ )TEXT";
+ auto expected = " hi there bob!\nnice weather today!\n so long!\n";
+ EXPECT_EQ(expected, stripLeftMargin(input));
+}
+
+TEST(String, stripLeftMargin_preceding_blank_lines) {
+ auto input = R"TEXT(
+
+
+ hi there bob!
+ )TEXT";
+ auto expected = "\n\nhi there bob!\n";
+ EXPECT_EQ(expected, stripLeftMargin(input));
+}
+
+TEST(String, stripLeftMargin_succeeding_blank_lines) {
+ auto input = R"TEXT(
+ hi there bob!
+
+
+ )TEXT";
+ auto expected = "hi there bob!\n\n\n";
+ EXPECT_EQ(expected, stripLeftMargin(input));
+}
+
+TEST(String, stripLeftMargin_interstitial_undented_whiteline) {
+ // using ~ as a marker
+ string input = R"TEXT(
+ hi there bob!
+ ~
+ so long!
+ )TEXT";
+ input = boost::regex_replace(input, boost::regex(" +~"), "");
+ EXPECT_EQ("\n hi there bob!\n\n so long!\n ", input);
+ auto expected = "hi there bob!\n\nso long!\n";
+ EXPECT_EQ(expected, stripLeftMargin(input));
+}
+
+TEST(String, stripLeftMargin_interstitial_dedented_whiteline) {
+ // using ~ as a marker
+ string input = R"TEXT(
+ hi there bob!
+ ~
+ so long!
+ )TEXT";
+ input = boost::regex_replace(input, boost::regex("~"), "");
+ EXPECT_EQ("\n hi there bob!\n \n so long!\n ", input);
+ auto expected = "hi there bob!\n\nso long!\n";
+ EXPECT_EQ(expected, stripLeftMargin(input));
+}
+
+TEST(String, stripLeftMargin_interstitial_equidented_whiteline) {
+ // using ~ as a marker
+ string input = R"TEXT(
+ hi there bob!
+ ~
+ so long!
+ )TEXT";
+ input = boost::regex_replace(input, boost::regex("~"), "");
+ EXPECT_EQ("\n hi there bob!\n \n so long!\n ", input);
+ auto expected = "hi there bob!\n\nso long!\n";
+ EXPECT_EQ(expected, stripLeftMargin(input));
+}
+
+TEST(String, stripLeftMargin_interstitial_indented_whiteline) {
+ // using ~ as a marker
+ string input = R"TEXT(
+ hi there bob!
+ ~
+ so long!
+ )TEXT";
+ input = boost::regex_replace(input, boost::regex("~"), "");
+ EXPECT_EQ("\n hi there bob!\n \n so long!\n ", input);
+ auto expected = "hi there bob!\n \nso long!\n";
+ EXPECT_EQ(expected, stripLeftMargin(input));
+}
+
+TEST(String, stripLeftMargin_no_pre_whitespace) {
+ // using ~ as a marker
+ string input = R"TEXT( hi there bob!
+ ~
+ so long!
+ )TEXT";
+ input = boost::regex_replace(input, boost::regex("~"), "");
+ EXPECT_EQ(" hi there bob!\n \n so long!\n ", input);
+ auto expected = "hi there bob!\n \nso long!\n";
+ EXPECT_EQ(expected, stripLeftMargin(input));
+}
+
+TEST(String, stripLeftMargin_no_post_whitespace) {
+ // using ~ as a marker
+ string input = R"TEXT(
+ hi there bob!
+ ~
+ so long! )TEXT";
+ input = boost::regex_replace(input, boost::regex("~"), "");
+ EXPECT_EQ("\n hi there bob!\n \n so long! ", input);
+ auto expected = "hi there bob!\n \nso long! ";
+ EXPECT_EQ(expected, stripLeftMargin(input));
+}
+
+const folly::StringPiece kTestUTF8 = u8"This is \U0001F602 stuff!";
+
+TEST(UTF8StringPiece, valid_utf8) {
+ folly::StringPiece sp = kTestUTF8;
+ UTF8StringPiece utf8 = sp;
+ // utf8.size() not available since it's not a random-access range
+ EXPECT_EQ(16, utf8.walk_size());
+}
+
+TEST(UTF8StringPiece, valid_suffix) {
+ UTF8StringPiece utf8 = kTestUTF8.subpiece(8);
+ EXPECT_EQ(8, utf8.walk_size());
+}
+
+TEST(UTF8StringPiece, empty_mid_codepoint) {
+ UTF8StringPiece utf8 = kTestUTF8.subpiece(9, 0); // okay since it's empty
+ EXPECT_EQ(0, utf8.walk_size());
+}
+
+TEST(UTF8StringPiece, invalid_mid_codepoint) {
+ EXPECT_THROW(UTF8StringPiece(kTestUTF8.subpiece(9, 1)), std::out_of_range);
+}
+
+TEST(UTF8StringPiece, valid_implicit_conversion) {
+ std::string input = u8"\U0001F602\U0001F602\U0001F602";
+ auto checkImplicitCtor = [](UTF8StringPiece implicitCtor) {
+ return implicitCtor.walk_size();
+ };
+ EXPECT_EQ(3, checkImplicitCtor(input));
+}