/*
 * ModeShape (http://www.modeshape.org)
 *
 * 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.modeshape.sequencer.ddl.datatype;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.modeshape.common.text.ParsingException;
import org.modeshape.sequencer.ddl.DdlConstants;
import org.modeshape.sequencer.ddl.DdlTokenStream;

public class DataTypeParserTest implements DdlConstants {
    private DataTypeParser parser;

    private boolean printTest = false;

    @Before
    public void beforeEach() {
        parser = new DataTypeParser();
    }

    private DdlTokenStream getTokens( String content ) {
        DdlTokenStream tokens = new DdlTokenStream(content, DdlTokenStream.ddlTokenizer(false), false);

        tokens.start();

        return tokens;
    }

    private String getDataTypeString( String[] input ) {
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < input.length; i++) {
            if (i > 0) {
                sb.append(SPACE);
            }
            sb.append(input[i]);
        }

        return sb.toString();
    }

    private void printTest( String value ) {
        if (printTest) {
            // CHECKSTYLE IGNORE check FOR NEXT 1 LINES
            System.out.println("TEST:  " + value);
        }
    }

    // private void printResult(String value) {
    // if( printTest ) {
    // System.out.println(value);
    // }
    // }

    /* ===========================================================================================================================
     * UTILITY METHODS
     * ==========================================================================================================================
     */

    @Test
    public void shouldParseBracketedInteger() {
        printTest("shouldParseBracketedInteger()");
        String content = "(255)";
        DdlTokenStream tokens = getTokens(content);
        long value = parser.parseBracketedLong(tokens, new DataType());

        Assert.assertEquals("DataType length is not correct", 255, value);
    }

    @Test
    public void shouldParseKMGInteger() {
        printTest("shouldParseKMGInteger()");
        String content = "1000M";
        DdlTokenStream tokens = getTokens(content);

        long value = parser.parseLong(tokens, new DataType());
        Assert.assertEquals("DataType length is not correct", 1000 * MEGA, value);

        content = "1000G";
        tokens = getTokens(content);
        value = parser.parseLong(tokens, new DataType());

        Assert.assertEquals("DataType length is not correct", 1000 * GIGA, value);

        content = "1000K";
        tokens = getTokens(content);
        value = parser.parseLong(tokens, new DataType());

        Assert.assertEquals("DataType length is not correct", 1000 * KILO, value);

        content = "(1000M)";
        tokens = getTokens(content);
        value = parser.parseBracketedLong(tokens, new DataType());

        Assert.assertEquals("DataType length is not correct", 1000 * MEGA, value);

        content = "(1000G)";
        tokens = getTokens(content);
        value = parser.parseBracketedLong(tokens, new DataType());

        Assert.assertEquals("DataType length is not correct", 1000 * GIGA, value);

        content = "(1000K)";
        tokens = getTokens(content);
        value = parser.parseBracketedLong(tokens, new DataType());

        Assert.assertEquals("DataType length is not correct", 1000 * KILO, value);
    }

    /* ===========================================================================================================================
     * CHARACTER STRING TYPE
     * ==========================================================================================================================
        <character string type> ::=
            CHARACTER [ <left paren> <length> <right paren> ]
          | CHAR [ <left paren> <length> <right paren> ]
          | CHARACTER VARYING <left paren> <length> <right paren>
          | CHAR VARYING <left paren> <length> <right paren>
          | VARCHAR <left paren> <length> <right paren>
    */

    @Test
    public void shouldParseCHAR() {
        printTest("shouldParseCHAR()");
        String typeString = getDataTypeString(DataTypes.DTYPE_CHAR);
        String content = typeString;

        DdlTokenStream tokens = getTokens(content);

        DataType dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());

        content = typeString + " (255)";
        tokens = getTokens(content);

        dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
        Assert.assertEquals("DataType length is not correct", 255, dType.getLength());
    }

    @Test
    public void shouldParseCHARACTER() {
        printTest("shouldParseCHARACTER()");
        String typeString = getDataTypeString(DataTypes.DTYPE_CHARACTER);
        String content = typeString;

        DdlTokenStream tokens = getTokens(content);

        DataType dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());

        content = typeString + " (255)";
        tokens = getTokens(content);

        dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
        Assert.assertEquals("DataType length is not correct", 255, dType.getLength());
    }

    @Test
    public void shouldParseCHAR_VARYING() {
        printTest("shouldParseCHAR_VARYING()");
        String typeString = getDataTypeString(DataTypes.DTYPE_CHAR_VARYING);
        String content = typeString + " (255)";

        DdlTokenStream tokens = getTokens(content);

        DataType dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
        Assert.assertEquals("DataType length is not correct", 255, dType.getLength());
    }

    @Test
    public void shouldParseCHARACTER_VARYING() {
        printTest("shouldParseCHARACTER_VARYING()");
        String typeString = getDataTypeString(DataTypes.DTYPE_CHARACTER_VARYING);
        String content = typeString + " (255)";

        DdlTokenStream tokens = getTokens(content);

        DataType dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
        Assert.assertEquals("DataType length is not correct", 255, dType.getLength());
    }

    @Test
    public void shouldParseVARCHAR() {
        printTest("shouldParseVARCHAR()");
        String typeString = getDataTypeString(DataTypes.DTYPE_VARCHAR);
        String content = typeString + " (255)";

        DdlTokenStream tokens = getTokens(content);

        DataType dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
        Assert.assertEquals("DataType length is not correct", 255, dType.getLength());

        content = typeString;
        tokens = getTokens(content);
        dType = null;
        try {
            dType = parser.parse(tokens);
        } catch (ParsingException e) {
            // Expect exception
        }

        Assert.assertNull("DataType should NOT have been found for Type = " + content, dType);
    }

    /* ===========================================================================================================================
     * NATIONAL CHARACTER STRING TYPE
     * ==========================================================================================================================
     * 
     * 
        <national character string type> ::=
              NATIONAL CHARACTER [ <left paren> <length> <right paren> ]
            | NATIONAL CHAR [ <left paren> <length> <right paren> ]
            | NCHAR [ <left paren> <length> <right paren> ]
            | NATIONAL CHARACTER VARYING <left paren> <length> <right paren>
            | NATIONAL CHAR VARYING <left paren> <length> <right paren>
            | NCHAR VARYING <left paren> <length> <right paren>

     * 
     * 
     */
    @Test
    public void shouldParseNATIONAL_CHAR() {
        printTest("shouldParseNATIONAL_CHAR()");
        String typeString = getDataTypeString(DataTypes.DTYPE_NATIONAL_CHAR);
        String content = typeString;

        DdlTokenStream tokens = getTokens(content);

        DataType dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());

        content = typeString + " (255)";
        tokens = getTokens(content);

        dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
        Assert.assertEquals("DataType length is not correct", 255, dType.getLength());
    }

    @Test
    public void shouldParseNATIONAL_CHARACTER() {
        printTest("shouldParseNATIONAL_CHARACTER()");
        String typeString = getDataTypeString(DataTypes.DTYPE_NATIONAL_CHARACTER);
        String content = typeString;

        DdlTokenStream tokens = getTokens(content);

        DataType dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());

        content = typeString + " (255)";
        tokens = getTokens(content);

        dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
        Assert.assertEquals("DataType length is not correct", 255, dType.getLength());
    }

    @Test
    public void shouldParseNATIONAL_CHAR_VARYING() {
        printTest("shouldParseNATIONAL_CHAR_VARYING()");
        String typeString = getDataTypeString(DataTypes.DTYPE_NATIONAL_CHAR_VARYING);
        String content = typeString + " (255)";

        DdlTokenStream tokens = getTokens(content);

        DataType dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
        Assert.assertEquals("DataType length is not correct", 255, dType.getLength());
    }

    @Test
    public void shouldParseNATIONAL_CHARACTER_VARYING() {
        printTest("shouldParseNATIONAL_CHARACTER_VARYING()");
        String typeString = getDataTypeString(DataTypes.DTYPE_NATIONAL_CHARACTER_VARYING);
        String content = typeString + " (255)";

        DdlTokenStream tokens = getTokens(content);

        DataType dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
        Assert.assertEquals("DataType length is not correct", 255, dType.getLength());
    }

    @Test
    public void shouldParseNCHAR_VARYING() {
        printTest("shouldParseNCHAR_VARYING()");
        String typeString = getDataTypeString(DataTypes.DTYPE_NCHAR_VARYING);
        String content = typeString + " (255)";

        DdlTokenStream tokens = getTokens(content);

        DataType dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
        Assert.assertEquals("DataType length is not correct", 255, dType.getLength());

        content = typeString;
        tokens = getTokens(content);
        dType = null;
        try {
            dType = parser.parse(tokens);
        } catch (ParsingException e) {
            // Expect exception
        }

        Assert.assertNull("DataType should NOT have been found for Type = " + content, dType);
    }

    /* ===========================================================================================================================
     * NATIONAL CHARACTER STRING TYPE
     * ==========================================================================================================================
     * 
        <bit string type> ::=
              BIT [ <left paren> <length> <right paren> ]
            | BIT VARYING <left paren> <length> <right paren>
     *
     */

    @Test
    public void shouldParseBIT() {
        printTest("shouldParseBIT()");
        String typeString = getDataTypeString(DataTypes.DTYPE_BIT);
        String content = typeString;

        DdlTokenStream tokens = getTokens(content);

        DataType dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
    }

    @Test
    public void shouldParseBITWithLength() {
        printTest("shouldParseBITWithLength()");
        String typeString = getDataTypeString(DataTypes.DTYPE_BIT);
        String content = typeString + " (255)";

        DdlTokenStream tokens = getTokens(content);

        DataType dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
        Assert.assertEquals("DataType length is not correct", 255, dType.getLength());
    }

    @Test
    public void shouldParseBIT_VARYINGWithLength() {
        printTest("shouldParseBIT_VARYINGWithLength()");
        String typeString = getDataTypeString(DataTypes.DTYPE_BIT_VARYING);
        String content = typeString + " (255)";

        DdlTokenStream tokens = getTokens(content);

        DataType dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
        Assert.assertEquals("DataType length is not correct", 255, dType.getLength());

        content = typeString;
        tokens = getTokens(content);
        dType = null;
        try {
            dType = parser.parse(tokens);
        } catch (ParsingException e) {
            // Expect exception
        }

        Assert.assertNull("DataType should NOT have been found for Type = " + content, dType);
    }

    /* ===========================================================================================================================
     * EXACT NUMERIC TYPE
     * ==========================================================================================================================
        <exact numeric type> ::=
              NUMERIC [ <left paren> <precision> [ <comma> <scale> ] <right paren> ]
            | DECIMAL [ <left paren> <precision> [ <comma> <scale> ] <right paren> ]
            | DEC [ <left paren> <precision> [ <comma> <scale> ] <right paren> ]
            | INTEGER
            | INT
            | SMALLINT
     * 
     */

    @Test
    public void shouldNotParseXXXXXXTYPE() {
        printTest("shouldNotParseXXXXXXTYPE()");
        String typeString = "XXXXXXTYPE";
        String content = typeString;

        DdlTokenStream tokens = getTokens(content);

        DataType dType = null;
        try {
            dType = parser.parse(tokens);
        } catch (ParsingException e) {
            // Expect exception
        }

        Assert.assertNull("DataType should NOT have been found for Type = " + typeString, dType);
    }

    @Test
    public void shouldParseINT() {
        printTest("shouldParseINT()");
        String typeString = getDataTypeString(DataTypes.DTYPE_INT);
        String content = typeString;

        DdlTokenStream tokens = getTokens(content);

        DataType dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
    }

    @Test
    public void shouldParseINTEGER() {
        printTest("shouldParseINTEGER()");
        String typeString = getDataTypeString(DataTypes.DTYPE_INTEGER);
        String content = typeString;

        DdlTokenStream tokens = getTokens(content);

        DataType dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
    }

    @Test
    public void shouldParseSMALLINT() {
        printTest("shouldParseSMALLINT()");
        String typeString = getDataTypeString(DataTypes.DTYPE_SMALLINT);
        String content = typeString;

        DdlTokenStream tokens = getTokens(content);

        DataType dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
    }

    @Test
    public void shouldParseNUMERIC() {
        printTest("shouldParseNUMERIC()");
        String typeString = getDataTypeString(DataTypes.DTYPE_NUMERIC);
        String content = typeString;

        DdlTokenStream tokens = getTokens(content);

        DataType dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());

        content = typeString + " (5)";
        tokens = getTokens(content);
        dType = parser.parse(tokens);
        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
        Assert.assertEquals("DataType length is not correct", 5, dType.getPrecision()); // PRECISION

        content = typeString + " (5, 2)";
        tokens = getTokens(content);
        dType = parser.parse(tokens);
        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
        Assert.assertEquals("DataType length is not correct", 5, dType.getPrecision()); // PRECISION
        Assert.assertEquals("DataType length is not correct", 2, dType.getScale()); // SCALE

        // MISSING COMMA
        content = typeString + " (5  2)";
        tokens = getTokens(content);
        dType = null;
        try {
            dType = parser.parse(tokens);
        } catch (ParsingException e) {
            // Expect exception
        }
        Assert.assertNull("DataType should NOT have been found for Type = " + content, dType);

        // INVALID Scale Integer
        content = typeString + " (5  A)";
        tokens = getTokens(content);
        try {
            dType = parser.parse(tokens);
        } catch (ParsingException e) {
            // Expect exception
        }
        Assert.assertNull("DataType should NOT have been found for Type = " + content, dType);
    }

    @Test
    public void shouldParseDECIMAL() {
        printTest("shouldParseDECIMAL()");
        String typeString = getDataTypeString(DataTypes.DTYPE_DECIMAL);
        String content = typeString;

        DdlTokenStream tokens = getTokens(content);

        DataType dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());

        content = typeString + " (5)";
        tokens = getTokens(content);
        dType = parser.parse(tokens);
        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
        Assert.assertEquals("DataType length is not correct", 5, dType.getPrecision()); // PRECISION

        content = typeString + " (5, 2)";
        tokens = getTokens(content);
        dType = parser.parse(tokens);
        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
        Assert.assertEquals("DataType length is not correct", 5, dType.getPrecision()); // PRECISION
        Assert.assertEquals("DataType length is not correct", 2, dType.getScale()); // SCALE

        // MISSING COMMA
        content = typeString + " (5  2)";
        tokens = getTokens(content);
        dType = null;
        try {
            dType = parser.parse(tokens);
        } catch (ParsingException e) {
            // Expect exception
        }
        Assert.assertNull("DataType should NOT have been found for Type = " + content, dType);

        // INVALID Scale Integer
        content = typeString + " (5  A)";
        tokens = getTokens(content);
        assert dType == null;
        try {
            dType = parser.parse(tokens);
        } catch (ParsingException e) {
            // Expect exception
        }
        Assert.assertNull("DataType should NOT have been found for Type = " + content, dType);
    }

    @Test
    public void shouldParseDEC() {
        printTest("shouldParseDEC()");
        String typeString = getDataTypeString(DataTypes.DTYPE_DEC);
        String content = typeString;

        DdlTokenStream tokens = getTokens(content);

        DataType dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());

        content = typeString + " (5)";
        tokens = getTokens(content);
        dType = parser.parse(tokens);
        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
        Assert.assertEquals("DataType length is not correct", 5, dType.getPrecision()); // PRECISION

        content = typeString + " (5, 2)";
        tokens = getTokens(content);
        dType = parser.parse(tokens);
        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
        Assert.assertEquals("DataType length is not correct", 5, dType.getPrecision()); // PRECISION
        Assert.assertEquals("DataType length is not correct", 2, dType.getScale()); // SCALE

        // MISSING COMMA
        content = typeString + " (5  2)";
        tokens = getTokens(content);
        dType = null;
        try {
            dType = parser.parse(tokens);
        } catch (ParsingException e) {
            // Expect exception
        }
        Assert.assertNull("DataType should NOT have been found for Type = " + content, dType);

        // INVALID Scale Integer
        content = typeString + " (5  A)";
        tokens = getTokens(content);
        assert dType == null;
        try {
            dType = parser.parse(tokens);
        } catch (ParsingException e) {
            // Expect exception
        }
        Assert.assertNull("DataType should NOT have been found for Type = " + content, dType);
    }

    /* ===========================================================================================================================
     * APPROXIMATE NUMERIC TYPE
     * ==========================================================================================================================
     * 
        <approximate numeric type> ::=
              FLOAT [ <left paren> <precision> <right paren> ]
            | REAL
            | DOUBLE PRECISION
     */

    @Test
    public void shouldParseFLOAT() {
        printTest("shouldParseFLOAT()");
        String typeString = getDataTypeString(DataTypes.DTYPE_FLOAT);
        String content = typeString;

        DdlTokenStream tokens = getTokens(content);

        DataType dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());

        content = typeString + " (5)";
        tokens = getTokens(content);
        dType = parser.parse(tokens);
        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
        Assert.assertEquals("DataType length is not correct", 5, dType.getPrecision()); // PRECISION

        // ADDED SCALE
        content = typeString + " (5,  2)";
        tokens = getTokens(content);
        dType = null;
        try {
            dType = parser.parse(tokens);
        } catch (ParsingException e) {
            // Expect exception
        }
        Assert.assertNull("DataType should NOT have been found for Type = " + content, dType);

    }

    @Test
    public void shouldParseREAL() {
        printTest("shouldParseREAL()");
        String typeString = getDataTypeString(DataTypes.DTYPE_REAL);
        String content = typeString;

        DdlTokenStream tokens = getTokens(content);

        DataType dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
    }

    @Test
    public void shouldParseDOUBLE_PRECISION() {
        printTest("shouldParseDOUBLE_PRECISION()");
        String typeString = getDataTypeString(DataTypes.DTYPE_DOUBLE_PRECISION);
        String content = typeString;

        DdlTokenStream tokens = getTokens(content);

        DataType dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
    }

    /* ===========================================================================================================================
     * APPROXIMATE NUMERIC TYPE
     * ==========================================================================================================================
     * 
        <datetime type> ::=
              DATE
            | TIME [ <left paren> <time precision> <right paren> ] [ WITH TIME ZONE ]
            | TIMESTAMP [ <left paren> <timestamp precision> <right paren> ] [ WITH TIME ZONE ]
            
            NOTE:  time precision & timestamp precision is an integer from 0 to 9
     */

    @Test
    public void shouldParseDATE() {
        printTest("shouldParseDATE()");
        String typeString = getDataTypeString(DataTypes.DTYPE_DATE);
        String content = typeString;

        DdlTokenStream tokens = getTokens(content);

        DataType dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
    }

    @Test
    public void shouldParseTIME() {
        printTest("shouldParseTIME()");
        String typeString = getDataTypeString(DataTypes.DTYPE_TIME);
        String content = typeString;

        DdlTokenStream tokens = getTokens(content);

        DataType dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());

        content = typeString + " (6)";
        tokens = getTokens(content);
        dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
        Assert.assertEquals("DataType length is not correct", 6, dType.getPrecision());
    }

    @Test
    public void shouldParseTIMESTAMP() {
        printTest("shouldParseTIMESTAMP()");
        String typeString = getDataTypeString(DataTypes.DTYPE_TIMESTAMP);
        String content = typeString;

        DdlTokenStream tokens = getTokens(content);

        DataType dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());

        content = typeString + " (6)";
        tokens = getTokens(content);
        dType = parser.parse(tokens);

        Assert.assertNotNull("DataType was NOT found for Type = " + typeString, dType);
        Assert.assertEquals("Wrong DataType found", typeString, dType.getName());
        Assert.assertEquals("DataType length is not correct", 6, dType.getPrecision());
    }
}
