Mon, 03 Nov 2014 11:47:41 +0100
8060204: Fix warnings in Joni and tests
Reviewed-by: hannesw, sundar, attila
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 */
26 package jdk.nashorn.api.scripting;
28 import static org.testng.Assert.assertEquals;
29 import static org.testng.Assert.assertFalse;
30 import static org.testng.Assert.fail;
32 import java.nio.IntBuffer;
33 import java.util.Collection;
34 import java.util.HashMap;
35 import java.util.LinkedHashMap;
36 import java.util.Set;
37 import javax.script.ScriptEngine;
38 import javax.script.ScriptEngineManager;
39 import org.testng.annotations.Test;
41 /**
42 * Tests for pluggable external impls. of jdk.nashorn.api.scripting.JSObject.
43 *
44 * JDK-8024615: Refactor ScriptObjectMirror and JSObject to support external
45 * JSObject implementations.
46 */
47 @SuppressWarnings("javadoc")
48 public class PluggableJSObjectTest {
49 public static class MapWrapperObject extends AbstractJSObject {
50 private final HashMap<String, Object> map = new LinkedHashMap<>();
52 public HashMap<String, Object> getMap() {
53 return map;
54 }
56 @Override
57 public Object getMember(final String name) {
58 return map.get(name);
59 }
61 @Override
62 public void setMember(final String name, final Object value) {
63 map.put(name, value);
64 }
66 @Override
67 public boolean hasMember(final String name) {
68 return map.containsKey(name);
69 }
71 @Override
72 public void removeMember(final String name) {
73 map.remove(name);
74 }
76 @Override
77 public Set<String> keySet() {
78 return map.keySet();
79 }
81 @Override
82 public Collection<Object> values() {
83 return map.values();
84 }
85 }
87 @Test
88 // Named property access on a JSObject
89 public void namedAccessTest() {
90 final ScriptEngineManager m = new ScriptEngineManager();
91 final ScriptEngine e = m.getEngineByName("nashorn");
92 try {
93 final MapWrapperObject obj = new MapWrapperObject();
94 e.put("obj", obj);
95 obj.getMap().put("foo", "bar");
97 // property-like access on MapWrapperObject objects
98 assertEquals(e.eval("obj.foo"), "bar");
99 e.eval("obj.foo = 'hello'");
100 assertEquals(e.eval("'foo' in obj"), Boolean.TRUE);
101 assertEquals(e.eval("obj.foo"), "hello");
102 assertEquals(obj.getMap().get("foo"), "hello");
103 e.eval("delete obj.foo");
104 assertFalse(obj.getMap().containsKey("foo"));
105 assertEquals(e.eval("'foo' in obj"), Boolean.FALSE);
106 } catch (final Exception exp) {
107 exp.printStackTrace();
108 fail(exp.getMessage());
109 }
110 }
112 public static class BufferObject extends AbstractJSObject {
113 private final IntBuffer buf;
115 public BufferObject(final int size) {
116 buf = IntBuffer.allocate(size);
117 }
119 public IntBuffer getBuffer() {
120 return buf;
121 }
123 @Override
124 public Object getMember(final String name) {
125 return name.equals("length")? buf.capacity() : null;
126 }
128 @Override
129 public boolean hasSlot(final int i) {
130 return i > -1 && i < buf.capacity();
131 }
133 @Override
134 public Object getSlot(final int i) {
135 return buf.get(i);
136 }
138 @Override
139 public void setSlot(final int i, final Object value) {
140 buf.put(i, ((Number)value).intValue());
141 }
143 @Override
144 public boolean isArray() {
145 return true;
146 }
147 }
149 @Test
150 // array-like indexed access for a JSObject
151 public void indexedAccessTest() {
152 final ScriptEngineManager m = new ScriptEngineManager();
153 final ScriptEngine e = m.getEngineByName("nashorn");
154 try {
155 final BufferObject buf = new BufferObject(2);
156 e.put("buf", buf);
158 // array-like access on BufferObject objects
159 assertEquals(e.eval("buf.length"), buf.getBuffer().capacity());
160 e.eval("buf[0] = 23");
161 assertEquals(buf.getBuffer().get(0), 23);
162 assertEquals(e.eval("buf[0]"), 23);
163 assertEquals(e.eval("buf[1]"), 0);
164 buf.getBuffer().put(1, 42);
165 assertEquals(e.eval("buf[1]"), 42);
166 assertEquals(e.eval("Array.isArray(buf)"), Boolean.TRUE);
167 } catch (final Exception exp) {
168 exp.printStackTrace();
169 fail(exp.getMessage());
170 }
171 }
173 public static class Adder extends AbstractJSObject {
174 @Override
175 public Object call(final Object thiz, final Object... args) {
176 double res = 0.0;
177 for (final Object arg : args) {
178 res += ((Number)arg).doubleValue();
179 }
180 return res;
181 }
183 @Override
184 public boolean isFunction() {
185 return true;
186 }
187 }
189 @Test
190 // a callable JSObject
191 public void callableJSObjectTest() {
192 final ScriptEngineManager m = new ScriptEngineManager();
193 final ScriptEngine e = m.getEngineByName("nashorn");
194 try {
195 e.put("sum", new Adder());
196 // check callability of Adder objects
197 assertEquals(e.eval("typeof sum"), "function");
198 assertEquals(((Number)e.eval("sum(1, 2, 3, 4, 5)")).intValue(), 15);
199 } catch (final Exception exp) {
200 exp.printStackTrace();
201 fail(exp.getMessage());
202 }
203 }
205 public static class Factory extends AbstractJSObject {
206 @SuppressWarnings("unused")
207 @Override
208 public Object newObject(final Object... args) {
209 return new HashMap<Object, Object>();
210 }
212 @Override
213 public boolean isFunction() {
214 return true;
215 }
216 }
218 @Test
219 // a factory JSObject
220 public void factoryJSObjectTest() {
221 final ScriptEngineManager m = new ScriptEngineManager();
222 final ScriptEngine e = m.getEngineByName("nashorn");
223 try {
224 e.put("Factory", new Factory());
226 // check new on Factory
227 assertEquals(e.eval("typeof Factory"), "function");
228 assertEquals(e.eval("typeof new Factory()"), "object");
229 assertEquals(e.eval("(new Factory()) instanceof java.util.Map"), Boolean.TRUE);
230 } catch (final Exception exp) {
231 exp.printStackTrace();
232 fail(exp.getMessage());
233 }
234 }
236 @Test
237 // iteration tests
238 public void iteratingJSObjectTest() {
239 final ScriptEngineManager m = new ScriptEngineManager();
240 final ScriptEngine e = m.getEngineByName("nashorn");
241 try {
242 final MapWrapperObject obj = new MapWrapperObject();
243 obj.setMember("foo", "hello");
244 obj.setMember("bar", "world");
245 e.put("obj", obj);
247 // check for..in
248 Object val = e.eval("var str = ''; for (i in obj) str += i; str");
249 assertEquals(val.toString(), "foobar");
251 // check for..each..in
252 val = e.eval("var str = ''; for each (i in obj) str += i; str");
253 assertEquals(val.toString(), "helloworld");
254 } catch (final Exception exp) {
255 exp.printStackTrace();
256 fail(exp.getMessage());
257 }
258 }
259 }