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.assertNull; 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.InvocationHandler; 37 import java.lang.reflect.Method; 38 import java.lang.reflect.Proxy; 39 import java.util.Collections; 40 import java.util.concurrent.Callable; 41 import java.util.concurrent.atomic.AtomicBoolean; 42 import java.util.function.Consumer; 43 import java.util.function.Function; 44 import javax.script.Bindings; 45 import javax.script.Compilable; 46 import javax.script.CompiledScript; 47 import javax.script.Invocable; 48 import javax.script.ScriptContext; 49 import javax.script.ScriptEngine; 50 import javax.script.ScriptEngineFactory; 51 import javax.script.ScriptEngineManager; 52 import javax.script.ScriptException; 53 import javax.script.SimpleScriptContext; 54 import org.testng.annotations.Test; 55 56 /** 57 * Tests for JSR-223 script engine for Nashorn. 58 * 59 * @test 60 * @build jdk.nashorn.api.scripting.Window jdk.nashorn.api.scripting.WindowEventHandler jdk.nashorn.api.scripting.VariableArityTestInterface jdk.nashorn.api.scripting.ScriptEngineTest 61 * @run testng/othervm jdk.nashorn.api.scripting.ScriptEngineTest 62 */ 63 @SuppressWarnings("javadoc") 64 public class ScriptEngineTest { 65 66 private static void log(final String msg) { 67 org.testng.Reporter.log(msg, true); 68 } 69 70 @Test 71 public void argumentsTest() { 72 final ScriptEngineManager m = new ScriptEngineManager(); 73 final ScriptEngine e = m.getEngineByName("nashorn"); 74 75 final String[] args = new String[] { "hello", "world" }; 76 try { 77 e.put("arguments", args); 78 final Object arg0 = e.eval("arguments[0]"); 79 final Object arg1 = e.eval("arguments[1]"); 80 assertEquals(args[0], arg0); 81 assertEquals(args[1], arg1); 82 } catch (final Exception exp) { 83 exp.printStackTrace(); 84 fail(exp.getMessage()); 85 } 86 } 87 88 @Test 89 public void argumentsWithTest() { 90 final ScriptEngineManager m = new ScriptEngineManager(); 91 final ScriptEngine e = m.getEngineByName("nashorn"); 92 93 final String[] args = new String[] { "hello", "world" }; 94 try { 95 e.put("arguments", args); 96 final Object arg0 = e.eval("var imports = new JavaImporter(java.io); " + 97 " with(imports) { arguments[0] }"); 98 final Object arg1 = e.eval("var imports = new JavaImporter(java.util, java.io); " + 99 " with(imports) { arguments[1] }"); 100 assertEquals(args[0], arg0); 101 assertEquals(args[1], arg1); 102 } catch (final Exception exp) { 103 exp.printStackTrace(); 104 fail(exp.getMessage()); 105 } 106 } 107 108 @Test 109 public void argumentsEmptyTest() { 110 final ScriptEngineManager m = new ScriptEngineManager(); 111 final ScriptEngine e = m.getEngineByName("nashorn"); 112 113 try { 114 assertEquals(e.eval("arguments instanceof Array"), true); 115 assertEquals(e.eval("arguments.length == 0"), true); 116 } catch (final Exception exp) { 117 exp.printStackTrace(); 118 fail(exp.getMessage()); 119 } 120 } 121 122 @Test 123 public void factoryTests() { 124 final ScriptEngineManager m = new ScriptEngineManager(); 125 final ScriptEngine e = m.getEngineByName("nashorn"); 126 assertNotNull(e); 127 128 final ScriptEngineFactory fac = e.getFactory(); 129 130 assertEquals(fac.getLanguageName(), "ECMAScript"); 131 assertEquals(fac.getParameter(ScriptEngine.NAME), "javascript"); 132 assertEquals(fac.getLanguageVersion(), "ECMA - 262 Edition 5.1"); 133 assertEquals(fac.getEngineName(), "Oracle Nashorn"); 134 assertEquals(fac.getOutputStatement("context"), "print(context)"); 135 assertEquals(fac.getProgram("print('hello')", "print('world')"), "print('hello');print('world');"); 136 assertEquals(fac.getParameter(ScriptEngine.NAME), "javascript"); 137 138 boolean seenJS = false; 139 for (final String ext : fac.getExtensions()) { 140 if (ext.equals("js")) { 141 seenJS = true; 142 } 143 } 144 145 assertEquals(seenJS, true); 146 final String str = fac.getMethodCallSyntax("obj", "foo", "x"); 147 assertEquals(str, "obj.foo(x)"); 148 149 boolean seenNashorn = false, seenJavaScript = false, seenECMAScript = false; 150 for (final String name : fac.getNames()) { 151 switch (name) { 152 case "nashorn": seenNashorn = true; break; 153 case "javascript": seenJavaScript = true; break; 154 case "ECMAScript": seenECMAScript = true; break; 155 default: 156 break; 157 } 158 } 159 160 assertTrue(seenNashorn); 161 assertTrue(seenJavaScript); 162 assertTrue(seenECMAScript); 163 164 boolean seenAppJS = false, seenAppECMA = false, seenTextJS = false, seenTextECMA = false; 165 for (final String mime : fac.getMimeTypes()) { 166 switch (mime) { 167 case "application/javascript": seenAppJS = true; break; 168 case "application/ecmascript": seenAppECMA = true; break; 169 case "text/javascript": seenTextJS = true; break; 170 case "text/ecmascript": seenTextECMA = true; break; 171 default: 172 break; 173 } 174 } 175 176 assertTrue(seenAppJS); 177 assertTrue(seenAppECMA); 178 assertTrue(seenTextJS); 179 assertTrue(seenTextECMA); 180 } 181 182 @Test 183 public void evalTests() { 184 final ScriptEngineManager m = new ScriptEngineManager(); 185 final ScriptEngine e = m.getEngineByName("nashorn"); 186 e.put(ScriptEngine.FILENAME, "myfile.js"); 187 188 try { 189 e.eval("print('hello')"); 190 } catch (final ScriptException se) { 191 fail(se.getMessage()); 192 } 193 try { 194 e.eval("print('hello)"); 195 fail("script exception expected"); 196 } catch (final ScriptException se) { 197 assertEquals(se.getLineNumber(), 1); 198 assertEquals(se.getColumnNumber(), 13); 199 assertEquals(se.getFileName(), "myfile.js"); 200 // se.printStackTrace(); 201 } 202 203 try { 204 Object obj = e.eval("34 + 41"); 205 assertTrue(34.0 + 41.0 == ((Number)obj).doubleValue()); 206 obj = e.eval("x = 5"); 207 assertTrue(5.0 == ((Number)obj).doubleValue()); 208 } catch (final ScriptException se) { 209 se.printStackTrace(); 210 fail(se.getMessage()); 211 } 212 } 213 214 @Test 215 public void compileTests() { 216 final ScriptEngineManager m = new ScriptEngineManager(); 217 final ScriptEngine e = m.getEngineByName("nashorn"); 218 CompiledScript script = null; 219 220 try { 221 script = ((Compilable)e).compile("print('hello')"); 222 } catch (final ScriptException se) { 223 fail(se.getMessage()); 224 } 225 226 try { 227 script.eval(); 228 } catch (final ScriptException | NullPointerException se) { 229 se.printStackTrace(); 230 fail(se.getMessage()); 231 } 232 233 // try to compile from a Reader 234 try { 235 script = ((Compilable)e).compile(new StringReader("print('world')")); 236 } catch (final ScriptException se) { 237 fail(se.getMessage()); 238 } 239 240 try { 241 script.eval(); 242 } catch (final ScriptException | NullPointerException se) { 243 se.printStackTrace(); 244 fail(se.getMessage()); 245 } 246 } 247 248 @Test 249 public void compileAndEvalInDiffContextTest() throws ScriptException { 250 final ScriptEngineManager m = new ScriptEngineManager(); 251 final ScriptEngine engine = m.getEngineByName("js"); 252 final Compilable compilable = (Compilable) engine; 253 final CompiledScript compiledScript = compilable.compile("foo"); 254 final ScriptContext ctxt = new SimpleScriptContext(); 255 ctxt.setAttribute("foo", "hello", ScriptContext.ENGINE_SCOPE); 256 assertEquals(compiledScript.eval(ctxt), "hello"); 257 } 258 259 @Test 260 public void accessGlobalTest() { 261 final ScriptEngineManager m = new ScriptEngineManager(); 262 final ScriptEngine e = m.getEngineByName("nashorn"); 263 264 try { 265 e.eval("var x = 'hello'"); 266 assertEquals(e.get("x"), "hello"); 267 } catch (final ScriptException exp) { 268 exp.printStackTrace(); 269 fail(exp.getMessage()); 270 } 271 } 272 273 @Test 274 public void exposeGlobalTest() { 275 final ScriptEngineManager m = new ScriptEngineManager(); 276 final ScriptEngine e = m.getEngineByName("nashorn"); 277 278 try { 279 e.put("y", "foo"); 280 e.eval("print(y)"); 281 } catch (final ScriptException exp) { 282 exp.printStackTrace(); 283 fail(exp.getMessage()); 284 } 285 } 286 287 @Test 288 public void putGlobalFunctionTest() { 289 final ScriptEngineManager m = new ScriptEngineManager(); 290 final ScriptEngine e = m.getEngineByName("nashorn"); 291 292 e.put("callable", new Callable<String>() { 293 @Override 294 public String call() throws Exception { 295 return "callable was called"; 296 } 297 }); 298 299 try { 300 e.eval("print(callable.call())"); 301 } catch (final ScriptException exp) { 302 exp.printStackTrace(); 303 fail(exp.getMessage()); 304 } 305 } 306 307 @Test 308 public void windowAlertTest() { 309 final ScriptEngineManager m = new ScriptEngineManager(); 310 final ScriptEngine e = m.getEngineByName("nashorn"); 311 final Window window = new Window(); 312 313 try { 314 e.put("window", window); 315 e.eval("print(window.alert)"); 316 e.eval("window.alert('calling window.alert...')"); 317 } catch (final Exception exp) { 318 exp.printStackTrace(); 319 fail(exp.getMessage()); 320 } 321 } 322 323 @Test 324 public void windowLocationTest() { 325 final ScriptEngineManager m = new ScriptEngineManager(); 326 final ScriptEngine e = m.getEngineByName("nashorn"); 327 final Window window = new Window(); 328 329 try { 330 e.put("window", window); 331 e.eval("print(window.location)"); 332 final Object locationValue = e.eval("window.getLocation()"); 333 assertEquals(locationValue, "http://localhost:8080/window"); 334 } catch (final Exception exp) { 335 exp.printStackTrace(); 336 fail(exp.getMessage()); 337 } 338 } 339 340 @Test 341 public void windowItemTest() { 342 final ScriptEngineManager m = new ScriptEngineManager(); 343 final ScriptEngine e = m.getEngineByName("nashorn"); 344 final Window window = new Window(); 345 346 try { 347 e.put("window", window); 348 final String item1 = (String)e.eval("window.item(65535)"); 349 assertEquals(item1, "ffff"); 350 final String item2 = (String)e.eval("window.item(255)"); 351 assertEquals(item2, "ff"); 352 } catch (final Exception exp) { 353 exp.printStackTrace(); 354 fail(exp.getMessage()); 355 } 356 } 357 358 @Test 359 public void windowEventTest() { 360 final ScriptEngineManager m = new ScriptEngineManager(); 361 final ScriptEngine e = m.getEngineByName("nashorn"); 362 final Window window = new Window(); 363 364 try { 365 e.put("window", window); 366 e.eval("window.onload = function() { print('window load event fired'); return true }"); 367 assertTrue((Boolean)e.eval("window.onload.loaded()")); 368 final WindowEventHandler handler = window.getOnload(); 369 assertNotNull(handler); 370 assertTrue(handler.loaded()); 371 } catch (final Exception exp) { 372 exp.printStackTrace(); 373 fail(exp.getMessage()); 374 } 375 } 376 377 @Test 378 public void throwTest() { 379 final ScriptEngineManager m = new ScriptEngineManager(); 380 final ScriptEngine e = m.getEngineByName("nashorn"); 381 e.put(ScriptEngine.FILENAME, "throwtest.js"); 382 383 try { 384 e.eval("throw 'foo'"); 385 } catch (final ScriptException exp) { 386 log(exp.getMessage()); 387 assertEquals(exp.getMessage(), "foo in throwtest.js at line number 1 at column number 0"); 388 assertEquals(exp.getFileName(), "throwtest.js"); 389 assertEquals(exp.getLineNumber(), 1); 390 } 391 } 392 393 @Test 394 public void setTimeoutTest() { 395 final ScriptEngineManager m = new ScriptEngineManager(); 396 final ScriptEngine e = m.getEngineByName("nashorn"); 397 final Window window = new Window(); 398 399 try { 400 final Class<?> setTimeoutParamTypes[] = { Window.class, String.class, int.class }; 401 final Method setTimeout = Window.class.getDeclaredMethod("setTimeout", setTimeoutParamTypes); 402 assertNotNull(setTimeout); 403 e.put("window", window); 404 e.eval("window.setTimeout('foo()', 100)"); 405 406 // try to make setTimeout global 407 e.put("setTimeout", setTimeout); 408 // TODO: java.lang.ClassCastException: required class 409 // java.lang.Integer but encountered class java.lang.Double 410 // e.eval("setTimeout('foo2()', 200)"); 411 } catch (final Exception exp) { 412 exp.printStackTrace(); 413 fail(exp.getMessage()); 414 } 415 } 416 417 @Test 418 public void setWriterTest() { 419 final ScriptEngineManager m = new ScriptEngineManager(); 420 final ScriptEngine e = m.getEngineByName("nashorn"); 421 final StringWriter sw = new StringWriter(); 422 e.getContext().setWriter(sw); 423 424 try { 425 e.eval("print('hello world')"); 426 } catch (final Exception exp) { 427 exp.printStackTrace(); 428 fail(exp.getMessage()); 429 } 430 assertEquals(sw.toString(), println("hello world")); 431 } 432 433 @Test 434 public void redefineEchoTest() { 435 final ScriptEngineManager m = new ScriptEngineManager(); 436 final ScriptEngine e = m.getEngineByName("nashorn"); 437 438 try { 439 e.eval("var echo = {}; if (typeof echo !== 'object') { throw 'echo is a '+typeof echo; }"); 440 } catch (final Exception exp) { 441 exp.printStackTrace(); 442 fail(exp.getMessage()); 443 } 444 } 445 @Test 446 public void noEnumerablePropertiesTest() { 447 final ScriptEngineManager m = new ScriptEngineManager(); 448 final ScriptEngine e = m.getEngineByName("nashorn"); 449 try { 450 e.eval("for (i in this) { throw 'found property: ' + i }"); 451 } catch (final Exception exp) { 452 exp.printStackTrace(); 453 fail(exp.getMessage()); 454 } 455 } 456 457 @Test 458 public void noRefErrorForGlobalThisAccessTest() { 459 final ScriptEngineManager m = new ScriptEngineManager(); 460 final ScriptEngine e = m.getEngineByName("nashorn"); 461 try { 462 e.eval("this.foo"); 463 } catch (final Exception exp) { 464 exp.printStackTrace(); 465 fail(exp.getMessage()); 466 } 467 } 468 469 @Test 470 public void refErrorForUndeclaredAccessTest() { 471 final ScriptEngineManager m = new ScriptEngineManager(); 472 final ScriptEngine e = m.getEngineByName("nashorn"); 473 try { 474 e.eval("try { print(foo); throw 'no ref error' } catch (e) { if (!(e instanceof ReferenceError)) throw e; }"); 475 } catch (final Exception exp) { 476 exp.printStackTrace(); 477 fail(exp.getMessage()); 478 } 479 } 480 481 @Test 482 public void typeErrorForGlobalThisCallTest() { 483 final ScriptEngineManager m = new ScriptEngineManager(); 484 final ScriptEngine e = m.getEngineByName("nashorn"); 485 try { 486 e.eval("try { this.foo() } catch(e) { if (! (e instanceof TypeError)) throw 'no type error' }"); 487 } catch (final Exception exp) { 488 exp.printStackTrace(); 489 fail(exp.getMessage()); 490 } 491 } 492 493 @Test 494 public void refErrorForUndeclaredCallTest() { 495 final ScriptEngineManager m = new ScriptEngineManager(); 496 final ScriptEngine e = m.getEngineByName("nashorn"); 497 try { 498 e.eval("try { foo() } catch(e) { if (! (e instanceof ReferenceError)) throw 'no ref error' }"); 499 } catch (final Exception exp) { 500 exp.printStackTrace(); 501 fail(exp.getMessage()); 502 } 503 } 504 505 @Test 506 // check that print function prints arg followed by newline char 507 public void printTest() { 508 final ScriptEngineManager m = new ScriptEngineManager(); 509 final ScriptEngine e = m.getEngineByName("nashorn"); 510 final StringWriter sw = new StringWriter(); 511 e.getContext().setWriter(sw); 512 try { 513 e.eval("print('hello')"); 514 } catch (final Throwable t) { 515 t.printStackTrace(); 516 fail(t.getMessage()); 517 } 518 519 assertEquals(sw.toString(), println("hello")); 520 } 521 522 @Test 523 // check that print prints all arguments (more than one) 524 public void printManyTest() { 525 final ScriptEngineManager m = new ScriptEngineManager(); 526 final ScriptEngine e = m.getEngineByName("nashorn"); 527 final StringWriter sw = new StringWriter(); 528 e.getContext().setWriter(sw); 529 try { 530 e.eval("print(34, true, 'hello')"); 531 } catch (final Throwable t) { 532 t.printStackTrace(); 533 fail(t.getMessage()); 534 } 535 536 assertEquals(sw.toString(), println("34 true hello")); 537 } 538 539 @Test 540 public void scriptObjectAutoConversionTest() throws ScriptException { 541 final ScriptEngineManager m = new ScriptEngineManager(); 542 final ScriptEngine e = m.getEngineByName("nashorn"); 543 e.eval("obj = { foo: 'hello' }"); 544 e.put("Window", e.eval("Packages.jdk.nashorn.api.scripting.Window")); 545 assertEquals(e.eval("Window.funcJSObject(obj)"), "hello"); 546 assertEquals(e.eval("Window.funcScriptObjectMirror(obj)"), "hello"); 547 assertEquals(e.eval("Window.funcMap(obj)"), "hello"); 548 assertEquals(e.eval("Window.funcJSObject(obj)"), "hello"); 549 } 550 551 // @bug 8032948: Nashorn linkages awry 552 @Test 553 public void checkProxyAccess() throws ScriptException { 554 final ScriptEngineManager m = new ScriptEngineManager(); 555 final ScriptEngine e = m.getEngineByName("nashorn"); 556 final boolean[] reached = new boolean[1]; 557 final Runnable r = (Runnable)Proxy.newProxyInstance( 558 ScriptEngineTest.class.getClassLoader(), 559 new Class[] { Runnable.class }, 560 new InvocationHandler() { 561 @Override 562 public Object invoke(final Object p, final Method mtd, final Object[] a) { 563 reached[0] = true; 564 return null; 565 } 566 }); 567 568 e.put("r", r); 569 e.eval("r.run()"); 570 571 assertTrue(reached[0]); 572 } 573 574 // properties that can be read by any code 575 private static String[] propNames = { 576 "java.version", 577 "java.vendor", 578 "java.vendor.url", 579 "java.class.version", 580 "os.name", 581 "os.version", 582 "os.arch", 583 "file.separator", 584 "path.separator", 585 "line.separator", 586 "java.specification.version", 587 "java.specification.vendor", 588 "java.specification.name", 589 "java.vm.specification.version", 590 "java.vm.specification.vendor", 591 "java.vm.specification.name", 592 "java.vm.version", 593 "java.vm.vendor", 594 "java.vm.name" 595 }; 596 597 // @bug 8033924: Default permissions are not given for eval code 598 @Test 599 public void checkPropertyReadPermissions() throws ScriptException { 600 final ScriptEngineManager m = new ScriptEngineManager(); 601 final ScriptEngine e = m.getEngineByName("nashorn"); 602 603 for (final String name : propNames) { 604 checkProperty(e, name); 605 } 606 } 607 608 // @bug 8046013: TypeError: Cannot apply "with" to non script object 609 @Test 610 public void withOnMirrorTest() throws ScriptException { 611 final ScriptEngineManager m = new ScriptEngineManager(); 612 final ScriptEngine e = m.getEngineByName("nashorn"); 613 614 final Object obj = e.eval("({ foo: 'hello'})"); 615 final Object[] arr = new Object[1]; 616 arr[0] = obj; 617 e.put("arr", arr); 618 final Object res = e.eval("var res; with(arr[0]) { res = foo; }; res"); 619 assertEquals(res, "hello"); 620 } 621 622 // @bug 8054223: Nashorn: AssertionError when use __DIR__ and ScriptEngine.eval() 623 @Test 624 public void check__DIR__Test() throws ScriptException { 625 final ScriptEngineManager m = new ScriptEngineManager(); 626 final ScriptEngine e = m.getEngineByName("nashorn"); 627 e.eval("__DIR__"); 628 } 629 630 // @bug 8050432:javax.script.filename variable should not be enumerable 631 // with nashorn engine's ENGINE_SCOPE bindings 632 @Test 633 public void enumerableGlobalsTest() throws ScriptException { 634 final ScriptEngineManager m = new ScriptEngineManager(); 635 final ScriptEngine e = m.getEngineByName("nashorn"); 636 637 e.put(ScriptEngine.FILENAME, "test"); 638 final Object enumerable = e.eval( 639 "Object.getOwnPropertyDescriptor(this, " + 640 " 'javax.script.filename').enumerable"); 641 assertEquals(enumerable, Boolean.FALSE); 642 } 643 644 public static class Context { 645 private Object myobj; 646 647 public void set(final Object o) { 648 myobj = o; 649 } 650 651 public Object get() { 652 return myobj; 653 } 654 } 655 656 // @bug 8050977: Java8 Javascript Nashorn exception: 657 // no current Global instance for nashorn 658 @Test 659 public void currentGlobalMissingTest() throws Exception { 660 final ScriptEngineManager manager = new ScriptEngineManager(); 661 final ScriptEngine e = manager.getEngineByName("nashorn"); 662 663 final Context ctx = new Context(); 664 e.put("ctx", ctx); 665 e.eval("var obj = { foo: function(str) { return str.toUpperCase() } }"); 666 e.eval("ctx.set(obj)"); 667 final Invocable inv = (Invocable)e; 668 assertEquals("HELLO", inv.invokeMethod(ctx.get(), "foo", "hello")); 669 // try object literal 670 e.eval("ctx.set({ bar: function(str) { return str.toLowerCase() } })"); 671 assertEquals("hello", inv.invokeMethod(ctx.get(), "bar", "HELLO")); 672 // try array literal 673 e.eval("var arr = [ 'hello', 'world' ]"); 674 e.eval("ctx.set(arr)"); 675 assertEquals("helloworld", inv.invokeMethod(ctx.get(), "join", "")); 676 } 677 678 // @bug 8068524: NashornScriptEngineFactory.getParameter() throws IAE 679 // for an unknown key, doesn't conform to the general spec 680 @Test 681 public void getParameterInvalidKeyTest() throws Exception { 682 final ScriptEngineManager manager = new ScriptEngineManager(); 683 final ScriptEngine e = manager.getEngineByName("nashorn"); 684 // no exception expected here! 685 Object value = e.getFactory().getParameter("no value assigned to this key"); 686 assertNull(value); 687 } 688 689 // @bug JDK-8068889: ConsString arguments to a functional interface wasn't converted to string. 690 @Test 691 public void functionalInterfaceStringTest() throws Exception { 692 final ScriptEngineManager manager = new ScriptEngineManager(); 693 final ScriptEngine e = manager.getEngineByName("nashorn"); 694 final AtomicBoolean invoked = new AtomicBoolean(false); 695 e.put("f", new Function<String, String>() { 696 @Override 697 public String apply(String t) { 698 invoked.set(true); 699 return t; 700 } 701 }); 702 assertEquals(e.eval("var x = 'a'; x += 'b'; f(x)"), "ab"); 703 assertTrue(invoked.get()); 704 } 705 706 // @bug JDK-8068889: ScriptObject arguments to a functional interface wasn't converted to a mirror. 707 @Test 708 public void functionalInterfaceObjectTest() throws Exception { 709 final ScriptEngineManager manager = new ScriptEngineManager(); 710 final ScriptEngine e = manager.getEngineByName("nashorn"); 711 final AtomicBoolean invoked = new AtomicBoolean(false); 712 e.put("c", new Consumer<Object>() { 713 @Override 714 public void accept(Object t) { 715 assertTrue(t instanceof ScriptObjectMirror); 716 assertEquals(((ScriptObjectMirror)t).get("a"), "xyz"); 717 invoked.set(true); 718 } 719 }); 720 e.eval("var x = 'xy'; x += 'z';c({a:x})"); 721 assertTrue(invoked.get()); 722 } 723 724 // @bug JDK-8068603: NashornScriptEngine.put/get() impls don't conform to NPE, IAE spec assertions 725 @Test 726 public void illegalBindingsValuesTest() throws Exception { 727 final ScriptEngineManager manager = new ScriptEngineManager(); 728 final ScriptEngine e = manager.getEngineByName("nashorn"); 729 730 try { 731 e.put(null, "null-value"); 732 fail(); 733 } catch (NullPointerException x) { 734 // expected 735 } 736 737 try { 738 e.put("", "empty-value"); 739 fail(); 740 } catch (IllegalArgumentException x) { 741 // expected 742 } 743 744 final Bindings b = e.getBindings(ScriptContext.ENGINE_SCOPE); 745 assertTrue(b instanceof ScriptObjectMirror); 746 747 try { 748 b.put(null, "null-value"); 749 fail(); 750 } catch (NullPointerException x) { 751 // expected 752 } 753 754 try { 755 b.put("", "empty-value"); 756 fail(); 757 } catch (IllegalArgumentException x) { 758 // expected 759 } 760 761 try { 762 b.get(null); 763 fail(); 764 } catch (NullPointerException x) { 765 // expected 766 } 767 768 try { 769 b.get(""); 770 fail(); 771 } catch (IllegalArgumentException x) { 772 // expected 773 } 774 775 try { 776 b.get(1); 777 fail(); 778 } catch (ClassCastException x) { 779 // expected 780 } 781 782 try { 783 b.remove(null); 784 fail(); 785 } catch (NullPointerException x) { 786 // expected 787 } 788 789 try { 790 b.remove(""); 791 fail(); 792 } catch (IllegalArgumentException x) { 793 // expected 794 } 795 796 try { 797 b.remove(1); 798 fail(); 799 } catch (ClassCastException x) { 800 // expected 801 } 802 803 try { 804 b.containsKey(null); 805 fail(); 806 } catch (NullPointerException x) { 807 // expected 808 } 809 810 try { 811 b.containsKey(""); 812 fail(); 813 } catch (IllegalArgumentException x) { 814 // expected 815 } 816 817 try { 818 b.containsKey(1); 819 fail(); 820 } catch (ClassCastException x) { 821 // expected 822 } 823 824 try { 825 b.putAll(null); 826 fail(); 827 } catch (NullPointerException x) { 828 // expected 829 } 830 831 try { 832 b.putAll(Collections.singletonMap((String)null, "null-value")); 833 fail(); 834 } catch (NullPointerException x) { 835 // expected 836 } 837 838 try { 839 b.putAll(Collections.singletonMap("", "empty-value")); 840 fail(); 841 } catch (IllegalArgumentException x) { 842 // expected 843 } 844 } 845 846 private static void checkProperty(final ScriptEngine e, final String name) 847 throws ScriptException { 848 final String value = System.getProperty(name); 849 e.put("name", name); 850 assertEquals(value, e.eval("java.lang.System.getProperty(name)")); 851 } 852 853 private static final String LINE_SEPARATOR = System.getProperty("line.separator"); 854 855 // Returns String that would be the result of calling PrintWriter.println 856 // of the given String. (This is to handle platform specific newline). 857 private static String println(final String str) { 858 return str + LINE_SEPARATOR; 859 } 860 }