| /* |
| * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| package jdk.nashorn.api.scripting; |
| |
| import static org.testng.Assert.assertEquals; |
| import static org.testng.Assert.assertNotNull; |
| import static org.testng.Assert.assertFalse; |
| import static org.testng.Assert.assertTrue; |
| import static org.testng.Assert.fail; |
| |
| import java.io.StringReader; |
| import java.io.StringWriter; |
| import java.lang.reflect.Method; |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.concurrent.Callable; |
| import javax.script.Bindings; |
| import javax.script.Compilable; |
| import javax.script.CompiledScript; |
| import javax.script.Invocable; |
| import javax.script.ScriptContext; |
| import javax.script.ScriptEngine; |
| import javax.script.ScriptEngineFactory; |
| import javax.script.ScriptEngineManager; |
| import javax.script.ScriptException; |
| import javax.script.SimpleScriptContext; |
| import jdk.nashorn.internal.runtime.Version; |
| import netscape.javascript.JSObject; |
| import org.testng.Assert; |
| import org.testng.TestNG; |
| import org.testng.annotations.Test; |
| |
| /** |
| * Tests for JSR-223 script engine for Nashorn. |
| */ |
| public class ScriptEngineTest { |
| |
| public static void main(final String[] args) { |
| TestNG.main(args); |
| } |
| |
| private void log(String msg) { |
| org.testng.Reporter.log(msg, true); |
| } |
| |
| @Test |
| public void argumentsTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| |
| String[] args = new String[] { "hello", "world" }; |
| try { |
| e.put("arguments", args); |
| Object arg0 = e.eval("arguments[0]"); |
| Object arg1 = e.eval("arguments[1]"); |
| assertEquals(args[0], arg0); |
| assertEquals(args[1], arg1); |
| } catch (final Exception exp) { |
| exp.printStackTrace(); |
| fail(exp.getMessage()); |
| } |
| } |
| |
| @Test |
| public void argumentsWithTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| |
| String[] args = new String[] { "hello", "world" }; |
| try { |
| e.put("arguments", args); |
| Object arg0 = e.eval("var imports = new JavaImporter(java.io); " + |
| " with(imports) { arguments[0] }"); |
| Object arg1 = e.eval("var imports = new JavaImporter(java.util, java.io); " + |
| " with(imports) { arguments[1] }"); |
| assertEquals(args[0], arg0); |
| assertEquals(args[1], arg1); |
| } catch (final Exception exp) { |
| exp.printStackTrace(); |
| fail(exp.getMessage()); |
| } |
| } |
| |
| @Test |
| public void argumentsEmptyTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| |
| try { |
| assertEquals(e.eval("arguments instanceof Array"), true); |
| assertEquals(e.eval("arguments.length == 0"), true); |
| } catch (final Exception exp) { |
| exp.printStackTrace(); |
| fail(exp.getMessage()); |
| } |
| } |
| |
| @Test |
| public void factoryTests() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| assertNotNull(e); |
| |
| final ScriptEngineFactory fac = e.getFactory(); |
| |
| assertEquals(fac.getLanguageName(), "ECMAScript"); |
| assertEquals(fac.getParameter(ScriptEngine.NAME), "javascript"); |
| assertEquals(fac.getLanguageVersion(), "ECMA - 262 Edition 5.1"); |
| assertEquals(fac.getEngineName(), "Oracle Nashorn"); |
| assertEquals(fac.getEngineVersion(), Version.version()); |
| assertEquals(fac.getOutputStatement("context"), "print(context)"); |
| assertEquals(fac.getParameter(ScriptEngine.NAME), "javascript"); |
| |
| boolean seenJS = false; |
| for (String ext : fac.getExtensions()) { |
| if (ext.equals("js")) { |
| seenJS = true; |
| } |
| } |
| |
| assertEquals(seenJS, true); |
| String str = fac.getMethodCallSyntax("obj", "foo", "x"); |
| assertEquals(str, "obj.foo(x)"); |
| |
| boolean seenNashorn = false, seenJavaScript = false, seenECMAScript = false; |
| for (String name : fac.getNames()) { |
| switch (name) { |
| case "nashorn": seenNashorn = true; break; |
| case "javascript": seenJavaScript = true; break; |
| case "ECMAScript": seenECMAScript = true; break; |
| } |
| } |
| |
| assertTrue(seenNashorn); |
| assertTrue(seenJavaScript); |
| assertTrue(seenECMAScript); |
| |
| boolean seenAppJS = false, seenAppECMA = false, seenTextJS = false, seenTextECMA = false; |
| for (String mime : fac.getMimeTypes()) { |
| switch (mime) { |
| case "application/javascript": seenAppJS = true; break; |
| case "application/ecmascript": seenAppECMA = true; break; |
| case "text/javascript": seenTextJS = true; break; |
| case "text/ecmascript": seenTextECMA = true; break; |
| } |
| } |
| |
| assertTrue(seenAppJS); |
| assertTrue(seenAppECMA); |
| assertTrue(seenTextJS); |
| assertTrue(seenTextECMA); |
| } |
| |
| @Test |
| public void evalTests() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| e.put(ScriptEngine.FILENAME, "myfile.js"); |
| |
| try { |
| e.eval("print('hello')"); |
| } catch (final ScriptException se) { |
| fail(se.getMessage()); |
| } |
| try { |
| e.eval("print('hello)"); |
| fail("script exception expected"); |
| } catch (final ScriptException se) { |
| assertEquals(se.getLineNumber(), 1); |
| assertEquals(se.getColumnNumber(), 13); |
| assertEquals(se.getFileName(), "myfile.js"); |
| // se.printStackTrace(); |
| } |
| |
| try { |
| Object obj = e.eval("34 + 41"); |
| assertTrue(34.0 + 41.0 == ((Number)obj).doubleValue()); |
| obj = e.eval("x = 5"); |
| assertTrue(5.0 == ((Number)obj).doubleValue()); |
| } catch (final ScriptException se) { |
| se.printStackTrace(); |
| fail(se.getMessage()); |
| } |
| } |
| |
| @Test |
| public void compileTests() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| CompiledScript script = null; |
| |
| try { |
| script = ((Compilable)e).compile("print('hello')"); |
| } catch (final ScriptException se) { |
| fail(se.getMessage()); |
| } |
| |
| try { |
| script.eval(); |
| } catch (final ScriptException | NullPointerException se) { |
| se.printStackTrace(); |
| fail(se.getMessage()); |
| } |
| |
| // try to compile from a Reader |
| try { |
| script = ((Compilable)e).compile(new StringReader("print('world')")); |
| } catch (final ScriptException se) { |
| fail(se.getMessage()); |
| } |
| |
| try { |
| script.eval(); |
| } catch (final ScriptException | NullPointerException se) { |
| se.printStackTrace(); |
| fail(se.getMessage()); |
| } |
| } |
| |
| @Test |
| public void createBindingsTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| Bindings b = e.createBindings(); |
| b.put("foo", 42.0); |
| Object res = null; |
| try { |
| res = e.eval("foo == 42.0", b); |
| } catch (final ScriptException | NullPointerException se) { |
| se.printStackTrace(); |
| fail(se.getMessage()); |
| } |
| |
| assertEquals(res, Boolean.TRUE); |
| } |
| |
| @Test |
| public void getInterfaceTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| final Invocable inv = (Invocable)e; |
| |
| // try to get interface from global functions |
| try { |
| e.eval("function run() { print('run'); };"); |
| final Runnable runnable = inv.getInterface(Runnable.class); |
| runnable.run(); |
| } catch (final Exception exp) { |
| exp.printStackTrace(); |
| fail(exp.getMessage()); |
| } |
| |
| // try interface on specific script object |
| try { |
| e.eval("var obj = { run: function() { print('run from obj'); } };"); |
| Object obj = e.get("obj"); |
| final Runnable runnable = inv.getInterface(obj, Runnable.class); |
| runnable.run(); |
| } catch (final Exception exp) { |
| exp.printStackTrace(); |
| fail(exp.getMessage()); |
| } |
| } |
| |
| @Test |
| public void accessGlobalTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| |
| try { |
| e.eval("var x = 'hello'"); |
| assertEquals(e.get("x"), "hello"); |
| } catch (final ScriptException exp) { |
| exp.printStackTrace(); |
| fail(exp.getMessage()); |
| } |
| } |
| |
| @Test |
| public void exposeGlobalTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| |
| try { |
| e.put("y", "foo"); |
| e.eval("print(y)"); |
| } catch (final ScriptException exp) { |
| exp.printStackTrace(); |
| fail(exp.getMessage()); |
| } |
| } |
| |
| public static void alert(final Object msg) { |
| System.out.println(msg); |
| } |
| |
| @Test |
| public void exposeMethodTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| |
| try { |
| final Method alert = ScriptEngineTest.class.getMethod("alert", Object.class); |
| // expose a Method object as global var. |
| e.put("alert", alert); |
| // call the global var. |
| e.eval("alert.invoke(null, 'alert! alert!!')"); |
| } catch (final NoSuchMethodException | SecurityException | ScriptException exp) { |
| exp.printStackTrace(); |
| fail(exp.getMessage()); |
| } |
| } |
| |
| @Test |
| public void putGlobalFunctionTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| |
| e.put("callable", new Callable<String>() { |
| @Override |
| public String call() throws Exception { |
| return "callable was called"; |
| } |
| }); |
| |
| try { |
| e.eval("print(callable.call())"); |
| } catch (final ScriptException exp) { |
| exp.printStackTrace(); |
| fail(exp.getMessage()); |
| } |
| } |
| |
| @Test |
| public void windowAlertTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| final Window window = new Window(); |
| |
| try { |
| e.put("window", window); |
| e.eval("print(window.alert)"); |
| e.eval("window.alert('calling window.alert...')"); |
| } catch (final Exception exp) { |
| exp.printStackTrace(); |
| fail(exp.getMessage()); |
| } |
| } |
| |
| @Test |
| public void windowLocationTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| final Window window = new Window(); |
| |
| try { |
| e.put("window", window); |
| e.eval("print(window.location)"); |
| final Object locationValue = e.eval("window.getLocation()"); |
| assertEquals(locationValue, "http://localhost:8080/window"); |
| } catch (final Exception exp) { |
| exp.printStackTrace(); |
| fail(exp.getMessage()); |
| } |
| } |
| |
| @Test |
| public void windowItemTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| final Window window = new Window(); |
| |
| try { |
| e.put("window", window); |
| final String item1 = (String)e.eval("window.item(65535)"); |
| assertEquals(item1, "ffff"); |
| final String item2 = (String)e.eval("window.item(255)"); |
| assertEquals(item2, "ff"); |
| } catch (final Exception exp) { |
| exp.printStackTrace(); |
| fail(exp.getMessage()); |
| } |
| } |
| |
| @Test |
| public void windowEventTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| final Window window = new Window(); |
| |
| try { |
| e.put("window", window); |
| e.eval("window.onload = function() { print('window load event fired'); return true }"); |
| assertTrue((Boolean)e.eval("window.onload.loaded()")); |
| final WindowEventHandler handler = window.getOnload(); |
| assertNotNull(handler); |
| assertTrue(handler.loaded()); |
| } catch (final Exception exp) { |
| exp.printStackTrace(); |
| fail(exp.getMessage()); |
| } |
| } |
| |
| @Test |
| public void throwTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| e.put(ScriptEngine.FILENAME, "throwtest.js"); |
| |
| try { |
| e.eval("throw 'foo'"); |
| } catch (final ScriptException exp) { |
| log(exp.getMessage()); |
| assertEquals(exp.getMessage(), "foo in throwtest.js at line number 1 at column number 0"); |
| assertEquals(exp.getFileName(), "throwtest.js"); |
| assertEquals(exp.getLineNumber(), 1); |
| } |
| } |
| |
| @Test |
| public void setTimeoutTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| final Window window = new Window(); |
| |
| try { |
| final Class<?> setTimeoutParamTypes[] = { Window.class, String.class, int.class }; |
| final Method setTimeout = Window.class.getDeclaredMethod("setTimeout", setTimeoutParamTypes); |
| assertNotNull(setTimeout); |
| e.put("window", window); |
| e.eval("window.setTimeout('foo()', 100)"); |
| |
| // try to make setTimeout global |
| e.put("setTimeout", setTimeout); |
| // TODO: java.lang.ClassCastException: required class |
| // java.lang.Integer but encountered class java.lang.Double |
| // e.eval("setTimeout('foo2()', 200)"); |
| } catch (final Exception exp) { |
| exp.printStackTrace(); |
| fail(exp.getMessage()); |
| } |
| } |
| |
| @Test |
| public void setWriterTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| final StringWriter sw = new StringWriter(); |
| e.getContext().setWriter(sw); |
| |
| try { |
| e.eval("print('hello world')"); |
| } catch (final Exception exp) { |
| exp.printStackTrace(); |
| fail(exp.getMessage()); |
| } |
| // dos2unix - fix line endings if running on windows |
| assertEquals(sw.toString().replaceAll("\r", ""), "hello world\n"); |
| } |
| |
| @SuppressWarnings("unchecked") |
| @Test |
| public void reflectionTest() throws ScriptException { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| |
| e.eval("var obj = { x: 344, y: 'nashorn' }"); |
| |
| int count = 0; |
| Map<Object, Object> map = (Map<Object, Object>)e.get("obj"); |
| assertFalse(map.isEmpty()); |
| assertTrue(map.keySet().contains("x")); |
| assertTrue(map.containsKey("x")); |
| assertTrue(map.values().contains("nashorn")); |
| assertTrue(map.containsValue("nashorn")); |
| for (final Map.Entry<?, ?> ex : map.entrySet()) { |
| final Object key = ex.getKey(); |
| if (key.equals("x")) { |
| assertTrue(344 == ((Number)ex.getValue()).doubleValue()); |
| count++; |
| } else if (key.equals("y")) { |
| assertEquals(ex.getValue(), "nashorn"); |
| count++; |
| } |
| } |
| assertEquals(2, count); |
| assertEquals(2, map.size()); |
| |
| // add property |
| map.put("z", "hello"); |
| assertEquals(e.eval("obj.z"), "hello"); |
| assertEquals(map.get("z"), "hello"); |
| assertTrue(map.keySet().contains("z")); |
| assertTrue(map.containsKey("z")); |
| assertTrue(map.values().contains("hello")); |
| assertTrue(map.containsValue("hello")); |
| assertEquals(map.size(), 3); |
| |
| final Map<Object, Object> newMap = new HashMap<>(); |
| newMap.put("foo", 23.0); |
| newMap.put("bar", true); |
| map.putAll(newMap); |
| |
| assertEquals(e.eval("obj.foo"), 23.0); |
| assertEquals(e.eval("obj.bar"), true); |
| |
| // remove using map method |
| map.remove("foo"); |
| assertEquals(e.eval("typeof obj.foo"), "undefined"); |
| |
| count = 0; |
| e.eval("var arr = [ true, 'hello' ]"); |
| map = (Map<Object, Object>)e.get("arr"); |
| assertFalse(map.isEmpty()); |
| assertTrue(map.containsKey("length")); |
| assertTrue(map.containsValue("hello")); |
| for (final Map.Entry<?, ?> ex : map.entrySet()) { |
| final Object key = ex.getKey(); |
| if (key.equals("0")) { |
| assertEquals(ex.getValue(), Boolean.TRUE); |
| count++; |
| } else if (key.equals("1")) { |
| assertEquals(ex.getValue(), "hello"); |
| count++; |
| } |
| } |
| assertEquals(count, 2); |
| assertEquals(map.size(), 2); |
| |
| // add element |
| map.put("2", "world"); |
| assertEquals(map.get("2"), "world"); |
| assertEquals(map.size(), 3); |
| |
| // remove all |
| map.clear(); |
| assertTrue(map.isEmpty()); |
| assertEquals(e.eval("typeof arr[0]"), "undefined"); |
| assertEquals(e.eval("typeof arr[1]"), "undefined"); |
| assertEquals(e.eval("typeof arr[2]"), "undefined"); |
| } |
| |
| @Test |
| public void redefineEchoTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| |
| try { |
| e.eval("var echo = {}; if (typeof echo !== 'object') { throw 'echo is a '+typeof echo; }"); |
| } catch (final Exception exp) { |
| exp.printStackTrace(); |
| fail(exp.getMessage()); |
| } |
| } |
| |
| @Test |
| public void invokeMethodTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| |
| try { |
| e.eval("var Example = function() { this.hello = function() { return 'Hello World!'; };}; myExample = new Example();"); |
| final Object obj = e.get("myExample"); |
| final Object res = ((Invocable)e).invokeMethod(obj, "hello"); |
| assertEquals(res, "Hello World!"); |
| } catch (final Exception exp) { |
| exp.printStackTrace(); |
| fail(exp.getMessage()); |
| } |
| } |
| |
| @Test |
| public void versionTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| assertEquals(e.getFactory().getEngineVersion(), Version.version()); |
| } |
| |
| @Test |
| public void noEnumerablePropertiesTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| try { |
| e.eval("for (i in this) { throw 'found property: ' + i }"); |
| } catch (final Exception exp) { |
| exp.printStackTrace(); |
| fail(exp.getMessage()); |
| } |
| } |
| |
| @Test |
| public void noRefErrorForGlobalThisAccessTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| try { |
| e.eval("this.foo"); |
| } catch (final Exception exp) { |
| exp.printStackTrace(); |
| fail(exp.getMessage()); |
| } |
| } |
| |
| @Test |
| public void refErrorForUndeclaredAccessTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| try { |
| e.eval("try { print(foo); throw 'no ref error' } catch (e) { if (!(e instanceof ReferenceError)) throw e; }"); |
| } catch (final Exception exp) { |
| exp.printStackTrace(); |
| fail(exp.getMessage()); |
| } |
| } |
| |
| @Test |
| public void typeErrorForGlobalThisCallTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| try { |
| e.eval("try { this.foo() } catch(e) { if (! (e instanceof TypeError)) throw 'no type error' }"); |
| } catch (final Exception exp) { |
| exp.printStackTrace(); |
| fail(exp.getMessage()); |
| } |
| } |
| |
| @Test |
| public void refErrorForUndeclaredCallTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| try { |
| e.eval("try { foo() } catch(e) { if (! (e instanceof ReferenceError)) throw 'no ref error' }"); |
| } catch (final Exception exp) { |
| exp.printStackTrace(); |
| fail(exp.getMessage()); |
| } |
| } |
| |
| @Test |
| public void securityPackagesTest() { |
| if (System.getSecurityManager() == null) { |
| // pass vacuously |
| } |
| |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| try { |
| e.eval("var v = Packages.sun.misc.Unsafe;"); |
| fail("should have thrown SecurityException"); |
| } catch (final Exception exp) { |
| if (exp instanceof SecurityException) { |
| log("got " + exp + " as expected"); |
| } else { |
| fail(exp.getMessage()); |
| } |
| } |
| } |
| |
| @Test |
| public void securityJavaTypeTest() { |
| if (System.getSecurityManager() == null) { |
| // pass vacuously |
| } |
| |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| try { |
| e.eval("var v = Java.type('sun.misc.Unsafe');"); |
| fail("should have thrown SecurityException"); |
| } catch (final Exception exp) { |
| if (exp instanceof SecurityException) { |
| log("got " + exp + " as expected"); |
| } else { |
| fail(exp.getMessage()); |
| } |
| } |
| } |
| |
| @Test |
| public void securityClassForNameTest() { |
| if (System.getSecurityManager() == null) { |
| // pass vacuously |
| } |
| |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| try { |
| e.eval("var v = java.lang.Class.forName('sun.misc.Unsafe');"); |
| fail("should have thrown SecurityException"); |
| } catch (final Exception exp) { |
| if (exp instanceof SecurityException) { |
| log("got " + exp + " as expected"); |
| } else { |
| fail(exp.getMessage()); |
| } |
| } |
| } |
| |
| @Test |
| public void securitySystemExit() { |
| if (System.getSecurityManager() == null) { |
| // pass vacuously |
| } |
| |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| try { |
| e.eval("java.lang.System.exit(0);"); |
| fail("should have thrown SecurityException"); |
| } catch (final Exception exp) { |
| if (exp instanceof SecurityException) { |
| log("got " + exp + " as expected"); |
| } else { |
| fail(exp.getMessage()); |
| } |
| } |
| } |
| |
| @Test |
| public void securitySystemLoadLibrary() { |
| if (System.getSecurityManager() == null) { |
| // pass vacuously |
| } |
| |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| try { |
| e.eval("java.lang.System.loadLibrary('foo');"); |
| fail("should have thrown SecurityException"); |
| } catch (final Exception exp) { |
| if (exp instanceof SecurityException) { |
| log("got " + exp + " as expected"); |
| } else { |
| fail(exp.getMessage()); |
| } |
| } |
| } |
| |
| @Test |
| public void jsobjectTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| try { |
| e.eval("var obj = { '1': 'world', func: function() { return this.bar; }, bar: 'hello' }"); |
| JSObject obj = (JSObject) e.get("obj"); |
| |
| // try basic get on existing properties |
| if (! obj.getMember("bar").equals("hello")) { |
| fail("obj.bar != 'hello'"); |
| } |
| |
| if (! obj.getSlot(1).equals("world")) { |
| fail("obj[1] != 'world'"); |
| } |
| |
| if (! obj.call("func", new Object[0]).equals("hello")) { |
| fail("obj.call('func') != 'hello'"); |
| } |
| |
| // try setting properties |
| obj.setMember("bar", "new-bar"); |
| obj.setSlot(1, "new-element-1"); |
| if (! obj.getMember("bar").equals("new-bar")) { |
| fail("obj.bar != 'new-bar'"); |
| } |
| |
| if (! obj.getSlot(1).equals("new-element-1")) { |
| fail("obj[1] != 'new-element-1'"); |
| } |
| |
| // try adding properties |
| obj.setMember("prop", "prop-value"); |
| obj.setSlot(12, "element-12"); |
| if (! obj.getMember("prop").equals("prop-value")) { |
| fail("obj.prop != 'prop-value'"); |
| } |
| |
| if (! obj.getSlot(12).equals("element-12")) { |
| fail("obj[12] != 'element-12'"); |
| } |
| |
| // delete properties |
| obj.removeMember("prop"); |
| if ("prop-value".equals(obj.getMember("prop"))) { |
| fail("obj.prop is not deleted!"); |
| } |
| |
| } catch (final Exception exp) { |
| exp.printStackTrace(); |
| fail(exp.getMessage()); |
| } |
| } |
| |
| @Test |
| public void invokeFunctionExceptionTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| try { |
| e.eval("function func() { throw new TypeError(); }"); |
| } catch (final Throwable t) { |
| t.printStackTrace(); |
| fail(t.getMessage()); |
| } |
| |
| try { |
| ((Invocable)e).invokeFunction("func"); |
| fail("should have thrown exception"); |
| } catch (final ScriptException se) { |
| // ECMA TypeError property wrapped as a ScriptException |
| log("got " + se + " as expected"); |
| } catch (final Throwable t) { |
| t.printStackTrace(); |
| fail(t.getMessage()); |
| } |
| } |
| |
| @Test |
| public void invokeMethodExceptionTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| try { |
| e.eval("var sobj = {}; sobj.foo = function func() { throw new TypeError(); }"); |
| } catch (final Throwable t) { |
| t.printStackTrace(); |
| fail(t.getMessage()); |
| } |
| |
| try { |
| final Object sobj = e.get("sobj"); |
| ((Invocable)e).invokeMethod(sobj, "foo"); |
| fail("should have thrown exception"); |
| } catch (final ScriptException se) { |
| // ECMA TypeError property wrapped as a ScriptException |
| log("got " + se + " as expected"); |
| } catch (final Throwable t) { |
| t.printStackTrace(); |
| fail(t.getMessage()); |
| } |
| } |
| |
| @Test |
| public void scriptObjectMirrorToStringTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| try { |
| Object obj = e.eval("new TypeError('wrong type')"); |
| assertEquals(obj.toString(), "TypeError: wrong type", "toString returns wrong value"); |
| } catch (final Throwable t) { |
| t.printStackTrace(); |
| fail(t.getMessage()); |
| } |
| |
| try { |
| Object obj = e.eval("function func() { print('hello'); }"); |
| assertEquals(obj.toString(), "function func() { print('hello'); }", "toString returns wrong value"); |
| } catch (final Throwable t) { |
| t.printStackTrace(); |
| fail(t.getMessage()); |
| } |
| } |
| |
| @Test |
| public void engineScopeTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| Bindings engineScope = e.getBindings(ScriptContext.ENGINE_SCOPE); |
| |
| // check few ECMA standard built-in global properties |
| assertNotNull(engineScope.get("Object")); |
| assertNotNull(engineScope.get("TypeError")); |
| assertNotNull(engineScope.get("eval")); |
| |
| // can access via ScriptEngine.get as well |
| assertNotNull(e.get("Object")); |
| assertNotNull(e.get("TypeError")); |
| assertNotNull(e.get("eval")); |
| |
| // Access by either way should return same object |
| assertEquals(engineScope.get("Array"), e.get("Array")); |
| assertEquals(engineScope.get("EvalError"), e.get("EvalError")); |
| assertEquals(engineScope.get("undefined"), e.get("undefined")); |
| |
| // try exposing a new variable from scope |
| engineScope.put("myVar", "foo"); |
| try { |
| assertEquals(e.eval("myVar"), "foo"); |
| } catch (final ScriptException se) { |
| se.printStackTrace(); |
| fail(se.getMessage()); |
| } |
| |
| // update "myVar" in script an check the value from scope |
| try { |
| e.eval("myVar = 'nashorn';"); |
| } catch (final ScriptException se) { |
| se.printStackTrace(); |
| fail(se.getMessage()); |
| } |
| |
| // now check modified value from scope and engine |
| assertEquals(engineScope.get("myVar"), "nashorn"); |
| assertEquals(e.get("myVar"), "nashorn"); |
| } |
| |
| @Test |
| public void multiGlobalTest() { |
| final ScriptEngineManager m = new ScriptEngineManager(); |
| final ScriptEngine e = m.getEngineByName("nashorn"); |
| final Bindings b = e.createBindings(); |
| final ScriptContext newCtxt = new SimpleScriptContext(); |
| newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); |
| |
| try { |
| Object obj1 = e.eval("Object"); |
| Object obj2 = e.eval("Object", newCtxt); |
| Assert.assertNotEquals(obj1, obj2); |
| Assert.assertNotNull(obj1); |
| Assert.assertNotNull(obj2); |
| Assert.assertEquals(obj1.toString(), obj2.toString()); |
| |
| e.eval("x = 'hello'"); |
| e.eval("x = 'world'", newCtxt); |
| Object x1 = e.getContext().getAttribute("x"); |
| Object x2 = newCtxt.getAttribute("x"); |
| Assert.assertNotEquals(x1, x2); |
| Assert.assertEquals(x1, "hello"); |
| Assert.assertEquals(x2, "world"); |
| |
| x1 = e.eval("x"); |
| x2 = e.eval("x", newCtxt); |
| Assert.assertNotEquals(x1, x2); |
| Assert.assertEquals(x1, "hello"); |
| Assert.assertEquals(x2, "world"); |
| |
| final ScriptContext origCtxt = e.getContext(); |
| e.setContext(newCtxt); |
| e.eval("y = new Object()"); |
| e.eval("y = new Object()", origCtxt); |
| |
| Object y1 = origCtxt.getAttribute("y"); |
| Object y2 = newCtxt.getAttribute("y"); |
| Assert.assertNotEquals(y1, y2); |
| Assert.assertNotEquals(e.eval("y"), e.eval("y", origCtxt)); |
| Assert.assertEquals("[object Object]", y1.toString()); |
| Assert.assertEquals("[object Object]", y2.toString()); |
| } catch (final ScriptException se) { |
| se.printStackTrace(); |
| fail(se.getMessage()); |
| } |
| } |
| |
| @Test |
| public void factoryOptionsTest() { |
| final ScriptEngineManager sm = new ScriptEngineManager(); |
| for (ScriptEngineFactory fac : sm.getEngineFactories()) { |
| if (fac instanceof NashornScriptEngineFactory) { |
| final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac; |
| // specify --no-syntax-extensions flag |
| final String[] options = new String[] { "--no-syntax-extensions" }; |
| final ScriptEngine e = nfac.getScriptEngine(options); |
| try { |
| // try nashorn specific extension |
| e.eval("var f = funtion(x) 2*x;"); |
| fail("should have thrown exception!"); |
| } catch (final ScriptException se) { |
| } |
| return; |
| } |
| } |
| |
| fail("Cannot find nashorn factory!"); |
| } |
| } |