Add ability to run acceptance tests on files
This commit is contained in:
parent
e1c544f0ea
commit
aa13394548
|
@ -3,6 +3,5 @@ Test
|
|||
---
|
||||
Unit tests for the dlambda special function.
|
||||
|
||||
| script | lisp interpreter fixture |
|
||||
| check | evaluate | (load "lisp/lang/dlambda-test.lisp") | T |
|
||||
| check | evaluate | (test-dlambda) | =~/T$/ |
|
||||
| script | lisp interpreter fixture |
|
||||
| check | evaluate file | lisp/lang/dlambda-test.lisp | =~/T$/ |
|
||||
|
|
|
@ -3,7 +3,7 @@ Test
|
|||
---
|
||||
A simple lexical closure.
|
||||
|
||||
| script | lisp interpreter fixture |
|
||||
| show | evaluate | (defun adder-x (x) (lambda (y) (+ x y))) |
|
||||
| show | evaluate | (setf adder-20 (adder-x 20)) |
|
||||
| check | evaluate | (funcall adder-20 2) | 22 |
|
||||
| script | lisp interpreter fixture |
|
||||
| show | evaluate text | (defun adder-x (x) (lambda (y) (+ x y))) |
|
||||
| show | evaluate text | (setf adder-20 (adder-x 20)) |
|
||||
| check | evaluate text | (funcall adder-20 2) | 22 |
|
||||
|
|
|
@ -3,8 +3,8 @@ Test
|
|||
---
|
||||
An object with multiple methods.
|
||||
|
||||
| script | lisp interpreter fixture |
|
||||
| show | evaluate |!-
|
||||
| script | lisp interpreter fixture |
|
||||
| show | evaluate text |!-
|
||||
|
||||
(defun counter-class ()
|
||||
(let ((counter 0))
|
||||
|
@ -16,10 +16,10 @@ An object with multiple methods.
|
|||
(setq counter (- counter 1)))))))
|
||||
|
||||
-!|
|
||||
| show | evaluate | (setq my-counter (counter-class)) |
|
||||
| check | evaluate | (funcall my-counter :inc) | 1 |
|
||||
| check | evaluate | (funcall my-counter :inc) | 2 |
|
||||
| check | evaluate | (funcall my-counter :inc) | 3 |
|
||||
| check | evaluate | (funcall my-counter :dec) | 2 |
|
||||
| check | evaluate | (funcall my-counter :dec) | 1 |
|
||||
| check | evaluate | (funcall my-counter :dec) | 0 |
|
||||
| show | evaluate text | (setq my-counter (counter-class)) |
|
||||
| check | evaluate text | (funcall my-counter :inc) | 1 |
|
||||
| check | evaluate text | (funcall my-counter :inc) | 2 |
|
||||
| check | evaluate text | (funcall my-counter :inc) | 3 |
|
||||
| check | evaluate text | (funcall my-counter :dec) | 2 |
|
||||
| check | evaluate text | (funcall my-counter :dec) | 1 |
|
||||
| check | evaluate text | (funcall my-counter :dec) | 0 |
|
||||
|
|
|
@ -3,11 +3,11 @@ Test
|
|||
---
|
||||
Shows object composition, a default method, and two different ways of referencing objects.
|
||||
|
||||
| script | lisp interpreter fixture |
|
||||
| check | evaluate | (load "lisp/object/fruit-counter.lisp") | T |
|
||||
| check | evaluate | (my-fruits :inc-apples) | 1 |
|
||||
| check | evaluate | (my-fruits :inc-apples) | 2 |
|
||||
| check | evaluate | (funcall my-fruits2 :dec-bananas) | 9999 |
|
||||
| check | evaluate | (my-fruits :set-coconuts 12) | 12 |
|
||||
| check | evaluate | (my-fruits) | ((APPLES 2) (BANANAS 0) (COCONUTS 12)) |
|
||||
| check | evaluate | (funcall my-fruits2) | ((APPLES 10000) (BANANAS 9999) (COCONUTS 10000)) |
|
||||
| script | lisp interpreter fixture |
|
||||
| check | evaluate text | (load "lisp/object/fruit-counter.lisp") | T |
|
||||
| check | evaluate text | (my-fruits :inc-apples) | 1 |
|
||||
| check | evaluate text | (my-fruits :inc-apples) | 2 |
|
||||
| check | evaluate text | (funcall my-fruits2 :dec-bananas) | 9999 |
|
||||
| check | evaluate text | (my-fruits :set-coconuts 12) | 12 |
|
||||
| check | evaluate text | (my-fruits) | ((APPLES 2) (BANANAS 0) (COCONUTS 12)) |
|
||||
| check | evaluate text | (funcall my-fruits2) | ((APPLES 10000) (BANANAS 9999) (COCONUTS 10000)) |
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
---
|
||||
Test
|
||||
---
|
||||
| import |
|
||||
| acceptance.fixture |
|
||||
|
||||
| script | lisp interpreter fixture |
|
||||
| reset |
|
||||
| clear functions and symbols |
|
||||
|
|
|
@ -5,7 +5,7 @@ Shows the usage of a static variable.
|
|||
''"Let Over Lambda Over Let Over Lambda"''
|
||||
|
||||
| script | lisp interpreter fixture |
|
||||
| show | evaluate | !-
|
||||
| show | evaluate text | !-
|
||||
|
||||
(let ((direction 'up))
|
||||
(defun toggle-counter-direction ()
|
||||
|
@ -20,16 +20,16 @@ Shows the usage of a static variable.
|
|||
(if (eq direction 'up)
|
||||
(setq counter (+ counter 1))
|
||||
(setq counter (- counter 1)))))))
|
||||
-!|
|
||||
| show | evaluate | (setq my-counter (counter-class)) |
|
||||
| check | evaluate | (funcall my-counter) | 1 |
|
||||
| check | evaluate | (funcall my-counter) | 2 |
|
||||
| check | evaluate | (funcall my-counter) | 3 |
|
||||
| show | evaluate | (toggle-counter-direction) |
|
||||
| check | evaluate | (funcall my-counter) | 2 |
|
||||
| check | evaluate | (funcall my-counter) | 1 |
|
||||
| check | evaluate | (funcall my-counter) | 0 |
|
||||
| show | evaluate | (toggle-counter-direction) |
|
||||
| check | evaluate | (funcall my-counter) | 1 |
|
||||
| check | evaluate | (funcall my-counter) | 2 |
|
||||
| check | evaluate | (funcall my-counter) | 3 |
|
||||
-!|
|
||||
| show | evaluate text | (setq my-counter (counter-class)) |
|
||||
| check | evaluate text | (funcall my-counter) | 1 |
|
||||
| check | evaluate text | (funcall my-counter) | 2 |
|
||||
| check | evaluate text | (funcall my-counter) | 3 |
|
||||
| show | evaluate text | (toggle-counter-direction) |
|
||||
| check | evaluate text | (funcall my-counter) | 2 |
|
||||
| check | evaluate text | (funcall my-counter) | 1 |
|
||||
| check | evaluate text | (funcall my-counter) | 0 |
|
||||
| show | evaluate text | (toggle-counter-direction) |
|
||||
| check | evaluate text | (funcall my-counter) | 1 |
|
||||
| check | evaluate text | (funcall my-counter) | 2 |
|
||||
| check | evaluate text | (funcall my-counter) | 3 |
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
Test
|
||||
---
|
||||
| import |
|
||||
| acceptance.fixture |
|
||||
|
||||
| script | lisp interpreter fixture |
|
||||
| build interpreter |
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
Test
|
||||
---
|
||||
| script | lisp interpreter fixture |
|
||||
| clean up |
|
|
@ -1,7 +1,11 @@
|
|||
|LispInterpreter.ObjectComposition||10:34:19 Mon, Mar 06, 2017|
|
||||
|LispInterpreter.ExternalFunctionUnitTests||10:30:46 Mon, Mar 06, 2017|
|
||||
|LispInterpreter.MultipleMethodObject||14:19:50 Fri, Mar 03, 2017|
|
||||
|LispInterpreter.LexicalClosures||14:18:39 Fri, Mar 03, 2017|
|
||||
|LispInterpreter.LexicalClosures||12:38:02 Mon, Mar 06, 2017|
|
||||
|LispInterpreter.ObjectComposition||12:30:58 Mon, Mar 06, 2017|
|
||||
|LispInterpreter.StaticVariable||12:30:28 Mon, Mar 06, 2017|
|
||||
|LispInterpreter.MultipleMethodObject||12:28:58 Mon, Mar 06, 2017|
|
||||
|LispInterpreter.SuiteSetUp||12:20:29 Mon, Mar 06, 2017|
|
||||
|LispInterpreter.SuiteTearDown||12:17:37 Mon, Mar 06, 2017|
|
||||
|LispInterpreter.SetUp||12:17:15 Mon, Mar 06, 2017|
|
||||
|LispInterpreter.ExternalFunctionUnitTests||12:10:52 Mon, Mar 06, 2017|
|
||||
|LispInterpreter.DlambdaUnitTests||10:16:42 Fri, Mar 03, 2017|
|
||||
|LispInterpreter.dlambda||10:12:59 Fri, Mar 03, 2017|
|
||||
|LispInterpreter||09:04:51 Fri, Mar 03, 2017|
|
||||
|
@ -9,8 +13,6 @@
|
|||
|LispInterpreter.FruitCounter||16:13:51 Thu, Mar 02, 2017|
|
||||
|LispInterpreter.SimpleClosure||16:12:31 Thu, Mar 02, 2017|
|
||||
|LispInterpreter.MultipleMethodClosure||16:11:28 Thu, Mar 02, 2017|
|
||||
|LispInterpreter.SetUp||15:09:12 Thu, Mar 02, 2017|
|
||||
|LispInterpreter.TestClosure||11:24:27 Mon, Feb 27, 2017|
|
||||
|LispInterpreter.TestOne||09:26:08 Fri, Feb 24, 2017|
|
||||
|LispInterpreter.SuiteSetUp||14:27:52 Wed, Feb 22, 2017|
|
||||
|FrontPage||14:15:03 Wed, Feb 22, 2017|
|
||||
|
|
|
@ -1,80 +1,78 @@
|
|||
(load "../unit/unit-test.lisp")
|
||||
(load "dlambda.lisp")
|
||||
|
||||
(defun test-dlambda ()
|
||||
(unit
|
||||
(list
|
||||
|
||||
(unit
|
||||
(list
|
||||
(defun empty-dlambda ()
|
||||
(assert-equal
|
||||
'(lambda (&rest arguments) (case (first arguments)))
|
||||
|
||||
(defun empty-dlambda ()
|
||||
(assert-equal
|
||||
'(lambda (&rest arguments) (case (first arguments)))
|
||||
(dlambda)))
|
||||
|
||||
(dlambda)))
|
||||
(defun dlambda-default-method-only ()
|
||||
(assert-equal
|
||||
'(lambda (&rest arguments)
|
||||
(case (first arguments)
|
||||
(t (apply (lambda () (print "nothing")) arguments))))
|
||||
|
||||
(defun dlambda-default-method-only ()
|
||||
(assert-equal
|
||||
'(lambda (&rest arguments)
|
||||
(case (first arguments)
|
||||
(t (apply (lambda () (print "nothing")) arguments))))
|
||||
(dlambda
|
||||
(t () (print "nothing")))))
|
||||
|
||||
(dlambda
|
||||
(t () (print "nothing")))))
|
||||
(defun dlambda-named-method-only ()
|
||||
(assert-equal
|
||||
'(lambda (&rest arguments)
|
||||
(case (first arguments)
|
||||
(:write (apply (lambda () (print "something")) (rest arguments)))))
|
||||
|
||||
(defun dlambda-named-method-only ()
|
||||
(assert-equal
|
||||
'(lambda (&rest arguments)
|
||||
(case (first arguments)
|
||||
(:write (apply (lambda () (print "something")) (rest arguments)))))
|
||||
(dlambda
|
||||
(:write () (print "something")))))
|
||||
|
||||
(dlambda
|
||||
(:write () (print "something")))))
|
||||
(defun dlambda-named-and-default-method ()
|
||||
(assert-equal
|
||||
'(lambda (&rest arguments)
|
||||
(case (first arguments)
|
||||
(:write (apply (lambda () (print "something")) (rest arguments)))
|
||||
(t (apply (lambda () (print "nothing")) arguments))))
|
||||
|
||||
(defun dlambda-named-and-default-method ()
|
||||
(assert-equal
|
||||
'(lambda (&rest arguments)
|
||||
(case (first arguments)
|
||||
(:write (apply (lambda () (print "something")) (rest arguments)))
|
||||
(t (apply (lambda () (print "nothing")) arguments))))
|
||||
(dlambda
|
||||
(:write () (print "something"))
|
||||
(t () (print "nothing")))))
|
||||
|
||||
(dlambda
|
||||
(:write () (print "something"))
|
||||
(t () (print "nothing")))))
|
||||
(defun dlambda-methods-with-arguments ()
|
||||
(assert-equal
|
||||
'(lambda (&rest arguments)
|
||||
(case (first arguments)
|
||||
(:write (apply (lambda (message) (print message)) (rest arguments)))
|
||||
(t (apply (lambda (&rest messages) (print messages)) arguments))))
|
||||
|
||||
(defun dlambda-methods-with-arguments ()
|
||||
(assert-equal
|
||||
'(lambda (&rest arguments)
|
||||
(case (first arguments)
|
||||
(:write (apply (lambda (message) (print message)) (rest arguments)))
|
||||
(t (apply (lambda (&rest messages) (print messages)) arguments))))
|
||||
(dlambda
|
||||
(:write (message) (print message))
|
||||
(t (&rest messages) (print messages)))))
|
||||
|
||||
(dlambda
|
||||
(:write (message) (print message))
|
||||
(t (&rest messages) (print messages)))))
|
||||
(defun dlambda-methods-with-multiple-arguments ()
|
||||
(assert-equal
|
||||
'(lambda (&rest arguments)
|
||||
(case (first arguments)
|
||||
(:write
|
||||
(apply
|
||||
(lambda (message &rest other-stuff)
|
||||
(print message)
|
||||
(print other-stuff))
|
||||
(rest arguments)))
|
||||
(t
|
||||
(apply
|
||||
(lambda (message1 message2 &rest other-stuff)
|
||||
(print message1)
|
||||
(print message2)
|
||||
(print other-stuff))
|
||||
arguments))))
|
||||
|
||||
(defun dlambda-methods-with-multiple-arguments ()
|
||||
(assert-equal
|
||||
'(lambda (&rest arguments)
|
||||
(case (first arguments)
|
||||
(:write
|
||||
(apply
|
||||
(lambda (message &rest other-stuff)
|
||||
(print message)
|
||||
(print other-stuff))
|
||||
(rest arguments)))
|
||||
(t
|
||||
(apply
|
||||
(lambda (message1 message2 &rest other-stuff)
|
||||
(print message1)
|
||||
(print message2)
|
||||
(print other-stuff))
|
||||
arguments))))
|
||||
|
||||
(dlambda
|
||||
(:write (message &rest other-stuff)
|
||||
(print message)
|
||||
(print other-stuff))
|
||||
(t (message1 message2 &rest other-stuff)
|
||||
(print message1)
|
||||
(print message2)
|
||||
(print other-stuff))))))))
|
||||
(dlambda
|
||||
(:write (message &rest other-stuff)
|
||||
(print message)
|
||||
(print other-stuff))
|
||||
(t (message1 message2 &rest other-stuff)
|
||||
(print message1)
|
||||
(print message2)
|
||||
(print other-stuff)))))))
|
||||
|
|
|
@ -3,6 +3,7 @@ package function.builtin;
|
|||
import static function.builtin.EVAL.eval;
|
||||
import static sexpression.Nil.NIL;
|
||||
import static sexpression.Symbol.T;
|
||||
import static util.Path.getPathPrefix;
|
||||
|
||||
import java.io.*;
|
||||
import java.text.MessageFormat;
|
||||
|
@ -80,10 +81,6 @@ public class LOAD extends LispFunction {
|
|||
return isSuccessful;
|
||||
}
|
||||
|
||||
private String getPathPrefix(String fileName) {
|
||||
return fileName.substring(0, fileName.lastIndexOf(File.separator) + 1);
|
||||
}
|
||||
|
||||
private boolean isSuccessfulEvaluation(LispParser parser) {
|
||||
while (!parser.isEof()) {
|
||||
try {
|
||||
|
|
|
@ -2,8 +2,6 @@ package interpreter;
|
|||
|
||||
import static function.builtin.EVAL.eval;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import environment.RuntimeEnvironment;
|
||||
import error.LispException;
|
||||
import parser.LispParser;
|
||||
|
@ -18,11 +16,6 @@ public class LispInterpreter {
|
|||
this.environment = RuntimeEnvironment.getInstance();
|
||||
}
|
||||
|
||||
public void setInput(InputStream input, String inputName) {
|
||||
environment.setInput(input);
|
||||
environment.setInputName(inputName);
|
||||
}
|
||||
|
||||
public void interpret() {
|
||||
createParser();
|
||||
printGreeting();
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package interpreter;
|
||||
|
||||
import static util.Path.getPathPrefix;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
|
@ -149,10 +151,6 @@ public class LispInterpreterBuilderImpl implements LispInterpreterBuilder {
|
|||
environment.setPath("");
|
||||
}
|
||||
|
||||
private String getPathPrefix(String fileName) {
|
||||
return fileName.substring(0, fileName.lastIndexOf(File.separator) + 1);
|
||||
}
|
||||
|
||||
private void configureInput(ErrorManager errorManager) {
|
||||
environment.setInputName(inputName);
|
||||
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package util;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public final class Path {
|
||||
|
||||
private Path() {}
|
||||
|
||||
public static String getPathPrefix(String fileName) {
|
||||
return fileName.substring(0, fileName.lastIndexOf(File.separator) + 1);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,35 +1,65 @@
|
|||
package acceptance.fixture;
|
||||
|
||||
import static table.FunctionTable.resetFunctionTable;
|
||||
import static util.Path.getPathPrefix;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
import environment.RuntimeEnvironment;
|
||||
import interpreter.*;
|
||||
import table.ExecutionContext;
|
||||
|
||||
public class LispInterpreterFixture {
|
||||
|
||||
private static ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
private static ExecutionContext executionContext = ExecutionContext.getInstance();
|
||||
private static RuntimeEnvironment environment = RuntimeEnvironment.getInstance();
|
||||
private static LispInterpreter interpreter = null;
|
||||
|
||||
static {
|
||||
public static void buildInterpreter() {
|
||||
LispInterpreterBuilder builder = LispInterpreterBuilderImpl.getInstance();
|
||||
builder.setOutput(new PrintStream(outputStream));
|
||||
builder.setErrorOutput(new PrintStream(outputStream));
|
||||
builder.setNotInteractive();
|
||||
builder.setTerminationFunction(() -> {});
|
||||
builder.setErrorTerminationFunction(() -> {});
|
||||
builder.setTerminationFunction(LispInterpreterFixture::terminate);
|
||||
builder.setErrorTerminationFunction(LispInterpreterFixture::terminateFromError);
|
||||
|
||||
interpreter = builder.build();
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
resetFunctionTable();
|
||||
ExecutionContext.getInstance().clearContext();
|
||||
public static void terminate() {}
|
||||
|
||||
public static void terminateFromError() {
|
||||
throw new RuntimeException("Error Termination");
|
||||
}
|
||||
|
||||
public String evaluate(String input) throws IOException {
|
||||
interpreter.setInput(new ByteArrayInputStream(input.getBytes()), "fitnesse");
|
||||
public static void cleanUp() {
|
||||
clearFunctionsAndSymbols();
|
||||
environment.reset();
|
||||
}
|
||||
|
||||
public static void clearFunctionsAndSymbols() {
|
||||
resetFunctionTable();
|
||||
executionContext.clearContext();
|
||||
}
|
||||
|
||||
public String evaluateText(String input) {
|
||||
environment.setInputName("fitnesse");
|
||||
environment.setInput(new ByteArrayInputStream(input.getBytes()));
|
||||
environment.setPath("");
|
||||
|
||||
return evaluate();
|
||||
}
|
||||
|
||||
public String evaluateFile(String inputFile) throws FileNotFoundException {
|
||||
environment.setInputName(inputFile);
|
||||
environment.setInput(new FileInputStream(inputFile));
|
||||
environment.setPath(getPathPrefix(inputFile));
|
||||
|
||||
return evaluate();
|
||||
}
|
||||
|
||||
private String evaluate() {
|
||||
interpreter.interpret();
|
||||
String output = outputStream.toString();
|
||||
outputStream.reset();
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package util;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class PathTester {
|
||||
|
||||
@Test
|
||||
public void constructorIsPrivate() throws Exception {
|
||||
Constructor<Path> constructor = Path.class.getDeclaredConstructor();
|
||||
|
||||
assertTrue(Modifier.isPrivate(constructor.getModifiers()));
|
||||
constructor.setAccessible(true);
|
||||
constructor.newInstance();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue