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