Home | History | Annotate | Download | only in testing
      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 
     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 */
     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   public void testTest_NoData() {
     56     tester.test();
     57   }
     58 
     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 
     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 
    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 
    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 
    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 
    196     TestObject(int group , int item) {
    197       this.group = group;
    198       this.item = item;
    199     }
    200 
    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 
    217     void expectEquivalent(Object a, Object b) {
    218       checkRecording();
    219       equivalentExpectationsBuilder.put(a, b, true);
    220     }
    221 
    222     void expectDistinct(Object a, Object b) {
    223       checkRecording();
    224       equivalentExpectationsBuilder.put(a, b, false);
    225     }
    226 
    227     void expectHash(Object object, int hash) {
    228       checkRecording();
    229       hashExpectationsBuilder.put(object, hash);
    230     }
    231 
    232     void replay() {
    233       checkRecording();
    234       equivalentExpectations = equivalentExpectationsBuilder.build();
    235       hashExpectations = hashExpectationsBuilder.build();
    236     }
    237 
    238     @Override protected boolean doEquivalent(Object a, Object b) {
    239       return equivalentExpectations.get(a, b);
    240     }
    241 
    242     @Override protected int doHash(Object object) {
    243       return hashExpectations.get(object);
    244     }
    245 
    246     void checkRecording() {
    247       checkState(equivalentExpectations == null && hashExpectations == null);
    248     }
    249   }
    250 }
    251