/*
 *  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.collections.iterators;

import java.util.Iterator;
import java.util.NoSuchElementException;

import org.apache.commons.collections.AbstractTestObject;

/**
 * Abstract class for testing the Iterator interface.
 * <p>
 * This class provides a framework for testing an implementation of Iterator.
 * Concrete subclasses must provide the iterator to be tested.
 * They must also specify certain details of how the iterator operates by
 * overriding the supportsXxx() methods if necessary.
 * 
 * @since Commons Collections 3.0
 * @version $Revision: 646780 $ $Date: 2008-04-10 13:48:07 +0100 (Thu, 10 Apr 2008) $
 * 
 * @author Morgan Delagrange
 * @author Stephen Colebourne
 */
public abstract class AbstractTestIterator extends AbstractTestObject {

    /**
     * JUnit constructor.
     * 
     * @param testName  the test class name
     */
    public AbstractTestIterator(String testName) {
        super(testName);
    }

    //-----------------------------------------------------------------------
    /**
     * Implement this method to return an iterator over an empty collection.
     * 
     * @return an empty iterator
     */
    public abstract Iterator makeEmptyIterator();

    /**
     * Implement this method to return an iterator over a collection with elements.
     * 
     * @return a full iterator
     */
    public abstract Iterator makeFullIterator();

    /**
     * Implements the abstract superclass method to return the full iterator.
     * 
     * @return a full iterator
     */
    public Object makeObject() {
        return makeFullIterator();
    }

    /**
     * Whether or not we are testing an iterator that can be empty.
     * Default is true.
     * 
     * @return true if Iterator can be empty
     */
    public boolean supportsEmptyIterator() {
        return true;
    }

    /**
     * Whether or not we are testing an iterator that can contain elements.
     * Default is true.
     * 
     * @return true if Iterator can be full
     */
    public boolean supportsFullIterator() {
        return true;
    }

    /**
     * Whether or not we are testing an iterator that supports remove().
     * Default is true.
     * 
     * @return true if Iterator supports remove
     */
    public boolean supportsRemove() {
        return true;
    }

    /**
     * Allows subclasses to add complex cross verification
     */
    public void verify() {
        // do nothing
    }

    //-----------------------------------------------------------------------
    /**
     * Test the empty iterator.
     */
    public void testEmptyIterator() {
        if (supportsEmptyIterator() == false) {
            return;
        }

        Iterator it = makeEmptyIterator();
        
        // hasNext() should return false
        assertEquals("hasNext() should return false for empty iterators", false, it.hasNext());
        
        // next() should throw a NoSuchElementException
        try {
            it.next();
            fail("NoSuchElementException must be thrown when Iterator is exhausted");
        } catch (NoSuchElementException e) {
        }
        verify();
        
        assertNotNull(it.toString());
    }

    /**
     * Test normal iteration behaviour.
     */
    public void testFullIterator() {
        if (supportsFullIterator() == false) {
            return;
        }

        Iterator it = makeFullIterator();

        // hasNext() must be true (ensure makeFullIterator is correct!)
        assertEquals("hasNext() should return true for at least one element", true, it.hasNext());

        // next() must not throw exception (ensure makeFullIterator is correct!)
        try {
            it.next();
        } catch (NoSuchElementException e) {
            fail("Full iterators must have at least one element");
        }

        // iterate through
        while (it.hasNext()) {
            it.next();
            verify();
        }

        // next() must throw NoSuchElementException now
        try {
            it.next();
            fail("NoSuchElementException must be thrown when Iterator is exhausted");
        } catch (NoSuchElementException e) {
        }
        
        assertNotNull(it.toString());
    }

    /**
     * Test remove behaviour.
     */
    public void testRemove() {
        Iterator it = makeFullIterator();
        
        if (supportsRemove() == false) {
            // check for UnsupportedOperationException if not supported
            try {
                it.remove();
            } catch (UnsupportedOperationException ex) {}
            return;
        }
        
        // should throw IllegalStateException before next() called
        try {
            it.remove();
            fail();
        } catch (IllegalStateException ex) {}
        verify();
        
        // remove after next should be fine
        it.next();
        it.remove();
        
        // should throw IllegalStateException for second remove()
        try {
            it.remove();
            fail();
        } catch (IllegalStateException ex) {}
    }
    
}
