1 /*
   2  * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package jdk.nashorn.api.scripting;
  27 
  28 import static org.testng.Assert.assertEquals;
  29 import static org.testng.Assert.assertNotNull;
  30 import static org.testng.Assert.assertTrue;
  31 import static org.testng.Assert.fail;
  32 
  33 import java.io.StringReader;
  34 import java.io.StringWriter;
  35 import java.lang.reflect.Method;
  36 import java.util.HashMap;
  37 import java.util.Map;
  38 import java.util.concurrent.Callable;
  39 import javax.script.Bindings;
  40 import javax.script.Compilable;
  41 import javax.script.CompiledScript;
  42 import javax.script.Invocable;
  43 import javax.script.ScriptEngine;
  44 import javax.script.ScriptEngineFactory;
  45 import javax.script.ScriptEngineManager;
  46 import javax.script.ScriptException;
  47 import jdk.nashorn.internal.runtime.Version;
  48 import netscape.javascript.JSObject;
  49 import org.testng.TestNG;
  50 import org.testng.annotations.Test;
  51 
  52 /**
  53  * Tests for JSR-223 script engine for Nashorn.
  54  */
  55 public class ScriptEngineTest {
  56 
  57     public static void main(final String[] args) {
  58         TestNG.main(args);
  59     }
  60 
  61     private void log(String msg) {
  62         org.testng.Reporter.log(msg, true);
  63     }
  64 
  65     @Test
  66     public void argumentsTest() {
  67         final ScriptEngineManager m = new ScriptEngineManager();
  68         final ScriptEngine e = m.getEngineByName("nashorn");
  69 
  70         String[] args = new String[] { "hello", "world" };
  71         try {
  72             e.put("arguments", args);
  73             Object arg0 = e.eval("arguments[0]");
  74             Object arg1 = e.eval("arguments[1]");
  75             assertEquals(args[0], arg0);
  76             assertEquals(args[1], arg1);
  77         } catch (final Exception exp) {
  78             exp.printStackTrace();
  79             fail(exp.getMessage());
  80         }
  81     }
  82 
  83     @Test
  84     public void argumentsWithTest() {
  85         final ScriptEngineManager m = new ScriptEngineManager();
  86         final ScriptEngine e = m.getEngineByName("nashorn");
  87 
  88         String[] args = new String[] { "hello", "world" };
  89         try {
  90             e.put("arguments", args);
  91             Object arg0 = e.eval("var imports = new JavaImporter(java.io); " +
  92                     " with(imports) { arguments[0] }");
  93             Object arg1 = e.eval("var imports = new JavaImporter(java.util, java.io); " +
  94                     " with(imports) { arguments[1] }");
  95             assertEquals(args[0], arg0);
  96             assertEquals(args[1], arg1);
  97         } catch (final Exception exp) {
  98             exp.printStackTrace();
  99             fail(exp.getMessage());
 100         }
 101     }
 102 
 103     @Test
 104     public void argumentsEmptyTest() {
 105         final ScriptEngineManager m = new ScriptEngineManager();
 106         final ScriptEngine e = m.getEngineByName("nashorn");
 107 
 108         try {
 109             assertEquals(true,e.eval("arguments instanceof Array"));
 110             assertEquals(true, e.eval("arguments.length == 0"));
 111         } catch (final Exception exp) {
 112             exp.printStackTrace();
 113             fail(exp.getMessage());
 114         }
 115     }
 116 
 117     @Test
 118     public void factoryTests() {
 119         final ScriptEngineManager m = new ScriptEngineManager();
 120         final ScriptEngine e = m.getEngineByName("nashorn");
 121         assertNotNull(e);
 122 
 123         final ScriptEngineFactory fac = e.getFactory();
 124 
 125         assertEquals("ECMAScript", fac.getLanguageName());
 126         assertEquals("javascript", fac.getParameter(ScriptEngine.NAME));
 127         assertEquals("ECMA - 262 Edition 5.1", fac.getLanguageVersion());
 128         assertEquals("Oracle Nashorn", fac.getEngineName());
 129         assertEquals(Version.version(), fac.getEngineVersion());
 130         assertEquals("print(context)", fac.getOutputStatement("context"));
 131         assertEquals("javascript", fac.getParameter(ScriptEngine.NAME));
 132 
 133         boolean seenJS = false;
 134         for (String ext : fac.getExtensions()) {
 135             if (ext.equals("js")) {
 136                 seenJS = true;
 137             }
 138         }
 139 
 140         assertEquals(true, seenJS);
 141         String str = fac.getMethodCallSyntax("obj", "foo", "x");
 142         assertEquals("obj.foo(x)", str);
 143 
 144         boolean seenNashorn = false, seenJavaScript = false, seenECMAScript = false;
 145         for (String name : fac.getNames()) {
 146             switch (name) {
 147                 case "nashorn": seenNashorn = true; break;
 148                 case "javascript": seenJavaScript = true; break;
 149                 case "ECMAScript": seenECMAScript = true; break;
 150             }
 151         }
 152 
 153         assertEquals(true, seenNashorn);
 154         assertEquals(true, seenJavaScript);
 155         assertEquals(true, seenECMAScript);
 156 
 157         boolean seenAppJS = false, seenAppECMA = false, seenTextJS = false, seenTextECMA = false;
 158         for (String mime : fac.getMimeTypes()) {
 159             switch (mime) {
 160                 case "application/javascript": seenAppJS = true; break;
 161                 case "application/ecmascript": seenAppECMA = true; break;
 162                 case "text/javascript": seenTextJS = true; break;
 163                 case "text/ecmascript": seenTextECMA = true; break;
 164             }
 165         }
 166 
 167         assertEquals(true, seenAppJS);
 168         assertEquals(true, seenAppECMA);
 169         assertEquals(true, seenTextJS);
 170         assertEquals(true, seenTextECMA);
 171     }
 172 
 173     @Test
 174     public void evalTests() {
 175         final ScriptEngineManager m = new ScriptEngineManager();
 176         final ScriptEngine e = m.getEngineByName("nashorn");
 177         e.put(ScriptEngine.FILENAME, "myfile.js");
 178 
 179         try {
 180             e.eval("print('hello')");
 181         } catch (final ScriptException se) {
 182             fail(se.getMessage());
 183         }
 184         try {
 185             e.eval("print('hello)");
 186             fail("script exception expected");
 187         } catch (final ScriptException se) {
 188             assertEquals(1, se.getLineNumber());
 189             assertEquals(13, se.getColumnNumber());
 190             assertEquals("myfile.js", se.getFileName());
 191             // se.printStackTrace();
 192         }
 193 
 194         try {
 195             Object obj = e.eval("34 + 41");
 196             assertTrue(34.0 + 41.0 == ((Number)obj).doubleValue());
 197             obj = e.eval("x = 5");
 198             assertTrue(5.0 == ((Number)obj).doubleValue());
 199         } catch (final ScriptException se) {
 200             se.printStackTrace();
 201             fail(se.getMessage());
 202         }
 203     }
 204 
 205     @Test
 206     public void compileTests() {
 207         final ScriptEngineManager m = new ScriptEngineManager();
 208         final ScriptEngine e = m.getEngineByName("nashorn");
 209         CompiledScript script = null;
 210 
 211         try {
 212             script = ((Compilable)e).compile("print('hello')");
 213         } catch (final ScriptException se) {
 214             fail(se.getMessage());
 215         }
 216 
 217         try {
 218             script.eval();
 219         } catch (final ScriptException | NullPointerException se) {
 220             se.printStackTrace();
 221             fail(se.getMessage());
 222         }
 223 
 224         // try to compile from a Reader
 225         try {
 226             script = ((Compilable)e).compile(new StringReader("print('world')"));
 227         } catch (final ScriptException se) {
 228             fail(se.getMessage());
 229         }
 230 
 231         try {
 232             script.eval();
 233         } catch (final ScriptException | NullPointerException se) {
 234             se.printStackTrace();
 235             fail(se.getMessage());
 236         }
 237     }
 238 
 239     @Test
 240     public void createBindingsTest() {
 241         final ScriptEngineManager m = new ScriptEngineManager();
 242         final ScriptEngine e = m.getEngineByName("nashorn");
 243         Bindings b = e.createBindings();
 244         b.put("foo", 42.0);
 245         Object res = null;
 246         try {
 247             res = e.eval("foo == 42.0", b);
 248         } catch (final ScriptException | NullPointerException se) {
 249             se.printStackTrace();
 250             fail(se.getMessage());
 251         }
 252 
 253         assertEquals(Boolean.TRUE, res);
 254     }
 255 
 256     @Test
 257     public void getInterfaceTest() {
 258         final ScriptEngineManager m = new ScriptEngineManager();
 259         final ScriptEngine e = m.getEngineByName("nashorn");
 260         final Invocable inv = (Invocable)e;
 261 
 262         // try to get interface from global functions
 263         try {
 264             e.eval("function run() { print('run'); };");
 265             final Runnable runnable = inv.getInterface(Runnable.class);
 266             runnable.run();
 267         } catch (final Exception exp) {
 268             exp.printStackTrace();
 269             fail(exp.getMessage());
 270         }
 271 
 272         // try interface on specific script object
 273         try {
 274             e.eval("var obj = { run: function() { print('run from obj'); } };");
 275             Object obj = e.get("obj");
 276             final Runnable runnable = inv.getInterface(obj, Runnable.class);
 277             runnable.run();
 278         } catch (final Exception exp) {
 279             exp.printStackTrace();
 280             fail(exp.getMessage());
 281         }
 282     }
 283 
 284     @Test
 285     public void accessGlobalTest() {
 286         final ScriptEngineManager m = new ScriptEngineManager();
 287         final ScriptEngine e = m.getEngineByName("nashorn");
 288 
 289         try {
 290             e.eval("var x = 'hello'");
 291             assertEquals("hello", e.get("x"));
 292         } catch (final ScriptException exp) {
 293             exp.printStackTrace();
 294             fail(exp.getMessage());
 295         }
 296     }
 297 
 298     @Test
 299     public void exposeGlobalTest() {
 300         final ScriptEngineManager m = new ScriptEngineManager();
 301         final ScriptEngine e = m.getEngineByName("nashorn");
 302 
 303         try {
 304             e.put("y", "foo");
 305             e.eval("print(y)");
 306         } catch (final ScriptException exp) {
 307             exp.printStackTrace();
 308             fail(exp.getMessage());
 309         }
 310     }
 311 
 312     public static void alert(final Object self, final Object msg) {
 313         System.out.println(msg);
 314     }
 315 
 316     @Test
 317     public void exposeFunctionTest() {
 318         final ScriptEngineManager m = new ScriptEngineManager();
 319         final ScriptEngine e = m.getEngineByName("nashorn");
 320 
 321         try {
 322             final Method alert = ScriptEngineTest.class.getMethod("alert", Object.class, Object.class);
 323             // expose a Method object as global var.
 324             e.put("alert", alert);
 325             // call the global var.
 326             e.eval("alert('alert! alert!!')");
 327         } catch (final NoSuchMethodException | SecurityException | ScriptException exp) {
 328             exp.printStackTrace();
 329             fail(exp.getMessage());
 330         }
 331     }
 332 
 333     @Test
 334     public void putGlobalFunctionTest() {
 335         final ScriptEngineManager m = new ScriptEngineManager();
 336         final ScriptEngine e = m.getEngineByName("nashorn");
 337 
 338         e.put("callable", new Callable<String>() {
 339             @Override
 340             public String call() throws Exception {
 341                 return "callable was called";
 342             }
 343         });
 344 
 345         try {
 346             e.eval("print(callable.call())");
 347         } catch (final ScriptException exp) {
 348             exp.printStackTrace();
 349             fail(exp.getMessage());
 350         }
 351     }
 352 
 353     @Test
 354     public void windowAlertTest() {
 355         final ScriptEngineManager m = new ScriptEngineManager();
 356         final ScriptEngine e = m.getEngineByName("nashorn");
 357         final Window window = new Window();
 358 
 359         try {
 360             e.put("window", window);
 361             e.eval("print(window.alert)"); // TODO: bug - prints 'undefined'
 362             e.eval("window.alert('calling window.alert...')");
 363             // TODO: java.lang.NoSuchMethodException: alert
 364             // ((Invocable) e).invokeMethod(window, "alert",
 365             // "invoking window.alert...");
 366         } catch (final Exception exp) {
 367             exp.printStackTrace();
 368             fail(exp.getMessage());
 369         }
 370     }
 371 
 372     @Test
 373     public void windowLocationTest() {
 374         final ScriptEngineManager m = new ScriptEngineManager();
 375         final ScriptEngine e = m.getEngineByName("nashorn");
 376         final Window window = new Window();
 377 
 378         try {
 379             e.put("window", window);
 380             e.eval("print(window.location)");
 381             final Object locationValue = ((Invocable)e).invokeMethod(window, "getLocation");
 382             assertEquals("http://localhost:8080/window", locationValue);
 383         } catch (final Exception exp) {
 384             exp.printStackTrace();
 385             fail(exp.getMessage());
 386         }
 387     }
 388 
 389     @Test
 390     public void windowItemTest() {
 391         final ScriptEngineManager m = new ScriptEngineManager();
 392         final ScriptEngine e = m.getEngineByName("nashorn");
 393         final Window window = new Window();
 394 
 395         try {
 396             e.put("window", window);
 397             final String item1 = (String)e.eval("window.item(65535)");
 398             assertEquals("ffff", item1);
 399             final String item2 = (String)((Invocable)e).invokeMethod(window, "item", 255);
 400             assertEquals("ff", item2);
 401         } catch (final Exception exp) {
 402             exp.printStackTrace();
 403             fail(exp.getMessage());
 404         }
 405     }
 406 
 407     @Test
 408     public void windowEventTest() {
 409         final ScriptEngineManager m = new ScriptEngineManager();
 410         final ScriptEngine e = m.getEngineByName("nashorn");
 411         final Window window = new Window();
 412 
 413         try {
 414             e.put("window", window);
 415             e.eval("window.onload = function() { print('window load event fired'); return true }");
 416             assertTrue((Boolean)e.eval("window.onload.loaded()"));
 417             final WindowEventHandler handler = window.getOnload();
 418             assertNotNull(handler);
 419             assertTrue(handler.loaded());
 420         } catch (final Exception exp) {
 421             exp.printStackTrace();
 422             fail(exp.getMessage());
 423         }
 424     }
 425 
 426     @Test
 427     public void throwTest() {
 428         final ScriptEngineManager m = new ScriptEngineManager();
 429         final ScriptEngine e = m.getEngineByName("nashorn");
 430         e.put(ScriptEngine.FILENAME, "throwtest.js");
 431 
 432         try {
 433             e.eval("throw 'foo'");
 434         } catch (final ScriptException exp) {
 435             log(exp.getMessage());
 436             assertEquals("foo in throwtest.js at line number 1 at column number 0", exp.getMessage());
 437             assertEquals("throwtest.js", exp.getFileName());
 438             assertEquals(1, exp.getLineNumber());
 439         }
 440     }
 441 
 442     @Test
 443     public void setTimeoutTest() {
 444         final ScriptEngineManager m = new ScriptEngineManager();
 445         final ScriptEngine e = m.getEngineByName("nashorn");
 446         final Window window = new Window();
 447 
 448         try {
 449             final Class<?> setTimeoutParamTypes[] = { Window.class, String.class, int.class };
 450             final Method setTimeout = Window.class.getDeclaredMethod("setTimeout", setTimeoutParamTypes);
 451             assertNotNull(setTimeout);
 452             e.put("window", window);
 453             e.eval("window.setTimeout('foo()', 100)");
 454 
 455             // try to make setTimeout global
 456             e.put("setTimeout", setTimeout);
 457             // TODO: java.lang.ClassCastException: required class
 458             // java.lang.Integer but encountered class java.lang.Double
 459             // e.eval("setTimeout('foo2()', 200)");
 460         } catch (final Exception exp) {
 461             exp.printStackTrace();
 462             fail(exp.getMessage());
 463         }
 464     }
 465 
 466     @Test
 467     public void setWriterTest() {
 468         final ScriptEngineManager m = new ScriptEngineManager();
 469         final ScriptEngine e = m.getEngineByName("nashorn");
 470         final StringWriter sw = new StringWriter();
 471         e.getContext().setWriter(sw);
 472 
 473         try {
 474             e.eval("print('hello world')");
 475         } catch (final Exception exp) {
 476             exp.printStackTrace();
 477             fail(exp.getMessage());
 478         }
 479         // dos2unix - fix line endings if running on windows
 480         assertEquals(sw.toString().replaceAll("\r", ""), "hello world\n");
 481     }
 482 
 483     @SuppressWarnings("unchecked")
 484     @Test
 485     public void reflectionTest() throws ScriptException {
 486         final ScriptEngineManager m = new ScriptEngineManager();
 487         final ScriptEngine e = m.getEngineByName("nashorn");
 488 
 489         e.eval("var obj = { x: 344, y: 'nashorn' }");
 490 
 491         int count = 0;
 492         Map<Object, Object> map = (Map<Object, Object>)e.get("obj");
 493         assertEquals(false, map.isEmpty());
 494         assertEquals(true, map.keySet().contains("x"));
 495         assertEquals(true, map.containsKey("x"));
 496         assertEquals(true, map.values().contains("nashorn"));
 497         assertEquals(true, map.containsValue("nashorn"));
 498         for (final Map.Entry<?, ?> ex : map.entrySet()) {
 499             final Object key = ex.getKey();
 500             if (key.equals("x")) {
 501                 assertTrue(344 == ((Number)ex.getValue()).doubleValue());
 502                 count++;
 503             } else if (key.equals("y")) {
 504                 assertEquals("nashorn", ex.getValue());
 505                 count++;
 506             }
 507         }
 508         assertEquals(2, count);
 509         assertEquals(2, map.size());
 510 
 511         // add property
 512         map.put("z", "hello");
 513         assertEquals("hello", e.eval("obj.z"));
 514         assertEquals("hello", map.get("z"));
 515         assertEquals(true, map.keySet().contains("z"));
 516         assertEquals(true, map.containsKey("z"));
 517         assertEquals(true, map.values().contains("hello"));
 518         assertEquals(true, map.containsValue("hello"));
 519         assertEquals(3, map.size());
 520 
 521         final Map<Object, Object> newMap = new HashMap<>();
 522         newMap.put("foo", 23.0);
 523         newMap.put("bar", true);
 524         map.putAll(newMap);
 525 
 526         assertEquals(23.0, e.eval("obj.foo"));
 527         assertEquals(true, e.eval("obj.bar"));
 528 
 529         // remove using map method
 530         map.remove("foo");
 531         assertEquals("undefined", e.eval("typeof obj.foo"));
 532 
 533         count = 0;
 534         e.eval("var arr = [ true, 'hello' ]");
 535         map = (Map<Object, Object>)e.get("arr");
 536         assertEquals(false, map.isEmpty());
 537         assertEquals(true, map.containsKey("length"));
 538         assertEquals(true, map.containsValue("hello"));
 539         for (final Map.Entry<?, ?> ex : map.entrySet()) {
 540             final Object key = ex.getKey();
 541             if (key.equals("0")) {
 542                 assertEquals(Boolean.TRUE, ex.getValue());
 543                 count++;
 544             } else if (key.equals("1")) {
 545                 assertEquals("hello", ex.getValue());
 546                 count++;
 547             }
 548         }
 549         assertEquals(2, count);
 550         assertEquals(2, map.size());
 551 
 552         // add element
 553         map.put(2, "world");
 554         assertEquals("world", map.get(2));
 555         assertEquals(3, map.size());
 556 
 557         // remove all
 558         map.clear();
 559         assertEquals(true, map.isEmpty());
 560         assertEquals("undefined", e.eval("typeof arr[0]"));
 561         assertEquals("undefined", e.eval("typeof arr[1]"));
 562         assertEquals("undefined", e.eval("typeof arr[2]"));
 563     }
 564 
 565     @Test
 566     public void redefineEchoTest() {
 567         final ScriptEngineManager m = new ScriptEngineManager();
 568         final ScriptEngine e = m.getEngineByName("nashorn");
 569 
 570         try {
 571             e.eval("var echo = {}; if (typeof echo !== 'object') { throw 'echo is a '+typeof echo; }");
 572         } catch (final Exception exp) {
 573             exp.printStackTrace();
 574             fail(exp.getMessage());
 575         }
 576     }
 577 
 578     @Test
 579     public void invokeMethodTest() {
 580         final ScriptEngineManager m = new ScriptEngineManager();
 581         final ScriptEngine e = m.getEngineByName("nashorn");
 582 
 583         try {
 584             e.eval("var Example = function() { this.hello = function() { return 'Hello World!'; };}; myExample = new Example();");
 585             final Object obj = e.get("myExample");
 586             final Object res = ((Invocable)e).invokeMethod(obj, "hello");
 587             assertEquals("Hello World!", res);
 588         } catch (final Exception exp) {
 589             exp.printStackTrace();
 590             fail(exp.getMessage());
 591         }
 592     }
 593 
 594     @Test
 595     public void versionTest() {
 596         final ScriptEngineManager m = new ScriptEngineManager();
 597         final ScriptEngine e = m.getEngineByName("nashorn");
 598         assertEquals(e.getFactory().getEngineVersion(), Version.version());
 599     }
 600 
 601     @Test
 602     public void noEnumerablePropertiesTest() {
 603         final ScriptEngineManager m = new ScriptEngineManager();
 604         final ScriptEngine e = m.getEngineByName("nashorn");
 605         try {
 606             e.eval("for (i in this) { throw 'found property: ' + i }");
 607         } catch (final Exception exp) {
 608             exp.printStackTrace();
 609             fail(exp.getMessage());
 610         }
 611     }
 612 
 613     @Test
 614     public void noRefErrorForGlobalThisAccessTest() {
 615         final ScriptEngineManager m = new ScriptEngineManager();
 616         final ScriptEngine e = m.getEngineByName("nashorn");
 617         try {
 618             e.eval("this.foo");
 619         } catch (final Exception exp) {
 620             exp.printStackTrace();
 621             fail(exp.getMessage());
 622         }
 623     }
 624 
 625     @Test
 626     public void refErrorForUndeclaredAccessTest() {
 627         final ScriptEngineManager m = new ScriptEngineManager();
 628         final ScriptEngine e = m.getEngineByName("nashorn");
 629         try {
 630             e.eval("try { print(foo); throw 'no ref error' } catch (e) { if (!(e instanceof ReferenceError)) throw e; }");
 631         } catch (final Exception exp) {
 632             exp.printStackTrace();
 633             fail(exp.getMessage());
 634         }
 635     }
 636 
 637     @Test
 638     public void typeErrorForGlobalThisCallTest() {
 639         final ScriptEngineManager m = new ScriptEngineManager();
 640         final ScriptEngine e = m.getEngineByName("nashorn");
 641         try {
 642             e.eval("try { this.foo() } catch(e) { if (! (e instanceof TypeError)) throw 'no type error' }");
 643         } catch (final Exception exp) {
 644             exp.printStackTrace();
 645             fail(exp.getMessage());
 646         }
 647     }
 648 
 649     @Test
 650     public void refErrorForUndeclaredCallTest() {
 651         final ScriptEngineManager m = new ScriptEngineManager();
 652         final ScriptEngine e = m.getEngineByName("nashorn");
 653         try {
 654             e.eval("try { foo() } catch(e) { if (! (e instanceof ReferenceError)) throw 'no ref error' }");
 655         } catch (final Exception exp) {
 656             exp.printStackTrace();
 657             fail(exp.getMessage());
 658         }
 659     }
 660 
 661     @Test
 662     public void securityPackagesTest() {
 663         if (System.getSecurityManager() == null) {
 664             // pass vacuously
 665         }
 666 
 667         final ScriptEngineManager m = new ScriptEngineManager();
 668         final ScriptEngine e = m.getEngineByName("nashorn");
 669         try {
 670             e.eval("var v = Packages.sun.misc.Unsafe;");
 671             fail("should have thrown SecurityException");
 672         } catch (final Exception exp) {
 673             if (exp instanceof SecurityException) {
 674                 log("got " + exp + " as expected");
 675             } else {
 676                 fail(exp.getMessage());
 677             }
 678         }
 679     }
 680 
 681     @Test
 682     public void securityJavaTypeTest() {
 683         if (System.getSecurityManager() == null) {
 684             // pass vacuously
 685         }
 686 
 687         final ScriptEngineManager m = new ScriptEngineManager();
 688         final ScriptEngine e = m.getEngineByName("nashorn");
 689         try {
 690             e.eval("var v = Java.type('sun.misc.Unsafe');");
 691             fail("should have thrown SecurityException");
 692         } catch (final Exception exp) {
 693             if (exp instanceof SecurityException) {
 694                 log("got " + exp + " as expected");
 695             } else {
 696                 fail(exp.getMessage());
 697             }
 698         }
 699     }
 700 
 701     @Test
 702     public void securityClassForNameTest() {
 703         if (System.getSecurityManager() == null) {
 704             // pass vacuously
 705         }
 706 
 707         final ScriptEngineManager m = new ScriptEngineManager();
 708         final ScriptEngine e = m.getEngineByName("nashorn");
 709         try {
 710             e.eval("var v = java.lang.Class.forName('sun.misc.Unsafe');");
 711             fail("should have thrown SecurityException");
 712         } catch (final Exception exp) {
 713             if (exp instanceof SecurityException) {
 714                 log("got " + exp + " as expected");
 715             } else {
 716                 fail(exp.getMessage());
 717             }
 718         }
 719     }
 720 
 721     @Test
 722     public void securitySystemExit() {
 723         if (System.getSecurityManager() == null) {
 724             // pass vacuously
 725         }
 726 
 727         final ScriptEngineManager m = new ScriptEngineManager();
 728         final ScriptEngine e = m.getEngineByName("nashorn");
 729         try {
 730             e.eval("java.lang.System.exit(0);");
 731             fail("should have thrown SecurityException");
 732         } catch (final Exception exp) {
 733             if (exp instanceof SecurityException) {
 734                 log("got " + exp + " as expected");
 735             } else {
 736                 fail(exp.getMessage());
 737             }
 738         }
 739     }
 740 
 741     @Test
 742     public void securitySystemLoadLibrary() {
 743         if (System.getSecurityManager() == null) {
 744             // pass vacuously
 745         }
 746 
 747         final ScriptEngineManager m = new ScriptEngineManager();
 748         final ScriptEngine e = m.getEngineByName("nashorn");
 749         try {
 750             e.eval("java.lang.System.loadLibrary('foo');");
 751             fail("should have thrown SecurityException");
 752         } catch (final Exception exp) {
 753             if (exp instanceof SecurityException) {
 754                 log("got " + exp + " as expected");
 755             } else {
 756                 fail(exp.getMessage());
 757             }
 758         }
 759     }
 760 
 761     @Test
 762     public void jsobjectTest() {
 763         final ScriptEngineManager m = new ScriptEngineManager();
 764         final ScriptEngine e = m.getEngineByName("nashorn");
 765         try {
 766             e.eval("var obj = { '1': 'world', func: function() { return this.bar; }, bar: 'hello' }");
 767             JSObject obj = (JSObject) e.get("obj");
 768 
 769             // try basic get on existing properties
 770             if (! obj.getMember("bar").equals("hello")) {
 771                 fail("obj.bar != 'hello'");
 772             }
 773 
 774             if (! obj.getSlot(1).equals("world")) {
 775                 fail("obj[1] != 'world'");
 776             }
 777 
 778             if (! obj.call("func", new Object[0]).equals("hello")) {
 779                 fail("obj.call('func') != 'hello'");
 780             }
 781 
 782             // try setting properties
 783             obj.setMember("bar", "new-bar");
 784             obj.setSlot(1, "new-element-1");
 785             if (! obj.getMember("bar").equals("new-bar")) {
 786                 fail("obj.bar != 'new-bar'");
 787             }
 788 
 789             if (! obj.getSlot(1).equals("new-element-1")) {
 790                 fail("obj[1] != 'new-element-1'");
 791             }
 792 
 793             // try adding properties
 794             obj.setMember("prop", "prop-value");
 795             obj.setSlot(12, "element-12");
 796             if (! obj.getMember("prop").equals("prop-value")) {
 797                 fail("obj.prop != 'prop-value'");
 798             }
 799 
 800             if (! obj.getSlot(12).equals("element-12")) {
 801                 fail("obj[12] != 'element-12'");
 802             }
 803 
 804             // delete properties
 805             obj.removeMember("prop");
 806             if ("prop-value".equals(obj.getMember("prop"))) {
 807                 fail("obj.prop is not deleted!");
 808             }
 809 
 810         } catch (final Exception exp) {
 811             exp.printStackTrace();
 812             fail(exp.getMessage());
 813         }
 814     }
 815 
 816     @Test
 817     public void invokeFunctionExceptionTest() {
 818         final ScriptEngineManager m = new ScriptEngineManager();
 819         final ScriptEngine e = m.getEngineByName("nashorn");
 820         try {
 821             e.eval("function func() { throw new TypeError(); }");
 822         } catch (final Throwable t) {
 823             t.printStackTrace();
 824             fail(t.getMessage());
 825         }
 826 
 827         try {
 828             ((Invocable)e).invokeFunction("func");
 829             fail("should have thrown exception");
 830         } catch (final ScriptException se) {
 831             // ECMA TypeError property wrapped as a ScriptException
 832             log("got " + se + " as expected");
 833         } catch (final Throwable t) {
 834             t.printStackTrace();
 835             fail(t.getMessage());
 836         }
 837     }
 838 
 839     @Test
 840     public void invokeMethodExceptionTest() {
 841         final ScriptEngineManager m = new ScriptEngineManager();
 842         final ScriptEngine e = m.getEngineByName("nashorn");
 843         try {
 844             e.eval("var sobj = {}; sobj.foo = function func() { throw new TypeError(); }");
 845         } catch (final Throwable t) {
 846             t.printStackTrace();
 847             fail(t.getMessage());
 848         }
 849 
 850         try {
 851             final Object sobj = e.get("sobj");
 852             ((Invocable)e).invokeMethod(sobj, "foo");
 853             fail("should have thrown exception");
 854         } catch (final ScriptException se) {
 855             // ECMA TypeError property wrapped as a ScriptException
 856             log("got " + se + " as expected");
 857         } catch (final Throwable t) {
 858             t.printStackTrace();
 859             fail(t.getMessage());
 860         }
 861     }
 862 }