1 /*
2  * Copyright (C) 2012 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.google.common.collect;
17 
18 import static com.google.common.base.Preconditions.checkArgument;
19 import static com.google.common.base.Preconditions.checkNotNull;
20 import static com.google.common.collect.testing.Helpers.mapEntry;
21 
22 import com.google.common.base.Charsets;
23 import com.google.common.base.Function;
24 import com.google.common.base.Predicate;
25 import com.google.common.collect.Maps.EntryTransformer;
26 import com.google.common.collect.testing.Helpers;
27 import com.google.common.collect.testing.MapTestSuiteBuilder;
28 import com.google.common.collect.testing.NavigableMapTestSuiteBuilder;
29 import com.google.common.collect.testing.SafeTreeMap;
30 import com.google.common.collect.testing.SampleElements;
31 import com.google.common.collect.testing.SortedMapTestSuiteBuilder;
32 import com.google.common.collect.testing.TestMapGenerator;
33 import com.google.common.collect.testing.TestStringMapGenerator;
34 import com.google.common.collect.testing.TestStringSortedMapGenerator;
35 import com.google.common.collect.testing.features.CollectionFeature;
36 import com.google.common.collect.testing.features.CollectionSize;
37 import com.google.common.collect.testing.features.MapFeature;
38 import com.google.common.collect.testing.google.BiMapTestSuiteBuilder;
39 import com.google.common.collect.testing.google.TestStringBiMapGenerator;
40 import com.google.common.io.BaseEncoding;
41 
42 import junit.framework.Test;
43 import junit.framework.TestCase;
44 import junit.framework.TestSuite;
45 
46 import java.util.Collections;
47 import java.util.Comparator;
48 import java.util.List;
49 import java.util.Map;
50 import java.util.Map.Entry;
51 import java.util.NavigableMap;
52 import java.util.NavigableSet;
53 import java.util.Set;
54 import java.util.SortedMap;
55 import java.util.SortedSet;
56 
57 import javax.annotation.Nullable;
58 
59 /**
60  * Test suites for wrappers in {@code Maps}.
61  *
62  * @author Louis Wasserman
63  */
64 public class MapsCollectionTest extends TestCase {
65   public static Test suite() {
66     TestSuite suite = new TestSuite();
67 
68     suite.addTest(NavigableMapTestSuiteBuilder
69         .using(new TestStringSortedMapGenerator() {
70           @Override
71           protected SortedMap<String, String> create(Entry<String, String>[] entries) {
72             SafeTreeMap<String, String> map = new SafeTreeMap<String, String>();
73             putEntries(map, entries);
74             return Maps.unmodifiableNavigableMap(map);
75           }
76         })
77         .named("unmodifiableNavigableMap[SafeTreeMap]")
78         .withFeatures(CollectionSize.ANY,
79             MapFeature.ALLOWS_NULL_VALUES,
80             CollectionFeature.SERIALIZABLE)
81         .createTestSuite());
82     suite.addTest(BiMapTestSuiteBuilder
83         .using(new TestStringBiMapGenerator() {
84           @Override
85           protected BiMap<String, String> create(Entry<String, String>[] entries) {
86             BiMap<String, String> bimap = HashBiMap.create(entries.length);
87             for (Entry<String, String> entry : entries) {
88               checkArgument(!bimap.containsKey(entry.getKey()));
89               bimap.put(entry.getKey(), entry.getValue());
90             }
91             return Maps.unmodifiableBiMap(bimap);
92           }
93         })
94         .named("unmodifiableBiMap[HashBiMap]")
95         .withFeatures(
96             CollectionSize.ANY,
97             MapFeature.ALLOWS_NULL_VALUES,
98             MapFeature.ALLOWS_NULL_KEYS,
99             MapFeature.ALLOWS_ANY_NULL_QUERIES,
100             MapFeature.REJECTS_DUPLICATES_AT_CREATION,
101             CollectionFeature.SERIALIZABLE)
102         .createTestSuite());
103     suite.addTest(MapTestSuiteBuilder
104         .using(new TestMapGenerator<String, Integer>() {
105           @Override
106           public SampleElements<Entry<String, Integer>> samples() {
107             return new SampleElements<Entry<String, Integer>>(
108                 mapEntry("x", 1),
109                 mapEntry("xxx", 3),
110                 mapEntry("xx", 2),
111                 mapEntry("xxxx", 4),
112                 mapEntry("aaaaa", 5));
113           }
114 
115           @Override
116           public Map<String, Integer> create(Object... elements) {
117             Set<String> set = Sets.newLinkedHashSet();
118             for (Object e : elements) {
119               Entry<?, ?> entry = (Entry<?, ?>) e;
120               checkNotNull(entry.getValue());
121               set.add((String) checkNotNull(entry.getKey()));
122             }
123             return Maps.asMap(set, new Function<String, Integer>() {
124               @Override
125               public Integer apply(String input) {
126                 return input.length();
127               }
128             });
129           }
130 
131           @SuppressWarnings("unchecked")
132           @Override
133           public Entry<String, Integer>[] createArray(int length) {
134             return new Entry[length];
135           }
136 
137           @Override
138           public Iterable<Entry<String, Integer>> order(
139               List<Entry<String, Integer>> insertionOrder) {
140             return insertionOrder;
141           }
142 
143           @Override
144           public String[] createKeyArray(int length) {
145             return new String[length];
146           }
147 
148           @Override
149           public Integer[] createValueArray(int length) {
150             return new Integer[length];
151           }
152         })
153         .named("Maps.asMap[Set, Function]")
154         .withFeatures(CollectionSize.ANY,
155             MapFeature.SUPPORTS_REMOVE,
156             CollectionFeature.SUPPORTS_ITERATOR_REMOVE)
157         .createTestSuite());
158     suite.addTest(SortedMapTestSuiteBuilder
159         .using(new TestMapGenerator<String, Integer>() {
160           @Override
161           public String[] createKeyArray(int length) {
162             return new String[length];
163           }
164 
165           @Override
166           public Integer[] createValueArray(int length) {
167             return new Integer[length];
168           }
169 
170           @Override
171           public SampleElements<Entry<String, Integer>> samples() {
172             return new SampleElements<Entry<String, Integer>>(
173                 mapEntry("a", 1),
174                 mapEntry("aa", 2),
175                 mapEntry("aba", 3),
176                 mapEntry("bbbb", 4),
177                 mapEntry("ccccc", 5));
178           }
179 
180           @Override
181           public SortedMap<String, Integer> create(Object... elements) {
182             SortedSet<String> set = new NonNavigableSortedSet();
183             for (Object e : elements) {
184               Entry<?, ?> entry = (Entry<?, ?>) e;
185               checkNotNull(entry.getValue());
186               set.add((String) checkNotNull(entry.getKey()));
187             }
188             return Maps.asMap(set, new Function<String, Integer>() {
189               @Override
190               public Integer apply(String input) {
191                 return input.length();
192               }
193             });
194           }
195 
196           @SuppressWarnings("unchecked")
197           @Override
198           public Entry<String, Integer>[] createArray(int length) {
199             return new Entry[length];
200           }
201 
202           @Override
203           public Iterable<Entry<String, Integer>> order(
204               List<Entry<String, Integer>> insertionOrder) {
205             Collections.sort(insertionOrder, new Comparator<Entry<String, Integer>>() {
206               @Override
207               public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
208                 return o1.getKey().compareTo(o2.getKey());
209               }
210             });
211             return insertionOrder;
212           }
213         })
214         .named("Maps.asMap[SortedSet, Function]")
215         .withFeatures(CollectionSize.ANY,
216             CollectionFeature.SUPPORTS_ITERATOR_REMOVE,
217             MapFeature.SUPPORTS_REMOVE)
218         .createTestSuite());
219     suite.addTest(NavigableMapTestSuiteBuilder
220         .using(new TestMapGenerator<String, Integer>() {
221           @Override
222           public String[] createKeyArray(int length) {
223             return new String[length];
224           }
225 
226           @Override
227           public Integer[] createValueArray(int length) {
228             return new Integer[length];
229           }
230 
231           @Override
232           public SampleElements<Entry<String, Integer>> samples() {
233             return new SampleElements<Entry<String, Integer>>(
234                 mapEntry("a", 1),
235                 mapEntry("aa", 2),
236                 mapEntry("aba", 3),
237                 mapEntry("bbbb", 4),
238                 mapEntry("ccccc", 5));
239           }
240 
241           @Override
242           public NavigableMap<String, Integer> create(Object... elements) {
243             NavigableSet<String> set = Sets.newTreeSet(Ordering.natural());
244             for (Object e : elements) {
245               Map.Entry<?, ?> entry = (Entry<?, ?>) e;
246               checkNotNull(entry.getValue());
247               set.add((String) checkNotNull(entry.getKey()));
248             }
249             return Maps.asMap(set, new Function<String, Integer>() {
250               @Override
251               public Integer apply(String input) {
252                 return input.length();
253               }
254             });
255           }
256 
257           @SuppressWarnings("unchecked")
258           @Override
259           public Entry<String, Integer>[] createArray(int length) {
260             return new Entry[length];
261           }
262 
263           @Override
264           public Iterable<Entry<String, Integer>> order(
265               List<Entry<String, Integer>> insertionOrder) {
266             Collections.sort(insertionOrder, new Comparator<Entry<String, Integer>>() {
267               @Override
268               public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
269                 return o1.getKey().compareTo(o2.getKey());
270               }
271             });
272             return insertionOrder;
273           }
274         })
275         .named("Maps.asMap[NavigableSet, Function]")
276         .withFeatures(CollectionSize.ANY,
277             MapFeature.SUPPORTS_REMOVE,
278             CollectionFeature.SUPPORTS_ITERATOR_REMOVE)
279         .createTestSuite());
280     suite.addTest(filterSuite());
281     suite.addTest(transformSuite());
282     return suite;
283   }
284 
285   static TestSuite filterSuite() {
286     TestSuite suite = new TestSuite("Filter");
287     suite.addTest(filterMapSuite());
288     suite.addTest(filterBiMapSuite());
289     suite.addTest(filterSortedMapSuite());
290     suite.addTest(filterNavigableMapSuite());
291     return suite;
292   }
293 
294   static TestSuite filterMapSuite() {
295     TestSuite suite = new TestSuite("FilterMap");
296     suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() {
297         @Override
298         protected Map<String, String> create(Entry<String, String>[] entries) {
299           Map<String, String> map = Maps.newHashMap();
300           putEntries(map, entries);
301           map.putAll(ENTRIES_TO_FILTER);
302           return Maps.filterKeys(map, FILTER_KEYS);
303         }
304       })
305       .named("Maps.filterKeys[Map, Predicate]")
306       .withFeatures(
307           MapFeature.ALLOWS_NULL_KEYS,
308           MapFeature.ALLOWS_NULL_VALUES,
309           MapFeature.ALLOWS_ANY_NULL_QUERIES,
310           MapFeature.GENERAL_PURPOSE,
311           CollectionSize.ANY)
312       .createTestSuite());
313     suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() {
314         @Override
315         protected Map<String, String> create(Entry<String, String>[] entries) {
316           Map<String, String> map = Maps.newHashMap();
317           putEntries(map, entries);
318           map.putAll(ENTRIES_TO_FILTER);
319           return Maps.filterValues(map, FILTER_VALUES);
320         }
321       })
322       .named("Maps.filterValues[Map, Predicate]")
323       .withFeatures(
324           MapFeature.ALLOWS_NULL_KEYS,
325           MapFeature.ALLOWS_NULL_VALUES,
326           MapFeature.ALLOWS_ANY_NULL_QUERIES,
327           MapFeature.GENERAL_PURPOSE,
328           CollectionSize.ANY)
329       .createTestSuite());
330     suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() {
331         @Override
332         protected Map<String, String> create(Entry<String, String>[] entries) {
333           Map<String, String> map = Maps.newHashMap();
334           putEntries(map, entries);
335            map.putAll(ENTRIES_TO_FILTER);
336           return Maps.filterEntries(map, FILTER_ENTRIES);
337         }
338       })
339       .named("Maps.filterEntries[Map, Predicate]")
340       .withFeatures(
341           MapFeature.ALLOWS_NULL_KEYS,
342           MapFeature.ALLOWS_NULL_VALUES,
343           MapFeature.ALLOWS_ANY_NULL_QUERIES,
344           MapFeature.GENERAL_PURPOSE,
345           CollectionSize.ANY)
346       .createTestSuite());
347     suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() {
348         @Override
349         protected Map<String, String> create(Entry<String, String>[] entries) {
350           Map<String, String> map = Maps.newHashMap();
351           putEntries(map, entries);
352           map.putAll(ENTRIES_TO_FILTER);
353           map = Maps.filterEntries(map, FILTER_ENTRIES_1);
354           return Maps.filterEntries(map, FILTER_ENTRIES_2);
355         }
356       })
357       .named("Maps.filterEntries[Maps.filterEntries[Map, Predicate], Predicate]")
358       .withFeatures(
359           MapFeature.ALLOWS_NULL_KEYS,
360           MapFeature.ALLOWS_NULL_VALUES,
361           MapFeature.ALLOWS_ANY_NULL_QUERIES,
362           MapFeature.GENERAL_PURPOSE,
363           CollectionSize.ANY)
364       .createTestSuite());
365     return suite;
366   }
367 
368   static TestSuite filterBiMapSuite() {
369     TestSuite suite = new TestSuite("FilterBiMap");
370     suite.addTest(BiMapTestSuiteBuilder.using(new TestStringBiMapGenerator() {
371         @Override
372         protected BiMap<String, String> create(Entry<String, String>[] entries) {
373           BiMap<String, String> map = HashBiMap.create();
374           putEntries(map, entries);
375           map.putAll(ENTRIES_TO_FILTER);
376           return Maps.filterKeys(map, FILTER_KEYS);
377         }
378       })
379       .named("Maps.filterKeys[BiMap, Predicate]")
380       .withFeatures(
381           MapFeature.ALLOWS_NULL_KEYS,
382           MapFeature.ALLOWS_NULL_VALUES,
383           MapFeature.GENERAL_PURPOSE,
384           CollectionSize.ANY)
385       .createTestSuite());
386     suite.addTest(BiMapTestSuiteBuilder.using(new TestStringBiMapGenerator() {
387         @Override
388         protected BiMap<String, String> create(Entry<String, String>[] entries) {
389           BiMap<String, String> map = HashBiMap.create();
390           putEntries(map, entries);
391           map.putAll(ENTRIES_TO_FILTER);
392           return Maps.filterValues(map, FILTER_VALUES);
393         }
394       })
395       .named("Maps.filterValues[BiMap, Predicate]")
396       .withFeatures(
397           MapFeature.ALLOWS_NULL_KEYS,
398           MapFeature.ALLOWS_NULL_VALUES,
399           MapFeature.ALLOWS_ANY_NULL_QUERIES,
400           MapFeature.GENERAL_PURPOSE,
401           CollectionSize.ANY)
402       .createTestSuite());
403     suite.addTest(BiMapTestSuiteBuilder.using(new TestStringBiMapGenerator() {
404         @Override
405         protected BiMap<String, String> create(Entry<String, String>[] entries) {
406           BiMap<String, String> map = HashBiMap.create();
407           putEntries(map, entries);
408           map.putAll(ENTRIES_TO_FILTER);
409           return Maps.filterEntries(map, FILTER_ENTRIES);
410         }
411       })
412       .named("Maps.filterEntries[BiMap, Predicate]")
413       .withFeatures(
414           MapFeature.ALLOWS_NULL_KEYS,
415           MapFeature.ALLOWS_NULL_VALUES,
416           MapFeature.ALLOWS_ANY_NULL_QUERIES,
417           MapFeature.GENERAL_PURPOSE,
418           CollectionSize.ANY)
419       .createTestSuite());
420     return suite;
421   }
422 
423   static TestSuite filterSortedMapSuite() {
424     TestSuite suite = new TestSuite("FilterSortedMap");
425     suite.addTest(SortedMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
426         @Override
427         protected SortedMap<String, String> create(Entry<String, String>[] entries) {
428           SortedMap<String, String> map = new NonNavigableSortedMap();
429           putEntries(map, entries);
430           map.putAll(ENTRIES_TO_FILTER);
431          return Maps.filterKeys(map, FILTER_KEYS);
432         }
433       })
434       .named("Maps.filterKeys[SortedMap, Predicate]")
435       .withFeatures(
436           MapFeature.ALLOWS_NULL_VALUES,
437           MapFeature.GENERAL_PURPOSE,
438           CollectionSize.ANY)
439       .createTestSuite());
440     suite.addTest(SortedMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
441         @Override
442         protected SortedMap<String, String> create(Entry<String, String>[] entries) {
443           SortedMap<String, String> map = new NonNavigableSortedMap();
444           putEntries(map, entries);
445           map.putAll(ENTRIES_TO_FILTER);
446           return Maps.filterValues(map, FILTER_VALUES);
447         }
448       })
449       .named("Maps.filterValues[SortedMap, Predicate]")
450       .withFeatures(
451           MapFeature.ALLOWS_NULL_VALUES,
452           MapFeature.GENERAL_PURPOSE,
453           CollectionSize.ANY)
454       .createTestSuite());
455     suite.addTest(SortedMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
456         @Override
457         protected SortedMap<String, String> create(Entry<String, String>[] entries) {
458           SortedMap<String, String> map = new NonNavigableSortedMap();
459           putEntries(map, entries);
460           map.putAll(ENTRIES_TO_FILTER);
461           return Maps.filterEntries(map, FILTER_ENTRIES);
462         }
463       })
464       .named("Maps.filterEntries[SortedMap, Predicate]")
465       .withFeatures(
466           MapFeature.ALLOWS_NULL_VALUES,
467           MapFeature.GENERAL_PURPOSE,
468           CollectionSize.ANY)
469       .createTestSuite());
470     return suite;
471   }
472 
473   static TestSuite filterNavigableMapSuite() {
474     TestSuite suite = new TestSuite("FilterNavigableMap");
475     suite.addTest(NavigableMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
476       @Override
477       protected NavigableMap<String, String> create(Entry<String, String>[] entries) {
478         NavigableMap<String, String> map = new SafeTreeMap<String, String>();
479         putEntries(map, entries);
480         map.put("banana", "toast");
481         map.put("eggplant", "spam");
482         return Maps.filterKeys(map, FILTER_KEYS);
483       }
484     })
485     .named("Maps.filterKeys[NavigableMap, Predicate]")
486     .withFeatures(
487         MapFeature.ALLOWS_NULL_VALUES,
488         MapFeature.GENERAL_PURPOSE,
489         CollectionSize.ANY)
490         .createTestSuite());
491     suite.addTest(NavigableMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
492       @Override
493       protected NavigableMap<String, String> create(Entry<String, String>[] entries) {
494         NavigableMap<String, String> map = new SafeTreeMap<String, String>();
495         putEntries(map, entries);
496         map.put("banana", "toast");
497         map.put("eggplant", "spam");
498           return Maps.filterValues(map, FILTER_VALUES);
499         }
500       })
501       .named("Maps.filterValues[NavigableMap, Predicate]")
502       .withFeatures(
503           MapFeature.ALLOWS_NULL_VALUES,
504           MapFeature.GENERAL_PURPOSE,
505           CollectionSize.ANY)
506           .createTestSuite());
507     suite.addTest(NavigableMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
508       @Override
509       protected NavigableMap<String, String> create(Entry<String, String>[] entries) {
510         NavigableMap<String, String> map = new SafeTreeMap<String, String>();
511         putEntries(map, entries);
512         map.put("banana", "toast");
513         map.put("eggplant", "spam");
514           return Maps.filterEntries(map, FILTER_ENTRIES);
515         }
516       })
517       .named("Maps.filterEntries[NavigableMap, Predicate]")
518       .withFeatures(
519           MapFeature.ALLOWS_NULL_VALUES,
520           MapFeature.GENERAL_PURPOSE,
521           CollectionSize.ANY)
522           .createTestSuite());
523     return suite;
524   }
525 
526   static void putEntries(Map<String, String> map, Entry<String, String>[] entries) {
527     for (Entry<String, String> entry : entries) {
528        map.put(entry.getKey(), entry.getValue());
529      }
530   }
531 
532   static final Predicate<String> FILTER_KEYS = new Predicate<String>() {
533     @Override
534     public boolean apply(@Nullable String string) {
535       return !"banana".equals(string) && !"eggplant".equals(string);
536     }
537   };
538 
539   static final Predicate<String> FILTER_VALUES = new Predicate<String>() {
540     @Override
541     public boolean apply(@Nullable String string) {
542       return !"toast".equals(string) && !"spam".equals(string);
543     }
544   };
545 
546   static final Predicate<Entry<String, String>> FILTER_ENTRIES =
547       new Predicate<Entry<String, String>>() {
548     @Override
549     public boolean apply(Entry<String, String> entry) {
550       return !Helpers.mapEntry("banana", "toast").equals(entry)
551           && !Helpers.mapEntry("eggplant", "spam").equals(entry);
552     }
553   };
554 
555   static final Predicate<Entry<String, String>> FILTER_ENTRIES_1 =
556       new Predicate<Entry<String, String>>() {
557     @Override
558     public boolean apply(Entry<String, String> entry) {
559       return !Helpers.mapEntry("banana", "toast").equals(entry);
560     }
561   };
562 
563   static final Predicate<Entry<String, String>> FILTER_ENTRIES_2 =
564       new Predicate<Entry<String, String>>() {
565     @Override
566     public boolean apply(Entry<String, String> entry) {
567       return !Helpers.mapEntry("eggplant", "spam").equals(entry);
568     }
569   };
570 
571   static final Map<String, String> ENTRIES_TO_FILTER =
572       ImmutableMap.of("banana", "toast", "eggplant", "spam");
573 
574   static final Predicate<Entry<String, String>> NOT_NULL_ENTRY =
575       new Predicate<Entry<String, String>>() {
576     @Override
577     public boolean apply(Entry<String, String> entry) {
578       return entry.getKey() != null && entry.getValue() != null;
579     }
580   };
581 
582   private static class NonNavigableSortedSet
583       extends ForwardingSortedSet<String> {
584 
585     private final SortedSet<String> delegate = Sets.newTreeSet(Ordering.natural());
586 
587     @Override
588     protected SortedSet<String> delegate() {
589       return delegate;
590     }
591   }
592 
593   private static class NonNavigableSortedMap
594       extends ForwardingSortedMap<String, String> {
595 
596     private final SortedMap<String, String> delegate =
597         new SafeTreeMap<String, String>(Ordering.natural());
598 
599     @Override
600     protected SortedMap<String, String> delegate() {
601       return delegate;
602     }
603   }
604 
605   private static String encode(String str) {
606     return BaseEncoding.base64().encode(str.getBytes(Charsets.UTF_8));
607   }
608 
609   private static final Function<String, String> DECODE_FUNCTION = new Function<String, String>() {
610     @Override
611     public String apply(String input) {
612       return new String(BaseEncoding.base64().decode(input), Charsets.UTF_8);
613     }
614   };
615 
616   private static final EntryTransformer<String, String, String> DECODE_ENTRY_TRANSFORMER =
617       new EntryTransformer<String, String, String>() {
618     @Override
619     public String transformEntry(String key, String value) {
620       return DECODE_FUNCTION.apply(value);
621     }
622   };
623 
624   static TestSuite transformSuite() {
625     TestSuite suite = new TestSuite("Maps.transform");
626     suite.addTest(transformMapSuite());
627     suite.addTest(transformSortedMapSuite());
628     suite.addTest(transformNavigableMapSuite());
629     return suite;
630   }
631 
632   static TestSuite transformMapSuite() {
633     TestSuite suite = new TestSuite("TransformMap");
634     suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() {
635         @Override
636         protected Map<String, String> create(Entry<String, String>[] entries) {
637           Map<String, String> map = Maps.newLinkedHashMap();
638           for (Entry<String, String> entry : entries) {
639             map.put(entry.getKey(), encode(entry.getValue()));
640           }
641           return Maps.transformValues(map, DECODE_FUNCTION);
642         }
643       })
644       .named("Maps.transformValues[Map, Function]")
645       .withFeatures(
646           CollectionSize.ANY,
647           CollectionFeature.KNOWN_ORDER,
648           MapFeature.ALLOWS_NULL_KEYS,
649           MapFeature.ALLOWS_ANY_NULL_QUERIES,
650           MapFeature.SUPPORTS_REMOVE,
651           CollectionFeature.SUPPORTS_ITERATOR_REMOVE)
652       .createTestSuite());
653     suite.addTest(MapTestSuiteBuilder.using(new TestStringMapGenerator() {
654         @Override
655         protected Map<String, String> create(Entry<String, String>[] entries) {
656           Map<String, String> map = Maps.newLinkedHashMap();
657           for (Entry<String, String> entry : entries) {
658             map.put(entry.getKey(), encode(entry.getValue()));
659           }
660           return Maps.transformEntries(map, DECODE_ENTRY_TRANSFORMER);
661         }
662       })
663       .named("Maps.transformEntries[Map, EntryTransformer]")
664       .withFeatures(
665           CollectionSize.ANY,
666           CollectionFeature.KNOWN_ORDER,
667           MapFeature.ALLOWS_NULL_KEYS,
668           MapFeature.ALLOWS_ANY_NULL_QUERIES,
669           MapFeature.SUPPORTS_REMOVE,
670           CollectionFeature.SUPPORTS_ITERATOR_REMOVE)
671       .createTestSuite());
672     return suite;
673   }
674 
675   static TestSuite transformSortedMapSuite() {
676     TestSuite suite = new TestSuite("TransformSortedMap");
677     suite.addTest(SortedMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
678         @Override
679         protected SortedMap<String, String> create(Entry<String, String>[] entries) {
680           SortedMap<String, String> map = new NonNavigableSortedMap();
681           for (Entry<String, String> entry : entries) {
682             map.put(entry.getKey(), encode(entry.getValue()));
683           }
684           return Maps.transformValues(map, DECODE_FUNCTION);
685         }
686       })
687       .named("Maps.transformValues[SortedMap, Function]")
688       .withFeatures(
689           CollectionSize.ANY,
690           CollectionFeature.KNOWN_ORDER,
691           MapFeature.SUPPORTS_REMOVE,
692           CollectionFeature.SUPPORTS_ITERATOR_REMOVE)
693       .createTestSuite());
694     suite.addTest(SortedMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
695         @Override
696         protected SortedMap<String, String> create(Entry<String, String>[] entries) {
697           SortedMap<String, String> map = new NonNavigableSortedMap();
698           for (Entry<String, String> entry : entries) {
699             map.put(entry.getKey(), encode(entry.getValue()));
700           }
701           return Maps.transformEntries(map, DECODE_ENTRY_TRANSFORMER);
702         }
703       })
704       .named("Maps.transformEntries[SortedMap, EntryTransformer]")
705       .withFeatures(
706           CollectionSize.ANY,
707           CollectionFeature.KNOWN_ORDER,
708           MapFeature.SUPPORTS_REMOVE,
709           CollectionFeature.SUPPORTS_ITERATOR_REMOVE)
710       .createTestSuite());
711     return suite;
712   }
713 
714   static TestSuite transformNavigableMapSuite() {
715     TestSuite suite = new TestSuite("TransformNavigableMap");
716     suite.addTest(NavigableMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
717         @Override
718         protected NavigableMap<String, String> create(Entry<String, String>[] entries) {
719           NavigableMap<String, String> map = new SafeTreeMap<String, String>();
720           for (Entry<String, String> entry : entries) {
721             map.put(entry.getKey(), encode(entry.getValue()));
722           }
723           return Maps.transformValues(map, DECODE_FUNCTION);
724         }
725       })
726       .named("Maps.transformValues[NavigableMap, Function]")
727       .withFeatures(
728           CollectionSize.ANY,
729           CollectionFeature.KNOWN_ORDER,
730           MapFeature.SUPPORTS_REMOVE,
731           CollectionFeature.SUPPORTS_ITERATOR_REMOVE)
732       .createTestSuite());
733     suite.addTest(NavigableMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() {
734         @Override
735         protected NavigableMap<String, String> create(Entry<String, String>[] entries) {
736           NavigableMap<String, String> map = new SafeTreeMap<String, String>();
737           for (Entry<String, String> entry : entries) {
738             map.put(entry.getKey(), encode(entry.getValue()));
739           }
740           return Maps.transformEntries(map, DECODE_ENTRY_TRANSFORMER);
741         }
742       })
743       .named("Maps.transformEntries[NavigableMap, EntryTransformer]")
744       .withFeatures(
745           CollectionSize.ANY,
746           CollectionFeature.KNOWN_ORDER,
747           MapFeature.SUPPORTS_REMOVE,
748           CollectionFeature.SUPPORTS_ITERATOR_REMOVE)
749       .createTestSuite());
750     return suite;
751   }
752 }
753