Java

Форк
0
/
RelationshipTester.java 
172 строки · 5.9 Кб
1
/*
2
 * Copyright (C) 2011 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

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;
26
import java.util.List;
27
import junit.framework.AssertionFailedError;
28

29
/**
30
 * Implementation helper for {@link EqualsTester} and {@link EquivalenceTester} that tests for
31
 * equivalence classes.
32
 *
33
 * @author Gregory Kick
34
 */
35
@GwtCompatible
36
@ElementTypesAreNonnullByDefault
37
final class RelationshipTester<T> {
38

39
  static class ItemReporter {
40
    String reportItem(Item<?> item) {
41
      return item.toString();
42
    }
43
  }
44

45
  /**
46
   * A word about using {@link Equivalence}, which automatically checks for {@code null} and
47
   * identical inputs: This sounds like it ought to be a problem here, since the goals of this class
48
   * include testing that {@code equals()} is reflexive and is tolerant of {@code null}. However,
49
   * there's no problem. The reason: {@link EqualsTester} tests {@code null} and identical inputs
50
   * directly against {@code equals()} rather than through the {@code Equivalence}.
51
   */
52
  private final Equivalence<? super T> equivalence;
53

54
  private final String relationshipName;
55
  private final String hashName;
56
  private final ItemReporter itemReporter;
57
  private final List<ImmutableList<T>> groups = Lists.newArrayList();
58

59
  RelationshipTester(
60
      Equivalence<? super T> equivalence,
61
      String relationshipName,
62
      String hashName,
63
      ItemReporter itemReporter) {
64
    this.equivalence = checkNotNull(equivalence);
65
    this.relationshipName = checkNotNull(relationshipName);
66
    this.hashName = checkNotNull(hashName);
67
    this.itemReporter = checkNotNull(itemReporter);
68
  }
69

70
  // TODO(cpovirk): should we reject null items, since the tests already check null automatically?
71
  @CanIgnoreReturnValue
72
  public RelationshipTester<T> addRelatedGroup(Iterable<? extends T> group) {
73
    groups.add(ImmutableList.copyOf(group));
74
    return this;
75
  }
76

77
  public void test() {
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++) {
81
        // check related items in same group
82
        for (int relatedItemNumber = 0; relatedItemNumber < group.size(); relatedItemNumber++) {
83
          if (itemNumber != relatedItemNumber) {
84
            assertRelated(groupNumber, itemNumber, relatedItemNumber);
85
          }
86
        }
87
        // check unrelated items in all other groups
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);
97
            }
98
          }
99
        }
100
      }
101
    }
102
  }
103

104
  private void assertRelated(int groupNumber, int itemNumber, int relatedItemNumber) {
105
    Item<T> itemInfo = getItem(groupNumber, itemNumber);
106
    Item<T> relatedInfo = getItem(groupNumber, relatedItemNumber);
107

108
    T item = itemInfo.value;
109
    T related = relatedInfo.value;
110
    assertWithTemplate(
111
        "$ITEM must be $RELATIONSHIP to $OTHER",
112
        itemInfo,
113
        relatedInfo,
114
        equivalence.equivalent(item, related));
115

116
    int itemHash = equivalence.hash(item);
117
    int relatedHash = equivalence.hash(related);
118
    assertWithTemplate(
119
        "the $HASH ("
120
            + itemHash
121
            + ") of $ITEM must be equal to the $HASH ("
122
            + relatedHash
123
            + ") of $OTHER",
124
        itemInfo,
125
        relatedInfo,
126
        itemHash == relatedHash);
127
  }
128

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);
133

134
    assertWithTemplate(
135
        "$ITEM must not be $RELATIONSHIP to $OTHER",
136
        itemInfo,
137
        unrelatedInfo,
138
        !equivalence.equivalent(itemInfo.value, unrelatedInfo.value));
139
  }
140

141
  private void assertWithTemplate(String template, Item<T> item, Item<T> other, boolean condition) {
142
    if (!condition) {
143
      throw new AssertionFailedError(
144
          template
145
              .replace("$RELATIONSHIP", relationshipName)
146
              .replace("$HASH", hashName)
147
              .replace("$ITEM", itemReporter.reportItem(item))
148
              .replace("$OTHER", itemReporter.reportItem(other)));
149
    }
150
  }
151

152
  private Item<T> getItem(int groupNumber, int itemNumber) {
153
    return new Item<>(groups.get(groupNumber).get(itemNumber), groupNumber, itemNumber);
154
  }
155

156
  static final class Item<T> {
157
    final T value;
158
    final int groupNumber;
159
    final int itemNumber;
160

161
    Item(T value, int groupNumber, int itemNumber) {
162
      this.value = value;
163
      this.groupNumber = groupNumber;
164
      this.itemNumber = itemNumber;
165
    }
166

167
    @Override
168
    public String toString() {
169
      return value + " [group " + (groupNumber + 1) + ", item " + (itemNumber + 1) + ']';
170
    }
171
  }
172
}
173

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.