gson-comments/gson/src/test/java/com/google/gson/functional/CustomDeserializerTest.java

192 lines
6.1 KiB
Java

/*
* Copyright (C) 2008 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.functional;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.common.TestTypes.Base;
import com.google.gson.common.TestTypes.ClassWithBaseField;
import junit.framework.TestCase;
import java.lang.reflect.Type;
/**
* Functional Test exercising custom deserialization only. When test applies to both
* serialization and deserialization then add it to CustomTypeAdapterTest.
*
* @author Joel Leitch
*/
public class CustomDeserializerTest extends TestCase {
private static final String DEFAULT_VALUE = "test123";
private static final String SUFFIX = "blah";
private Gson gson;
@Override
protected void setUp() throws Exception {
super.setUp();
gson = new GsonBuilder().registerTypeAdapter(DataHolder.class, new DataHolderDeserializer()).create();
}
public void testDefaultConstructorNotCalledOnObject() throws Exception {
DataHolder data = new DataHolder(DEFAULT_VALUE);
String json = gson.toJson(data);
DataHolder actual = gson.fromJson(json, DataHolder.class);
assertEquals(DEFAULT_VALUE + SUFFIX, actual.getData());
}
public void testDefaultConstructorNotCalledOnField() throws Exception {
DataHolderWrapper dataWrapper = new DataHolderWrapper(new DataHolder(DEFAULT_VALUE));
String json = gson.toJson(dataWrapper);
DataHolderWrapper actual = gson.fromJson(json, DataHolderWrapper.class);
assertEquals(DEFAULT_VALUE + SUFFIX, actual.getWrappedData().getData());
}
private static class DataHolder {
private final String data;
// For use by Gson
@SuppressWarnings("unused")
private DataHolder() {
throw new IllegalStateException();
}
public DataHolder(String data) {
this.data = data;
}
public String getData() {
return data;
}
}
private static class DataHolderWrapper {
private final DataHolder wrappedData;
// For use by Gson
@SuppressWarnings("unused")
private DataHolderWrapper() {
this(new DataHolder(DEFAULT_VALUE));
}
public DataHolderWrapper(DataHolder data) {
this.wrappedData = data;
}
public DataHolder getWrappedData() {
return wrappedData;
}
}
private static class DataHolderDeserializer implements JsonDeserializer<DataHolder> {
@Override
public DataHolder deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
JsonObject jsonObj = json.getAsJsonObject();
String dataString = jsonObj.get("data").getAsString();
return new DataHolder(dataString + SUFFIX);
}
}
public void testJsonTypeFieldBasedDeserialization() {
String json = "{field1:'abc',field2:'def',__type__:'SUB_TYPE1'}";
Gson gson = new GsonBuilder()
.setLenient()
.registerTypeAdapter(MyBase.class, (JsonDeserializer<MyBase>) (json1, pojoType, context) -> {
String type = json1.getAsJsonObject().get(MyBase.TYPE_ACCESS).getAsString();
return context.deserialize(json1, SubTypes.valueOf(type).getSubclass());
}).create();
SubType1 target = (SubType1) gson.fromJson(json, MyBase.class);
assertEquals("abc", target.field1);
}
private static class MyBase {
static final String TYPE_ACCESS = "__type__";
}
private enum SubTypes {
SUB_TYPE1(SubType1.class),
SUB_TYPE2(SubType2.class);
private final Type subClass;
private SubTypes(Type subClass) {
this.subClass = subClass;
}
public Type getSubclass() {
return subClass;
}
}
private static class SubType1 extends MyBase {
String field1;
}
private static class SubType2 extends MyBase {
@SuppressWarnings("unused")
String field2;
}
public void testCustomDeserializerReturnsNullForTopLevelObject() {
Gson gson = new GsonBuilder()
.setLenient()
.registerTypeAdapter(Base.class, (JsonDeserializer<Base>) (json, typeOfT, context) -> null).create();
String json = "{baseName:'Base',subName:'SubRevised'}";
Base target = gson.fromJson(json, Base.class);
assertNull(target);
}
public void testCustomDeserializerReturnsNull() {
Gson gson = new GsonBuilder()
.setLenient()
.registerTypeAdapter(Base.class, (JsonDeserializer<Base>) (json, typeOfT, context) -> null).create();
String json = "{base:{baseName:'Base',subName:'SubRevised'}}";
ClassWithBaseField target = gson.fromJson(json, ClassWithBaseField.class);
assertNull(target.base);
}
public void testCustomDeserializerReturnsNullForArrayElements() {
Gson gson = new GsonBuilder()
.setLenient()
.registerTypeAdapter(Base.class, (JsonDeserializer<Base>) (json, typeOfT, context) -> null).create();
String json = "[{baseName:'Base'},{baseName:'Base'}]";
Base[] target = gson.fromJson(json, Base[].class);
assertNull(target[0]);
assertNull(target[1]);
}
public void testCustomDeserializerReturnsNullForArrayElementsForArrayField() {
Gson gson = new GsonBuilder()
.setLenient()
.registerTypeAdapter(Base.class, (JsonDeserializer<Base>) (json, typeOfT, context) -> null).create();
String json = "{bases:[{baseName:'Base'},{baseName:'Base'}]}";
ClassWithBaseArray target = gson.fromJson(json, ClassWithBaseArray.class);
assertNull(target.bases[0]);
assertNull(target.bases[1]);
}
private static final class ClassWithBaseArray {
Base[] bases;
}
}