transcendental-lisp/test/function/builtin/special/DEFINE_MACROTester.java

134 lines
3.8 KiB
Java
Raw Normal View History

package function.builtin.special;
import static org.junit.Assert.assertTrue;
import static testutil.TestUtilities.*;
import java.io.*;
import org.junit.*;
import environment.RuntimeEnvironment;
import error.ErrorManager;
import function.ArgumentValidator.*;
import table.FunctionTable;
public class DEFINE_MACROTester {
private ByteArrayOutputStream outputStream;
private RuntimeEnvironment environment;
public DEFINE_MACROTester() {
this.environment = RuntimeEnvironment.getInstance();
}
private void assertSomethingPrinted() {
assertTrue(outputStream.toByteArray().length > 0);
}
@Before
public void setUp() {
outputStream = new ByteArrayOutputStream();
environment.setOutput(new PrintStream(outputStream));
environment.setErrorManager(new ErrorManager());
environment.setWarningOutputDecorator(s -> s);
FunctionTable.reset();
}
@After
public void tearDown() {
FunctionTable.reset();
}
@Test
public void defineMacro() {
String input = "(define-macro f () t)";
assertSExpressionsMatch(parseString("f"), evaluateString(input));
assertSExpressionsMatch(parseString("t"), evaluateString("(f)"));
}
@Test
public void defineMacroWithEmptyBody() {
String input = "(define-macro f ())";
assertSExpressionsMatch(parseString("f"), evaluateString(input));
assertSExpressionsMatch(parseString("()"), evaluateString("(f)"));
}
@Test
public void defineMacroDoesNotEvaluatesArguments() {
evaluateString("(define-macro f (x) (car x))");
assertSExpressionsMatch(parseString("quote"), evaluateString("(f '(1 2 3))"));
}
2017-02-25 19:12:34 -05:00
@Test
public void defineMacroAdd() {
evaluateString("(define-macro f (x) (+ (eval x) 23))");
assertSExpressionsMatch(parseString("27"), evaluateString("(f (+ 2 2))"));
}
@Test
public void defineMacroSetVariable() {
evaluateString("(define-macro f (x) (set x 23))");
evaluateString("(f y)");
assertSExpressionsMatch(parseString("23"), evaluateString("y"));
}
@Test
public void defineMacroVariableCapture() {
evaluateString("(setf x 0)");
evaluateString("(define-macro f (x) (set x 23))");
evaluateString("(f x)");
assertSExpressionsMatch(parseString("0"), evaluateString("x"));
}
2017-02-25 19:12:34 -05:00
@Test
public void defineMacroAvoidVariableCaptureConvention() {
evaluateString("(setf x 0)");
evaluateString("(define-macro f (-x-) (set -x- 23))");
evaluateString("(f x)");
assertSExpressionsMatch(parseString("23"), evaluateString("x"));
}
2017-02-25 19:12:34 -05:00
@Test
public void redefineMacro_DisplaysWarning() {
String input = "(define-macro myFunction () nil)";
evaluateString(input);
evaluateString(input);
assertSomethingPrinted();
}
@Test
public void redefineMacro_ActuallyRedefinesMacro() {
evaluateString("(define-macro myMacro () nil)");
evaluateString("(define-macro myMacro () T)");
assertSomethingPrinted();
assertSExpressionsMatch(parseString("t"), evaluateString("(myMacro)"));
}
@Test(expected = DottedArgumentListException.class)
public void defineMacroWithDottedLambdaList() {
evaluateString("(funcall 'define-macro 'x (cons 'a 'b) ())");
}
@Test(expected = BadArgumentTypeException.class)
public void defineMacroWithNonSymbolName() {
evaluateString("(define-macro 1 () ())");
}
@Test(expected = BadArgumentTypeException.class)
public void defineMacroWithBadLambdaList() {
evaluateString("(define-macro x a ())");
}
@Test(expected = TooFewArgumentsException.class)
public void defineMacroWithTooFewArguments() {
evaluateString("(define-macro x)");
}
}