From 8d0188da42244d3d9f23965a03af823247ab2794 Mon Sep 17 00:00:00 2001 From: ghost Date: Thu, 7 Nov 2024 14:34:12 +0100 Subject: [PATCH] [LANG-1540] - added StringUtils.startsAndEndsWith and StringUtils.startsAndEndsWithIgnoreCase --- .../org/apache/commons/lang3/StringUtils.java | 70 ++++++++++ .../apache/commons/lang3/StringUtilsTest.java | 124 ++++++++++++++++++ 2 files changed, 194 insertions(+) diff --git a/src/main/java/org/apache/commons/lang3/StringUtils.java b/src/main/java/org/apache/commons/lang3/StringUtils.java index 70c26ee315b..0ab087dd119 100644 --- a/src/main/java/org/apache/commons/lang3/StringUtils.java +++ b/src/main/java/org/apache/commons/lang3/StringUtils.java @@ -189,6 +189,17 @@ public class StringUtils { */ private static final Pattern STRIP_ACCENTS_PATTERN = Pattern.compile("\\p{InCombiningDiacriticalMarks}+"); //$NON-NLS-1$ + /** + * Exception message used when {@link #startsAndEndsWith(String, String)} or {@link #startsAndEndsWithIgnoreCase(String, String)} are passed null. + */ + private static final String NULL_ARGUMENTS_PASSED_EXCEPTION_MESSAGE_STRING_TO_TEST = "The method was expecting the stringToTest passed to have a value but was passed null or empty instead."; + + + /** + * Exception message used when {@link #startsAndEndsWith(String, String)} or {@link #startsAndEndsWithIgnoreCase(String, String)} are passed null. + */ + private static final String NULL_ARGUMENTS_PASSED_EXCEPTION_MESSAGE_STARTS_AND_ENDS_WITH = "The method was expecting the startAndEndsWith argument passed to have a value but was passed null or empty instead."; + /** * Abbreviates a String using ellipses. This will turn * "Now is the time for all good men" into "Now is the time for..." @@ -9347,4 +9358,63 @@ public StringUtils() { // empty } + /** + * The method will check if the beginning and ending of the text to be tested against matches + *

+ * e.g. + * stringToTest = "Five workers went to work at 9 and left at Five" + * startsAndEndsWith = "Five" + *

+ * result will be true since the stringToTest begins with "Five" and ends with "Five" + *

+ * NOTE: + * This is case-sensitive! + * + * @param stringToTest This is the subject string or text that you want to check. + * @param startsAndEndsWith This is the string that you want to check if it exists at the beginning and end of the text or paragraph. + * @return true if the text begins and ends with the string or false if it doesn't. + * @throws IllegalArgumentException if any argument passed is null or empty + */ + public static boolean startsAndEndsWith(CharSequence stringToTest, CharSequence startsAndEndsWith) { + if (stringToTest == null || stringToTest.length() == 0) { + throw new IllegalArgumentException(NULL_ARGUMENTS_PASSED_EXCEPTION_MESSAGE_STRING_TO_TEST); + } + + if (startsAndEndsWith == null || startsAndEndsWith.length() == 0) { + throw new IllegalArgumentException(NULL_ARGUMENTS_PASSED_EXCEPTION_MESSAGE_STARTS_AND_ENDS_WITH); + } + + + return stringToTest.toString().startsWith(startsAndEndsWith.toString()) && stringToTest.toString().endsWith(startsAndEndsWith.toString()); + } + + /** + * The method will check if the beginning and ending of the text to be tested against matches + *

+ * e.g. + * stringToTest = "Five workers went to work at 9 and left at five" + * startsAndEndsWith = "five" + *

+ * result will be true since the stringToTest begins with "Five" and ends with "five" and case is ignored + * + * @param stringToTest This is the subject string or text that you want to check. + * @param startsAndEndsWith This is the string that you want to check if it exists at the beginning and end of the text or paragraph. + * @return true if the text begins and ends with the string or false if it doesn't. + * @throws IllegalArgumentException if any argument passed is null or empty + */ + public static boolean startsAndEndsWithIgnoreCase(CharSequence stringToTest, CharSequence startsAndEndsWith) { + if (stringToTest == null || stringToTest.length() == 0) { + throw new IllegalArgumentException(NULL_ARGUMENTS_PASSED_EXCEPTION_MESSAGE_STRING_TO_TEST); + } + + if (startsAndEndsWith == null || startsAndEndsWith.length() == 0) { + throw new IllegalArgumentException(NULL_ARGUMENTS_PASSED_EXCEPTION_MESSAGE_STARTS_AND_ENDS_WITH); + } + + String normalizedStringToTest = stringToTest.toString().toLowerCase(); + String normalizedStartsAndEndsWith = startsAndEndsWith.toString().toLowerCase(); + + return normalizedStringToTest.startsWith(normalizedStartsAndEndsWith) && normalizedStringToTest.endsWith(normalizedStartsAndEndsWith); + } + } diff --git a/src/test/java/org/apache/commons/lang3/StringUtilsTest.java b/src/test/java/org/apache/commons/lang3/StringUtilsTest.java index d6e436e94cb..820b9ce51e5 100644 --- a/src/test/java/org/apache/commons/lang3/StringUtilsTest.java +++ b/src/test/java/org/apache/commons/lang3/StringUtilsTest.java @@ -16,6 +16,8 @@ */ package org.apache.commons.lang3; +import static org.apache.commons.lang3.StringUtils.startsAndEndsWith; +import static org.apache.commons.lang3.StringUtils.startsAndEndsWithIgnoreCase; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.lessThanOrEqualTo; import static org.junit.jupiter.api.Assertions.assertArrayEquals; @@ -26,6 +28,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertThrowsExactly; import static org.junit.jupiter.api.Assertions.assertTrue; import java.io.UnsupportedEncodingException; @@ -3431,4 +3434,125 @@ public void testWrapIfMissing_StringString() { assertSame("ab/ab", StringUtils.wrapIfMissing("ab/ab", "ab")); assertSame("//x//", StringUtils.wrapIfMissing("//x//", "//")); } + + @Test + public void testStartsAndEndsPassesWithCaseSensitiveText() { + String stringToTest = "Five dears were jumping in caves at Five"; + String beginsWithAndEndsWith = "Five"; + + assertTrue(startsAndEndsWith(stringToTest, beginsWithAndEndsWith), "the method returned false but expected was true since the beginning and end matches."); + } + + @Test + public void testStartsAndEndsFailsWithCaseSensitiveEnd() { + String stringToTest = "Five dears were jumping in caves at five"; + String beginsWithAndEndsWith = "Five"; + + assertFalse(startsAndEndsWith(stringToTest, beginsWithAndEndsWith), "the method returned true but expected was false since the beginning and end case don't match."); + + stringToTest = "Five dears were jumping in caves at the fire"; + assertFalse(startsAndEndsWith(stringToTest, beginsWithAndEndsWith), "the method returned true but expected was false since the beginning and end don't matche."); + + } + + @Test + public void testStartsAndEndsFailsWithCaseSensitiveStart() { + String stringToTest = "Fire dears were jumping in caves at Five"; + String beginsWithAndEndsWith = "Five"; + + assertFalse(startsAndEndsWith(stringToTest, beginsWithAndEndsWith), "the method returned true but expected was false since the beginning and end case don't match."); + + stringToTest = "Five dears were jumping in caves at the fire"; + assertFalse(startsAndEndsWith(stringToTest, beginsWithAndEndsWith), "the method returned true but expected was false since the beginning and end don't matche."); + + } + + @Test + public void testStartsAndEndsThrowsIllegalArgumentExceptionWhenPassedNull() { + final String stringToTestNull = null; + final String beginsWithAndEndsWith = "Five"; + + assertThrowsExactly(IllegalArgumentException.class, () -> startsAndEndsWith(stringToTestNull, beginsWithAndEndsWith), "Was supposed to throw IllegalArgumentException when passed stringToTest as null but returned value instead."); + + final String stringToTestNotNull = "Five dears were jumping in caves at Five"; + final String beginsWithAndEndsWithNull = null; + + assertThrowsExactly(IllegalArgumentException.class, () -> startsAndEndsWith(stringToTestNotNull, beginsWithAndEndsWithNull), "Was supposed to throw IllegalArgumentException when passed startsAndEndsWith string as null but returned value instead."); + + assertThrowsExactly(IllegalArgumentException.class, () -> startsAndEndsWith(stringToTestNull, beginsWithAndEndsWithNull), "Was supposed to throw IllegalArgumentException when passed null arguments but returned value instead."); + + } + + @Test + public void testStartsAndEndsThrowsIllegalArgumentExceptionWhenPassedEmptyStrings() { + final String stringToTestNull = ""; + final String beginsWithAndEndsWith = "Five"; + + assertThrowsExactly(IllegalArgumentException.class, () -> startsAndEndsWith(stringToTestNull, beginsWithAndEndsWith), "Was supposed to throw IllegalArgumentException when passed stringToTest as empty string but returned value instead."); + + final String stringToTestNotNull = "Five dears were jumping in caves at Five"; + final String beginsWithAndEndsWithNull = ""; + + assertThrowsExactly(IllegalArgumentException.class, () -> startsAndEndsWith(stringToTestNotNull, beginsWithAndEndsWithNull), "Was supposed to throw IllegalArgumentException when passed startsAndEndsWith string as empty string but returned value instead."); + + assertThrowsExactly(IllegalArgumentException.class, () -> startsAndEndsWith(stringToTestNull, beginsWithAndEndsWithNull), "Was supposed to throw IllegalArgumentException when passed empty string arguments but returned value instead."); + + } + + @Test + public void testStartsAndEndsWithIgnoreCasePasses() { + String stringToTest = "Five dears were jumping in caves at five"; + String beginsWithAndEndsWith = "Five"; + + assertTrue(startsAndEndsWithIgnoreCase(stringToTest, beginsWithAndEndsWith), "the method returned false but expected was true since the beginning and end matches with ignored case."); + } + + @Test + public void testStartsAndEndsWithIgnoreCaseFailsWithWrongEnd() { + String stringToTest = "Five dears were jumping in caves at fire"; + String beginsWithAndEndsWith = "Five"; + + assertFalse(startsAndEndsWithIgnoreCase(stringToTest, beginsWithAndEndsWith), "the method returned true but expected was false since the beginning and end don't matche."); + } + + @Test + public void testStartsAndEndsWithIgnoreCaseFailsWithWrongBeginning() { + String stringToTest = "fight dears were jumping in caves at five"; + String beginsWithAndEndsWith = "Five"; + + assertFalse(startsAndEndsWithIgnoreCase(stringToTest, beginsWithAndEndsWith), "the method returned true but expected was false since the beginning and end don't matche."); + } + + @Test + public void testStartsAndEndsIgnoreCaseThrowsIllegalArgumentExceptionWhenPassedNull() { + final String stringToTestNull = null; + final String beginsWithAndEndsWith = "Five"; + + assertThrowsExactly(IllegalArgumentException.class, () -> startsAndEndsWithIgnoreCase(stringToTestNull, beginsWithAndEndsWith), "Was supposed to throw IllegalArgumentException when passed stringToTest as null but returned value instead."); + + final String stringToTestNotNull = "Five dears were jumping in caves at Five"; + final String beginsWithAndEndsWithNull = null; + + assertThrowsExactly(IllegalArgumentException.class, () -> startsAndEndsWithIgnoreCase(stringToTestNotNull, beginsWithAndEndsWithNull), "Was supposed to throw IllegalArgumentException when passed startsAndEndsWith string as null but returned value instead."); + + assertThrowsExactly(IllegalArgumentException.class, () -> startsAndEndsWithIgnoreCase(stringToTestNull, beginsWithAndEndsWithNull), "Was supposed to throw IllegalArgumentException when passed null arguments but returned value instead."); + + } + + @Test + public void testStartsAndEndsIgnoreCaseThrowsIllegalArgumentExceptionWhenPassedEmptyStrings() { + final String stringToTestNull = ""; + final String beginsWithAndEndsWith = "Five"; + + assertThrowsExactly(IllegalArgumentException.class, () -> startsAndEndsWithIgnoreCase(stringToTestNull, beginsWithAndEndsWith), "Was supposed to throw IllegalArgumentException when passed stringToTest as empty string but returned value instead."); + + final String stringToTestNotNull = "Five dears were jumping in caves at Five"; + final String beginsWithAndEndsWithNull = ""; + + assertThrowsExactly(IllegalArgumentException.class, () -> startsAndEndsWithIgnoreCase(stringToTestNotNull, beginsWithAndEndsWithNull), "Was supposed to throw IllegalArgumentException when passed startsAndEndsWith string as empty string but returned value instead."); + + assertThrowsExactly(IllegalArgumentException.class, () -> startsAndEndsWithIgnoreCase(stringToTestNull, beginsWithAndEndsWithNull), "Was supposed to throw IllegalArgumentException when passed empty string arguments but returned value instead."); + + } + }