View Javadoc

1   // Copyright (C) 2011 - 2012 Philip Aston
2   // All rights reserved.
3   //
4   // This file is part of The Grinder software distribution. Refer to
5   // the file LICENSE which is part of The Grinder distribution for
6   // licensing details. The Grinder distribution is available on the
7   // Internet at http://grinder.sourceforge.net/
8   //
9   // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
10  // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
11  // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
12  // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
13  // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
14  // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
15  // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
16  // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
17  // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
18  // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
19  // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
20  // OF THE POSSIBILITY OF SUCH DAMAGE.
21  
22  package net.grinder.scriptengine.clojure;
23  
24  import static net.grinder.testutility.AssertUtilities.assertContains;
25  import static net.grinder.testutility.FileUtilities.createFile;
26  import static org.junit.Assert.assertEquals;
27  import static org.junit.Assert.assertTrue;
28  import static org.junit.Assert.fail;
29  
30  import java.io.File;
31  import java.io.StringReader;
32  
33  import net.grinder.engine.common.ScriptLocation;
34  import net.grinder.scriptengine.ScriptEngineService.ScriptEngine;
35  import net.grinder.scriptengine.ScriptEngineService.WorkerRunnable;
36  import net.grinder.scriptengine.ScriptExecutionException;
37  import net.grinder.testutility.AbstractJUnit4FileTestCase;
38  import net.grinder.util.Directory;
39  
40  import org.junit.Test;
41  
42  import clojure.lang.Compiler;
43  
44  
45  /**
46   * Unit tests for {@link ClojureScriptEngine}.
47   *
48   * @author Philip Aston
49   */
50  public class TestClojureScriptEngine extends AbstractJUnit4FileTestCase {
51  
52    private static int s_called;
53  
54    @Test public void testBadScript() throws Exception {
55  
56      final ScriptLocation script =
57        new ScriptLocation(new Directory(getDirectory()), new File("my.clj"));
58  
59      createFile(script.getFile(),
60                 "(");
61  
62      try {
63        new ClojureScriptEngineService().createScriptEngine(script);
64        fail("Expected ScriptExecutionException");
65      }
66      catch (final ScriptExecutionException e) {
67        assertTrue(e.getCause() instanceof RuntimeException);
68      }
69    }
70  
71    @Test public void testNilRunnerFactory() throws Exception {
72  
73      final ScriptLocation script =
74        new ScriptLocation(new Directory(getDirectory()), new File("my.clj"));
75  
76      createFile(script.getFile(),
77                 "()");
78  
79      try {
80        new ClojureScriptEngineService().createScriptEngine(script);
81        fail("Expected ScriptExecutionException");
82      }
83      catch (final ScriptExecutionException e) {
84        assertContains(e.getMessage(), "should return a function");
85      }
86    }
87  
88    @Test public void testNoneRunnerFactory() throws Exception {
89  
90      final ScriptLocation script =
91        new ScriptLocation(new Directory(getDirectory()), new File("my.clj"));
92  
93      createFile(script.getFile(),
94                 "");
95  
96      try {
97        new ClojureScriptEngineService().createScriptEngine(script);
98        fail("Expected ScriptExecutionException");
99      }
100     catch (final ScriptExecutionException e) {
101       assertContains(e.getMessage(), "should return a function");
102     }
103   }
104 
105   @Test public void testNoWorkerRunnable() throws Exception {
106 
107     final ScriptLocation script =
108       new ScriptLocation(new Directory(getDirectory()), new File("my.clj"));
109 
110     createFile(script.getFile(),
111                "(fn [] ())");
112 
113     final ScriptEngine scriptEngine =
114       new ClojureScriptEngineService().createScriptEngine(script);
115 
116     try {
117       scriptEngine.createWorkerRunnable();
118       fail("Expected ScriptExecutionException");
119     }
120     catch (final ScriptExecutionException e) {
121       assertContains(e.getMessage(), "should return a function");
122     }
123   }
124 
125   @Test public void testNilWorkerRunnable() throws Exception {
126 
127     final ScriptLocation script =
128       new ScriptLocation(new Directory(getDirectory()), new File("my.clj"));
129 
130     createFile(script.getFile(),
131                "(fn [] nil)");
132 
133     final ScriptEngine scriptEngine =
134       new ClojureScriptEngineService().createScriptEngine(script);
135 
136     try {
137       scriptEngine.createWorkerRunnable();
138       fail("Expected ScriptExecutionException");
139     }
140     catch (final ScriptExecutionException e) {
141       assertContains(e.getMessage(), "should return a function");
142     }
143   }
144 
145   @Test public void testBadRunnerFactory() throws Exception {
146 
147     final ScriptLocation script =
148       new ScriptLocation(new Directory(getDirectory()), new File("my.clj"));
149 
150     createFile(script.getFile(),
151                "(fn [] (throw))");
152 
153     final ScriptEngine scriptEngine =
154       new ClojureScriptEngineService().createScriptEngine(script);
155 
156     try {
157       scriptEngine.createWorkerRunnable();
158       fail("Expected ScriptExecutionException");
159     }
160     catch (final ScriptExecutionException e) {
161       assertTrue(e.getCause() instanceof NullPointerException);
162     }
163   }
164 
165   @Test public void testGoodWorkerRunnable() throws Exception {
166 
167     final ScriptLocation script =
168       new ScriptLocation(new Directory(getDirectory()), new File("my.clj"));
169 
170     createFile(script.getFile(),
171                "(fn [] (fn [] ()))");
172 
173     final ScriptEngine scriptEngine =
174       new ClojureScriptEngineService().createScriptEngine(script);
175 
176     assertContains(scriptEngine.getDescription(), "Clojure");
177 
178     final WorkerRunnable workerRunnable = scriptEngine.createWorkerRunnable();
179 
180     workerRunnable.run();
181 
182     workerRunnable.shutdown();
183 
184     scriptEngine.shutdown();
185   }
186 
187   @Test public void testBadWorkerRunnable() throws Exception {
188 
189     final ScriptLocation script =
190       new ScriptLocation(new Directory(getDirectory()), new File("my.clj"));
191 
192     createFile(script.getFile(),
193                "(fn [] (fn [] (throw)))");
194 
195     final ScriptEngine scriptEngine =
196       new ClojureScriptEngineService().createScriptEngine(script);
197 
198     final WorkerRunnable workerRunnable = scriptEngine.createWorkerRunnable();
199 
200     try {
201       workerRunnable.run();
202       fail("Expected ScriptExecutionException");
203     }
204     catch (final ScriptExecutionException e) {
205       assertTrue(e.getCause() instanceof NullPointerException);
206     }
207 
208     workerRunnable.shutdown();
209   }
210 
211   @Test public void testCreateWorkerRunnableWithBadRunner() throws Exception {
212 
213     final ScriptLocation script =
214       new ScriptLocation(new Directory(getDirectory()), new File("my.clj"));
215 
216     createFile(script.getFile(), "(fn [] ())");
217 
218     final ScriptEngine scriptEngine =
219       new ClojureScriptEngineService().createScriptEngine(script);
220 
221     try {
222       scriptEngine.createWorkerRunnable(this);
223       fail("Expected ScriptExecutionException");
224     }
225     catch (final ScriptExecutionException e) {
226       assertContains(e.getShortMessage(), "testRunner is not a function");
227     }
228   }
229 
230   @Test public void testCreateWorkerRunnableWithGoodRunner() throws Exception {
231 
232     final ScriptLocation script =
233       new ScriptLocation(new Directory(getDirectory()), new File("my.clj"));
234 
235     createFile(script.getFile(), CALL_ME);
236 
237     s_called = 0;
238 
239     final ScriptEngine scriptEngine =
240       new ClojureScriptEngineService().createScriptEngine(script);
241 
242     final Object runner = Compiler.load(new StringReader(CALL_ME));
243 
244     final WorkerRunnable workerRunnable =
245       scriptEngine.createWorkerRunnable(runner);
246 
247     assertEquals(0, s_called);
248 
249     s_called = 0;
250 
251     workerRunnable.run();
252 
253     assertEquals(1, s_called);
254 
255     workerRunnable.shutdown();
256   }
257 
258   private static final String CALL_ME =
259     "(fn [] (" + TestClojureScriptEngine.class.getName() + "/called))";
260 
261   public static void called() {
262     ++s_called;
263   }
264 }