• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.checkState;
20 import static com.google.common.truth.Truth.assertThat;
21 
22 import com.google.common.annotations.GwtCompatible;
23 import com.google.common.base.Equivalence;
24 import com.google.common.base.MoreObjects;
25 import com.google.common.collect.ImmutableMap;
26 import com.google.common.collect.ImmutableTable;
27 import junit.framework.AssertionFailedError;
28 import junit.framework.TestCase;
29 
30 /**
31  * Tests for {@link EquivalenceTester}.
32  *
33  * @author Gregory Kick
34  */
35 @GwtCompatible
36 public class EquivalenceTesterTest extends TestCase {
37   private EquivalenceTester<Object> tester;
38   private MockEquivalence equivalenceMock;
39 
40   @Override
setUp()41   public void setUp() throws Exception {
42     super.setUp();
43     this.equivalenceMock = new MockEquivalence();
44     this.tester = EquivalenceTester.of(equivalenceMock);
45   }
46 
47   /** Test null reference yields error */
testOf_NullPointerException()48   public void testOf_NullPointerException() {
49     try {
50       EquivalenceTester.of(null);
51       fail("Should fail on null reference");
52     } catch (NullPointerException expected) {
53     }
54   }
55 
testTest_NoData()56   public void testTest_NoData() {
57     tester.test();
58   }
59 
testTest()60   public void testTest() {
61     Object group1Item1 = new TestObject(1, 1);
62     Object group1Item2 = new TestObject(1, 2);
63     Object group2Item1 = new TestObject(2, 1);
64     Object group2Item2 = new TestObject(2, 2);
65 
66     equivalenceMock.expectEquivalent(group1Item1, group1Item2);
67     equivalenceMock.expectDistinct(group1Item1, group2Item1);
68     equivalenceMock.expectDistinct(group1Item1, group2Item2);
69     equivalenceMock.expectEquivalent(group1Item2, group1Item1);
70     equivalenceMock.expectDistinct(group1Item2, group2Item1);
71     equivalenceMock.expectDistinct(group1Item2, group2Item2);
72     equivalenceMock.expectDistinct(group2Item1, group1Item1);
73     equivalenceMock.expectDistinct(group2Item1, group1Item2);
74     equivalenceMock.expectEquivalent(group2Item1, group2Item2);
75     equivalenceMock.expectDistinct(group2Item2, group1Item1);
76     equivalenceMock.expectDistinct(group2Item2, group1Item2);
77     equivalenceMock.expectEquivalent(group2Item2, group2Item1);
78 
79     equivalenceMock.expectHash(group1Item1, 1);
80     equivalenceMock.expectHash(group1Item2, 1);
81     equivalenceMock.expectHash(group2Item1, 2);
82     equivalenceMock.expectHash(group2Item2, 2);
83 
84     equivalenceMock.replay();
85 
86     tester
87         .addEquivalenceGroup(group1Item1, group1Item2)
88         .addEquivalenceGroup(group2Item1, group2Item2)
89         .test();
90   }
91 
testTest_symmetric()92   public void testTest_symmetric() {
93     Object group1Item1 = new TestObject(1, 1);
94     Object group1Item2 = new TestObject(1, 2);
95 
96     equivalenceMock.expectEquivalent(group1Item1, group1Item2);
97     equivalenceMock.expectDistinct(group1Item2, group1Item1);
98 
99     equivalenceMock.expectHash(group1Item1, 1);
100     equivalenceMock.expectHash(group1Item2, 1);
101 
102     equivalenceMock.replay();
103 
104     try {
105       tester.addEquivalenceGroup(group1Item1, group1Item2).test();
106     } catch (AssertionFailedError expected) {
107       assertThat(expected.getMessage())
108           .contains(
109               "TestObject{group=1, item=2} [group 1, item 2] must be equivalent to "
110                   + "TestObject{group=1, item=1} [group 1, item 1]");
111       return;
112     }
113     fail();
114   }
115 
testTest_trasitive()116   public void testTest_trasitive() {
117     Object group1Item1 = new TestObject(1, 1);
118     Object group1Item2 = new TestObject(1, 2);
119     Object group1Item3 = new TestObject(1, 3);
120 
121     equivalenceMock.expectEquivalent(group1Item1, group1Item2);
122     equivalenceMock.expectEquivalent(group1Item1, group1Item3);
123     equivalenceMock.expectEquivalent(group1Item2, group1Item1);
124     equivalenceMock.expectDistinct(group1Item2, group1Item3);
125     equivalenceMock.expectEquivalent(group1Item3, group1Item1);
126     equivalenceMock.expectEquivalent(group1Item3, group1Item2);
127 
128     equivalenceMock.expectHash(group1Item1, 1);
129     equivalenceMock.expectHash(group1Item2, 1);
130     equivalenceMock.expectHash(group1Item3, 1);
131 
132     equivalenceMock.replay();
133 
134     try {
135       tester.addEquivalenceGroup(group1Item1, group1Item2, group1Item3).test();
136     } catch (AssertionFailedError expected) {
137       assertThat(expected.getMessage())
138           .contains(
139               "TestObject{group=1, item=2} [group 1, item 2] must be equivalent to "
140                   + "TestObject{group=1, item=3} [group 1, item 3]");
141       return;
142     }
143     fail();
144   }
145 
testTest_inequivalence()146   public void testTest_inequivalence() {
147     Object group1Item1 = new TestObject(1, 1);
148     Object group2Item1 = new TestObject(2, 1);
149 
150     equivalenceMock.expectEquivalent(group1Item1, group2Item1);
151     equivalenceMock.expectDistinct(group2Item1, group1Item1);
152 
153     equivalenceMock.expectHash(group1Item1, 1);
154     equivalenceMock.expectHash(group2Item1, 2);
155 
156     equivalenceMock.replay();
157 
158     try {
159       tester.addEquivalenceGroup(group1Item1).addEquivalenceGroup(group2Item1).test();
160     } catch (AssertionFailedError expected) {
161       assertThat(expected.getMessage())
162           .contains(
163               "TestObject{group=1, item=1} [group 1, item 1] must not be equivalent to "
164                   + "TestObject{group=2, item=1} [group 2, item 1]");
165       return;
166     }
167     fail();
168   }
169 
testTest_hash()170   public void testTest_hash() {
171     Object group1Item1 = new TestObject(1, 1);
172     Object group1Item2 = new TestObject(1, 2);
173 
174     equivalenceMock.expectEquivalent(group1Item1, group1Item2);
175     equivalenceMock.expectEquivalent(group1Item2, group1Item1);
176 
177     equivalenceMock.expectHash(group1Item1, 1);
178     equivalenceMock.expectHash(group1Item2, 2);
179 
180     equivalenceMock.replay();
181 
182     try {
183       tester.addEquivalenceGroup(group1Item1, group1Item2).test();
184     } catch (AssertionFailedError expected) {
185       String expectedMessage =
186           "the hash (1) of TestObject{group=1, item=1} [group 1, item 1] must be "
187               + "equal to the hash (2) of TestObject{group=1, item=2} [group 1, item 2]";
188       if (!expected.getMessage().contains(expectedMessage)) {
189         fail("<" + expected.getMessage() + "> expected to contain <" + expectedMessage + ">");
190       }
191       return;
192     }
193     fail();
194   }
195 
196   /** An object with a friendly {@link #toString()}. */
197   private static final class TestObject {
198     final int group;
199     final int item;
200 
TestObject(int group, int item)201     TestObject(int group, int item) {
202       this.group = group;
203       this.item = item;
204     }
205 
206     @Override
toString()207     public String toString() {
208       return MoreObjects.toStringHelper("TestObject")
209           .add("group", group)
210           .add("item", item)
211           .toString();
212     }
213   }
214 
215   private static final class MockEquivalence extends Equivalence<Object> {
216     final ImmutableTable.Builder<Object, Object, Boolean> equivalentExpectationsBuilder =
217         ImmutableTable.builder();
218     final ImmutableMap.Builder<Object, Integer> hashExpectationsBuilder = ImmutableMap.builder();
219     ImmutableTable<Object, Object, Boolean> equivalentExpectations;
220     ImmutableMap<Object, Integer> hashExpectations;
221 
expectEquivalent(Object a, Object b)222     void expectEquivalent(Object a, Object b) {
223       checkRecording();
224       equivalentExpectationsBuilder.put(a, b, true);
225     }
226 
expectDistinct(Object a, Object b)227     void expectDistinct(Object a, Object b) {
228       checkRecording();
229       equivalentExpectationsBuilder.put(a, b, false);
230     }
231 
expectHash(Object object, int hash)232     void expectHash(Object object, int hash) {
233       checkRecording();
234       hashExpectationsBuilder.put(object, hash);
235     }
236 
replay()237     void replay() {
238       checkRecording();
239       equivalentExpectations = equivalentExpectationsBuilder.build();
240       hashExpectations = hashExpectationsBuilder.build();
241     }
242 
243     @Override
doEquivalent(Object a, Object b)244     protected boolean doEquivalent(Object a, Object b) {
245       return equivalentExpectations.get(a, b);
246     }
247 
248     @Override
doHash(Object object)249     protected int doHash(Object object) {
250       return hashExpectations.get(object);
251     }
252 
checkRecording()253     void checkRecording() {
254       checkState(equivalentExpectations == null && hashExpectations == null);
255     }
256   }
257 }
258