transcendental-lisp/test/parser/LispParserTest.java

383 lines
11 KiB
Java

package parser;
import static error.ErrorManager.Severity.ERROR;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static testutil.TestUtilities.createIOExceptionThrowingInputStream;
import static testutil.TestUtilities.createInputStreamFromString;
import static testutil.TypeAssertions.assertAtSignExpression;
import static testutil.TypeAssertions.assertBackTickExpression;
import static testutil.TypeAssertions.assertCommaExpression;
import static testutil.TypeAssertions.assertList;
import static testutil.TypeAssertions.assertNil;
import static testutil.TypeAssertions.assertNumber;
import static testutil.TypeAssertions.assertString;
import static testutil.TypeAssertions.assertSymbol;
import java.io.InputStream;
import org.junit.Test;
import error.LispException;
import scanner.LispScanner.UnterminatedStringException;
import stream.UncheckedIOException;
import token.Eof.EofEncounteredException;
import token.RightParenthesis.StartsWithRightParenthesisException;
import token.TokenFactory.BadCharacterException;
public class LispParserTest {
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());
}
}