diff --git a/common/src/main/java/com/highgo/cloud/util/toolkit/StringUtil.java b/common/src/main/java/com/highgo/cloud/util/toolkit/StringUtil.java index 9398671..0bcc35d 100644 --- a/common/src/main/java/com/highgo/cloud/util/toolkit/StringUtil.java +++ b/common/src/main/java/com/highgo/cloud/util/toolkit/StringUtil.java @@ -834,7 +834,7 @@ public static int lastIndexOf(final CharSequence str, final CharSequence searchS return str.toString().lastIndexOf(searchStr.toString(), fromIndex); } - for (int i = fromIndex; i > 0; i--) { + for (int i = fromIndex; i >= 0; i--) { if (isSubEquals(str, i, searchStr, 0, searchStr.length(), true)) { return i; } @@ -969,7 +969,7 @@ public static boolean equals(CharSequence str1, CharSequence str2, boolean ignor if (ignoreCase) { return str1.toString().equalsIgnoreCase(str2.toString()); } else { - return str1.equals(str2); + return str1.toString().equals(str2.toString()); } } diff --git a/tests/StringUtilCharSequenceEqualsRegression.java b/tests/StringUtilCharSequenceEqualsRegression.java new file mode 100644 index 0000000..6f9182d --- /dev/null +++ b/tests/StringUtilCharSequenceEqualsRegression.java @@ -0,0 +1,47 @@ +import com.highgo.cloud.util.toolkit.StringUtil; + +/** Exercises the complete production class and its real Spring superclass. */ +public final class StringUtilCharSequenceEqualsRegression { + private static int failures; + + private static void check(String name, boolean expected, boolean actual) { + if (expected != actual) { + failures++; + System.err.println("FAIL " + name + ": expected " + expected + " but was " + actual); + } else { + System.out.println("PASS " + name); + } + } + + public static void main(String[] args) { + check("distinct-builders-two-argument", true, + StringUtil.equals(new StringBuilder("same"), new StringBuilder("same"))); + check("distinct-buffers-explicit-false", true, + StringUtil.equals(new StringBuffer("same"), new StringBuffer("same"), false)); + check("string-to-builder", true, + StringUtil.equals("same", new StringBuilder("same"))); + check("builder-to-string", true, + StringUtil.equals(new StringBuilder("same"), "same")); + check("buffer-to-builder", true, + StringUtil.equals(new StringBuffer("same"), new StringBuilder("same"), false)); + check("builder-to-buffer", true, + StringUtil.equals(new StringBuilder("same"), new StringBuffer("same"), false)); + + check("string-value-control", true, + StringUtil.equals(new String("same"), new String("same"))); + check("unequal-content-control", false, + StringUtil.equals(new StringBuilder("left"), new StringBuffer("right"))); + check("case-sensitive-control", false, + StringUtil.equals(new StringBuilder("Same"), new StringBuffer("same"), false)); + check("ignore-case-control", true, + StringUtil.equalsIgnoreCase(new StringBuilder("Same"), new StringBuffer("same"))); + StringBuilder shared = new StringBuilder("same"); + check("same-instance-control", true, StringUtil.equals(shared, shared)); + check("both-null-control", true, StringUtil.equals(null, null)); + check("left-null-control", false, StringUtil.equals(null, new StringBuilder("same"))); + check("right-null-control", false, StringUtil.equals(new StringBuffer("same"), null, false)); + if (failures != 0) { + throw new AssertionError(failures + " CharSequence equality cases failed"); + } + } +} diff --git a/tests/StringUtilReverseSearchRegression.java b/tests/StringUtilReverseSearchRegression.java new file mode 100644 index 0000000..edda37b --- /dev/null +++ b/tests/StringUtilReverseSearchRegression.java @@ -0,0 +1,40 @@ +import com.highgo.cloud.util.toolkit.StringUtil; + +/** JDK assertion runner; the complete production class uses real Spring Core. */ +public final class StringUtilReverseSearchRegression { + private static int failures; + + private static void check(String name, int expected, int actual) { + if (expected != actual) { + failures++; + System.err.println("FAIL " + name + ": expected " + expected + " but was " + actual); + } else { + System.out.println("PASS " + name); + } + } + + public static void main(String[] args) { + check("two-argument-prefix", 0, + StringUtil.lastIndexOfIgnoreCase("ABCxyz", "abc")); + check("three-argument-zero-start", 0, + StringUtil.lastIndexOfIgnoreCase("abcABC", "abc", 0)); + check("generic-identical-case-at-zero", 0, + StringUtil.lastIndexOf("abc", "abc", 0, true)); + check("charsequence-prefix", 0, + StringUtil.lastIndexOfIgnoreCase( + new StringBuilder("AbCd"), new StringBuilder("aB"), 4)); + + check("case-sensitive-zero-control", 0, + StringUtil.lastIndexOf("abc", "abc", 0, false)); + check("later-match-control", 3, + StringUtil.lastIndexOfIgnoreCase("aBcAbC", "abc")); + check("absent-control", -1, + StringUtil.lastIndexOfIgnoreCase("abc", "z")); + check("empty-needle-control", 0, + StringUtil.lastIndexOfIgnoreCase("abc", "", 0)); + if (failures != 0) { + throw new AssertionError(failures + " reverse-search cases failed"); + } + } +} +