11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2011 The Guava Authors
31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License");
51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * you may not use this file except in compliance with the License.
61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * You may obtain a copy of the License at
71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0
91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software
111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * distributed under the License is distributed on an "AS IS" BASIS,
121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * See the License for the specific language governing permissions and
141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * limitations under the License.
151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.collect;
181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtCompatible;
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Function;
211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.base.Functions;
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.collect.testing.MapInterfaceTest;
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Collection;
251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Iterator;
261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Map;
271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.Set;
281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport javax.annotation.Nullable;
301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/**
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Tests for {@link Maps#transformValues} when the backing map's views
331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * have iterators that don't support {@code remove()}.
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Jared Levy
361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible
381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic class MapsTransformValuesUnmodifiableIteratorTest extends MapInterfaceTest<String, String> {
391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // TODO(jlevy): Move shared code of this class and MapsTransformValuesTest
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // to a superclass.
411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public MapsTransformValuesUnmodifiableIteratorTest() {
431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    super(true, true, false /*supportsPut*/, true, true, false);
441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static class UnmodifiableIteratorMap<K, V> extends ForwardingMap<K, V> {
471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final Map<K, V> delegate;
481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    UnmodifiableIteratorMap(Map<K, V> delegate) {
501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      this.delegate = delegate;
511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override protected Map<K, V> delegate() {
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return delegate;
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Set<K> keySet() {
581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return new ForwardingSet<K>() {
591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override protected Set<K> delegate() {
601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return delegate.keySet();
611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public Iterator<K> iterator() {
631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return Iterators.unmodifiableIterator(delegate.keySet().iterator());
641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public boolean removeAll(Collection<?> c) {
661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return delegate.keySet().removeAll(c);
671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public boolean retainAll(Collection<?> c) {
691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return delegate.keySet().retainAll(c);
701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      };
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Collection<V> values() {
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return new ForwardingCollection<V>() {
761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override protected Collection<V> delegate() {
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return delegate.values();
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public Iterator<V> iterator() {
801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return Iterators.unmodifiableIterator(delegate.values().iterator());
811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public boolean removeAll(Collection<?> c) {
831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return delegate.values().removeAll(c);
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public boolean retainAll(Collection<?> c) {
861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return delegate.values().retainAll(c);
871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      };
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    @Override public Set<Entry<K, V>> entrySet() {
921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return new ForwardingSet<Entry<K, V>>() {
931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override protected Set<Entry<K, V>> delegate() {
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return delegate.entrySet();
951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public Iterator<Entry<K, V>> iterator() {
971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return Iterators.unmodifiableIterator(delegate.entrySet().iterator());
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public boolean removeAll(Collection<?> c) {
1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return delegate.entrySet().removeAll(c);
1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        @Override public boolean retainAll(Collection<?> c) {
1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          return delegate.entrySet().retainAll(c);
1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      };
1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override protected Map<String, String> makeEmptyMap() {
1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, Integer> underlying = Maps.newHashMap();
1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return Maps.transformValues(
1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        new UnmodifiableIteratorMap<String, Integer>(underlying), Functions.toStringFunction());
1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override protected Map<String, String> makePopulatedMap() {
1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, Integer> underlying = Maps.newHashMap();
1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    underlying.put("a", 1);
1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    underlying.put("b", 2);
1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    underlying.put("c", 3);
1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return Maps.transformValues(
1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        new UnmodifiableIteratorMap<String, Integer>(underlying), Functions.toStringFunction());
1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override protected String getKeyNotInPopulatedMap()
1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throws UnsupportedOperationException {
1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return "z";
1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override protected String getValueNotInPopulatedMap()
1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throws UnsupportedOperationException {
1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return "26";
1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /** Helper assertion comparing two maps */
1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private void assertMapsEqual(Map<?, ?> expected, Map<?, ?> map) {
1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(expected, map);
1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(expected.hashCode(), map.hashCode());
1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(expected.entrySet(), map.entrySet());
1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Assert that expectedValues > mapValues and that
1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // mapValues > expectedValues; i.e. that expectedValues == mapValues.
1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Collection<?> expectedValues = expected.values();
1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Collection<?> mapValues = map.values();
1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(expectedValues.size(), mapValues.size());
1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(expectedValues.containsAll(mapValues));
1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(mapValues.containsAll(expectedValues));
1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTransformEmptyMapEquality() {
1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, String> map = Maps.transformValues(
1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ImmutableMap.<String, Integer>of(), Functions.toStringFunction());
1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertMapsEqual(Maps.newHashMap(), map);
1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTransformSingletonMapEquality() {
1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, String> map = Maps.transformValues(
1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ImmutableMap.of("a", 1), Functions.toStringFunction());
1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, String> expected = ImmutableMap.of("a", "1");
1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertMapsEqual(expected, map);
1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(expected.get("a"), map.get("a"));
1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTransformIdentityFunctionEquality() {
1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, Integer> underlying = ImmutableMap.of("a", 1);
1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, Integer> map = Maps.transformValues(
1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        underlying, Functions.<Integer>identity());
1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertMapsEqual(underlying, map);
1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTransformPutEntryIsUnsupported() {
1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, String> map = Maps.transformValues(
1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        ImmutableMap.of("a", 1), Functions.toStringFunction());
1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      map.put("b", "2");
1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {
1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      map.putAll(ImmutableMap.of("b", "2"));
1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {
1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      map.entrySet().iterator().next().setValue("one");
1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      fail();
1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (UnsupportedOperationException expected) {
1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTransformRemoveEntry() {
1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, Integer> underlying = Maps.newHashMap();
1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    underlying.put("a", 1);
1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, String> map
1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        = Maps.transformValues(underlying, Functions.toStringFunction());
1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("1", map.remove("a"));
1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertNull(map.remove("b"));
1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTransformEqualityOfMapsWithNullValues() {
2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, String> underlying = Maps.newHashMap();
2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    underlying.put("a", null);
2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    underlying.put("b", "");
2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, Boolean> map = Maps.transformValues(underlying,
2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        new Function<String, Boolean>() {
2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          @Override
2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          public Boolean apply(@Nullable String from) {
2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return from == null;
2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    );
2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, Boolean> expected = ImmutableMap.of("a", true, "b", false);
2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertMapsEqual(expected, map);
2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(expected.get("a"), map.get("a"));
2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(expected.containsKey("a"), map.containsKey("a"));
2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(expected.get("b"), map.get("b"));
2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(expected.containsKey("b"), map.containsKey("b"));
2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(expected.get("c"), map.get("c"));
2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(expected.containsKey("c"), map.containsKey("c"));
2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTransformReflectsUnderlyingMap() {
2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, Integer> underlying = Maps.newHashMap();
2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    underlying.put("a", 1);
2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    underlying.put("b", 2);
2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    underlying.put("c", 3);
2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, String> map
2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        = Maps.transformValues(underlying, Functions.toStringFunction());
2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(underlying.size(), map.size());
2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    underlying.put("d", 4);
2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(underlying.size(), map.size());
2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals("4", map.get("d"));
2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    underlying.remove("c");
2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(underlying.size(), map.size());
2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(map.containsKey("c"));
2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    underlying.clear();
2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertEquals(underlying.size(), map.size());
2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTransformChangesAreReflectedInUnderlyingMap() {
2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, Integer> underlying = Maps.newLinkedHashMap();
2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    underlying.put("a", 1);
2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    underlying.put("b", 2);
2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    underlying.put("c", 3);
2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    underlying.put("d", 4);
2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    underlying.put("e", 5);
2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    underlying.put("f", 6);
2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    underlying.put("g", 7);
2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, String> map
2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        = Maps.transformValues(underlying, Functions.toStringFunction());
2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    map.remove("a");
2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(underlying.containsKey("a"));
2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Set<String> keys = map.keySet();
2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    keys.remove("b");
2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(underlying.containsKey("b"));
2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Iterator<String> keyIterator = keys.iterator();
2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    keyIterator.next();
2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    keyIterator.remove();
2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(underlying.containsKey("c"));
2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Collection<String> values = map.values();
2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    values.remove("4");
2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(underlying.containsKey("d"));
2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Iterator<String> valueIterator = values.iterator();
2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    valueIterator.next();
2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    valueIterator.remove();
2761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(underlying.containsKey("e"));
2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Set<Map.Entry<String, String>> entries = map.entrySet();
2791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map.Entry<String, String> firstEntry = entries.iterator().next();
2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    entries.remove(firstEntry);
2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(underlying.containsKey("f"));
2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Iterator<Map.Entry<String, String>> entryIterator = entries.iterator();
2841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    entryIterator.next();
2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    entryIterator.remove();
2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(underlying.containsKey("g"));
2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(underlying.isEmpty());
2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(map.isEmpty());
2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(keys.isEmpty());
2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(values.isEmpty());
2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(entries.isEmpty());
2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTransformEquals() {
2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, Integer> underlying = ImmutableMap.of("a", 0, "b", 1, "c", 2);
2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, Integer> expected
2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        = Maps.transformValues(underlying, Functions.<Integer>identity());
2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertMapsEqual(expected, expected);
3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, Integer> equalToUnderlying = Maps.newTreeMap();
3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    equalToUnderlying.putAll(underlying);
3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, Integer> map = Maps.transformValues(
3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        equalToUnderlying, Functions.<Integer>identity());
3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertMapsEqual(expected, map);
3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    map = Maps.transformValues(ImmutableMap.of("a", 1, "b", 2, "c", 3),
3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        new Function<Integer, Integer>() {
3101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          @Override
3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          public Integer apply(Integer from) {
3121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return from - 1;
3131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
3141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    );
3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertMapsEqual(expected, map);
3171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public void testTransformEntrySetContains() {
3201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, Boolean> underlying = Maps.newHashMap();
3211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    underlying.put("a", null);
3221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    underlying.put("b", true);
3231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    underlying.put(null, true);
3241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Map<String, Boolean> map = Maps.transformValues(
3261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        underlying, new Function<Boolean, Boolean>() {
3271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          @Override
3281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          public Boolean apply(@Nullable Boolean from) {
3291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert            return (from == null) ? true : null;
3301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert          }
3311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        }
3321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    );
3331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    Set<Map.Entry<String, Boolean>> entries = map.entrySet();
3351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(entries.contains(Maps.immutableEntry("a", true)));
3361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(entries.contains(Maps.immutableEntry("b", (Boolean) null)));
3371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertTrue(entries.contains(
3381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        Maps.immutableEntry((String) null, (Boolean) null)));
3391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(entries.contains(Maps.immutableEntry("c", (Boolean) null)));
3411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    assertFalse(entries.contains(Maps.immutableEntry((String) null, true)));
3421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override public void testKeySetRemoveAllNullFromEmpty() {
3451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
3461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      super.testKeySetRemoveAllNullFromEmpty();
3471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (RuntimeException tolerated) {
3481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // GWT's HashMap.keySet().removeAll(null) doesn't throws NPE.
3491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
3521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  @Override public void testEntrySetRemoveAllNullFromEmpty() {
3531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    try {
3541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      super.testEntrySetRemoveAllNullFromEmpty();
3551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    } catch (RuntimeException tolerated) {
3561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      // GWT's HashMap.entrySet().removeAll(null) doesn't throws NPE.
3571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
3581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
3591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
360