diff --git a/fitnesse/FitNesseRoot/LispInterpreter/ExternalFunctionUnitTests.wiki b/fitnesse/FitNesseRoot/LispInterpreter/ExternalFunctionUnitTests.wiki index 82cdf46..cc29ebe 100644 --- a/fitnesse/FitNesseRoot/LispInterpreter/ExternalFunctionUnitTests.wiki +++ b/fitnesse/FitNesseRoot/LispInterpreter/ExternalFunctionUnitTests.wiki @@ -4,6 +4,4 @@ Test Unit tests for the dlambda special function. | script | lisp interpreter fixture | -| show | evaluate | (load "lisp/unit-test.lisp") | -| show | evaluate | (load "lisp/dlambda.lisp") | | show | evaluate | (load "lisp/dlambda-test.lisp") | diff --git a/fitnesse/FitNesseRoot/LispInterpreter/ObjectComposition.wiki b/fitnesse/FitNesseRoot/LispInterpreter/ObjectComposition.wiki index 3602128..8fe1739 100644 --- a/fitnesse/FitNesseRoot/LispInterpreter/ObjectComposition.wiki +++ b/fitnesse/FitNesseRoot/LispInterpreter/ObjectComposition.wiki @@ -4,7 +4,6 @@ Test Shows object composition, a default method, and two different ways of referencing objects. | script | lisp interpreter fixture | -| show | evaluate | (load "lisp/dlambda.lisp") | | show | evaluate | (load "lisp/fruit-counter.lisp") | | check | evaluate | (my-counter :inc-apples) | 1 | | check | evaluate | (my-counter :inc-apples) | 2 | diff --git a/fitnesse/FitNesseRoot/RecentChanges.wiki b/fitnesse/FitNesseRoot/RecentChanges.wiki index dabce81..b85b8c1 100644 --- a/fitnesse/FitNesseRoot/RecentChanges.wiki +++ b/fitnesse/FitNesseRoot/RecentChanges.wiki @@ -1,6 +1,7 @@ +|LispInterpreter.ExternalFunctionUnitTests||12:36:10 Fri, Mar 03, 2017| +|LispInterpreter.ObjectComposition||12:36:01 Fri, Mar 03, 2017| |LispInterpreter.DlambdaUnitTests||10:16:42 Fri, Mar 03, 2017| |LispInterpreter.dlambda||10:12:59 Fri, Mar 03, 2017| -|LispInterpreter.ObjectComposition||09:05:15 Fri, Mar 03, 2017| |LispInterpreter||09:04:51 Fri, Mar 03, 2017| |LispInterpreter.LexicalClosures||16:31:40 Thu, Mar 02, 2017| |LispInterpreter.LexicalClosure||16:26:49 Thu, Mar 02, 2017| diff --git a/src/function/builtin/LOAD.java b/src/function/builtin/LOAD.java index aaf232e..063a63a 100644 --- a/src/function/builtin/LOAD.java +++ b/src/function/builtin/LOAD.java @@ -6,6 +6,7 @@ import static sexpression.Symbol.T; import java.io.*; import java.text.MessageFormat; +import java.util.Stack; import environment.RuntimeEnvironment; import error.*; @@ -18,12 +19,14 @@ public class LOAD extends LispFunction { private ArgumentValidator argumentValidator; private ErrorManager errorManager; + private Stack pathPrefixes; public LOAD() { this.argumentValidator = new ArgumentValidator("LOAD"); this.argumentValidator.setExactNumberOfArguments(1); this.argumentValidator.setEveryArgumentExpectedType(LispString.class); this.errorManager = RuntimeEnvironment.getInstance().getErrorManager(); + this.pathPrefixes = new Stack<>(); } public SExpression call(Cons argumentList) { @@ -40,13 +43,18 @@ public class LOAD extends LispFunction { } private SExpression processFile(String fileName) { - boolean wasSuccessful = false; - LispParser parser = attemptToCreateParserOnFile(fileName); + boolean isSuccessful = false; + String prefixedFileName = prefixFileNameIfNecessary(fileName); + LispParser parser = attemptToCreateParserOnFile(prefixedFileName); if (parser != null) - wasSuccessful = isSuccessfulEvaluation(parser); + isSuccessful = isSuccessfulEvaluationWithPathPrefix(prefixedFileName, parser); - return wasSuccessful ? T : NIL; + return isSuccessful ? T : NIL; + } + + private String prefixFileNameIfNecessary(String fileName) { + return pathPrefixes.empty() ? fileName : pathPrefixes.peek() + fileName; } private LispParser attemptToCreateParserOnFile(String fileName) { @@ -61,6 +69,18 @@ public class LOAD extends LispFunction { return parser; } + private boolean isSuccessfulEvaluationWithPathPrefix(String prefixedFileName, LispParser parser) { + pathPrefixes.push(getPathPrefix(prefixedFileName)); + boolean isSuccessful = isSuccessfulEvaluation(parser); + pathPrefixes.pop(); + + 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/test/function/builtin/LOADTester.java b/test/function/builtin/LOADTester.java index 5041cdc..483cb8e 100644 --- a/test/function/builtin/LOADTester.java +++ b/test/function/builtin/LOADTester.java @@ -33,7 +33,7 @@ public class LOADTester { } private void assertNothingPrinted() { - assertTrue(outputStream.toByteArray().length == 0); + assertTrue(errorOutputStream.toByteArray().length == 0); assertTrue(outputStream.toByteArray().length == 0); } @@ -74,6 +74,22 @@ public class LOADTester { assertWarningMessagePrinted(); } + @Test + public void nestedLoadsInTheSameDirectory() { + String input = "(load \"test/function/builtin/test-files/nested/nested.lisp\")"; + + assertT(evaluateString(input)); + assertNothingPrinted(); + } + + @Test + public void nestedLoadsInDifferentDirectories() { + String input = "(load \"test/function/builtin/test-files/nested/one/load-one.lisp\")"; + + assertT(evaluateString(input)); + assertNothingPrinted(); + } + @Test(expected = BadArgumentTypeException.class) public void loadWithBadArgumentType() { evaluateString("(load '1)"); diff --git a/test/function/builtin/test-files/nested/included.lisp b/test/function/builtin/test-files/nested/included.lisp new file mode 100644 index 0000000..4e42c67 --- /dev/null +++ b/test/function/builtin/test-files/nested/included.lisp @@ -0,0 +1 @@ +"included" \ No newline at end of file diff --git a/test/function/builtin/test-files/nested/nested.lisp b/test/function/builtin/test-files/nested/nested.lisp new file mode 100644 index 0000000..6b67b0b --- /dev/null +++ b/test/function/builtin/test-files/nested/nested.lisp @@ -0,0 +1 @@ +(load "included.lisp") diff --git a/test/function/builtin/test-files/nested/one/load-one.lisp b/test/function/builtin/test-files/nested/one/load-one.lisp new file mode 100644 index 0000000..84a64b5 --- /dev/null +++ b/test/function/builtin/test-files/nested/one/load-one.lisp @@ -0,0 +1 @@ +(load "two/three/load-three.lisp") \ No newline at end of file diff --git a/test/function/builtin/test-files/nested/one/two/load-two.lisp b/test/function/builtin/test-files/nested/one/two/load-two.lisp new file mode 100644 index 0000000..8c35ae8 --- /dev/null +++ b/test/function/builtin/test-files/nested/one/two/load-two.lisp @@ -0,0 +1 @@ +(load "../../nested.lisp") \ No newline at end of file diff --git a/test/function/builtin/test-files/nested/one/two/three/load-three.lisp b/test/function/builtin/test-files/nested/one/two/three/load-three.lisp new file mode 100644 index 0000000..56417a6 --- /dev/null +++ b/test/function/builtin/test-files/nested/one/two/three/load-three.lisp @@ -0,0 +1 @@ +(load "../load-two.lisp") \ No newline at end of file