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