diff --git a/src/test/kotlin/scanner/LispCommentRemovingInputStreamTest.java b/src/test/kotlin/scanner/LispCommentRemovingInputStreamTest.java deleted file mode 100644 index 874ff76..0000000 --- a/src/test/kotlin/scanner/LispCommentRemovingInputStreamTest.java +++ /dev/null @@ -1,228 +0,0 @@ -package scanner; - -import org.junit.Test; -import scanner.LispInputStream.MaximumUnreadsExceededException; -import stream.LispIOException; - -import java.io.InputStream; - -import static error.Severity.CRITICAL; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static testutil.TestUtilities.createIOExceptionThrowingInputStream; -import static testutil.TestUtilities.createInputStreamFromString; - -public class LispCommentRemovingInputStreamTest { - - private String getLispCommentRemovingInputStreamResult(String inputString) { - return readInputStreamIntoString(createLispInputStream(inputString)); - } - - private LispInputStream createLispInputStream(String inputString) { - InputStream stringInputStream = createInputStreamFromString(inputString); - - return new LispCommentRemovingInputStream(stringInputStream); - } - - private String readInputStreamIntoString(LispInputStream inputStream) { - StringBuilder charactersRead = new StringBuilder(); - for (int c = inputStream.read(); c != -1; c = inputStream.read()) - charactersRead.append((char) c); - - return charactersRead.toString(); - } - - @Test - public void noBytesIn_noBytesOut() { - String input = ""; - - assertEquals(input, getLispCommentRemovingInputStreamResult(input)); - } - - @Test - public void oneCharacter_notRemoved() { - String input = "x"; - - assertEquals(input, getLispCommentRemovingInputStreamResult(input)); - } - - @Test - public void allNonCommentCharacters_notRemoved() { - String input = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" - + "`1234567890-=~!@#$%^&*()_+[]\\',./{}|:\"<>?"; - - assertEquals(input, getLispCommentRemovingInputStreamResult(input)); - } - - @Test - public void oneComment_Removed() { - String input = ";comment"; - String expectedResult = ""; - - assertEquals(expectedResult, getLispCommentRemovingInputStreamResult(input)); - } - - @Test - public void multipleComments_Removed() { - String input = ";comment1\n;comment2\n;comment3"; - String expectedResult = "\n\n"; - - assertEquals(expectedResult, getLispCommentRemovingInputStreamResult(input)); - } - - @Test - public void nil_NotRemoved() { - String input = "()"; - String expectedResult = "()"; - - assertEquals(expectedResult, getLispCommentRemovingInputStreamResult(input)); - } - - @Test - public void interiorComment_Removed() { - String input = "(;this is a comment\n)"; - String expectedResult = "(\n)"; - - assertEquals(expectedResult, getLispCommentRemovingInputStreamResult(input)); - } - - @Test - public void commentInString_NotRemoved() { - String input = "\"string;this should remain\""; - - assertEquals(input, getLispCommentRemovingInputStreamResult(input)); - } - - @Test - public void commentInStringWithNewline_NotRemoved() { - String input = "\"string;this should\n remain\""; - - assertEquals(input, getLispCommentRemovingInputStreamResult(input)); - } - - @Test - public void commentInStringWithEscapedDoubleQuote_NotRemoved() { - String input = "\"string \\\" ;this should remain\""; - - assertEquals(input, getLispCommentRemovingInputStreamResult(input)); - } - - @Test - public void manyCommentsWithStatements_OnlyCommentsRemoved() { - String input = ";first comment \n '(1 2 3) \n ;second comment \n (defun add1 (x) (+ x 1)) ;third comment"; - String expectedResult = "\n '(1 2 3) \n \n (defun add1 (x) (+ x 1)) "; - - assertEquals(expectedResult, getLispCommentRemovingInputStreamResult(input)); - } - - @Test - public void unreadOneCharacter_ReturnsSameCharacter() { - String input = "abc"; - char expectedResult = 'a'; - LispInputStream lispInputStream = createLispInputStream(input); - - lispInputStream.read(); - lispInputStream.unreadLastCharacter(); - - assertEquals(expectedResult, lispInputStream.read()); - } - - @Test - public void unreadAndRereadSameCharacterMultipleTimes_ReturnsSameCharacter() { - String input = "abc"; - char expectedResult = 'a'; - LispInputStream lispInputStream = createLispInputStream(input); - - lispInputStream.read(); - lispInputStream.unreadLastCharacter(); - lispInputStream.read(); - lispInputStream.unreadLastCharacter(); - lispInputStream.read(); - lispInputStream.unreadLastCharacter(); - - assertEquals(expectedResult, lispInputStream.read()); - } - - @Test - public void unreadOneCharacterAndRereadIt_ReturnsNextCharacterOnNextRead() { - String input = "abc"; - char expectedResult = 'b'; - LispInputStream lispInputStream = createLispInputStream(input); - - lispInputStream.read(); - lispInputStream.unreadLastCharacter(); - lispInputStream.read(); - - assertEquals(expectedResult, lispInputStream.read()); - } - - @Test - public void unreadNewlineInStringAfterComment_ReturnsNewline() { - String input = "a;123\n"; - char expectedResult = '\n'; - LispInputStream lispInputStream = createLispInputStream(input); - - lispInputStream.read(); - lispInputStream.read(); - lispInputStream.unreadLastCharacter(); - - assertEquals(expectedResult, lispInputStream.read()); - } - - @Test(expected = MaximumUnreadsExceededException.class) - public void callUnreadMultipleTimes_ThrowsException() { - String input = "abc"; - LispInputStream lispInputStream = createLispInputStream(input); - - lispInputStream.read(); - lispInputStream.unreadLastCharacter(); - lispInputStream.unreadLastCharacter(); - } - - @Test - public void callUnreadMultipleTimes_ExceptionHasCorrectSeverity() { - String input = "abc"; - LispInputStream lispInputStream = createLispInputStream(input); - - lispInputStream.read(); - lispInputStream.unreadLastCharacter(); - - try { - lispInputStream.unreadLastCharacter(); - } catch (MaximumUnreadsExceededException e) { - assertEquals(CRITICAL, e.getSeverity()); - } - } - - @Test(expected = LispIOException.class) - public void underlyingInputStreamThrowsIOException_ConvertsToUncheckedIOException() { - InputStream ioExceptionThrowingInputStream = createIOExceptionThrowingInputStream(); - LispInputStream lispInputStream = new LispCommentRemovingInputStream(ioExceptionThrowingInputStream); - - lispInputStream.read(); - } - - @Test - public void underlyingInputStreamThrowsIOException_ExceptionHasCorrectAttributes() { - InputStream ioExceptionThrowingInputStream = createIOExceptionThrowingInputStream(); - LispInputStream lispInputStream = new LispCommentRemovingInputStream(ioExceptionThrowingInputStream); - - try { - lispInputStream.read(); - } catch (LispIOException e) { - String message = e.getMessage(); - assertNotNull(message); - assertTrue(message.length() >= 0); - assertEquals(CRITICAL, e.getSeverity()); - } - } - - @Test - public void readUnicodeCharacter() { - String input = "λ"; - String expectedResult = "λ"; - - assertEquals(expectedResult, getLispCommentRemovingInputStreamResult(input)); - } -} diff --git a/src/test/kotlin/scanner/LispCommentRemovingInputStreamTest.kt b/src/test/kotlin/scanner/LispCommentRemovingInputStreamTest.kt new file mode 100644 index 0000000..840f5f9 --- /dev/null +++ b/src/test/kotlin/scanner/LispCommentRemovingInputStreamTest.kt @@ -0,0 +1,216 @@ +package scanner + +import error.Severity.CRITICAL +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Assertions.assertThrows +import org.junit.jupiter.api.Test +import scanner.LispInputStream.MaximumUnreadsExceededException +import stream.LispIOException +import testutil.TestUtilities.createIOExceptionThrowingInputStream +import testutil.TestUtilities.createInputStreamFromString + +class LispCommentRemovingInputStreamTest { + + private fun getLispCommentRemovingInputStreamResult(inputString: String) = + readInputStreamIntoString(createLispInputStream(inputString)) + + private fun createLispInputStream(inputString: String) = + LispCommentRemovingInputStream(createInputStreamFromString(inputString)) + + private fun readInputStreamIntoString(inputStream: LispInputStream) = StringBuilder().let { + for (c in inputStream) + it.append(c.toChar()) + + it.toString() + } + + @Test + fun `no bytes in gives no bytes out`() { + val input = "" + + assertThat(getLispCommentRemovingInputStreamResult(input)).isEqualTo(input) + } + + @Test + fun `one character is not removed`() { + val input = "x" + + assertThat(getLispCommentRemovingInputStreamResult(input)).isEqualTo(input) + } + + @Test + fun `all non-comment characters are preserved`() { + val input = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`1234567890-=~!@#$%^&*()_+[]\\',./{}|:\"<>?" + + assertThat(getLispCommentRemovingInputStreamResult(input)).isEqualTo(input) + } + + @Test + fun `one comment is removed`() { + val input = ";comment" + val expectedResult = "" + + assertThat(getLispCommentRemovingInputStreamResult(input)).isEqualTo(expectedResult) + } + + @Test + fun `multiple comments are removed`() { + val input = ";comment1\n;comment2\n;comment3" + val expectedResult = "\n\n" + + assertThat(getLispCommentRemovingInputStreamResult(input)).isEqualTo(expectedResult) + } + + @Test + fun `NIL is not removed`() { + val input = "()" + val expectedResult = "()" + + assertThat(getLispCommentRemovingInputStreamResult(input)).isEqualTo(expectedResult) + } + + @Test + fun `interior comment is removed`() { + val input = "(;this is a comment\n)" + val expectedResult = "(\n)" + + assertThat(getLispCommentRemovingInputStreamResult(input)).isEqualTo(expectedResult) + } + + @Test + fun `comment in a string is not removed`() { + val input = "\"string;this should remain\"" + + assertThat(getLispCommentRemovingInputStreamResult(input)).isEqualTo(input) + } + + @Test + fun `comment in a string with a newline is not removed`() { + val input = "\"string;this should\n remain\"" + + assertThat(getLispCommentRemovingInputStreamResult(input)).isEqualTo(input) + } + + @Test + fun `comment in a strign with an escaped double quote is not removed`() { + val input = "\"string \\\" ;this should remain\"" + + assertThat(getLispCommentRemovingInputStreamResult(input)).isEqualTo(input) + } + + @Test + fun `only the comments are removed from several lines with expressions`() { + val input = ";first comment \n '(1 2 3) \n ;second comment \n (defun add1 (x) (+ x 1)) ;third comment" + val expectedResult = "\n '(1 2 3) \n \n (defun add1 (x) (+ x 1)) " + + assertThat(getLispCommentRemovingInputStreamResult(input)).isEqualTo(expectedResult) + } + + @Test + fun `reread one character`() { + val input = "abc" + val expectedResult = 'a' + val lispInputStream = createLispInputStream(input) + + lispInputStream.read() + lispInputStream.unreadLastCharacter() + + assertThat(lispInputStream.read().toLong()).isEqualTo(expectedResult.toLong()) + } + + @Test + fun `reread the same character multiple times`() { + val input = "abc" + val expectedResult = 'a' + val lispInputStream = createLispInputStream(input) + + lispInputStream.read() + lispInputStream.unreadLastCharacter() + lispInputStream.read() + lispInputStream.unreadLastCharacter() + lispInputStream.read() + lispInputStream.unreadLastCharacter() + + assertThat(lispInputStream.read().toLong()).isEqualTo(expectedResult.toLong()) + } + + @Test + fun `next character is read after a read and unread`() { + val input = "abc" + val expectedResult = 'b' + val lispInputStream = createLispInputStream(input) + + lispInputStream.read() + lispInputStream.unreadLastCharacter() + lispInputStream.read() + + assertThat(lispInputStream.read().toLong()).isEqualTo(expectedResult.toLong()) + } + + @Test + fun `read a newline after an unread at the end of a comment`() { + val input = "a;123\n" + val expectedResult = '\n' + val lispInputStream = createLispInputStream(input) + + lispInputStream.read() + lispInputStream.read() + lispInputStream.unreadLastCharacter() + + assertThat(lispInputStream.read().toLong()).isEqualTo(expectedResult.toLong()) + } + + @Test + fun `unable to unread more than one character`() { + val input = "abc" + val lispInputStream = createLispInputStream(input) + + lispInputStream.read() + lispInputStream.unreadLastCharacter() + assertThrows(MaximumUnreadsExceededException::class.java) { lispInputStream.unreadLastCharacter() } + } + + @Test + fun `MaximumUnreadsExceededException is cool`() { + val input = "abc" + val lispInputStream = createLispInputStream(input) + + lispInputStream.read() + lispInputStream.unreadLastCharacter() + + try { + lispInputStream.unreadLastCharacter() + } catch (e: MaximumUnreadsExceededException) { + assertThat(e.severity).isEqualTo(CRITICAL) + } + } + + @Test + fun `IOException is converted to LispIOException`() { + val ioExceptionThrowingInputStream = createIOExceptionThrowingInputStream() + val lispInputStream = LispCommentRemovingInputStream(ioExceptionThrowingInputStream) + + assertThrows(LispIOException::class.java) { lispInputStream.read() } + } + + @Test + fun `LispIOException is cool`() { + val ioExceptionThrowingInputStream = createIOExceptionThrowingInputStream() + val lispInputStream = LispCommentRemovingInputStream(ioExceptionThrowingInputStream) + + try { + lispInputStream.read() + } catch (e: LispIOException) { + assertThat(e.message).isNotEmpty() + assertThat(e.severity).isEqualTo(CRITICAL) + } + } + + @Test + fun `read a unicode character`() { + val input = "λ" + val expectedResult = "λ" + + assertThat(getLispCommentRemovingInputStreamResult(input)).isEqualTo(expectedResult) + } +} diff --git a/src/test/kotlin/scanner/LispScannerLineColumnTest.java b/src/test/kotlin/scanner/LispScannerLineColumnTest.java deleted file mode 100644 index 201ba9d..0000000 --- a/src/test/kotlin/scanner/LispScannerLineColumnTest.java +++ /dev/null @@ -1,136 +0,0 @@ -package scanner; - -import file.FilePosition; -import org.junit.Test; -import token.Token; - -import java.io.InputStream; - -import static org.junit.Assert.assertTrue; -import static testutil.TestUtilities.createInputStreamFromString; - -public class LispScannerLineColumnTest { - - private static class LineColumn { - - private int line; - private int column; - - public static LineColumn create(int line, int column) { - LineColumn lineColumn = new LineColumn(); - lineColumn.line = line; - lineColumn.column = column; - - return lineColumn; - } - - public boolean isEqual(FilePosition position) { - return (this.line == position.getLineNumber()) && (this.column == position.getColumnNumber()); - } - } - - private void assertTokenLineAndColumnsMatch(String input, LineColumn[] expectedLineColumnList) { - InputStream stringInputStream = createInputStreamFromString(input); - LispScanner lispScanner = new LispScanner(stringInputStream, "testFile"); - - for (LineColumn lineColumn : expectedLineColumnList) { - Token nextToken = lispScanner.getNextToken(); - assertTrue(lineColumn.isEqual(nextToken.getPosition())); - } - } - - @Test - public void givenNothing_RecordsCorrectEofLocation() { - String input = ""; - LineColumn[] expectedLinesAndColumns = { LineColumn.create(1, 0) }; - - assertTokenLineAndColumnsMatch(input, expectedLinesAndColumns); - } - - @Test - public void givenSimpleString_RecordsCorrectLocation() { - String input = "\"string\""; - LineColumn[] expectedLinesAndColumns = { LineColumn.create(1, 1) }; - - assertTokenLineAndColumnsMatch(input, expectedLinesAndColumns); - } - - @Test - public void givenStringWithTrailingSpace_RecordsCorrectLocation() { - String input = "\"string\" "; - LineColumn[] expectedLinesAndColumns = { LineColumn.create(1, 1) }; - - assertTokenLineAndColumnsMatch(input, expectedLinesAndColumns); - } - - @Test - public void givenIdentifier_RecordsCorrectLocation() { - String input = "identifier"; - LineColumn[] expectedLinesAndColumns = { LineColumn.create(1, 1) }; - - assertTokenLineAndColumnsMatch(input, expectedLinesAndColumns); - } - - @Test - public void givenIdentifierWithTrailingSpace_RecordsCorrectLocation() { - String input = "identifier "; - LineColumn[] expectedLinesAndColumns = { LineColumn.create(1, 1) }; - - assertTokenLineAndColumnsMatch(input, expectedLinesAndColumns); - } - - @Test - public void givenNumber_RecordsCorrectLocation() { - String input = "123456789"; - LineColumn[] expectedLinesAndColumns = { LineColumn.create(1, 1) }; - - assertTokenLineAndColumnsMatch(input, expectedLinesAndColumns); - } - - @Test - public void givenNumberWithTrailingSpace_RecordsCorrectLocation() { - String input = "123456789 "; - LineColumn[] expectedLinesAndColumns = { LineColumn.create(1, 1) }; - - assertTokenLineAndColumnsMatch(input, expectedLinesAndColumns); - } - - @Test - public void givenMultipleStrings_RecordsCorrectLocations() { - String input = "\"string1\" \n \"string2 \n with newline\" \n \"string3\""; - LineColumn[] expectedLinesAndColumns = { LineColumn.create(1, 1), LineColumn.create(2, 2), - LineColumn.create(4, 3) }; - - assertTokenLineAndColumnsMatch(input, expectedLinesAndColumns); - } - - @Test - public void givenQuotedList_RecordsCorrectLocations() { - String input = "'(1 2 3 4 5)"; - LineColumn[] expectedLinesAndColumns = { LineColumn.create(1, 1), LineColumn.create(1, 2), - LineColumn.create(1, 3), LineColumn.create(1, 5), - LineColumn.create(1, 7), LineColumn.create(1, 9), - LineColumn.create(1, 11), LineColumn.create(1, 12) }; - - assertTokenLineAndColumnsMatch(input, expectedLinesAndColumns); - } - - @Test - public void givenListSpanningMultipleLines_RecordsCorrectLocations() { - String input = " ( 1 2 \n 3 4 \n5 ) "; - LineColumn[] expectedLinesAndColumns = { LineColumn.create(1, 2), LineColumn.create(1, 4), - LineColumn.create(1, 6), LineColumn.create(2, 2), - LineColumn.create(2, 4), LineColumn.create(3, 1), - LineColumn.create(3, 3) }; - - assertTokenLineAndColumnsMatch(input, expectedLinesAndColumns); - } - - @Test - public void givenCommentImmediatelyFollowingNumber_RecordsCorrectLocations() { - String input = "12;comment\n34"; - LineColumn[] expectedLinesAndColumns = { LineColumn.create(1, 1), LineColumn.create(2, 1) }; - - assertTokenLineAndColumnsMatch(input, expectedLinesAndColumns); - } -} diff --git a/src/test/kotlin/scanner/LispScannerLineColumnTest.kt b/src/test/kotlin/scanner/LispScannerLineColumnTest.kt new file mode 100644 index 0000000..5408364 --- /dev/null +++ b/src/test/kotlin/scanner/LispScannerLineColumnTest.kt @@ -0,0 +1,145 @@ +package scanner + +import file.FilePosition +import org.junit.Test +import token.Token + +import java.io.InputStream + +import org.junit.Assert.assertTrue +import testutil.TestUtilities.createInputStreamFromString + +class LispScannerLineColumnTest { + + private class LineColumn { + + private var line: Int = 0 + private var column: Int = 0 + + fun isEqual(position: FilePosition): Boolean { + return this.line == position.lineNumber && this.column == position.columnNumber + } + + companion object { + + fun create(line: Int, column: Int): LineColumn { + val lineColumn = LineColumn() + lineColumn.line = line + lineColumn.column = column + + return lineColumn + } + } + } + + private fun assertTokenLineAndColumnsMatch(input: String, expectedLineColumnList: Array) { + val stringInputStream = createInputStreamFromString(input) + val lispScanner = LispScanner(stringInputStream, "testFile") + + for (lineColumn in expectedLineColumnList) { + val nextToken = lispScanner.nextToken + assertTrue(lineColumn.isEqual(nextToken.position)) + } + } + + @Test + fun givenNothing_RecordsCorrectEofLocation() { + val input = "" + val expectedLinesAndColumns = arrayOf(LineColumn.create(1, 0)) + + assertTokenLineAndColumnsMatch(input, expectedLinesAndColumns) + } + + @Test + fun givenSimpleString_RecordsCorrectLocation() { + val input = "\"string\"" + val expectedLinesAndColumns = arrayOf(LineColumn.create(1, 1)) + + assertTokenLineAndColumnsMatch(input, expectedLinesAndColumns) + } + + @Test + fun givenStringWithTrailingSpace_RecordsCorrectLocation() { + val input = "\"string\" " + val expectedLinesAndColumns = arrayOf(LineColumn.create(1, 1)) + + assertTokenLineAndColumnsMatch(input, expectedLinesAndColumns) + } + + @Test + fun givenIdentifier_RecordsCorrectLocation() { + val input = "identifier" + val expectedLinesAndColumns = arrayOf(LineColumn.create(1, 1)) + + assertTokenLineAndColumnsMatch(input, expectedLinesAndColumns) + } + + @Test + fun givenIdentifierWithTrailingSpace_RecordsCorrectLocation() { + val input = "identifier " + val expectedLinesAndColumns = arrayOf(LineColumn.create(1, 1)) + + assertTokenLineAndColumnsMatch(input, expectedLinesAndColumns) + } + + @Test + fun givenNumber_RecordsCorrectLocation() { + val input = "123456789" + val expectedLinesAndColumns = arrayOf(LineColumn.create(1, 1)) + + assertTokenLineAndColumnsMatch(input, expectedLinesAndColumns) + } + + @Test + fun givenNumberWithTrailingSpace_RecordsCorrectLocation() { + val input = "123456789 " + val expectedLinesAndColumns = arrayOf(LineColumn.create(1, 1)) + + assertTokenLineAndColumnsMatch(input, expectedLinesAndColumns) + } + + @Test + fun givenMultipleStrings_RecordsCorrectLocations() { + val input = "\"string1\" \n \"string2 \n with newline\" \n \"string3\"" + val expectedLinesAndColumns = arrayOf(LineColumn.create(1, 1), LineColumn.create(2, 2), LineColumn.create(4, 3)) + + assertTokenLineAndColumnsMatch(input, expectedLinesAndColumns) + } + + @Test + fun givenQuotedList_RecordsCorrectLocations() { + val input = "'(1 2 3 4 5)" + val expectedLinesAndColumns = arrayOf(LineColumn.create(1, 1), + LineColumn.create(1, 2), + LineColumn.create(1, 3), + LineColumn.create(1, 5), + LineColumn.create(1, 7), + LineColumn.create(1, 9), + LineColumn.create(1, 11), + LineColumn.create(1, 12)) + + assertTokenLineAndColumnsMatch(input, expectedLinesAndColumns) + } + + @Test + fun givenListSpanningMultipleLines_RecordsCorrectLocations() { + val input = " ( 1 2 \n 3 4 \n5 ) " + val expectedLinesAndColumns = arrayOf(LineColumn.create(1, 2), + LineColumn.create(1, 4), + LineColumn.create(1, 6), + LineColumn.create(2, 2), + LineColumn.create(2, 4), + LineColumn.create(3, 1), + LineColumn.create(3, 3)) + + assertTokenLineAndColumnsMatch(input, expectedLinesAndColumns) + } + + @Test + fun givenCommentImmediatelyFollowingNumber_RecordsCorrectLocations() { + val input = "12;comment\n34" + val expectedLinesAndColumns = arrayOf(LineColumn.create(1, 1), LineColumn.create(2, 1)) + + assertTokenLineAndColumnsMatch(input, expectedLinesAndColumns) + } +} diff --git a/src/test/kotlin/scanner/LispScannerTextTest.java b/src/test/kotlin/scanner/LispScannerTextTest.java deleted file mode 100644 index 9694d43..0000000 --- a/src/test/kotlin/scanner/LispScannerTextTest.java +++ /dev/null @@ -1,116 +0,0 @@ -package scanner; - -import file.FilePosition; -import org.junit.Test; - -import java.io.InputStream; - -import static org.junit.Assert.assertEquals; -import static testutil.TestUtilities.createInputStreamFromString; - -public class LispScannerTextTest { - - private void assertTokenTextMatches(String input, String[] expectedTextList) { - LispScanner lispScanner = createLispScanner(input); - - for (String expectedText : expectedTextList) - assertEquals(expectedText, lispScanner.getNextToken().getText()); - } - - private void assertTokenTextMatches(String input, String expectedText) { - LispScanner lispScanner = createLispScanner(input); - - assertEquals(expectedText, lispScanner.getNextToken().getText()); - } - - private LispScanner createLispScanner(String input) { - InputStream stringInputStream = createInputStreamFromString(input); - - return new LispScanner(stringInputStream, "testFile"); - } - - private void assertInputFileNameMatches(String input, String expectedInputFileName) { - InputStream stringInputStream = createInputStreamFromString(input); - LispScanner lispScanner = new LispScanner(stringInputStream, expectedInputFileName); - FilePosition tokenPosition = lispScanner.getNextToken().getPosition(); - - assertEquals(expectedInputFileName, tokenPosition.getFileName()); - } - - @Test - public void givenEmptyStream_RecordsCorrectFileName() { - String input = ""; - String expectedFileName = "testFileName"; - - assertInputFileNameMatches(input, expectedFileName); - } - - @Test - public void givenParenthesis_RecordsCorrectText() { - String input = "()"; - String[] expected = { "(", ")" }; - - assertTokenTextMatches(input, expected); - } - - @Test - public void givenQuote_RecordsCorrectText() { - String input = "'"; - String expected = "'"; - - assertTokenTextMatches(input, expected); - } - - @Test - public void givenEof_ReordsCorrectText() { - String input = ""; - String expected = "EOF"; - - assertTokenTextMatches(input, expected); - } - - @Test - public void givenIdentifier_RecordsCorrectText() { - String input = "identifier"; - - assertTokenTextMatches(input, input); - } - - @Test - public void givenNumber_RecordsCorrectText() { - String input = "192837456"; - - assertTokenTextMatches(input, input); - } - - @Test - public void givenString_RecordsCorrectText() { - String input = "\"String!!! \n More... \""; - - assertTokenTextMatches(input, input); - } - - @Test - public void givenNumberFollowedByComment_RecordsCorrectText() { - String input = "192837456;comment"; - String expected = "192837456"; - - assertTokenTextMatches(input, expected); - } - - @Test - public void givenIdentifiersWithCommentBetween_RecordsCorrectText() { - String input = "abc123;comment\nabc222"; - String[] expected = { "abc123", "abc222" }; - - assertTokenTextMatches(input, expected); - } - - @Test - public void givenBackTickExpression_RecordsCorrectText() { - String input = "`(list ,a ,@b)"; - String[] expected = { "`", "(", "list", ",", "a", ",", "@", "b", ")" }; - - assertTokenTextMatches(input, expected); - } -} diff --git a/src/test/kotlin/scanner/LispScannerTextTest.kt b/src/test/kotlin/scanner/LispScannerTextTest.kt new file mode 100644 index 0000000..faca00d --- /dev/null +++ b/src/test/kotlin/scanner/LispScannerTextTest.kt @@ -0,0 +1,116 @@ +package scanner + +import file.FilePosition +import org.junit.Test + +import java.io.InputStream + +import org.junit.Assert.assertEquals +import testutil.TestUtilities.createInputStreamFromString + +class LispScannerTextTest { + + private fun assertTokenTextMatches(input: String, expectedTextList: Array) { + val lispScanner = createLispScanner(input) + + for (expectedText in expectedTextList) + assertEquals(expectedText, lispScanner.nextToken.text) + } + + private fun assertTokenTextMatches(input: String, expectedText: String) { + val lispScanner = createLispScanner(input) + + assertEquals(expectedText, lispScanner.nextToken.text) + } + + private fun createLispScanner(input: String): LispScanner { + val stringInputStream = createInputStreamFromString(input) + + return LispScanner(stringInputStream, "testFile") + } + + private fun assertInputFileNameMatches(input: String, expectedInputFileName: String) { + val stringInputStream = createInputStreamFromString(input) + val lispScanner = LispScanner(stringInputStream, expectedInputFileName) + val (fileName) = lispScanner.nextToken.position + + assertEquals(expectedInputFileName, fileName) + } + + @Test + fun givenEmptyStream_RecordsCorrectFileName() { + val input = "" + val expectedFileName = "testFileName" + + assertInputFileNameMatches(input, expectedFileName) + } + + @Test + fun givenParenthesis_RecordsCorrectText() { + val input = "()" + val expected = arrayOf("(", ")") + + assertTokenTextMatches(input, expected) + } + + @Test + fun givenQuote_RecordsCorrectText() { + val input = "'" + val expected = "'" + + assertTokenTextMatches(input, expected) + } + + @Test + fun givenEof_ReordsCorrectText() { + val input = "" + val expected = "EOF" + + assertTokenTextMatches(input, expected) + } + + @Test + fun givenIdentifier_RecordsCorrectText() { + val input = "identifier" + + assertTokenTextMatches(input, input) + } + + @Test + fun givenNumber_RecordsCorrectText() { + val input = "192837456" + + assertTokenTextMatches(input, input) + } + + @Test + fun givenString_RecordsCorrectText() { + val input = "\"String!!! \n More... \"" + + assertTokenTextMatches(input, input) + } + + @Test + fun givenNumberFollowedByComment_RecordsCorrectText() { + val input = "192837456;comment" + val expected = "192837456" + + assertTokenTextMatches(input, expected) + } + + @Test + fun givenIdentifiersWithCommentBetween_RecordsCorrectText() { + val input = "abc123;comment\nabc222" + val expected = arrayOf("abc123", "abc222") + + assertTokenTextMatches(input, expected) + } + + @Test + fun givenBackTickExpression_RecordsCorrectText() { + val input = "`(list ,a ,@b)" + val expected = arrayOf("`", "(", "list", ",", "a", ",", "@", "b", ")") + + assertTokenTextMatches(input, expected) + } +} diff --git a/src/test/kotlin/scanner/LispScannerTypeTest.java b/src/test/kotlin/scanner/LispScannerTypeTest.java deleted file mode 100644 index 04f686b..0000000 --- a/src/test/kotlin/scanner/LispScannerTypeTest.java +++ /dev/null @@ -1,308 +0,0 @@ -package scanner; - -import org.junit.Before; -import org.junit.Test; -import scanner.LispScanner.UnterminatedStringException; -import token.AtSign; -import token.Backquote; -import token.Comma; -import token.Eof; -import token.Identifier; -import token.LeftParenthesis; -import token.Number; -import token.QuoteMark; -import token.QuotedString; -import token.RightParenthesis; -import token.Token; -import token.TokenFactory.BadCharacterException; - -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; - -import static error.Severity.ERROR; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static testutil.TestUtilities.createInputStreamFromString; - -public class LispScannerTypeTest { - - private List> expectedTypes; - - private void assertTokenTypesMatch(String input) { - InputStream stringInputStream = createInputStreamFromString(input); - LispScanner lispScanner = new LispScanner(stringInputStream, "testFile"); - - for (Class type : expectedTypes) - assertTrue(type.isInstance(lispScanner.getNextToken())); - - assertTrue(lispScanner.getNextToken() instanceof Eof); - } - - @Before - public void setUp() { - expectedTypes = new ArrayList<>(); - } - - @Test - public void givenEmptyFile_ReturnsCorrectTypes() { - String input = ""; - - assertTokenTypesMatch(input); - } - - @Test(expected = BadCharacterException.class) - public void givenBadCharacter_ThrowsException() { - String input = "["; - - assertTokenTypesMatch(input); - } - - @Test - public void givenBadCharacter_ExceptionContainsCorrectSeverity() { - String input = "abc\ndef["; - expectedTypes.add(Identifier.class); - expectedTypes.add(Identifier.class); - - try { - assertTokenTypesMatch(input); - } catch (BadCharacterException e) { - assertEquals(ERROR, e.getSeverity()); - } - } - - @Test - public void givenBadCharacter_ExceptionContainsMessage() { - String input = "abc\ndef["; - expectedTypes.add(Identifier.class); - expectedTypes.add(Identifier.class); - - try { - assertTokenTypesMatch(input); - } catch (BadCharacterException e) { - String message = e.getMessage(); - assertNotNull(message); - assertTrue(message.length() > 0); - } - } - - @Test - public void givenNil_ReturnsCorrectTypes() { - String input = "()"; - expectedTypes.add(LeftParenthesis.class); - expectedTypes.add(RightParenthesis.class); - - assertTokenTypesMatch(input); - } - - @Test - public void givenListOfNumbers_ReturnsCorrectTypes() { - String input = "(1 2)"; - expectedTypes.add(LeftParenthesis.class); - expectedTypes.add(Number.class); - expectedTypes.add(Number.class); - expectedTypes.add(RightParenthesis.class); - - assertTokenTypesMatch(input); - } - - @Test - public void givenString_ReturnsCorrectTypes() { - String input = "\"string\""; - expectedTypes.add(QuotedString.class); - - assertTokenTypesMatch(input); - } - - @Test - public void givenStringWithEscapedDoubleQuote_ReturnsCorrectTypes() { - String input = "\"string \n hi \\\" bye\""; - expectedTypes.add(QuotedString.class); - - assertTokenTypesMatch(input); - } - - @Test - public void givenStringWithEscapedDoubleQuoteAndComment_ReturnsCorrectTypes() { - String input = "\"string \n hi \\\" ; bye\""; - expectedTypes.add(QuotedString.class); - - assertTokenTypesMatch(input); - } - - @Test(expected = UnterminatedStringException.class) - public void givenUnterminatedString_ThrowsException() { - String input = "\"oh no!"; - expectedTypes.add(QuotedString.class); - - assertTokenTypesMatch(input); - } - - @Test() - public void givenUnterminatedString_ExceptionHasCorrectSeverity() { - String input = "\"oh no!"; - expectedTypes.add(QuotedString.class); - - try { - assertTokenTypesMatch(input); - } catch (LispScanner.UnterminatedStringException e) { - assertEquals(ERROR, e.getSeverity()); - } - } - - @Test() - public void givenUnterminatedString_ExceptionContainsMessage() { - String input = "\"oh no!"; - expectedTypes.add(QuotedString.class); - - try { - assertTokenTypesMatch(input); - } catch (LispScanner.UnterminatedStringException e) { - String message = e.getMessage(); - assertNotNull(message); - assertTrue(message.length() > 0); - } - } - - @Test - public void givenIdentifier_ReturnsCorrectTypes() { - String input = "abcdefgHIJKLMNOP1234"; - expectedTypes.add(Identifier.class); - - assertTokenTypesMatch(input); - } - - @Test - public void givenPrefixedIdentifiers_ReturnsCorrectTypes() { - String input = "-a +b"; - expectedTypes.add(Identifier.class); - expectedTypes.add(Identifier.class); - - assertTokenTypesMatch(input); - } - - @Test - public void givenSingleDigitNumber_ReturnsCorrectTypes() { - String input = "1"; - expectedTypes.add(Number.class); - - assertTokenTypesMatch(input); - } - - @Test - public void givenPrefixedNegativeNumber_ReturnsCorrectTypes() { - String input = "-1"; - expectedTypes.add(Number.class); - - assertTokenTypesMatch(input); - } - - @Test - public void givenPrefixedNumber_ReturnsCorrectTypes() { - String input = "+1"; - expectedTypes.add(Number.class); - - assertTokenTypesMatch(input); - } - - @Test - public void givenPrefixedNegativeNumberAndIdentifier_ReturnsCorrectTypes() { - String input = "-1apple"; - expectedTypes.add(Number.class); - expectedTypes.add(Identifier.class); - - assertTokenTypesMatch(input); - } - - @Test - public void givenPrefixedNumberAndIdentifier_ReturnsCorrectTypes() { - String input = "+1apple"; - expectedTypes.add(Number.class); - expectedTypes.add(Identifier.class); - - assertTokenTypesMatch(input); - } - - @Test - public void givenPrefixedNegativeNumberAndString_ReturnsCorrectTypes() { - String input = "-1\"apple\""; - expectedTypes.add(Number.class); - expectedTypes.add(QuotedString.class); - - assertTokenTypesMatch(input); - } - - @Test - public void givenPrefixedNumberAndString_ReturnsCorrectTypes() { - String input = "+1\"apple\""; - expectedTypes.add(Number.class); - expectedTypes.add(QuotedString.class); - - assertTokenTypesMatch(input); - } - - @Test - public void givenMultipleDigitNumber_ReturnsCorrectTypes() { - String input = "1234567890"; - expectedTypes.add(Number.class); - - assertTokenTypesMatch(input); - } - - @Test - public void givenQuote_ReturnsCorrectTypes() { - String input = "'"; - expectedTypes.add(QuoteMark.class); - - assertTokenTypesMatch(input); - } - - @Test - public void givenManyTypesWithNoWhitespace_ReturnsCorrectTypes() { - String input = "xxx\"hi\"999()'aaa"; - expectedTypes.add(Identifier.class); - expectedTypes.add(QuotedString.class); - expectedTypes.add(Number.class); - expectedTypes.add(LeftParenthesis.class); - expectedTypes.add(RightParenthesis.class); - expectedTypes.add(QuoteMark.class); - expectedTypes.add(Identifier.class); - - assertTokenTypesMatch(input); - } - - @Test - public void givenFunctionCall_ReturnsCorrectTypes() { - String input = "(defun myFunction (x)\n (print x))"; - expectedTypes.add(LeftParenthesis.class); - expectedTypes.add(Identifier.class); - expectedTypes.add(Identifier.class); - expectedTypes.add(LeftParenthesis.class); - expectedTypes.add(Identifier.class); - expectedTypes.add(RightParenthesis.class); - expectedTypes.add(LeftParenthesis.class); - expectedTypes.add(Identifier.class); - expectedTypes.add(Identifier.class); - expectedTypes.add(RightParenthesis.class); - expectedTypes.add(RightParenthesis.class); - - assertTokenTypesMatch(input); - } - - @Test - public void givenBackTickExpression_ReturnsCorrectTypes() { - String input = "`(list ,a ,@b)"; - expectedTypes.add(Backquote.class); - expectedTypes.add(LeftParenthesis.class); - expectedTypes.add(Identifier.class); - expectedTypes.add(Comma.class); - expectedTypes.add(Identifier.class); - expectedTypes.add(Comma.class); - expectedTypes.add(AtSign.class); - expectedTypes.add(Identifier.class); - expectedTypes.add(RightParenthesis.class); - - assertTokenTypesMatch(input); - } -} diff --git a/src/test/kotlin/scanner/LispScannerTypeTest.kt b/src/test/kotlin/scanner/LispScannerTypeTest.kt new file mode 100644 index 0000000..27a7159 --- /dev/null +++ b/src/test/kotlin/scanner/LispScannerTypeTest.kt @@ -0,0 +1,307 @@ +package scanner + +import org.junit.Before +import org.junit.Test +import scanner.LispScanner.UnterminatedStringException +import token.AtSign +import token.Backquote +import token.Comma +import token.Eof +import token.Identifier +import token.LeftParenthesis +import token.Number +import token.QuoteMark +import token.QuotedString +import token.RightParenthesis +import token.Token +import token.TokenFactory.BadCharacterException + +import java.io.InputStream +import java.util.ArrayList + +import error.Severity.ERROR +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotNull +import org.junit.Assert.assertTrue +import testutil.TestUtilities.createInputStreamFromString + +class LispScannerTypeTest { + + private var expectedTypes: MutableList>? = null + + private fun assertTokenTypesMatch(input: String) { + val stringInputStream = createInputStreamFromString(input) + val lispScanner = LispScanner(stringInputStream, "testFile") + + for (type in expectedTypes!!) + assertTrue(type.isInstance(lispScanner.nextToken)) + + assertTrue(lispScanner.nextToken is Eof) + } + + @Before + fun setUp() { + expectedTypes = ArrayList() + } + + @Test + fun givenEmptyFile_ReturnsCorrectTypes() { + val input = "" + + assertTokenTypesMatch(input) + } + + @Test(expected = BadCharacterException::class) + fun givenBadCharacter_ThrowsException() { + val input = "[" + + assertTokenTypesMatch(input) + } + + @Test + fun givenBadCharacter_ExceptionContainsCorrectSeverity() { + val input = "abc\ndef[" + expectedTypes!!.add(Identifier::class.java) + expectedTypes!!.add(Identifier::class.java) + + try { + assertTokenTypesMatch(input) + } catch (e: BadCharacterException) { + assertEquals(ERROR, e.severity) + } + } + + @Test + fun givenBadCharacter_ExceptionContainsMessage() { + val input = "abc\ndef[" + expectedTypes!!.add(Identifier::class.java) + expectedTypes!!.add(Identifier::class.java) + + try { + assertTokenTypesMatch(input) + } catch (e: BadCharacterException) { + val message = e.message + assertNotNull(message) + assertTrue(message.length > 0) + } + } + + @Test + fun givenNil_ReturnsCorrectTypes() { + val input = "()" + expectedTypes!!.add(LeftParenthesis::class.java) + expectedTypes!!.add(RightParenthesis::class.java) + + assertTokenTypesMatch(input) + } + + @Test + fun givenListOfNumbers_ReturnsCorrectTypes() { + val input = "(1 2)" + expectedTypes!!.add(LeftParenthesis::class.java) + expectedTypes!!.add(Number::class.java) + expectedTypes!!.add(Number::class.java) + expectedTypes!!.add(RightParenthesis::class.java) + + assertTokenTypesMatch(input) + } + + @Test + fun givenString_ReturnsCorrectTypes() { + val input = "\"string\"" + expectedTypes!!.add(QuotedString::class.java) + + assertTokenTypesMatch(input) + } + + @Test + fun givenStringWithEscapedDoubleQuote_ReturnsCorrectTypes() { + val input = "\"string \n hi \\\" bye\"" + expectedTypes!!.add(QuotedString::class.java) + + assertTokenTypesMatch(input) + } + + @Test + fun givenStringWithEscapedDoubleQuoteAndComment_ReturnsCorrectTypes() { + val input = "\"string \n hi \\\" ; bye\"" + expectedTypes!!.add(QuotedString::class.java) + + assertTokenTypesMatch(input) + } + + @Test(expected = UnterminatedStringException::class) + fun givenUnterminatedString_ThrowsException() { + val input = "\"oh no!" + expectedTypes!!.add(QuotedString::class.java) + + assertTokenTypesMatch(input) + } + + @Test + fun givenUnterminatedString_ExceptionHasCorrectSeverity() { + val input = "\"oh no!" + expectedTypes!!.add(QuotedString::class.java) + + try { + assertTokenTypesMatch(input) + } catch (e: LispScanner.UnterminatedStringException) { + assertEquals(ERROR, e.severity) + } + } + + @Test + fun givenUnterminatedString_ExceptionContainsMessage() { + val input = "\"oh no!" + expectedTypes!!.add(QuotedString::class.java) + + try { + assertTokenTypesMatch(input) + } catch (e: LispScanner.UnterminatedStringException) { + val message = e.message + assertNotNull(message) + assertTrue(message.length > 0) + } + } + + @Test + fun givenIdentifier_ReturnsCorrectTypes() { + val input = "abcdefgHIJKLMNOP1234" + expectedTypes!!.add(Identifier::class.java) + + assertTokenTypesMatch(input) + } + + @Test + fun givenPrefixedIdentifiers_ReturnsCorrectTypes() { + val input = "-a +b" + expectedTypes!!.add(Identifier::class.java) + expectedTypes!!.add(Identifier::class.java) + + assertTokenTypesMatch(input) + } + + @Test + fun givenSingleDigitNumber_ReturnsCorrectTypes() { + val input = "1" + expectedTypes!!.add(Number::class.java) + + assertTokenTypesMatch(input) + } + + @Test + fun givenPrefixedNegativeNumber_ReturnsCorrectTypes() { + val input = "-1" + expectedTypes!!.add(Number::class.java) + + assertTokenTypesMatch(input) + } + + @Test + fun givenPrefixedNumber_ReturnsCorrectTypes() { + val input = "+1" + expectedTypes!!.add(Number::class.java) + + assertTokenTypesMatch(input) + } + + @Test + fun givenPrefixedNegativeNumberAndIdentifier_ReturnsCorrectTypes() { + val input = "-1apple" + expectedTypes!!.add(Number::class.java) + expectedTypes!!.add(Identifier::class.java) + + assertTokenTypesMatch(input) + } + + @Test + fun givenPrefixedNumberAndIdentifier_ReturnsCorrectTypes() { + val input = "+1apple" + expectedTypes!!.add(Number::class.java) + expectedTypes!!.add(Identifier::class.java) + + assertTokenTypesMatch(input) + } + + @Test + fun givenPrefixedNegativeNumberAndString_ReturnsCorrectTypes() { + val input = "-1\"apple\"" + expectedTypes!!.add(Number::class.java) + expectedTypes!!.add(QuotedString::class.java) + + assertTokenTypesMatch(input) + } + + @Test + fun givenPrefixedNumberAndString_ReturnsCorrectTypes() { + val input = "+1\"apple\"" + expectedTypes!!.add(Number::class.java) + expectedTypes!!.add(QuotedString::class.java) + + assertTokenTypesMatch(input) + } + + @Test + fun givenMultipleDigitNumber_ReturnsCorrectTypes() { + val input = "1234567890" + expectedTypes!!.add(Number::class.java) + + assertTokenTypesMatch(input) + } + + @Test + fun givenQuote_ReturnsCorrectTypes() { + val input = "'" + expectedTypes!!.add(QuoteMark::class.java) + + assertTokenTypesMatch(input) + } + + @Test + fun givenManyTypesWithNoWhitespace_ReturnsCorrectTypes() { + val input = "xxx\"hi\"999()'aaa" + expectedTypes!!.add(Identifier::class.java) + expectedTypes!!.add(QuotedString::class.java) + expectedTypes!!.add(Number::class.java) + expectedTypes!!.add(LeftParenthesis::class.java) + expectedTypes!!.add(RightParenthesis::class.java) + expectedTypes!!.add(QuoteMark::class.java) + expectedTypes!!.add(Identifier::class.java) + + assertTokenTypesMatch(input) + } + + @Test + fun givenFunctionCall_ReturnsCorrectTypes() { + val input = "(defun myFunction (x)\n (print x))" + expectedTypes!!.add(LeftParenthesis::class.java) + expectedTypes!!.add(Identifier::class.java) + expectedTypes!!.add(Identifier::class.java) + expectedTypes!!.add(LeftParenthesis::class.java) + expectedTypes!!.add(Identifier::class.java) + expectedTypes!!.add(RightParenthesis::class.java) + expectedTypes!!.add(LeftParenthesis::class.java) + expectedTypes!!.add(Identifier::class.java) + expectedTypes!!.add(Identifier::class.java) + expectedTypes!!.add(RightParenthesis::class.java) + expectedTypes!!.add(RightParenthesis::class.java) + + assertTokenTypesMatch(input) + } + + @Test + fun givenBackTickExpression_ReturnsCorrectTypes() { + val input = "`(list ,a ,@b)" + expectedTypes!!.add(Backquote::class.java) + expectedTypes!!.add(LeftParenthesis::class.java) + expectedTypes!!.add(Identifier::class.java) + expectedTypes!!.add(Comma::class.java) + expectedTypes!!.add(Identifier::class.java) + expectedTypes!!.add(Comma::class.java) + expectedTypes!!.add(AtSign::class.java) + expectedTypes!!.add(Identifier::class.java) + expectedTypes!!.add(RightParenthesis::class.java) + + assertTokenTypesMatch(input) + } +}