Validating JsonObject Map Interface Implementation in google/gson
This test suite validates the Map interface implementation for JsonObject in the GSON library, ensuring proper JSON object to Map conversion and manipulation capabilities.
Test Coverage Overview
Implementation Analysis
Technical Details
Best Practices Demonstrated
google/gson
gson/src/test/java/com/google/gson/JsonObjectAsMapTest.java
/*
* Copyright (C) 2022 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;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;
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();
assertThat(o.asMap().size()).isEqualTo(0);
o.addProperty("a", 1);
Map<String, JsonElement> map = o.asMap();
assertThat(map).hasSize(1);
map.clear();
assertThat(map).hasSize(0);
assertThat(o.size()).isEqualTo(0);
}
@Test
public void testContainsKey() {
JsonObject o = new JsonObject();
o.addProperty("a", 1);
Map<String, JsonElement> map = o.asMap();
assertThat(map.containsKey("a")).isTrue();
assertThat(map.containsKey("b")).isFalse();
assertThat(map.containsKey(null)).isFalse();
}
@Test
public void testContainsValue() {
JsonObject o = new JsonObject();
o.addProperty("a", 1);
o.add("b", JsonNull.INSTANCE);
Map<String, JsonElement> map = o.asMap();
assertThat(map.containsValue(new JsonPrimitive(1))).isTrue();
assertThat(map.containsValue(new JsonPrimitive(2))).isFalse();
assertThat(map.containsValue(null)).isFalse();
@SuppressWarnings({"unlikely-arg-type", "CollectionIncompatibleType"})
boolean containsInt = map.containsValue(1); // should only contain JsonPrimitive(1)
assertThat(containsInt).isFalse();
}
@Test
public void testGet() {
JsonObject o = new JsonObject();
o.addProperty("a", 1);
Map<String, JsonElement> map = o.asMap();
assertThat(map.get("a")).isEqualTo(new JsonPrimitive(1));
assertThat(map.get("b")).isNull();
assertThat(map.get(null)).isNull();
}
@Test
public void testPut() {
JsonObject o = new JsonObject();
Map<String, JsonElement> map = o.asMap();
assertThat(map.put("a", new JsonPrimitive(1))).isNull();
assertThat(map.get("a")).isEqualTo(new JsonPrimitive(1));
JsonElement old = map.put("a", new JsonPrimitive(2));
assertThat(old).isEqualTo(new JsonPrimitive(1));
assertThat(map).hasSize(1);
assertThat(map.get("a")).isEqualTo(new JsonPrimitive(2));
assertThat(o.get("a")).isEqualTo(new JsonPrimitive(2));
assertThat(map.put("b", JsonNull.INSTANCE)).isNull();
assertThat(map.get("b")).isEqualTo(JsonNull.INSTANCE);
var e = assertThrows(NullPointerException.class, () -> map.put(null, new JsonPrimitive(1)));
assertThat(e).hasMessageThat().isEqualTo("key == null");
e = assertThrows(NullPointerException.class, () -> map.put("a", null));
assertThat(e).hasMessageThat().isEqualTo("value == null");
}
@Test
public void testRemove() {
JsonObject o = new JsonObject();
o.addProperty("a", 1);
Map<String, JsonElement> map = o.asMap();
assertThat(map.remove("b")).isNull();
assertThat(map).hasSize(1);
JsonElement old = map.remove("a");
assertThat(old).isEqualTo(new JsonPrimitive(1));
assertThat(map).hasSize(0);
assertThat(map.remove("a")).isNull();
assertThat(map).hasSize(0);
assertThat(o.size()).isEqualTo(0);
assertThat(map.remove(null)).isNull();
}
@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);
assertThat(map).hasSize(2);
assertThat(map.get("a")).isEqualTo(new JsonPrimitive(2));
assertThat(map.get("b")).isEqualTo(new JsonPrimitive(3));
var e =
assertThrows(
NullPointerException.class,
() -> map.putAll(Collections.singletonMap(null, new JsonPrimitive(1))));
assertThat(e).hasMessageThat().isEqualTo("key == null");
e =
assertThrows(
NullPointerException.class, () -> map.putAll(Collections.singletonMap("a", null)));
assertThat(e).hasMessageThat().isEqualTo("value == null");
}
@Test
public void testClear() {
JsonObject o = new JsonObject();
o.addProperty("a", 1);
Map<String, JsonElement> map = o.asMap();
map.clear();
assertThat(map).hasSize(0);
assertThat(o.size()).isEqualTo(0);
}
@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
assertThat(keySet).containsExactly("b", "a").inOrder();
// Key set doesn't support insertions
assertThrows(UnsupportedOperationException.class, () -> keySet.add("c"));
assertThat(keySet.remove("a")).isTrue();
assertThat(map.keySet()).isEqualTo(Collections.singleton("b"));
assertThat(o.keySet()).isEqualTo(Collections.singleton("b"));
}
@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
assertThat(values).containsExactly(new JsonPrimitive(2), new JsonPrimitive(1)).inOrder();
// Values collection doesn't support insertions
assertThrows(UnsupportedOperationException.class, () -> values.add(new JsonPrimitive(3)));
assertThat(values.remove(new JsonPrimitive(2))).isTrue();
assertThat(new ArrayList<>(map.values()))
.isEqualTo(Collections.singletonList(new JsonPrimitive(1)));
assertThat(o.size()).isEqualTo(1);
assertThat(o.get("b")).isEqualTo(new JsonPrimitive(1));
}
@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.asList(
new SimpleEntry<>("b", new JsonPrimitive(2)),
new SimpleEntry<>("a", new JsonPrimitive(1)));
// Should contain entries in same order
assertThat(new ArrayList<>(entrySet)).isEqualTo(expectedEntrySet);
// Entry set doesn't support insertions
assertThrows(
UnsupportedOperationException.class,
() -> entrySet.add(new SimpleEntry<>("c", new JsonPrimitive(3))));
assertThat(entrySet.remove(new SimpleEntry<>("a", new JsonPrimitive(1)))).isTrue();
assertThat(map.entrySet())
.isEqualTo(Collections.singleton(new SimpleEntry<>("b", new JsonPrimitive(2))));
assertThat(o.entrySet())
.isEqualTo(Collections.singleton(new SimpleEntry<>("b", new JsonPrimitive(2))));
// Should return false because entry has already been removed
assertThat(entrySet.remove(new SimpleEntry<>("a", new JsonPrimitive(1)))).isFalse();
Entry<String, JsonElement> entry = entrySet.iterator().next();
JsonElement old = entry.setValue(new JsonPrimitive(3));
assertThat(old).isEqualTo(new JsonPrimitive(2));
assertThat(map.entrySet())
.isEqualTo(Collections.singleton(new SimpleEntry<>("b", new JsonPrimitive(3))));
assertThat(o.entrySet())
.isEqualTo(Collections.singleton(new SimpleEntry<>("b", new JsonPrimitive(3))));
var e = assertThrows(NullPointerException.class, () -> entry.setValue(null));
assertThat(e).hasMessageThat().isEqualTo("value == null");
}
@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)));
assertThat(map.equals(Collections.emptyMap())).isFalse();
assertThat(map.equals(Collections.singletonMap("a", new JsonPrimitive(2)))).isFalse();
}
/** 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);
assertThat(map).hasSize(1);
assertThat(map.get("a")).isEqualTo(new JsonPrimitive(1));
map.put("b", new JsonPrimitive(2));
assertThat(o.size()).isEqualTo(2);
assertThat(map.get("b")).isEqualTo(new JsonPrimitive(2));
}
}