package org.incava.doctorj;

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


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

    public void testMethodParametersOK()
    {
        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      */\n" +
                 "    void method() {}\n" +
                 "}\n",
                 new Object[][] { 
                 });

        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param i This describes the i parameter.\n" +
                 "      */\n" +
                 "    void method(int i) {}\n" +
                 "}\n",
                 new Object[][] { 
                 });
    }

    public void testMethodParametersNoParamsInCode()
    {
        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param\n" +
                 "      */\n" +
                 "    void method() {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ParameterDocAnalyzer.MSG_PARAMETERS_DOCUMENTED_BUT_NO_CODE_PARAMETERS, new Integer(4), new Integer(9), new Integer(4), new Integer(14) }
                 });

        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param i\n" +
                 "      */\n" +
                 "    void method() {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ParameterDocAnalyzer.MSG_PARAMETERS_DOCUMENTED_BUT_NO_CODE_PARAMETERS, new Integer(4), new Integer(9), new Integer(4), new Integer(14) }
                 });

        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param i This describes the i parameter.\n" +
                 "      */\n" +
                 "    void method() {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ParameterDocAnalyzer.MSG_PARAMETERS_DOCUMENTED_BUT_NO_CODE_PARAMETERS, new Integer(4), new Integer(9), new Integer(4), new Integer(14) }
                 });

        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param i This describes the i parameter.\n" +
                 "      * @param j This describes the j parameter.\n" +
                 "      */\n" +
                 "    void method() {}\n" +
                 "}\n",
                 new Object[][] { 
                     // should be only one error:
                     { ParameterDocAnalyzer.MSG_PARAMETERS_DOCUMENTED_BUT_NO_CODE_PARAMETERS, new Integer(4), new Integer(9), new Integer(4), new Integer(14) }
                 });

        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param i This describes the i parameter.\n" +
                 "      * @param j This describes the j parameter.\n" +
                 "      * @param k This describes the k parameter.\n" +
                 "      * @param l This describes the l parameter.\n" +
                 "      * @param m This describes the m parameter.\n" +
                 "      */\n" +
                 "    void method() {}\n" +
                 "}\n",
                 new Object[][] { 
                     // should be only one error:
                     { ParameterDocAnalyzer.MSG_PARAMETERS_DOCUMENTED_BUT_NO_CODE_PARAMETERS, new Integer(4), new Integer(9), new Integer(4), new Integer(14) }
                 });
    }

    public void testMethodParametersParamWithoutTarget()
    {
        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param\n" +
                 "      */\n" +
                 "    void method(int i) {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ParameterDocAnalyzer.MSG_PARAMETER_WITHOUT_NAME,   new Integer(4), new Integer(9),  new Integer(4), new Integer(14) },
                     { ParameterDocAnalyzer.MSG_PARAMETER_NOT_DOCUMENTED, new Integer(6), new Integer(21), new Integer(6), new Integer(21) }
                 });
    }

    public void testMethodParametersParamMisspelled()
    {
        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param st The string in question.\n" +
                 "      */\n" +
                 "    void method(String str) {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ParameterDocAnalyzer.MSG_PARAMETER_MISSPELLED,   new Integer(4), new Integer(16), new Integer(4), new Integer(17) }
                 });

        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param s The string in question.\n" +
                 "      */\n" +
                 "    void method(String str) {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ParameterDocAnalyzer.MSG_PARAMETER_MISSPELLED,   new Integer(4), new Integer(16), new Integer(4), new Integer(16) }
                 });
    }

    public void testMethodParametersParamNotDocumented()
    {
        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param comp A Comparator of some sort.\n" +
                 "      */\n" +
                 "    void method(String str, Comparator comp) {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ParameterDocAnalyzer.MSG_PARAMETER_NOT_DOCUMENTED, new Integer(6), new Integer(24), new Integer(6), new Integer(26) }
                 });

        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param price The price of tea in China.\n" +
                 "      */\n" +
                 "    void method(String str, int price, Comparator comp) {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ParameterDocAnalyzer.MSG_PARAMETER_NOT_DOCUMENTED, new Integer(6), new Integer(24), new Integer(6), new Integer(26) },
                     { ParameterDocAnalyzer.MSG_PARAMETER_NOT_DOCUMENTED, new Integer(6), new Integer(51), new Integer(6), new Integer(54) }
                 });
    }

    public void testMethodParametersMisordered()
    {
        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param comp A Comparator of some sort.\n" +
                 "      * @param str The string in question.\n" +
                 "      */\n" +
                 "    void method(String str, Comparator comp) {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ParameterDocAnalyzer.MSG_PARAMETER_NOT_IN_CODE_ORDER, new Integer(5), new Integer(16), new Integer(5), new Integer(18) }
                 });

        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param size The height and width of something.\n" +
                 "      * @param comp A Comparator of some sort.\n" +
                 "      * @param str The string in question.\n" +
                 "      */\n" +
                 "    void method(java.awt.Dimension size, String str, Comparator comp) {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ParameterDocAnalyzer.MSG_PARAMETER_NOT_IN_CODE_ORDER, new Integer(6), new Integer(16), new Integer(6), new Integer(18) }
                 });
    }

    public void testMethodParametersTypeUsed()
    {
        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param String The string in question.\n" +
                 "      */\n" +
                 "    void method(String str) {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ParameterDocAnalyzer.MSG_PARAMETER_TYPE_USED, new Integer(4), new Integer(16), new Integer(4), new Integer(21) }
                 });

        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param String The string in question.\n" +
                 "      * @param Comparator A Comparator of some sort.\n" +
                 "      */\n" +
                 "    void method(String str, Comparator comp) {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ParameterDocAnalyzer.MSG_PARAMETER_TYPE_USED, new Integer(4), new Integer(16), new Integer(4), new Integer(21) },
                     { ParameterDocAnalyzer.MSG_PARAMETER_TYPE_USED, new Integer(5), new Integer(16), new Integer(5), new Integer(25) }
                 });
    }

    // Same as above, but for constructors.

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

        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param i This describes the i parameter.\n" +
                 "      */\n" +
                 "    Test(int i) {}\n" +
                 "}\n",
                 new Object[][] { 
                 });
    }

    public void testCtorParametersNoParamsInCode()
    {
        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param\n" +
                 "      */\n" +
                 "    Test() {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ParameterDocAnalyzer.MSG_PARAMETERS_DOCUMENTED_BUT_NO_CODE_PARAMETERS, new Integer(4), new Integer(9), new Integer(4), new Integer(14) }
                 });

        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param i\n" +
                 "      */\n" +
                 "    Test() {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ParameterDocAnalyzer.MSG_PARAMETERS_DOCUMENTED_BUT_NO_CODE_PARAMETERS, new Integer(4), new Integer(9), new Integer(4), new Integer(14) }
                 });

        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param i This describes the i parameter.\n" +
                 "      */\n" +
                 "    Test() {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ParameterDocAnalyzer.MSG_PARAMETERS_DOCUMENTED_BUT_NO_CODE_PARAMETERS, new Integer(4), new Integer(9), new Integer(4), new Integer(14) }
                 });

        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param i This describes the i parameter.\n" +
                 "      * @param j This describes the j parameter.\n" +
                 "      */\n" +
                 "    Test() {}\n" +
                 "}\n",
                 new Object[][] { 
                     // should be only one error:
                     { ParameterDocAnalyzer.MSG_PARAMETERS_DOCUMENTED_BUT_NO_CODE_PARAMETERS, new Integer(4), new Integer(9), new Integer(4), new Integer(14) }
                 });

        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param i This describes the i parameter.\n" +
                 "      * @param j This describes the j parameter.\n" +
                 "      * @param k This describes the k parameter.\n" +
                 "      * @param l This describes the l parameter.\n" +
                 "      * @param m This describes the m parameter.\n" +
                 "      */\n" +
                 "    Test() {}\n" +
                 "}\n",
                 new Object[][] { 
                     // should be only one error:
                     { ParameterDocAnalyzer.MSG_PARAMETERS_DOCUMENTED_BUT_NO_CODE_PARAMETERS, new Integer(4), new Integer(9), new Integer(4), new Integer(14) }
                 });
    }

    public void testCtorParametersParamWithoutTarget()
    {
        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param\n" +
                 "      */\n" +
                 "    Test(int i) {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ParameterDocAnalyzer.MSG_PARAMETER_WITHOUT_NAME,   new Integer(4), new Integer(9), new Integer(4), new Integer(14) },
                     { ParameterDocAnalyzer.MSG_PARAMETER_NOT_DOCUMENTED, new Integer(6), new Integer(14), new Integer(6), new Integer(14) }
                 });
    }

    public void testCtorParametersParamMisspelled()
    {
        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param st The string in question.\n" +
                 "      */\n" +
                 "    Test(String str) {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ParameterDocAnalyzer.MSG_PARAMETER_MISSPELLED,   new Integer(4), new Integer(16), new Integer(4), new Integer(17) }
                 });

        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param s The string in question.\n" +
                 "      */\n" +
                 "    Test(String str) {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ParameterDocAnalyzer.MSG_PARAMETER_MISSPELLED,   new Integer(4), new Integer(16), new Integer(4), new Integer(16) }
                 });
    }

    public void testCtorParametersParamNotDocumented()
    {
        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param comp A Comparator of some sort.\n" +
                 "      */\n" +
                 "    Test(String str, Comparator comp) {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ParameterDocAnalyzer.MSG_PARAMETER_NOT_DOCUMENTED, new Integer(6), new Integer(17), new Integer(6), new Integer(19) }
                 });

        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param price The price of tea in China.\n" +
                 "      */\n" +
                 "    Test(String str, int price, Comparator comp) {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ParameterDocAnalyzer.MSG_PARAMETER_NOT_DOCUMENTED, new Integer(6), new Integer(17), new Integer(6), new Integer(19) },
                     { ParameterDocAnalyzer.MSG_PARAMETER_NOT_DOCUMENTED, new Integer(6), new Integer(44), new Integer(6), new Integer(47) }
                 });
    }

    public void testCtorParametersMisordered()
    {
        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param comp A Comparator of some sort.\n" +
                 "      * @param str The string in question.\n" +
                 "      */\n" +
                 "    Test(String str, Comparator comp) {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ParameterDocAnalyzer.MSG_PARAMETER_NOT_IN_CODE_ORDER, new Integer(5), new Integer(16), new Integer(5), new Integer(18) }
                 });

        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param size The height and width of something.\n" +
                 "      * @param comp A Comparator of some sort.\n" +
                 "      * @param str The string in question.\n" +
                 "      */\n" +
                 "    Test(java.awt.Dimension size, String str, Comparator comp) {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ParameterDocAnalyzer.MSG_PARAMETER_NOT_IN_CODE_ORDER, new Integer(6), new Integer(16), new Integer(6), new Integer(18) }
                 });
    }

    public void testCtorParametersTypeUsed()
    {
        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param String The string in question.\n" +
                 "      */\n" +
                 "    Test(String str) {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ParameterDocAnalyzer.MSG_PARAMETER_TYPE_USED, new Integer(4), new Integer(16), new Integer(4), new Integer(21) }
                 });

        evaluate("/** This is a description. */\n" +
                 "class Test {\n" +
                 "    /** This is a description.\n" +
                 "      * @param String The string in question.\n" +
                 "      * @param Comparator A Comparator of some sort.\n" +
                 "      */\n" +
                 "    Test(String str, Comparator comp) {}\n" +
                 "}\n",
                 new Object[][] { 
                     { ParameterDocAnalyzer.MSG_PARAMETER_TYPE_USED, new Integer(4), new Integer(16), new Integer(4), new Integer(21) },
                     { ParameterDocAnalyzer.MSG_PARAMETER_TYPE_USED, new Integer(5), new Integer(16), new Integer(5), new Integer(25) }
                 });
    }
}

