Coverage Summary for Class: EqualsTester (com.google.common.testing)

Class Method, % Line, %
EqualsTester 100% (5/5) 100% (31/31)
EqualsTester$NotAnInstance 100% (2/2) 100% (2/2)
Total 100% (7/7) 100% (33/33)


1 /* 2  * Copyright (C) 2007 The Guava Authors 3  * 4  * Licensed under the Apache License, Version 2.0 (the "License"); 5  * you may not use this file except in compliance with the License. 6  * You may obtain a copy of the License at 7  * 8  * http://www.apache.org/licenses/LICENSE-2.0 9  * 10  * Unless required by applicable law or agreed to in writing, software 11  * distributed under the License is distributed on an "AS IS" BASIS, 12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13  * See the License for the specific language governing permissions and 14  * limitations under the License. 15  */ 16  17 package com.google.common.testing; 18  19 import static com.google.common.base.Preconditions.checkNotNull; 20 import static junit.framework.Assert.assertEquals; 21 import static junit.framework.Assert.assertTrue; 22  23 import com.google.common.annotations.Beta; 24 import com.google.common.annotations.GwtCompatible; 25 import com.google.common.base.Equivalence; 26 import com.google.common.collect.ImmutableList; 27 import com.google.common.collect.Iterables; 28 import com.google.common.collect.Lists; 29 import java.util.List; 30  31 /** 32  * Tester for equals() and hashCode() methods of a class. 33  * 34  * <p>The simplest use case is: 35  * 36  * <pre> 37  * new EqualsTester().addEqualityGroup(foo).testEquals(); 38  * </pre> 39  * 40  * <p>This tests {@code foo.equals(foo)}, {@code foo.equals(null)}, and a few other operations. 41  * 42  * <p>For more extensive testing, add multiple equality groups. Each group should contain objects 43  * that are equal to each other but unequal to the objects in any other group. For example: 44  * 45  * <pre> 46  * new EqualsTester() 47  * .addEqualityGroup(new User("page"), new User("page")) 48  * .addEqualityGroup(new User("sergey")) 49  * .testEquals(); 50  * </pre> 51  * 52  * <p>This tests: 53  * 54  * <ul> 55  * <li>comparing each object against itself returns true 56  * <li>comparing each object against null returns false 57  * <li>comparing each object against an instance of an incompatible class returns false 58  * <li>comparing each pair of objects within the same equality group returns true 59  * <li>comparing each pair of objects from different equality groups returns false 60  * <li>the hash codes of any two equal objects are equal 61  * </ul> 62  * 63  * <p>When a test fails, the error message labels the objects involved in the failed comparison as 64  * follows: 65  * 66  * <ul> 67  * <li>"{@code [group }<i>i</i>{@code , item }<i>j</i>{@code ]}" refers to the 68  * <i>j</i><sup>th</sup> item in the <i>i</i><sup>th</sup> equality group, where both equality 69  * groups and the items within equality groups are numbered starting from 1. When either a 70  * constructor argument or an equal object is provided, that becomes group 1. 71  * </ul> 72  * 73  * @author Jim McMaster 74  * @author Jige Yu 75  * @since 10.0 76  */ 77 @Beta 78 @GwtCompatible 79 public final class EqualsTester { 80  private static final int REPETITIONS = 3; 81  82  private final List<List<Object>> equalityGroups = Lists.newArrayList(); 83  private final RelationshipTester.ItemReporter itemReporter; 84  85  /** Constructs an empty EqualsTester instance */ 86  public EqualsTester() { 87  this(new RelationshipTester.ItemReporter()); 88  } 89  90  EqualsTester(RelationshipTester.ItemReporter itemReporter) { 91  this.itemReporter = checkNotNull(itemReporter); 92  } 93  94  /** 95  * Adds {@code equalityGroup} with objects that are supposed to be equal to each other and not 96  * equal to any other equality groups added to this tester. 97  */ 98  public EqualsTester addEqualityGroup(Object... equalityGroup) { 99  checkNotNull(equalityGroup); 100  equalityGroups.add(ImmutableList.copyOf(equalityGroup)); 101  return this; 102  } 103  104  /** Run tests on equals method, throwing a failure on an invalid test */ 105  public EqualsTester testEquals() { 106  RelationshipTester<Object> delegate = 107  new RelationshipTester<>( 108  Equivalence.equals(), "Object#equals", "Object#hashCode", itemReporter); 109  for (List<Object> group : equalityGroups) { 110  delegate.addRelatedGroup(group); 111  } 112  for (int run = 0; run < REPETITIONS; run++) { 113  testItems(); 114  delegate.test(); 115  } 116  return this; 117  } 118  119  private void testItems() { 120  for (Object item : Iterables.concat(equalityGroups)) { 121  assertTrue(item + " must not be Object#equals to null", !item.equals(null)); 122  assertTrue( 123  item + " must not be Object#equals to an arbitrary object of another class", 124  !item.equals(NotAnInstance.EQUAL_TO_NOTHING)); 125  assertEquals(item + " must be Object#equals to itself", item, item); 126  assertEquals( 127  "the Object#hashCode of " + item + " must be consistent", 128  item.hashCode(), 129  item.hashCode()); 130  if (!(item instanceof String)) { 131  assertTrue( 132  item + " must not be Object#equals to its Object#toString representation", 133  !item.equals(item.toString())); 134  } 135  } 136  } 137  138  /** 139  * Class used to test whether equals() correctly handles an instance of an incompatible class. 140  * Since it is a private inner class, the invoker can never pass in an instance to the tester 141  */ 142  private enum NotAnInstance { 143  EQUAL_TO_NOTHING; 144  } 145 }