AbstractMultimapTester.java revision 3c77433663281544363151bf284b0240dfd22a42
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
17package com.google.common.collect.testing.google;
18
19import static java.util.Arrays.asList;
20import static org.truth0.Truth.ASSERT;
21
22import com.google.common.annotations.GwtCompatible;
23import com.google.common.collect.Multimap;
24import com.google.common.collect.testing.AbstractContainerTester;
25import com.google.common.collect.testing.Helpers;
26import com.google.common.collect.testing.SampleElements;
27
28import java.util.Arrays;
29import java.util.Collection;
30import java.util.Iterator;
31import java.util.Map;
32import java.util.Map.Entry;
33
34/**
35 * Superclass for all {@code Multimap} testers.
36 *
37 * @author Louis Wasserman
38 */
39@GwtCompatible
40public abstract class AbstractMultimapTester<K, V, M extends Multimap<K, V>>
41    extends AbstractContainerTester<M, Map.Entry<K, V>> {
42
43  private M multimap;
44
45  protected M multimap() {
46    return multimap;
47  }
48
49  /**
50   * @return an array of the proper size with {@code null} as the key of the
51   * middle element.
52   */
53  protected Map.Entry<K, V>[] createArrayWithNullKey() {
54    Map.Entry<K, V>[] array = createSamplesArray();
55    final int nullKeyLocation = getNullLocation();
56    final Map.Entry<K, V> oldEntry = array[nullKeyLocation];
57    array[nullKeyLocation] = Helpers.mapEntry(null, oldEntry.getValue());
58    return array;
59  }
60
61  /**
62   * @return an array of the proper size with {@code null} as the value of the
63   * middle element.
64   */
65  protected Map.Entry<K, V>[] createArrayWithNullValue() {
66    Map.Entry<K, V>[] array = createSamplesArray();
67    final int nullValueLocation = getNullLocation();
68    final Map.Entry<K, V> oldEntry = array[nullValueLocation];
69    array[nullValueLocation] = Helpers.mapEntry(oldEntry.getKey(), null);
70    return array;
71  }
72
73  /**
74   * @return an array of the proper size with {@code null} as the key and value of the
75   * middle element.
76   */
77  protected Map.Entry<K, V>[] createArrayWithNullKeyAndValue() {
78    Map.Entry<K, V>[] array = createSamplesArray();
79    final int nullValueLocation = getNullLocation();
80    array[nullValueLocation] = Helpers.mapEntry(null, null);
81    return array;
82  }
83
84  protected V getValueForNullKey() {
85    return getEntryNullReplaces().getValue();
86  }
87
88  protected K getKeyForNullValue() {
89    return getEntryNullReplaces().getKey();
90  }
91
92  private Entry<K, V> getEntryNullReplaces() {
93    Iterator<Entry<K, V>> entries = getSampleElements().iterator();
94    for (int i = 0; i < getNullLocation(); i++) {
95      entries.next();
96    }
97    return entries.next();
98  }
99
100  protected void initMultimapWithNullKey() {
101    resetContainer(getSubjectGenerator().create(createArrayWithNullKey()));
102  }
103
104  protected void initMultimapWithNullValue() {
105    resetContainer(getSubjectGenerator().create(createArrayWithNullValue()));
106  }
107
108  protected void initMultimapWithNullKeyAndValue() {
109    resetContainer(getSubjectGenerator().create(createArrayWithNullKeyAndValue()));
110  }
111
112  protected SampleElements<K> sampleKeys() {
113    return ((TestMultimapGenerator<K, V, ? extends Multimap<K, V>>) getSubjectGenerator()
114        .getInnerGenerator()).sampleKeys();
115  }
116
117  protected SampleElements<V> sampleValues() {
118    return ((TestMultimapGenerator<K, V, ? extends Multimap<K, V>>) getSubjectGenerator()
119        .getInnerGenerator()).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(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    ASSERT.that(multimap().get(key)).has().allFrom(values);
150
151    if (!values.isEmpty()) {
152      ASSERT.that(multimap().asMap().get(key)).has().allFrom(values);
153      assertFalse(multimap().isEmpty());
154    } else {
155      ASSERT.that(multimap().asMap().get(key)).isNull();
156    }
157
158    // TODO(user): Add proper overrides to prevent autoboxing.
159    // Truth+autoboxing == compile error. Cast int to long to fix:
160    ASSERT.that(multimap().get(key).size()).is((long) values.size());
161
162    assertEquals(values.size() > 0, multimap().containsKey(key));
163    assertEquals(values.size() > 0, multimap().keySet().contains(key));
164    assertEquals(values.size() > 0, multimap().keys().contains(key));
165  }
166}
167