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.Type; import token.TokenFactory.BadCharacterException; public class LispScannerTypeTester { private void assertTokenTypesMatch(String input, Type[] expectedTypeList) { InputStream stringInputStream = TestUtilities.createInputStreamFromString(input); LispScanner lispScanner = new LispScanner(stringInputStream, "testFile"); for (Type expectedType : expectedTypeList) assertEquals(expectedType, lispScanner.getNextToken().getType()); assertEquals(Type.EOF, lispScanner.getNextToken().getType()); } @Test public void givenEmptyFile_ReturnsCorrectTypes() { String input = ""; Type[] expectedTypes = {}; assertTokenTypesMatch(input, expectedTypes); } @Test(expected = BadCharacterException.class) public void givenBadCharacter_ThrowsException() { String input = "["; Type[] expectedTypes = {}; assertTokenTypesMatch(input, expectedTypes); } @Test public void givenBadCharacter_ExceptionContainsCorrectSeverity() { String input = "abc\ndef["; 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["; 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 = "()"; Type[] expectedTypes = { Type.LEFT_PAREN, Type.RIGHT_PAREN }; assertTokenTypesMatch(input, expectedTypes); } @Test public void givenListOfNumbers_ReturnsCorrectTypes() { String input = "(1 2)"; Type[] expectedTypes = { Type.LEFT_PAREN, Type.NUMBER, Type.NUMBER, Type.RIGHT_PAREN }; assertTokenTypesMatch(input, expectedTypes); } @Test public void givenString_ReturnsCorrectTypes() { String input = "\"string\""; Type[] expectedTypes = { Type.STRING }; assertTokenTypesMatch(input, expectedTypes); } @Test public void givenStringWithEscapedDoubleQuote_ReturnsCorrectTypes() { String input = "\"string \n hi \\\" bye\""; Type[] expectedTypes = { Type.STRING }; assertTokenTypesMatch(input, expectedTypes); } @Test public void givenStringWithEscapedDoubleQuoteAndComment_ReturnsCorrectTypes() { String input = "\"string \n hi \\\" ; bye\""; Type[] expectedTypes = { Type.STRING }; assertTokenTypesMatch(input, expectedTypes); } @Test(expected = UnterminatedStringException.class) public void givenUnterminatedString_ThrowsException() { String input = "\"oh no!"; Type[] expectedTypes = { Type.STRING }; assertTokenTypesMatch(input, expectedTypes); } @Test() public void givenUnterminatedString_ExceptionHasCorrectSeverity() { String input = "\"oh no!"; 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!"; 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"; Type[] expectedTypes = { Type.IDENTIFIER }; assertTokenTypesMatch(input, expectedTypes); } @Test public void givenSingleDigitNumber_ReturnsCorrectTypes() { String input = "1"; Type[] expectedTypes = { Type.NUMBER }; assertTokenTypesMatch(input, expectedTypes); } @Test public void givenMultipleDigitNumber_ReturnsCorrectTypes() { String input = "1234567890"; Type[] expectedTypes = { Type.NUMBER }; assertTokenTypesMatch(input, expectedTypes); } @Test public void givenQuote_ReturnsCorrectTypes() { String input = "'"; Type[] expectedTypes = { Type.QUOTE_MARK }; assertTokenTypesMatch(input, expectedTypes); } @Test public void givenManyTypesWithNoWhitespace_ReturnsCorrectTypes() { String input = "xxx\"hi\"999()'aaa"; 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))"; 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); } }