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