package parser; import static error.ErrorManager.Severity.ERROR; import static org.junit.Assert.*; import static testutil.TestUtilities.*; import static testutil.TypeAssertions.*; import java.io.InputStream; import org.junit.Test; import error.LispException; import scanner.LispInputStream.UncheckedIOException; import scanner.LispScanner.UnterminatedStringException; import token.Eof.EofEncounteredException; import token.RightParenthesis.StartsWithRightParenthesisException; import token.TokenFactory.BadCharacterException; public class LispParserTester { private LispParser createLispParser(String input) { InputStream stringInputStream = createInputStreamFromString(input); return new LispParser(stringInputStream, "testFile"); } private LispParser createIOExceptionThrowingLispParser() { InputStream stringInputStream = createIOExceptionThrowingInputStream(); return new LispParser(stringInputStream, "testFile"); } @Test public void eofMethod_ReturnsTrueWithNoInput() { String input = ""; LispParser parser = createLispParser(input); assertTrue(parser.isEof()); } @Test public void eofMethod_ReturnsFalseWithSomeInput() { String input = "abc"; LispParser parser = createLispParser(input); assertFalse(parser.isEof()); } @Test public void eofMethod_ReturnsTrueAfterSomeInput() { String input = "(yyz 9 9 9)"; LispParser parser = createLispParser(input); parser.getNextSExpression(); assertTrue(parser.isEof()); } @Test public void eofMethod_ReturnsFalseAfterMultipleExpressions() { String input = "()()()"; LispParser parser = createLispParser(input); assertFalse(parser.isEof()); parser.getNextSExpression(); assertFalse(parser.isEof()); parser.getNextSExpression(); assertFalse(parser.isEof()); } @Test public void eofMethod_ReturnsTrueAfterMultipleExpressions() { String input = "()()()"; LispParser parser = createLispParser(input); assertFalse(parser.isEof()); parser.getNextSExpression(); assertFalse(parser.isEof()); parser.getNextSExpression(); assertFalse(parser.isEof()); parser.getNextSExpression(); assertTrue(parser.isEof()); } @Test public void givenNil_CreatesCorrectSExpression() { String input = "()"; LispParser parser = createLispParser(input); assertNil(parser.getNextSExpression()); } @Test public void givenNumber_CreatesCorrectSExpression() { String input = "12"; LispParser parser = createLispParser(input); assertNumber(parser.getNextSExpression()); } @Test public void givenIdentifier_CreatesCorrectSExpression() { String input = "identifier1"; LispParser parser = createLispParser(input); assertSymbol(parser.getNextSExpression()); } @Test public void givenString_CreatesCorrectSExpression() { String input = "\"string\""; LispParser parser = createLispParser(input); assertString(parser.getNextSExpression()); } @Test public void givenList_CreatesCorrectSExpression() { String input = "(1 2)"; LispParser parser = createLispParser(input); assertList(parser.getNextSExpression()); } @Test public void givenQuotedIdentifier_CreatesCorrectSExpression() { String input = "'quoted"; LispParser parser = createLispParser(input); assertList(parser.getNextSExpression()); assertTrue(parser.isEof()); } @Test public void givenComplexList_CreatesCorrectSExpression() { String input = "(defun f (x) \n (print \n (list \"x is \" x) \n ) \n )"; LispParser parser = createLispParser(input); assertList(parser.getNextSExpression()); assertTrue(parser.isEof()); } @Test public void givenMultipleComplexLists_CreatesCorrectSExpressions() { String input = "(defun f (x) \n (print \n (list \"x is \" x) \n ) \n )" + "(defun f (x) \n (print \n (list \"x is \" x) \n ) \n )"; LispParser parser = createLispParser(input); assertList(parser.getNextSExpression()); assertList(parser.getNextSExpression()); assertTrue(parser.isEof()); } @Test public void givenMultipleExpressions_CreatesCorrectSExpressions() { String input = "(setq x 2) x \"hi\" () 29"; LispParser parser = createLispParser(input); assertList(parser.getNextSExpression()); assertSymbol(parser.getNextSExpression()); assertString(parser.getNextSExpression()); assertNil(parser.getNextSExpression()); assertNumber(parser.getNextSExpression()); assertTrue(parser.isEof()); } @Test public void givenNil_CreatesCorrectSExpressionAfterEofCalls() { String input = "()"; LispParser parser = createLispParser(input); parser.isEof(); parser.isEof(); assertNil(parser.getNextSExpression()); assertTrue(parser.isEof()); } @Test(expected = BadCharacterException.class) public void givenBadToken_ThrowsException() { String input = "["; LispParser parser = createLispParser(input); parser.getNextSExpression(); } @Test public void givenBadToken_ExceptionHasCorrectAttributes() { String input = "["; LispParser parser = createLispParser(input); try { parser.getNextSExpression(); } catch (BadCharacterException e) { String message = e.getMessage(); assertEquals(ERROR, e.getSeverity()); assertNotNull(message); assertTrue(message.length() > 0); } } @Test(expected = UnterminatedStringException.class) public void givenUnterminatedString_ThrowsException() { String input = "\"string"; LispParser parser = createLispParser(input); parser.getNextSExpression(); } @Test(expected = EofEncounteredException.class) public void givenUnterminatedList_ThrowsException() { String input = "(bad list"; LispParser parser = createLispParser(input); parser.getNextSExpression(); } @Test public void givenUnterminatedList_ExceptionHasCorrectAttributes() { String input = "(bad list"; LispParser parser = createLispParser(input); try { parser.getNextSExpression(); } catch (EofEncounteredException e) { String message = e.getMessage(); assertEquals(ERROR, e.getSeverity()); assertNotNull(message); assertTrue(message.length() > 0); } } @Test(expected = StartsWithRightParenthesisException.class) public void givenUnmatchedRightParenthesis_ThrowsException() { String input = ")"; LispParser parser = createLispParser(input); parser.getNextSExpression(); } @Test public void givenUnmatchedRightParenthesis_ExceptionHasCorrectAttributes() { String input = ")"; LispParser parser = createLispParser(input); try { parser.getNextSExpression(); } catch (StartsWithRightParenthesisException e) { String message = e.getMessage(); assertEquals(ERROR, e.getSeverity()); assertNotNull(message); assertTrue(message.length() > 0); } } @Test(expected = BadCharacterException.class) public void givenBadCharacter_ThrowsExceptionAfterEofCalled() { String input = "["; LispParser parser = createLispParser(input); try { parser.isEof(); } catch (LispException e) { fail("Exception thrown too early"); } parser.getNextSExpression(); } @Test(expected = BadCharacterException.class) public void givenBadCharacterAfterValidToken_ThrowsExceptionAtTheCorrectTime() { String input = "id["; LispParser parser = createLispParser(input); try { parser.getNextSExpression(); parser.isEof(); } catch (LispException e) { fail("Exception thrown too early"); } parser.getNextSExpression(); } @Test public void afterException_ReturnsEofCorrectly() { String input = "id["; LispParser parser = createLispParser(input); parser.getNextSExpression(); parser.isEof(); try { parser.getNextSExpression(); fail("Expected LispException"); } catch (LispException e) {} assertTrue(parser.isEof()); } @Test(expected = UncheckedIOException.class) public void handlesIOExceptionCorrectly() { LispParser parser = createIOExceptionThrowingLispParser(); try { parser.isEof(); } catch (LispException e) { fail("Exception thrown too early"); } parser.getNextSExpression(); } @Test public void givenBackTickExpression_CreatesCorrectSExpression() { String input = "`(list ,a ,@b)"; LispParser parser = createLispParser(input); assertBackTickExpression(parser.getNextSExpression()); assertTrue(parser.isEof()); } @Test public void givenComma_CreatesCorrectSExpression() { String input = ",a"; LispParser parser = createLispParser(input); assertCommaExpression(parser.getNextSExpression()); assertTrue(parser.isEof()); } @Test public void givenAtSignExpression_CreatesCorrectSExpression() { String input = "@b"; LispParser parser = createLispParser(input); assertAtSignExpression(parser.getNextSExpression()); assertTrue(parser.isEof()); } @Test public void backTickIsNotPartOfIdentifier() { String input = "id`ab"; LispParser parser = createLispParser(input); assertSymbol(parser.getNextSExpression()); assertBackTickExpression(parser.getNextSExpression()); assertTrue(parser.isEof()); } @Test public void commaIsNotPartOfIdentifier() { String input = "id,ab"; LispParser parser = createLispParser(input); assertSymbol(parser.getNextSExpression()); assertCommaExpression(parser.getNextSExpression()); assertTrue(parser.isEof()); } @Test public void atSignIsNotPartOfIdentifier() { String input = "id@ab"; LispParser parser = createLispParser(input); assertSymbol(parser.getNextSExpression()); assertAtSignExpression(parser.getNextSExpression()); assertTrue(parser.isEof()); } }