Skip to content

Commit

Permalink
Use Guava testlib for collection tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Marcono1234 committed Sep 23, 2024
1 parent 58eaac3 commit 27b509f
Show file tree
Hide file tree
Showing 3 changed files with 238 additions and 0 deletions.
68 changes: 68 additions & 0 deletions gson/src/test/java/com/google/gson/JsonArrayAsListSuiteTest.java
Original file line number Diff line number Diff line change
@@ -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<JsonElement> {
@Override
public SampleElements<JsonElement> samples() {
return new SampleElements<JsonElement>(
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<JsonElement> order(List<JsonElement> insertionOrder) {
return insertionOrder;
}

@Override
public List<JsonElement> 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();
}
}
87 changes: 87 additions & 0 deletions gson/src/test/java/com/google/gson/JsonObjectAsMapSuiteTest.java
Original file line number Diff line number Diff line change
@@ -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<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();
for (Object element : elements) {
@SuppressWarnings("unchecked")
var entry = (Entry<String, JsonElement>) element;
object.add(entry.getKey(), entry.getValue());
}
return object.asMap();
}

@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,
// 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();
}
}
Original file line number Diff line number Diff line change
@@ -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<String, String> create(Entry<String, String>[] entries) {
var map = new LinkedTreeMap<String, String>(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<Feature<?>>(
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;
}
}

0 comments on commit 27b509f

Please sign in to comment.