From aa133945481eb0dcc601fc54ba765352450683c9 Mon Sep 17 00:00:00 2001 From: Mike Cifelli Date: Mon, 6 Mar 2017 12:44:06 -0500 Subject: [PATCH] Add ability to run acceptance tests on files --- .../ExternalFunctionUnitTests.wiki | 5 +- .../LispInterpreter/LexicalClosures.wiki | 8 +- .../LispInterpreter/MultipleMethodObject.wiki | 18 +-- .../LispInterpreter/ObjectComposition.wiki | 16 +-- .../FitNesseRoot/LispInterpreter/SetUp.wiki | 5 +- .../LispInterpreter/StaticVariable.wiki | 28 ++-- .../LispInterpreter/SuiteSetUp.wiki | 8 ++ .../LispInterpreter/SuiteTearDown.wiki | 5 + fitnesse/FitNesseRoot/RecentChanges.wiki | 14 +- lisp/lang/dlambda-test.lisp | 128 +++++++++--------- src/function/builtin/LOAD.java | 5 +- src/interpreter/LispInterpreter.java | 7 - .../LispInterpreterBuilderImpl.java | 6 +- src/util/Path.java | 13 ++ .../fixture/LispInterpreterFixture.java | 46 +++++-- test/util/PathTester.java | 20 +++ 16 files changed, 196 insertions(+), 136 deletions(-) create mode 100644 fitnesse/FitNesseRoot/LispInterpreter/SuiteSetUp.wiki create mode 100644 fitnesse/FitNesseRoot/LispInterpreter/SuiteTearDown.wiki create mode 100644 src/util/Path.java create mode 100644 test/util/PathTester.java diff --git a/fitnesse/FitNesseRoot/LispInterpreter/ExternalFunctionUnitTests.wiki b/fitnesse/FitNesseRoot/LispInterpreter/ExternalFunctionUnitTests.wiki index c341ee9..2e0df2b 100644 --- a/fitnesse/FitNesseRoot/LispInterpreter/ExternalFunctionUnitTests.wiki +++ b/fitnesse/FitNesseRoot/LispInterpreter/ExternalFunctionUnitTests.wiki @@ -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$/ | diff --git a/fitnesse/FitNesseRoot/LispInterpreter/LexicalClosures.wiki b/fitnesse/FitNesseRoot/LispInterpreter/LexicalClosures.wiki index fab5e23..0dda92f 100644 --- a/fitnesse/FitNesseRoot/LispInterpreter/LexicalClosures.wiki +++ b/fitnesse/FitNesseRoot/LispInterpreter/LexicalClosures.wiki @@ -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 | diff --git a/fitnesse/FitNesseRoot/LispInterpreter/MultipleMethodObject.wiki b/fitnesse/FitNesseRoot/LispInterpreter/MultipleMethodObject.wiki index e212df9..7354ef0 100644 --- a/fitnesse/FitNesseRoot/LispInterpreter/MultipleMethodObject.wiki +++ b/fitnesse/FitNesseRoot/LispInterpreter/MultipleMethodObject.wiki @@ -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 | diff --git a/fitnesse/FitNesseRoot/LispInterpreter/ObjectComposition.wiki b/fitnesse/FitNesseRoot/LispInterpreter/ObjectComposition.wiki index 820d88e..790fc3c 100644 --- a/fitnesse/FitNesseRoot/LispInterpreter/ObjectComposition.wiki +++ b/fitnesse/FitNesseRoot/LispInterpreter/ObjectComposition.wiki @@ -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)) | diff --git a/fitnesse/FitNesseRoot/LispInterpreter/SetUp.wiki b/fitnesse/FitNesseRoot/LispInterpreter/SetUp.wiki index efb4cee..1375dec 100644 --- a/fitnesse/FitNesseRoot/LispInterpreter/SetUp.wiki +++ b/fitnesse/FitNesseRoot/LispInterpreter/SetUp.wiki @@ -1,8 +1,5 @@ --- Test --- -| import | -| acceptance.fixture | - | script | lisp interpreter fixture | -| reset | +| clear functions and symbols | diff --git a/fitnesse/FitNesseRoot/LispInterpreter/StaticVariable.wiki b/fitnesse/FitNesseRoot/LispInterpreter/StaticVariable.wiki index 84c4804..c1efdf2 100644 --- a/fitnesse/FitNesseRoot/LispInterpreter/StaticVariable.wiki +++ b/fitnesse/FitNesseRoot/LispInterpreter/StaticVariable.wiki @@ -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 | diff --git a/fitnesse/FitNesseRoot/LispInterpreter/SuiteSetUp.wiki b/fitnesse/FitNesseRoot/LispInterpreter/SuiteSetUp.wiki new file mode 100644 index 0000000..099b392 --- /dev/null +++ b/fitnesse/FitNesseRoot/LispInterpreter/SuiteSetUp.wiki @@ -0,0 +1,8 @@ +--- +Test +--- +| import | +| acceptance.fixture | + +| script | lisp interpreter fixture | +| build interpreter | diff --git a/fitnesse/FitNesseRoot/LispInterpreter/SuiteTearDown.wiki b/fitnesse/FitNesseRoot/LispInterpreter/SuiteTearDown.wiki new file mode 100644 index 0000000..3f18339 --- /dev/null +++ b/fitnesse/FitNesseRoot/LispInterpreter/SuiteTearDown.wiki @@ -0,0 +1,5 @@ +--- +Test +--- +| script | lisp interpreter fixture | +| clean up | diff --git a/fitnesse/FitNesseRoot/RecentChanges.wiki b/fitnesse/FitNesseRoot/RecentChanges.wiki index 851a824..cb09c74 100644 --- a/fitnesse/FitNesseRoot/RecentChanges.wiki +++ b/fitnesse/FitNesseRoot/RecentChanges.wiki @@ -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| diff --git a/lisp/lang/dlambda-test.lisp b/lisp/lang/dlambda-test.lisp index 1800004..eb5222c 100644 --- a/lisp/lang/dlambda-test.lisp +++ b/lisp/lang/dlambda-test.lisp @@ -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))))))) diff --git a/src/function/builtin/LOAD.java b/src/function/builtin/LOAD.java index 709fcff..7a6a2d8 100644 --- a/src/function/builtin/LOAD.java +++ b/src/function/builtin/LOAD.java @@ -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 { diff --git a/src/interpreter/LispInterpreter.java b/src/interpreter/LispInterpreter.java index b30fab0..183d609 100644 --- a/src/interpreter/LispInterpreter.java +++ b/src/interpreter/LispInterpreter.java @@ -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(); diff --git a/src/interpreter/LispInterpreterBuilderImpl.java b/src/interpreter/LispInterpreterBuilderImpl.java index f2507dd..e4f7381 100644 --- a/src/interpreter/LispInterpreterBuilderImpl.java +++ b/src/interpreter/LispInterpreterBuilderImpl.java @@ -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); diff --git a/src/util/Path.java b/src/util/Path.java new file mode 100644 index 0000000..4cd97db --- /dev/null +++ b/src/util/Path.java @@ -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); + } + +} diff --git a/test/acceptance/fixture/LispInterpreterFixture.java b/test/acceptance/fixture/LispInterpreterFixture.java index 421e913..a4b759a 100644 --- a/test/acceptance/fixture/LispInterpreterFixture.java +++ b/test/acceptance/fixture/LispInterpreterFixture.java @@ -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(); diff --git a/test/util/PathTester.java b/test/util/PathTester.java new file mode 100644 index 0000000..b3a5877 --- /dev/null +++ b/test/util/PathTester.java @@ -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 constructor = Path.class.getDeclaredConstructor(); + + assertTrue(Modifier.isPrivate(constructor.getModifiers())); + constructor.setAccessible(true); + constructor.newInstance(); + } + +}