package token;

import static error.ErrorManager.Severity.CRITICAL;
import static org.junit.Assert.*;

import org.junit.*;

import file.FilePosition;
import token.TokenFactory.*;

public class TokenFactoryTester {

    private TokenFactory tokenFactory;
    private FilePosition testPosition;

    @Before
    public void setUp() throws Exception {
        tokenFactory = new TokenFactoryImpl();
        testPosition = new FilePosition("testFile");
        testPosition.setLineNumber(0);
        testPosition.setColumnNumber(0);
    }

    private Token createToken(String text) {
        return tokenFactory.createToken(text, testPosition);
    }

    @Test
    public void testEOFTokenCreation() {
        assertTrue(tokenFactory.createEOFToken(testPosition) instanceof Eof);
    }

    @Test
    public void testLeftParenthesisCreation() {
        String text = "(";
        assertTrue(createToken(text) instanceof LeftParenthesis);
    }

    @Test
    public void testRightParenthesisCreation() {
        String text = ")";
        assertTrue(createToken(text) instanceof RightParenthesis);
    }

    @Test
    public void testQuoteMarkCreation() {
        String text = "'";
        assertTrue(createToken(text) instanceof QuoteMark);
    }

    @Test
    public void testNumberCreation() {
        String text = "987";
        assertTrue(createToken(text) instanceof Number);
    }

    @Test
    public void testIdentifierCreation() {
        String text = "identifier";
        assertTrue(createToken(text) instanceof Identifier);
    }

    @Test
    public void testStringCreation() {
        String text = "\"string\"";
        assertTrue(createToken(text) instanceof QuotedString);
    }

    @Test(expected = EmptyTokenTextException.class)
    public void testEmptyString_ThrowsException() {
        createToken("");
    }

    @Test
    public void EmptyTokenTextException_ContainsCorrectSeverity() {
        try {
            createToken("");
        } catch (EmptyTokenTextException e) {
            assertEquals(CRITICAL, e.getSeverity());
        }
    }

    @Test
    public void EmptyTokenTextException_ContainsMessage() {
        try {
            createToken("");
        } catch (EmptyTokenTextException e) {
            String message = e.getMessage();
            assertNotNull(message);
            assertTrue(message.length() > 0);
        }
    }

    @Test(expected = BadCharacterException.class)
    public void testBadCharacter_ThrowsException() {
        createToken("[abc]");
    }

}
