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