All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.common.collect.testing.google.UnmodifiableCollectionTests Maven / Gradle / Ivy

Go to download

Guava testlib is a set of java classes used for more convenient unit testing - particularly to assist the tests for Guava itself.

There is a newer version: 33.1.0-jre
Show newest version
/*
 * Copyright (C) 2007 The Guava Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.common.collect.testing.google;

import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertTrue;
import static junit.framework.TestCase.fail;

import com.google.common.annotations.GwtCompatible;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Iterators;
import com.google.common.collect.LinkedHashMultiset;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multiset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;

/**
 * A series of tests that support asserting that collections cannot be modified, either through
 * direct or indirect means.
 *
 * @author Robert Konigsberg
 */
@GwtCompatible
public class UnmodifiableCollectionTests {

  public static void assertMapEntryIsUnmodifiable(Entry entry) {
    try {
      entry.setValue(null);
      fail("setValue on unmodifiable Map.Entry succeeded");
    } catch (UnsupportedOperationException expected) {
    }
  }

  /**
   * Verifies that an Iterator is unmodifiable.
   *
   * 

This test only works with iterators that iterate over a finite set. */ public static void assertIteratorIsUnmodifiable(Iterator iterator) { while (iterator.hasNext()) { iterator.next(); try { iterator.remove(); fail("Remove on unmodifiable iterator succeeded"); } catch (UnsupportedOperationException expected) { } } } /** * Asserts that two iterators contain elements in tandem. * *

This test only works with iterators that iterate over a finite set. */ public static void assertIteratorsInOrder( Iterator expectedIterator, Iterator actualIterator) { int i = 0; while (expectedIterator.hasNext()) { Object expected = expectedIterator.next(); assertTrue( "index " + i + " expected <" + expected + "., actual is exhausted", actualIterator.hasNext()); Object actual = actualIterator.next(); assertEquals("index " + i, expected, actual); i++; } if (actualIterator.hasNext()) { fail("index " + i + ", expected is exhausted, actual <" + actualIterator.next() + ">"); } } /** * Verifies that a collection is immutable. * *

A collection is considered immutable if: * *

    *
  1. All its mutation methods result in UnsupportedOperationException, and do not change the * underlying contents. *
  2. All methods that return objects that can indirectly mutate the collection throw * UnsupportedOperationException when those mutators are called. *
* * @param collection the presumed-immutable collection * @param sampleElement an element of the same type as that contained by {@code collection}. * {@code collection} may or may not have {@code sampleElement} as a member. */ public static void assertCollectionIsUnmodifiable(Collection collection, E sampleElement) { Collection siblingCollection = new ArrayList<>(); siblingCollection.add(sampleElement); Collection copy = new ArrayList<>(); // Avoid copy.addAll(collection), which runs afoul of an Android bug in older versions: // http://b.android.com/72073 http://r.android.com/98929 Iterators.addAll(copy, collection.iterator()); try { collection.add(sampleElement); fail("add succeeded on unmodifiable collection"); } catch (UnsupportedOperationException expected) { } assertCollectionsAreEquivalent(copy, collection); try { collection.addAll(siblingCollection); fail("addAll succeeded on unmodifiable collection"); } catch (UnsupportedOperationException expected) { } assertCollectionsAreEquivalent(copy, collection); try { collection.clear(); fail("clear succeeded on unmodifiable collection"); } catch (UnsupportedOperationException expected) { } assertCollectionsAreEquivalent(copy, collection); assertIteratorIsUnmodifiable(collection.iterator()); assertCollectionsAreEquivalent(copy, collection); try { collection.remove(sampleElement); fail("remove succeeded on unmodifiable collection"); } catch (UnsupportedOperationException expected) { } assertCollectionsAreEquivalent(copy, collection); try { collection.removeAll(siblingCollection); fail("removeAll succeeded on unmodifiable collection"); } catch (UnsupportedOperationException expected) { } assertCollectionsAreEquivalent(copy, collection); try { collection.retainAll(siblingCollection); fail("retainAll succeeded on unmodifiable collection"); } catch (UnsupportedOperationException expected) { } assertCollectionsAreEquivalent(copy, collection); } /** * Verifies that a set is immutable. * *

A set is considered immutable if: * *

    *
  1. All its mutation methods result in UnsupportedOperationException, and do not change the * underlying contents. *
  2. All methods that return objects that can indirectly mutate the set throw * UnsupportedOperationException when those mutators are called. *
* * @param set the presumed-immutable set * @param sampleElement an element of the same type as that contained by {@code set}. {@code set} * may or may not have {@code sampleElement} as a member. */ public static void assertSetIsUnmodifiable(Set set, E sampleElement) { assertCollectionIsUnmodifiable(set, sampleElement); } /** * Verifies that a multiset is immutable. * *

A multiset is considered immutable if: * *

    *
  1. All its mutation methods result in UnsupportedOperationException, and do not change the * underlying contents. *
  2. All methods that return objects that can indirectly mutate the multiset throw * UnsupportedOperationException when those mutators are called. *
* * @param multiset the presumed-immutable multiset * @param sampleElement an element of the same type as that contained by {@code multiset}. {@code * multiset} may or may not have {@code sampleElement} as a member. */ public static void assertMultisetIsUnmodifiable(Multiset multiset, final E sampleElement) { Multiset copy = LinkedHashMultiset.create(multiset); assertCollectionsAreEquivalent(multiset, copy); // Multiset is a collection, so we can use all those tests. assertCollectionIsUnmodifiable(multiset, sampleElement); assertCollectionsAreEquivalent(multiset, copy); try { multiset.add(sampleElement, 2); fail("add(Object, int) succeeded on unmodifiable collection"); } catch (UnsupportedOperationException expected) { } assertCollectionsAreEquivalent(multiset, copy); try { multiset.remove(sampleElement, 2); fail("remove(Object, int) succeeded on unmodifiable collection"); } catch (UnsupportedOperationException expected) { } assertCollectionsAreEquivalent(multiset, copy); assertCollectionsAreEquivalent(multiset, copy); assertSetIsUnmodifiable(multiset.elementSet(), sampleElement); assertCollectionsAreEquivalent(multiset, copy); assertSetIsUnmodifiable( multiset.entrySet(), new Multiset.Entry() { @Override public int getCount() { return 1; } @Override public E getElement() { return sampleElement; } }); assertCollectionsAreEquivalent(multiset, copy); } /** * Verifies that a multimap is immutable. * *

A multimap is considered immutable if: * *

    *
  1. All its mutation methods result in UnsupportedOperationException, and do not change the * underlying contents. *
  2. All methods that return objects that can indirectly mutate the multimap throw * UnsupportedOperationException when those mutators *
* * @param multimap the presumed-immutable multimap * @param sampleKey a key of the same type as that contained by {@code multimap}. {@code multimap} * may or may not have {@code sampleKey} as a key. * @param sampleValue a key of the same type as that contained by {@code multimap}. {@code * multimap} may or may not have {@code sampleValue} as a key. */ public static void assertMultimapIsUnmodifiable( Multimap multimap, final K sampleKey, final V sampleValue) { List> originalEntries = Collections.unmodifiableList(Lists.newArrayList(multimap.entries())); assertMultimapRemainsUnmodified(multimap, originalEntries); Collection sampleValueAsCollection = Collections.singleton(sampleValue); // Test #clear() try { multimap.clear(); fail("clear succeeded on unmodifiable multimap"); } catch (UnsupportedOperationException expected) { } assertMultimapRemainsUnmodified(multimap, originalEntries); // Test asMap().entrySet() assertSetIsUnmodifiable( multimap.asMap().entrySet(), Maps.immutableEntry(sampleKey, sampleValueAsCollection)); // Test #values() assertMultimapRemainsUnmodified(multimap, originalEntries); if (!multimap.isEmpty()) { Collection values = multimap.asMap().entrySet().iterator().next().getValue(); assertCollectionIsUnmodifiable(values, sampleValue); } // Test #entries() assertCollectionIsUnmodifiable(multimap.entries(), Maps.immutableEntry(sampleKey, sampleValue)); assertMultimapRemainsUnmodified(multimap, originalEntries); // Iterate over every element in the entry set for (Entry entry : multimap.entries()) { assertMapEntryIsUnmodifiable(entry); } assertMultimapRemainsUnmodified(multimap, originalEntries); // Test #keys() assertMultisetIsUnmodifiable(multimap.keys(), sampleKey); assertMultimapRemainsUnmodified(multimap, originalEntries); // Test #keySet() assertSetIsUnmodifiable(multimap.keySet(), sampleKey); assertMultimapRemainsUnmodified(multimap, originalEntries); // Test #get() if (!multimap.isEmpty()) { K key = multimap.keySet().iterator().next(); assertCollectionIsUnmodifiable(multimap.get(key), sampleValue); assertMultimapRemainsUnmodified(multimap, originalEntries); } // Test #put() try { multimap.put(sampleKey, sampleValue); fail("put succeeded on unmodifiable multimap"); } catch (UnsupportedOperationException expected) { } assertMultimapRemainsUnmodified(multimap, originalEntries); // Test #putAll(K, Collection) try { multimap.putAll(sampleKey, sampleValueAsCollection); fail("putAll(K, Iterable) succeeded on unmodifiable multimap"); } catch (UnsupportedOperationException expected) { } assertMultimapRemainsUnmodified(multimap, originalEntries); // Test #putAll(Multimap) Multimap multimap2 = ArrayListMultimap.create(); multimap2.put(sampleKey, sampleValue); try { multimap.putAll(multimap2); fail("putAll(Multimap) succeeded on unmodifiable multimap"); } catch (UnsupportedOperationException expected) { } assertMultimapRemainsUnmodified(multimap, originalEntries); // Test #remove() try { multimap.remove(sampleKey, sampleValue); fail("remove succeeded on unmodifiable multimap"); } catch (UnsupportedOperationException expected) { } assertMultimapRemainsUnmodified(multimap, originalEntries); // Test #removeAll() try { multimap.removeAll(sampleKey); fail("removeAll succeeded on unmodifiable multimap"); } catch (UnsupportedOperationException expected) { } assertMultimapRemainsUnmodified(multimap, originalEntries); // Test #replaceValues() try { multimap.replaceValues(sampleKey, sampleValueAsCollection); fail("replaceValues succeeded on unmodifiable multimap"); } catch (UnsupportedOperationException expected) { } assertMultimapRemainsUnmodified(multimap, originalEntries); // Test #asMap() try { multimap.asMap().remove(sampleKey); fail("asMap().remove() succeeded on unmodifiable multimap"); } catch (UnsupportedOperationException expected) { } assertMultimapRemainsUnmodified(multimap, originalEntries); if (!multimap.isEmpty()) { K presentKey = multimap.keySet().iterator().next(); try { multimap.asMap().get(presentKey).remove(sampleValue); fail("asMap().get().remove() succeeded on unmodifiable multimap"); } catch (UnsupportedOperationException expected) { } assertMultimapRemainsUnmodified(multimap, originalEntries); try { multimap.asMap().values().iterator().next().remove(sampleValue); fail("asMap().values().iterator().next().remove() succeeded on unmodifiable multimap"); } catch (UnsupportedOperationException expected) { } try { ((Collection) multimap.asMap().values().toArray()[0]).clear(); fail("asMap().values().toArray()[0].clear() succeeded on unmodifiable multimap"); } catch (UnsupportedOperationException expected) { } } assertCollectionIsUnmodifiable(multimap.values(), sampleValue); assertMultimapRemainsUnmodified(multimap, originalEntries); } private static void assertCollectionsAreEquivalent( Collection expected, Collection actual) { assertIteratorsInOrder(expected.iterator(), actual.iterator()); } private static void assertMultimapRemainsUnmodified( Multimap expected, List> actual) { assertIteratorsInOrder(expected.entries().iterator(), actual.iterator()); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy