From 3a9c87d8db9a999bf9149116a9f71d9f4e25b2dd Mon Sep 17 00:00:00 2001 From: Nathan Young Date: Wed, 20 Mar 2024 18:14:48 -0400 Subject: [PATCH] BUG: StringUtilities::split-Add Additional Edge Case Checks(#893) --- src/simplnx/DataStructure/DataPath.cpp | 4 ++ src/simplnx/Utilities/StringUtilities.hpp | 10 ++++ test/StringUtilitiesTest.cpp | 63 +++++++++++++++++++++++ 3 files changed, 77 insertions(+) diff --git a/src/simplnx/DataStructure/DataPath.cpp b/src/simplnx/DataStructure/DataPath.cpp index bb54a60370..8854e71176 100644 --- a/src/simplnx/DataStructure/DataPath.cpp +++ b/src/simplnx/DataStructure/DataPath.cpp @@ -43,6 +43,10 @@ std::optional DataPath::FromString(std::string_view inputPath, char de { return DataPath{}; } + if(inputPath.size() == 1 && inputPath[0] == delimiter) + { + return DataPath{}; + } auto parts = StringUtilities::split(inputPath, delimiter); if(parts.empty()) { diff --git a/src/simplnx/Utilities/StringUtilities.hpp b/src/simplnx/Utilities/StringUtilities.hpp index c685b0f3aa..d8978ff84b 100644 --- a/src/simplnx/Utilities/StringUtilities.hpp +++ b/src/simplnx/Utilities/StringUtilities.hpp @@ -93,6 +93,10 @@ using SplitAllowEmptyRightAnalyze = SplitTypeOptions; template inline std::vector optimized_split(std::string_view str, nonstd::span delimiters) { + if(str.empty()) + { + return {}; + } auto endPos = str.end(); auto startPos = str.begin(); @@ -141,6 +145,12 @@ inline std::vector optimized_split(std::string_view str, nonstd::sp tokens.shrink_to_fit(); + // No Delimiters found + if(tokens.empty()) + { + tokens.emplace_back(str); + } + return tokens; } } // namespace diff --git a/test/StringUtilitiesTest.cpp b/test/StringUtilitiesTest.cpp index 6f2bde9764..3c950a0918 100644 --- a/test/StringUtilitiesTest.cpp +++ b/test/StringUtilitiesTest.cpp @@ -7,6 +7,69 @@ using namespace nx::core; +TEST_CASE("Empty Input Utility Function Test: split(str, char), split(str, char, bool), specific_split(str, char, StringUtilities::SplitType)") +{ + std::string emptyInput = ""; + std::string noDelimiterInput = "ThisIsABaselineTest"; + + std::vector result; + std::array k_Delimiter = {'|'}; + + // Case 1 + result = StringUtilities::split(emptyInput, k_Delimiter[0]); + + REQUIRE(result.empty()); + + result = StringUtilities::split(noDelimiterInput, k_Delimiter[0]); + + REQUIRE(result == std::vector{noDelimiterInput}); + + // Case 2 + result = StringUtilities::split(emptyInput, k_Delimiter, true); + + REQUIRE(result.empty()); + + result = StringUtilities::split(noDelimiterInput, k_Delimiter, true); + + REQUIRE(result == std::vector{noDelimiterInput}); + + // Case 4 + result = StringUtilities::specific_split(emptyInput, k_Delimiter, StringUtilities::SplitType::OnlyConsecutive); + + REQUIRE(result.empty()); + + result = StringUtilities::specific_split(noDelimiterInput, k_Delimiter, StringUtilities::SplitType::OnlyConsecutive); + + REQUIRE(result == std::vector{noDelimiterInput}); + + // Case 5 + result = StringUtilities::specific_split(emptyInput, k_Delimiter, StringUtilities::SplitType::NoStripIgnoreConsecutive); + + REQUIRE(result.empty()); + + result = StringUtilities::specific_split(noDelimiterInput, k_Delimiter, StringUtilities::SplitType::NoStripIgnoreConsecutive); + + REQUIRE(result == std::vector{noDelimiterInput}); + + // Case 6 + result = StringUtilities::specific_split(emptyInput, k_Delimiter, StringUtilities::SplitType::AllowEmptyLeftAnalyze); + + REQUIRE(result.empty()); + + result = StringUtilities::specific_split(noDelimiterInput, k_Delimiter, StringUtilities::SplitType::AllowEmptyLeftAnalyze); + + REQUIRE(result == std::vector{noDelimiterInput}); + + // Case 7 + result = StringUtilities::specific_split(emptyInput, k_Delimiter, StringUtilities::SplitType::AllowEmptyRightAnalyze); + + REQUIRE(result.empty()); + + result = StringUtilities::specific_split(noDelimiterInput, k_Delimiter, StringUtilities::SplitType::AllowEmptyRightAnalyze); + + REQUIRE(result == std::vector{noDelimiterInput}); +} + TEST_CASE("Utility Function Test: split(str, char)") { // Case 1