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 java.nio.ByteBuffer; 29 import java.util.HashMap; 30 import java.util.List; 31 import java.util.Map; 32 import javax.script.ScriptEngine; 33 import javax.script.ScriptEngineManager; 34 import javax.script.ScriptException; 35 import static org.testng.Assert.assertEquals; 36 import static org.testng.Assert.assertFalse; 37 import static org.testng.Assert.assertTrue; 38 import static org.testng.Assert.fail; 39 import org.testng.annotations.Test; 40 41 /** 42 * Tests to check jdk.nashorn.api.scripting.ScriptObjectMirror API. 43 */ 44 public class ScriptObjectMirrorTest { 45 46 @SuppressWarnings("unchecked") 47 @Test 48 public void reflectionTest() throws ScriptException { 49 final ScriptEngineManager m = new ScriptEngineManager(); 50 final ScriptEngine e = m.getEngineByName("nashorn"); 51 52 e.eval("var obj = { x: 344, y: 'nashorn' }"); 53 54 int count = 0; 55 Map<Object, Object> map = (Map<Object, Object>) e.get("obj"); 56 assertFalse(map.isEmpty()); 57 assertTrue(map.keySet().contains("x")); 58 assertTrue(map.containsKey("x")); 59 assertTrue(map.values().contains("nashorn")); 60 assertTrue(map.containsValue("nashorn")); 61 for (final Map.Entry<?, ?> ex : map.entrySet()) { 62 final Object key = ex.getKey(); 63 if (key.equals("x")) { 64 assertTrue(344 == ((Number) ex.getValue()).doubleValue()); 65 count++; 66 } else if (key.equals("y")) { 67 assertEquals(ex.getValue(), "nashorn"); 68 count++; 69 } 70 } 71 assertEquals(2, count); 72 assertEquals(2, map.size()); 73 74 // add property 75 map.put("z", "hello"); 76 assertEquals(e.eval("obj.z"), "hello"); 77 assertEquals(map.get("z"), "hello"); 78 assertTrue(map.keySet().contains("z")); 79 assertTrue(map.containsKey("z")); 80 assertTrue(map.values().contains("hello")); 81 assertTrue(map.containsValue("hello")); 82 assertEquals(map.size(), 3); 83 84 final Map<Object, Object> newMap = new HashMap<>(); 85 newMap.put("foo", 23.0); 86 newMap.put("bar", true); 87 map.putAll(newMap); 88 89 assertEquals(e.eval("obj.foo"), 23.0); 90 assertEquals(e.eval("obj.bar"), true); 91 92 // remove using map method 93 map.remove("foo"); 94 assertEquals(e.eval("typeof obj.foo"), "undefined"); 95 96 count = 0; 97 e.eval("var arr = [ true, 'hello' ]"); 98 map = (Map<Object, Object>) e.get("arr"); 99 assertFalse(map.isEmpty()); 100 assertTrue(map.containsKey("length")); 101 assertTrue(map.containsValue("hello")); 102 for (final Map.Entry<?, ?> ex : map.entrySet()) { 103 final Object key = ex.getKey(); 104 if (key.equals("0")) { 105 assertEquals(ex.getValue(), Boolean.TRUE); 106 count++; 107 } else if (key.equals("1")) { 108 assertEquals(ex.getValue(), "hello"); 109 count++; 110 } 111 } 112 assertEquals(count, 2); 113 assertEquals(map.size(), 2); 114 115 // add element 116 map.put("2", "world"); 117 assertEquals(map.get("2"), "world"); 118 assertEquals(map.size(), 3); 119 120 // remove all 121 map.clear(); 122 assertTrue(map.isEmpty()); 123 assertEquals(e.eval("typeof arr[0]"), "undefined"); 124 assertEquals(e.eval("typeof arr[1]"), "undefined"); 125 assertEquals(e.eval("typeof arr[2]"), "undefined"); 126 } 127 128 @Test 129 public void jsobjectTest() { 130 final ScriptEngineManager m = new ScriptEngineManager(); 131 final ScriptEngine e = m.getEngineByName("nashorn"); 132 try { 133 e.eval("var obj = { '1': 'world', func: function() { return this.bar; }, bar: 'hello' }"); 134 ScriptObjectMirror obj = (ScriptObjectMirror) e.get("obj"); 135 136 // try basic get on existing properties 137 if (!obj.getMember("bar").equals("hello")) { 138 fail("obj.bar != 'hello'"); 139 } 140 141 if (!obj.getSlot(1).equals("world")) { 142 fail("obj[1] != 'world'"); 143 } 144 145 if (!obj.callMember("func", new Object[0]).equals("hello")) { 146 fail("obj.func() != 'hello'"); 147 } 148 149 // try setting properties 150 obj.setMember("bar", "new-bar"); 151 obj.setSlot(1, "new-element-1"); 152 if (!obj.getMember("bar").equals("new-bar")) { 153 fail("obj.bar != 'new-bar'"); 154 } 155 156 if (!obj.getSlot(1).equals("new-element-1")) { 157 fail("obj[1] != 'new-element-1'"); 158 } 159 160 // try adding properties 161 obj.setMember("prop", "prop-value"); 162 obj.setSlot(12, "element-12"); 163 if (!obj.getMember("prop").equals("prop-value")) { 164 fail("obj.prop != 'prop-value'"); 165 } 166 167 if (!obj.getSlot(12).equals("element-12")) { 168 fail("obj[12] != 'element-12'"); 169 } 170 171 // delete properties 172 obj.removeMember("prop"); 173 if ("prop-value".equals(obj.getMember("prop"))) { 174 fail("obj.prop is not deleted!"); 175 } 176 177 // Simple eval tests 178 assertEquals(obj.eval("typeof Object"), "function"); 179 assertEquals(obj.eval("'nashorn'.substring(3)"), "horn"); 180 } catch (final Exception exp) { 181 exp.printStackTrace(); 182 fail(exp.getMessage()); 183 } 184 } 185 186 @Test 187 public void scriptObjectMirrorToStringTest() { 188 final ScriptEngineManager m = new ScriptEngineManager(); 189 final ScriptEngine e = m.getEngineByName("nashorn"); 190 try { 191 Object obj = e.eval("new TypeError('wrong type')"); 192 assertEquals(obj.toString(), "TypeError: wrong type", "toString returns wrong value"); 193 } catch (final Throwable t) { 194 t.printStackTrace(); 195 fail(t.getMessage()); 196 } 197 198 try { 199 Object obj = e.eval("function func() { print('hello'); }"); 200 assertEquals(obj.toString(), "function func() { print('hello'); }", "toString returns wrong value"); 201 } catch (final Throwable t) { 202 t.printStackTrace(); 203 fail(t.getMessage()); 204 } 205 } 206 207 @Test 208 public void mirrorNewObjectGlobalFunctionTest() throws ScriptException { 209 final ScriptEngineManager m = new ScriptEngineManager(); 210 final ScriptEngine e = m.getEngineByName("nashorn"); 211 final ScriptEngine e2 = m.getEngineByName("nashorn"); 212 213 e.eval("function func() {}"); 214 e2.put("foo", e.get("func")); 215 final ScriptObjectMirror e2global = (ScriptObjectMirror)e2.eval("this"); 216 final Object newObj = ((ScriptObjectMirror)e2global.getMember("foo")).newObject(); 217 assertTrue(newObj instanceof ScriptObjectMirror); 218 } 219 220 @Test 221 public void mirrorNewObjectInstanceFunctionTest() throws ScriptException { 222 final ScriptEngineManager m = new ScriptEngineManager(); 223 final ScriptEngine e = m.getEngineByName("nashorn"); 224 final ScriptEngine e2 = m.getEngineByName("nashorn"); 225 226 e.eval("function func() {}"); 227 e2.put("func", e.get("func")); 228 final ScriptObjectMirror e2obj = (ScriptObjectMirror)e2.eval("({ foo: func })"); 229 final Object newObj = ((ScriptObjectMirror)e2obj.getMember("foo")).newObject(); 230 assertTrue(newObj instanceof ScriptObjectMirror); 231 } 232 233 @Test 234 public void indexPropertiesExternalBufferTest() throws ScriptException { 235 final ScriptEngineManager m = new ScriptEngineManager(); 236 final ScriptEngine e = m.getEngineByName("nashorn"); 237 final ScriptObjectMirror obj = (ScriptObjectMirror)e.eval("var obj = {}; obj"); 238 final ByteBuffer buf = ByteBuffer.allocate(5); 239 int i; 240 for (i = 0; i < 5; i++) { 241 buf.put(i, (byte)(i+10)); 242 } 243 obj.setIndexedPropertiesToExternalArrayData(buf); 244 245 for (i = 0; i < 5; i++) { 246 assertEquals((byte)(i+10), ((Number)e.eval("obj[" + i + "]")).byteValue()); 247 } 248 249 e.eval("for (i = 0; i < 5; i++) obj[i] = 0"); 250 for (i = 0; i < 5; i++) { 251 assertEquals((byte)0, ((Number)e.eval("obj[" + i + "]")).byteValue()); 252 assertEquals((byte)0, buf.get(i)); 253 } 254 } 255 256 @Test 257 public void conversionTest() throws ScriptException { 258 final ScriptEngineManager m = new ScriptEngineManager(); 259 final ScriptEngine e = m.getEngineByName("nashorn"); 260 final ScriptObjectMirror arr = (ScriptObjectMirror)e.eval("[33, 45, 23]"); 261 final int[] intArr = arr.to(int[].class); 262 assertEquals(intArr[0], 33); 263 assertEquals(intArr[1], 45); 264 assertEquals(intArr[2], 23); 265 266 final List<?> list = arr.to(List.class); 267 assertEquals(list.get(0), 33); 268 assertEquals(list.get(1), 45); 269 assertEquals(list.get(2), 23); 270 271 ScriptObjectMirror obj = (ScriptObjectMirror)e.eval( 272 "({ valueOf: function() { return 42 } })"); 273 assertEquals(Double.valueOf(42.0), obj.to(Double.class)); 274 275 obj = (ScriptObjectMirror)e.eval( 276 "({ toString: function() { return 'foo' } })"); 277 assertEquals("foo", obj.to(String.class)); 278 } 279 }