From 195281719fea50d299eab64833a1697bfbd86407 Mon Sep 17 00:00:00 2001 From: Dongliang Xie Date: Mon, 29 Jun 2026 23:06:42 +0800 Subject: [PATCH] Fix Copy equality/hashCode contract --- src/main/java/io/zold/api/Copies.java | 2 +- src/test/java/io/zold/api/CopiesTest.java | 51 ++++++++++++++++++++++- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/zold/api/Copies.java b/src/main/java/io/zold/api/Copies.java index c0a13b2..a7da2d7 100644 --- a/src/main/java/io/zold/api/Copies.java +++ b/src/main/java/io/zold/api/Copies.java @@ -116,7 +116,7 @@ public int compareTo(final Copy other) { @Override public boolean equals(final Object obj) { return obj instanceof Copy - && this.compareTo((Copy) obj) == 0; + && this.wlt.equals(((Copy) obj).wlt); } @Override diff --git a/src/test/java/io/zold/api/CopiesTest.java b/src/test/java/io/zold/api/CopiesTest.java index a880fa1..7ab0aeb 100644 --- a/src/test/java/io/zold/api/CopiesTest.java +++ b/src/test/java/io/zold/api/CopiesTest.java @@ -41,13 +41,60 @@ void groupsRemotesScoresIntoSingleCopy() { ); } + @Test + void keepsIdentityWhenCopyGetsRemote() { + final Copies.Copy copy = new Copies.Copy( + new Wallet.Fake(1L), + CopiesTest.remote("a") + ); + MatcherAssert.assertThat( + "copy identity is stable when a remote is added", + copy.with(CopiesTest.remote("b")), + new IsEqual<>(copy) + ); + } + + @Test + void keepsHashCodeWhenCopyGetsRemote() { + final Copies.Copy copy = new Copies.Copy( + new Wallet.Fake(1L), + CopiesTest.remote("a") + ); + MatcherAssert.assertThat( + "hash code matches equality after adding a remote", + copy.with(CopiesTest.remote("b")).hashCode(), + new IsEqual<>(copy.hashCode()) + ); + } + + @Test + void distinguishesCopiesWithDifferentWalletsAndSameScore() { + MatcherAssert.assertThat( + "different wallets are not equal even with the same score", + new Copies.Copy( + new Wallet.Fake(1L), + CopiesTest.remote("a") + ).equals( + new Copies.Copy( + new Wallet.Fake(2L), + CopiesTest.remote("b") + ) + ), + new IsEqual<>(false) + ); + } + private static Iterable copies() { return new Copies( 1L, new IterableOf<>( - new Remote.Fake(new RtScore(new IterableOf<>(new TextOf("a")))), - new Remote.Fake(new RtScore(new IterableOf<>(new TextOf("b")))) + CopiesTest.remote("a"), + CopiesTest.remote("b") ) ); } + + private static Remote remote(final String suffix) { + return new Remote.Fake(new RtScore(new IterableOf<>(new TextOf(suffix)))); + } }