Add JsonArray.asList and JsonObject.asMap view methods (#2225)

* Add `JsonArray.asList` and `JsonObject.asMap` view methods

* Address review comments
This commit is contained in:
Marcono1234 2022-10-16 21:30:49 +02:00 committed by GitHub
parent c2458bf876
commit 954d526af4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 904 additions and 166 deletions

View File

@ -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}.
*
* <p>{@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<JsonElement> {
private final List<JsonElement> elements;
private final ArrayList<JsonElement> elements;
/**
* Creates an empty JsonArray.
@ -393,6 +397,20 @@ public final class JsonArray extends JsonElement implements Iterable<JsonElement
return getAsSingleElement().getAsBoolean();
}
/**
* Returns a mutable {@link List} view of this {@code JsonArray}. Changes to the {@code List}
* are visible in this {@code JsonArray} and the other way around.
*
* <p>The {@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<JsonElement> 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

View File

@ -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}.
*
* <p>{@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.
*
* <p>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<String, JsonElement> 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

View File

@ -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<E> extends AbstractList<E> implements RandomAccess {
// Explicitly specify ArrayList as type to guarantee that delegate implements RandomAccess
private final ArrayList<E> delegate;
public NonNullElementWrapperList(ArrayList<E> 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> 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
}

View File

@ -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<JsonElement> 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<JsonElement> 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<JsonElement> 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<JsonElement> 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<JsonElement> expectedList = Arrays.<JsonElement>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<JsonElement> list = a.asList();
list.addAll(Arrays.asList(new JsonPrimitive(2), new JsonPrimitive(3)));
List<JsonElement> expectedList = Arrays.<JsonElement>asList(
new JsonPrimitive(1),
new JsonPrimitive(2),
new JsonPrimitive(3)
);
assertEquals(expectedList, list);
try {
list.addAll(0, Collections.<JsonElement>singletonList(null));
fail();
} catch (NullPointerException e) {
assertEquals("Element must be non-null", e.getMessage());
}
try {
list.addAll(Collections.<JsonElement>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<JsonElement> 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<JsonElement> 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<JsonElement> 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<JsonElement> 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<JsonElement> 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<JsonElement> 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<JsonElement> 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<JsonElement> 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));
}
}

View File

@ -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());
}
}

View File

@ -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<String, JsonElement> 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<String, JsonElement> 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<String, JsonElement> 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<String, JsonElement> 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<String, JsonElement> 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<String, JsonElement> 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<String, JsonElement> otherMap = new HashMap<>();
otherMap.put("a", new JsonPrimitive(2));
otherMap.put("b", new JsonPrimitive(3));
Map<String, JsonElement> 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.<String, JsonElement>singletonMap(null, new JsonPrimitive(1)));
fail();
} catch (NullPointerException e) {
assertEquals("key == null", e.getMessage());
}
try {
map.putAll(Collections.<String, JsonElement>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<String, JsonElement> 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<String, JsonElement> map = o.asMap();
Set<String> 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<String, JsonElement> map = o.asMap();
Collection<JsonElement> 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<String, JsonElement> map = o.asMap();
Set<Entry<String, JsonElement>> entrySet = map.entrySet();
List<Entry<?, ?>> expectedEntrySet = Arrays.<Entry<?, ?>>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<String, JsonElement>("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<String, JsonElement> 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<String, JsonElement> 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<String, JsonElement> 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"));
}
}

View File

@ -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());

View File

@ -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());
}
}