/* * Copyright 2014-2017 Real Logic Ltd. * * 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 org.agrona.collections; import org.junit.Test; import java.util.*; import static org.hamcrest.Matchers.*; import static org.hamcrest.core.IsEqual.equalTo; import static org.junit.Assert.*; public class ObjectHashSetIntegerTest { private static final int INITIAL_CAPACITY = 100; private final ObjectHashSet<Integer> testSet = new ObjectHashSet<>(INITIAL_CAPACITY); @Test public void initiallyContainsNoElements() throws Exception { for (int i = 0; i < 10_000; i++) { assertFalse(testSet.contains(i)); } } @Test public void initiallyContainsNoBoxedElements() { for (int i = 0; i < 10_000; i++) { //noinspection UnnecessaryBoxing assertFalse(testSet.contains(Integer.valueOf(i))); } } @Test public void containsAddedElement() { assertTrue(testSet.add(1)); assertTrue(testSet.contains(1)); } @Test public void addingAnElementTwiceDoesNothing() { assertTrue(testSet.add(1)); assertFalse(testSet.add(1)); } @Test public void containsAddedBoxedElements() { assertTrue(testSet.add(1)); //noinspection UnnecessaryBoxing assertTrue(testSet.add(Integer.valueOf(2))); //noinspection UnnecessaryBoxing assertTrue(testSet.contains(Integer.valueOf(1))); assertTrue(testSet.contains(2)); } @Test public void doesNotContainMissingValue() { assertFalse(testSet.contains(2048)); } @Test public void removingAnElementFromAnEmptyListDoesNothing() { assertFalse(testSet.remove(0)); } @Test public void removingAPresentElementRemovesIt() { assertTrue(testSet.add(1)); assertTrue(testSet.remove(1)); assertFalse(testSet.contains(1)); } @Test public void sizeIsInitiallyZero() { assertEquals(0, testSet.size()); } @Test public void sizeIncrementsWithNumberOfAddedElements() { addTwoElements(testSet); assertEquals(2, testSet.size()); } @Test public void sizeContainsNumberOfNewElements() { testSet.add(1); testSet.add(1); assertEquals(1, testSet.size()); } @Test public void iteratorsListElements() { addTwoElements(testSet); assertIteratorHasElements(); } @Test public void iteratorsStartFromTheBeginningEveryTime() { iteratorsListElements(); assertIteratorHasElements(); } @Test public void iteratorsListElementsWithoutHasNext() { addTwoElements(testSet); assertIteratorHasElementsWithoutHasNext(); } @Test public void iteratorsStartFromTheBeginningEveryTimeWithoutHasNext() { iteratorsListElementsWithoutHasNext(); assertIteratorHasElementsWithoutHasNext(); } @Test(expected = NoSuchElementException.class) public void iteratorsThrowNoSuchElementException() { addTwoElements(testSet); exhaustIterator(); } @Test(expected = NoSuchElementException.class) public void iteratorsThrowNoSuchElementExceptionFromTheBeginningEveryTime() { addTwoElements(testSet); try { exhaustIterator(); } catch (final NoSuchElementException ignore) { } exhaustIterator(); } @Test public void iteratorHasNoElements() { assertFalse(testSet.iterator().hasNext()); } @Test(expected = NoSuchElementException.class) public void iteratorThrowExceptionForEmptySet() { testSet.iterator().next(); } @Test public void clearRemovesAllElementsOfTheSet() { addTwoElements(testSet); testSet.clear(); assertEquals(0, testSet.size()); assertFalse(testSet.contains(1)); assertFalse(testSet.contains(1001)); } @Test public void differenceReturnsNullIfBothSetsEqual() { addTwoElements(testSet); final ObjectHashSet<Integer> other = new ObjectHashSet<>(100); addTwoElements(other); assertNull(testSet.difference(other)); } @Test public void differenceReturnsSetDifference() { addTwoElements(testSet); final ObjectHashSet<Integer> other = new ObjectHashSet<>(100); other.add(1); final ObjectHashSet<Integer> diff = testSet.difference(other); assertThat(diff, containsInAnyOrder(1001)); } @Test public void copiesOtherIntHashSet() { addTwoElements(testSet); final ObjectHashSet<Integer> other = new ObjectHashSet<>(100); other.copy(testSet); assertContainsElements(other); } @Test public void twoEmptySetsAreEqual() { final ObjectHashSet other = new ObjectHashSet(100); assertEquals(testSet, other); } @Test public void setsWithTheSameValuesAreEqual() { final ObjectHashSet<Integer> other = new ObjectHashSet<>(100); addTwoElements(testSet); addTwoElements(other); assertEquals(testSet, other); } @Test public void setsWithTheDifferentSizesAreNotEqual() { final ObjectHashSet<Integer> other = new ObjectHashSet<>(100); addTwoElements(testSet); other.add(1001); assertNotEquals(testSet, other); } @Test public void setsWithTheDifferentValuesAreNotEqual() { final ObjectHashSet<Integer> other = new ObjectHashSet<>(100); addTwoElements(testSet); other.add(2); other.add(1001); assertNotEquals(testSet, other); } @Test public void twoEmptySetsHaveTheSameHashcode() { assertEquals(testSet.hashCode(), new ObjectHashSet<Integer>(100).hashCode()); } @Test public void setsWithTheSameValuesHaveTheSameHashcode() { addTwoElements(testSet); final ObjectHashSet<Integer> secondSet = new ObjectHashSet<>(100); addTwoElements(secondSet); assertEquals(testSet.hashCode(), secondSet.hashCode()); } @Test public void reducesSizeWhenElementRemoved() { addTwoElements(testSet); testSet.remove(1001); assertEquals(1, testSet.size()); } @Test(expected = NullPointerException.class) public void toArrayThrowsNullPointerExceptionForNullArgument() { //noinspection ConstantConditions testSet.toArray(null); } @Test public void toArrayCopiesElementsIntoSufficientlySizedArray() { addTwoElements(testSet); final Integer[] result = testSet.toArray(new Integer[testSet.size()]); assertArrayContainingElements(result); } @Test public void toArrayCopiesElementsIntoNewArray() { addTwoElements(testSet); final Integer[] result = testSet.toArray(new Integer[testSet.size()]); assertArrayContainingElements(result); } @Test public void toArraySupportsEmptyCollection() { final Integer[] result = testSet.toArray(new Integer[testSet.size()]); assertArrayEquals(result, new Integer[]{}); } // Test case from usage bug. @Test public void chainCompactionShouldNotCauseElementsToBeMovedBeforeTheirHash() { final ObjectHashSet<Integer> requiredFields = new ObjectHashSet<>(14); requiredFields.add(8); requiredFields.add(9); requiredFields.add(35); requiredFields.add(49); requiredFields.add(56); assertTrue("Failed to remove 8", requiredFields.remove(8)); assertTrue("Failed to remove 9", requiredFields.remove(9)); assertThat(requiredFields, containsInAnyOrder(35, 49, 56)); } @Test public void shouldResizeWhenItHitsCapacity() { for (int i = 0; i < 2 * INITIAL_CAPACITY; i++) { assertTrue(testSet.add(i)); } for (int i = 0; i < 2 * INITIAL_CAPACITY; i++) { assertTrue(testSet.contains(i)); } } @Test public void containsEmptySet() { final ObjectHashSet<Integer> other = new ObjectHashSet<>(100); assertTrue(testSet.containsAll(other)); } @Test public void containsSubset() { addTwoElements(testSet); final ObjectHashSet<Integer> subset = new ObjectHashSet<>(100); subset.add(1); assertTrue(testSet.containsAll(subset)); } @Test public void doesNotContainDisjointSet() { addTwoElements(testSet); final ObjectHashSet<Integer> other = new ObjectHashSet<>(100); other.add(1); other.add(1002); assertFalse(testSet.containsAll(other)); } @Test public void doesNotContainSuperset() { addTwoElements(testSet); final ObjectHashSet<Integer> superset = new ObjectHashSet<>(100); addTwoElements(superset); superset.add(15); assertFalse(testSet.containsAll(superset)); } @Test public void addingEmptySetDoesNothing() { addTwoElements(testSet); assertFalse(testSet.addAll(new ObjectHashSet<>(100))); assertContainsElements(testSet); } @Test public void addingSubsetDoesNothing() { addTwoElements(testSet); final ObjectHashSet<Integer> subset = new ObjectHashSet<>(100); subset.add(1); assertFalse(testSet.addAll(subset)); assertContainsElements(testSet); } @Test public void addingEqualSetDoesNothing() { addTwoElements(testSet); final ObjectHashSet<Integer> equal = new ObjectHashSet<>(100); addTwoElements(equal); assertFalse(testSet.addAll(equal)); assertContainsElements(testSet); } @Test public void containsValuesAddedFromDisjointSet() { addTwoElements(testSet); final ObjectHashSet<Integer> disjoint = new ObjectHashSet<>(100); disjoint.add(2); disjoint.add(1002); assertTrue(testSet.addAll(disjoint)); assertTrue(testSet.contains(1)); assertTrue(testSet.contains(1001)); assertTrue(testSet.containsAll(disjoint)); } @Test public void containsValuesAddedFromIntersectingSet() { addTwoElements(testSet); final ObjectHashSet<Integer> intersecting = new ObjectHashSet<>(100); intersecting.add(1); intersecting.add(1002); assertTrue(testSet.addAll(intersecting)); assertTrue(testSet.contains(1)); assertTrue(testSet.contains(1001)); assertTrue(testSet.containsAll(intersecting)); } @Test public void removingEmptySetDoesNothing() { addTwoElements(testSet); assertFalse(testSet.removeAll(new ObjectHashSet<Integer>(100))); assertContainsElements(testSet); } @Test public void removingDisjointSetDoesNothing() { addTwoElements(testSet); final ObjectHashSet<Integer> disjoint = new ObjectHashSet<>(100); disjoint.add(2); disjoint.add(1002); assertFalse(testSet.removeAll(disjoint)); assertContainsElements(testSet); } @Test public void doesNotContainRemovedIntersectingSet() { addTwoElements(testSet); final ObjectHashSet<Integer> intersecting = new ObjectHashSet<>(100); intersecting.add(1); intersecting.add(1002); assertTrue(testSet.removeAll(intersecting)); assertTrue(testSet.contains(1001)); assertFalse(testSet.containsAll(intersecting)); } @Test public void isEmptyAfterRemovingEqualSet() { addTwoElements(testSet); final ObjectHashSet<Integer> equal = new ObjectHashSet<>(100); addTwoElements(equal); assertTrue(testSet.removeAll(equal)); assertTrue(testSet.isEmpty()); } @Test public void removeElementsFromIterator() { addTwoElements(testSet); final ObjectIterator intIterator = testSet.iterator(); while (intIterator.hasNext()) { if (intIterator.nextValue().equals(1)) { intIterator.remove(); } } assertThat(testSet, contains(1001)); assertThat(testSet, hasSize(1)); } @Test public void shouldGenerateStringRepresentation() { final int[] testEntries = {3, 1, -1, 19, 7, 11, 12, 7}; for (final int testEntry : testEntries) { testSet.add(testEntry); } final String mapAsAString = "{1, 3, 7, 11, 12, 19, -1}"; assertThat(testSet.toString(), equalTo(mapAsAString)); } @Test public void shouldIterateOverExpandedSet() { final HashSet<Integer> refSet = new HashSet<>(5); final ObjectHashSet<Integer> testSet = new ObjectHashSet<>(5); for (int i = 0; i < 20; i++) { refSet.add(i); testSet.add(i); } final ObjectIterator<Integer> iter = testSet.iterator(); for (int i = 0; i < 20; i++) { assertTrue(iter.hasNext()); assertTrue(refSet.contains(iter.next())); } assertFalse(iter.hasNext()); } private static void addTwoElements(final ObjectHashSet<Integer> obj) { obj.add(1); obj.add(1001); } private void assertIteratorHasElements() { final Iterator<Integer> iter = testSet.iterator(); final Set<Integer> values = new HashSet<>(); assertTrue(iter.hasNext()); values.add(iter.next()); assertTrue(iter.hasNext()); values.add(iter.next()); assertFalse(iter.hasNext()); assertContainsElements(values); } private void assertIteratorHasElementsWithoutHasNext() { final Iterator<Integer> iter = testSet.iterator(); final Set<Integer> values = new HashSet<>(); values.add(iter.next()); values.add(iter.next()); assertContainsElements(values); } private static void assertArrayContainingElements(final Integer[] result) { assertThat(result, arrayContainingInAnyOrder(1, 1001)); } private static void assertContainsElements(final Set<Integer> other) { assertThat(other, containsInAnyOrder(1, 1001)); } private void exhaustIterator() { final ObjectIterator iterator = testSet.iterator(); iterator.next(); iterator.next(); iterator.next(); } }