001/* 002 * Copyright (C) 2009 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.collect.testing.Helpers.mapEntry; 020 021import com.google.common.annotations.GwtCompatible; 022import com.google.common.collect.ImmutableMap; 023import com.google.common.collect.ImmutableSet; 024import com.google.common.collect.Iterables; 025import com.google.common.collect.Maps; 026import com.google.common.collect.Ordering; 027import com.google.common.collect.testing.AnEnum; 028import com.google.common.collect.testing.SampleElements; 029import com.google.common.collect.testing.TestEnumMapGenerator; 030import com.google.common.collect.testing.TestListGenerator; 031import com.google.common.collect.testing.TestMapGenerator; 032import com.google.common.collect.testing.TestStringListGenerator; 033import com.google.common.collect.testing.TestStringMapGenerator; 034import com.google.common.collect.testing.TestUnhashableCollectionGenerator; 035import com.google.common.collect.testing.UnhashableObject; 036import java.util.Arrays; 037import java.util.Collection; 038import java.util.EnumMap; 039import java.util.List; 040import java.util.Map; 041import java.util.Map.Entry; 042 043/** 044 * Generators of different types of map and related collections, such as keys, entries and values. 045 * 046 * @author Hayward Chan 047 */ 048@GwtCompatible 049@ElementTypesAreNonnullByDefault 050public class MapGenerators { 051 public static class ImmutableMapGenerator extends TestStringMapGenerator { 052 @Override 053 protected Map<String, String> create(Entry<String, String>[] entries) { 054 ImmutableMap.Builder<String, String> builder = ImmutableMap.builder(); 055 for (Entry<String, String> entry : entries) { 056 builder.put(entry.getKey(), entry.getValue()); 057 } 058 return builder.buildOrThrow(); 059 } 060 } 061 062 public static class ImmutableMapCopyOfGenerator extends TestStringMapGenerator { 063 @Override 064 protected Map<String, String> create(Entry<String, String>[] entries) { 065 Map<String, String> builder = Maps.newLinkedHashMap(); 066 for (Entry<String, String> entry : entries) { 067 builder.put(entry.getKey(), entry.getValue()); 068 } 069 return ImmutableMap.copyOf(builder); 070 } 071 } 072 073 public static class ImmutableMapCopyOfEntriesGenerator extends TestStringMapGenerator { 074 @Override 075 protected Map<String, String> create(Entry<String, String>[] entries) { 076 return ImmutableMap.copyOf(Arrays.asList(entries)); 077 } 078 } 079 080 public static class ImmutableMapUnhashableValuesGenerator 081 extends TestUnhashableCollectionGenerator<Collection<UnhashableObject>> { 082 083 @Override 084 public Collection<UnhashableObject> create(UnhashableObject[] elements) { 085 ImmutableMap.Builder<Integer, UnhashableObject> builder = ImmutableMap.builder(); 086 int key = 1; 087 for (UnhashableObject value : elements) { 088 builder.put(key++, value); 089 } 090 return builder.buildOrThrow().values(); 091 } 092 } 093 094 public static class ImmutableMapKeyListGenerator extends TestStringListGenerator { 095 @Override 096 public List<String> create(String[] elements) { 097 ImmutableMap.Builder<String, Integer> builder = ImmutableMap.builder(); 098 for (int i = 0; i < elements.length; i++) { 099 builder.put(elements[i], i); 100 } 101 return builder.buildOrThrow().keySet().asList(); 102 } 103 } 104 105 public static class ImmutableMapValueListGenerator extends TestStringListGenerator { 106 @Override 107 public List<String> create(String[] elements) { 108 ImmutableMap.Builder<Integer, String> builder = ImmutableMap.builder(); 109 for (int i = 0; i < elements.length; i++) { 110 builder.put(i, elements[i]); 111 } 112 return builder.buildOrThrow().values().asList(); 113 } 114 } 115 116 public static class ImmutableMapEntryListGenerator 117 implements TestListGenerator<Entry<String, Integer>> { 118 119 @Override 120 public SampleElements<Entry<String, Integer>> samples() { 121 return new SampleElements<>( 122 mapEntry("foo", 5), 123 mapEntry("bar", 3), 124 mapEntry("baz", 17), 125 mapEntry("quux", 1), 126 mapEntry("toaster", -2)); 127 } 128 129 @SuppressWarnings("unchecked") 130 @Override 131 public Entry<String, Integer>[] createArray(int length) { 132 return (Entry<String, Integer>[]) new Entry<?, ?>[length]; 133 } 134 135 @Override 136 public Iterable<Entry<String, Integer>> order(List<Entry<String, Integer>> insertionOrder) { 137 return insertionOrder; 138 } 139 140 @Override 141 public List<Entry<String, Integer>> create(Object... elements) { 142 ImmutableMap.Builder<String, Integer> builder = ImmutableMap.builder(); 143 for (Object o : elements) { 144 @SuppressWarnings("unchecked") 145 Entry<String, Integer> entry = (Entry<String, Integer>) o; 146 builder.put(entry); 147 } 148 return builder.buildOrThrow().entrySet().asList(); 149 } 150 } 151 152 public static class ImmutableEnumMapGenerator extends TestEnumMapGenerator { 153 @Override 154 protected Map<AnEnum, String> create(Entry<AnEnum, String>[] entries) { 155 Map<AnEnum, String> map = Maps.newHashMap(); 156 for (Entry<AnEnum, String> entry : entries) { 157 // checkArgument(!map.containsKey(entry.getKey())); 158 map.put(entry.getKey(), entry.getValue()); 159 } 160 return Maps.immutableEnumMap(map); 161 } 162 } 163 164 public static class ImmutableMapCopyOfEnumMapGenerator extends TestEnumMapGenerator { 165 @Override 166 protected Map<AnEnum, String> create(Entry<AnEnum, String>[] entries) { 167 EnumMap<AnEnum, String> map = new EnumMap<>(AnEnum.class); 168 for (Entry<AnEnum, String> entry : entries) { 169 map.put(entry.getKey(), entry.getValue()); 170 } 171 return ImmutableMap.copyOf(map); 172 } 173 174 @Override 175 public Iterable<Entry<AnEnum, String>> order(List<Entry<AnEnum, String>> insertionOrder) { 176 return new Ordering<Entry<AnEnum, String>>() { 177 178 @Override 179 public int compare(Entry<AnEnum, String> left, Entry<AnEnum, String> right) { 180 return left.getKey().compareTo(right.getKey()); 181 } 182 }.sortedCopy(insertionOrder); 183 } 184 } 185 186 public static class ImmutableMapValuesAsSingletonSetGenerator 187 implements TestMapGenerator<String, Collection<Integer>> { 188 189 @Override 190 public SampleElements<Entry<String, Collection<Integer>>> samples() { 191 return new SampleElements<>( 192 mapEntry("one", collectionOf(10000)), 193 mapEntry("two", collectionOf(-2000)), 194 mapEntry("three", collectionOf(300)), 195 mapEntry("four", collectionOf(-40)), 196 mapEntry("five", collectionOf(5))); 197 } 198 199 // javac7 can't infer the type parameters correctly in samples() 200 private static Collection<Integer> collectionOf(int item) { 201 return ImmutableSet.of(item); 202 } 203 204 @Override 205 public Map<String, Collection<Integer>> create(Object... elements) { 206 ImmutableMap.Builder<String, Integer> builder = ImmutableMap.builder(); 207 // assumes that each set is a singleton or less (as is done for the samples) 208 for (Object elem : elements) { 209 @SuppressWarnings("unchecked") // safe by generator contract 210 Entry<String, Collection<Integer>> entry = (Entry<String, Collection<Integer>>) elem; 211 Integer value = Iterables.getOnlyElement(entry.getValue()); 212 builder.put(entry.getKey(), value); 213 } 214 return builder.buildOrThrow().asMultimap().asMap(); 215 } 216 217 @Override 218 @SuppressWarnings({"unchecked", "rawtypes"}) // needed for arrays 219 public Entry<String, Collection<Integer>>[] createArray(int length) { 220 return new Entry[length]; 221 } 222 223 @Override 224 public Iterable<Entry<String, Collection<Integer>>> order( 225 List<Entry<String, Collection<Integer>>> insertionOrder) { 226 return insertionOrder; 227 } 228 229 @Override 230 public String[] createKeyArray(int length) { 231 return new String[length]; 232 } 233 234 @Override 235 @SuppressWarnings({"unchecked", "rawtypes"}) // needed for arrays 236 public Collection<Integer>[] createValueArray(int length) { 237 return new ImmutableSet[length]; 238 } 239 } 240}