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