Validating JsonObject Map Interface Compliance in Google Gson
This test suite implements comprehensive Map interface validation for JsonObject’s asMap() functionality in the Gson library. It utilizes Google’s collection testing framework to verify map operations and behavior compliance.
Test Coverage Overview
Implementation Analysis
Technical Details
Best Practices Demonstrated
google/gson
gson/src/test/java/com/google/gson/JsonObjectAsMapSuiteTest.java
package com.google.gson;
import com.google.common.collect.testing.MapTestSuiteBuilder;
import com.google.common.collect.testing.SampleElements;
import com.google.common.collect.testing.TestMapGenerator;
import com.google.common.collect.testing.features.CollectionFeature;
import com.google.common.collect.testing.features.CollectionSize;
import com.google.common.collect.testing.features.MapFeature;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import junit.framework.Test;
import org.junit.runner.RunWith;
import org.junit.runners.AllTests;
/**
* Dynamic {@link MapTestSuiteBuilder Map test suite} for {@link JsonObject#asMap()}. This
* complements {@link JsonObjectAsMapTest}, which can cover some cases which are not covered here,
* e.g. making sure changes in the {@code Map} view are visible in the {@code JsonObject}.
*/
@RunWith(AllTests.class)
public class JsonObjectAsMapSuiteTest {
private static class MapGenerator implements TestMapGenerator<String, JsonElement> {
@Override
public SampleElements<Entry<String, JsonElement>> samples() {
return new SampleElements<>(
Map.entry("one", JsonNull.INSTANCE),
Map.entry("two", new JsonPrimitive(true)),
Map.entry("three", new JsonPrimitive("test")),
Map.entry("four", new JsonArray()),
Map.entry("five", new JsonObject()));
}
@Override
public Map<String, JsonElement> create(Object... elements) {
JsonObject object = new JsonObject();
// This is not completely accurate: Because there is no way to directly construct JsonObject
// or its Map view with existing entries, this has to add the entries individually with
// `Map#put`
var map = object.asMap();
for (Object element : elements) {
var entry = (Entry<?, ?>) element;
map.put((String) entry.getKey(), (JsonElement) entry.getValue());
}
return map;
}
@SuppressWarnings("unchecked")
@Override
public Entry<String, JsonElement>[] createArray(int length) {
return (Entry<String, JsonElement>[]) new Entry<?, ?>[length];
}
@Override
public Iterable<Entry<String, JsonElement>> order(
List<Entry<String, JsonElement>> insertionOrder) {
// Preserves insertion order
return insertionOrder;
}
@Override
public String[] createKeyArray(int length) {
return new String[length];
}
@Override
public JsonElement[] createValueArray(int length) {
return new JsonElement[length];
}
}
// Special method recognized by JUnit's `AllTests` runner
public static Test suite() {
return MapTestSuiteBuilder.using(new MapGenerator())
.withFeatures(
CollectionSize.ANY,
MapFeature.ALLOWS_ANY_NULL_QUERIES,
MapFeature.RESTRICTS_KEYS, // Map only allows String keys
MapFeature.RESTRICTS_VALUES, // Map only allows JsonElement values
MapFeature.SUPPORTS_PUT,
MapFeature.SUPPORTS_REMOVE,
// Affects keySet, values and entrySet (?)
CollectionFeature.KNOWN_ORDER, // Map preserves insertion order
CollectionFeature.SUPPORTS_ITERATOR_REMOVE)
.named("JsonObject#asMap")
.createTestSuite();
}
}