Fri, 23 Aug 2013 16:10:37 +0530
8023631: engine.js init script should be loaded into every global instance created by engines
Reviewed-by: attila, hannesw
1.1 --- a/src/jdk/nashorn/api/scripting/NashornScriptEngine.java Thu Aug 22 22:32:16 2013 +0530 1.2 +++ b/src/jdk/nashorn/api/scripting/NashornScriptEngine.java Fri Aug 23 16:10:37 2013 +0530 1.3 @@ -80,6 +80,7 @@ 1.4 */ 1.5 public static final String NASHORN_GLOBAL = "nashorn.global"; 1.6 1.7 + // commonly used access control context objects 1.8 private static AccessControlContext createPermAccCtxt(final String permName) { 1.9 final Permissions perms = new Permissions(); 1.10 perms.add(new RuntimePermission(permName)); 1.11 @@ -89,18 +90,23 @@ 1.12 private static final AccessControlContext CREATE_CONTEXT_ACC_CTXT = createPermAccCtxt(Context.NASHORN_CREATE_CONTEXT); 1.13 private static final AccessControlContext CREATE_GLOBAL_ACC_CTXT = createPermAccCtxt(Context.NASHORN_CREATE_GLOBAL); 1.14 1.15 + // the factory that created this engine 1.16 private final ScriptEngineFactory factory; 1.17 + // underlying nashorn Context - 1:1 with engine instance 1.18 private final Context nashornContext; 1.19 // do we want to share single Nashorn global instance across ENGINE_SCOPEs? 1.20 private final boolean _global_per_engine; 1.21 + // This is the initial default Nashorn global object. 1.22 + // This is used as "shared" global if above option is true. 1.23 private final ScriptObject global; 1.24 - // initialized bit late to be made 'final'. Property object for "context" 1.25 - // property of global object 1.26 - private Property contextProperty; 1.27 + // initialized bit late to be made 'final'. 1.28 + // Property object for "context" property of global object. 1.29 + private volatile Property contextProperty; 1.30 1.31 // default options passed to Nashorn Options object 1.32 private static final String[] DEFAULT_OPTIONS = new String[] { "-scripting", "-doe" }; 1.33 1.34 + // Nashorn script engine error message management 1.35 private static final String MESSAGES_RESOURCE = "jdk.nashorn.api.scripting.resources.Messages"; 1.36 1.37 private static final ResourceBundle MESSAGES_BUNDLE; 1.38 @@ -108,6 +114,7 @@ 1.39 MESSAGES_BUNDLE = ResourceBundle.getBundle(MESSAGES_RESOURCE, Locale.getDefault()); 1.40 } 1.41 1.42 + // helper to get Nashorn script engine error message 1.43 private static String getMessage(final String msgId, final String... args) { 1.44 try { 1.45 return new MessageFormat(MESSAGES_BUNDLE.getString(msgId)).format(args); 1.46 @@ -116,6 +123,30 @@ 1.47 } 1.48 } 1.49 1.50 + // load engine.js and return content as a char[] 1.51 + private static char[] loadEngineJSSource() { 1.52 + final String script = "resources/engine.js"; 1.53 + try { 1.54 + final InputStream is = AccessController.doPrivileged( 1.55 + new PrivilegedExceptionAction<InputStream>() { 1.56 + @Override 1.57 + public InputStream run() throws Exception { 1.58 + final URL url = NashornScriptEngine.class.getResource(script); 1.59 + return url.openStream(); 1.60 + } 1.61 + }); 1.62 + return Source.readFully(new InputStreamReader(is)); 1.63 + } catch (final PrivilegedActionException | IOException e) { 1.64 + if (Context.DEBUG) { 1.65 + e.printStackTrace(); 1.66 + } 1.67 + throw new RuntimeException(e); 1.68 + } 1.69 + } 1.70 + 1.71 + // Source object for engine.js 1.72 + private static final Source ENGINE_SCRIPT_SRC = new Source(NashornException.ENGINE_SCRIPT_SOURCE_NAME, loadEngineJSSource()); 1.73 + 1.74 NashornScriptEngine(final NashornScriptEngineFactory factory, final ClassLoader appLoader) { 1.75 this(factory, DEFAULT_OPTIONS, appLoader); 1.76 } 1.77 @@ -146,19 +177,9 @@ 1.78 this._global_per_engine = nashornContext.getEnv()._global_per_engine; 1.79 1.80 // create new global object 1.81 - this.global = createNashornGlobal(); 1.82 - // set the default engine scope for the default context 1.83 + this.global = createNashornGlobal(context); 1.84 + // set the default ENGINE_SCOPE object for the default context 1.85 context.setBindings(new ScriptObjectMirror(global, global), ScriptContext.ENGINE_SCOPE); 1.86 - 1.87 - // evaluate engine initial script 1.88 - try { 1.89 - evalEngineScript(); 1.90 - } catch (final ScriptException e) { 1.91 - if (Context.DEBUG) { 1.92 - e.printStackTrace(); 1.93 - } 1.94 - throw new RuntimeException(e); 1.95 - } 1.96 } 1.97 1.98 @Override 1.99 @@ -192,8 +213,7 @@ 1.100 // We use same 'global' for all Bindings. 1.101 return new SimpleBindings(); 1.102 } else { 1.103 - final ScriptObject newGlobal = createNashornGlobal(); 1.104 - return new ScriptObjectMirror(newGlobal, newGlobal); 1.105 + return createGlobalMirror(null); 1.106 } 1.107 } 1.108 1.109 @@ -230,6 +250,48 @@ 1.110 return invokeImpl(thiz, name, args); 1.111 } 1.112 1.113 + @Override 1.114 + public <T> T getInterface(final Class<T> clazz) { 1.115 + return getInterfaceInner(null, clazz); 1.116 + } 1.117 + 1.118 + @Override 1.119 + public <T> T getInterface(final Object thiz, final Class<T> clazz) { 1.120 + if (thiz == null) { 1.121 + throw new IllegalArgumentException(getMessage("thiz.cannot.be.null")); 1.122 + } 1.123 + return getInterfaceInner(thiz, clazz); 1.124 + } 1.125 + 1.126 + // These are called from the "engine.js" script 1.127 + 1.128 + /** 1.129 + * This hook is used to search js global variables exposed from Java code. 1.130 + * 1.131 + * @param self 'this' passed from the script 1.132 + * @param ctxt current ScriptContext in which name is searched 1.133 + * @param name name of the variable searched 1.134 + * @return the value of the named variable 1.135 + */ 1.136 + public Object __noSuchProperty__(final Object self, final ScriptContext ctxt, final String name) { 1.137 + if (ctxt != null) { 1.138 + final int scope = ctxt.getAttributesScope(name); 1.139 + final ScriptObject ctxtGlobal = getNashornGlobalFrom(ctxt); 1.140 + if (scope != -1) { 1.141 + return ScriptObjectMirror.unwrap(ctxt.getAttribute(name, scope), ctxtGlobal); 1.142 + } 1.143 + 1.144 + if (self == UNDEFINED) { 1.145 + // scope access and so throw ReferenceError 1.146 + throw referenceError(ctxtGlobal, "not.defined", name); 1.147 + } 1.148 + } 1.149 + 1.150 + return UNDEFINED; 1.151 + } 1.152 + 1.153 + // Implementation only below this point 1.154 + 1.155 private <T> T getInterfaceInner(final Object thiz, final Class<T> clazz) { 1.156 if (clazz == null || !clazz.isInterface()) { 1.157 throw new IllegalArgumentException(getMessage("interface.class.expected")); 1.158 @@ -297,47 +359,10 @@ 1.159 } 1.160 } 1.161 1.162 - @Override 1.163 - public <T> T getInterface(final Class<T> clazz) { 1.164 - return getInterfaceInner(null, clazz); 1.165 - } 1.166 - 1.167 - @Override 1.168 - public <T> T getInterface(final Object thiz, final Class<T> clazz) { 1.169 - if (thiz == null) { 1.170 - throw new IllegalArgumentException(getMessage("thiz.cannot.be.null")); 1.171 - } 1.172 - return getInterfaceInner(thiz, clazz); 1.173 - } 1.174 - 1.175 - // These are called from the "engine.js" script 1.176 - 1.177 - /** 1.178 - * This hook is used to search js global variables exposed from Java code. 1.179 - * 1.180 - * @param self 'this' passed from the script 1.181 - * @param ctxt current ScriptContext in which name is searched 1.182 - * @param name name of the variable searched 1.183 - * @return the value of the named variable 1.184 - */ 1.185 - public Object __noSuchProperty__(final Object self, final ScriptContext ctxt, final String name) { 1.186 - final int scope = ctxt.getAttributesScope(name); 1.187 - final ScriptObject ctxtGlobal = getNashornGlobalFrom(ctxt); 1.188 - if (scope != -1) { 1.189 - return ScriptObjectMirror.unwrap(ctxt.getAttribute(name, scope), ctxtGlobal); 1.190 - } 1.191 - 1.192 - if (self == UNDEFINED) { 1.193 - // scope access and so throw ReferenceError 1.194 - throw referenceError(ctxtGlobal, "not.defined", name); 1.195 - } 1.196 - 1.197 - return UNDEFINED; 1.198 - } 1.199 - 1.200 + // Retrieve nashorn Global object for a given ScriptContext object 1.201 private ScriptObject getNashornGlobalFrom(final ScriptContext ctxt) { 1.202 if (_global_per_engine) { 1.203 - // shared single global for all ENGINE_SCOPE Bindings 1.204 + // shared single global object for all ENGINE_SCOPE Bindings 1.205 return global; 1.206 } 1.207 1.208 @@ -361,11 +386,12 @@ 1.209 1.210 // We didn't find associated nashorn global mirror in the Bindings given! 1.211 // Create new global instance mirror and associate with the Bindings. 1.212 - final ScriptObjectMirror mirror = (ScriptObjectMirror)createBindings(); 1.213 + final ScriptObjectMirror mirror = createGlobalMirror(ctxt); 1.214 bindings.put(NASHORN_GLOBAL, mirror); 1.215 return mirror.getScriptObject(); 1.216 } 1.217 1.218 + // Retrieve nashorn Global object from a given ScriptObjectMirror 1.219 private ScriptObject globalFromMirror(final ScriptObjectMirror mirror) { 1.220 ScriptObject sobj = mirror.getScriptObject(); 1.221 if (sobj instanceof GlobalObject && sobj.isOfContext(nashornContext)) { 1.222 @@ -375,7 +401,14 @@ 1.223 return null; 1.224 } 1.225 1.226 - private ScriptObject createNashornGlobal() { 1.227 + // Create a new ScriptObjectMirror wrapping a newly created Nashorn Global object 1.228 + private ScriptObjectMirror createGlobalMirror(final ScriptContext ctxt) { 1.229 + final ScriptObject newGlobal = createNashornGlobal(ctxt); 1.230 + return new ScriptObjectMirror(newGlobal, newGlobal); 1.231 + } 1.232 + 1.233 + // Create a new Nashorn Global object 1.234 + private ScriptObject createNashornGlobal(final ScriptContext ctxt) { 1.235 final ScriptObject newGlobal = AccessController.doPrivileged(new PrivilegedAction<ScriptObject>() { 1.236 @Override 1.237 public ScriptObject run() { 1.238 @@ -396,7 +429,7 @@ 1.239 // current ScriptContext exposed as "context" 1.240 // "context" is non-writable from script - but script engine still 1.241 // needs to set it and so save the context Property object 1.242 - contextProperty = newGlobal.addOwnProperty("context", NON_ENUMERABLE_CONSTANT, UNDEFINED); 1.243 + contextProperty = newGlobal.addOwnProperty("context", NON_ENUMERABLE_CONSTANT, null); 1.244 // current ScriptEngine instance exposed as "engine". We added @SuppressWarnings("LeakingThisInConstructor") as 1.245 // NetBeans identifies this assignment as such a leak - this is a false positive as we're setting this property 1.246 // in the Global of a Context we just created - both the Context and the Global were just created and can not be 1.247 @@ -406,38 +439,17 @@ 1.248 newGlobal.addOwnProperty("arguments", Property.NOT_ENUMERABLE, UNDEFINED); 1.249 // file name default is null 1.250 newGlobal.addOwnProperty(ScriptEngine.FILENAME, Property.NOT_ENUMERABLE, null); 1.251 + // evaluate engine.js initialization script this new global object 1.252 + try { 1.253 + evalImpl(compileImpl(ENGINE_SCRIPT_SRC, newGlobal), ctxt, newGlobal); 1.254 + } catch (final ScriptException exp) { 1.255 + throw new RuntimeException(exp); 1.256 + } 1.257 return newGlobal; 1.258 } 1.259 1.260 - private void evalEngineScript() throws ScriptException { 1.261 - final String script = "resources/engine.js"; 1.262 - final String name = NashornException.ENGINE_SCRIPT_SOURCE_NAME; 1.263 - try { 1.264 - final InputStream is = AccessController.doPrivileged( 1.265 - new PrivilegedExceptionAction<InputStream>() { 1.266 - @Override 1.267 - public InputStream run() throws Exception { 1.268 - final URL url = NashornScriptEngine.class.getResource(script); 1.269 - return url.openStream(); 1.270 - } 1.271 - }); 1.272 - put(ScriptEngine.FILENAME, name); 1.273 - try (final InputStreamReader isr = new InputStreamReader(is)) { 1.274 - eval(isr); 1.275 - } 1.276 - } catch (final PrivilegedActionException | IOException e) { 1.277 - if (Context.DEBUG) { 1.278 - e.printStackTrace(); 1.279 - } 1.280 - throw new ScriptException(e); 1.281 - } finally { 1.282 - put(ScriptEngine.FILENAME, null); 1.283 - } 1.284 - } 1.285 - 1.286 - // scripts should see "context" and "engine" as variables 1.287 - private void setContextVariables(final ScriptContext ctxt) { 1.288 - final ScriptObject ctxtGlobal = getNashornGlobalFrom(ctxt); 1.289 + // scripts should see "context" and "engine" as variables in the given global object 1.290 + private void setContextVariables(final ScriptObject ctxtGlobal, final ScriptContext ctxt) { 1.291 // set "context" global variable via contextProperty - because this 1.292 // property is non-writable 1.293 contextProperty.setObjectValue(ctxtGlobal, ctxtGlobal, ctxt, false); 1.294 @@ -502,18 +514,24 @@ 1.295 } 1.296 1.297 private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt) throws ScriptException { 1.298 + return evalImpl(script, ctxt, getNashornGlobalFrom(ctxt)); 1.299 + } 1.300 + 1.301 + private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt, final ScriptObject ctxtGlobal) throws ScriptException { 1.302 if (script == null) { 1.303 return null; 1.304 } 1.305 final ScriptObject oldGlobal = Context.getGlobal(); 1.306 - final ScriptObject ctxtGlobal = getNashornGlobalFrom(ctxt); 1.307 final boolean globalChanged = (oldGlobal != ctxtGlobal); 1.308 try { 1.309 if (globalChanged) { 1.310 Context.setGlobal(ctxtGlobal); 1.311 } 1.312 1.313 - setContextVariables(ctxt); 1.314 + // set ScriptContext variables if ctxt is non-null 1.315 + if (ctxt != null) { 1.316 + setContextVariables(ctxtGlobal, ctxt); 1.317 + } 1.318 return ScriptObjectMirror.translateUndefined(ScriptObjectMirror.wrap(ScriptRuntime.apply(script, ctxtGlobal), ctxtGlobal)); 1.319 } catch (final Exception e) { 1.320 throwAsScriptException(e); 1.321 @@ -563,15 +581,18 @@ 1.322 } 1.323 1.324 private ScriptFunction compileImpl(final Source source, final ScriptContext ctxt) throws ScriptException { 1.325 + return compileImpl(source, getNashornGlobalFrom(ctxt)); 1.326 + } 1.327 + 1.328 + private ScriptFunction compileImpl(final Source source, final ScriptObject newGlobal) throws ScriptException { 1.329 final ScriptObject oldGlobal = Context.getGlobal(); 1.330 - final ScriptObject ctxtGlobal = getNashornGlobalFrom(ctxt); 1.331 - final boolean globalChanged = (oldGlobal != ctxtGlobal); 1.332 + final boolean globalChanged = (oldGlobal != newGlobal); 1.333 try { 1.334 if (globalChanged) { 1.335 - Context.setGlobal(ctxtGlobal); 1.336 + Context.setGlobal(newGlobal); 1.337 } 1.338 1.339 - return nashornContext.compileScript(source, ctxtGlobal); 1.340 + return nashornContext.compileScript(source, newGlobal); 1.341 } catch (final Exception e) { 1.342 throwAsScriptException(e); 1.343 throw new AssertionError("should not reach here");
2.1 --- a/src/jdk/nashorn/api/scripting/resources/engine.js Thu Aug 22 22:32:16 2013 +0530 2.2 +++ b/src/jdk/nashorn/api/scripting/resources/engine.js Fri Aug 23 16:10:37 2013 +0530 2.3 @@ -23,10 +23,9 @@ 2.4 2.5 /** 2.6 * This script file is executed by script engine at the construction 2.7 - * of the engine. The functions here assume global variables "context" 2.8 - * of type javax.script.ScriptContext and "engine" of the type 2.9 + * of the every new Global object. The functions here assume global variables 2.10 + * "context" of type javax.script.ScriptContext and "engine" of the type 2.11 * jdk.nashorn.api.scripting.NashornScriptEngine. 2.12 - * 2.13 **/ 2.14 2.15 Object.defineProperty(this, "__noSuchProperty__", { 2.16 @@ -40,7 +39,7 @@ 2.17 }); 2.18 2.19 function print() { 2.20 - var writer = context.getWriter(); 2.21 + var writer = context != null? context.writer : engine.context.writer; 2.22 if (! (writer instanceof java.io.PrintWriter)) { 2.23 writer = new java.io.PrintWriter(writer); 2.24 }
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/test/src/jdk/nashorn/api/scripting/InvocableTest.java Fri Aug 23 16:10:37 2013 +0530 3.3 @@ -0,0 +1,525 @@ 3.4 +/* 3.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.7 + * 3.8 + * This code is free software; you can redistribute it and/or modify it 3.9 + * under the terms of the GNU General Public License version 2 only, as 3.10 + * published by the Free Software Foundation. Oracle designates this 3.11 + * particular file as subject to the "Classpath" exception as provided 3.12 + * by Oracle in the LICENSE file that accompanied this code. 3.13 + * 3.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 3.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 3.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 3.17 + * version 2 for more details (a copy is included in the LICENSE file that 3.18 + * accompanied this code). 3.19 + * 3.20 + * You should have received a copy of the GNU General Public License version 3.21 + * 2 along with this work; if not, write to the Free Software Foundation, 3.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 3.23 + * 3.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 3.25 + * or visit www.oracle.com if you need additional information or have any 3.26 + * questions. 3.27 + */ 3.28 + 3.29 +package jdk.nashorn.api.scripting; 3.30 + 3.31 +import java.util.Objects; 3.32 +import javax.script.Invocable; 3.33 +import javax.script.ScriptContext; 3.34 +import javax.script.ScriptEngine; 3.35 +import javax.script.ScriptEngineManager; 3.36 +import javax.script.ScriptException; 3.37 +import javax.script.SimpleScriptContext; 3.38 +import org.testng.Assert; 3.39 +import static org.testng.Assert.assertEquals; 3.40 +import static org.testng.Assert.fail; 3.41 +import org.testng.annotations.Test; 3.42 + 3.43 +/** 3.44 + * Tests for javax.script.Invocable implementation of nashorn. 3.45 + */ 3.46 +public class InvocableTest { 3.47 + 3.48 + private void log(String msg) { 3.49 + org.testng.Reporter.log(msg, true); 3.50 + } 3.51 + 3.52 + @Test 3.53 + public void invokeMethodTest() { 3.54 + final ScriptEngineManager m = new ScriptEngineManager(); 3.55 + final ScriptEngine e = m.getEngineByName("nashorn"); 3.56 + 3.57 + try { 3.58 + e.eval("var Example = function() { this.hello = function() { return 'Hello World!'; };}; myExample = new Example();"); 3.59 + final Object obj = e.get("myExample"); 3.60 + final Object res = ((Invocable) e).invokeMethod(obj, "hello"); 3.61 + assertEquals(res, "Hello World!"); 3.62 + } catch (final Exception exp) { 3.63 + exp.printStackTrace(); 3.64 + fail(exp.getMessage()); 3.65 + } 3.66 + } 3.67 + 3.68 + @Test 3.69 + /** 3.70 + * Check that we can call invokeMethod on an object that we got by 3.71 + * evaluating script with different Context set. 3.72 + */ 3.73 + public void invokeMethodDifferentContextTest() { 3.74 + ScriptEngineManager m = new ScriptEngineManager(); 3.75 + ScriptEngine e = m.getEngineByName("nashorn"); 3.76 + 3.77 + try { 3.78 + // define an object with method on it 3.79 + Object obj = e.eval("({ hello: function() { return 'Hello World!'; } })"); 3.80 + 3.81 + final ScriptContext ctxt = new SimpleScriptContext(); 3.82 + ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE); 3.83 + e.setContext(ctxt); 3.84 + 3.85 + // invoke 'func' on obj - but with current script context changed 3.86 + final Object res = ((Invocable) e).invokeMethod(obj, "hello"); 3.87 + assertEquals(res, "Hello World!"); 3.88 + } catch (final Exception exp) { 3.89 + exp.printStackTrace(); 3.90 + fail(exp.getMessage()); 3.91 + } 3.92 + } 3.93 + 3.94 + @Test 3.95 + /** 3.96 + * Check that invokeMethod throws NPE on null method name. 3.97 + */ 3.98 + public void invokeMethodNullNameTest() { 3.99 + final ScriptEngineManager m = new ScriptEngineManager(); 3.100 + final ScriptEngine e = m.getEngineByName("nashorn"); 3.101 + 3.102 + try { 3.103 + final Object obj = e.eval("({})"); 3.104 + final Object res = ((Invocable) e).invokeMethod(obj, null); 3.105 + fail("should have thrown NPE"); 3.106 + } catch (final Exception exp) { 3.107 + if (!(exp instanceof NullPointerException)) { 3.108 + exp.printStackTrace(); 3.109 + fail(exp.getMessage()); 3.110 + } 3.111 + } 3.112 + } 3.113 + 3.114 + @Test 3.115 + /** 3.116 + * Check that invokeMethod throws NoSuchMethodException on missing method. 3.117 + */ 3.118 + public void invokeMethodMissingTest() { 3.119 + final ScriptEngineManager m = new ScriptEngineManager(); 3.120 + final ScriptEngine e = m.getEngineByName("nashorn"); 3.121 + 3.122 + try { 3.123 + final Object obj = e.eval("({})"); 3.124 + final Object res = ((Invocable) e).invokeMethod(obj, "nonExistentMethod"); 3.125 + fail("should have thrown NoSuchMethodException"); 3.126 + } catch (final Exception exp) { 3.127 + if (!(exp instanceof NoSuchMethodException)) { 3.128 + exp.printStackTrace(); 3.129 + fail(exp.getMessage()); 3.130 + } 3.131 + } 3.132 + } 3.133 + 3.134 + @Test 3.135 + /** 3.136 + * Check that calling method on non-script object 'thiz' results in 3.137 + * IllegalArgumentException. 3.138 + */ 3.139 + public void invokeMethodNonScriptObjectThizTest() { 3.140 + final ScriptEngineManager m = new ScriptEngineManager(); 3.141 + final ScriptEngine e = m.getEngineByName("nashorn"); 3.142 + 3.143 + try { 3.144 + ((Invocable) e).invokeMethod(new Object(), "toString"); 3.145 + fail("should have thrown IllegalArgumentException"); 3.146 + } catch (final Exception exp) { 3.147 + if (!(exp instanceof IllegalArgumentException)) { 3.148 + exp.printStackTrace(); 3.149 + fail(exp.getMessage()); 3.150 + } 3.151 + } 3.152 + } 3.153 + 3.154 + @Test 3.155 + /** 3.156 + * Check that calling method on null 'thiz' results in 3.157 + * IllegalArgumentException. 3.158 + */ 3.159 + public void invokeMethodNullThizTest() { 3.160 + final ScriptEngineManager m = new ScriptEngineManager(); 3.161 + final ScriptEngine e = m.getEngineByName("nashorn"); 3.162 + 3.163 + try { 3.164 + ((Invocable) e).invokeMethod(null, "toString"); 3.165 + fail("should have thrown IllegalArgumentException"); 3.166 + } catch (final Exception exp) { 3.167 + if (!(exp instanceof IllegalArgumentException)) { 3.168 + exp.printStackTrace(); 3.169 + fail(exp.getMessage()); 3.170 + } 3.171 + } 3.172 + } 3.173 + 3.174 + @Test 3.175 + /** 3.176 + * Check that calling method on mirror created by another engine results in 3.177 + * IllegalArgumentException. 3.178 + */ 3.179 + public void invokeMethodMixEnginesTest() { 3.180 + final ScriptEngineManager m = new ScriptEngineManager(); 3.181 + final ScriptEngine engine1 = m.getEngineByName("nashorn"); 3.182 + final ScriptEngine engine2 = m.getEngineByName("nashorn"); 3.183 + 3.184 + try { 3.185 + Object obj = engine1.eval("({ run: function() {} })"); 3.186 + // pass object from engine1 to engine2 as 'thiz' for invokeMethod 3.187 + ((Invocable) engine2).invokeMethod(obj, "run"); 3.188 + fail("should have thrown IllegalArgumentException"); 3.189 + } catch (final Exception exp) { 3.190 + if (!(exp instanceof IllegalArgumentException)) { 3.191 + exp.printStackTrace(); 3.192 + fail(exp.getMessage()); 3.193 + } 3.194 + } 3.195 + } 3.196 + 3.197 + @Test 3.198 + public void getInterfaceTest() { 3.199 + final ScriptEngineManager m = new ScriptEngineManager(); 3.200 + final ScriptEngine e = m.getEngineByName("nashorn"); 3.201 + final Invocable inv = (Invocable) e; 3.202 + 3.203 + // try to get interface from global functions 3.204 + try { 3.205 + e.eval("function run() { print('run'); };"); 3.206 + final Runnable runnable = inv.getInterface(Runnable.class); 3.207 + runnable.run(); 3.208 + } catch (final Exception exp) { 3.209 + exp.printStackTrace(); 3.210 + fail(exp.getMessage()); 3.211 + } 3.212 + 3.213 + // try interface on specific script object 3.214 + try { 3.215 + e.eval("var obj = { run: function() { print('run from obj'); } };"); 3.216 + Object obj = e.get("obj"); 3.217 + final Runnable runnable = inv.getInterface(obj, Runnable.class); 3.218 + runnable.run(); 3.219 + } catch (final Exception exp) { 3.220 + exp.printStackTrace(); 3.221 + fail(exp.getMessage()); 3.222 + } 3.223 + } 3.224 + 3.225 + public interface Foo { 3.226 + 3.227 + public void bar(); 3.228 + } 3.229 + 3.230 + public interface Foo2 extends Foo { 3.231 + 3.232 + public void bar2(); 3.233 + } 3.234 + 3.235 + @Test 3.236 + public void getInterfaceMissingTest() { 3.237 + final ScriptEngineManager manager = new ScriptEngineManager(); 3.238 + final ScriptEngine engine = manager.getEngineByName("nashorn"); 3.239 + 3.240 + // don't define any function. 3.241 + try { 3.242 + engine.eval(""); 3.243 + } catch (final Exception exp) { 3.244 + exp.printStackTrace(); 3.245 + fail(exp.getMessage()); 3.246 + } 3.247 + 3.248 + Runnable runnable = ((Invocable) engine).getInterface(Runnable.class); 3.249 + if (runnable != null) { 3.250 + fail("runnable is not null!"); 3.251 + } 3.252 + 3.253 + // now define "run" 3.254 + try { 3.255 + engine.eval("function run() { print('this is run function'); }"); 3.256 + } catch (final Exception exp) { 3.257 + exp.printStackTrace(); 3.258 + fail(exp.getMessage()); 3.259 + } 3.260 + runnable = ((Invocable) engine).getInterface(Runnable.class); 3.261 + // should not return null now! 3.262 + runnable.run(); 3.263 + 3.264 + // define only one method of "Foo2" 3.265 + try { 3.266 + engine.eval("function bar() { print('bar function'); }"); 3.267 + } catch (final Exception exp) { 3.268 + exp.printStackTrace(); 3.269 + fail(exp.getMessage()); 3.270 + } 3.271 + 3.272 + Foo2 foo2 = ((Invocable) engine).getInterface(Foo2.class); 3.273 + if (foo2 != null) { 3.274 + throw new RuntimeException("foo2 is not null!"); 3.275 + } 3.276 + 3.277 + // now define other method of "Foo2" 3.278 + try { 3.279 + engine.eval("function bar2() { print('bar2 function'); }"); 3.280 + } catch (final Exception exp) { 3.281 + exp.printStackTrace(); 3.282 + fail(exp.getMessage()); 3.283 + } 3.284 + foo2 = ((Invocable) engine).getInterface(Foo2.class); 3.285 + foo2.bar(); 3.286 + foo2.bar2(); 3.287 + } 3.288 + 3.289 + @Test 3.290 + /** 3.291 + * Try passing non-interface Class object for interface implementation. 3.292 + */ 3.293 + public void getNonInterfaceGetInterfaceTest() { 3.294 + final ScriptEngineManager manager = new ScriptEngineManager(); 3.295 + final ScriptEngine engine = manager.getEngineByName("nashorn"); 3.296 + try { 3.297 + log(Objects.toString(((Invocable) engine).getInterface(Object.class))); 3.298 + fail("Should have thrown IllegalArgumentException"); 3.299 + } catch (final Exception exp) { 3.300 + if (!(exp instanceof IllegalArgumentException)) { 3.301 + fail("IllegalArgumentException expected, got " + exp); 3.302 + } 3.303 + } 3.304 + } 3.305 + 3.306 + @Test 3.307 + /** 3.308 + * Check that we can get interface out of a script object even after 3.309 + * switching to use different ScriptContext. 3.310 + */ 3.311 + public void getInterfaceDifferentContext() { 3.312 + ScriptEngineManager m = new ScriptEngineManager(); 3.313 + ScriptEngine e = m.getEngineByName("nashorn"); 3.314 + try { 3.315 + Object obj = e.eval("({ run: function() { } })"); 3.316 + 3.317 + // change script context 3.318 + ScriptContext ctxt = new SimpleScriptContext(); 3.319 + ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE); 3.320 + e.setContext(ctxt); 3.321 + 3.322 + Runnable r = ((Invocable) e).getInterface(obj, Runnable.class); 3.323 + r.run(); 3.324 + } catch (final Exception exp) { 3.325 + exp.printStackTrace(); 3.326 + fail(exp.getMessage()); 3.327 + } 3.328 + } 3.329 + 3.330 + @Test 3.331 + /** 3.332 + * Check that getInterface on non-script object 'thiz' results in 3.333 + * IllegalArgumentException. 3.334 + */ 3.335 + public void getInterfaceNonScriptObjectThizTest() { 3.336 + final ScriptEngineManager m = new ScriptEngineManager(); 3.337 + final ScriptEngine e = m.getEngineByName("nashorn"); 3.338 + 3.339 + try { 3.340 + ((Invocable) e).getInterface(new Object(), Runnable.class); 3.341 + fail("should have thrown IllegalArgumentException"); 3.342 + } catch (final Exception exp) { 3.343 + if (!(exp instanceof IllegalArgumentException)) { 3.344 + exp.printStackTrace(); 3.345 + fail(exp.getMessage()); 3.346 + } 3.347 + } 3.348 + } 3.349 + 3.350 + @Test 3.351 + /** 3.352 + * Check that getInterface on null 'thiz' results in 3.353 + * IllegalArgumentException. 3.354 + */ 3.355 + public void getInterfaceNullThizTest() { 3.356 + final ScriptEngineManager m = new ScriptEngineManager(); 3.357 + final ScriptEngine e = m.getEngineByName("nashorn"); 3.358 + 3.359 + try { 3.360 + ((Invocable) e).getInterface(null, Runnable.class); 3.361 + fail("should have thrown IllegalArgumentException"); 3.362 + } catch (final Exception exp) { 3.363 + if (!(exp instanceof IllegalArgumentException)) { 3.364 + exp.printStackTrace(); 3.365 + fail(exp.getMessage()); 3.366 + } 3.367 + } 3.368 + } 3.369 + 3.370 + @Test 3.371 + /** 3.372 + * Check that calling getInterface on mirror created by another engine 3.373 + * results in IllegalArgumentException. 3.374 + */ 3.375 + public void getInterfaceMixEnginesTest() { 3.376 + final ScriptEngineManager m = new ScriptEngineManager(); 3.377 + final ScriptEngine engine1 = m.getEngineByName("nashorn"); 3.378 + final ScriptEngine engine2 = m.getEngineByName("nashorn"); 3.379 + 3.380 + try { 3.381 + Object obj = engine1.eval("({ run: function() {} })"); 3.382 + // pass object from engine1 to engine2 as 'thiz' for getInterface 3.383 + ((Invocable) engine2).getInterface(obj, Runnable.class); 3.384 + fail("should have thrown IllegalArgumentException"); 3.385 + } catch (final Exception exp) { 3.386 + if (!(exp instanceof IllegalArgumentException)) { 3.387 + exp.printStackTrace(); 3.388 + fail(exp.getMessage()); 3.389 + } 3.390 + } 3.391 + } 3.392 + 3.393 + @Test 3.394 + /** 3.395 + * check that null function name results in NPE. 3.396 + */ 3.397 + public void invokeFunctionNullNameTest() { 3.398 + final ScriptEngineManager m = new ScriptEngineManager(); 3.399 + final ScriptEngine e = m.getEngineByName("nashorn"); 3.400 + 3.401 + try { 3.402 + final Object res = ((Invocable) e).invokeFunction(null); 3.403 + fail("should have thrown NPE"); 3.404 + } catch (final Exception exp) { 3.405 + if (!(exp instanceof NullPointerException)) { 3.406 + exp.printStackTrace(); 3.407 + fail(exp.getMessage()); 3.408 + } 3.409 + } 3.410 + } 3.411 + 3.412 + @Test 3.413 + /** 3.414 + * Check that attempt to call missing function results in 3.415 + * NoSuchMethodException. 3.416 + */ 3.417 + public void invokeFunctionMissingTest() { 3.418 + final ScriptEngineManager m = new ScriptEngineManager(); 3.419 + final ScriptEngine e = m.getEngineByName("nashorn"); 3.420 + 3.421 + try { 3.422 + final Object res = ((Invocable) e).invokeFunction("NonExistentFunc"); 3.423 + fail("should have thrown NoSuchMethodException"); 3.424 + } catch (final Exception exp) { 3.425 + if (!(exp instanceof NoSuchMethodException)) { 3.426 + exp.printStackTrace(); 3.427 + fail(exp.getMessage()); 3.428 + } 3.429 + } 3.430 + } 3.431 + 3.432 + @Test 3.433 + /** 3.434 + * Check that invokeFunction calls functions only from current context's 3.435 + * Bindings. 3.436 + */ 3.437 + public void invokeFunctionDifferentContextTest() { 3.438 + ScriptEngineManager m = new ScriptEngineManager(); 3.439 + ScriptEngine e = m.getEngineByName("nashorn"); 3.440 + 3.441 + try { 3.442 + // define an object with method on it 3.443 + Object obj = e.eval("function hello() { return 'Hello World!'; }"); 3.444 + final ScriptContext ctxt = new SimpleScriptContext(); 3.445 + ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE); 3.446 + // change engine's current context 3.447 + e.setContext(ctxt); 3.448 + 3.449 + ((Invocable) e).invokeFunction("hello"); // no 'hello' in new context! 3.450 + fail("should have thrown NoSuchMethodException"); 3.451 + } catch (final Exception exp) { 3.452 + if (!(exp instanceof NoSuchMethodException)) { 3.453 + exp.printStackTrace(); 3.454 + fail(exp.getMessage()); 3.455 + } 3.456 + } 3.457 + } 3.458 + 3.459 + @Test 3.460 + public void invokeFunctionExceptionTest() { 3.461 + final ScriptEngineManager m = new ScriptEngineManager(); 3.462 + final ScriptEngine e = m.getEngineByName("nashorn"); 3.463 + try { 3.464 + e.eval("function func() { throw new TypeError(); }"); 3.465 + } catch (final Throwable t) { 3.466 + t.printStackTrace(); 3.467 + fail(t.getMessage()); 3.468 + } 3.469 + 3.470 + try { 3.471 + ((Invocable) e).invokeFunction("func"); 3.472 + fail("should have thrown exception"); 3.473 + } catch (final ScriptException se) { 3.474 + // ECMA TypeError property wrapped as a ScriptException 3.475 + log("got " + se + " as expected"); 3.476 + } catch (final Throwable t) { 3.477 + t.printStackTrace(); 3.478 + fail(t.getMessage()); 3.479 + } 3.480 + } 3.481 + 3.482 + @Test 3.483 + public void invokeMethodExceptionTest() { 3.484 + final ScriptEngineManager m = new ScriptEngineManager(); 3.485 + final ScriptEngine e = m.getEngineByName("nashorn"); 3.486 + try { 3.487 + e.eval("var sobj = {}; sobj.foo = function func() { throw new TypeError(); }"); 3.488 + } catch (final Throwable t) { 3.489 + t.printStackTrace(); 3.490 + fail(t.getMessage()); 3.491 + } 3.492 + 3.493 + try { 3.494 + final Object sobj = e.get("sobj"); 3.495 + ((Invocable) e).invokeMethod(sobj, "foo"); 3.496 + fail("should have thrown exception"); 3.497 + } catch (final ScriptException se) { 3.498 + // ECMA TypeError property wrapped as a ScriptException 3.499 + log("got " + se + " as expected"); 3.500 + } catch (final Throwable t) { 3.501 + t.printStackTrace(); 3.502 + fail(t.getMessage()); 3.503 + } 3.504 + } 3.505 + 3.506 + @Test 3.507 + /** 3.508 + * Tests whether invocation of a JavaScript method through a variable arity 3.509 + * Java method will pass the vararg array. Both non-vararg and vararg 3.510 + * JavaScript methods are tested. 3.511 + * 3.512 + * @throws ScriptException 3.513 + */ 3.514 + public void variableArityInterfaceTest() throws ScriptException { 3.515 + final ScriptEngineManager m = new ScriptEngineManager(); 3.516 + final ScriptEngine e = m.getEngineByName("nashorn"); 3.517 + e.eval( 3.518 + "function test1(i, strings) {" 3.519 + + " return 'i == ' + i + ', strings instanceof java.lang.String[] == ' + (strings instanceof Java.type('java.lang.String[]')) + ', strings == ' + java.util.Arrays.toString(strings)" 3.520 + + "}" 3.521 + + "function test2() {" 3.522 + + " return 'arguments[0] == ' + arguments[0] + ', arguments[1] instanceof java.lang.String[] == ' + (arguments[1] instanceof Java.type('java.lang.String[]')) + ', arguments[1] == ' + java.util.Arrays.toString(arguments[1])" 3.523 + + "}"); 3.524 + final VariableArityTestInterface itf = ((Invocable) e).getInterface(VariableArityTestInterface.class); 3.525 + Assert.assertEquals(itf.test1(42, "a", "b"), "i == 42, strings instanceof java.lang.String[] == true, strings == [a, b]"); 3.526 + Assert.assertEquals(itf.test2(44, "c", "d", "e"), "arguments[0] == 44, arguments[1] instanceof java.lang.String[] == true, arguments[1] == [c, d, e]"); 3.527 + } 3.528 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/test/src/jdk/nashorn/api/scripting/ScopeTest.java Fri Aug 23 16:10:37 2013 +0530 4.3 @@ -0,0 +1,248 @@ 4.4 +/* 4.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.7 + * 4.8 + * This code is free software; you can redistribute it and/or modify it 4.9 + * under the terms of the GNU General Public License version 2 only, as 4.10 + * published by the Free Software Foundation. Oracle designates this 4.11 + * particular file as subject to the "Classpath" exception as provided 4.12 + * by Oracle in the LICENSE file that accompanied this code. 4.13 + * 4.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 4.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 4.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 4.17 + * version 2 for more details (a copy is included in the LICENSE file that 4.18 + * accompanied this code). 4.19 + * 4.20 + * You should have received a copy of the GNU General Public License version 4.21 + * 2 along with this work; if not, write to the Free Software Foundation, 4.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 4.23 + * 4.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 4.25 + * or visit www.oracle.com if you need additional information or have any 4.26 + * questions. 4.27 + */ 4.28 +package jdk.nashorn.api.scripting; 4.29 + 4.30 +import javax.script.Bindings; 4.31 +import javax.script.ScriptContext; 4.32 +import javax.script.ScriptEngine; 4.33 +import javax.script.ScriptEngineManager; 4.34 +import javax.script.ScriptException; 4.35 +import javax.script.SimpleBindings; 4.36 +import javax.script.SimpleScriptContext; 4.37 +import org.testng.Assert; 4.38 +import static org.testng.Assert.assertEquals; 4.39 +import static org.testng.Assert.assertNotNull; 4.40 +import static org.testng.Assert.assertTrue; 4.41 +import static org.testng.Assert.fail; 4.42 +import org.testng.annotations.Test; 4.43 + 4.44 +/** 4.45 + * Tests for jsr223 Bindings "scope" (engine, global scopes) 4.46 + */ 4.47 +public class ScopeTest { 4.48 + 4.49 + @Test 4.50 + public void createBindingsTest() { 4.51 + final ScriptEngineManager m = new ScriptEngineManager(); 4.52 + final ScriptEngine e = m.getEngineByName("nashorn"); 4.53 + Bindings b = e.createBindings(); 4.54 + b.put("foo", 42.0); 4.55 + Object res = null; 4.56 + try { 4.57 + res = e.eval("foo == 42.0", b); 4.58 + } catch (final ScriptException | NullPointerException se) { 4.59 + se.printStackTrace(); 4.60 + fail(se.getMessage()); 4.61 + } 4.62 + 4.63 + assertEquals(res, Boolean.TRUE); 4.64 + } 4.65 + 4.66 + @Test 4.67 + public void engineScopeTest() { 4.68 + final ScriptEngineManager m = new ScriptEngineManager(); 4.69 + final ScriptEngine e = m.getEngineByName("nashorn"); 4.70 + Bindings engineScope = e.getBindings(ScriptContext.ENGINE_SCOPE); 4.71 + 4.72 + // check few ECMA standard built-in global properties 4.73 + assertNotNull(engineScope.get("Object")); 4.74 + assertNotNull(engineScope.get("TypeError")); 4.75 + assertNotNull(engineScope.get("eval")); 4.76 + 4.77 + // can access via ScriptEngine.get as well 4.78 + assertNotNull(e.get("Object")); 4.79 + assertNotNull(e.get("TypeError")); 4.80 + assertNotNull(e.get("eval")); 4.81 + 4.82 + // Access by either way should return same object 4.83 + assertEquals(engineScope.get("Array"), e.get("Array")); 4.84 + assertEquals(engineScope.get("EvalError"), e.get("EvalError")); 4.85 + assertEquals(engineScope.get("undefined"), e.get("undefined")); 4.86 + 4.87 + // try exposing a new variable from scope 4.88 + engineScope.put("myVar", "foo"); 4.89 + try { 4.90 + assertEquals(e.eval("myVar"), "foo"); 4.91 + } catch (final ScriptException se) { 4.92 + se.printStackTrace(); 4.93 + fail(se.getMessage()); 4.94 + } 4.95 + 4.96 + // update "myVar" in script an check the value from scope 4.97 + try { 4.98 + e.eval("myVar = 'nashorn';"); 4.99 + } catch (final ScriptException se) { 4.100 + se.printStackTrace(); 4.101 + fail(se.getMessage()); 4.102 + } 4.103 + 4.104 + // now check modified value from scope and engine 4.105 + assertEquals(engineScope.get("myVar"), "nashorn"); 4.106 + assertEquals(e.get("myVar"), "nashorn"); 4.107 + } 4.108 + 4.109 + @Test 4.110 + public void multiGlobalTest() { 4.111 + final ScriptEngineManager m = new ScriptEngineManager(); 4.112 + final ScriptEngine e = m.getEngineByName("nashorn"); 4.113 + final Bindings b = e.createBindings(); 4.114 + final ScriptContext newCtxt = new SimpleScriptContext(); 4.115 + newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); 4.116 + 4.117 + try { 4.118 + Object obj1 = e.eval("Object"); 4.119 + Object obj2 = e.eval("Object", newCtxt); 4.120 + Assert.assertNotEquals(obj1, obj2); 4.121 + Assert.assertNotNull(obj1); 4.122 + Assert.assertNotNull(obj2); 4.123 + Assert.assertEquals(obj1.toString(), obj2.toString()); 4.124 + 4.125 + e.eval("x = 'hello'"); 4.126 + e.eval("x = 'world'", newCtxt); 4.127 + Object x1 = e.getContext().getAttribute("x"); 4.128 + Object x2 = newCtxt.getAttribute("x"); 4.129 + Assert.assertNotEquals(x1, x2); 4.130 + Assert.assertEquals(x1, "hello"); 4.131 + Assert.assertEquals(x2, "world"); 4.132 + 4.133 + x1 = e.eval("x"); 4.134 + x2 = e.eval("x", newCtxt); 4.135 + Assert.assertNotEquals(x1, x2); 4.136 + Assert.assertEquals(x1, "hello"); 4.137 + Assert.assertEquals(x2, "world"); 4.138 + 4.139 + final ScriptContext origCtxt = e.getContext(); 4.140 + e.setContext(newCtxt); 4.141 + e.eval("y = new Object()"); 4.142 + e.eval("y = new Object()", origCtxt); 4.143 + 4.144 + Object y1 = origCtxt.getAttribute("y"); 4.145 + Object y2 = newCtxt.getAttribute("y"); 4.146 + Assert.assertNotEquals(y1, y2); 4.147 + Assert.assertNotEquals(e.eval("y"), e.eval("y", origCtxt)); 4.148 + Assert.assertEquals("[object Object]", y1.toString()); 4.149 + Assert.assertEquals("[object Object]", y2.toString()); 4.150 + } catch (final ScriptException se) { 4.151 + se.printStackTrace(); 4.152 + fail(se.getMessage()); 4.153 + } 4.154 + } 4.155 + 4.156 + @Test 4.157 + public void userEngineScopeBindingsTest() throws ScriptException { 4.158 + final ScriptEngineManager m = new ScriptEngineManager(); 4.159 + final ScriptEngine e = m.getEngineByName("nashorn"); 4.160 + e.eval("function func() {}"); 4.161 + 4.162 + final ScriptContext newContext = new SimpleScriptContext(); 4.163 + newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE); 4.164 + // we are using a new bindings - so it should have 'func' defined 4.165 + Object value = e.eval("typeof func", newContext); 4.166 + assertTrue(value.equals("undefined")); 4.167 + } 4.168 + 4.169 + @Test 4.170 + public void userEngineScopeBindingsNoLeakTest() throws ScriptException { 4.171 + final ScriptEngineManager m = new ScriptEngineManager(); 4.172 + final ScriptEngine e = m.getEngineByName("nashorn"); 4.173 + final ScriptContext newContext = new SimpleScriptContext(); 4.174 + newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE); 4.175 + e.eval("function foo() {}", newContext); 4.176 + 4.177 + // in the default context's ENGINE_SCOPE, 'foo' shouldn't exist 4.178 + assertTrue(e.eval("typeof foo").equals("undefined")); 4.179 + } 4.180 + 4.181 + @Test 4.182 + public void userEngineScopeBindingsRetentionTest() throws ScriptException { 4.183 + final ScriptEngineManager m = new ScriptEngineManager(); 4.184 + final ScriptEngine e = m.getEngineByName("nashorn"); 4.185 + final ScriptContext newContext = new SimpleScriptContext(); 4.186 + newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE); 4.187 + e.eval("function foo() {}", newContext); 4.188 + 4.189 + // definition retained with user's ENGINE_SCOPE Binding 4.190 + assertTrue(e.eval("typeof foo", newContext).equals("function")); 4.191 + 4.192 + final Bindings oldBindings = newContext.getBindings(ScriptContext.ENGINE_SCOPE); 4.193 + // but not in another ENGINE_SCOPE binding 4.194 + newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE); 4.195 + assertTrue(e.eval("typeof foo", newContext).equals("undefined")); 4.196 + 4.197 + // restore ENGINE_SCOPE and check again 4.198 + newContext.setBindings(oldBindings, ScriptContext.ENGINE_SCOPE); 4.199 + assertTrue(e.eval("typeof foo", newContext).equals("function")); 4.200 + } 4.201 + 4.202 + @Test 4.203 + // check that engine.js definitions are visible in all new global instances 4.204 + public void checkBuiltinsInNewBindingsTest() throws ScriptException { 4.205 + final ScriptEngineManager m = new ScriptEngineManager(); 4.206 + final ScriptEngine e = m.getEngineByName("nashorn"); 4.207 + 4.208 + // check default global instance has engine.js definitions 4.209 + final Bindings g = (Bindings) e.eval("this"); 4.210 + Object value = g.get("__noSuchProperty__"); 4.211 + assertTrue(value instanceof ScriptObjectMirror && ((ScriptObjectMirror)value).isFunction()); 4.212 + value = g.get("print"); 4.213 + assertTrue(value instanceof ScriptObjectMirror && ((ScriptObjectMirror)value).isFunction()); 4.214 + 4.215 + // check new global instance created has engine.js definitions 4.216 + Bindings b = e.createBindings(); 4.217 + value = b.get("__noSuchProperty__"); 4.218 + assertTrue(value instanceof ScriptObjectMirror && ((ScriptObjectMirror)value).isFunction()); 4.219 + value = b.get("print"); 4.220 + assertTrue(value instanceof ScriptObjectMirror && ((ScriptObjectMirror)value).isFunction()); 4.221 + 4.222 + // put a mapping into GLOBAL_SCOPE 4.223 + final Bindings globalScope = e.getContext().getBindings(ScriptContext.GLOBAL_SCOPE); 4.224 + globalScope.put("x", "hello"); 4.225 + 4.226 + // GLOBAL_SCOPE mapping should be visible from default ScriptContext eval 4.227 + assertTrue(e.eval("x").equals("hello")); 4.228 + 4.229 + final ScriptContext ctx = new SimpleScriptContext(); 4.230 + ctx.setBindings(globalScope, ScriptContext.GLOBAL_SCOPE); 4.231 + ctx.setBindings(b, ScriptContext.ENGINE_SCOPE); 4.232 + 4.233 + // GLOBAL_SCOPE mapping should be visible from non-default ScriptContext eval 4.234 + assertTrue(e.eval("x", ctx).equals("hello")); 4.235 + 4.236 + // try some arbitray Bindings for ENGINE_SCOPE 4.237 + Bindings sb = new SimpleBindings(); 4.238 + ctx.setBindings(sb, ScriptContext.ENGINE_SCOPE); 4.239 + 4.240 + // GLOBAL_SCOPE mapping should be visible from non-default ScriptContext eval 4.241 + assertTrue(e.eval("x", ctx).equals("hello")); 4.242 + 4.243 + // engine.js builtins are still defined even with arbitrary Bindings 4.244 + assertTrue(e.eval("typeof print", ctx).equals("function")); 4.245 + assertTrue(e.eval("typeof __noSuchProperty__", ctx).equals("function")); 4.246 + 4.247 + // ENGINE_SCOPE definition should 'hide' GLOBAL_SCOPE definition 4.248 + sb.put("x", "newX"); 4.249 + assertTrue(e.eval("x", ctx).equals("newX")); 4.250 + } 4.251 +}
5.1 --- a/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Thu Aug 22 22:32:16 2013 +0530 5.2 +++ b/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Fri Aug 23 16:10:37 2013 +0530 5.3 @@ -26,7 +26,6 @@ 5.4 package jdk.nashorn.api.scripting; 5.5 5.6 import static org.testng.Assert.assertEquals; 5.7 -import static org.testng.Assert.assertFalse; 5.8 import static org.testng.Assert.assertNotNull; 5.9 import static org.testng.Assert.assertTrue; 5.10 import static org.testng.Assert.fail; 5.11 @@ -34,22 +33,13 @@ 5.12 import java.io.StringReader; 5.13 import java.io.StringWriter; 5.14 import java.lang.reflect.Method; 5.15 -import java.util.HashMap; 5.16 -import java.util.Map; 5.17 -import java.util.Objects; 5.18 import java.util.concurrent.Callable; 5.19 -import javax.script.Bindings; 5.20 import javax.script.Compilable; 5.21 import javax.script.CompiledScript; 5.22 -import javax.script.Invocable; 5.23 -import javax.script.ScriptContext; 5.24 import javax.script.ScriptEngine; 5.25 import javax.script.ScriptEngineFactory; 5.26 import javax.script.ScriptEngineManager; 5.27 import javax.script.ScriptException; 5.28 -import javax.script.SimpleBindings; 5.29 -import javax.script.SimpleScriptContext; 5.30 -import org.testng.Assert; 5.31 import org.testng.annotations.Test; 5.32 5.33 /** 5.34 @@ -240,214 +230,6 @@ 5.35 } 5.36 5.37 @Test 5.38 - public void createBindingsTest() { 5.39 - final ScriptEngineManager m = new ScriptEngineManager(); 5.40 - final ScriptEngine e = m.getEngineByName("nashorn"); 5.41 - Bindings b = e.createBindings(); 5.42 - b.put("foo", 42.0); 5.43 - Object res = null; 5.44 - try { 5.45 - res = e.eval("foo == 42.0", b); 5.46 - } catch (final ScriptException | NullPointerException se) { 5.47 - se.printStackTrace(); 5.48 - fail(se.getMessage()); 5.49 - } 5.50 - 5.51 - assertEquals(res, Boolean.TRUE); 5.52 - } 5.53 - 5.54 - @Test 5.55 - public void getInterfaceTest() { 5.56 - final ScriptEngineManager m = new ScriptEngineManager(); 5.57 - final ScriptEngine e = m.getEngineByName("nashorn"); 5.58 - final Invocable inv = (Invocable)e; 5.59 - 5.60 - // try to get interface from global functions 5.61 - try { 5.62 - e.eval("function run() { print('run'); };"); 5.63 - final Runnable runnable = inv.getInterface(Runnable.class); 5.64 - runnable.run(); 5.65 - } catch (final Exception exp) { 5.66 - exp.printStackTrace(); 5.67 - fail(exp.getMessage()); 5.68 - } 5.69 - 5.70 - // try interface on specific script object 5.71 - try { 5.72 - e.eval("var obj = { run: function() { print('run from obj'); } };"); 5.73 - Object obj = e.get("obj"); 5.74 - final Runnable runnable = inv.getInterface(obj, Runnable.class); 5.75 - runnable.run(); 5.76 - } catch (final Exception exp) { 5.77 - exp.printStackTrace(); 5.78 - fail(exp.getMessage()); 5.79 - } 5.80 - } 5.81 - 5.82 - public interface Foo { 5.83 - public void bar(); 5.84 - } 5.85 - 5.86 - public interface Foo2 extends Foo { 5.87 - public void bar2(); 5.88 - } 5.89 - 5.90 - @Test 5.91 - public void getInterfaceMissingTest() { 5.92 - final ScriptEngineManager manager = new ScriptEngineManager(); 5.93 - final ScriptEngine engine = manager.getEngineByName("nashorn"); 5.94 - 5.95 - // don't define any function. 5.96 - try { 5.97 - engine.eval(""); 5.98 - } catch (final Exception exp) { 5.99 - exp.printStackTrace(); 5.100 - fail(exp.getMessage()); 5.101 - } 5.102 - 5.103 - Runnable runnable = ((Invocable)engine).getInterface(Runnable.class); 5.104 - if (runnable != null) { 5.105 - fail("runnable is not null!"); 5.106 - } 5.107 - 5.108 - // now define "run" 5.109 - try { 5.110 - engine.eval("function run() { print('this is run function'); }"); 5.111 - } catch (final Exception exp) { 5.112 - exp.printStackTrace(); 5.113 - fail(exp.getMessage()); 5.114 - } 5.115 - runnable = ((Invocable)engine).getInterface(Runnable.class); 5.116 - // should not return null now! 5.117 - runnable.run(); 5.118 - 5.119 - // define only one method of "Foo2" 5.120 - try { 5.121 - engine.eval("function bar() { print('bar function'); }"); 5.122 - } catch (final Exception exp) { 5.123 - exp.printStackTrace(); 5.124 - fail(exp.getMessage()); 5.125 - } 5.126 - 5.127 - Foo2 foo2 = ((Invocable)engine).getInterface(Foo2.class); 5.128 - if (foo2 != null) { 5.129 - throw new RuntimeException("foo2 is not null!"); 5.130 - } 5.131 - 5.132 - // now define other method of "Foo2" 5.133 - try { 5.134 - engine.eval("function bar2() { print('bar2 function'); }"); 5.135 - } catch (final Exception exp) { 5.136 - exp.printStackTrace(); 5.137 - fail(exp.getMessage()); 5.138 - } 5.139 - foo2 = ((Invocable)engine).getInterface(Foo2.class); 5.140 - foo2.bar(); 5.141 - foo2.bar2(); 5.142 - } 5.143 - 5.144 - @Test 5.145 - /** 5.146 - * Try passing non-interface Class object for interface implementation. 5.147 - */ 5.148 - public void getNonInterfaceGetInterfaceTest() { 5.149 - final ScriptEngineManager manager = new ScriptEngineManager(); 5.150 - final ScriptEngine engine = manager.getEngineByName("nashorn"); 5.151 - try { 5.152 - log(Objects.toString(((Invocable)engine).getInterface(Object.class))); 5.153 - fail("Should have thrown IllegalArgumentException"); 5.154 - } catch (final Exception exp) { 5.155 - if (! (exp instanceof IllegalArgumentException)) { 5.156 - fail("IllegalArgumentException expected, got " + exp); 5.157 - } 5.158 - } 5.159 - } 5.160 - 5.161 - @Test 5.162 - /** 5.163 - * Check that we can get interface out of a script object even after 5.164 - * switching to use different ScriptContext. 5.165 - */ 5.166 - public void getInterfaceDifferentContext() { 5.167 - ScriptEngineManager m = new ScriptEngineManager(); 5.168 - ScriptEngine e = m.getEngineByName("nashorn"); 5.169 - try { 5.170 - Object obj = e.eval("({ run: function() { } })"); 5.171 - 5.172 - // change script context 5.173 - ScriptContext ctxt = new SimpleScriptContext(); 5.174 - ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE); 5.175 - e.setContext(ctxt); 5.176 - 5.177 - Runnable r = ((Invocable)e).getInterface(obj, Runnable.class); 5.178 - r.run(); 5.179 - }catch (final Exception exp) { 5.180 - exp.printStackTrace(); 5.181 - fail(exp.getMessage()); 5.182 - } 5.183 - } 5.184 - 5.185 - @Test 5.186 - /** 5.187 - * Check that getInterface on non-script object 'thiz' results in IllegalArgumentException. 5.188 - */ 5.189 - public void getInterfaceNonScriptObjectThizTest() { 5.190 - final ScriptEngineManager m = new ScriptEngineManager(); 5.191 - final ScriptEngine e = m.getEngineByName("nashorn"); 5.192 - 5.193 - try { 5.194 - ((Invocable)e).getInterface(new Object(), Runnable.class); 5.195 - fail("should have thrown IllegalArgumentException"); 5.196 - } catch (final Exception exp) { 5.197 - if (! (exp instanceof IllegalArgumentException)) { 5.198 - exp.printStackTrace(); 5.199 - fail(exp.getMessage()); 5.200 - } 5.201 - } 5.202 - } 5.203 - 5.204 - @Test 5.205 - /** 5.206 - * Check that getInterface on null 'thiz' results in IllegalArgumentException. 5.207 - */ 5.208 - public void getInterfaceNullThizTest() { 5.209 - final ScriptEngineManager m = new ScriptEngineManager(); 5.210 - final ScriptEngine e = m.getEngineByName("nashorn"); 5.211 - 5.212 - try { 5.213 - ((Invocable)e).getInterface(null, Runnable.class); 5.214 - fail("should have thrown IllegalArgumentException"); 5.215 - } catch (final Exception exp) { 5.216 - if (! (exp instanceof IllegalArgumentException)) { 5.217 - exp.printStackTrace(); 5.218 - fail(exp.getMessage()); 5.219 - } 5.220 - } 5.221 - } 5.222 - 5.223 - @Test 5.224 - /** 5.225 - * Check that calling getInterface on mirror created by another engine results in IllegalArgumentException. 5.226 - */ 5.227 - public void getInterfaceMixEnginesTest() { 5.228 - final ScriptEngineManager m = new ScriptEngineManager(); 5.229 - final ScriptEngine engine1 = m.getEngineByName("nashorn"); 5.230 - final ScriptEngine engine2 = m.getEngineByName("nashorn"); 5.231 - 5.232 - try { 5.233 - Object obj = engine1.eval("({ run: function() {} })"); 5.234 - // pass object from engine1 to engine2 as 'thiz' for getInterface 5.235 - ((Invocable)engine2).getInterface(obj, Runnable.class); 5.236 - fail("should have thrown IllegalArgumentException"); 5.237 - } catch (final Exception exp) { 5.238 - if (! (exp instanceof IllegalArgumentException)) { 5.239 - exp.printStackTrace(); 5.240 - fail(exp.getMessage()); 5.241 - } 5.242 - } 5.243 - } 5.244 - 5.245 - @Test 5.246 public void accessGlobalTest() { 5.247 final ScriptEngineManager m = new ScriptEngineManager(); 5.248 final ScriptEngine e = m.getEngineByName("nashorn"); 5.249 @@ -622,88 +404,6 @@ 5.250 assertEquals(sw.toString().replaceAll("\r", ""), "hello world\n"); 5.251 } 5.252 5.253 - @SuppressWarnings("unchecked") 5.254 - @Test 5.255 - public void reflectionTest() throws ScriptException { 5.256 - final ScriptEngineManager m = new ScriptEngineManager(); 5.257 - final ScriptEngine e = m.getEngineByName("nashorn"); 5.258 - 5.259 - e.eval("var obj = { x: 344, y: 'nashorn' }"); 5.260 - 5.261 - int count = 0; 5.262 - Map<Object, Object> map = (Map<Object, Object>)e.get("obj"); 5.263 - assertFalse(map.isEmpty()); 5.264 - assertTrue(map.keySet().contains("x")); 5.265 - assertTrue(map.containsKey("x")); 5.266 - assertTrue(map.values().contains("nashorn")); 5.267 - assertTrue(map.containsValue("nashorn")); 5.268 - for (final Map.Entry<?, ?> ex : map.entrySet()) { 5.269 - final Object key = ex.getKey(); 5.270 - if (key.equals("x")) { 5.271 - assertTrue(344 == ((Number)ex.getValue()).doubleValue()); 5.272 - count++; 5.273 - } else if (key.equals("y")) { 5.274 - assertEquals(ex.getValue(), "nashorn"); 5.275 - count++; 5.276 - } 5.277 - } 5.278 - assertEquals(2, count); 5.279 - assertEquals(2, map.size()); 5.280 - 5.281 - // add property 5.282 - map.put("z", "hello"); 5.283 - assertEquals(e.eval("obj.z"), "hello"); 5.284 - assertEquals(map.get("z"), "hello"); 5.285 - assertTrue(map.keySet().contains("z")); 5.286 - assertTrue(map.containsKey("z")); 5.287 - assertTrue(map.values().contains("hello")); 5.288 - assertTrue(map.containsValue("hello")); 5.289 - assertEquals(map.size(), 3); 5.290 - 5.291 - final Map<Object, Object> newMap = new HashMap<>(); 5.292 - newMap.put("foo", 23.0); 5.293 - newMap.put("bar", true); 5.294 - map.putAll(newMap); 5.295 - 5.296 - assertEquals(e.eval("obj.foo"), 23.0); 5.297 - assertEquals(e.eval("obj.bar"), true); 5.298 - 5.299 - // remove using map method 5.300 - map.remove("foo"); 5.301 - assertEquals(e.eval("typeof obj.foo"), "undefined"); 5.302 - 5.303 - count = 0; 5.304 - e.eval("var arr = [ true, 'hello' ]"); 5.305 - map = (Map<Object, Object>)e.get("arr"); 5.306 - assertFalse(map.isEmpty()); 5.307 - assertTrue(map.containsKey("length")); 5.308 - assertTrue(map.containsValue("hello")); 5.309 - for (final Map.Entry<?, ?> ex : map.entrySet()) { 5.310 - final Object key = ex.getKey(); 5.311 - if (key.equals("0")) { 5.312 - assertEquals(ex.getValue(), Boolean.TRUE); 5.313 - count++; 5.314 - } else if (key.equals("1")) { 5.315 - assertEquals(ex.getValue(), "hello"); 5.316 - count++; 5.317 - } 5.318 - } 5.319 - assertEquals(count, 2); 5.320 - assertEquals(map.size(), 2); 5.321 - 5.322 - // add element 5.323 - map.put("2", "world"); 5.324 - assertEquals(map.get("2"), "world"); 5.325 - assertEquals(map.size(), 3); 5.326 - 5.327 - // remove all 5.328 - map.clear(); 5.329 - assertTrue(map.isEmpty()); 5.330 - assertEquals(e.eval("typeof arr[0]"), "undefined"); 5.331 - assertEquals(e.eval("typeof arr[1]"), "undefined"); 5.332 - assertEquals(e.eval("typeof arr[2]"), "undefined"); 5.333 - } 5.334 - 5.335 @Test 5.336 public void redefineEchoTest() { 5.337 final ScriptEngineManager m = new ScriptEngineManager(); 5.338 @@ -716,150 +416,6 @@ 5.339 fail(exp.getMessage()); 5.340 } 5.341 } 5.342 - 5.343 - @Test 5.344 - public void invokeMethodTest() { 5.345 - final ScriptEngineManager m = new ScriptEngineManager(); 5.346 - final ScriptEngine e = m.getEngineByName("nashorn"); 5.347 - 5.348 - try { 5.349 - e.eval("var Example = function() { this.hello = function() { return 'Hello World!'; };}; myExample = new Example();"); 5.350 - final Object obj = e.get("myExample"); 5.351 - final Object res = ((Invocable)e).invokeMethod(obj, "hello"); 5.352 - assertEquals(res, "Hello World!"); 5.353 - } catch (final Exception exp) { 5.354 - exp.printStackTrace(); 5.355 - fail(exp.getMessage()); 5.356 - } 5.357 - } 5.358 - 5.359 - @Test 5.360 - /** 5.361 - * Check that we can call invokeMethod on an object that we got by evaluating 5.362 - * script with different Context set. 5.363 - */ 5.364 - public void invokeMethodDifferentContextTest() { 5.365 - ScriptEngineManager m = new ScriptEngineManager(); 5.366 - ScriptEngine e = m.getEngineByName("nashorn"); 5.367 - 5.368 - try { 5.369 - // define an object with method on it 5.370 - Object obj = e.eval("({ hello: function() { return 'Hello World!'; } })"); 5.371 - 5.372 - final ScriptContext ctxt = new SimpleScriptContext(); 5.373 - ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE); 5.374 - e.setContext(ctxt); 5.375 - 5.376 - // invoke 'func' on obj - but with current script context changed 5.377 - final Object res = ((Invocable)e).invokeMethod(obj, "hello"); 5.378 - assertEquals(res, "Hello World!"); 5.379 - } catch (final Exception exp) { 5.380 - exp.printStackTrace(); 5.381 - fail(exp.getMessage()); 5.382 - } 5.383 - } 5.384 - 5.385 - @Test 5.386 - /** 5.387 - * Check that invokeMethod throws NPE on null method name. 5.388 - */ 5.389 - public void invokeMethodNullNameTest() { 5.390 - final ScriptEngineManager m = new ScriptEngineManager(); 5.391 - final ScriptEngine e = m.getEngineByName("nashorn"); 5.392 - 5.393 - try { 5.394 - final Object obj = e.eval("({})"); 5.395 - final Object res = ((Invocable)e).invokeMethod(obj, null); 5.396 - fail("should have thrown NPE"); 5.397 - } catch (final Exception exp) { 5.398 - if (! (exp instanceof NullPointerException)) { 5.399 - exp.printStackTrace(); 5.400 - fail(exp.getMessage()); 5.401 - } 5.402 - } 5.403 - } 5.404 - 5.405 - @Test 5.406 - /** 5.407 - * Check that invokeMethod throws NoSuchMethodException on missing method. 5.408 - */ 5.409 - public void invokeMethodMissingTest() { 5.410 - final ScriptEngineManager m = new ScriptEngineManager(); 5.411 - final ScriptEngine e = m.getEngineByName("nashorn"); 5.412 - 5.413 - try { 5.414 - final Object obj = e.eval("({})"); 5.415 - final Object res = ((Invocable)e).invokeMethod(obj, "nonExistentMethod"); 5.416 - fail("should have thrown NoSuchMethodException"); 5.417 - } catch (final Exception exp) { 5.418 - if (! (exp instanceof NoSuchMethodException)) { 5.419 - exp.printStackTrace(); 5.420 - fail(exp.getMessage()); 5.421 - } 5.422 - } 5.423 - } 5.424 - 5.425 - @Test 5.426 - /** 5.427 - * Check that calling method on non-script object 'thiz' results in IllegalArgumentException. 5.428 - */ 5.429 - public void invokeMethodNonScriptObjectThizTest() { 5.430 - final ScriptEngineManager m = new ScriptEngineManager(); 5.431 - final ScriptEngine e = m.getEngineByName("nashorn"); 5.432 - 5.433 - try { 5.434 - ((Invocable)e).invokeMethod(new Object(), "toString"); 5.435 - fail("should have thrown IllegalArgumentException"); 5.436 - } catch (final Exception exp) { 5.437 - if (! (exp instanceof IllegalArgumentException)) { 5.438 - exp.printStackTrace(); 5.439 - fail(exp.getMessage()); 5.440 - } 5.441 - } 5.442 - } 5.443 - 5.444 - @Test 5.445 - /** 5.446 - * Check that calling method on null 'thiz' results in IllegalArgumentException. 5.447 - */ 5.448 - public void invokeMethodNullThizTest() { 5.449 - final ScriptEngineManager m = new ScriptEngineManager(); 5.450 - final ScriptEngine e = m.getEngineByName("nashorn"); 5.451 - 5.452 - try { 5.453 - ((Invocable)e).invokeMethod(null, "toString"); 5.454 - fail("should have thrown IllegalArgumentException"); 5.455 - } catch (final Exception exp) { 5.456 - if (! (exp instanceof IllegalArgumentException)) { 5.457 - exp.printStackTrace(); 5.458 - fail(exp.getMessage()); 5.459 - } 5.460 - } 5.461 - } 5.462 - 5.463 - 5.464 - @Test 5.465 - /** 5.466 - * Check that calling method on mirror created by another engine results in IllegalArgumentException. 5.467 - */ 5.468 - public void invokeMethodMixEnginesTest() { 5.469 - final ScriptEngineManager m = new ScriptEngineManager(); 5.470 - final ScriptEngine engine1 = m.getEngineByName("nashorn"); 5.471 - final ScriptEngine engine2 = m.getEngineByName("nashorn"); 5.472 - 5.473 - try { 5.474 - Object obj = engine1.eval("({ run: function() {} })"); 5.475 - // pass object from engine1 to engine2 as 'thiz' for invokeMethod 5.476 - ((Invocable)engine2).invokeMethod(obj, "run"); 5.477 - fail("should have thrown IllegalArgumentException"); 5.478 - } catch (final Exception exp) { 5.479 - if (! (exp instanceof IllegalArgumentException)) { 5.480 - exp.printStackTrace(); 5.481 - fail(exp.getMessage()); 5.482 - } 5.483 - } 5.484 - } 5.485 - 5.486 @Test 5.487 public void noEnumerablePropertiesTest() { 5.488 final ScriptEngineManager m = new ScriptEngineManager(); 5.489 @@ -921,308 +477,6 @@ 5.490 } 5.491 5.492 @Test 5.493 - public void jsobjectTest() { 5.494 - final ScriptEngineManager m = new ScriptEngineManager(); 5.495 - final ScriptEngine e = m.getEngineByName("nashorn"); 5.496 - try { 5.497 - e.eval("var obj = { '1': 'world', func: function() { return this.bar; }, bar: 'hello' }"); 5.498 - JSObject obj = (JSObject) e.get("obj"); 5.499 - 5.500 - // try basic get on existing properties 5.501 - if (! obj.getMember("bar").equals("hello")) { 5.502 - fail("obj.bar != 'hello'"); 5.503 - } 5.504 - 5.505 - if (! obj.getSlot(1).equals("world")) { 5.506 - fail("obj[1] != 'world'"); 5.507 - } 5.508 - 5.509 - if (! obj.call("func", new Object[0]).equals("hello")) { 5.510 - fail("obj.call('func') != 'hello'"); 5.511 - } 5.512 - 5.513 - // try setting properties 5.514 - obj.setMember("bar", "new-bar"); 5.515 - obj.setSlot(1, "new-element-1"); 5.516 - if (! obj.getMember("bar").equals("new-bar")) { 5.517 - fail("obj.bar != 'new-bar'"); 5.518 - } 5.519 - 5.520 - if (! obj.getSlot(1).equals("new-element-1")) { 5.521 - fail("obj[1] != 'new-element-1'"); 5.522 - } 5.523 - 5.524 - // try adding properties 5.525 - obj.setMember("prop", "prop-value"); 5.526 - obj.setSlot(12, "element-12"); 5.527 - if (! obj.getMember("prop").equals("prop-value")) { 5.528 - fail("obj.prop != 'prop-value'"); 5.529 - } 5.530 - 5.531 - if (! obj.getSlot(12).equals("element-12")) { 5.532 - fail("obj[12] != 'element-12'"); 5.533 - } 5.534 - 5.535 - // delete properties 5.536 - obj.removeMember("prop"); 5.537 - if ("prop-value".equals(obj.getMember("prop"))) { 5.538 - fail("obj.prop is not deleted!"); 5.539 - } 5.540 - 5.541 - // Simple eval tests 5.542 - assertEquals(obj.eval("typeof Object"), "function"); 5.543 - assertEquals(obj.eval("'nashorn'.substring(3)"), "horn"); 5.544 - } catch (final Exception exp) { 5.545 - exp.printStackTrace(); 5.546 - fail(exp.getMessage()); 5.547 - } 5.548 - } 5.549 - 5.550 - @Test 5.551 - /** 5.552 - * check that null function name results in NPE. 5.553 - */ 5.554 - public void invokeFunctionNullNameTest() { 5.555 - final ScriptEngineManager m = new ScriptEngineManager(); 5.556 - final ScriptEngine e = m.getEngineByName("nashorn"); 5.557 - 5.558 - try { 5.559 - final Object res = ((Invocable)e).invokeFunction(null); 5.560 - fail("should have thrown NPE"); 5.561 - } catch (final Exception exp) { 5.562 - if (! (exp instanceof NullPointerException)) { 5.563 - exp.printStackTrace(); 5.564 - fail(exp.getMessage()); 5.565 - } 5.566 - } 5.567 - } 5.568 - 5.569 - @Test 5.570 - /** 5.571 - * Check that attempt to call missing function results in NoSuchMethodException. 5.572 - */ 5.573 - public void invokeFunctionMissingTest() { 5.574 - final ScriptEngineManager m = new ScriptEngineManager(); 5.575 - final ScriptEngine e = m.getEngineByName("nashorn"); 5.576 - 5.577 - try { 5.578 - final Object res = ((Invocable)e).invokeFunction("NonExistentFunc"); 5.579 - fail("should have thrown NoSuchMethodException"); 5.580 - } catch (final Exception exp) { 5.581 - if (! (exp instanceof NoSuchMethodException)) { 5.582 - exp.printStackTrace(); 5.583 - fail(exp.getMessage()); 5.584 - } 5.585 - } 5.586 - } 5.587 - 5.588 - @Test 5.589 - /** 5.590 - * Check that invokeFunction calls functions only from current context's Bindings. 5.591 - */ 5.592 - public void invokeFunctionDifferentContextTest() { 5.593 - ScriptEngineManager m = new ScriptEngineManager(); 5.594 - ScriptEngine e = m.getEngineByName("nashorn"); 5.595 - 5.596 - try { 5.597 - // define an object with method on it 5.598 - Object obj = e.eval("function hello() { return 'Hello World!'; }"); 5.599 - final ScriptContext ctxt = new SimpleScriptContext(); 5.600 - ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE); 5.601 - // change engine's current context 5.602 - e.setContext(ctxt); 5.603 - 5.604 - ((Invocable)e).invokeFunction("hello"); // no 'hello' in new context! 5.605 - fail("should have thrown NoSuchMethodException"); 5.606 - } catch (final Exception exp) { 5.607 - if (! (exp instanceof NoSuchMethodException)) { 5.608 - exp.printStackTrace(); 5.609 - fail(exp.getMessage()); 5.610 - } 5.611 - } 5.612 - } 5.613 - 5.614 - @Test 5.615 - public void invokeFunctionExceptionTest() { 5.616 - final ScriptEngineManager m = new ScriptEngineManager(); 5.617 - final ScriptEngine e = m.getEngineByName("nashorn"); 5.618 - try { 5.619 - e.eval("function func() { throw new TypeError(); }"); 5.620 - } catch (final Throwable t) { 5.621 - t.printStackTrace(); 5.622 - fail(t.getMessage()); 5.623 - } 5.624 - 5.625 - try { 5.626 - ((Invocable)e).invokeFunction("func"); 5.627 - fail("should have thrown exception"); 5.628 - } catch (final ScriptException se) { 5.629 - // ECMA TypeError property wrapped as a ScriptException 5.630 - log("got " + se + " as expected"); 5.631 - } catch (final Throwable t) { 5.632 - t.printStackTrace(); 5.633 - fail(t.getMessage()); 5.634 - } 5.635 - } 5.636 - 5.637 - @Test 5.638 - public void invokeMethodExceptionTest() { 5.639 - final ScriptEngineManager m = new ScriptEngineManager(); 5.640 - final ScriptEngine e = m.getEngineByName("nashorn"); 5.641 - try { 5.642 - e.eval("var sobj = {}; sobj.foo = function func() { throw new TypeError(); }"); 5.643 - } catch (final Throwable t) { 5.644 - t.printStackTrace(); 5.645 - fail(t.getMessage()); 5.646 - } 5.647 - 5.648 - try { 5.649 - final Object sobj = e.get("sobj"); 5.650 - ((Invocable)e).invokeMethod(sobj, "foo"); 5.651 - fail("should have thrown exception"); 5.652 - } catch (final ScriptException se) { 5.653 - // ECMA TypeError property wrapped as a ScriptException 5.654 - log("got " + se + " as expected"); 5.655 - } catch (final Throwable t) { 5.656 - t.printStackTrace(); 5.657 - fail(t.getMessage()); 5.658 - } 5.659 - } 5.660 - 5.661 - @Test 5.662 - public void scriptObjectMirrorToStringTest() { 5.663 - final ScriptEngineManager m = new ScriptEngineManager(); 5.664 - final ScriptEngine e = m.getEngineByName("nashorn"); 5.665 - try { 5.666 - Object obj = e.eval("new TypeError('wrong type')"); 5.667 - assertEquals(obj.toString(), "TypeError: wrong type", "toString returns wrong value"); 5.668 - } catch (final Throwable t) { 5.669 - t.printStackTrace(); 5.670 - fail(t.getMessage()); 5.671 - } 5.672 - 5.673 - try { 5.674 - Object obj = e.eval("function func() { print('hello'); }"); 5.675 - assertEquals(obj.toString(), "function func() { print('hello'); }", "toString returns wrong value"); 5.676 - } catch (final Throwable t) { 5.677 - t.printStackTrace(); 5.678 - fail(t.getMessage()); 5.679 - } 5.680 - } 5.681 - 5.682 - @Test 5.683 - public void engineScopeTest() { 5.684 - final ScriptEngineManager m = new ScriptEngineManager(); 5.685 - final ScriptEngine e = m.getEngineByName("nashorn"); 5.686 - Bindings engineScope = e.getBindings(ScriptContext.ENGINE_SCOPE); 5.687 - 5.688 - // check few ECMA standard built-in global properties 5.689 - assertNotNull(engineScope.get("Object")); 5.690 - assertNotNull(engineScope.get("TypeError")); 5.691 - assertNotNull(engineScope.get("eval")); 5.692 - 5.693 - // can access via ScriptEngine.get as well 5.694 - assertNotNull(e.get("Object")); 5.695 - assertNotNull(e.get("TypeError")); 5.696 - assertNotNull(e.get("eval")); 5.697 - 5.698 - // Access by either way should return same object 5.699 - assertEquals(engineScope.get("Array"), e.get("Array")); 5.700 - assertEquals(engineScope.get("EvalError"), e.get("EvalError")); 5.701 - assertEquals(engineScope.get("undefined"), e.get("undefined")); 5.702 - 5.703 - // try exposing a new variable from scope 5.704 - engineScope.put("myVar", "foo"); 5.705 - try { 5.706 - assertEquals(e.eval("myVar"), "foo"); 5.707 - } catch (final ScriptException se) { 5.708 - se.printStackTrace(); 5.709 - fail(se.getMessage()); 5.710 - } 5.711 - 5.712 - // update "myVar" in script an check the value from scope 5.713 - try { 5.714 - e.eval("myVar = 'nashorn';"); 5.715 - } catch (final ScriptException se) { 5.716 - se.printStackTrace(); 5.717 - fail(se.getMessage()); 5.718 - } 5.719 - 5.720 - // now check modified value from scope and engine 5.721 - assertEquals(engineScope.get("myVar"), "nashorn"); 5.722 - assertEquals(e.get("myVar"), "nashorn"); 5.723 - } 5.724 - 5.725 - @Test 5.726 - public void multiGlobalTest() { 5.727 - final ScriptEngineManager m = new ScriptEngineManager(); 5.728 - final ScriptEngine e = m.getEngineByName("nashorn"); 5.729 - final Bindings b = e.createBindings(); 5.730 - final ScriptContext newCtxt = new SimpleScriptContext(); 5.731 - newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); 5.732 - 5.733 - try { 5.734 - Object obj1 = e.eval("Object"); 5.735 - Object obj2 = e.eval("Object", newCtxt); 5.736 - Assert.assertNotEquals(obj1, obj2); 5.737 - Assert.assertNotNull(obj1); 5.738 - Assert.assertNotNull(obj2); 5.739 - Assert.assertEquals(obj1.toString(), obj2.toString()); 5.740 - 5.741 - e.eval("x = 'hello'"); 5.742 - e.eval("x = 'world'", newCtxt); 5.743 - Object x1 = e.getContext().getAttribute("x"); 5.744 - Object x2 = newCtxt.getAttribute("x"); 5.745 - Assert.assertNotEquals(x1, x2); 5.746 - Assert.assertEquals(x1, "hello"); 5.747 - Assert.assertEquals(x2, "world"); 5.748 - 5.749 - x1 = e.eval("x"); 5.750 - x2 = e.eval("x", newCtxt); 5.751 - Assert.assertNotEquals(x1, x2); 5.752 - Assert.assertEquals(x1, "hello"); 5.753 - Assert.assertEquals(x2, "world"); 5.754 - 5.755 - final ScriptContext origCtxt = e.getContext(); 5.756 - e.setContext(newCtxt); 5.757 - e.eval("y = new Object()"); 5.758 - e.eval("y = new Object()", origCtxt); 5.759 - 5.760 - Object y1 = origCtxt.getAttribute("y"); 5.761 - Object y2 = newCtxt.getAttribute("y"); 5.762 - Assert.assertNotEquals(y1, y2); 5.763 - Assert.assertNotEquals(e.eval("y"), e.eval("y", origCtxt)); 5.764 - Assert.assertEquals("[object Object]", y1.toString()); 5.765 - Assert.assertEquals("[object Object]", y2.toString()); 5.766 - } catch (final ScriptException se) { 5.767 - se.printStackTrace(); 5.768 - fail(se.getMessage()); 5.769 - } 5.770 - } 5.771 - 5.772 - @Test 5.773 - /** 5.774 - * Tests whether invocation of a JavaScript method through a variable arity Java method will pass the vararg array. 5.775 - * Both non-vararg and vararg JavaScript methods are tested. 5.776 - * @throws ScriptException 5.777 - */ 5.778 - public void variableArityInterfaceTest() throws ScriptException { 5.779 - final ScriptEngineManager m = new ScriptEngineManager(); 5.780 - final ScriptEngine e = m.getEngineByName("nashorn"); 5.781 - e.eval( 5.782 - "function test1(i, strings) {" + 5.783 - " return 'i == ' + i + ', strings instanceof java.lang.String[] == ' + (strings instanceof Java.type('java.lang.String[]')) + ', strings == ' + java.util.Arrays.toString(strings)" + 5.784 - "}" + 5.785 - "function test2() {" + 5.786 - " return 'arguments[0] == ' + arguments[0] + ', arguments[1] instanceof java.lang.String[] == ' + (arguments[1] instanceof Java.type('java.lang.String[]')) + ', arguments[1] == ' + java.util.Arrays.toString(arguments[1])" + 5.787 - "}" 5.788 - ); 5.789 - final VariableArityTestInterface itf = ((Invocable)e).getInterface(VariableArityTestInterface.class); 5.790 - Assert.assertEquals(itf.test1(42, "a", "b"), "i == 42, strings instanceof java.lang.String[] == true, strings == [a, b]"); 5.791 - Assert.assertEquals(itf.test2(44, "c", "d", "e"), "arguments[0] == 44, arguments[1] instanceof java.lang.String[] == true, arguments[1] == [c, d, e]"); 5.792 - } 5.793 - 5.794 - @Test 5.795 // check that print function prints arg followed by newline char 5.796 public void printTest() { 5.797 final ScriptEngineManager m = new ScriptEngineManager(); 5.798 @@ -1257,76 +511,4 @@ 5.799 // dos2unix - fix line endings if running on windows 5.800 assertEquals(sw.toString().replaceAll("\r", ""), "34 true hello\n"); 5.801 } 5.802 - 5.803 - @Test 5.804 - public void mirrorNewObjectGlobalFunctionTest() throws ScriptException { 5.805 - final ScriptEngineManager m = new ScriptEngineManager(); 5.806 - final ScriptEngine e = m.getEngineByName("nashorn"); 5.807 - final ScriptEngine e2 = m.getEngineByName("nashorn"); 5.808 - 5.809 - e.eval("function func() {}"); 5.810 - e2.put("foo", e.get("func")); 5.811 - final Object e2global = e2.eval("this"); 5.812 - final Object newObj = ((ScriptObjectMirror)e2global).newObject("foo"); 5.813 - assertTrue(newObj instanceof ScriptObjectMirror); 5.814 - } 5.815 - 5.816 - @Test 5.817 - public void mirrorNewObjectInstanceFunctionTest() throws ScriptException { 5.818 - final ScriptEngineManager m = new ScriptEngineManager(); 5.819 - final ScriptEngine e = m.getEngineByName("nashorn"); 5.820 - final ScriptEngine e2 = m.getEngineByName("nashorn"); 5.821 - 5.822 - e.eval("function func() {}"); 5.823 - e2.put("func", e.get("func")); 5.824 - final Object e2obj = e2.eval("({ foo: func })"); 5.825 - final Object newObj = ((ScriptObjectMirror)e2obj).newObject("foo"); 5.826 - assertTrue(newObj instanceof ScriptObjectMirror); 5.827 - } 5.828 - 5.829 - @Test 5.830 - public void userEngineScopeBindingsTest() throws ScriptException { 5.831 - final ScriptEngineManager m = new ScriptEngineManager(); 5.832 - final ScriptEngine e = m.getEngineByName("nashorn"); 5.833 - e.eval("function func() {}"); 5.834 - 5.835 - final ScriptContext newContext = new SimpleScriptContext(); 5.836 - newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE); 5.837 - // we are using a new bindings - so it should have 'func' defined 5.838 - Object value = e.eval("typeof func", newContext); 5.839 - assertTrue(value.equals("undefined")); 5.840 - } 5.841 - 5.842 - @Test 5.843 - public void userEngineScopeBindingsNoLeakTest() throws ScriptException { 5.844 - final ScriptEngineManager m = new ScriptEngineManager(); 5.845 - final ScriptEngine e = m.getEngineByName("nashorn"); 5.846 - final ScriptContext newContext = new SimpleScriptContext(); 5.847 - newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE); 5.848 - e.eval("function foo() {}", newContext); 5.849 - 5.850 - // in the default context's ENGINE_SCOPE, 'foo' shouldn't exist 5.851 - assertTrue(e.eval("typeof foo").equals("undefined")); 5.852 - } 5.853 - 5.854 - @Test 5.855 - public void userEngineScopeBindingsRetentionTest() throws ScriptException { 5.856 - final ScriptEngineManager m = new ScriptEngineManager(); 5.857 - final ScriptEngine e = m.getEngineByName("nashorn"); 5.858 - final ScriptContext newContext = new SimpleScriptContext(); 5.859 - newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE); 5.860 - e.eval("function foo() {}", newContext); 5.861 - 5.862 - // definition retained with user's ENGINE_SCOPE Binding 5.863 - assertTrue(e.eval("typeof foo", newContext).equals("function")); 5.864 - 5.865 - final Bindings oldBindings = newContext.getBindings(ScriptContext.ENGINE_SCOPE); 5.866 - // but not in another ENGINE_SCOPE binding 5.867 - newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE); 5.868 - assertTrue(e.eval("typeof foo", newContext).equals("undefined")); 5.869 - 5.870 - // restore ENGINE_SCOPE and check again 5.871 - newContext.setBindings(oldBindings, ScriptContext.ENGINE_SCOPE); 5.872 - assertTrue(e.eval("typeof foo", newContext).equals("function")); 5.873 - } 5.874 }
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java Fri Aug 23 16:10:37 2013 +0530 6.3 @@ -0,0 +1,230 @@ 6.4 +/* 6.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.7 + * 6.8 + * This code is free software; you can redistribute it and/or modify it 6.9 + * under the terms of the GNU General Public License version 2 only, as 6.10 + * published by the Free Software Foundation. Oracle designates this 6.11 + * particular file as subject to the "Classpath" exception as provided 6.12 + * by Oracle in the LICENSE file that accompanied this code. 6.13 + * 6.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 6.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 6.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 6.17 + * version 2 for more details (a copy is included in the LICENSE file that 6.18 + * accompanied this code). 6.19 + * 6.20 + * You should have received a copy of the GNU General Public License version 6.21 + * 2 along with this work; if not, write to the Free Software Foundation, 6.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 6.23 + * 6.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 6.25 + * or visit www.oracle.com if you need additional information or have any 6.26 + * questions. 6.27 + */ 6.28 + 6.29 +package jdk.nashorn.api.scripting; 6.30 + 6.31 +import java.util.HashMap; 6.32 +import java.util.Map; 6.33 +import javax.script.ScriptEngine; 6.34 +import javax.script.ScriptEngineManager; 6.35 +import javax.script.ScriptException; 6.36 +import static org.testng.Assert.assertEquals; 6.37 +import static org.testng.Assert.assertFalse; 6.38 +import static org.testng.Assert.assertTrue; 6.39 +import static org.testng.Assert.fail; 6.40 +import org.testng.annotations.Test; 6.41 + 6.42 +/** 6.43 + * Tests to check jdk.nashorn.api.scripting.ScriptObjectMirror API. 6.44 + */ 6.45 +public class ScriptObjectMirrorTest { 6.46 + 6.47 + @SuppressWarnings("unchecked") 6.48 + @Test 6.49 + public void reflectionTest() throws ScriptException { 6.50 + final ScriptEngineManager m = new ScriptEngineManager(); 6.51 + final ScriptEngine e = m.getEngineByName("nashorn"); 6.52 + 6.53 + e.eval("var obj = { x: 344, y: 'nashorn' }"); 6.54 + 6.55 + int count = 0; 6.56 + Map<Object, Object> map = (Map<Object, Object>) e.get("obj"); 6.57 + assertFalse(map.isEmpty()); 6.58 + assertTrue(map.keySet().contains("x")); 6.59 + assertTrue(map.containsKey("x")); 6.60 + assertTrue(map.values().contains("nashorn")); 6.61 + assertTrue(map.containsValue("nashorn")); 6.62 + for (final Map.Entry<?, ?> ex : map.entrySet()) { 6.63 + final Object key = ex.getKey(); 6.64 + if (key.equals("x")) { 6.65 + assertTrue(344 == ((Number) ex.getValue()).doubleValue()); 6.66 + count++; 6.67 + } else if (key.equals("y")) { 6.68 + assertEquals(ex.getValue(), "nashorn"); 6.69 + count++; 6.70 + } 6.71 + } 6.72 + assertEquals(2, count); 6.73 + assertEquals(2, map.size()); 6.74 + 6.75 + // add property 6.76 + map.put("z", "hello"); 6.77 + assertEquals(e.eval("obj.z"), "hello"); 6.78 + assertEquals(map.get("z"), "hello"); 6.79 + assertTrue(map.keySet().contains("z")); 6.80 + assertTrue(map.containsKey("z")); 6.81 + assertTrue(map.values().contains("hello")); 6.82 + assertTrue(map.containsValue("hello")); 6.83 + assertEquals(map.size(), 3); 6.84 + 6.85 + final Map<Object, Object> newMap = new HashMap<>(); 6.86 + newMap.put("foo", 23.0); 6.87 + newMap.put("bar", true); 6.88 + map.putAll(newMap); 6.89 + 6.90 + assertEquals(e.eval("obj.foo"), 23.0); 6.91 + assertEquals(e.eval("obj.bar"), true); 6.92 + 6.93 + // remove using map method 6.94 + map.remove("foo"); 6.95 + assertEquals(e.eval("typeof obj.foo"), "undefined"); 6.96 + 6.97 + count = 0; 6.98 + e.eval("var arr = [ true, 'hello' ]"); 6.99 + map = (Map<Object, Object>) e.get("arr"); 6.100 + assertFalse(map.isEmpty()); 6.101 + assertTrue(map.containsKey("length")); 6.102 + assertTrue(map.containsValue("hello")); 6.103 + for (final Map.Entry<?, ?> ex : map.entrySet()) { 6.104 + final Object key = ex.getKey(); 6.105 + if (key.equals("0")) { 6.106 + assertEquals(ex.getValue(), Boolean.TRUE); 6.107 + count++; 6.108 + } else if (key.equals("1")) { 6.109 + assertEquals(ex.getValue(), "hello"); 6.110 + count++; 6.111 + } 6.112 + } 6.113 + assertEquals(count, 2); 6.114 + assertEquals(map.size(), 2); 6.115 + 6.116 + // add element 6.117 + map.put("2", "world"); 6.118 + assertEquals(map.get("2"), "world"); 6.119 + assertEquals(map.size(), 3); 6.120 + 6.121 + // remove all 6.122 + map.clear(); 6.123 + assertTrue(map.isEmpty()); 6.124 + assertEquals(e.eval("typeof arr[0]"), "undefined"); 6.125 + assertEquals(e.eval("typeof arr[1]"), "undefined"); 6.126 + assertEquals(e.eval("typeof arr[2]"), "undefined"); 6.127 + } 6.128 + 6.129 + @Test 6.130 + public void jsobjectTest() { 6.131 + final ScriptEngineManager m = new ScriptEngineManager(); 6.132 + final ScriptEngine e = m.getEngineByName("nashorn"); 6.133 + try { 6.134 + e.eval("var obj = { '1': 'world', func: function() { return this.bar; }, bar: 'hello' }"); 6.135 + JSObject obj = (JSObject) e.get("obj"); 6.136 + 6.137 + // try basic get on existing properties 6.138 + if (!obj.getMember("bar").equals("hello")) { 6.139 + fail("obj.bar != 'hello'"); 6.140 + } 6.141 + 6.142 + if (!obj.getSlot(1).equals("world")) { 6.143 + fail("obj[1] != 'world'"); 6.144 + } 6.145 + 6.146 + if (!obj.call("func", new Object[0]).equals("hello")) { 6.147 + fail("obj.call('func') != 'hello'"); 6.148 + } 6.149 + 6.150 + // try setting properties 6.151 + obj.setMember("bar", "new-bar"); 6.152 + obj.setSlot(1, "new-element-1"); 6.153 + if (!obj.getMember("bar").equals("new-bar")) { 6.154 + fail("obj.bar != 'new-bar'"); 6.155 + } 6.156 + 6.157 + if (!obj.getSlot(1).equals("new-element-1")) { 6.158 + fail("obj[1] != 'new-element-1'"); 6.159 + } 6.160 + 6.161 + // try adding properties 6.162 + obj.setMember("prop", "prop-value"); 6.163 + obj.setSlot(12, "element-12"); 6.164 + if (!obj.getMember("prop").equals("prop-value")) { 6.165 + fail("obj.prop != 'prop-value'"); 6.166 + } 6.167 + 6.168 + if (!obj.getSlot(12).equals("element-12")) { 6.169 + fail("obj[12] != 'element-12'"); 6.170 + } 6.171 + 6.172 + // delete properties 6.173 + obj.removeMember("prop"); 6.174 + if ("prop-value".equals(obj.getMember("prop"))) { 6.175 + fail("obj.prop is not deleted!"); 6.176 + } 6.177 + 6.178 + // Simple eval tests 6.179 + assertEquals(obj.eval("typeof Object"), "function"); 6.180 + assertEquals(obj.eval("'nashorn'.substring(3)"), "horn"); 6.181 + } catch (final Exception exp) { 6.182 + exp.printStackTrace(); 6.183 + fail(exp.getMessage()); 6.184 + } 6.185 + } 6.186 + 6.187 + @Test 6.188 + public void scriptObjectMirrorToStringTest() { 6.189 + final ScriptEngineManager m = new ScriptEngineManager(); 6.190 + final ScriptEngine e = m.getEngineByName("nashorn"); 6.191 + try { 6.192 + Object obj = e.eval("new TypeError('wrong type')"); 6.193 + assertEquals(obj.toString(), "TypeError: wrong type", "toString returns wrong value"); 6.194 + } catch (final Throwable t) { 6.195 + t.printStackTrace(); 6.196 + fail(t.getMessage()); 6.197 + } 6.198 + 6.199 + try { 6.200 + Object obj = e.eval("function func() { print('hello'); }"); 6.201 + assertEquals(obj.toString(), "function func() { print('hello'); }", "toString returns wrong value"); 6.202 + } catch (final Throwable t) { 6.203 + t.printStackTrace(); 6.204 + fail(t.getMessage()); 6.205 + } 6.206 + } 6.207 + 6.208 + @Test 6.209 + public void mirrorNewObjectGlobalFunctionTest() throws ScriptException { 6.210 + final ScriptEngineManager m = new ScriptEngineManager(); 6.211 + final ScriptEngine e = m.getEngineByName("nashorn"); 6.212 + final ScriptEngine e2 = m.getEngineByName("nashorn"); 6.213 + 6.214 + e.eval("function func() {}"); 6.215 + e2.put("foo", e.get("func")); 6.216 + final Object e2global = e2.eval("this"); 6.217 + final Object newObj = ((ScriptObjectMirror) e2global).newObject("foo"); 6.218 + assertTrue(newObj instanceof ScriptObjectMirror); 6.219 + } 6.220 + 6.221 + @Test 6.222 + public void mirrorNewObjectInstanceFunctionTest() throws ScriptException { 6.223 + final ScriptEngineManager m = new ScriptEngineManager(); 6.224 + final ScriptEngine e = m.getEngineByName("nashorn"); 6.225 + final ScriptEngine e2 = m.getEngineByName("nashorn"); 6.226 + 6.227 + e.eval("function func() {}"); 6.228 + e2.put("func", e.get("func")); 6.229 + final Object e2obj = e2.eval("({ foo: func })"); 6.230 + final Object newObj = ((ScriptObjectMirror) e2obj).newObject("foo"); 6.231 + assertTrue(newObj instanceof ScriptObjectMirror); 6.232 + } 6.233 +}