/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.stetho.json;
import android.os.Build;
import com.facebook.stetho.json.annotation.JsonProperty;
import com.facebook.stetho.json.annotation.JsonValue;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
import java.util.Objects;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* Tests for {@link ObjectMapper}
*/
@Config(emulateSdk = Build.VERSION_CODES.JELLY_BEAN)
@RunWith(RobolectricTestRunner.class)
public class ObjectMapperTest {
private ObjectMapper mObjectMapper;
@Before
public void setup() {
mObjectMapper = new ObjectMapper();
}
@Test
public void testJsonProperty() throws IOException, JSONException {
JsonPropertyString c = new JsonPropertyString();
c.testString = "test";
String expected = "{\"testString\":\"test\"}";
JSONObject jsonObject = mObjectMapper.convertValue(c, JSONObject.class);
String str = jsonObject.toString();
assertEquals(expected, str);
JsonPropertyString jsonPropertyString = mObjectMapper.convertValue(
new JSONObject(expected),
JsonPropertyString.class);
assertEquals(c, jsonPropertyString);
}
@Test
public void testNestedProperty() throws JSONException {
NestedJsonProperty njp = new NestedJsonProperty();
njp.child1 = new JsonPropertyString();
njp.child2 = new JsonPropertyInt();
njp.child1.testString = "testString";
njp.child2.i = 4;
// The ordering of serialization changes depending on Java 7 vs Java 8.
String expected7 = "{\"child1\":{\"testString\":\"testString\"},\"child2\":{\"i\":4}}";
String expected8 = "{\"child2\":{\"i\":4},\"child1\":{\"testString\":\"testString\"}}";
NestedJsonProperty parsed7 = mObjectMapper.convertValue(
new JSONObject(expected7),
NestedJsonProperty.class);
assertEquals(njp, parsed7);
NestedJsonProperty parsed8 = mObjectMapper.convertValue(
new JSONObject(expected8),
NestedJsonProperty.class);
assertEquals(njp, parsed8);
JSONObject jsonObject = mObjectMapper.convertValue(njp, JSONObject.class);
assertTrue(expected7.equals(jsonObject.toString()) || expected8.equals(jsonObject.toString()));
}
@Test
public void testEnumProperty() throws JSONException {
JsonPropertyEnum jpe = new JsonPropertyEnum();
jpe.enumValue = TestEnum.VALUE_TWO;
String expected = "{\"enumValue\":\"two\"}";
JsonPropertyEnum parsed = mObjectMapper.convertValue(
new JSONObject(expected),
JsonPropertyEnum.class);
assertEquals(jpe, parsed);
JSONObject jsonObject = mObjectMapper.convertValue(jpe, JSONObject.class);
assertEquals(expected, jsonObject.toString());
}
@Test
public void testListString() throws JSONException {
JsonPropertyStringList jpsl = new JsonPropertyStringList();
List<String> values = new ArrayList<String>();
jpsl.stringList = values;
values.add("one");
values.add("two");
values.add("three");
String expected = "{\"stringList\":[\"one\",\"two\",\"three\"]}";
JsonPropertyStringList jsonPropertyStringList = mObjectMapper.convertValue(
new JSONObject(expected),
JsonPropertyStringList.class);
assertEquals(jpsl, jsonPropertyStringList);
JSONObject jsonObject = mObjectMapper.convertValue(jpsl, JSONObject.class);
String str = jsonObject.toString();
assertEquals(expected, str);
}
@Test
public void testSerializeMultitypedList() throws JSONException {
List<Object> list = new ArrayList<Object>();
list.add("foo");
list.add(Collections.singletonList("bar"));
JsonPropertyMultitypedList javaObj = new JsonPropertyMultitypedList();
javaObj.multitypedList = list;
String expected = "{\"multitypedList\":[\"foo\",[\"bar\"]]}";
JSONObject jsonObj = mObjectMapper.convertValue(javaObj, JSONObject.class);
String str = jsonObj.toString();
assertEquals(expected, str);
}
@Test
public void testSerializeListOfLists() throws JSONException {
List<List<String>> listOfLists = new ArrayList<List<String>>();
listOfLists.add(Collections.singletonList("foo"));
ArrayList<String> sublist2 = new ArrayList<String>();
sublist2.add("1");
sublist2.add("2");
listOfLists.add(sublist2);
JsonPropertyListOfLists javaObj = new JsonPropertyListOfLists();
javaObj.listOfLists = listOfLists;
String expected = "{\"listOfLists\":[[\"foo\"],[\"1\",\"2\"]]}";
JSONObject jsonObj = mObjectMapper.convertValue(javaObj, JSONObject.class);
String str = jsonObj.toString();
assertEquals(expected, str);
}
@Test
public void testObjectToPrimitive() throws JSONException {
ArrayOfPrimitivesContainer container = new ArrayOfPrimitivesContainer();
ArrayList<Object> primitives = container.primitives;
primitives.add(Long.MIN_VALUE);
primitives.add(Long.MAX_VALUE);
primitives.add(Integer.MIN_VALUE);
primitives.add(Integer.MAX_VALUE);
primitives.add(Float.MIN_VALUE);
primitives.add(Float.MAX_VALUE);
primitives.add(Double.MIN_VALUE);
primitives.add(Double.MAX_VALUE);
String json = mObjectMapper.convertValue(container, JSONObject.class).toString();
JSONObject obj = new JSONObject(json);
JSONArray array = obj.getJSONArray("primitives");
ArrayList<Object> actual = new ArrayList<>();
for (int i = 0, N = array.length(); i < N; i++) {
actual.add(array.get(i));
}
assertEquals(primitives.toString(), actual.toString());
}
public static class ArrayOfPrimitivesContainer {
@JsonProperty
public final ArrayList<Object> primitives = new ArrayList<>();
}
public static class NestedJsonProperty {
@JsonProperty(required = true)
public JsonPropertyString child1;
@JsonProperty
public JsonPropertyInt child2;
@Override
public boolean equals(Object o) {
if (o == null || !(o instanceof NestedJsonProperty)) {
return false;
}
return Objects.equals(child1, ((NestedJsonProperty) o).child1) &&
Objects.equals(child2, ((NestedJsonProperty) o).child2);
}
}
public static class JsonPropertyString {
@JsonProperty
public String testString;
@Override
public boolean equals(Object o) {
if (o == null || !(o instanceof JsonPropertyString)) {
return false;
}
return Objects.equals(testString, ((JsonPropertyString) o).testString);
}
}
public static class JsonPropertyInt {
@JsonProperty
public int i;
@Override
public boolean equals(Object o) {
if (o == null || !(o instanceof JsonPropertyInt)) {
return false;
}
return Objects.equals(i, ((JsonPropertyInt) o).i);
}
}
public static class JsonPropertyEnum {
@JsonProperty
public TestEnum enumValue;
@Override
public boolean equals(Object o) {
if (o == null || !(o instanceof JsonPropertyEnum)) {
return false;
}
return Objects.equals(enumValue, ((JsonPropertyEnum) o).enumValue);
}
}
public static class JsonPropertyStringList {
@JsonProperty
public List<String> stringList;
@Override
public boolean equals(Object o) {
if (o == null || !(o instanceof JsonPropertyStringList)) {
return false;
}
JsonPropertyStringList rhs = (JsonPropertyStringList) o;
if (stringList == null || rhs.stringList == null) {
return stringList == rhs.stringList;
}
if (stringList.size() != rhs.stringList.size()) {
return false;
}
ListIterator<String> myIter = stringList.listIterator();
ListIterator<String> rhsIter = rhs.stringList.listIterator();
while (myIter.hasNext()) {
if (!Objects.equals(myIter.next(), rhsIter.next())) {
return false;
}
}
return true;
}
}
public enum TestEnum {
VALUE_ONE("one"),
VALUE_TWO("two"),
VALUE_THREE("three");
private final String mValue;
private TestEnum(String str) {
mValue = str;
}
@JsonValue
public String getValue() {
return mValue;
}
}
private static class JsonPropertyMultitypedList {
@JsonProperty
public List<Object> multitypedList;
}
private static class JsonPropertyListOfLists {
@JsonProperty
public List<List<String>> listOfLists;
}
}