diff --git a/src/libutil-tests/strings.cc b/src/libutil-tests/strings.cc index bf1f66025..bd740ce0c 100644 --- a/src/libutil-tests/strings.cc +++ b/src/libutil-tests/strings.cc @@ -2,6 +2,7 @@ #include #include "nix/util/strings.hh" +#include "nix/util/strings-inline.hh" #include "nix/util/error.hh" namespace nix { @@ -271,113 +272,122 @@ TEST(tokenizeString, tokenizeSepEmpty) * splitString * --------------------------------------------------------------------------*/ -TEST(splitString, empty) -{ - Strings expected = {""}; +using SplitStringTestContainerTypes = ::testing:: + Types, std::vector, std::list, std::list>; - ASSERT_EQ(splitString("", " \t\n\r"), expected); +template +class splitStringTest : public ::testing::Test +{}; + +TYPED_TEST_SUITE(splitStringTest, SplitStringTestContainerTypes); + +TYPED_TEST(splitStringTest, empty) +{ + TypeParam expected = {""}; + + EXPECT_EQ(splitString("", " \t\n\r"), expected); } -TEST(splitString, oneSep) +TYPED_TEST(splitStringTest, oneSep) { - Strings expected = {"", ""}; + TypeParam expected = {"", ""}; - ASSERT_EQ(splitString(" ", " \t\n\r"), expected); + EXPECT_EQ(splitString(" ", " \t\n\r"), expected); } -TEST(splitString, twoSep) +TYPED_TEST(splitStringTest, twoSep) { - Strings expected = {"", "", ""}; + TypeParam expected = {"", "", ""}; - ASSERT_EQ(splitString(" \n", " \t\n\r"), expected); + EXPECT_EQ(splitString(" \n", " \t\n\r"), expected); } -TEST(splitString, tokenizeSpacesWithSpaces) +TYPED_TEST(splitStringTest, tokenizeSpacesWithSpaces) { auto s = "foo bar baz"; - Strings expected = {"foo", "bar", "baz"}; + TypeParam expected = {"foo", "bar", "baz"}; - ASSERT_EQ(splitString(s, " \t\n\r"), expected); + EXPECT_EQ(splitString(s, " \t\n\r"), expected); } -TEST(splitString, tokenizeTabsWithDefaults) +TYPED_TEST(splitStringTest, tokenizeTabsWithDefaults) { auto s = "foo\tbar\tbaz"; // Using it like this is weird, but shows the difference with tokenizeString, which also has this test - Strings expected = {"foo", "bar", "baz"}; + TypeParam expected = {"foo", "bar", "baz"}; - ASSERT_EQ(splitString(s, " \t\n\r"), expected); + EXPECT_EQ(splitString(s, " \t\n\r"), expected); } -TEST(splitString, tokenizeTabsSpacesWithDefaults) +TYPED_TEST(splitStringTest, tokenizeTabsSpacesWithDefaults) { auto s = "foo\t bar\t baz"; // Using it like this is weird, but shows the difference with tokenizeString, which also has this test - Strings expected = {"foo", "", "bar", "", "baz"}; + TypeParam expected = {"foo", "", "bar", "", "baz"}; - ASSERT_EQ(splitString(s, " \t\n\r"), expected); + EXPECT_EQ(splitString(s, " \t\n\r"), expected); } -TEST(splitString, tokenizeTabsSpacesNewlineWithDefaults) +TYPED_TEST(splitStringTest, tokenizeTabsSpacesNewlineWithDefaults) { auto s = "foo\t\n bar\t\n baz"; // Using it like this is weird, but shows the difference with tokenizeString, which also has this test - Strings expected = {"foo", "", "", "bar", "", "", "baz"}; + TypeParam expected = {"foo", "", "", "bar", "", "", "baz"}; - ASSERT_EQ(splitString(s, " \t\n\r"), expected); + EXPECT_EQ(splitString(s, " \t\n\r"), expected); } -TEST(splitString, tokenizeTabsSpacesNewlineRetWithDefaults) +TYPED_TEST(splitStringTest, tokenizeTabsSpacesNewlineRetWithDefaults) { auto s = "foo\t\n\r bar\t\n\r baz"; // Using it like this is weird, but shows the difference with tokenizeString, which also has this test - Strings expected = {"foo", "", "", "", "bar", "", "", "", "baz"}; + TypeParam expected = {"foo", "", "", "", "bar", "", "", "", "baz"}; - ASSERT_EQ(splitString(s, " \t\n\r"), expected); + EXPECT_EQ(splitString(s, " \t\n\r"), expected); auto s2 = "foo \t\n\r bar \t\n\r baz"; - Strings expected2 = {"foo", "", "", "", "", "bar", "", "", "", "", "baz"}; + TypeParam expected2 = {"foo", "", "", "", "", "bar", "", "", "", "", "baz"}; - ASSERT_EQ(splitString(s2, " \t\n\r"), expected2); + EXPECT_EQ(splitString(s2, " \t\n\r"), expected2); } -TEST(splitString, tokenizeWithCustomSep) +TYPED_TEST(splitStringTest, tokenizeWithCustomSep) { auto s = "foo\n,bar\n,baz\n"; - Strings expected = {"foo\n", "bar\n", "baz\n"}; + TypeParam expected = {"foo\n", "bar\n", "baz\n"}; - ASSERT_EQ(splitString(s, ","), expected); + EXPECT_EQ(splitString(s, ","), expected); } -TEST(splitString, tokenizeSepAtStart) +TYPED_TEST(splitStringTest, tokenizeSepAtStart) { auto s = ",foo,bar,baz"; - Strings expected = {"", "foo", "bar", "baz"}; + TypeParam expected = {"", "foo", "bar", "baz"}; - ASSERT_EQ(splitString(s, ","), expected); + EXPECT_EQ(splitString(s, ","), expected); } -TEST(splitString, tokenizeSepAtEnd) +TYPED_TEST(splitStringTest, tokenizeSepAtEnd) { auto s = "foo,bar,baz,"; - Strings expected = {"foo", "bar", "baz", ""}; + TypeParam expected = {"foo", "bar", "baz", ""}; - ASSERT_EQ(splitString(s, ","), expected); + EXPECT_EQ(splitString(s, ","), expected); } -TEST(splitString, tokenizeSepEmpty) +TYPED_TEST(splitStringTest, tokenizeSepEmpty) { auto s = "foo,,baz"; - Strings expected = {"foo", "", "baz"}; + TypeParam expected = {"foo", "", "baz"}; - ASSERT_EQ(splitString(s, ","), expected); + EXPECT_EQ(splitString(s, ","), expected); } // concatStringsSep sep . splitString sep = id if sep is 1 char -RC_GTEST_PROP(splitString, recoveredByConcatStringsSep, (const std::string & s)) +RC_GTEST_TYPED_FIXTURE_PROP(splitStringTest, recoveredByConcatStringsSep, (const std::string & s)) { - RC_ASSERT(concatStringsSep("/", splitString(s, "/")) == s); - RC_ASSERT(concatStringsSep("a", splitString(s, "a")) == s); + RC_ASSERT(concatStringsSep("/", splitString(s, "/")) == s); + RC_ASSERT(concatStringsSep("a", splitString(s, "a")) == s); } /* ---------------------------------------------------------------------------- diff --git a/src/libutil/include/nix/util/strings-inline.hh b/src/libutil/include/nix/util/strings-inline.hh index d99b686fc..61bddfeda 100644 --- a/src/libutil/include/nix/util/strings-inline.hh +++ b/src/libutil/include/nix/util/strings-inline.hh @@ -26,18 +26,29 @@ C tokenizeString(std::string_view s, std::string_view separators) } template -C basicSplitString(std::basic_string_view s, std::basic_string_view separators) +void basicSplitStringInto(C & accum, std::basic_string_view s, std::basic_string_view separators) { - C result; size_t pos = 0; while (pos <= s.size()) { auto end = s.find_first_of(separators, pos); if (end == s.npos) end = s.size(); - result.insert(result.end(), std::basic_string(s, pos, end - pos)); + accum.insert(accum.end(), typename C::value_type{s.substr(pos, end - pos)}); pos = end + 1; } +} +template +void splitStringInto(C & accum, std::string_view s, std::string_view separators) +{ + basicSplitStringInto(accum, s, separators); +} + +template +C basicSplitString(std::basic_string_view s, std::basic_string_view separators) +{ + C result; + basicSplitStringInto(result, s, separators); return result; }