From cd267b3320501b33f3e7954ca456296fff16981c Mon Sep 17 00:00:00 2001 From: Tom Golden Date: Thu, 4 Feb 2021 23:12:43 -0500 Subject: [PATCH 1/6] Adds additional unit test that checks all characters considered 'whitespace' by java.lang.Character The Java regex character class \s is not consistent with Character.isWhitespace (presumably to mimic how older, non-unicode aware regular expressons worked?) This means that testing for blank strings with \s gives inconsistent results with String.isBlank, which delegates to the Character.isWhitespace implementations. This new test case demonstrates that inconsistency. --- .../org/hamcrest/text/IsBlankStringTest.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/hamcrest/src/test/java/org/hamcrest/text/IsBlankStringTest.java b/hamcrest/src/test/java/org/hamcrest/text/IsBlankStringTest.java index c5f35f1c..89d6072c 100644 --- a/hamcrest/src/test/java/org/hamcrest/text/IsBlankStringTest.java +++ b/hamcrest/src/test/java/org/hamcrest/text/IsBlankStringTest.java @@ -34,6 +34,28 @@ public final class IsBlankStringTest { assertMatches(blankString(), " \t"); assertMatches(blankOrNullString(), " \t"); } + + @Test public void + matchesAllCharactersConsideredWhitespaceByJavaLangCharacter() { + // See Javadocs for Character.isWhitespace + String[] consideredBlankByJavaLangCharacter = new String[] { + "\t", + "\n", + "\u000B", + "\f", + "\r", + "\u001C", + "\u001D", + "\u001E", + "\u001F" + }; + + for(String string : consideredBlankByJavaLangCharacter) { + assertTrue(string.isBlank()); + assertMatches(blankString(), string); + assertMatches(blankOrNullString(), string); + } + } @Test public void doesNotMatchFilledString() { @@ -52,4 +74,5 @@ public final class IsBlankStringTest { assertMismatchDescription("was \"a\"", blankString(), "a"); assertMismatchDescription("was \"a\"", blankOrNullString(), "a"); } + } From 6d5f972608004d2c9331f9e8d002db4bba89c093 Mon Sep 17 00:00:00 2001 From: Tom Golden Date: Thu, 4 Feb 2021 23:14:27 -0500 Subject: [PATCH 2/6] Changes IsBlank matcher to use String.isBlank The principal of least astonishment suggests that the matcher should be consistent with the similarly named string method. The isBlank method does a simple O(N) search through the codepoints of the string and bails out at the first non-whitespace character it finds, so I can't think of any negative performance implications here. The implementation continues to pass for all original test cases. --- hamcrest/src/main/java/org/hamcrest/text/IsBlankString.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/hamcrest/src/main/java/org/hamcrest/text/IsBlankString.java b/hamcrest/src/main/java/org/hamcrest/text/IsBlankString.java index b168541b..d30d0492 100644 --- a/hamcrest/src/main/java/org/hamcrest/text/IsBlankString.java +++ b/hamcrest/src/main/java/org/hamcrest/text/IsBlankString.java @@ -5,8 +5,6 @@ import org.hamcrest.Matcher; import org.hamcrest.TypeSafeMatcher; -import java.util.regex.Pattern; - import static org.hamcrest.core.AnyOf.anyOf; import static org.hamcrest.core.IsNull.nullValue; @@ -18,13 +16,11 @@ public final class IsBlankString extends TypeSafeMatcher { @SuppressWarnings("unchecked") private static final Matcher NULL_OR_BLANK_INSTANCE = anyOf(nullValue(), BLANK_INSTANCE); - private static final Pattern REGEX_WHITESPACE = Pattern.compile("\\s*"); - private IsBlankString() { } @Override public boolean matchesSafely(String item) { - return REGEX_WHITESPACE.matcher(item).matches(); + return item.isBlank(); } @Override From fbae71bd4bae30bb9a8bc900b25d425a57f117af Mon Sep 17 00:00:00 2001 From: Tom Golden Date: Thu, 4 Feb 2021 23:19:17 -0500 Subject: [PATCH 3/6] Fixes checkstyle violation; replaces tabs with spaces --- .../org/hamcrest/text/IsBlankStringTest.java | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/hamcrest/src/test/java/org/hamcrest/text/IsBlankStringTest.java b/hamcrest/src/test/java/org/hamcrest/text/IsBlankStringTest.java index 89d6072c..e18e784f 100644 --- a/hamcrest/src/test/java/org/hamcrest/text/IsBlankStringTest.java +++ b/hamcrest/src/test/java/org/hamcrest/text/IsBlankStringTest.java @@ -37,24 +37,24 @@ public final class IsBlankStringTest { @Test public void matchesAllCharactersConsideredWhitespaceByJavaLangCharacter() { - // See Javadocs for Character.isWhitespace - String[] consideredBlankByJavaLangCharacter = new String[] { - "\t", - "\n", - "\u000B", - "\f", - "\r", - "\u001C", - "\u001D", - "\u001E", - "\u001F" - }; - - for(String string : consideredBlankByJavaLangCharacter) { - assertTrue(string.isBlank()); - assertMatches(blankString(), string); - assertMatches(blankOrNullString(), string); - } + // See Javadocs for Character.isWhitespace + String[] consideredBlankByJavaLangCharacter = new String[] { + "\t", + "\n", + "\u000B", + "\f", + "\r", + "\u001C", + "\u001D", + "\u001E", + "\u001F" + }; + + for(String string : consideredBlankByJavaLangCharacter) { + assertTrue(string.isBlank()); + assertMatches(blankString(), string); + assertMatches(blankOrNullString(), string); + } } @Test public void From c802ff74217d906a40022dac16ef5ecd9b14d94c Mon Sep 17 00:00:00 2001 From: Tom Golden Date: Fri, 19 Feb 2021 15:15:32 -0500 Subject: [PATCH 4/6] Replaces isBlank implementation String#isBlank is a newer convenience method and not supported on all target platforms --- .../main/java/org/hamcrest/text/IsBlankString.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/hamcrest/src/main/java/org/hamcrest/text/IsBlankString.java b/hamcrest/src/main/java/org/hamcrest/text/IsBlankString.java index d30d0492..c1991d1d 100644 --- a/hamcrest/src/main/java/org/hamcrest/text/IsBlankString.java +++ b/hamcrest/src/main/java/org/hamcrest/text/IsBlankString.java @@ -20,7 +20,16 @@ private IsBlankString() { } @Override public boolean matchesSafely(String item) { - return item.isBlank(); + final int length = item.length(); + int offset = 0; + while(offset < length) { + final int codePoint = item.codePointAt(offset); + if(!Character.isWhitespace(codePoint)) { + return false; + } + offset += Character.charCount(codePoint); + } + return true; } @Override From 62e747dab967d4e222a427e4c9f3482bd674c734 Mon Sep 17 00:00:00 2001 From: Tom Golden Date: Fri, 19 Feb 2021 15:36:23 -0500 Subject: [PATCH 5/6] Removes unavailable #isBlank method from test --- hamcrest/src/test/java/org/hamcrest/text/IsBlankStringTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/hamcrest/src/test/java/org/hamcrest/text/IsBlankStringTest.java b/hamcrest/src/test/java/org/hamcrest/text/IsBlankStringTest.java index e18e784f..e2506dff 100644 --- a/hamcrest/src/test/java/org/hamcrest/text/IsBlankStringTest.java +++ b/hamcrest/src/test/java/org/hamcrest/text/IsBlankStringTest.java @@ -51,7 +51,6 @@ public final class IsBlankStringTest { }; for(String string : consideredBlankByJavaLangCharacter) { - assertTrue(string.isBlank()); assertMatches(blankString(), string); assertMatches(blankOrNullString(), string); } From 620bbbc264a46762e32a1951c7d816ed61f6c9f0 Mon Sep 17 00:00:00 2001 From: Tom Golden Date: Tue, 23 Feb 2021 14:27:45 -0500 Subject: [PATCH 6/6] Adds spaces to match style guide --- hamcrest/src/main/java/org/hamcrest/text/IsBlankString.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hamcrest/src/main/java/org/hamcrest/text/IsBlankString.java b/hamcrest/src/main/java/org/hamcrest/text/IsBlankString.java index c1991d1d..ae0991c0 100644 --- a/hamcrest/src/main/java/org/hamcrest/text/IsBlankString.java +++ b/hamcrest/src/main/java/org/hamcrest/text/IsBlankString.java @@ -22,9 +22,9 @@ private IsBlankString() { } public boolean matchesSafely(String item) { final int length = item.length(); int offset = 0; - while(offset < length) { + while (offset < length) { final int codePoint = item.codePointAt(offset); - if(!Character.isWhitespace(codePoint)) { + if (!Character.isWhitespace(codePoint)) { return false; } offset += Character.charCount(codePoint);