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