package scanner; import static org.junit.Assert.*; import java.io.InputStream; import org.junit.Test; import error.ErrorManager; import scanner.LispScanner.UnterminatedStringException; import testutils.TestUtilities; import token.Token; import token.Token.Type; import token.TokenFactory; import token.TokenFactory.BadCharacterException; public class LispScannerTypeTester { @Test public void givenEmptyFile_ReturnsCorrectTypes() { String input = ""; Token.Type[] expectedTypes = {}; assertTokenTypesMatch(input, expectedTypes); } @Test(expected = BadCharacterException.class) public void givenBadCharacter_ThrowsException() { String input = "["; Token.Type[] expectedTypes = {}; assertTokenTypesMatch(input, expectedTypes); } @Test public void givenBadCharacter_ExceptionContainsCorrectSeverity() { String input = "abc\ndef["; Token.Type[] expectedTypes = { Type.IDENTIFIER, Type.IDENTIFIER }; try { assertTokenTypesMatch(input, expectedTypes); } catch (BadCharacterException e) { assertTrue(e.getSeverity() < ErrorManager.CRITICAL_LEVEL); } } @Test public void givenBadCharacter_ExceptionContainsMessage() { String input = "abc\ndef["; Token.Type[] expectedTypes = { Type.IDENTIFIER, Type.IDENTIFIER }; try { assertTokenTypesMatch(input, expectedTypes); } catch (BadCharacterException e) { String message = e.getMessage(); assertNotNull(message); assertTrue(message.length() > 0); } } @Test public void givenNil_ReturnsCorrectTypes() { String input = "()"; Token.Type[] expectedTypes = { Type.LEFT_PAREN, Type.RIGHT_PAREN }; assertTokenTypesMatch(input, expectedTypes); } @Test public void givenListOfNumbers_ReturnsCorrectTypes() { String input = "(1 2)"; Token.Type[] expectedTypes = { Type.LEFT_PAREN, Type.NUMBER, Type.NUMBER, Type.RIGHT_PAREN }; assertTokenTypesMatch(input, expectedTypes); } @Test public void givenString_ReturnsCorrectTypes() { String input = "\"string\""; Token.Type[] expectedTypes = { Type.STRING }; assertTokenTypesMatch(input, expectedTypes); } @Test public void givenStringWithEscapedDoubleQuote_ReturnsCorrectTypes() { String input = "\"string \n hi \\\" bye\""; Token.Type[] expectedTypes = { Type.STRING }; assertTokenTypesMatch(input, expectedTypes); } @Test public void givenStringWithEscapedDoubleQuoteAndComment_ReturnsCorrectTypes() { String input = "\"string \n hi \\\" ; bye\""; Token.Type[] expectedTypes = { Type.STRING }; assertTokenTypesMatch(input, expectedTypes); } @Test(expected = UnterminatedStringException.class) public void givenUnterminatedString_ThrowsException() { String input = "\"oh no!"; Token.Type[] expectedTypes = { Type.STRING }; assertTokenTypesMatch(input, expectedTypes); } @Test() public void givenUnterminatedString_ExceptionHasCorrectSeverity() { String input = "\"oh no!"; Token.Type[] expectedTypes = { Type.STRING }; try { assertTokenTypesMatch(input, expectedTypes); } catch (LispScanner.UnterminatedStringException e) { assertTrue(e.getSeverity() < ErrorManager.CRITICAL_LEVEL); } } @Test() public void givenUnterminatedString_ExceptionContainsMessage() { String input = "\"oh no!"; Token.Type[] expectedTypes = { Type.STRING }; try { assertTokenTypesMatch(input, expectedTypes); } catch (LispScanner.UnterminatedStringException e) { String message = e.getMessage(); assertNotNull(message); assertTrue(message.length() > 0); } } @Test public void givenIdentifier_ReturnsCorrectTypes() { String input = "abcdefgHIJKLMNOP1234"; Token.Type[] expectedTypes = { Type.IDENTIFIER }; assertTokenTypesMatch(input, expectedTypes); } @Test public void givenSingleDigitNumber_ReturnsCorrectTypes() { String input = "1"; Token.Type[] expectedTypes = { Type.NUMBER }; assertTokenTypesMatch(input, expectedTypes); } @Test public void givenMultipleDigitNumber_ReturnsCorrectTypes() { String input = "1234567890"; Token.Type[] expectedTypes = { Type.NUMBER }; assertTokenTypesMatch(input, expectedTypes); } @Test public void givenQuote_ReturnsCorrectTypes() { String input = "'"; Token.Type[] expectedTypes = { Type.QUOTE_MARK }; assertTokenTypesMatch(input, expectedTypes); } @Test public void givenManyTypesWithNoWhitespace_ReturnsCorrectTypes() { String input = "xxx\"hi\"999()'aaa"; Token.Type[] expectedTypes = { Type.IDENTIFIER, Type.STRING, Type.NUMBER, Type.LEFT_PAREN, Type.RIGHT_PAREN, Type.QUOTE_MARK, Type.IDENTIFIER }; assertTokenTypesMatch(input, expectedTypes); } @Test public void givenFunctionCall_ReturnsCorrectTypes() { String input = "(defun myFunction (x)\n (print x))"; Token.Type[] expectedTypes = { Type.LEFT_PAREN, Type.IDENTIFIER, Type.IDENTIFIER, Type.LEFT_PAREN, Type.IDENTIFIER, Type.RIGHT_PAREN, Type.LEFT_PAREN, Type.IDENTIFIER, Type.IDENTIFIER, Type.RIGHT_PAREN, Type.RIGHT_PAREN }; assertTokenTypesMatch(input, expectedTypes); } private void assertTokenTypesMatch(String input, Token.Type[] expectedTypeList) { InputStream stringInputStream = TestUtilities.createInputStreamFromString(input); LispScanner lispScanner = new LispScanner(stringInputStream, "stringInputStream"); for (Token.Type expectedType : expectedTypeList) assertEquals(expectedType, lispScanner.getNextToken().getType()); assertEquals(Token.Type.EOF, lispScanner.getNextToken().getType()); } }