diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d1298139..9542329eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## [3.1.6] - 2019-03-11 +### Fixed +- Testing a class with `StringBuilder` causes StringIndexOutOfBoundsException. ([Issue 234](https://github.com/jqno/equalsverifier/issues/234)) + ## [3.1.5] - 2019-02-18 ### Fixed - Verifying interfaces directly causes NullPointerException. ([Issue 232](https://github.com/jqno/equalsverifier/issues/232)) @@ -644,8 +648,9 @@ Please don't use version 1.3; [it's a broken release](https://jqno.nl/post/2013/ You can now use EqualsVerifier! -[Unreleased]: https://github.com/jqno/equalsverifier/compare/equalsverifier-3.1.5...HEAD +[Unreleased]: https://github.com/jqno/equalsverifier/compare/equalsverifier-3.1.6...HEAD +[3.1.6]: https://github.com/jqno/equalsverifier/compare/equalsverifier-3.1.5...equalsverifier-3.1.6 [3.1.5]: https://github.com/jqno/equalsverifier/compare/equalsverifier-3.1.4...equalsverifier-3.1.5 [3.1.4]: https://github.com/jqno/equalsverifier/compare/equalsverifier-3.1.3...equalsverifier-3.1.4 [3.1.3]: https://github.com/jqno/equalsverifier/compare/equalsverifier-3.1.2...equalsverifier-3.1.3 diff --git a/src/main/java/nl/jqno/equalsverifier/internal/prefabvalues/JavaApiPrefabValues.java b/src/main/java/nl/jqno/equalsverifier/internal/prefabvalues/JavaApiPrefabValues.java index a5ce67361..be32d891b 100644 --- a/src/main/java/nl/jqno/equalsverifier/internal/prefabvalues/JavaApiPrefabValues.java +++ b/src/main/java/nl/jqno/equalsverifier/internal/prefabvalues/JavaApiPrefabValues.java @@ -138,6 +138,7 @@ private void addCommonClasses() { addValues(Pattern.class, Pattern.compile("one"), Pattern.compile("two"), Pattern.compile("one")); addValues(Scanner.class, new Scanner("one"), new Scanner("two"), new Scanner("one")); addValues(StampedLock.class, new StampedLock(), new StampedLock(), new StampedLock()); + addValues(StringBuilder.class, new StringBuilder("one"), new StringBuilder("two"), new StringBuilder("three")); addValues(Thread.class, new Thread("one"), new Thread("two"), new Thread("one")); addValues(Throwable.class, new Throwable(), new Throwable(), new Throwable()); addValues(URI.class, URI.create("x"), URI.create("y"), URI.create("x")); diff --git a/src/test/java/nl/jqno/equalsverifier/integration/extended_contract/JavaApiClassesTest.java b/src/test/java/nl/jqno/equalsverifier/integration/extended_contract/JavaApiClassesTest.java index 9611dfec7..e7a16382f 100644 --- a/src/test/java/nl/jqno/equalsverifier/integration/extended_contract/JavaApiClassesTest.java +++ b/src/test/java/nl/jqno/equalsverifier/integration/extended_contract/JavaApiClassesTest.java @@ -1,6 +1,7 @@ package nl.jqno.equalsverifier.integration.extended_contract; import nl.jqno.equalsverifier.EqualsVerifier; +import nl.jqno.equalsverifier.Warning; import nl.jqno.equalsverifier.testhelpers.ExpectedExceptionTestBase; import nl.jqno.equalsverifier.testhelpers.types.TypeHelper; import org.junit.Test; @@ -91,6 +92,13 @@ public void succeed_whenClassContainsAThreadLocalField() { .verify(); } + @Test + public void succeed_whenClassContainsStringBuilderThatCallsToStringInEquals() { + EqualsVerifier.forClass(StringBuilderContainer.class) + .suppress(Warning.NULL_FIELDS) + .verify(); + } + abstract static class CollectionContainer { @@ -441,4 +449,26 @@ public boolean equals(Object obj) { @Override public int hashCode() { return defaultHashCode(this); } } + + static final class StringBuilderContainer { + private final StringBuilder stringBuilder; + + public StringBuilderContainer(StringBuilder stringBuilder) { + this.stringBuilder = stringBuilder; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof StringBuilderContainer)) { + return false; + } + StringBuilderContainer other = (StringBuilderContainer)obj; + return Objects.equals(stringBuilder.toString(), other.stringBuilder.toString()); + } + + @Override + public int hashCode() { + return defaultHashCode(this); + } + } }