package nginx.clojure; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.util.ArrayList; import org.junit.After; import org.junit.Before; import org.junit.Test; import clojure.lang.IFn; import clojure.lang.RT; import clojure.lang.Symbol; public class ClojureFnTest { ArrayList<String> messages = new ArrayList<String>(); @Before public void setUp() throws Exception { // String classpath = System.getProperty("java.class.path"); // String[] cps = classpath.split(File.pathSeparator); // for (String cp : cps) { // System.out.println(cp); // } messages = new ArrayList<String>(); } @After public void tearDown() throws Exception { messages.clear(); } @Test public void testSimpleFnOutofCoroutine() { RT.var("clojure.core", "require").invoke(Symbol.create("nginx.clojure.fns-for-test")); // System.out.println("rq cl :" + rq.getClass().getClassLoader()); final IFn fn = (IFn)RT.var("nginx.clojure.fns-for-test", "fn-out-of-coroutine").fn(); fn.invoke(messages); assertEquals(4, messages.size()); assertEquals("entering fn-out-of-coroutine", messages.get(0)); for (int i = 0; i < 3; i++) { assertEquals("echo:" + i, messages.get(i+1)); } } @Test public void testSimpleFn() { RT.var("clojure.core", "require").invoke(Symbol.create("nginx.clojure.fns-for-test")); // System.out.println("rq cl :" + rq.getClass().getClassLoader()); final IFn fn = (IFn)RT.var("nginx.clojure.fns-for-test", "simplefn").fn(); Coroutine cr = new Coroutine(new Runnable() { @Override public void run() throws SuspendExecution { fn.invoke(messages); } }); cr.resume(); assertEquals(1, messages.size()); assertEquals("entering simplefn", messages.get(0)); cr.resume(); assertEquals(2, messages.size()); assertEquals("before yield:0", messages.get(1)); cr.resume(); assertEquals(4, messages.size()); assertEquals("end yield:0", messages.get(2)); assertEquals("before yield:1", messages.get(3)); cr.resume(); assertEquals(6, messages.size()); assertEquals("end yield:1", messages.get(4)); assertEquals("before yield:2", messages.get(5)); cr.resume(); assertEquals(8, messages.size()); assertEquals("end yield:2", messages.get(6)); long tid = Thread.currentThread().getId(); //the same thread with caller: good! assertEquals("threadId:"+tid, messages.get(7)); assertEquals(Coroutine.State.FINISHED, cr.getState()); assertTrue(cr.getStack().allObjsAreNull()); } @Test public void testReduce() { for (int k = 0; k < 10; k++) { RT.var("clojure.core", "require").invoke(Symbol.create("nginx.clojure.fns-for-test")); // System.out.println("rq cl :" + rq.getClass().getClassLoader()); final IFn fn = (IFn)RT.var("nginx.clojure.fns-for-test", "coreduce-test").fn(); ArrayList<Long> ma = new ArrayList<Long>(); Coroutine cr = (Coroutine)fn.invoke(ma); cr.resume(); for (int i = 0; i < 4; i++) { cr.resume(); } assertEquals(25L, (Number)ma.get(0)); assertEquals(Coroutine.State.FINISHED, cr.getState()); assertTrue(cr.getStack().allObjsAreNull()); } } @Test public void testBinding() { RT.var("clojure.core", "require").invoke(Symbol.create("nginx.clojure.fns-for-test")); IFn cafn = (IFn)RT.var("nginx.clojure.fns-for-test", "ca").fn(); IFn cbfn = (IFn)RT.var("nginx.clojure.fns-for-test", "cb").fn(); ArrayList<String> ma = new ArrayList<String>(); Coroutine ca = (Coroutine) cafn.invoke(ma); ArrayList<String> mb = new ArrayList<String>(); Coroutine cb = (Coroutine) cbfn.invoke(mb); ca.resume(); cb.resume(); assertTrue(ma.isEmpty()); assertTrue(mb.isEmpty()); ca.resume(); assertEquals("ca", ma.get(0)); cb.resume(); assertEquals("cb", mb.get(0)); } }