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 package jdk.nashorn.api.scripting;
  26 
  27 import javax.script.Bindings;
  28 import javax.script.ScriptContext;
  29 import javax.script.ScriptEngine;
  30 import javax.script.ScriptEngineManager;
  31 import javax.script.ScriptException;
  32 import javax.script.SimpleBindings;
  33 import javax.script.SimpleScriptContext;
  34 import org.testng.Assert;
  35 import static org.testng.Assert.assertEquals;
  36 import static org.testng.Assert.assertNotNull;
  37 import static org.testng.Assert.assertTrue;
  38 import static org.testng.Assert.fail;
  39 import org.testng.annotations.Test;
  40 
  41 /**
  42  * Tests for jsr223 Bindings "scope" (engine, global scopes)
  43  */
  44 public class ScopeTest {
  45 
  46     @Test
  47     public void createBindingsTest() {
  48         final ScriptEngineManager m = new ScriptEngineManager();
  49         final ScriptEngine e = m.getEngineByName("nashorn");
  50         Bindings b = e.createBindings();
  51         b.put("foo", 42.0);
  52         Object res = null;
  53         try {
  54             res = e.eval("foo == 42.0", b);
  55         } catch (final ScriptException | NullPointerException se) {
  56             se.printStackTrace();
  57             fail(se.getMessage());
  58         }
  59 
  60         assertEquals(res, Boolean.TRUE);
  61     }
  62 
  63     @Test
  64     public void engineScopeTest() {
  65         final ScriptEngineManager m = new ScriptEngineManager();
  66         final ScriptEngine e = m.getEngineByName("nashorn");
  67         Bindings engineScope = e.getBindings(ScriptContext.ENGINE_SCOPE);
  68 
  69         // check few ECMA standard built-in global properties
  70         assertNotNull(engineScope.get("Object"));
  71         assertNotNull(engineScope.get("TypeError"));
  72         assertNotNull(engineScope.get("eval"));
  73 
  74         // can access via ScriptEngine.get as well
  75         assertNotNull(e.get("Object"));
  76         assertNotNull(e.get("TypeError"));
  77         assertNotNull(e.get("eval"));
  78 
  79         // Access by either way should return same object
  80         assertEquals(engineScope.get("Array"), e.get("Array"));
  81         assertEquals(engineScope.get("EvalError"), e.get("EvalError"));
  82         assertEquals(engineScope.get("undefined"), e.get("undefined"));
  83 
  84         // try exposing a new variable from scope
  85         engineScope.put("myVar", "foo");
  86         try {
  87             assertEquals(e.eval("myVar"), "foo");
  88         } catch (final ScriptException se) {
  89             se.printStackTrace();
  90             fail(se.getMessage());
  91         }
  92 
  93         // update "myVar" in script an check the value from scope
  94         try {
  95             e.eval("myVar = 'nashorn';");
  96         } catch (final ScriptException se) {
  97             se.printStackTrace();
  98             fail(se.getMessage());
  99         }
 100 
 101         // now check modified value from scope and engine
 102         assertEquals(engineScope.get("myVar"), "nashorn");
 103         assertEquals(e.get("myVar"), "nashorn");
 104     }
 105 
 106     @Test
 107     public void multiGlobalTest() {
 108         final ScriptEngineManager m = new ScriptEngineManager();
 109         final ScriptEngine e = m.getEngineByName("nashorn");
 110         final Bindings b = e.createBindings();
 111         final ScriptContext newCtxt = new SimpleScriptContext();
 112         newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
 113 
 114         try {
 115             Object obj1 = e.eval("Object");
 116             Object obj2 = e.eval("Object", newCtxt);
 117             Assert.assertNotEquals(obj1, obj2);
 118             Assert.assertNotNull(obj1);
 119             Assert.assertNotNull(obj2);
 120             Assert.assertEquals(obj1.toString(), obj2.toString());
 121 
 122             e.eval("x = 'hello'");
 123             e.eval("x = 'world'", newCtxt);
 124             Object x1 = e.getContext().getAttribute("x");
 125             Object x2 = newCtxt.getAttribute("x");
 126             Assert.assertNotEquals(x1, x2);
 127             Assert.assertEquals(x1, "hello");
 128             Assert.assertEquals(x2, "world");
 129 
 130             x1 = e.eval("x");
 131             x2 = e.eval("x", newCtxt);
 132             Assert.assertNotEquals(x1, x2);
 133             Assert.assertEquals(x1, "hello");
 134             Assert.assertEquals(x2, "world");
 135 
 136             final ScriptContext origCtxt = e.getContext();
 137             e.setContext(newCtxt);
 138             e.eval("y = new Object()");
 139             e.eval("y = new Object()", origCtxt);
 140 
 141             Object y1 = origCtxt.getAttribute("y");
 142             Object y2 = newCtxt.getAttribute("y");
 143             Assert.assertNotEquals(y1, y2);
 144             Assert.assertNotEquals(e.eval("y"), e.eval("y", origCtxt));
 145             Assert.assertEquals("[object Object]", y1.toString());
 146             Assert.assertEquals("[object Object]", y2.toString());
 147         } catch (final ScriptException se) {
 148             se.printStackTrace();
 149             fail(se.getMessage());
 150         }
 151     }
 152 
 153     @Test
 154     public void userEngineScopeBindingsTest() throws ScriptException {
 155         final ScriptEngineManager m = new ScriptEngineManager();
 156         final ScriptEngine e = m.getEngineByName("nashorn");
 157         e.eval("function func() {}");
 158 
 159         final ScriptContext newContext = new SimpleScriptContext();
 160         newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE);
 161         // we are using a new bindings - so it should have 'func' defined
 162         Object value = e.eval("typeof func", newContext);
 163         assertTrue(value.equals("undefined"));
 164     }
 165 
 166     @Test
 167     public void userEngineScopeBindingsNoLeakTest() throws ScriptException {
 168         final ScriptEngineManager m = new ScriptEngineManager();
 169         final ScriptEngine e = m.getEngineByName("nashorn");
 170         final ScriptContext newContext = new SimpleScriptContext();
 171         newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE);
 172         e.eval("function foo() {}", newContext);
 173 
 174         // in the default context's ENGINE_SCOPE, 'foo' shouldn't exist
 175         assertTrue(e.eval("typeof foo").equals("undefined"));
 176     }
 177 
 178     @Test
 179     public void userEngineScopeBindingsRetentionTest() throws ScriptException {
 180         final ScriptEngineManager m = new ScriptEngineManager();
 181         final ScriptEngine e = m.getEngineByName("nashorn");
 182         final ScriptContext newContext = new SimpleScriptContext();
 183         newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE);
 184         e.eval("function foo() {}", newContext);
 185 
 186         // definition retained with user's ENGINE_SCOPE Binding
 187         assertTrue(e.eval("typeof foo", newContext).equals("function"));
 188 
 189         final Bindings oldBindings = newContext.getBindings(ScriptContext.ENGINE_SCOPE);
 190         // but not in another ENGINE_SCOPE binding
 191         newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE);
 192         assertTrue(e.eval("typeof foo", newContext).equals("undefined"));
 193 
 194         // restore ENGINE_SCOPE and check again
 195         newContext.setBindings(oldBindings, ScriptContext.ENGINE_SCOPE);
 196         assertTrue(e.eval("typeof foo", newContext).equals("function"));
 197     }
 198 
 199     @Test
 200     // check that engine.js definitions are visible in all new global instances
 201     public void checkBuiltinsInNewBindingsTest() throws ScriptException {
 202         final ScriptEngineManager m = new ScriptEngineManager();
 203         final ScriptEngine e = m.getEngineByName("nashorn");
 204 
 205         // check default global instance has engine.js definitions
 206         final Bindings g = (Bindings) e.eval("this");
 207         Object value = g.get("__noSuchProperty__");
 208         assertTrue(value instanceof ScriptObjectMirror && ((ScriptObjectMirror)value).isFunction());
 209         value = g.get("print");
 210         assertTrue(value instanceof ScriptObjectMirror && ((ScriptObjectMirror)value).isFunction());
 211 
 212         // check new global instance created has engine.js definitions
 213         Bindings b = e.createBindings();
 214         value = b.get("__noSuchProperty__");
 215         assertTrue(value instanceof ScriptObjectMirror && ((ScriptObjectMirror)value).isFunction());
 216         value = b.get("print");
 217         assertTrue(value instanceof ScriptObjectMirror && ((ScriptObjectMirror)value).isFunction());
 218 
 219         // put a mapping into GLOBAL_SCOPE
 220         final Bindings globalScope = e.getContext().getBindings(ScriptContext.GLOBAL_SCOPE);
 221         globalScope.put("x", "hello");
 222 
 223         // GLOBAL_SCOPE mapping should be visible from default ScriptContext eval
 224         assertTrue(e.eval("x").equals("hello"));
 225 
 226         final ScriptContext ctx = new SimpleScriptContext();
 227         ctx.setBindings(globalScope, ScriptContext.GLOBAL_SCOPE);
 228         ctx.setBindings(b, ScriptContext.ENGINE_SCOPE);
 229 
 230         // GLOBAL_SCOPE mapping should be visible from non-default ScriptContext eval
 231         assertTrue(e.eval("x", ctx).equals("hello"));
 232 
 233         // try some arbitray Bindings for ENGINE_SCOPE
 234         Bindings sb = new SimpleBindings();
 235         ctx.setBindings(sb, ScriptContext.ENGINE_SCOPE);
 236 
 237         // GLOBAL_SCOPE mapping should be visible from non-default ScriptContext eval
 238         assertTrue(e.eval("x", ctx).equals("hello"));
 239 
 240         // engine.js builtins are still defined even with arbitrary Bindings
 241         assertTrue(e.eval("typeof print", ctx).equals("function"));
 242         assertTrue(e.eval("typeof __noSuchProperty__", ctx).equals("function"));
 243 
 244         // ENGINE_SCOPE definition should 'hide' GLOBAL_SCOPE definition
 245         sb.put("x", "newX");
 246         assertTrue(e.eval("x", ctx).equals("newX"));
 247     }




































































































































































































































































































 248 }
--- EOF ---