Verify that JsonTreeReader and JsonTreeWriter override all methods (#2181)
* Verify that JsonTreeReader and JsonTreeWriter override all methods If those classes do not override one of the JsonReader or JsonWriter methods the user might encounter an AssertionError. * Address review feedback
This commit is contained in:
parent
7f77ad4ff6
commit
325f37cd6b
@ -16,9 +16,13 @@
|
||||
|
||||
package com.google.gson.common;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.junit.Assert;
|
||||
|
||||
/**
|
||||
* Handy asserts that we wish were present in {@link Assert}
|
||||
@ -49,4 +53,53 @@ public class MoreAsserts {
|
||||
Assert.assertFalse(a.equals(null));
|
||||
Assert.assertFalse(a.equals(new Object()));
|
||||
}
|
||||
|
||||
private static boolean isProtectedOrPublic(Method method) {
|
||||
int modifiers = method.getModifiers();
|
||||
return Modifier.isProtected(modifiers) || Modifier.isPublic(modifiers);
|
||||
}
|
||||
|
||||
private static String getMethodSignature(Method method) {
|
||||
StringBuilder builder = new StringBuilder(method.getName());
|
||||
builder.append('(');
|
||||
|
||||
String sep = "";
|
||||
for (Class<?> paramType : method.getParameterTypes()) {
|
||||
builder.append(sep).append(paramType.getName());
|
||||
sep = ",";
|
||||
}
|
||||
|
||||
builder.append(')');
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that {@code subClass} overrides all protected and public methods declared by
|
||||
* {@code baseClass} except for the ones whose signatures are in {@code ignoredMethods}.
|
||||
*/
|
||||
public static void assertOverridesMethods(Class<?> baseClass, Class<?> subClass, List<String> ignoredMethods) {
|
||||
Set<String> requiredOverriddenMethods = new LinkedHashSet<>();
|
||||
for (Method method : baseClass.getDeclaredMethods()) {
|
||||
// Note: Do not filter out `final` methods; maybe they should not be `final` and subclass needs
|
||||
// to override them
|
||||
if (isProtectedOrPublic(method)) {
|
||||
requiredOverriddenMethods.add(getMethodSignature(method));
|
||||
}
|
||||
}
|
||||
|
||||
for (Method method : subClass.getDeclaredMethods()) {
|
||||
requiredOverriddenMethods.remove(getMethodSignature(method));
|
||||
}
|
||||
|
||||
for (String ignoredMethod : ignoredMethods) {
|
||||
boolean foundIgnored = requiredOverriddenMethods.remove(ignoredMethod);
|
||||
if (!foundIgnored) {
|
||||
throw new IllegalArgumentException("Method '" + ignoredMethod + "' does not exist or is already overridden");
|
||||
}
|
||||
}
|
||||
|
||||
if (!requiredOverriddenMethods.isEmpty()) {
|
||||
Assert.fail(subClass.getSimpleName() + " must override these methods: " + requiredOverriddenMethods);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,9 +19,14 @@ import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.common.MoreAsserts;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.MalformedJsonException;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
@ -80,4 +85,14 @@ public class JsonTreeReaderTest extends TestCase {
|
||||
expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link JsonTreeReader} effectively replaces the complete reading logic of {@link JsonReader} to
|
||||
* read from a {@link JsonElement} instead of a {@link Reader}. Therefore all relevant methods of
|
||||
* {@code JsonReader} must be overridden.
|
||||
*/
|
||||
public void testOverrides() {
|
||||
List<String> ignoredMethods = Arrays.asList("setLenient(boolean)", "isLenient()");
|
||||
MoreAsserts.assertOverridesMethods(JsonReader.class, JsonTreeReader.class, ignoredMethods);
|
||||
}
|
||||
}
|
||||
|
@ -16,8 +16,14 @@
|
||||
|
||||
package com.google.gson.internal.bind;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.common.MoreAsserts;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
@ -243,4 +249,15 @@ public final class JsonTreeWriterTest extends TestCase {
|
||||
} catch (UnsupportedOperationException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link JsonTreeWriter} effectively replaces the complete writing logic of {@link JsonWriter} to
|
||||
* create a {@link JsonElement} tree instead of writing to a {@link Writer}. Therefore all relevant
|
||||
* methods of {@code JsonWriter} must be overridden.
|
||||
*/
|
||||
public void testOverrides() {
|
||||
List<String> ignoredMethods = Arrays.asList("setLenient(boolean)", "isLenient()", "setIndent(java.lang.String)",
|
||||
"setHtmlSafe(boolean)", "isHtmlSafe()", "setSerializeNulls(boolean)", "getSerializeNulls()");
|
||||
MoreAsserts.assertOverridesMethods(JsonWriter.class, JsonTreeWriter.class, ignoredMethods);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user