nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java
changeset 29784 b9220497eb43
parent 29783 db33e568f107
parent 29770 6415d011ad02
child 29785 da950f343762
equal deleted inserted replaced
29783:db33e568f107 29784:b9220497eb43
     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     @Test
       
   725     public void testLengthOnArrayLikeObjects() throws Exception {
       
   726         final ScriptEngine e = new ScriptEngineManager().getEngineByName("nashorn");
       
   727         final Object val = e.eval("var arr = { length: 1, 0: 1}; arr.length");
       
   728 
       
   729         assertTrue(Number.class.isAssignableFrom(val.getClass()));
       
   730         assertTrue(((Number)val).intValue() == 1);
       
   731     }
       
   732 
       
   733     // @bug JDK-8068603: NashornScriptEngine.put/get() impls don't conform to NPE, IAE spec assertions
       
   734     @Test
       
   735     public void illegalBindingsValuesTest() throws Exception {
       
   736         final ScriptEngineManager manager = new ScriptEngineManager();
       
   737         final ScriptEngine e = manager.getEngineByName("nashorn");
       
   738 
       
   739         try {
       
   740             e.put(null, "null-value");
       
   741             fail();
       
   742         } catch (NullPointerException x) {
       
   743             // expected
       
   744         }
       
   745 
       
   746         try {
       
   747             e.put("", "empty-value");
       
   748             fail();
       
   749         } catch (IllegalArgumentException x) {
       
   750             // expected
       
   751         }
       
   752 
       
   753         final Bindings b = e.getBindings(ScriptContext.ENGINE_SCOPE);
       
   754         assertTrue(b instanceof ScriptObjectMirror);
       
   755 
       
   756         try {
       
   757             b.put(null, "null-value");
       
   758             fail();
       
   759         } catch (NullPointerException x) {
       
   760             // expected
       
   761         }
       
   762 
       
   763         try {
       
   764             b.put("", "empty-value");
       
   765             fail();
       
   766         } catch (IllegalArgumentException x) {
       
   767             // expected
       
   768         }
       
   769 
       
   770         try {
       
   771             b.get(null);
       
   772             fail();
       
   773         } catch (NullPointerException x) {
       
   774             // expected
       
   775         }
       
   776 
       
   777         try {
       
   778             b.get("");
       
   779             fail();
       
   780         } catch (IllegalArgumentException x) {
       
   781             // expected
       
   782         }
       
   783 
       
   784         try {
       
   785             b.get(1);
       
   786             fail();
       
   787         } catch (ClassCastException x) {
       
   788             // expected
       
   789         }
       
   790 
       
   791         try {
       
   792             b.remove(null);
       
   793             fail();
       
   794         } catch (NullPointerException x) {
       
   795             // expected
       
   796         }
       
   797 
       
   798         try {
       
   799             b.remove("");
       
   800             fail();
       
   801         } catch (IllegalArgumentException x) {
       
   802             // expected
       
   803         }
       
   804 
       
   805         try {
       
   806             b.remove(1);
       
   807             fail();
       
   808         } catch (ClassCastException x) {
       
   809             // expected
       
   810         }
       
   811 
       
   812         try {
       
   813             b.containsKey(null);
       
   814             fail();
       
   815         } catch (NullPointerException x) {
       
   816             // expected
       
   817         }
       
   818 
       
   819         try {
       
   820             b.containsKey("");
       
   821             fail();
       
   822         } catch (IllegalArgumentException x) {
       
   823             // expected
       
   824         }
       
   825 
       
   826         try {
       
   827             b.containsKey(1);
       
   828             fail();
       
   829         } catch (ClassCastException x) {
       
   830             // expected
       
   831         }
       
   832 
       
   833         try {
       
   834             b.putAll(null);
       
   835             fail();
       
   836         } catch (NullPointerException x) {
       
   837             // expected
       
   838         }
       
   839 
       
   840         try {
       
   841             b.putAll(Collections.singletonMap((String)null, "null-value"));
       
   842             fail();
       
   843         } catch (NullPointerException x) {
       
   844             // expected
       
   845         }
       
   846 
       
   847         try {
       
   848             b.putAll(Collections.singletonMap("", "empty-value"));
       
   849             fail();
       
   850         } catch (IllegalArgumentException x) {
       
   851             // expected
       
   852         }
       
   853     }
       
   854 
       
   855     // @bug 8071989: NashornScriptEngine returns javax.script.ScriptContext instance
       
   856     // with insonsistent get/remove methods behavior for undefined attributes
       
   857     @Test
       
   858     public void testScriptContextGetRemoveUndefined() throws Exception {
       
   859         final ScriptEngineManager manager = new ScriptEngineManager();
       
   860         final ScriptEngine e = manager.getEngineByName("nashorn");
       
   861         final ScriptContext ctx = e.getContext();
       
   862         assertNull(ctx.getAttribute("undefinedname", ScriptContext.ENGINE_SCOPE));
       
   863         assertNull(ctx.removeAttribute("undefinedname", ScriptContext.ENGINE_SCOPE));
       
   864     }
       
   865 
       
   866     private static void checkProperty(final ScriptEngine e, final String name)
       
   867         throws ScriptException {
       
   868         final String value = System.getProperty(name);
       
   869         e.put("name", name);
       
   870         assertEquals(value, e.eval("java.lang.System.getProperty(name)"));
       
   871     }
       
   872 
       
   873     private static final String LINE_SEPARATOR = System.getProperty("line.separator");
       
   874 
       
   875     // Returns String that would be the result of calling PrintWriter.println
       
   876     // of the given String. (This is to handle platform specific newline).
       
   877     private static String println(final String str) {
       
   878         return str + LINE_SEPARATOR;
       
   879     }
       
   880 }