package org.incava.doctorj;

import java.io.*;
import java.util.*;
import junit.framework.TestCase;


public class TestExceptionDocAnalyzer extends Tester
{
    public TestExceptionDocAnalyzer(String name)
    {
        super(name);
    }

    public void testMethodExceptionWithoutTag()
    {
        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @exception\n" +
                 "      */\n" +
                 "    public void method() throws IOException {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ExceptionDocAnalyzer.MSG_EXCEPTION_WITHOUT_CLASS_NAME, new Integer(4), new Integer(9),  new Integer(4), new Integer(18) },
                     { ExceptionDocAnalyzer.MSG_EXCEPTION_NOT_DOCUMENTED,     new Integer(6), new Integer(33), new Integer(6), new Integer(43) }
                 });
    }

    public void testMethodExceptionUndocumented()
    {
        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @exception IOException\n" +
                 "      */\n" +
                 "    public void method() throws IOException {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ExceptionDocAnalyzer.MSG_EXCEPTION_WITHOUT_DESCRIPTION, new Integer(4), new Integer(20), new Integer(4), new Integer(30) }
                 });
    }

    public void testMethodExceptionMisspelled()
    {
        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @exception IOExceptoin thrown on I/O error.\n" +
                 "      */\n" +
                 "    public void method() throws IOException {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ExceptionDocAnalyzer.MSG_EXCEPTION_MISSPELLED, new Integer(4), new Integer(20), new Integer(4), new Integer(30) }
                 });
    }
    
    public void testMethodExceptionAsNameMisspelled()
    {
        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @exception IOExceptoin thrown on I/O error.\n" +
                 "      */\n" +
                 "    public void method() throws java.io.IOException {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ExceptionDocAnalyzer.MSG_EXCEPTION_MISSPELLED, new Integer(4), new Integer(20), new Integer(4), new Integer(30) }
                 });
    }
    
    public void testMethodExceptionDocumentedButNotInCode()
    {
        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @exception IOException thrown on I/O error.\n" +
                 "      */\n" +
                 "    public void method() {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ExceptionDocAnalyzer.MSG_EXCEPTION_NOT_IN_THROWS_LIST, new Integer(4), new Integer(20), new Integer(4), new Integer(30) }
                 });

        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @exception FileNotFoundException thrown when there is no file\n" +
                 "      * @exception IOException thrown on I/O error.\n" +
                 "      */\n" +
                 "    public void method() throws FileNotFoundException {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ExceptionDocAnalyzer.MSG_EXCEPTION_NOT_IN_THROWS_LIST, new Integer(5), new Integer(20), new Integer(5), new Integer(30) }
                 });
    }

    public void testMethodExceptionNotDocumented()
    {
        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      */\n" +
                 "    public void method() throws IOException {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ExceptionDocAnalyzer.MSG_EXCEPTION_NOT_DOCUMENTED, new Integer(5), new Integer(33), new Integer(5), new Integer(43) }
                 });

        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @exception IOException thrown on I/O error.\n" +
                 "      */\n" +
                 "    public void method() throws java.io.IOException {}\n" +
                 "}\n",
                 new Object[][] { 
                 });

        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @exception java.io.IOException thrown on I/O error.\n" +
                 "      */\n" +
                 "    public void method() throws java.io.IOException {}\n" +
                 "}\n",
                 new Object[][] { 
                 });

        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @exception java.io.IOException thrown on I/O error.\n" +
                 "      */\n" +
                 "    public void method() throws IOException {}\n" +
                 "}\n",
                 new Object[][] { 
                 });
    }

    public void testMethodExceptionNotAlphabetical()
    {
        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @exception NullPointerException thrown when there is no file\n" +
                 "      * @exception IOException thrown on I/O error.\n" +
                 "      */\n" +
                 "    public void method() throws NullPointerException, IOException {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ExceptionDocAnalyzer.MSG_EXCEPTIONS_NOT_ALPHABETICAL, new Integer(5), new Integer(20), new Integer(5), new Integer(30) }
                 });

        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @exception ArrayIndexOutOfBoundsException thrown when index >= array.length\n" +
                 "      * @exception NullPointerException thrown when there is no file\n" +
                 "      * @exception IOException thrown on I/O error.\n" +
                 "      */\n" +
                 "    public void method() throws IOException {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ExceptionDocAnalyzer.MSG_EXCEPTIONS_NOT_ALPHABETICAL, new Integer(6), new Integer(20), new Integer(6), new Integer(30) }
                 });
    }

    public void testMethodExceptionRuntimeExceptionNotDeclared()
    {
        List runtimeExceptions = new ArrayList();
        runtimeExceptions.add("ArithmeticException");
        runtimeExceptions.add("ArrayIndexOutOfBoundsException");
        runtimeExceptions.add("ArrayStoreException");
        runtimeExceptions.add("BufferOverflowException");
        runtimeExceptions.add("BufferUnderflowException");
        runtimeExceptions.add("CMMException");
        runtimeExceptions.add("CannotRedoException");
        runtimeExceptions.add("CannotUndoException");
        runtimeExceptions.add("ClassCastException");
        runtimeExceptions.add("ConcurrentModificationException");
        runtimeExceptions.add("DOMException");
        runtimeExceptions.add("EmptyStackException");
        runtimeExceptions.add("IllegalArgumentException");
        runtimeExceptions.add("IllegalMonitorStateException");
        runtimeExceptions.add("IllegalPathStateException");
        runtimeExceptions.add("IllegalStateException");
        runtimeExceptions.add("ImagingOpException");
        runtimeExceptions.add("IndexOutOfBoundsException");
        runtimeExceptions.add("MissingResourceException");
        runtimeExceptions.add("NegativeArraySizeException");
        runtimeExceptions.add("NoSuchElementException");
        runtimeExceptions.add("NullPointerException");
        runtimeExceptions.add("ProfileDataException");
        runtimeExceptions.add("ProviderException");
        runtimeExceptions.add("RasterFormatException");
        runtimeExceptions.add("SecurityException");
        runtimeExceptions.add("StringIndexOutOfBoundsException");
        runtimeExceptions.add("SystemException");
        runtimeExceptions.add("UndeclaredThrowableException");
        runtimeExceptions.add("UnmodifiableSetException");
        runtimeExceptions.add("UnsupportedOperationException");

        Iterator it = runtimeExceptions.iterator();
        while (it.hasNext()) {
            String rtexc = (String)it.next();

            evaluate("/** This is a description.\n" +
                     "  */\n" +
                     "class Test {\n" +
                     "    /** This is a description.\n" +
                     "      * @exception " + rtexc + " This is a description.\n" +
                     "      */\n" +
                     "    public void method() {}\n" +
                     "}\n",
                     new Object[][] { 
                     });
        }
    }
    
    public void testCtorExceptionWithoutTag()
    {
        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @exception\n" +
                 "      */\n" +
                 "    public TestExceptionDocAnalyzer() throws IOException {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ExceptionDocAnalyzer.MSG_EXCEPTION_WITHOUT_CLASS_NAME, new Integer(4), new Integer(9),  new Integer(4), new Integer(18) },
                     { ExceptionDocAnalyzer.MSG_EXCEPTION_NOT_DOCUMENTED,     new Integer(6), new Integer(46), new Integer(6), new Integer(56) }
                 });
    }

    public void testCtorExceptionUndocumented()
    {
        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @exception IOException\n" +
                 "      */\n" +
                 "    public TestExceptionDocAnalyzer() throws IOException {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ExceptionDocAnalyzer.MSG_EXCEPTION_WITHOUT_DESCRIPTION, new Integer(4), new Integer(20), new Integer(4), new Integer(30) }
                 });
    }

    public void testCtorExceptionMisspelled()
    {
        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @exception IOExceptoin thrown on I/O error.\n" +
                 "      */\n" +
                 "    public TestExceptionDocAnalyzer() throws IOException {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ExceptionDocAnalyzer.MSG_EXCEPTION_MISSPELLED, new Integer(4), new Integer(20), new Integer(4), new Integer(30) }
                 });
    }
    
    public void testCtorExceptionAsNameMisspelled()
    {
        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @exception IOExceptoin thrown on I/O error.\n" +
                 "      */\n" +
                 "    public TestExceptionDocAnalyzer() throws java.io.IOException {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ExceptionDocAnalyzer.MSG_EXCEPTION_MISSPELLED, new Integer(4), new Integer(20), new Integer(4), new Integer(30) }
                 });
    }
    
    public void testCtorExceptionDocumentedButNotInCode()
    {
        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @exception IOException thrown on I/O error.\n" +
                 "      */\n" +
                 "    public TestExceptionDocAnalyzer() {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ExceptionDocAnalyzer.MSG_EXCEPTION_NOT_IN_THROWS_LIST, new Integer(4), new Integer(20), new Integer(4), new Integer(30) }
                 });

        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @exception FileNotFoundException thrown when there is no file\n" +
                 "      * @exception IOException thrown on I/O error.\n" +
                 "      */\n" +
                 "    public TestExceptionDocAnalyzer() throws FileNotFoundException {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ExceptionDocAnalyzer.MSG_EXCEPTION_NOT_IN_THROWS_LIST, new Integer(5), new Integer(20), new Integer(5), new Integer(30) }
                 });
    }

    public void testCtorExceptionNotDocumented()
    {
        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      */\n" +
                 "    public TestExceptionDocAnalyzer() throws IOException {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ExceptionDocAnalyzer.MSG_EXCEPTION_NOT_DOCUMENTED, new Integer(5), new Integer(46), new Integer(5), new Integer(56) }
                 });

        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @exception IOException thrown on I/O error.\n" +
                 "      */\n" +
                 "    public TestExceptionDocAnalyzer() throws java.io.IOException {}\n" +
                 "}\n",
                 new Object[][] { 
                 });

        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @exception java.io.IOException thrown on I/O error.\n" +
                 "      */\n" +
                 "    public TestExceptionDocAnalyzer() throws java.io.IOException {}\n" +
                 "}\n",
                 new Object[][] { 
                 });

        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @exception java.io.IOException thrown on I/O error.\n" +
                 "      */\n" +
                 "    public TestExceptionDocAnalyzer() throws IOException {}\n" +
                 "}\n",
                 new Object[][] { 
                 });
    }

    public void testCtorExceptionNotAlphabetical()
    {
        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @exception NullPointerException thrown when there is no file\n" +
                 "      * @exception IOException thrown on I/O error.\n" +
                 "      */\n" +
                 "    public TestExceptionDocAnalyzer() throws NullPointerException, IOException {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ExceptionDocAnalyzer.MSG_EXCEPTIONS_NOT_ALPHABETICAL, new Integer(5), new Integer(20), new Integer(5), new Integer(30) }
                 });

        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @exception ArrayIndexOutOfBoundsException thrown when index >= array.length\n" +
                 "      * @exception NullPointerException thrown when there is no file\n" +
                 "      * @exception IOException thrown on I/O error.\n" +
                 "      */\n" +
                 "    public TestExceptionDocAnalyzer() throws IOException {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ExceptionDocAnalyzer.MSG_EXCEPTIONS_NOT_ALPHABETICAL, new Integer(6), new Integer(20), new Integer(6), new Integer(30) }
                 });
    }

    public void testCtorExceptionRuntimeExceptionNotDeclared()
    {
        List runtimeExceptions = new ArrayList();
        runtimeExceptions.add("ArithmeticException");
        runtimeExceptions.add("ArrayIndexOutOfBoundsException");
        runtimeExceptions.add("ArrayStoreException");
        runtimeExceptions.add("BufferOverflowException");
        runtimeExceptions.add("BufferUnderflowException");
        runtimeExceptions.add("CMMException");
        runtimeExceptions.add("CannotRedoException");
        runtimeExceptions.add("CannotUndoException");
        runtimeExceptions.add("ClassCastException");
        runtimeExceptions.add("ConcurrentModificationException");
        runtimeExceptions.add("DOMException");
        runtimeExceptions.add("EmptyStackException");
        runtimeExceptions.add("IllegalArgumentException");
        runtimeExceptions.add("IllegalMonitorStateException");
        runtimeExceptions.add("IllegalPathStateException");
        runtimeExceptions.add("IllegalStateException");
        runtimeExceptions.add("ImagingOpException");
        runtimeExceptions.add("IndexOutOfBoundsException");
        runtimeExceptions.add("MissingResourceException");
        runtimeExceptions.add("NegativeArraySizeException");
        runtimeExceptions.add("NoSuchElementException");
        runtimeExceptions.add("NullPointerException");
        runtimeExceptions.add("ProfileDataException");
        runtimeExceptions.add("ProviderException");
        runtimeExceptions.add("RasterFormatException");
        runtimeExceptions.add("SecurityException");
        runtimeExceptions.add("StringIndexOutOfBoundsException");
        runtimeExceptions.add("SystemException");
        runtimeExceptions.add("UndeclaredThrowableException");
        runtimeExceptions.add("UnmodifiableSetException");
        runtimeExceptions.add("UnsupportedOperationException");

        Iterator it = runtimeExceptions.iterator();
        while (it.hasNext()) {
            String rtexc = (String)it.next();

            evaluate("/** This is a description.\n" +
                     "  */\n" +
                     "class Test {\n" +
                     "    /** This is a description.\n" +
                     "      * @exception " + rtexc + " This is a description.\n" +
                     "      */\n" +
                     "    public TestExceptionDocAnalyzer() {}\n" +
                     "}\n",
                     new Object[][] { 
                     });
        }
    }
    
}
