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 static com.google.common.base.Preconditions.checkNotNull; 020import static com.google.common.collect.testing.Helpers.mapEntry; 021 022import com.google.common.annotations.GwtCompatible; 023import com.google.common.collect.BiMap; 024import com.google.common.collect.testing.DerivedGenerator; 025import com.google.common.collect.testing.OneSizeTestContainerGenerator; 026import com.google.common.collect.testing.SampleElements; 027import com.google.common.collect.testing.TestMapGenerator; 028import com.google.common.collect.testing.TestSetGenerator; 029import com.google.common.collect.testing.TestSubjectGenerator; 030import java.util.ArrayList; 031import java.util.Collection; 032import java.util.List; 033import java.util.Map; 034import java.util.Map.Entry; 035import java.util.Set; 036import org.jspecify.annotations.NullMarked; 037import org.jspecify.annotations.Nullable; 038 039/** 040 * Derived suite generators for Guava collection interfaces, split out of the suite builders so that 041 * they are available to GWT. 042 * 043 * @author Louis Wasserman 044 */ 045@GwtCompatible 046@NullMarked 047public final class DerivedGoogleCollectionGenerators { 048 public static class MapGenerator<K extends @Nullable Object, V extends @Nullable Object> 049 implements TestMapGenerator<K, V>, DerivedGenerator { 050 051 private final OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> generator; 052 053 public MapGenerator( 054 OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> oneSizeTestContainerGenerator) { 055 this.generator = oneSizeTestContainerGenerator; 056 } 057 058 @Override 059 public SampleElements<Entry<K, V>> samples() { 060 return generator.samples(); 061 } 062 063 @Override 064 public Map<K, V> create(Object... elements) { 065 return generator.create(elements); 066 } 067 068 @Override 069 public Entry<K, V>[] createArray(int length) { 070 return generator.createArray(length); 071 } 072 073 @Override 074 public Iterable<Entry<K, V>> order(List<Entry<K, V>> insertionOrder) { 075 return generator.order(insertionOrder); 076 } 077 078 @SuppressWarnings("unchecked") 079 @Override 080 public K[] createKeyArray(int length) { 081 return (K[]) new Object[length]; 082 } 083 084 @SuppressWarnings("unchecked") 085 @Override 086 public V[] createValueArray(int length) { 087 return (V[]) new Object[length]; 088 } 089 090 @Override 091 public TestSubjectGenerator<?> getInnerGenerator() { 092 return generator; 093 } 094 } 095 096 public static class InverseBiMapGenerator<K extends @Nullable Object, V extends @Nullable Object> 097 implements TestBiMapGenerator<V, K>, DerivedGenerator { 098 099 private final OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> generator; 100 101 public InverseBiMapGenerator( 102 OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> oneSizeTestContainerGenerator) { 103 this.generator = oneSizeTestContainerGenerator; 104 } 105 106 @Override 107 public SampleElements<Entry<V, K>> samples() { 108 SampleElements<Entry<K, V>> samples = generator.samples(); 109 return new SampleElements<>( 110 reverse(samples.e0()), 111 reverse(samples.e1()), 112 reverse(samples.e2()), 113 reverse(samples.e3()), 114 reverse(samples.e4())); 115 } 116 117 private Entry<V, K> reverse(Entry<K, V> entry) { 118 checkNotNull(entry); 119 return mapEntry(entry.getValue(), entry.getKey()); 120 } 121 122 @SuppressWarnings("unchecked") 123 @Override 124 public BiMap<V, K> create(Object... elements) { 125 Entry<?, ?>[] entries = new Entry<?, ?>[elements.length]; 126 for (int i = 0; i < elements.length; i++) { 127 entries[i] = reverse((Entry<K, V>) elements[i]); 128 } 129 return generator.create((Object[]) entries).inverse(); 130 } 131 132 @SuppressWarnings("unchecked") 133 @Override 134 public Entry<V, K>[] createArray(int length) { 135 return (Entry<V, K>[]) new Entry<?, ?>[length]; 136 } 137 138 @Override 139 public Iterable<Entry<V, K>> order(List<Entry<V, K>> insertionOrder) { 140 return insertionOrder; 141 } 142 143 @SuppressWarnings("unchecked") 144 @Override 145 public V[] createKeyArray(int length) { 146 return (V[]) new Object[length]; 147 } 148 149 @SuppressWarnings("unchecked") 150 @Override 151 public K[] createValueArray(int length) { 152 return (K[]) new Object[length]; 153 } 154 155 @Override 156 public TestSubjectGenerator<?> getInnerGenerator() { 157 return generator; 158 } 159 } 160 161 public static class BiMapValueSetGenerator<K extends @Nullable Object, V extends @Nullable Object> 162 implements TestSetGenerator<V>, DerivedGenerator { 163 private final OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> mapGenerator; 164 private final SampleElements<V> samples; 165 166 public BiMapValueSetGenerator( 167 OneSizeTestContainerGenerator<BiMap<K, V>, Entry<K, V>> mapGenerator) { 168 this.mapGenerator = mapGenerator; 169 SampleElements<Entry<K, V>> mapSamples = this.mapGenerator.samples(); 170 this.samples = 171 new SampleElements<>( 172 mapSamples.e0().getValue(), 173 mapSamples.e1().getValue(), 174 mapSamples.e2().getValue(), 175 mapSamples.e3().getValue(), 176 mapSamples.e4().getValue()); 177 } 178 179 @Override 180 public SampleElements<V> samples() { 181 return samples; 182 } 183 184 @Override 185 public Set<V> create(Object... elements) { 186 @SuppressWarnings("unchecked") 187 V[] valuesArray = (V[]) elements; 188 189 // Start with a suitably shaped collection of entries 190 Collection<Entry<K, V>> originalEntries = mapGenerator.getSampleElements(elements.length); 191 192 // Create a copy of that, with the desired value for each value 193 Collection<Entry<K, V>> entries = new ArrayList<>(elements.length); 194 int i = 0; 195 for (Entry<K, V> entry : originalEntries) { 196 entries.add(mapEntry(entry.getKey(), valuesArray[i++])); 197 } 198 199 return mapGenerator.create(entries.toArray()).values(); 200 } 201 202 @Override 203 public V[] createArray(int length) { 204 V[] vs = 205 ((TestBiMapGenerator<K, V>) mapGenerator.getInnerGenerator()).createValueArray(length); 206 return vs; 207 } 208 209 @Override 210 public Iterable<V> order(List<V> insertionOrder) { 211 return insertionOrder; 212 } 213 214 @Override 215 public TestSubjectGenerator<?> getInnerGenerator() { 216 return mapGenerator; 217 } 218 } 219 220 private DerivedGoogleCollectionGenerators() {} 221}