17
package com.google.common.testing;
19
import com.google.common.annotations.GwtCompatible;
20
import com.google.common.base.Preconditions;
21
import com.google.common.collect.ImmutableList;
22
import com.google.common.collect.Sets;
24
import junit.framework.AssertionFailedError;
25
import junit.framework.TestCase;
26
import org.checkerframework.checker.nullness.qual.Nullable;
34
@SuppressWarnings("MissingTestCall")
35
public class EqualsTesterTest extends TestCase {
36
private ValidTestObject reference;
37
private EqualsTester equalsTester;
38
private ValidTestObject equalObject1;
39
private ValidTestObject equalObject2;
40
private ValidTestObject notEqualObject1;
43
public void setUp() throws Exception {
45
reference = new ValidTestObject(1, 2);
46
equalsTester = new EqualsTester();
47
equalObject1 = new ValidTestObject(1, 2);
48
equalObject2 = new ValidTestObject(1, 2);
49
notEqualObject1 = new ValidTestObject(0, 2);
53
public void testAddNullReference() {
55
equalsTester.addEqualityGroup((Object) null);
56
fail("Should fail on null reference");
57
} catch (NullPointerException e) {
62
public void testAddTwoEqualObjectsAtOnceWithNull() {
64
equalsTester.addEqualityGroup(reference, equalObject1, null);
65
fail("Should fail on null equal object");
66
} catch (NullPointerException e) {
71
public void testAddNullEqualObject() {
73
equalsTester.addEqualityGroup(reference, (Object[]) null);
74
fail("Should fail on null equal object");
75
} catch (NullPointerException e) {
83
public void testAddEqualObjectWithOArgConstructor() {
84
equalsTester.addEqualityGroup(equalObject1, notEqualObject1);
86
equalsTester.testEquals();
87
} catch (AssertionFailedError e) {
91
+ " [group 1, item 1] must be Object#equals to "
93
+ " [group 1, item 2]");
96
fail("Should get not equal to equal object error");
103
public void testTestEqualsEmptyLists() {
104
equalsTester.addEqualityGroup(reference);
105
equalsTester.testEquals();
112
public void testTestEqualsEqualsObjects() {
113
equalsTester.addEqualityGroup(reference, equalObject1, equalObject2);
114
equalsTester.testEquals();
118
public void testNonReflexiveEquals() {
119
Object obj = new NonReflexiveObject();
120
equalsTester.addEqualityGroup(obj);
122
equalsTester.testEquals();
123
} catch (AssertionFailedError e) {
124
assertErrorMessage(e, obj + " must be Object#equals to itself");
127
fail("Should get non-reflexive error");
131
public void testInvalidEqualsNull() {
132
Object obj = new InvalidEqualsNullObject();
133
equalsTester.addEqualityGroup(obj);
135
equalsTester.testEquals();
136
} catch (AssertionFailedError e) {
137
assertErrorMessage(e, obj + " must not be Object#equals to null");
140
fail("Should get equal to null error");
144
public void testInvalidEqualsIncompatibleClass() {
145
Object obj = new InvalidEqualsIncompatibleClassObject();
146
equalsTester.addEqualityGroup(obj);
148
equalsTester.testEquals();
149
} catch (AssertionFailedError e) {
151
e, obj + " must not be Object#equals to an arbitrary object of another class");
154
fail("Should get equal to incompatible class error");
158
public void testInvalidNotEqualsEqualObject() {
159
equalsTester.addEqualityGroup(reference, notEqualObject1);
161
equalsTester.testEquals();
162
} catch (AssertionFailedError e) {
163
assertErrorMessage(e, reference + " [group 1, item 1]");
164
assertErrorMessage(e, notEqualObject1 + " [group 1, item 2]");
167
fail("Should get not equal to equal object error");
174
public void testInvalidHashCode() {
175
Object a = new InvalidHashCodeObject(1, 2);
176
Object b = new InvalidHashCodeObject(1, 2);
177
equalsTester.addEqualityGroup(a, b);
179
equalsTester.testEquals();
180
} catch (AssertionFailedError e) {
183
"the Object#hashCode ("
187
+ " [group 1, item 1] must be equal to the Object#hashCode ("
193
fail("Should get invalid hashCode error");
196
public void testNullEqualityGroup() {
197
EqualsTester tester = new EqualsTester();
199
tester.addEqualityGroup((Object[]) null);
201
} catch (NullPointerException e) {
205
public void testNullObjectInEqualityGroup() {
206
EqualsTester tester = new EqualsTester();
208
tester.addEqualityGroup(1, null, 3);
210
} catch (NullPointerException e) {
211
assertErrorMessage(e, "at index 1");
215
public void testSymmetryBroken() {
216
EqualsTester tester =
217
new EqualsTester().addEqualityGroup(named("foo").addPeers("bar"), named("bar"));
220
} catch (AssertionFailedError e) {
221
assertErrorMessage(e, "bar [group 1, item 2] must be Object#equals to foo [group 1, item 1]");
224
fail("should failed because symmetry is broken");
227
public void testTransitivityBrokenInEqualityGroup() {
228
EqualsTester tester =
231
named("foo").addPeers("bar", "baz"),
232
named("bar").addPeers("foo"),
233
named("baz").addPeers("foo"));
236
} catch (AssertionFailedError e) {
237
assertErrorMessage(e, "bar [group 1, item 2] must be Object#equals to baz [group 1, item 3]");
240
fail("should failed because transitivity is broken");
243
public void testUnequalObjectsInEqualityGroup() {
244
EqualsTester tester = new EqualsTester().addEqualityGroup(named("foo"), named("bar"));
247
} catch (AssertionFailedError e) {
248
assertErrorMessage(e, "foo [group 1, item 1] must be Object#equals to bar [group 1, item 2]");
251
fail("should failed because of unequal objects in the same equality group");
254
public void testTransitivityBrokenAcrossEqualityGroups() {
255
EqualsTester tester =
257
.addEqualityGroup(named("foo").addPeers("bar"), named("bar").addPeers("foo", "x"))
258
.addEqualityGroup(named("baz").addPeers("x"), named("x").addPeers("baz", "bar"));
261
} catch (AssertionFailedError e) {
263
e, "bar [group 1, item 2] must not be Object#equals to x [group 2, item 2]");
266
fail("should failed because transitivity is broken");
269
public void testEqualityGroups() {
271
.addEqualityGroup(named("foo").addPeers("bar"), named("bar").addPeers("foo"))
272
.addEqualityGroup(named("baz"), named("baz"))
276
public void testEqualityBasedOnToString() {
278
new EqualsTester().addEqualityGroup(new EqualsBasedOnToString("foo")).testEquals();
280
} catch (AssertionFailedError e) {
281
assertTrue(e.getMessage().contains("toString representation"));
285
private static void assertErrorMessage(Throwable e, String message) {
287
if (!e.getMessage().contains(message)) {
288
fail("expected <" + e.getMessage() + "> to contain <" + message + ">");
296
private static class ValidTestObject {
300
ValidTestObject(int aspect1, int aspect2) {
301
this.aspect1 = aspect1;
302
this.aspect2 = aspect2;
306
public boolean equals(@Nullable Object o) {
307
if (!(o instanceof ValidTestObject)) {
310
ValidTestObject other = (ValidTestObject) o;
311
if (aspect1 != other.aspect1) {
314
if (aspect2 != other.aspect2) {
321
public int hashCode() {
323
result = 37 * result + aspect1;
324
result = 37 * result + aspect2;
330
private static class InvalidHashCodeObject {
334
InvalidHashCodeObject(int aspect1, int aspect2) {
335
this.aspect1 = aspect1;
336
this.aspect2 = aspect2;
339
@SuppressWarnings("EqualsHashCode")
341
public boolean equals(@Nullable Object o) {
342
if (!(o instanceof InvalidHashCodeObject)) {
345
InvalidHashCodeObject other = (InvalidHashCodeObject) o;
346
if (aspect1 != other.aspect1) {
349
if (aspect2 != other.aspect2) {
357
private static class NonReflexiveObject {
360
public boolean equals(@Nullable Object o) {
365
public int hashCode() {
366
return super.hashCode();
371
private static class InvalidEqualsNullObject {
374
public boolean equals(@Nullable Object o) {
375
return o == this || o == null;
379
public int hashCode() {
385
private static class InvalidEqualsIncompatibleClassObject {
388
public boolean equals(@Nullable Object o) {
393
public int hashCode() {
398
private static NamedObject named(String name) {
399
return new NamedObject(name);
402
private static class NamedObject {
403
private final Set<String> peerNames = Sets.newHashSet();
405
private final String name;
407
NamedObject(String name) {
408
this.name = Preconditions.checkNotNull(name);
411
NamedObject addPeers(String... names) {
412
peerNames.addAll(ImmutableList.copyOf(names));
417
public boolean equals(@Nullable Object obj) {
418
if (obj instanceof NamedObject) {
419
NamedObject that = (NamedObject) obj;
420
return name.equals(that.name) || peerNames.contains(that.name);
426
public int hashCode() {
431
public String toString() {
436
private static final class EqualsBasedOnToString {
437
private final String s;
439
private EqualsBasedOnToString(String s) {
444
public boolean equals(@Nullable Object obj) {
445
return obj != null && obj.toString().equals(toString());
449
public int hashCode() {
454
public String toString() {