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.PrintWriter; 34 import java.io.StringReader; 35 import java.io.StringWriter; 36 import java.lang.reflect.Method; 37 import java.util.concurrent.Callable; 38 import javax.script.Compilable; 39 import javax.script.CompiledScript; 40 import javax.script.ScriptContext; 41 import javax.script.ScriptEngine; 42 import javax.script.ScriptEngineFactory; 43 import javax.script.ScriptEngineManager; 44 import javax.script.ScriptException; 45 import javax.script.SimpleScriptContext; 46 import org.testng.annotations.Test; 47 48 /** 49 * Tests for JSR-223 script engine for Nashorn. 50 * 51 * @test 52 * @build jdk.nashorn.api.scripting.Window jdk.nashorn.api.scripting.WindowEventHandler jdk.nashorn.api.scripting.VariableArityTestInterface jdk.nashorn.api.scripting.ScriptEngineTest 53 * @run testng jdk.nashorn.api.scripting.ScriptEngineTest 54 */ 55 public class ScriptEngineTest { 56 57 private void log(String msg) { 58 org.testng.Reporter.log(msg, true); 59 } 60 61 @Test 62 public void argumentsTest() { 63 final ScriptEngineManager m = new ScriptEngineManager(); 64 final ScriptEngine e = m.getEngineByName("nashorn"); 65 66 String[] args = new String[] { "hello", "world" }; 67 try { 68 e.put("arguments", args); 69 Object arg0 = e.eval("arguments[0]"); 70 Object arg1 = e.eval("arguments[1]"); 71 assertEquals(args[0], arg0); 72 assertEquals(args[1], arg1); 73 } catch (final Exception exp) { 74 exp.printStackTrace(); 75 fail(exp.getMessage()); 76 } 77 } 78 79 @Test 80 public void argumentsWithTest() { 81 final ScriptEngineManager m = new ScriptEngineManager(); 82 final ScriptEngine e = m.getEngineByName("nashorn"); 83 84 String[] args = new String[] { "hello", "world" }; 85 try { 86 e.put("arguments", args); 87 Object arg0 = e.eval("var imports = new JavaImporter(java.io); " + 88 " with(imports) { arguments[0] }"); 89 Object arg1 = e.eval("var imports = new JavaImporter(java.util, java.io); " + 90 " with(imports) { arguments[1] }"); 91 assertEquals(args[0], arg0); 92 assertEquals(args[1], arg1); 93 } catch (final Exception exp) { 94 exp.printStackTrace(); 95 fail(exp.getMessage()); 96 } 97 } 98 99 @Test 100 public void argumentsEmptyTest() { 101 final ScriptEngineManager m = new ScriptEngineManager(); 102 final ScriptEngine e = m.getEngineByName("nashorn"); 103 104 try { 105 assertEquals(e.eval("arguments instanceof Array"), true); 106 assertEquals(e.eval("arguments.length == 0"), true); 107 } catch (final Exception exp) { 108 exp.printStackTrace(); 109 fail(exp.getMessage()); 110 } 111 } 112 113 @Test 114 public void factoryTests() { 115 final ScriptEngineManager m = new ScriptEngineManager(); 116 final ScriptEngine e = m.getEngineByName("nashorn"); 117 assertNotNull(e); 118 119 final ScriptEngineFactory fac = e.getFactory(); 120 121 assertEquals(fac.getLanguageName(), "ECMAScript"); 122 assertEquals(fac.getParameter(ScriptEngine.NAME), "javascript"); 123 assertEquals(fac.getLanguageVersion(), "ECMA - 262 Edition 5.1"); 124 assertEquals(fac.getEngineName(), "Oracle Nashorn"); 125 assertEquals(fac.getOutputStatement("context"), "print(context)"); 126 assertEquals(fac.getProgram("print('hello')", "print('world')"), "print('hello');print('world');"); 127 assertEquals(fac.getParameter(ScriptEngine.NAME), "javascript"); 128 129 boolean seenJS = false; 130 for (String ext : fac.getExtensions()) { 131 if (ext.equals("js")) { 132 seenJS = true; 133 } 134 } 135 136 assertEquals(seenJS, true); 137 String str = fac.getMethodCallSyntax("obj", "foo", "x"); 138 assertEquals(str, "obj.foo(x)"); 139 140 boolean seenNashorn = false, seenJavaScript = false, seenECMAScript = false; 141 for (String name : fac.getNames()) { 142 switch (name) { 143 case "nashorn": seenNashorn = true; break; 144 case "javascript": seenJavaScript = true; break; 145 case "ECMAScript": seenECMAScript = true; break; 146 } 147 } 148 149 assertTrue(seenNashorn); 150 assertTrue(seenJavaScript); 151 assertTrue(seenECMAScript); 152 153 boolean seenAppJS = false, seenAppECMA = false, seenTextJS = false, seenTextECMA = false; 154 for (String mime : fac.getMimeTypes()) { 155 switch (mime) { 156 case "application/javascript": seenAppJS = true; break; 157 case "application/ecmascript": seenAppECMA = true; break; 158 case "text/javascript": seenTextJS = true; break; 159 case "text/ecmascript": seenTextECMA = true; break; 160 } 161 } 162 163 assertTrue(seenAppJS); 164 assertTrue(seenAppECMA); 165 assertTrue(seenTextJS); 166 assertTrue(seenTextECMA); 167 } 168 169 @Test 170 public void evalTests() { 171 final ScriptEngineManager m = new ScriptEngineManager(); 172 final ScriptEngine e = m.getEngineByName("nashorn"); 173 e.put(ScriptEngine.FILENAME, "myfile.js"); 174 175 try { 176 e.eval("print('hello')"); 177 } catch (final ScriptException se) { 178 fail(se.getMessage()); 179 } 180 try { 181 e.eval("print('hello)"); 182 fail("script exception expected"); 183 } catch (final ScriptException se) { 184 assertEquals(se.getLineNumber(), 1); 185 assertEquals(se.getColumnNumber(), 13); 186 assertEquals(se.getFileName(), "myfile.js"); 187 // se.printStackTrace(); 188 } 189 190 try { 191 Object obj = e.eval("34 + 41"); 192 assertTrue(34.0 + 41.0 == ((Number)obj).doubleValue()); 193 obj = e.eval("x = 5"); 194 assertTrue(5.0 == ((Number)obj).doubleValue()); 195 } catch (final ScriptException se) { 196 se.printStackTrace(); 197 fail(se.getMessage()); 198 } 199 } 200 201 @Test 202 public void compileTests() { 203 final ScriptEngineManager m = new ScriptEngineManager(); 204 final ScriptEngine e = m.getEngineByName("nashorn"); 205 CompiledScript script = null; 206 207 try { 208 script = ((Compilable)e).compile("print('hello')"); 209 } catch (final ScriptException se) { 210 fail(se.getMessage()); 211 } 212 213 try { 214 script.eval(); 215 } catch (final ScriptException | NullPointerException se) { 216 se.printStackTrace(); 217 fail(se.getMessage()); 218 } 219 220 // try to compile from a Reader 221 try { 222 script = ((Compilable)e).compile(new StringReader("print('world')")); 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 235 @Test 236 public void compileAndEvalInDiffContextTest() throws ScriptException { 237 final ScriptEngineManager m = new ScriptEngineManager(); 238 final ScriptEngine engine = m.getEngineByName("js"); 239 final Compilable compilable = (Compilable) engine; 240 final CompiledScript compiledScript = compilable.compile("foo"); 241 final ScriptContext ctxt = new SimpleScriptContext(); 242 ctxt.setAttribute("foo", "hello", ScriptContext.ENGINE_SCOPE); 243 assertEquals(compiledScript.eval(ctxt), "hello"); 244 } 245 246 @Test 247 public void accessGlobalTest() { 248 final ScriptEngineManager m = new ScriptEngineManager(); 249 final ScriptEngine e = m.getEngineByName("nashorn"); 250 251 try { 252 e.eval("var x = 'hello'"); 253 assertEquals(e.get("x"), "hello"); 254 } catch (final ScriptException exp) { 255 exp.printStackTrace(); 256 fail(exp.getMessage()); 257 } 258 } 259 260 @Test 261 public void exposeGlobalTest() { 262 final ScriptEngineManager m = new ScriptEngineManager(); 263 final ScriptEngine e = m.getEngineByName("nashorn"); 264 265 try { 266 e.put("y", "foo"); 267 e.eval("print(y)"); 268 } catch (final ScriptException exp) { 269 exp.printStackTrace(); 270 fail(exp.getMessage()); 271 } 272 } 273 274 @Test 275 public void putGlobalFunctionTest() { 276 final ScriptEngineManager m = new ScriptEngineManager(); 277 final ScriptEngine e = m.getEngineByName("nashorn"); 278 279 e.put("callable", new Callable<String>() { 280 @Override 281 public String call() throws Exception { 282 return "callable was called"; 283 } 284 }); 285 286 try { 287 e.eval("print(callable.call())"); 288 } catch (final ScriptException exp) { 289 exp.printStackTrace(); 290 fail(exp.getMessage()); 291 } 292 } 293 294 @Test 295 public void windowAlertTest() { 296 final ScriptEngineManager m = new ScriptEngineManager(); 297 final ScriptEngine e = m.getEngineByName("nashorn"); 298 final Window window = new Window(); 299 300 try { 301 e.put("window", window); 302 e.eval("print(window.alert)"); 303 e.eval("window.alert('calling window.alert...')"); 304 } catch (final Exception exp) { 305 exp.printStackTrace(); 306 fail(exp.getMessage()); 307 } 308 } 309 310 @Test 311 public void windowLocationTest() { 312 final ScriptEngineManager m = new ScriptEngineManager(); 313 final ScriptEngine e = m.getEngineByName("nashorn"); 314 final Window window = new Window(); 315 316 try { 317 e.put("window", window); 318 e.eval("print(window.location)"); 319 final Object locationValue = e.eval("window.getLocation()"); 320 assertEquals(locationValue, "http://localhost:8080/window"); 321 } catch (final Exception exp) { 322 exp.printStackTrace(); 323 fail(exp.getMessage()); 324 } 325 } 326 327 @Test 328 public void windowItemTest() { 329 final ScriptEngineManager m = new ScriptEngineManager(); 330 final ScriptEngine e = m.getEngineByName("nashorn"); 331 final Window window = new Window(); 332 333 try { 334 e.put("window", window); 335 final String item1 = (String)e.eval("window.item(65535)"); 336 assertEquals(item1, "ffff"); 337 final String item2 = (String)e.eval("window.item(255)"); 338 assertEquals(item2, "ff"); 339 } catch (final Exception exp) { 340 exp.printStackTrace(); 341 fail(exp.getMessage()); 342 } 343 } 344 345 @Test 346 public void windowEventTest() { 347 final ScriptEngineManager m = new ScriptEngineManager(); 348 final ScriptEngine e = m.getEngineByName("nashorn"); 349 final Window window = new Window(); 350 351 try { 352 e.put("window", window); 353 e.eval("window.onload = function() { print('window load event fired'); return true }"); 354 assertTrue((Boolean)e.eval("window.onload.loaded()")); 355 final WindowEventHandler handler = window.getOnload(); 356 assertNotNull(handler); 357 assertTrue(handler.loaded()); 358 } catch (final Exception exp) { 359 exp.printStackTrace(); 360 fail(exp.getMessage()); 361 } 362 } 363 364 @Test 365 public void throwTest() { 366 final ScriptEngineManager m = new ScriptEngineManager(); 367 final ScriptEngine e = m.getEngineByName("nashorn"); 368 e.put(ScriptEngine.FILENAME, "throwtest.js"); 369 370 try { 371 e.eval("throw 'foo'"); 372 } catch (final ScriptException exp) { 373 log(exp.getMessage()); 374 assertEquals(exp.getMessage(), "foo in throwtest.js at line number 1 at column number 0"); 375 assertEquals(exp.getFileName(), "throwtest.js"); 376 assertEquals(exp.getLineNumber(), 1); 377 } 378 } 379 380 @Test 381 public void setTimeoutTest() { 382 final ScriptEngineManager m = new ScriptEngineManager(); 383 final ScriptEngine e = m.getEngineByName("nashorn"); 384 final Window window = new Window(); 385 386 try { 387 final Class<?> setTimeoutParamTypes[] = { Window.class, String.class, int.class }; 388 final Method setTimeout = Window.class.getDeclaredMethod("setTimeout", setTimeoutParamTypes); 389 assertNotNull(setTimeout); 390 e.put("window", window); 391 e.eval("window.setTimeout('foo()', 100)"); 392 393 // try to make setTimeout global 394 e.put("setTimeout", setTimeout); 395 // TODO: java.lang.ClassCastException: required class 396 // java.lang.Integer but encountered class java.lang.Double 397 // e.eval("setTimeout('foo2()', 200)"); 398 } catch (final Exception exp) { 399 exp.printStackTrace(); 400 fail(exp.getMessage()); 401 } 402 } 403 404 @Test 405 public void setWriterTest() { 406 final ScriptEngineManager m = new ScriptEngineManager(); 407 final ScriptEngine e = m.getEngineByName("nashorn"); 408 final StringWriter sw = new StringWriter(); 409 e.getContext().setWriter(sw); 410 411 try { 412 e.eval("print('hello world')"); 413 } catch (final Exception exp) { 414 exp.printStackTrace(); 415 fail(exp.getMessage()); 416 } 417 assertEquals(sw.toString(), println("hello world")); 418 } 419 420 @Test 421 public void redefineEchoTest() { 422 final ScriptEngineManager m = new ScriptEngineManager(); 423 final ScriptEngine e = m.getEngineByName("nashorn"); 424 425 try { 426 e.eval("var echo = {}; if (typeof echo !== 'object') { throw 'echo is a '+typeof echo; }"); 427 } catch (final Exception exp) { 428 exp.printStackTrace(); 429 fail(exp.getMessage()); 430 } 431 } 432 @Test 433 public void noEnumerablePropertiesTest() { 434 final ScriptEngineManager m = new ScriptEngineManager(); 435 final ScriptEngine e = m.getEngineByName("nashorn"); 436 try { 437 e.eval("for (i in this) { throw 'found property: ' + i }"); 438 } catch (final Exception exp) { 439 exp.printStackTrace(); 440 fail(exp.getMessage()); 441 } 442 } 443 444 @Test 445 public void noRefErrorForGlobalThisAccessTest() { 446 final ScriptEngineManager m = new ScriptEngineManager(); 447 final ScriptEngine e = m.getEngineByName("nashorn"); 448 try { 449 e.eval("this.foo"); 450 } catch (final Exception exp) { 451 exp.printStackTrace(); 452 fail(exp.getMessage()); 453 } 454 } 455 456 @Test 457 public void refErrorForUndeclaredAccessTest() { 458 final ScriptEngineManager m = new ScriptEngineManager(); 459 final ScriptEngine e = m.getEngineByName("nashorn"); 460 try { 461 e.eval("try { print(foo); throw 'no ref error' } catch (e) { if (!(e instanceof ReferenceError)) throw e; }"); 462 } catch (final Exception exp) { 463 exp.printStackTrace(); 464 fail(exp.getMessage()); 465 } 466 } 467 468 @Test 469 public void typeErrorForGlobalThisCallTest() { 470 final ScriptEngineManager m = new ScriptEngineManager(); 471 final ScriptEngine e = m.getEngineByName("nashorn"); 472 try { 473 e.eval("try { this.foo() } catch(e) { if (! (e instanceof TypeError)) throw 'no type error' }"); 474 } catch (final Exception exp) { 475 exp.printStackTrace(); 476 fail(exp.getMessage()); 477 } 478 } 479 480 @Test 481 public void refErrorForUndeclaredCallTest() { 482 final ScriptEngineManager m = new ScriptEngineManager(); 483 final ScriptEngine e = m.getEngineByName("nashorn"); 484 try { 485 e.eval("try { foo() } catch(e) { if (! (e instanceof ReferenceError)) throw 'no ref error' }"); 486 } catch (final Exception exp) { 487 exp.printStackTrace(); 488 fail(exp.getMessage()); 489 } 490 } 491 492 @Test 493 // check that print function prints arg followed by newline char 494 public void printTest() { 495 final ScriptEngineManager m = new ScriptEngineManager(); 496 final ScriptEngine e = m.getEngineByName("nashorn"); 497 final StringWriter sw = new StringWriter(); 498 e.getContext().setWriter(sw); 499 try { 500 e.eval("print('hello')"); 501 } catch (final Throwable t) { 502 t.printStackTrace(); 503 fail(t.getMessage()); 504 } 505 506 assertEquals(sw.toString(), println("hello")); 507 } 508 509 @Test 510 // check that print prints all arguments (more than one) 511 public void printManyTest() { 512 final ScriptEngineManager m = new ScriptEngineManager(); 513 final ScriptEngine e = m.getEngineByName("nashorn"); 514 final StringWriter sw = new StringWriter(); 515 e.getContext().setWriter(sw); 516 try { 517 e.eval("print(34, true, 'hello')"); 518 } catch (final Throwable t) { 519 t.printStackTrace(); 520 fail(t.getMessage()); 521 } 522 523 assertEquals(sw.toString(), println("34 true hello")); 524 } 525 526 private static final String LINE_SEPARATOR = System.getProperty("line.separator"); 527 528 // Returns String that would be the result of calling PrintWriter.println 529 // of the given String. (This is to handle platform specific newline). 530 private static String println(final String str) { 531 return str + LINE_SEPARATOR; 532 } 533 } --- EOF ---