diff --git a/gson/src/main/java/com/google/gson/JsonArray.java b/gson/src/main/java/com/google/gson/JsonArray.java
index 5a0c77e8..e9ce580c 100644
--- a/gson/src/main/java/com/google/gson/JsonArray.java
+++ b/gson/src/main/java/com/google/gson/JsonArray.java
@@ -16,6 +16,7 @@
package com.google.gson;
+import com.google.gson.internal.NonNullElementWrapperList;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
@@ -28,11 +29,14 @@ import java.util.List;
* elements are added is preserved. This class does not support {@code null} values. If {@code null}
* is provided as element argument to any of the methods, it is converted to a {@link JsonNull}.
*
+ *
{@code JsonArray} only implements the {@link Iterable} interface but not the {@link List}
+ * interface. A {@code List} view of it can be obtained with {@link #asList()}.
+ *
* @author Inderjeet Singh
* @author Joel Leitch
*/
public final class JsonArray extends JsonElement implements Iterable {
- private final List elements;
+ private final ArrayList elements;
/**
* Creates an empty JsonArray.
@@ -393,6 +397,20 @@ public final class JsonArray extends JsonElement implements IterableThe {@code List} does not permit {@code null} elements. Unlike {@code JsonArray}'s
+ * {@code null} handling, a {@link NullPointerException} is thrown when trying to add {@code null}.
+ * Use {@link JsonNull} for JSON null values.
+ *
+ * @return mutable {@code List} view
+ */
+ public List asList() {
+ return new NonNullElementWrapperList<>(elements);
+ }
+
/**
* Returns whether the other object is equal to this. This method only considers
* the other object to be equal if it is an instance of {@code JsonArray} and has
diff --git a/gson/src/main/java/com/google/gson/JsonObject.java b/gson/src/main/java/com/google/gson/JsonObject.java
index 428861a6..0c36ef24 100644
--- a/gson/src/main/java/com/google/gson/JsonObject.java
+++ b/gson/src/main/java/com/google/gson/JsonObject.java
@@ -27,6 +27,9 @@ import java.util.Set;
* This class does not support {@code null} values. If {@code null} is provided as value argument
* to any of the methods, it is converted to a {@link JsonNull}.
*
+ * {@code JsonObject} does not implement the {@link Map} interface, but a {@code Map} view
+ * of it can be obtained with {@link #asMap()}.
+ *
* @author Inderjeet Singh
* @author Joel Leitch
*/
@@ -208,6 +211,21 @@ public final class JsonObject extends JsonElement {
return (JsonObject) members.get(memberName);
}
+ /**
+ * Returns a mutable {@link Map} view of this {@code JsonObject}. Changes to the {@code Map}
+ * are visible in this {@code JsonObject} and the other way around.
+ *
+ *
The {@code Map} does not permit {@code null} keys or values. Unlike {@code JsonObject}'s
+ * {@code null} handling, a {@link NullPointerException} is thrown when trying to add {@code null}.
+ * Use {@link JsonNull} for JSON null values.
+ *
+ * @return mutable {@code Map} view
+ */
+ public Map asMap() {
+ // It is safe to expose the underlying map because it disallows null keys and values
+ return members;
+ }
+
/**
* Returns whether the other object is equal to this. This method only considers
* the other object to be equal if it is an instance of {@code JsonObject} and has
diff --git a/gson/src/main/java/com/google/gson/internal/NonNullElementWrapperList.java b/gson/src/main/java/com/google/gson/internal/NonNullElementWrapperList.java
new file mode 100644
index 00000000..b3017430
--- /dev/null
+++ b/gson/src/main/java/com/google/gson/internal/NonNullElementWrapperList.java
@@ -0,0 +1,98 @@
+package com.google.gson.internal;
+
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+import java.util.RandomAccess;
+
+/**
+ * {@link List} which wraps another {@code List} but prevents insertion of
+ * {@code null} elements. Methods which only perform checks with the element
+ * argument (e.g. {@link #contains(Object)}) do not throw exceptions for
+ * {@code null} arguments.
+ */
+public class NonNullElementWrapperList extends AbstractList implements RandomAccess {
+ // Explicitly specify ArrayList as type to guarantee that delegate implements RandomAccess
+ private final ArrayList delegate;
+
+ public NonNullElementWrapperList(ArrayList delegate) {
+ this.delegate = Objects.requireNonNull(delegate);
+ }
+
+ @Override public E get(int index) {
+ return delegate.get(index);
+ }
+
+ @Override public int size() {
+ return delegate.size();
+ }
+
+ private E nonNull(E element) {
+ if (element == null) {
+ throw new NullPointerException("Element must be non-null");
+ }
+ return element;
+ }
+
+ @Override public E set(int index, E element) {
+ return delegate.set(index, nonNull(element));
+ }
+
+ @Override public void add(int index, E element) {
+ delegate.add(index, nonNull(element));
+ }
+
+ @Override public E remove(int index) {
+ return delegate.remove(index);
+ }
+
+ /* The following methods are overridden because their default implementation is inefficient */
+
+ @Override public void clear() {
+ delegate.clear();
+ }
+
+ @Override public boolean remove(Object o) {
+ return delegate.remove(o);
+ }
+
+ @Override public boolean removeAll(Collection> c) {
+ return delegate.removeAll(c);
+ }
+
+ @Override public boolean retainAll(Collection> c) {
+ return delegate.retainAll(c);
+ }
+
+ @Override public boolean contains(Object o) {
+ return delegate.contains(o);
+ }
+
+ @Override public int indexOf(Object o) {
+ return delegate.indexOf(o);
+ }
+
+ @Override public int lastIndexOf(Object o) {
+ return delegate.lastIndexOf(o);
+ }
+
+ @Override public Object[] toArray() {
+ return delegate.toArray();
+ }
+
+ @Override public T[] toArray(T[] a) {
+ return delegate.toArray(a);
+ }
+
+ @Override public boolean equals(Object o) {
+ return delegate.equals(o);
+ }
+
+ @Override public int hashCode() {
+ return delegate.hashCode();
+ }
+
+ // TODO: Once Gson targets Java 8 also override List.sort
+}
diff --git a/gson/src/test/java/com/google/gson/JsonArrayAsListTest.java b/gson/src/test/java/com/google/gson/JsonArrayAsListTest.java
new file mode 100644
index 00000000..36d671f9
--- /dev/null
+++ b/gson/src/test/java/com/google/gson/JsonArrayAsListTest.java
@@ -0,0 +1,285 @@
+package com.google.gson;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.google.gson.common.MoreAsserts;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import org.junit.Test;
+
+/**
+ * Tests for {@link JsonArray#asList()}.
+ */
+public class JsonArrayAsListTest {
+ @Test
+ public void testGet() {
+ JsonArray a = new JsonArray();
+ a.add(1);
+
+ List list = a.asList();
+ assertEquals(new JsonPrimitive(1), list.get(0));
+
+ try {
+ list.get(-1);
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ list.get(2);
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ a.add((JsonElement) null);
+ assertEquals(JsonNull.INSTANCE, list.get(1));
+ }
+
+ @Test
+ public void testSize() {
+ JsonArray a = new JsonArray();
+ a.add(1);
+
+ List list = a.asList();
+ assertEquals(1, list.size());
+ list.add(new JsonPrimitive(2));
+ assertEquals(2, list.size());
+ }
+
+ @Test
+ public void testSet() {
+ JsonArray a = new JsonArray();
+ a.add(1);
+
+ List list = a.asList();
+ JsonElement old = list.set(0, new JsonPrimitive(2));
+ assertEquals(new JsonPrimitive(1), old);
+ assertEquals(new JsonPrimitive(2), list.get(0));
+ assertEquals(new JsonPrimitive(2), a.get(0));
+
+ try {
+ list.set(-1, new JsonPrimitive(1));
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ list.set(2, new JsonPrimitive(1));
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ list.set(0, null);
+ fail();
+ } catch (NullPointerException e) {
+ assertEquals("Element must be non-null", e.getMessage());
+ }
+ }
+
+ @Test
+ public void testAdd() {
+ JsonArray a = new JsonArray();
+ a.add(1);
+
+ List list = a.asList();
+ list.add(0, new JsonPrimitive(2));
+ list.add(1, new JsonPrimitive(3));
+ assertTrue(list.add(new JsonPrimitive(4)));
+ assertTrue(list.add(JsonNull.INSTANCE));
+
+ List expectedList = Arrays.asList(
+ new JsonPrimitive(2),
+ new JsonPrimitive(3),
+ new JsonPrimitive(1),
+ new JsonPrimitive(4),
+ JsonNull.INSTANCE
+ );
+ assertEquals(expectedList, list);
+
+ try {
+ list.set(-1, new JsonPrimitive(1));
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ list.set(list.size(), new JsonPrimitive(1));
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ }
+
+ try {
+ list.add(0, null);
+ fail();
+ } catch (NullPointerException e) {
+ assertEquals("Element must be non-null", e.getMessage());
+ }
+ try {
+ list.add(null);
+ fail();
+ } catch (NullPointerException e) {
+ assertEquals("Element must be non-null", e.getMessage());
+ }
+ }
+
+ @Test
+ public void testAddAll() {
+ JsonArray a = new JsonArray();
+ a.add(1);
+
+ List list = a.asList();
+ list.addAll(Arrays.asList(new JsonPrimitive(2), new JsonPrimitive(3)));
+
+ List expectedList = Arrays.asList(
+ new JsonPrimitive(1),
+ new JsonPrimitive(2),
+ new JsonPrimitive(3)
+ );
+ assertEquals(expectedList, list);
+
+ try {
+ list.addAll(0, Collections.singletonList(null));
+ fail();
+ } catch (NullPointerException e) {
+ assertEquals("Element must be non-null", e.getMessage());
+ }
+ try {
+ list.addAll(Collections.singletonList(null));
+ fail();
+ } catch (NullPointerException e) {
+ assertEquals("Element must be non-null", e.getMessage());
+ }
+ }
+
+ @Test
+ public void testRemoveIndex() {
+ JsonArray a = new JsonArray();
+ a.add(1);
+
+ List list = a.asList();
+ assertEquals(new JsonPrimitive(1), list.remove(0));
+ assertEquals(0, list.size());
+ assertEquals(0, a.size());
+
+ try {
+ list.remove(0);
+ fail();
+ } catch (IndexOutOfBoundsException e) {
+ }
+ }
+
+ @Test
+ public void testRemoveElement() {
+ JsonArray a = new JsonArray();
+ a.add(1);
+
+ List list = a.asList();
+ assertTrue(list.remove(new JsonPrimitive(1)));
+ assertEquals(0, list.size());
+ assertEquals(0, a.size());
+
+ assertFalse(list.remove(new JsonPrimitive(1)));
+ assertFalse(list.remove(null));
+ }
+
+ @Test
+ public void testClear() {
+ JsonArray a = new JsonArray();
+ a.add(1);
+
+ List list = a.asList();
+ list.clear();
+ assertEquals(0, list.size());
+ assertEquals(0, a.size());
+ }
+
+ @Test
+ public void testContains() {
+ JsonArray a = new JsonArray();
+ a.add(1);
+
+ List list = a.asList();
+ assertTrue(list.contains(new JsonPrimitive(1)));
+ assertFalse(list.contains(new JsonPrimitive(2)));
+ assertFalse(list.contains(null));
+
+ @SuppressWarnings("unlikely-arg-type")
+ boolean containsInt = list.contains(1); // should only contain JsonPrimitive(1)
+ assertFalse(containsInt);
+ }
+
+ @Test
+ public void testIndexOf() {
+ JsonArray a = new JsonArray();
+ // Add the same value twice to test indexOf vs. lastIndexOf
+ a.add(1);
+ a.add(1);
+
+ List list = a.asList();
+ assertEquals(0, list.indexOf(new JsonPrimitive(1)));
+ assertEquals(-1, list.indexOf(new JsonPrimitive(2)));
+ assertEquals(-1, list.indexOf(null));
+
+ @SuppressWarnings("unlikely-arg-type")
+ int indexOfInt = list.indexOf(1); // should only contain JsonPrimitive(1)
+ assertEquals(-1, indexOfInt);
+
+ assertEquals(1, list.lastIndexOf(new JsonPrimitive(1)));
+ assertEquals(-1, list.lastIndexOf(new JsonPrimitive(2)));
+ assertEquals(-1, list.lastIndexOf(null));
+ }
+
+ @Test
+ public void testToArray() {
+ JsonArray a = new JsonArray();
+ a.add(1);
+
+ List list = a.asList();
+ assertArrayEquals(new Object[] {new JsonPrimitive(1)}, list.toArray());
+
+ JsonElement[] array = list.toArray(new JsonElement[0]);
+ assertArrayEquals(new Object[] {new JsonPrimitive(1)}, array);
+
+ array = new JsonElement[1];
+ assertSame(array, list.toArray(array));
+ assertArrayEquals(new Object[] {new JsonPrimitive(1)}, array);
+
+ array = new JsonElement[] {null, new JsonPrimitive(2)};
+ assertSame(array, list.toArray(array));
+ // Should have set existing array element to null
+ assertArrayEquals(new Object[] {new JsonPrimitive(1), null}, array);
+ }
+
+ @Test
+ public void testEqualsHashCode() {
+ JsonArray a = new JsonArray();
+ a.add(1);
+
+ List list = a.asList();
+ MoreAsserts.assertEqualsAndHashCode(list, Collections.singletonList(new JsonPrimitive(1)));
+ assertFalse(list.equals(Collections.emptyList()));
+ assertFalse(list.equals(Collections.singletonList(new JsonPrimitive(2))));
+ }
+
+ /** Verify that {@code JsonArray} updates are visible to view and vice versa */
+ @Test
+ public void testViewUpdates() {
+ JsonArray a = new JsonArray();
+ List list = a.asList();
+
+ a.add(1);
+ assertEquals(1, list.size());
+ assertEquals(new JsonPrimitive(1), list.get(0));
+
+ list.add(new JsonPrimitive(2));
+ assertEquals(2, a.size());
+ assertEquals(new JsonPrimitive(2), a.get(1));
+ }
+}
diff --git a/gson/src/test/java/com/google/gson/JsonArrayTest.java b/gson/src/test/java/com/google/gson/JsonArrayTest.java
index 70398460..45070e3f 100644
--- a/gson/src/test/java/com/google/gson/JsonArrayTest.java
+++ b/gson/src/test/java/com/google/gson/JsonArrayTest.java
@@ -16,18 +16,26 @@
package com.google.gson;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
import com.google.gson.common.MoreAsserts;
-import junit.framework.TestCase;
+import java.math.BigInteger;
+import org.junit.Test;
/**
* @author Jesse Wilson
*/
-public final class JsonArrayTest extends TestCase {
+public final class JsonArrayTest {
+ @Test
public void testEqualsOnEmptyArray() {
MoreAsserts.assertEqualsAndHashCode(new JsonArray(), new JsonArray());
}
+ @Test
public void testEqualsNonEmptyArray() {
JsonArray a = new JsonArray();
JsonArray b = new JsonArray();
@@ -50,6 +58,7 @@ public final class JsonArrayTest extends TestCase {
assertFalse(b.equals(a));
}
+ @Test
public void testRemove() {
JsonArray array = new JsonArray();
try {
@@ -67,6 +76,7 @@ public final class JsonArrayTest extends TestCase {
assertTrue(array.contains(a));
}
+ @Test
public void testSet() {
JsonArray array = new JsonArray();
try {
@@ -91,6 +101,7 @@ public final class JsonArrayTest extends TestCase {
assertEquals(1, array.size());
}
+ @Test
public void testDeepCopy() {
JsonArray original = new JsonArray();
JsonArray firstEntry = new JsonArray();
@@ -106,6 +117,7 @@ public final class JsonArrayTest extends TestCase {
assertEquals(0, copy.get(0).getAsJsonArray().size());
}
+ @Test
public void testIsEmpty() {
JsonArray array = new JsonArray();
assertTrue(array.isEmpty());
@@ -118,6 +130,7 @@ public final class JsonArrayTest extends TestCase {
assertTrue(array.isEmpty());
}
+ @Test
public void testFailedGetArrayValues() {
JsonArray jsonArray = new JsonArray();
jsonArray.add(JsonParser.parseString("{" + "\"key1\":\"value1\"," + "\"key2\":\"value2\"," + "\"key3\":\"value3\"," + "\"key4\":\"value4\"" + "}"));
@@ -182,6 +195,7 @@ public final class JsonArrayTest extends TestCase {
}
}
+ @Test
public void testGetAs_WrongArraySize() {
JsonArray jsonArray = new JsonArray();
try {
@@ -200,4 +214,160 @@ public final class JsonArrayTest extends TestCase {
assertEquals("Array must have size 1, but has size 2", e.getMessage());
}
}
+
+ @Test
+ public void testStringPrimitiveAddition() {
+ JsonArray jsonArray = new JsonArray();
+
+ jsonArray.add("Hello");
+ jsonArray.add("Goodbye");
+ jsonArray.add("Thank you");
+ jsonArray.add((String) null);
+ jsonArray.add("Yes");
+
+ assertEquals("[\"Hello\",\"Goodbye\",\"Thank you\",null,\"Yes\"]", jsonArray.toString());
+ }
+
+ @Test
+ public void testIntegerPrimitiveAddition() {
+ JsonArray jsonArray = new JsonArray();
+
+ int x = 1;
+ jsonArray.add(x);
+
+ x = 2;
+ jsonArray.add(x);
+
+ x = -3;
+ jsonArray.add(x);
+
+ jsonArray.add((Integer) null);
+
+ x = 4;
+ jsonArray.add(x);
+
+ x = 0;
+ jsonArray.add(x);
+
+ assertEquals("[1,2,-3,null,4,0]", jsonArray.toString());
+ }
+
+ @Test
+ public void testDoublePrimitiveAddition() {
+ JsonArray jsonArray = new JsonArray();
+
+ double x = 1.0;
+ jsonArray.add(x);
+
+ x = 2.13232;
+ jsonArray.add(x);
+
+ x = 0.121;
+ jsonArray.add(x);
+
+ jsonArray.add((Double) null);
+
+ x = -0.00234;
+ jsonArray.add(x);
+
+ jsonArray.add((Double) null);
+
+ assertEquals("[1.0,2.13232,0.121,null,-0.00234,null]", jsonArray.toString());
+ }
+
+ @Test
+ public void testBooleanPrimitiveAddition() {
+ JsonArray jsonArray = new JsonArray();
+
+ jsonArray.add(true);
+ jsonArray.add(true);
+ jsonArray.add(false);
+ jsonArray.add(false);
+ jsonArray.add((Boolean) null);
+ jsonArray.add(true);
+
+ assertEquals("[true,true,false,false,null,true]", jsonArray.toString());
+ }
+
+ @Test
+ public void testCharPrimitiveAddition() {
+ JsonArray jsonArray = new JsonArray();
+
+ jsonArray.add('a');
+ jsonArray.add('e');
+ jsonArray.add('i');
+ jsonArray.add((char) 111);
+ jsonArray.add((Character) null);
+ jsonArray.add('u');
+ jsonArray.add("and sometimes Y");
+
+ assertEquals("[\"a\",\"e\",\"i\",\"o\",null,\"u\",\"and sometimes Y\"]", jsonArray.toString());
+ }
+
+ @Test
+ public void testMixedPrimitiveAddition() {
+ JsonArray jsonArray = new JsonArray();
+
+ jsonArray.add('a');
+ jsonArray.add("apple");
+ jsonArray.add(12121);
+ jsonArray.add((char) 111);
+
+ jsonArray.add((Boolean) null);
+ assertEquals(JsonNull.INSTANCE, jsonArray.get(jsonArray.size() - 1));
+
+ jsonArray.add((Character) null);
+ assertEquals(JsonNull.INSTANCE, jsonArray.get(jsonArray.size() - 1));
+
+ jsonArray.add(12.232);
+ jsonArray.add(BigInteger.valueOf(2323));
+
+ assertEquals("[\"a\",\"apple\",12121,\"o\",null,null,12.232,2323]", jsonArray.toString());
+ }
+
+ @Test
+ public void testNullPrimitiveAddition() {
+ JsonArray jsonArray = new JsonArray();
+
+ jsonArray.add((Character) null);
+ jsonArray.add((Boolean) null);
+ jsonArray.add((Integer) null);
+ jsonArray.add((Double) null);
+ jsonArray.add((Float) null);
+ jsonArray.add((BigInteger) null);
+ jsonArray.add((String) null);
+ jsonArray.add((Boolean) null);
+ jsonArray.add((Number) null);
+
+ assertEquals("[null,null,null,null,null,null,null,null,null]", jsonArray.toString());
+ for (int i = 0; i < jsonArray.size(); i++) {
+ // Verify that they are actually a JsonNull and not a Java null
+ assertEquals(JsonNull.INSTANCE, jsonArray.get(i));
+ }
+ }
+
+ @Test
+ public void testNullJsonElementAddition() {
+ JsonArray jsonArray = new JsonArray();
+ jsonArray.add((JsonElement) null);
+ assertEquals(JsonNull.INSTANCE, jsonArray.get(0));
+ }
+
+ @Test
+ public void testSameAddition() {
+ JsonArray jsonArray = new JsonArray();
+
+ jsonArray.add('a');
+ jsonArray.add('a');
+ jsonArray.add(true);
+ jsonArray.add(true);
+ jsonArray.add(1212);
+ jsonArray.add(1212);
+ jsonArray.add(34.34);
+ jsonArray.add(34.34);
+ jsonArray.add((Boolean) null);
+ jsonArray.add((Boolean) null);
+
+ assertEquals("[\"a\",\"a\",true,true,1212,1212,34.34,34.34,null,null]", jsonArray.toString());
+ }
}
diff --git a/gson/src/test/java/com/google/gson/JsonObjectAsMapTest.java b/gson/src/test/java/com/google/gson/JsonObjectAsMapTest.java
new file mode 100644
index 00000000..7f175389
--- /dev/null
+++ b/gson/src/test/java/com/google/gson/JsonObjectAsMapTest.java
@@ -0,0 +1,287 @@
+package com.google.gson;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.google.gson.common.MoreAsserts;
+import java.util.AbstractMap.SimpleEntry;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import org.junit.Test;
+
+/**
+ * Tests for {@link JsonObject#asMap()}.
+ */
+public class JsonObjectAsMapTest {
+ @Test
+ public void testSize() {
+ JsonObject o = new JsonObject();
+ assertEquals(0, o.asMap().size());
+
+ o.addProperty("a", 1);
+ Map map = o.asMap();
+ assertEquals(1, map.size());
+
+ map.clear();
+ assertEquals(0, map.size());
+ assertEquals(0, o.size());
+ }
+
+ @Test
+ public void testContainsKey() {
+ JsonObject o = new JsonObject();
+ o.addProperty("a", 1);
+
+ Map map = o.asMap();
+ assertTrue(map.containsKey("a"));
+ assertFalse(map.containsKey("b"));
+ assertFalse(map.containsKey(null));
+ }
+
+ @Test
+ public void testContainsValue() {
+ JsonObject o = new JsonObject();
+ o.addProperty("a", 1);
+ o.add("b", JsonNull.INSTANCE);
+
+ Map map = o.asMap();
+ assertTrue(map.containsValue(new JsonPrimitive(1)));
+ assertFalse(map.containsValue(new JsonPrimitive(2)));
+ assertFalse(map.containsValue(null));
+
+ @SuppressWarnings("unlikely-arg-type")
+ boolean containsInt = map.containsValue(1); // should only contain JsonPrimitive(1)
+ assertFalse(containsInt);
+ }
+
+ @Test
+ public void testGet() {
+ JsonObject o = new JsonObject();
+ o.addProperty("a", 1);
+
+ Map map = o.asMap();
+ assertEquals(new JsonPrimitive(1), map.get("a"));
+ assertNull(map.get("b"));
+ assertNull(map.get(null));
+ }
+
+ @Test
+ public void testPut() {
+ JsonObject o = new JsonObject();
+ Map map = o.asMap();
+
+ assertNull(map.put("a", new JsonPrimitive(1)));
+ assertEquals(1, map.size());
+ assertEquals(new JsonPrimitive(1), map.get("a"));
+
+ JsonElement old = map.put("a", new JsonPrimitive(2));
+ assertEquals(new JsonPrimitive(1), old);
+ assertEquals(1, map.size());
+ assertEquals(new JsonPrimitive(2), map.get("a"));
+ assertEquals(new JsonPrimitive(2), o.get("a"));
+
+ assertNull(map.put("b", JsonNull.INSTANCE));
+ assertEquals(JsonNull.INSTANCE, map.get("b"));
+
+ try {
+ map.put(null, new JsonPrimitive(1));
+ fail();
+ } catch (NullPointerException e) {
+ assertEquals("key == null", e.getMessage());
+ }
+
+ try {
+ map.put("a", null);
+ fail();
+ } catch (NullPointerException e) {
+ assertEquals("value == null", e.getMessage());
+ }
+ }
+
+ @Test
+ public void testRemove() {
+ JsonObject o = new JsonObject();
+ o.addProperty("a", 1);
+
+ Map map = o.asMap();
+ assertNull(map.remove("b"));
+ assertEquals(1, map.size());
+
+ JsonElement old = map.remove("a");
+ assertEquals(new JsonPrimitive(1), old);
+ assertEquals(0, map.size());
+
+ assertNull(map.remove("a"));
+ assertEquals(0, map.size());
+ assertEquals(0, o.size());
+
+ assertNull(map.remove(null));
+ }
+
+ @Test
+ public void testPutAll() {
+ JsonObject o = new JsonObject();
+ o.addProperty("a", 1);
+
+ Map otherMap = new HashMap<>();
+ otherMap.put("a", new JsonPrimitive(2));
+ otherMap.put("b", new JsonPrimitive(3));
+
+ Map map = o.asMap();
+ map.putAll(otherMap);
+ assertEquals(2, map.size());
+ assertEquals(new JsonPrimitive(2), map.get("a"));
+ assertEquals(new JsonPrimitive(3), map.get("b"));
+
+ try {
+ map.putAll(Collections.singletonMap(null, new JsonPrimitive(1)));
+ fail();
+ } catch (NullPointerException e) {
+ assertEquals("key == null", e.getMessage());
+ }
+
+ try {
+ map.putAll(Collections.singletonMap("a", null));
+ fail();
+ } catch (NullPointerException e) {
+ assertEquals("value == null", e.getMessage());
+ }
+ }
+
+ @Test
+ public void testClear() {
+ JsonObject o = new JsonObject();
+ o.addProperty("a", 1);
+
+ Map map = o.asMap();
+ map.clear();
+ assertEquals(0, map.size());
+ assertEquals(0, o.size());
+ }
+
+ @Test
+ public void testKeySet() {
+ JsonObject o = new JsonObject();
+ o.addProperty("b", 1);
+ o.addProperty("a", 2);
+
+ Map map = o.asMap();
+ Set keySet = map.keySet();
+ // Should contain keys in same order
+ assertEquals(Arrays.asList("b", "a"), new ArrayList<>(keySet));
+
+ // Key set doesn't support insertions
+ try {
+ keySet.add("c");
+ fail();
+ } catch (UnsupportedOperationException e) {
+ }
+
+ assertTrue(keySet.remove("a"));
+ assertEquals(Collections.singleton("b"), map.keySet());
+ assertEquals(Collections.singleton("b"), o.keySet());
+ }
+
+ @Test
+ public void testValues() {
+ JsonObject o = new JsonObject();
+ o.addProperty("a", 2);
+ o.addProperty("b", 1);
+
+ Map map = o.asMap();
+ Collection values = map.values();
+ // Should contain values in same order
+ assertEquals(Arrays.asList(new JsonPrimitive(2), new JsonPrimitive(1)), new ArrayList<>(values));
+
+ // Values collection doesn't support insertions
+ try {
+ values.add(new JsonPrimitive(3));
+ fail();
+ } catch (UnsupportedOperationException e) {
+ }
+
+ assertTrue(values.remove(new JsonPrimitive(2)));
+ assertEquals(Collections.singletonList(new JsonPrimitive(1)), new ArrayList<>(map.values()));
+ assertEquals(1, o.size());
+ assertEquals(new JsonPrimitive(1), o.get("b"));
+ }
+
+ @Test
+ public void testEntrySet() {
+ JsonObject o = new JsonObject();
+ o.addProperty("b", 2);
+ o.addProperty("a", 1);
+
+ Map map = o.asMap();
+ Set> entrySet = map.entrySet();
+
+ List> expectedEntrySet = Arrays.>asList(
+ new SimpleEntry<>("b", new JsonPrimitive(2)),
+ new SimpleEntry<>("a", new JsonPrimitive(1))
+ );
+ // Should contain entries in same order
+ assertEquals(expectedEntrySet, new ArrayList<>(entrySet));
+
+ try {
+ entrySet.add(new SimpleEntry("c", new JsonPrimitive(3)));
+ fail();
+ } catch (UnsupportedOperationException e) {
+ }
+
+ assertTrue(entrySet.remove(new SimpleEntry<>("a", new JsonPrimitive(1))));
+ assertEquals(Collections.singleton(new SimpleEntry<>("b", new JsonPrimitive(2))), map.entrySet());
+ assertEquals(Collections.singleton(new SimpleEntry<>("b", new JsonPrimitive(2))), o.entrySet());
+
+ // Should return false because entry has already been removed
+ assertFalse(entrySet.remove(new SimpleEntry<>("a", new JsonPrimitive(1))));
+
+ Entry entry = entrySet.iterator().next();
+ JsonElement old = entry.setValue(new JsonPrimitive(3));
+ assertEquals(new JsonPrimitive(2), old);
+ assertEquals(Collections.singleton(new SimpleEntry<>("b", new JsonPrimitive(3))), map.entrySet());
+ assertEquals(Collections.singleton(new SimpleEntry<>("b", new JsonPrimitive(3))), o.entrySet());
+
+ try {
+ entry.setValue(null);
+ fail();
+ } catch (NullPointerException e) {
+ assertEquals("value == null", e.getMessage());
+ }
+ }
+
+ @Test
+ public void testEqualsHashCode() {
+ JsonObject o = new JsonObject();
+ o.addProperty("a", 1);
+
+ Map map = o.asMap();
+ MoreAsserts.assertEqualsAndHashCode(map, Collections.singletonMap("a", new JsonPrimitive(1)));
+ assertFalse(map.equals(Collections.emptyMap()));
+ assertFalse(map.equals(Collections.singletonMap("a", new JsonPrimitive(2))));
+ }
+
+ /** Verify that {@code JsonObject} updates are visible to view and vice versa */
+ @Test
+ public void testViewUpdates() {
+ JsonObject o = new JsonObject();
+ Map map = o.asMap();
+
+ o.addProperty("a", 1);
+ assertEquals(1, map.size());
+ assertEquals(new JsonPrimitive(1), map.get("a"));
+
+ map.put("b", new JsonPrimitive(2));
+ assertEquals(2, o.size());
+ assertEquals(new JsonPrimitive(2), o.get("b"));
+ }
+}
diff --git a/gson/src/test/java/com/google/gson/JsonObjectTest.java b/gson/src/test/java/com/google/gson/JsonObjectTest.java
index d12d12d8..a0109ba8 100644
--- a/gson/src/test/java/com/google/gson/JsonObjectTest.java
+++ b/gson/src/test/java/com/google/gson/JsonObjectTest.java
@@ -16,6 +16,13 @@
package com.google.gson;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
import com.google.gson.common.MoreAsserts;
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayDeque;
@@ -27,15 +34,16 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
-import junit.framework.TestCase;
+import org.junit.Test;
/**
* Unit test for the {@link JsonObject} class.
*
* @author Joel Leitch
*/
-public class JsonObjectTest extends TestCase {
+public class JsonObjectTest {
+ @Test
public void testAddingAndRemovingObjectProperties() throws Exception {
JsonObject jsonObj = new JsonObject();
String propertyName = "property";
@@ -54,6 +62,7 @@ public class JsonObjectTest extends TestCase {
assertNull(jsonObj.remove(propertyName));
}
+ @Test
public void testAddingNullPropertyValue() throws Exception {
String propertyName = "property";
JsonObject jsonObj = new JsonObject();
@@ -66,6 +75,7 @@ public class JsonObjectTest extends TestCase {
assertTrue(jsonElement.isJsonNull());
}
+ @Test
public void testAddingNullOrEmptyPropertyName() throws Exception {
JsonObject jsonObj = new JsonObject();
try {
@@ -77,6 +87,7 @@ public class JsonObjectTest extends TestCase {
jsonObj.add(" \t", JsonNull.INSTANCE);
}
+ @Test
public void testAddingBooleanProperties() throws Exception {
String propertyName = "property";
JsonObject jsonObj = new JsonObject();
@@ -89,6 +100,7 @@ public class JsonObjectTest extends TestCase {
assertTrue(jsonElement.getAsBoolean());
}
+ @Test
public void testAddingStringProperties() throws Exception {
String propertyName = "property";
String value = "blah";
@@ -103,6 +115,7 @@ public class JsonObjectTest extends TestCase {
assertEquals(value, jsonElement.getAsString());
}
+ @Test
public void testAddingCharacterProperties() throws Exception {
String propertyName = "property";
char value = 'a';
@@ -124,6 +137,7 @@ public class JsonObjectTest extends TestCase {
/**
* From bug report http://code.google.com/p/google-gson/issues/detail?id=182
*/
+ @Test
public void testPropertyWithQuotes() {
JsonObject jsonObj = new JsonObject();
jsonObj.add("a\"b", new JsonPrimitive("c\"d"));
@@ -134,6 +148,7 @@ public class JsonObjectTest extends TestCase {
/**
* From issue 227.
*/
+ @Test
public void testWritePropertyWithEmptyStringName() {
JsonObject jsonObj = new JsonObject();
jsonObj.add("", new JsonPrimitive(true));
@@ -141,15 +156,18 @@ public class JsonObjectTest extends TestCase {
}
+ @Test
public void testReadPropertyWithEmptyStringName() {
JsonObject jsonObj = JsonParser.parseString("{\"\":true}").getAsJsonObject();
assertEquals(true, jsonObj.get("").getAsBoolean());
}
+ @Test
public void testEqualsOnEmptyObject() {
MoreAsserts.assertEqualsAndHashCode(new JsonObject(), new JsonObject());
}
+ @Test
public void testEqualsNonEmptyObject() {
JsonObject a = new JsonObject();
JsonObject b = new JsonObject();
@@ -172,6 +190,7 @@ public class JsonObjectTest extends TestCase {
assertFalse(b.equals(a));
}
+ @Test
public void testEqualsHashCodeIgnoringOrder() {
JsonObject a = new JsonObject();
JsonObject b = new JsonObject();
@@ -188,6 +207,7 @@ public class JsonObjectTest extends TestCase {
MoreAsserts.assertEqualsAndHashCode(a, b);
}
+ @Test
public void testSize() {
JsonObject o = new JsonObject();
assertEquals(0, o.size());
@@ -202,6 +222,7 @@ public class JsonObjectTest extends TestCase {
assertEquals(1, o.size());
}
+ @Test
public void testDeepCopy() {
JsonObject original = new JsonObject();
JsonArray firstEntry = new JsonArray();
@@ -217,6 +238,7 @@ public class JsonObjectTest extends TestCase {
/**
* From issue 941
*/
+ @Test
public void testKeySet() {
JsonObject a = new JsonObject();
assertEquals(0, a.keySet().size());
@@ -250,6 +272,7 @@ public class JsonObjectTest extends TestCase {
}
}
+ @Test
public void testEntrySet() {
JsonObject o = new JsonObject();
assertEquals(0, o.entrySet().size());
diff --git a/gson/src/test/java/com/google/gson/functional/JsonArrayTest.java b/gson/src/test/java/com/google/gson/functional/JsonArrayTest.java
deleted file mode 100644
index 410a0817..00000000
--- a/gson/src/test/java/com/google/gson/functional/JsonArrayTest.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2008 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.gson.functional;
-
-import com.google.gson.JsonArray;
-import java.math.BigInteger;
-import junit.framework.TestCase;
-
-/**
- * Functional tests for adding primitives to a JsonArray.
- *
- * @author Dillon Dixon
- */
-public class JsonArrayTest extends TestCase {
-
- public void testStringPrimitiveAddition() {
- JsonArray jsonArray = new JsonArray();
-
- jsonArray.add("Hello");
- jsonArray.add("Goodbye");
- jsonArray.add("Thank you");
- jsonArray.add((String) null);
- jsonArray.add("Yes");
-
- assertEquals("[\"Hello\",\"Goodbye\",\"Thank you\",null,\"Yes\"]", jsonArray.toString());
- }
-
- public void testIntegerPrimitiveAddition() {
- JsonArray jsonArray = new JsonArray();
-
- int x = 1;
- jsonArray.add(x);
-
- x = 2;
- jsonArray.add(x);
-
- x = -3;
- jsonArray.add(x);
-
- jsonArray.add((Integer) null);
-
- x = 4;
- jsonArray.add(x);
-
- x = 0;
- jsonArray.add(x);
-
- assertEquals("[1,2,-3,null,4,0]", jsonArray.toString());
- }
-
- public void testDoublePrimitiveAddition() {
- JsonArray jsonArray = new JsonArray();
-
- double x = 1.0;
- jsonArray.add(x);
-
- x = 2.13232;
- jsonArray.add(x);
-
- x = 0.121;
- jsonArray.add(x);
-
- jsonArray.add((Double) null);
-
- x = -0.00234;
- jsonArray.add(x);
-
- jsonArray.add((Double) null);
-
- assertEquals("[1.0,2.13232,0.121,null,-0.00234,null]", jsonArray.toString());
- }
-
- public void testBooleanPrimitiveAddition() {
- JsonArray jsonArray = new JsonArray();
-
- jsonArray.add(true);
- jsonArray.add(true);
- jsonArray.add(false);
- jsonArray.add(false);
- jsonArray.add((Boolean) null);
- jsonArray.add(true);
-
- assertEquals("[true,true,false,false,null,true]", jsonArray.toString());
- }
-
- public void testCharPrimitiveAddition() {
- JsonArray jsonArray = new JsonArray();
-
- jsonArray.add('a');
- jsonArray.add('e');
- jsonArray.add('i');
- jsonArray.add((char) 111);
- jsonArray.add((Character) null);
- jsonArray.add('u');
- jsonArray.add("and sometimes Y");
-
- assertEquals("[\"a\",\"e\",\"i\",\"o\",null,\"u\",\"and sometimes Y\"]", jsonArray.toString());
- }
-
- public void testMixedPrimitiveAddition() {
- JsonArray jsonArray = new JsonArray();
-
- jsonArray.add('a');
- jsonArray.add("apple");
- jsonArray.add(12121);
- jsonArray.add((char) 111);
- jsonArray.add((Boolean) null);
- jsonArray.add((Character) null);
- jsonArray.add(12.232);
- jsonArray.add(BigInteger.valueOf(2323));
-
- assertEquals("[\"a\",\"apple\",12121,\"o\",null,null,12.232,2323]", jsonArray.toString());
- }
-
- public void testNullPrimitiveAddition() {
- JsonArray jsonArray = new JsonArray();
-
- jsonArray.add((Character) null);
- jsonArray.add((Boolean) null);
- jsonArray.add((Integer) null);
- jsonArray.add((Double) null);
- jsonArray.add((Float) null);
- jsonArray.add((BigInteger) null);
- jsonArray.add((String) null);
- jsonArray.add((Boolean) null);
- jsonArray.add((Number) null);
-
- assertEquals("[null,null,null,null,null,null,null,null,null]", jsonArray.toString());
- }
-
- public void testSameAddition() {
- JsonArray jsonArray = new JsonArray();
-
- jsonArray.add('a');
- jsonArray.add('a');
- jsonArray.add(true);
- jsonArray.add(true);
- jsonArray.add(1212);
- jsonArray.add(1212);
- jsonArray.add(34.34);
- jsonArray.add(34.34);
- jsonArray.add((Boolean) null);
- jsonArray.add((Boolean) null);
-
- assertEquals("[\"a\",\"a\",true,true,1212,1212,34.34,34.34,null,null]", jsonArray.toString());
- }
-}