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.internal.runtime.test;
  27 
  28 import static jdk.nashorn.internal.runtime.Source.sourceFor;
  29 import static org.testng.Assert.assertEquals;
  30 import static org.testng.Assert.assertTrue;
  31 import static org.testng.Assert.fail;
  32 import java.util.Map;
  33 import jdk.nashorn.internal.objects.Global;
  34 import jdk.nashorn.internal.runtime.Context;
  35 import jdk.nashorn.internal.runtime.ErrorManager;
  36 import jdk.nashorn.internal.runtime.ScriptFunction;
  37 import jdk.nashorn.internal.runtime.ScriptObject;
  38 import jdk.nashorn.internal.runtime.ScriptRuntime;
  39 import jdk.nashorn.internal.runtime.Source;
  40 import jdk.nashorn.internal.runtime.options.Options;
  41 import org.testng.annotations.Test;
  42 
  43 /**
  44  * Basic Context API tests.
  45  *
  46  * @test
  47  * @modules jdk.scripting.nashorn/jdk.nashorn.internal.runtime
  48  *          jdk.scripting.nashorn/jdk.nashorn.internal.runtime.options
  49  *          jdk.scripting.nashorn/jdk.nashorn.internal.objects
  50  * @run testng jdk.nashorn.internal.runtime.test.ContextTest
  51  */
  52 @SuppressWarnings("javadoc")
  53 public class ContextTest {
  54     // basic context eval test
  55     @Test
  56     public void evalTest() {
  57         final Options options = new Options("");
  58         final ErrorManager errors = new ErrorManager();
  59         final Context cx = new Context(options, errors, Thread.currentThread().getContextClassLoader());
  60         final Global oldGlobal = Context.getGlobal();
  61         Context.setGlobal(cx.createGlobal());
  62         try {
  63             String code = "22 + 10";
  64             assertTrue(32.0 == ((Number)(eval(cx, "<evalTest>", code))).doubleValue());
  65 
  66             code = "obj = { js: 'nashorn' }; obj.js";
  67             assertEquals(eval(cx, "<evalTest2>", code), "nashorn");
  68         } finally {
  69             Context.setGlobal(oldGlobal);
  70         }
  71     }
  72 
  73     // Make sure trying to compile an invalid script returns null - see JDK-8046215.
  74     @Test
  75     public void compileErrorTest() {
  76         final Options options = new Options("");
  77         final ErrorManager errors = new ErrorManager();
  78         final Context cx = new Context(options, errors, Thread.currentThread().getContextClassLoader());
  79         final Global oldGlobal = Context.getGlobal();
  80         Context.setGlobal(cx.createGlobal());
  81         try {
  82             final ScriptFunction script = cx.compileScript(sourceFor("<evalCompileErrorTest>", "*/"), Context.getGlobal());
  83             if (script != null) {
  84                 fail("Invalid script compiled without errors");
  85             }
  86             if (errors.getNumberOfErrors() != 1) {
  87                 fail("Wrong number of errors: " + errors.getNumberOfErrors());
  88             }
  89         } finally {
  90             Context.setGlobal(oldGlobal);
  91         }
  92     }
  93 
  94     // basic check for JS reflection access - java.util.Map-like access on ScriptObject
  95     @Test
  96     public void reflectionTest() {
  97         final Options options = new Options("");
  98         final ErrorManager errors = new ErrorManager();
  99         final Context cx = new Context(options, errors, Thread.currentThread().getContextClassLoader());
 100         final boolean strict = cx.getEnv()._strict;
 101         final Global oldGlobal = Context.getGlobal();
 102         Context.setGlobal(cx.createGlobal());
 103 
 104         try {
 105             final String code = "var obj = { x: 344, y: 42 }";
 106             eval(cx, "<reflectionTest>", code);
 107 
 108             final Object obj = Context.getGlobal().get("obj");
 109 
 110             assertTrue(obj instanceof ScriptObject);
 111 
 112             final ScriptObject sobj = (ScriptObject)obj;
 113             int count = 0;
 114             for (final Map.Entry<?, ?> ex : sobj.entrySet()) {
 115                 final Object key = ex.getKey();
 116                 if (key.equals("x")) {
 117                     assertTrue(ex.getValue() instanceof Number);
 118                     assertTrue(344.0 == ((Number)ex.getValue()).doubleValue());
 119 
 120                     count++;
 121                 } else if (key.equals("y")) {
 122                     assertTrue(ex.getValue() instanceof Number);
 123                     assertTrue(42.0 == ((Number)ex.getValue()).doubleValue());
 124 
 125                     count++;
 126                 }
 127             }
 128             assertEquals(count, 2);
 129             assertEquals(sobj.size(), 2);
 130 
 131             // add property
 132             sobj.put("zee", "hello", strict);
 133             assertEquals(sobj.get("zee"), "hello");
 134             assertEquals(sobj.size(), 3);
 135 
 136         } finally {
 137             Context.setGlobal(oldGlobal);
 138         }
 139     }
 140 
 141     private static Object eval(final Context cx, final String name, final String code) {
 142         final Source source = sourceFor(name, code);
 143         final ScriptObject global = Context.getGlobal();
 144         final ScriptFunction func = cx.compileScript(source, global);
 145         return func != null ? ScriptRuntime.apply(func, global) : null;
 146     }
 147 }