From 27b509f0e0de0d5dc37ddbef0a1962ac535b3800 Mon Sep 17 00:00:00 2001 From: Marcono1234 Date: Mon, 23 Sep 2024 23:38:01 +0200 Subject: [PATCH] Use Guava testlib for collection tests --- .../google/gson/JsonArrayAsListSuiteTest.java | 68 +++++++++++++++ .../google/gson/JsonObjectAsMapSuiteTest.java | 87 +++++++++++++++++++ .../gson/internal/LinkedTreeMapSuiteTest.java | 83 ++++++++++++++++++ 3 files changed, 238 insertions(+) create mode 100644 gson/src/test/java/com/google/gson/JsonArrayAsListSuiteTest.java create mode 100644 gson/src/test/java/com/google/gson/JsonObjectAsMapSuiteTest.java create mode 100644 gson/src/test/java/com/google/gson/internal/LinkedTreeMapSuiteTest.java diff --git a/gson/src/test/java/com/google/gson/JsonArrayAsListSuiteTest.java b/gson/src/test/java/com/google/gson/JsonArrayAsListSuiteTest.java new file mode 100644 index 0000000000..baca3846b9 --- /dev/null +++ b/gson/src/test/java/com/google/gson/JsonArrayAsListSuiteTest.java @@ -0,0 +1,68 @@ +package com.google.gson; + +import com.google.common.collect.testing.ListTestSuiteBuilder; +import com.google.common.collect.testing.SampleElements; +import com.google.common.collect.testing.TestListGenerator; +import com.google.common.collect.testing.features.CollectionFeature; +import com.google.common.collect.testing.features.CollectionSize; +import com.google.common.collect.testing.features.ListFeature; +import java.util.List; +import junit.framework.Test; +import org.junit.runner.RunWith; +import org.junit.runners.AllTests; + +/** + * Dynamic {@link ListTestSuiteBuilder List test suite} for {@link JsonArray#asList()}. This + * complements {@link JsonArrayAsListTest}, which can cover some cases which are not covered here, + * e.g. making sure changes in the {@code List} view are visible in the {@code JsonArray}. + */ +@RunWith(AllTests.class) +public class JsonArrayAsListSuiteTest { + private static class ListGenerator implements TestListGenerator { + @Override + public SampleElements samples() { + return new SampleElements( + JsonNull.INSTANCE, + new JsonPrimitive(true), + new JsonPrimitive("test"), + new JsonArray(), + new JsonObject()); + } + + @Override + public JsonElement[] createArray(int length) { + return new JsonElement[length]; + } + + @Override + public Iterable order(List insertionOrder) { + return insertionOrder; + } + + @Override + public List create(Object... elements) { + JsonArray array = new JsonArray(); + for (Object element : elements) { + array.add((JsonElement) element); + } + return array.asList(); + } + } + + // Special method recognized by JUnit's `AllTests` runner + public static Test suite() { + return ListTestSuiteBuilder.using(new ListGenerator()) + .withFeatures( + CollectionSize.ANY, + // Note: There is current a Guava bug which causes 'null additions' to not be tested if + // 'null queries' is enabled, see https://github.com/google/guava/issues/7401 + CollectionFeature.ALLOWS_NULL_QUERIES, + CollectionFeature.RESTRICTS_ELEMENTS, // List only allows JsonElement + CollectionFeature.SUPPORTS_ADD, + ListFeature.REMOVE_OPERATIONS, + ListFeature.SUPPORTS_ADD_WITH_INDEX, + ListFeature.SUPPORTS_SET) + .named("JsonArray#asList") + .createTestSuite(); + } +} diff --git a/gson/src/test/java/com/google/gson/JsonObjectAsMapSuiteTest.java b/gson/src/test/java/com/google/gson/JsonObjectAsMapSuiteTest.java new file mode 100644 index 0000000000..bbaa6cb74b --- /dev/null +++ b/gson/src/test/java/com/google/gson/JsonObjectAsMapSuiteTest.java @@ -0,0 +1,87 @@ +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 { + @Override + public SampleElements> 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 create(Object... elements) { + JsonObject object = new JsonObject(); + for (Object element : elements) { + @SuppressWarnings("unchecked") + var entry = (Entry) element; + object.add(entry.getKey(), entry.getValue()); + } + return object.asMap(); + } + + @SuppressWarnings("unchecked") + @Override + public Entry[] createArray(int length) { + return (Entry[]) new Entry[length]; + } + + @Override + public Iterable> order( + List> 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, + // Note: There is current a Guava bug which causes 'null additions' to not be tested if + // 'null queries' is enabled, see https://github.com/google/guava/issues/7401 + 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(); + } +} diff --git a/gson/src/test/java/com/google/gson/internal/LinkedTreeMapSuiteTest.java b/gson/src/test/java/com/google/gson/internal/LinkedTreeMapSuiteTest.java new file mode 100644 index 0000000000..d81812fb1d --- /dev/null +++ b/gson/src/test/java/com/google/gson/internal/LinkedTreeMapSuiteTest.java @@ -0,0 +1,83 @@ +package com.google.gson.internal; + +import com.google.common.collect.testing.MapTestSuiteBuilder; +import com.google.common.collect.testing.TestStringMapGenerator; +import com.google.common.collect.testing.features.CollectionFeature; +import com.google.common.collect.testing.features.CollectionSize; +import com.google.common.collect.testing.features.Feature; +import com.google.common.collect.testing.features.MapFeature; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import junit.framework.Test; +import junit.framework.TestSuite; +import org.junit.runner.RunWith; +import org.junit.runners.AllTests; + +/** + * Dynamic {@link MapTestSuiteBuilder Map test suite} for {@link LinkedTreeMap}. This complements + * {@link LinkedTreeMapTest}. + */ +@RunWith(AllTests.class) +public class LinkedTreeMapSuiteTest { + private static class MapGenerator extends TestStringMapGenerator { + private final boolean allowNullValues; + + public MapGenerator(boolean allowNullValues) { + this.allowNullValues = allowNullValues; + } + + @Override + protected Map create(Entry[] entries) { + var map = new LinkedTreeMap(allowNullValues); + for (var entry : entries) { + map.put(entry.getKey(), entry.getValue()); + } + return map; + } + } + + private static Feature[] createFeatures(Feature... additionalFeatures) { + // Don't specify CollectionFeature.SERIALIZABLE because Guava testlib seems to assume + // deserialized Map has same properties as original map (e.g. disallowing null keys), but this + // is not the case for LinkedTreeMap which is serialized as JDK LinkedHashMap + var features = + new ArrayList>( + List.of( + CollectionSize.ANY, + // Note: There is current a Guava bug which causes 'null additions' to not be tested + // if 'null queries' is enabled, see https://github.com/google/guava/issues/7401 + MapFeature.ALLOWS_ANY_NULL_QUERIES, + MapFeature.RESTRICTS_KEYS, // Map only allows comparable keys + MapFeature.SUPPORTS_PUT, + MapFeature.SUPPORTS_REMOVE, + // Affects keySet, values and entrySet (?) + CollectionFeature.KNOWN_ORDER, // Map preserves insertion order + CollectionFeature.SUPPORTS_ITERATOR_REMOVE)); + features.addAll(Arrays.asList(additionalFeatures)); + return features.toArray(Feature[]::new); + } + + // Special method recognized by JUnit's `AllTests` runner + public static Test suite() { + var nullValuesSuite = + MapTestSuiteBuilder.using(new MapGenerator(true)) + .withFeatures(createFeatures(MapFeature.ALLOWS_NULL_VALUES)) + .named("nullValues=true") + .createTestSuite(); + + var nonNullValuesSuite = + MapTestSuiteBuilder.using(new MapGenerator(false)) + .withFeatures(createFeatures()) + .named("nullValues=false") + .createTestSuite(); + + TestSuite testSuite = new TestSuite("LinkedTreeMap"); + testSuite.addTest(nullValuesSuite); + testSuite.addTest(nonNullValuesSuite); + + return testSuite; + } +}