17
package com.google.common.testing;
19
import static com.google.common.base.Preconditions.checkNotNull;
21
import com.google.common.annotations.GwtCompatible;
22
import com.google.common.base.Equivalence;
23
import com.google.common.collect.ImmutableList;
24
import com.google.common.collect.Lists;
25
import com.google.errorprone.annotations.CanIgnoreReturnValue;
27
import junit.framework.AssertionFailedError;
36
@ElementTypesAreNonnullByDefault
37
final class RelationshipTester<T> {
39
static class ItemReporter {
40
String reportItem(Item<?> item) {
41
return item.toString();
52
private final Equivalence<? super T> equivalence;
54
private final String relationshipName;
55
private final String hashName;
56
private final ItemReporter itemReporter;
57
private final List<ImmutableList<T>> groups = Lists.newArrayList();
60
Equivalence<? super T> equivalence,
61
String relationshipName,
63
ItemReporter itemReporter) {
64
this.equivalence = checkNotNull(equivalence);
65
this.relationshipName = checkNotNull(relationshipName);
66
this.hashName = checkNotNull(hashName);
67
this.itemReporter = checkNotNull(itemReporter);
72
public RelationshipTester<T> addRelatedGroup(Iterable<? extends T> group) {
73
groups.add(ImmutableList.copyOf(group));
78
for (int groupNumber = 0; groupNumber < groups.size(); groupNumber++) {
79
ImmutableList<T> group = groups.get(groupNumber);
80
for (int itemNumber = 0; itemNumber < group.size(); itemNumber++) {
82
for (int relatedItemNumber = 0; relatedItemNumber < group.size(); relatedItemNumber++) {
83
if (itemNumber != relatedItemNumber) {
84
assertRelated(groupNumber, itemNumber, relatedItemNumber);
88
for (int unrelatedGroupNumber = 0;
89
unrelatedGroupNumber < groups.size();
90
unrelatedGroupNumber++) {
91
if (groupNumber != unrelatedGroupNumber) {
92
ImmutableList<T> unrelatedGroup = groups.get(unrelatedGroupNumber);
93
for (int unrelatedItemNumber = 0;
94
unrelatedItemNumber < unrelatedGroup.size();
95
unrelatedItemNumber++) {
96
assertUnrelated(groupNumber, itemNumber, unrelatedGroupNumber, unrelatedItemNumber);
104
private void assertRelated(int groupNumber, int itemNumber, int relatedItemNumber) {
105
Item<T> itemInfo = getItem(groupNumber, itemNumber);
106
Item<T> relatedInfo = getItem(groupNumber, relatedItemNumber);
108
T item = itemInfo.value;
109
T related = relatedInfo.value;
111
"$ITEM must be $RELATIONSHIP to $OTHER",
114
equivalence.equivalent(item, related));
116
int itemHash = equivalence.hash(item);
117
int relatedHash = equivalence.hash(related);
121
+ ") of $ITEM must be equal to the $HASH ("
126
itemHash == relatedHash);
129
private void assertUnrelated(
130
int groupNumber, int itemNumber, int unrelatedGroupNumber, int unrelatedItemNumber) {
131
Item<T> itemInfo = getItem(groupNumber, itemNumber);
132
Item<T> unrelatedInfo = getItem(unrelatedGroupNumber, unrelatedItemNumber);
135
"$ITEM must not be $RELATIONSHIP to $OTHER",
138
!equivalence.equivalent(itemInfo.value, unrelatedInfo.value));
141
private void assertWithTemplate(String template, Item<T> item, Item<T> other, boolean condition) {
143
throw new AssertionFailedError(
145
.replace("$RELATIONSHIP", relationshipName)
146
.replace("$HASH", hashName)
147
.replace("$ITEM", itemReporter.reportItem(item))
148
.replace("$OTHER", itemReporter.reportItem(other)));
152
private Item<T> getItem(int groupNumber, int itemNumber) {
153
return new Item<>(groups.get(groupNumber).get(itemNumber), groupNumber, itemNumber);
156
static final class Item<T> {
158
final int groupNumber;
159
final int itemNumber;
161
Item(T value, int groupNumber, int itemNumber) {
163
this.groupNumber = groupNumber;
164
this.itemNumber = itemNumber;
168
public String toString() {
169
return value + " [group " + (groupNumber + 1) + ", item " + (itemNumber + 1) + ']';