Added unit tests, refactored some code, and removed IOException references

This commit is contained in:
Mike Cifelli 2016-12-11 15:09:48 -05:00
parent f50b07842c
commit c02ef37f64
8 changed files with 127 additions and 25 deletions

View File

@ -72,10 +72,6 @@ public class LOAD extends LispFunction {
} catch (RuntimeException e) {
System.out.println("LOAD: " + e.getMessage());
return Nil.getUniqueInstance();
} catch (IOException e) {
System.out.println("LOAD: " + e.getMessage());
return Nil.getUniqueInstance();
}
}

View File

@ -9,6 +9,8 @@ package main;
import parser.*;
import eval.*;
import error.ErrorManager;
import error.LispException;
import java.io.*;
import java.text.MessageFormat;
@ -67,11 +69,12 @@ public class LispInterpreter {
LispInterpreter.erasePrompt(interactive);
System.out.println(result);
} catch (LispException e) {
LispInterpreter.erasePrompt(interactive);
ErrorManager.generateError(e);
} catch (RuntimeException e) {
LispInterpreter.erasePrompt(interactive);
ErrorManager.generateError(e.getMessage(), 2);
} catch (IOException e) {
ErrorManager.generateError(e.getMessage(), ErrorManager.CRITICAL_LEVEL);
ErrorManager.generateError(e.getMessage(), 0);
}
if (interactive) {

View File

@ -6,10 +6,10 @@
package parser;
import scanner.*;
import java.io.*;
import java.io.InputStream;
import constructs.Token;
import scanner.LispScanner;
/**
* A <code>LispParser</code> converts a stream of bytes into internal
@ -91,19 +91,12 @@ public class LispParser {
* @throws IOException
* Indicates that an I/O error has occurred.
*/
public SExpression getSExpr() throws IOException {
public SExpression getSExpr() {
if (delayedException != null) {
// the 'eof' method has stored an exception for us to throw
// determine the type of the stored exception and throw it!
if (delayedException instanceof IOException) {
IOException e = (IOException) delayedException;
// remove the exception from 'delayedException'
delayedException = null;
throw e;
} else if (delayedException instanceof RuntimeException) {
if (delayedException instanceof RuntimeException) {
RuntimeException e = (RuntimeException) delayedException;
// remove the exception from 'delayedException'
@ -136,7 +129,7 @@ public class LispParser {
// encountered in the underlying input stream.
// Throws: IOException - Indicates that an I/O error has occurred.
// Precondition: 'nextToken' is not null.
private SExpression sExpr() throws IOException {
private SExpression sExpr() {
// determine the type of 'nextToken' and create the appropriate
// S-expression
switch (nextToken.getType()) {
@ -174,7 +167,7 @@ public class LispParser {
// Returns: an S-expression that matches the rules given above
// Throws: IOException - Indicates that an I/O error has occurred.
// Precondition: 'scanner' is not null.
private SExpression sExprTail() throws IOException {
private SExpression sExprTail() {
nextToken = scanner.getNextToken();
// determine the type of 'nextToken' and create the appropriate

View File

@ -83,7 +83,7 @@ public class LispScanner {
return retriever.retrieveToken();
}
public class ComplexTokenTextRetriever {
private class ComplexTokenTextRetriever {
Function<Character, Boolean> isPartOfToken;
StringBuilder text;
@ -115,7 +115,7 @@ public class LispScanner {
addCharacterToToken();
if (isStringToken() && isTerminatingDoubleQuote())
if (isTerminatingCharacter())
return text.toString();
previousCharacter = currentCharacter;
@ -132,6 +132,10 @@ public class LispScanner {
positionTracker.incrementLine();
}
private boolean isTerminatingCharacter() {
return isStringToken() && isTerminatingDoubleQuote();
}
private boolean isStringToken() {
return firstCharacter == DOUBLE_QUOTE;
}

View File

@ -0,0 +1,70 @@
package constructs;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import file.FilePosition;
public class TokenFactoryTester {
private TokenFactory tokenFactory;
private FilePosition testPosition;
@Before
public void setUp() throws Exception {
tokenFactory = new TokenFactoryImpl();
testPosition = new FilePosition("testFile");
testPosition.setLineNumber(0);
testPosition.setColumnNumber(0);
}
@Test
public void testEOFTokenCreation() {
assertEquals(Token.Type.EOF, tokenFactory.createEOFToken(testPosition).getType());
}
@Test
public void testLeftParenthesisCreation() {
String text = "(";
assertEquals(Token.Type.LEFT_PAREN, tokenFactory.createToken(text, testPosition).getType());
}
@Test
public void testRightParenthesisCreation() {
String text = ")";
assertEquals(Token.Type.RIGHT_PAREN, tokenFactory.createToken(text, testPosition).getType());
}
@Test
public void testQuoteMarkCreation() {
String text = "'";
assertEquals(Token.Type.QUOTE_MARK, tokenFactory.createToken(text, testPosition).getType());
}
@Test
public void testNumberCreation() {
String text = "987";
assertEquals(Token.Type.NUMBER, tokenFactory.createToken(text, testPosition).getType());
}
@Test
public void testIdentifierCreation() {
String text = "identifier";
assertEquals(Token.Type.IDENTIFIER, tokenFactory.createToken(text, testPosition).getType());
}
@Test
public void testStringCreation() {
String text = "\"string\"";
assertEquals(Token.Type.STRING, tokenFactory.createToken(text, testPosition).getType());
}
@Test(expected = TokenFactory.BadCharacterException.class)
public void testBadCharacter() {
String text = "[abc]";
tokenFactory.createToken(text, testPosition);
}
}

View File

@ -103,6 +103,14 @@ public class LispScannerLineColumnTester {
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);
}
private void assertTokenLineAndColumnsMatch(String input, LineColumn[] expectedLineColumnList) {
InputStream stringInputStream = TestUtilities.createInputStreamFromString(input);
LispScanner lispScanner = new LispScanner(stringInputStream, "stringInputStream");

View File

@ -32,11 +32,27 @@ public class LispScannerTextTester {
}
@Test
public void givenEmptyStream_RecordsCorrectInputStreamName() {
public void givenEmptyStream_RecordsCorrectFileName() {
String input = "";
String expectedInputStreamName = "testInputStream";
String expectedFileName = "testFileName";
assertInputFileNameMatches(input, expectedInputStreamName);
assertInputFileNameMatches(input, expectedFileName);
}
@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";
assertTokenTextMatches(input, expected);
}
private void assertTokenTextMatches(String input, String expectedText) {

View File

@ -30,6 +30,18 @@ public class LispScannerTypeTester {
assertTokenTypesMatch(input, expectedTypes);
}
@Test
public void givenBadCharacter_ExceptionContainsCorrectSeverity() {
String input = "abc\ndef[";
Token.Type[] expectedTypes = { Type.IDENTIFIER, Type.IDENTIFIER };
try {
assertTokenTypesMatch(input, expectedTypes);
} catch (TokenFactory.BadCharacterException e) {
assertTrue(e.getSeverity() < ErrorManager.CRITICAL_LEVEL);
}
}
@Test
public void givenNil_ReturnsCorrectTypes() {
String input = "()";