/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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.apache.commons.collections4.set; import java.util.Iterator; import java.util.NavigableSet; import java.util.TreeSet; import org.apache.commons.collections4.BulkTest; /** * Abstract test class for {@link NavigableSet} methods and contracts. * <p> * To use, subclass and override the {@link #makeObject()} * method. You may have to override other protected methods if your * set is not modifiable, or if your set restricts what kinds of * elements may be added; see {@link AbstractSetTest} for more details. * * @since 4.1 * @version $Id$ */ public abstract class AbstractNavigableSetTest<E> extends AbstractSortedSetTest<E> { /** * JUnit constructor. * * @param name name for test */ public AbstractNavigableSetTest(final String name) { super(name); } //----------------------------------------------------------------------- /** * {@inheritDoc} */ @Override public abstract NavigableSet<E> makeObject(); /** * {@inheritDoc} */ @Override public NavigableSet<E> makeFullCollection() { return (NavigableSet<E>) super.makeFullCollection(); } //----------------------------------------------------------------------- /** * Returns an empty {@link TreeSet} for use in modification testing. * * @return a confirmed empty collection */ @Override public NavigableSet<E> makeConfirmedCollection() { return new TreeSet<E>(); } //----------------------------------------------------------------------- /** * Verification extension, will check the order of elements, * the sets should already be verified equal. */ @Override public void verify() { super.verify(); // Check that descending iterator returns elements in order and higher(), lower(), // floor() and ceiling() are consistent final Iterator<E> colliter = getCollection().descendingIterator(); final Iterator<E> confiter = getConfirmed().descendingIterator(); while (colliter.hasNext()) { final E element = colliter.next(); final E confelement = confiter.next(); assertEquals("Element appears to be out of order.", confelement, element); assertEquals("Incorrect element returned by higher().", getConfirmed().higher(element), getCollection().higher(element)); assertEquals("Incorrect element returned by lower().", getConfirmed().lower(element), getCollection().lower(element)); assertEquals("Incorrect element returned by floor().", getConfirmed().floor(element), getCollection().floor(element)); assertEquals("Incorrect element returned by ceiling().", getConfirmed().ceiling(element), getCollection().ceiling(element)); } } //----------------------------------------------------------------------- /** * Override to return comparable objects. */ @Override @SuppressWarnings("unchecked") public E[] getFullNonNullElements() { final Object[] elements = new Object[30]; for (int i = 0; i < 30; i++) { elements[i] = Integer.valueOf(i + i + 1); } return (E[]) elements; } /** * Override to return comparable objects. */ @Override @SuppressWarnings("unchecked") public E[] getOtherNonNullElements() { final Object[] elements = new Object[30]; for (int i = 0; i < 30; i++) { elements[i] = Integer.valueOf(i + i + 2); } return (E[]) elements; } //----------------------------------------------------------------------- /** * Bulk test {@link NavigableSet#subSet(Object, boolean, Object, boolean)}. * This method runs through all of the tests in {@link AbstractNavigableSetTest}. * After modification operations, {@link #verify()} is invoked to ensure * that the set and the other collection views are still valid. * * @return a {@link AbstractNavigableSetTest} instance for testing a subset. */ public BulkTest bulkTestNavigableSetSubSet() { final int length = getFullElements().length; final int lobound = length / 3; final int hibound = lobound * 2; return new TestNavigableSetSubSet(lobound, hibound, false); } /** * Bulk test {@link NavigableSet#headSet(Object, boolean)}. * This method runs through all of the tests in {@link AbstractNavigableSetTest}. * After modification operations, {@link #verify()} is invoked to ensure * that the set and the other collection views are still valid. * * @return a {@link AbstractNavigableSetTest} instance for testing a headset. */ public BulkTest bulkTestNavigableSetHeadSet() { final int length = getFullElements().length; final int lobound = length / 3; final int hibound = lobound * 2; return new TestNavigableSetSubSet(hibound, true, true); } /** * Bulk test {@link NavigableSet#tailSet(Object, boolean)}. * This method runs through all of the tests in {@link AbstractNavigableSetTest}. * After modification operations, {@link #verify()} is invoked to ensure * that the set and the other collection views are still valid. * * @return a {@link AbstractNavigableSetTest} instance for testing a tailset. */ public BulkTest bulkTestNavigableSetTailSet() { final int length = getFullElements().length; final int lobound = length / 3; return new TestNavigableSetSubSet(lobound, false, false); } public class TestNavigableSetSubSet extends AbstractNavigableSetTest<E> { private int m_Type; private int m_LowBound; private int m_HighBound; private E[] m_FullElements; private E[] m_OtherElements; private boolean m_Inclusive; @SuppressWarnings("unchecked") public TestNavigableSetSubSet(final int bound, final boolean head, final boolean inclusive) { super("TestNavigableSetSubSet"); if (head) { m_Type = TYPE_HEADSET; m_Inclusive = inclusive; m_HighBound = bound; final int realBound = inclusive ? bound + 1 : bound; m_FullElements = (E[]) new Object[realBound]; System.arraycopy(AbstractNavigableSetTest.this.getFullElements(), 0, m_FullElements, 0, realBound); m_OtherElements = (E[]) new Object[bound - 1]; System.arraycopy(//src src_pos dst dst_pos length AbstractNavigableSetTest.this.getOtherElements(), 0, m_OtherElements, 0, bound - 1); } else { m_Type = TYPE_TAILSET; m_Inclusive = inclusive; m_LowBound = bound; final Object[] allelements = AbstractNavigableSetTest.this.getFullElements(); final int realBound = inclusive ? bound : bound + 1; m_FullElements = (E[]) new Object[allelements.length - realBound]; System.arraycopy(allelements, realBound, m_FullElements, 0, allelements.length - realBound); m_OtherElements = (E[]) new Object[allelements.length - bound - 1]; System.arraycopy(//src src_pos dst dst_pos length AbstractNavigableSetTest.this.getOtherElements(), bound, m_OtherElements, 0, allelements.length - bound - 1); } } //type @SuppressWarnings("unchecked") public TestNavigableSetSubSet(final int lobound, final int hibound, final boolean inclusive) { super("TestNavigableSetSubSet"); m_Type = TYPE_SUBSET; m_LowBound = lobound; m_HighBound = hibound; m_Inclusive = inclusive; final int fullLoBound = inclusive ? lobound : lobound + 1; final int length = hibound - lobound + 1 - (inclusive ? 0 : 2); m_FullElements = (E[]) new Object[length]; System.arraycopy(AbstractNavigableSetTest.this.getFullElements(), fullLoBound, m_FullElements, 0, length); final int otherLength = hibound - lobound; m_OtherElements = (E[]) new Object[otherLength - 1]; System.arraycopy(//src src_pos dst dst_pos length AbstractNavigableSetTest.this.getOtherElements(), lobound, m_OtherElements, 0, otherLength - 1); } @Override public boolean isNullSupported() { return AbstractNavigableSetTest.this.isNullSupported(); } @Override public boolean isAddSupported() { return AbstractNavigableSetTest.this.isAddSupported(); } @Override public boolean isRemoveSupported() { return AbstractNavigableSetTest.this.isRemoveSupported(); } @Override public boolean isFailFastSupported() { return AbstractNavigableSetTest.this.isFailFastSupported(); } @Override public E[] getFullElements() { return m_FullElements; } @Override public E[] getOtherElements() { return m_OtherElements; } private NavigableSet<E> getSubSet(final NavigableSet<E> set) { final E[] elements = AbstractNavigableSetTest.this.getFullElements(); switch (m_Type) { case TYPE_SUBSET : return set.subSet(elements[m_LowBound], m_Inclusive, elements[m_HighBound], m_Inclusive); case TYPE_HEADSET : return set.headSet(elements[m_HighBound], m_Inclusive); case TYPE_TAILSET : return set.tailSet(elements[m_LowBound], m_Inclusive); default : return null; } } @Override public NavigableSet<E> makeObject() { return getSubSet(AbstractNavigableSetTest.this.makeObject()); } @Override public NavigableSet<E> makeFullCollection() { return getSubSet(AbstractNavigableSetTest.this.makeFullCollection()); } @Override public boolean isTestSerialization() { return false; } @Override public BulkTest bulkTestSortedSetSubSet() { return null; // prevent infinite recursion } @Override public BulkTest bulkTestSortedSetHeadSet() { return null; // prevent infinite recursion } @Override public BulkTest bulkTestSortedSetTailSet() { return null; // prevent infinite recursion } @Override public BulkTest bulkTestNavigableSetSubSet() { return null; // prevent infinite recursion } @Override public BulkTest bulkTestNavigableSetHeadSet() { return null; // prevent infinite recursion } @Override public BulkTest bulkTestNavigableSetTailSet() { return null; // prevent infinite recursion } static final int TYPE_SUBSET = 0; static final int TYPE_TAILSET = 1; static final int TYPE_HEADSET = 2; } /** * {@inheritDoc} */ @Override public NavigableSet<E> getCollection() { return (NavigableSet<E>) super.getCollection(); } /** * {@inheritDoc} */ @Override public NavigableSet<E> getConfirmed() { return (NavigableSet<E>) super.getConfirmed(); } }