View Javadoc
1   /*
2    * Copyright (C) 2012 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.collect.testing.google;
18  
19  import static com.google.common.collect.testing.Helpers.assertEqualIgnoringOrder;
20  
21  import com.google.common.annotations.GwtCompatible;
22  import com.google.common.collect.Multimap;
23  import com.google.common.collect.testing.AbstractContainerTester;
24  import com.google.common.collect.testing.Helpers;
25  import com.google.common.collect.testing.SampleElements;
26  import java.util.Arrays;
27  import java.util.Collection;
28  import java.util.Iterator;
29  import java.util.Map;
30  import java.util.Map.Entry;
31  
32  /**
33   * Superclass for all {@code Multimap} testers.
34   *
35   * @author Louis Wasserman
36   */
37  @GwtCompatible
38  public abstract class AbstractMultimapTester<K, V, M extends Multimap<K, V>>
39      extends AbstractContainerTester<M, Map.Entry<K, V>> {
40  
41    private M multimap;
42  
43    protected M multimap() {
44      return multimap;
45    }
46  
47    /**
48     * @return an array of the proper size with {@code null} as the key of the
49     * middle element.
50     */
51    protected Map.Entry<K, V>[] createArrayWithNullKey() {
52      Map.Entry<K, V>[] array = createSamplesArray();
53      final int nullKeyLocation = getNullLocation();
54      final Map.Entry<K, V> oldEntry = array[nullKeyLocation];
55      array[nullKeyLocation] = Helpers.mapEntry(null, oldEntry.getValue());
56      return array;
57    }
58  
59    /**
60     * @return an array of the proper size with {@code null} as the value of the
61     * middle element.
62     */
63    protected Map.Entry<K, V>[] createArrayWithNullValue() {
64      Map.Entry<K, V>[] array = createSamplesArray();
65      final int nullValueLocation = getNullLocation();
66      final Map.Entry<K, V> oldEntry = array[nullValueLocation];
67      array[nullValueLocation] = Helpers.mapEntry(oldEntry.getKey(), null);
68      return array;
69    }
70  
71    /**
72     * @return an array of the proper size with {@code null} as the key and value of the
73     * middle element.
74     */
75    protected Map.Entry<K, V>[] createArrayWithNullKeyAndValue() {
76      Map.Entry<K, V>[] array = createSamplesArray();
77      final int nullValueLocation = getNullLocation();
78      array[nullValueLocation] = Helpers.mapEntry(null, null);
79      return array;
80    }
81  
82    protected V getValueForNullKey() {
83      return getEntryNullReplaces().getValue();
84    }
85  
86    protected K getKeyForNullValue() {
87      return getEntryNullReplaces().getKey();
88    }
89  
90    private Entry<K, V> getEntryNullReplaces() {
91      Iterator<Entry<K, V>> entries = getSampleElements().iterator();
92      for (int i = 0; i < getNullLocation(); i++) {
93        entries.next();
94      }
95      return entries.next();
96    }
97  
98    protected void initMultimapWithNullKey() {
99      resetContainer(getSubjectGenerator().create((Object[]) createArrayWithNullKey()));
100   }
101 
102   protected void initMultimapWithNullValue() {
103     resetContainer(getSubjectGenerator().create((Object[]) createArrayWithNullValue()));
104   }
105 
106   protected void initMultimapWithNullKeyAndValue() {
107     resetContainer(getSubjectGenerator().create((Object[]) createArrayWithNullKeyAndValue()));
108   }
109 
110   protected SampleElements<K> sampleKeys() {
111     return ((TestMultimapGenerator<K, V, ? extends Multimap<K, V>>)
112             getSubjectGenerator().getInnerGenerator())
113         .sampleKeys();
114   }
115 
116   protected SampleElements<V> sampleValues() {
117     return ((TestMultimapGenerator<K, V, ? extends Multimap<K, V>>)
118             getSubjectGenerator().getInnerGenerator())
119         .sampleValues();
120   }
121 
122   @Override
123   protected Collection<Entry<K, V>> actualContents() {
124     return multimap.entries();
125   }
126 
127   // TODO: dispose of this once collection is encapsulated.
128   @Override
129   protected M resetContainer(M newContents) {
130     multimap = super.resetContainer(newContents);
131     return multimap;
132   }
133 
134   protected Multimap<K, V> resetContainer(Entry<K, V>... newContents) {
135     multimap = super.resetContainer(getSubjectGenerator().create((Object[]) newContents));
136     return multimap;
137   }
138 
139   /** @see AbstractContainerTester#resetContainer() */
140   protected void resetCollection() {
141     resetContainer();
142   }
143 
144   protected void assertGet(K key, V... values) {
145     assertGet(key, Arrays.asList(values));
146   }
147 
148   protected void assertGet(K key, Collection<V> values) {
149     assertEqualIgnoringOrder(values, multimap().get(key));
150 
151     if (!values.isEmpty()) {
152       assertEqualIgnoringOrder(values, multimap().asMap().get(key));
153       assertFalse(multimap().isEmpty());
154     } else {
155       assertNull(multimap().asMap().get(key));
156     }
157 
158     assertEquals(values.size(), multimap().get(key).size());
159 
160     assertEquals(values.size() > 0, multimap().containsKey(key));
161     assertEquals(values.size() > 0, multimap().keySet().contains(key));
162     assertEquals(values.size() > 0, multimap().keys().contains(key));
163   }
164 
165   protected final K k0() {
166     return e0().getKey();
167   }
168 
169   protected final V v0() {
170     return e0().getValue();
171   }
172 
173   protected final K k1() {
174     return e1().getKey();
175   }
176 
177   protected final V v1() {
178     return e1().getValue();
179   }
180 
181   protected final K k2() {
182     return e2().getKey();
183   }
184 
185   protected final V v2() {
186     return e2().getValue();
187   }
188 
189   protected final K k3() {
190     return e3().getKey();
191   }
192 
193   protected final V v3() {
194     return e3().getValue();
195   }
196 
197   protected final K k4() {
198     return e4().getKey();
199   }
200 
201   protected final V v4() {
202     return e4().getValue();
203   }
204 }