diff --git a/src/main/kotlin/token/TokenFactory.java b/src/main/kotlin/token/TokenFactory.java deleted file mode 100644 index 5910b52..0000000 --- a/src/main/kotlin/token/TokenFactory.java +++ /dev/null @@ -1,44 +0,0 @@ -package token; - -import error.CriticalLineColumnException; -import error.LineColumnException; -import file.FilePosition; - -import static java.text.MessageFormat.format; - -public interface TokenFactory { - - Token createToken(String text, FilePosition position); - - Token createEofToken(FilePosition position); - - public static class EmptyTokenTextException extends CriticalLineColumnException { - - private static final long serialVersionUID = 1L; - - public EmptyTokenTextException(FilePosition position) { - super(position); - } - - @Override - public String getMessagePrefix() { - return "empty token"; - } - } - - public static class BadCharacterException extends LineColumnException { - - private static final long serialVersionUID = 1L; - private String text; - - public BadCharacterException(String text, FilePosition position) { - super(position); - this.text = text; - } - - @Override - public String getMessagePrefix() { - return format("illegal character >>{0}<<", text); - } - } -} diff --git a/src/main/kotlin/token/TokenFactory.kt b/src/main/kotlin/token/TokenFactory.kt new file mode 100644 index 0000000..29c9b27 --- /dev/null +++ b/src/main/kotlin/token/TokenFactory.kt @@ -0,0 +1,21 @@ +package token + +import error.CriticalLineColumnException +import error.LineColumnException +import file.FilePosition + +interface TokenFactory { + + fun createToken(text: String, position: FilePosition): Token + fun createEofToken(position: FilePosition): Token + + class EmptyTokenTextException(position: FilePosition) : CriticalLineColumnException(position) { + override val messagePrefix: String + get() = "empty token" + } + + class BadCharacterException(private val text: String, position: FilePosition) : LineColumnException(position) { + override val messagePrefix: String + get() = "illegal character >>$text<<" + } +} diff --git a/src/main/kotlin/token/TokenFactoryImpl.java b/src/main/kotlin/token/TokenFactoryImpl.java deleted file mode 100644 index c5edf1a..0000000 --- a/src/main/kotlin/token/TokenFactoryImpl.java +++ /dev/null @@ -1,58 +0,0 @@ -package token; - -import file.FilePosition; -import util.Characters; - -import static java.lang.Character.isDigit; - -public class TokenFactoryImpl implements TokenFactory { - - @Override - public Token createToken(String text, FilePosition position) { - if (text.length() == 0) - throw new EmptyTokenTextException(position); - - char firstCharacter = text.charAt(0); - - switch (firstCharacter) { - case Characters.LEFT_PARENTHESIS: - return new LeftParenthesis(text, position); - case Characters.RIGHT_PARENTHESIS: - return new RightParenthesis(text, position); - case Characters.SINGLE_QUOTE: - return new QuoteMark(text, position); - case Characters.DOUBLE_QUOTE: - return new QuotedString(text, position); - case Characters.BACKQUOTE: - return new Backquote(text, position); - case Characters.AT_SIGN: - return new AtSign(text, position); - case Characters.COMMA: - return new Comma(text, position); - default: - if (isNumeric(firstCharacter, text)) - return new Number(text, position); - else if (Characters.INSTANCE.isLegalIdentifierCharacter(firstCharacter)) - return new Identifier(text, position); - } - - throw new BadCharacterException(text, position); - } - - private boolean isNumeric(char firstCharacter, String text) { - return isDigit(firstCharacter) || isPrefixedNumeric(firstCharacter, text); - } - - private boolean isPrefixedNumeric(char firstCharacter, String text) { - return Characters.INSTANCE.isNumberPrefix(firstCharacter) && isNextCharacterDigit(text); - } - - private boolean isNextCharacterDigit(String text) { - return (text.length() > 1) && isDigit(text.charAt(1)); - } - - @Override - public Token createEofToken(FilePosition position) { - return new Eof("EOF", position); - } -} diff --git a/src/main/kotlin/token/TokenFactoryImpl.kt b/src/main/kotlin/token/TokenFactoryImpl.kt new file mode 100644 index 0000000..3d085bb --- /dev/null +++ b/src/main/kotlin/token/TokenFactoryImpl.kt @@ -0,0 +1,56 @@ +package token + +import file.FilePosition +import token.TokenFactory.BadCharacterException +import token.TokenFactory.EmptyTokenTextException +import util.Characters.AT_SIGN +import util.Characters.BACKQUOTE +import util.Characters.COMMA +import util.Characters.DOUBLE_QUOTE +import util.Characters.LEFT_PARENTHESIS +import util.Characters.RIGHT_PARENTHESIS +import util.Characters.SINGLE_QUOTE +import util.Characters.isLegalIdentifierCharacter +import util.Characters.isNumberPrefix +import java.lang.Character.isDigit + +class TokenFactoryImpl : TokenFactory { + + override fun createToken(text: String, position: FilePosition): Token { + if (text.isEmpty()) + throw EmptyTokenTextException(position) + + val firstCharacter = text[0] + + return when (firstCharacter) { + LEFT_PARENTHESIS -> LeftParenthesis(text, position) + RIGHT_PARENTHESIS -> RightParenthesis(text, position) + SINGLE_QUOTE -> QuoteMark(text, position) + DOUBLE_QUOTE -> QuotedString(text, position) + BACKQUOTE -> Backquote(text, position) + AT_SIGN -> AtSign(text, position) + COMMA -> Comma(text, position) + else -> when { + isNumeric(firstCharacter, text) -> Number(text, position) + isLegalIdentifierCharacter(firstCharacter) -> Identifier(text, position) + else -> throw BadCharacterException(text, position) + } + } + } + + override fun createEofToken(position: FilePosition): Token { + return Eof("EOF", position) + } + + private fun isNumeric(firstCharacter: Char, text: String): Boolean { + return isDigit(firstCharacter) || isPrefixedNumeric(firstCharacter, text) + } + + private fun isPrefixedNumeric(firstCharacter: Char, text: String): Boolean { + return isNumberPrefix(firstCharacter) && isNextCharacterDigit(text) + } + + private fun isNextCharacterDigit(text: String): Boolean { + return text.length > 1 && isDigit(text[1]) + } +} diff --git a/src/test/kotlin/function/builtin/ExitTest.kt b/src/test/kotlin/function/builtin/ExitTest.kt index 18fab39..5cc669f 100644 --- a/src/test/kotlin/function/builtin/ExitTest.kt +++ b/src/test/kotlin/function/builtin/ExitTest.kt @@ -5,10 +5,13 @@ import function.ArgumentValidator.TooManyArgumentsException import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Assertions.assertThrows import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInstance +import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS import testutil.SymbolAndFunctionCleaner import testutil.TestUtilities.evaluateString import java.util.HashSet +@TestInstance(PER_CLASS) class ExitTest : SymbolAndFunctionCleaner() { companion object { diff --git a/src/test/kotlin/token/TokenFactoryTest.java b/src/test/kotlin/token/TokenFactoryTest.java deleted file mode 100644 index 170b6f8..0000000 --- a/src/test/kotlin/token/TokenFactoryTest.java +++ /dev/null @@ -1,123 +0,0 @@ -package token; - -import file.FilePosition; -import org.junit.Before; -import org.junit.Test; -import token.TokenFactory.BadCharacterException; -import token.TokenFactory.EmptyTokenTextException; - -import static error.Severity.CRITICAL; -import static org.hamcrest.Matchers.greaterThan; -import static org.hamcrest.Matchers.instanceOf; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.notNullValue; -import static org.junit.Assert.assertThat; - -public class TokenFactoryTest { - - private TokenFactory tokenFactory; - private FilePosition testPosition; - - @Before - public void setUp() { - tokenFactory = new TokenFactoryImpl(); - testPosition = new FilePosition("testFile", 0, 0); - } - - private Token createToken(String text) { - return tokenFactory.createToken(text, testPosition); - } - - @Test - public void eofTokenCreation() { - assertThat(tokenFactory.createEofToken(testPosition), instanceOf(Eof.class)); - } - - @Test - public void leftParenthesisCreation() { - String text = "("; - assertThat(createToken(text), instanceOf(LeftParenthesis.class)); - } - - @Test - public void rightParenthesisCreation() { - String text = ")"; - assertThat(createToken(text), instanceOf(RightParenthesis.class)); - } - - @Test - public void quoteMarkCreation() { - String text = "'"; - assertThat(createToken(text), instanceOf(QuoteMark.class)); - } - - @Test - public void numberCreation() { - String text = "987"; - assertThat(createToken(text), instanceOf(Number.class)); - } - - @Test - public void prefixedNumberCreation() { - String text = "-987"; - assertThat(createToken(text), instanceOf(Number.class)); - } - - @Test - public void identifierCreation() { - String text = "identifier"; - assertThat(createToken(text), instanceOf(Identifier.class)); - } - - @Test - public void prefixedIdentifierCreation() { - String text = "-identifier"; - assertThat(createToken(text), instanceOf(Identifier.class)); - } - - @Test - public void stringCreation() { - String text = "\"string\""; - assertThat(createToken(text), instanceOf(QuotedString.class)); - } - - @Test(expected = EmptyTokenTextException.class) - public void emptyString_ThrowsException() { - createToken(""); - } - - @Test - public void emptyTokenTextException_ContainsCorrectAttributes() { - try { - createToken(""); - } catch (EmptyTokenTextException e) { - String message = e.getMessage(); - assertThat(message, is(notNullValue())); - assertThat(message.length(), greaterThan(0)); - assertThat(e.getSeverity(), is(CRITICAL)); - } - } - - @Test(expected = BadCharacterException.class) - public void badCharacter_ThrowsException() { - createToken("[abc]"); - } - - @Test - public void backTickCreation() { - String text = "`"; - assertThat(createToken(text), instanceOf(Backquote.class)); - } - - @Test - public void commaCreation() { - String text = ","; - assertThat(createToken(text), instanceOf(Comma.class)); - } - - @Test - public void atSignCreation() { - String text = "@"; - assertThat(createToken(text), instanceOf(AtSign.class)); - } -} diff --git a/src/test/kotlin/token/TokenFactoryTest.kt b/src/test/kotlin/token/TokenFactoryTest.kt new file mode 100644 index 0000000..a468dbd --- /dev/null +++ b/src/test/kotlin/token/TokenFactoryTest.kt @@ -0,0 +1,109 @@ +package token + +import error.Severity.CRITICAL +import file.FilePosition +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Assertions.assertThrows +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInstance +import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS +import token.TokenFactory.BadCharacterException +import token.TokenFactory.EmptyTokenTextException + +@TestInstance(PER_CLASS) +class TokenFactoryTest { + + private lateinit var tokenFactory: TokenFactory + private lateinit var testPosition: FilePosition + + @BeforeEach + fun setUp() { + tokenFactory = TokenFactoryImpl() + testPosition = FilePosition("testFile", 0, 0) + } + + private fun createToken(text: String): Token { + return tokenFactory.createToken(text, testPosition) + } + + @Test + fun eofTokenCreation() { + assertThat(tokenFactory.createEofToken(testPosition)).isInstanceOf(Eof::class.java) + } + + @Test + fun leftParenthesisCreation() { + assertThat(createToken("(")).isInstanceOf(LeftParenthesis::class.java) + } + + @Test + fun rightParenthesisCreation() { + assertThat(createToken(")")).isInstanceOf(RightParenthesis::class.java) + } + + @Test + fun quoteMarkCreation() { + assertThat(createToken("'")).isInstanceOf(QuoteMark::class.java) + } + + @Test + fun numberCreation() { + assertThat(createToken("987")).isInstanceOf(Number::class.java) + } + + @Test + fun prefixedNumberCreation() { + assertThat(createToken("-987")).isInstanceOf(Number::class.java) + } + + @Test + fun identifierCreation() { + assertThat(createToken("identifier")).isInstanceOf(Identifier::class.java) + } + + @Test + fun prefixedIdentifierCreation() { + assertThat(createToken("-identifier")).isInstanceOf(Identifier::class.java) + } + + @Test + fun stringCreation() { + assertThat(createToken("\"string\"")).isInstanceOf(QuotedString::class.java) + } + + @Test + fun emptyString_ThrowsException() { + assertThrows(EmptyTokenTextException::class.java) { createToken("") } + } + + @Test + fun emptyTokenTextException_ContainsCorrectAttributes() { + try { + createToken("") + } catch (e: EmptyTokenTextException) { + assertThat(e.message).isNotEmpty(); + assertThat(e.severity).isEqualTo(CRITICAL) + } + } + + @Test + fun badCharacter_ThrowsException() { + assertThrows(BadCharacterException::class.java) { createToken("[abc]") } + } + + @Test + fun backTickCreation() { + assertThat(createToken("`")).isInstanceOf(Backquote::class.java) + } + + @Test + fun commaCreation() { + assertThat(createToken(",")).isInstanceOf(Comma::class.java) + } + + @Test + fun atSignCreation() { + assertThat(createToken("@")).isInstanceOf(AtSign::class.java) + } +}