package org.dynjs.jsr223; import org.dynjs.runtime.JSObject; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.fail; import javax.script.*; import static org.fest.assertions.Assertions.*; /** * @author Bob McWhirter */ public class ScriptEngineTest { private DynJSScriptEngine engine; @Before public void setUpEngine() { ScriptEngineManager manager = new ScriptEngineManager(); this.engine = (DynJSScriptEngine) manager.getEngineByName( "dynjs" ); } @Test public void testScriptEngineFactoryRegistration() { assertThat( engine ).isNotNull(); } @Test public void testGlobalNoState() throws ScriptException { Object result = engine.eval( "4+2" ); assertThat( result ).isEqualTo( 6L ); } @Test public void testGlobalCreateState() throws ScriptException { engine.eval( "var foo=42"); assertThat( engine.eval( "foo" ) ).isEqualTo( 42L ); } @Test public void testGlobalWithGlobalState() throws ScriptException { engine.getBindings(ScriptContext.GLOBAL_SCOPE ).put("foo", 44L); assertThat(engine.eval("foo")).isEqualTo( 44L ); } @Test public void testGlobalWithEngineState() throws ScriptException { engine.put( "foo", 46L ); assertThat(engine.eval("foo")).isEqualTo( 46L ); } @Test public void testGlobalWithEngineStateOverridingGlobalState() throws ScriptException { engine.getBindings(ScriptContext.GLOBAL_SCOPE ).put( "foo", 44L ); engine.put( "foo", 46L ); assertThat(engine.eval("foo")).isEqualTo(46L); } @Test public void testGlobalWithLocalStateOverridingAllOtherStateButNotModifyingIt() throws ScriptException { engine.getBindings(ScriptContext.GLOBAL_SCOPE ).put( "foo", 44L ); engine.put("foo", 46L); engine.eval("foo=48;"); assertThat( engine.eval( "foo" ) ).isEqualTo(48L); assertThat( engine.getBindings( ScriptContext.GLOBAL_SCOPE ).get( "foo" ) ).isEqualTo( 44L ); assertThat( engine.getBindings( ScriptContext.ENGINE_SCOPE ).get( "foo" ) ).isEqualTo( 46L ); } @Test public void testEvalOverrideEngineState() throws ScriptException { SimpleBindings override = new SimpleBindings(); override.put( "foo", "tacos" ); engine.getBindings(ScriptContext.GLOBAL_SCOPE ).put( "foo", 44L ); engine.getBindings(ScriptContext.ENGINE_SCOPE ).put("foo", 46L); Object result = engine.eval( "foo", override ); assertThat( result ).isEqualTo( "tacos" ); assertThat( engine.getBindings( ScriptContext.GLOBAL_SCOPE ).get( "foo" ) ).isEqualTo( 44L ); assertThat( engine.getBindings( ScriptContext.ENGINE_SCOPE ).get( "foo" ) ).isEqualTo( 46L ); } @Test public void testArgv() throws ScriptException { engine.put( ScriptEngine.ARGV, new String[]{ "one", "two" }); Object result = engine.eval( "dynjs.argv[1]" ); assertThat( result ).isEqualTo( "two" ); } @Test public void testInvokeMethod() throws ScriptException, NoSuchMethodException { Object o = engine.eval( "var o = { foo: function(arg) { return arg+42; }, bar: 84 }; o;"); assertThat( o ).isNotNull(); assertThat( o ).isInstanceOf( JSObject.class ); Object result = engine.invokeMethod( o, "foo", 14 ); assertThat( result ).isEqualTo( 56L ); try { engine.invokeMethod( o, "bar" ); fail("should have thrown ScriptException"); } catch (ScriptException t) { // expected and correct } try { engine.invokeMethod(o, "noSuch"); fail( "should have thrown NoSuchMethodException" ); } catch (NoSuchMethodException e) { // expected and correct } } @Test public void testInvokeFunction() throws ScriptException, NoSuchMethodException { engine.eval( "function foo(arg) { return 42+arg; }; var bar = 99;"); Object result = engine.invokeFunction( "foo", 12 ); assertThat( result ).isEqualTo( 54L ); try { engine.invokeFunction( "bar" ); fail( "Should have thrown ScriptException"); } catch (ScriptException e) { // expected and correct } try { engine.invokeFunction( "noSuch" ); fail("should have thrown NoSuchMethodException"); } catch (NoSuchMethodException e) { // expected and correct } } ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// public static interface Thingy { int foo(); String bar(); } @Test public void testGetInterface() throws ScriptException { engine.eval( "function foo() { return 42; }; function bar() { return 'taco'; }" ); Thingy thingy = engine.getInterface( Thingy.class ); assertThat( thingy.foo() ).isEqualTo( 42 ); assertThat( thingy.bar() ).isEqualTo( "taco" ); } @Test public void testGetInterfaceWithThis() throws ScriptException { Object o = engine.eval( "var o = { foo: function() { return 99; }, bar: function() { return 'bob'; } }; o;"); assertThat( o ).isInstanceOf( JSObject.class ); Thingy thingy = engine.getInterface( o, Thingy.class ); assertThat( thingy.foo() ).isEqualTo( 99 ); assertThat( thingy.bar() ).isEqualTo( "bob" ); } }