/** * Creates a Map from a V8Object using a deep copy. All elements * in the V8Object are released after they are accessed. However, the root * object itself is not released. * * @param object The root of the V8Object graph. * * @return A map representing a deep copy of the V8Object rooted at 'object'. */ public static Map<String, ? super Object> toMap(final V8Object object) { return toMap(object, DEFAULT_TYPE_ADAPTER); }
/** * Creates a Map from a V8Object using a deep copy and a TypeAdapter to handle * type conversions. All elements in the V8Object are released after they are accessed. * However, the root object itself is not released. * * @param object The root of the V8Object graph. * @param adapter The {@link TypeAdapter} to use for the object conversions. * * @return A map representing a deep copy of the V8Object rooted at 'object'. */ public static Map<String, ? super Object> toMap(final V8Object object, final TypeAdapter adapter) { V8Map<Object> cache = new V8Map<Object>(); try { return toMap(object, cache, adapter); } finally { cache.close(); } }
private static Object getValue(final Object value, final int valueType, final V8Map<Object> cache, final TypeAdapter adapter) { Object adapterResult = adapter.adapt(valueType, value); if (TypeAdapter.DEFAULT != adapterResult) { return adapterResult; } switch (valueType) { case V8Value.INTEGER: case V8Value.DOUBLE: case V8Value.BOOLEAN: case V8Value.STRING: return value; case V8Value.V8_FUNCTION: return IGNORE; case V8Value.V8_ARRAY_BUFFER: return new ArrayBuffer((V8ArrayBuffer) value); case V8Value.V8_TYPED_ARRAY: return new TypedArray((V8TypedArray) value); case V8Value.V8_ARRAY: return toList((V8Array) value, cache, adapter); case V8Value.V8_OBJECT: return toMap((V8Object) value, cache, adapter); case V8Value.NULL: return null; case V8Value.UNDEFINED: return V8.getUndefined(); default: throw new IllegalStateException("Cannot convert type " + V8Value.getStringRepresentation(valueType)); } }
/** * Creates a Map from a V8Object using a deep copy. All elements * in the V8Object are released after they are accessed. However, the root * object itself is not released. * * @param object The root of the V8Object graph. * * @return A map representing a deep copy of the V8Object rooted at 'object'. */ public static Map<String, ? super Object> toMap(final V8Object object) { return toMap(object, DEFAULT_TYPE_ADAPTER); }
@Test public void testNullObjectGivesEmptyMap() { Map<String, ? super Object> map = V8ObjectUtils.toMap(null); assertNotNull(map); assertEquals(0, map.size()); }
@SuppressWarnings("rawtypes") @Test public void testCreateMapWithLists() { V8Object object = v8.executeObjectScript("x = {a:[1,2,3], b:[4,5,6]}; x;"); Map<String, ? super Object> map = V8ObjectUtils.toMap(object); assertEquals(2, map.size()); assertEquals(1, ((List) map.get("a")).get(0)); assertEquals(2, ((List) map.get("a")).get(1)); assertEquals(3, ((List) map.get("a")).get(2)); assertEquals(4, ((List) map.get("b")).get(0)); assertEquals(5, ((List) map.get("b")).get(1)); assertEquals(6, ((List) map.get("b")).get(2)); object.close(); }
@SuppressWarnings("unchecked") @Test public void testBackpointer() { V8Object parent = v8.executeObjectScript("var parent = {};\n" + "var child = {parent : parent};\n" + "parent.child = child\n;" + "parent;"); Map<String, Object> map = V8ObjectUtils.toMap(parent); assertEquals(map, ((Map<String, Object>) map.get("child")).get("parent")); parent.close(); }
@Test public void testV8ObjectContainsSelf() { V8Object v8Object = new V8Object(v8); v8Object.add("self", v8Object); Map<String, Object> map = V8ObjectUtils.toMap(v8Object); assertEquals(map, map.get("self")); assertEquals(map.hashCode(), map.get("self").hashCode()); v8Object.close(); }
@SuppressWarnings("rawtypes") @Test public void testCreateNestedMapFromV8Object() { V8Object object = v8.executeObjectScript("x = { name : { first :'john', last: 'smith'}, age: 7}; x"); Map<String, ? super Object> map = V8ObjectUtils.toMap(object); assertEquals(2, map.size()); assertEquals(7, map.get("age")); assertEquals("john", ((Map) map.get("name")).get("first")); assertEquals("smith", ((Map) map.get("name")).get("last")); object.close(); }
@Test public void testEqualSiblings() { V8Object parent = v8.executeObjectScript("var parent = {};\n" + "var child = {parent : parent};\n" + "parent.child1 = child\n;" + "parent.child2 = child\n;" + "parent;"); Map<String, Object> map = V8ObjectUtils.toMap(parent); assertEquals((map.get("child2")), (map.get("child1"))); parent.close(); }
@Test public void testCreateDoubleMapFromV8Object() { V8Object object = v8.executeObjectScript("x = {a:1.1, b:2.2, c:3.3, d:4.4}; x"); Map<String, ? super Object> map = V8ObjectUtils.toMap(object); assertEquals(4, map.size()); assertEquals(1.1, (Double) map.get("a"), 0.000001); assertEquals(2.2, (Double) map.get("b"), 0.000001); assertEquals(3.3, (Double) map.get("c"), 0.000001); assertEquals(4.4, (Double) map.get("d"), 0.000001); object.close(); }
@Test public void testCreateMixedMapFromV8Object() { V8Object object = v8.executeObjectScript("x = {boolean:true, integer:1, double:3.14159, string:'hello'}; x"); Map<String, ? super Object> map = V8ObjectUtils.toMap(object); assertEquals(4, map.size()); assertTrue((Boolean) map.get("boolean")); assertEquals(1, (int) (Integer) map.get("integer")); assertEquals(3.14159, (Double) map.get("double"), 0.0000001); assertEquals("hello", map.get("string")); object.close(); }
@Test public void testCreateIntegerMapFromV8Object() { V8Object object = v8.executeObjectScript("x = {a:1, b:2, c:3}; x"); Map<String, ? super Object> map = V8ObjectUtils.toMap(object); assertEquals(3, map.size()); assertEquals(1, map.get("a")); assertEquals(2, map.get("b")); assertEquals(3, map.get("c")); object.close(); }
@Test public void testCreateBooleanMapFromV8Object() { V8Object object = v8.executeObjectScript("x = {a:true, b:1==1, c:false, d:1!=1}; x"); Map<String, ? super Object> map = V8ObjectUtils.toMap(object); assertEquals(4, map.size()); assertTrue((Boolean) map.get("a")); assertTrue((Boolean) map.get("b")); assertFalse((Boolean) map.get("c")); assertFalse((Boolean) map.get("d")); object.close(); }
@Test public void testCreateMapWithFunction() { V8Object object = v8.executeObjectScript("x = {a : function() {return 1;}, b : 'foo'}; x;"); Map<String, ? super Object> map = V8ObjectUtils.toMap(object); assertEquals(1, map.size()); assertEquals("foo", map.get("b")); object.close(); }
@Test public void testCreateStringMapFromV8Object() { V8Object object = v8.executeObjectScript("x = {a:'foo', b:'bar', c:'baz', d:'boo'}; x"); Map<String, ? super Object> map = V8ObjectUtils.toMap(object); assertEquals(4, map.size()); assertEquals("foo", map.get("a")); assertEquals("bar", map.get("b")); assertEquals("baz", map.get("c")); assertEquals("boo", map.get("d")); object.close(); }
@Test public void testCreateMapWithNulls() { V8Object object = v8.executeObjectScript("x = {a:null}; x;"); Map<String, ? super Object> map = V8ObjectUtils.toMap(object); assertEquals(1, map.size()); assertNull(map.get("a")); object.close(); }
@Test public void testObjectUndefinedTypeAdapter_Map() { V8Object object = v8.executeObjectScript("x = {b:{a:{}}}; x"); Map<String, ? super Object> map = V8ObjectUtils.toMap(object, new SingleTypeAdapter(V8Value.V8_OBJECT) { @Override public Object adapt(final Object value) { return V8.getUndefined(); } }); assertEquals(1, map.size()); assertEquals(V8.getUndefined(), map.get("b")); object.close(); }
@Test public void testCloneV8Object() { V8Object list = v8.executeObjectScript("var l = [{first:'ian', last:'bull'}, {first:'sadie', last:'bull'}]; l;"); V8Object v8Object = V8ObjectUtils.toV8Object(v8, V8ObjectUtils.toMap(list)); v8.add("l2", v8Object); v8.executeBooleanScript("JSON.stringify(l) === JSON.stringify(l2);"); list.close(); v8Object.close(); }
@Test public void testCloneV8ObjectsWithCircularStructure() { V8Object parent = v8.executeObjectScript("var parent = {};\n" + "var child = {parent : parent};\n" + "parent.child = child\n;" + "parent;"); V8Object v8Object = V8ObjectUtils.toV8Object(v8, V8ObjectUtils.toMap(parent)); assertEquals(1, v8Object.getKeys().length); assertEquals("child", v8Object.getKeys()[0]); parent.close(); v8Object.close(); }