001/*
002 * Copyright (C) 2012 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package com.google.common.collect.testing.google;
018
019import com.google.common.annotations.GwtCompatible;
020import com.google.common.collect.BiMap;
021import com.google.common.collect.testing.DerivedGenerator;
022import com.google.common.collect.testing.Helpers;
023import com.google.common.collect.testing.OneSizeTestContainerGenerator;
024import com.google.common.collect.testing.SampleElements;
025import com.google.common.collect.testing.TestMapGenerator;
026import com.google.common.collect.testing.TestSetGenerator;
027import com.google.common.collect.testing.TestSubjectGenerator;
028import java.util.ArrayList;
029import java.util.Collection;
030import java.util.List;
031import java.util.Map;
032import java.util.Map.Entry;
033import java.util.Set;
034
035/**
036 * Derived suite generators for Guava collection interfaces, split out of the suite builders so that
037 * they are available to GWT.
038 *
039 * @author Louis Wasserman
040 */
041@GwtCompatible
042public final class DerivedGoogleCollectionGenerators {
043  public static class MapGenerator<K, V> implements TestMapGenerator<K, V>, DerivedGenerator {
044
045    private final OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> generator;
046
047    public MapGenerator(
048        OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> oneSizeTestContainerGenerator) {
049      this.generator = oneSizeTestContainerGenerator;
050    }
051
052    @Override
053    public SampleElements<Entry<K, V>> samples() {
054      return generator.samples();
055    }
056
057    @Override
058    public Map<K, V> create(Object... elements) {
059      return generator.create(elements);
060    }
061
062    @Override
063    public Entry<K, V>[] createArray(int length) {
064      return generator.createArray(length);
065    }
066
067    @Override
068    public Iterable<Entry<K, V>> order(List<Entry<K, V>> insertionOrder) {
069      return generator.order(insertionOrder);
070    }
071
072    @SuppressWarnings("unchecked")
073    @Override
074    public K[] createKeyArray(int length) {
075      return (K[]) new Object[length];
076    }
077
078    @SuppressWarnings("unchecked")
079    @Override
080    public V[] createValueArray(int length) {
081      return (V[]) new Object[length];
082    }
083
084    public TestSubjectGenerator<?> getInnerGenerator() {
085      return generator;
086    }
087  }
088
089  public static class InverseBiMapGenerator<K, V>
090      implements TestBiMapGenerator<V, K>, DerivedGenerator {
091
092    private final OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> generator;
093
094    public InverseBiMapGenerator(
095        OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> oneSizeTestContainerGenerator) {
096      this.generator = oneSizeTestContainerGenerator;
097    }
098
099    @Override
100    public SampleElements<Entry<V, K>> samples() {
101      SampleElements<Entry<K, V>> samples = generator.samples();
102      return new SampleElements<>(
103          reverse(samples.e0()),
104          reverse(samples.e1()),
105          reverse(samples.e2()),
106          reverse(samples.e3()),
107          reverse(samples.e4()));
108    }
109
110    private Entry<V, K> reverse(Entry<K, V> entry) {
111      return Helpers.mapEntry(entry.getValue(), entry.getKey());
112    }
113
114    @SuppressWarnings("unchecked")
115    @Override
116    public BiMap<V, K> create(Object... elements) {
117      Entry<?, ?>[] entries = new Entry<?, ?>[elements.length];
118      for (int i = 0; i < elements.length; i++) {
119        entries[i] = reverse((Entry<K, V>) elements[i]);
120      }
121      return generator.create((Object[]) entries).inverse();
122    }
123
124    @SuppressWarnings("unchecked")
125    @Override
126    public Entry<V, K>[] createArray(int length) {
127      return new Entry[length];
128    }
129
130    @Override
131    public Iterable<Entry<V, K>> order(List<Entry<V, K>> insertionOrder) {
132      return insertionOrder;
133    }
134
135    @SuppressWarnings("unchecked")
136    @Override
137    public V[] createKeyArray(int length) {
138      return (V[]) new Object[length];
139    }
140
141    @SuppressWarnings("unchecked")
142    @Override
143    public K[] createValueArray(int length) {
144      return (K[]) new Object[length];
145    }
146
147    public TestSubjectGenerator<?> getInnerGenerator() {
148      return generator;
149    }
150  }
151
152  public static class BiMapValueSetGenerator<K, V>
153      implements TestSetGenerator<V>, DerivedGenerator {
154    private final OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> mapGenerator;
155    private final SampleElements<V> samples;
156
157    public BiMapValueSetGenerator(
158        OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> mapGenerator) {
159      this.mapGenerator = mapGenerator;
160      final SampleElements<Entry<K, V>> mapSamples = this.mapGenerator.samples();
161      this.samples =
162          new SampleElements<V>(
163              mapSamples.e0().getValue(),
164              mapSamples.e1().getValue(),
165              mapSamples.e2().getValue(),
166              mapSamples.e3().getValue(),
167              mapSamples.e4().getValue());
168    }
169
170    @Override
171    public SampleElements<V> samples() {
172      return samples;
173    }
174
175    @Override
176    public Set<V> create(Object... elements) {
177      @SuppressWarnings("unchecked")
178      V[] valuesArray = (V[]) elements;
179
180      // Start with a suitably shaped collection of entries
181      Collection<Entry<K, V>> originalEntries = mapGenerator.getSampleElements(elements.length);
182
183      // Create a copy of that, with the desired value for each value
184      Collection<Entry<K, V>> entries = new ArrayList<>(elements.length);
185      int i = 0;
186      for (Entry<K, V> entry : originalEntries) {
187        entries.add(Helpers.mapEntry(entry.getKey(), valuesArray[i++]));
188      }
189
190      return mapGenerator.create(entries.toArray()).values();
191    }
192
193    @Override
194    public V[] createArray(int length) {
195      final V[] vs =
196          ((TestBiMapGenerator<K, V>) mapGenerator.getInnerGenerator()).createValueArray(length);
197      return vs;
198    }
199
200    @Override
201    public Iterable<V> order(List<V> insertionOrder) {
202      return insertionOrder;
203    }
204
205    public TestSubjectGenerator<?> getInnerGenerator() {
206      return mapGenerator;
207    }
208  }
209
210  private DerivedGoogleCollectionGenerators() {}
211}