Improve versioning support documentation and validate version (#2214)
This commit is contained in:
parent
28609089fa
commit
796193d032
@ -28,6 +28,8 @@ import static com.google.gson.Gson.DEFAULT_SERIALIZE_NULLS;
|
|||||||
import static com.google.gson.Gson.DEFAULT_SPECIALIZE_FLOAT_VALUES;
|
import static com.google.gson.Gson.DEFAULT_SPECIALIZE_FLOAT_VALUES;
|
||||||
import static com.google.gson.Gson.DEFAULT_USE_JDK_UNSAFE;
|
import static com.google.gson.Gson.DEFAULT_USE_JDK_UNSAFE;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Since;
|
||||||
|
import com.google.gson.annotations.Until;
|
||||||
import com.google.gson.internal.$Gson$Preconditions;
|
import com.google.gson.internal.$Gson$Preconditions;
|
||||||
import com.google.gson.internal.Excluder;
|
import com.google.gson.internal.Excluder;
|
||||||
import com.google.gson.internal.bind.DefaultDateTypeAdapter;
|
import com.google.gson.internal.bind.DefaultDateTypeAdapter;
|
||||||
@ -143,14 +145,25 @@ public final class GsonBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures Gson to enable versioning support.
|
* Configures Gson to enable versioning support. Versioning support works based on the
|
||||||
|
* annotation types {@link Since} and {@link Until}. It allows including or excluding fields
|
||||||
|
* and classes based on the specified version. See the documentation of these annotation
|
||||||
|
* types for more information.
|
||||||
*
|
*
|
||||||
* @param ignoreVersionsAfter any field or type marked with a version higher than this value
|
* <p>By default versioning support is disabled and usage of {@code @Since} and {@code @Until}
|
||||||
* are ignored during serialization or deserialization.
|
* has no effect.
|
||||||
|
*
|
||||||
|
* @param version the version number to use.
|
||||||
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
||||||
|
* @throws IllegalArgumentException if the version number is NaN or negative
|
||||||
|
* @see Since
|
||||||
|
* @see Until
|
||||||
*/
|
*/
|
||||||
public GsonBuilder setVersion(double ignoreVersionsAfter) {
|
public GsonBuilder setVersion(double version) {
|
||||||
excluder = excluder.withVersion(ignoreVersionsAfter);
|
if (Double.isNaN(version) || version < 0.0) {
|
||||||
|
throw new IllegalArgumentException("Invalid version: " + version);
|
||||||
|
}
|
||||||
|
excluder = excluder.withVersion(version);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.google.gson.annotations;
|
package com.google.gson.annotations;
|
||||||
|
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
import java.lang.annotation.Documented;
|
import java.lang.annotation.Documented;
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
@ -24,12 +25,11 @@ import java.lang.annotation.Target;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* An annotation that indicates the version number since a member or a type has been present.
|
* An annotation that indicates the version number since a member or a type has been present.
|
||||||
* This annotation is useful to manage versioning of your Json classes for a web-service.
|
* This annotation is useful to manage versioning of your JSON classes for a web-service.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* This annotation has no effect unless you build {@link com.google.gson.Gson} with a
|
* This annotation has no effect unless you build {@link com.google.gson.Gson} with a
|
||||||
* {@link com.google.gson.GsonBuilder} and invoke
|
* {@code GsonBuilder} and invoke the {@link GsonBuilder#setVersion(double)} method.
|
||||||
* {@link com.google.gson.GsonBuilder#setVersion(double)} method.
|
|
||||||
*
|
*
|
||||||
* <p>Here is an example of how this annotation is meant to be used:</p>
|
* <p>Here is an example of how this annotation is meant to be used:</p>
|
||||||
* <pre>
|
* <pre>
|
||||||
@ -50,14 +50,16 @@ import java.lang.annotation.Target;
|
|||||||
*
|
*
|
||||||
* @author Inderjeet Singh
|
* @author Inderjeet Singh
|
||||||
* @author Joel Leitch
|
* @author Joel Leitch
|
||||||
|
* @see GsonBuilder#setVersion(double)
|
||||||
|
* @see Until
|
||||||
*/
|
*/
|
||||||
@Documented
|
@Documented
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target({ElementType.FIELD, ElementType.TYPE})
|
@Target({ElementType.FIELD, ElementType.TYPE})
|
||||||
public @interface Since {
|
public @interface Since {
|
||||||
/**
|
/**
|
||||||
* the value indicating a version number since this member
|
* The value indicating a version number since this member or type has been present.
|
||||||
* or type has been present.
|
* The number is inclusive; annotated elements will be included if {@code gsonVersion >= value}.
|
||||||
*/
|
*/
|
||||||
double value();
|
double value();
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.google.gson.annotations;
|
package com.google.gson.annotations;
|
||||||
|
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
import java.lang.annotation.Documented;
|
import java.lang.annotation.Documented;
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
@ -24,14 +25,13 @@ import java.lang.annotation.Target;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* An annotation that indicates the version number until a member or a type should be present.
|
* An annotation that indicates the version number until a member or a type should be present.
|
||||||
* Basically, if Gson is created with a version number that exceeds the value stored in the
|
* Basically, if Gson is created with a version number that is equal to or exceeds the value
|
||||||
* {@code Until} annotation then the field will be ignored from the JSON output. This annotation
|
* stored in the {@code Until} annotation then the field will be ignored from the JSON output.
|
||||||
* is useful to manage versioning of your JSON classes for a web-service.
|
* This annotation is useful to manage versioning of your JSON classes for a web-service.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* This annotation has no effect unless you build {@link com.google.gson.Gson} with a
|
* This annotation has no effect unless you build {@link com.google.gson.Gson} with a
|
||||||
* {@link com.google.gson.GsonBuilder} and invoke
|
* {@code GsonBuilder} and invoke the {@link GsonBuilder#setVersion(double)} method.
|
||||||
* {@link com.google.gson.GsonBuilder#setVersion(double)} method.
|
|
||||||
*
|
*
|
||||||
* <p>Here is an example of how this annotation is meant to be used:</p>
|
* <p>Here is an example of how this annotation is meant to be used:</p>
|
||||||
* <pre>
|
* <pre>
|
||||||
@ -47,12 +47,14 @@ import java.lang.annotation.Target;
|
|||||||
* methods will use all the fields for serialization and deserialization. However, if you created
|
* methods will use all the fields for serialization and deserialization. However, if you created
|
||||||
* Gson with {@code Gson gson = new GsonBuilder().setVersion(1.2).create()} then the
|
* Gson with {@code Gson gson = new GsonBuilder().setVersion(1.2).create()} then the
|
||||||
* {@code toJson()} and {@code fromJson()} methods of Gson will exclude the {@code emailAddress}
|
* {@code toJson()} and {@code fromJson()} methods of Gson will exclude the {@code emailAddress}
|
||||||
* and {@code password} fields from the example above, because the version number passed to the
|
* and {@code password} fields from the example above, because the version number passed to the
|
||||||
* GsonBuilder, {@code 1.2}, exceeds the version number set on the {@code Until} annotation,
|
* GsonBuilder, {@code 1.2}, exceeds the version number set on the {@code Until} annotation,
|
||||||
* {@code 1.1}, for those fields.
|
* {@code 1.1}, for those fields.
|
||||||
*
|
*
|
||||||
* @author Inderjeet Singh
|
* @author Inderjeet Singh
|
||||||
* @author Joel Leitch
|
* @author Joel Leitch
|
||||||
|
* @see GsonBuilder#setVersion(double)
|
||||||
|
* @see Since
|
||||||
* @since 1.3
|
* @since 1.3
|
||||||
*/
|
*/
|
||||||
@Documented
|
@Documented
|
||||||
@ -61,8 +63,8 @@ import java.lang.annotation.Target;
|
|||||||
public @interface Until {
|
public @interface Until {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the value indicating a version number until this member
|
* The value indicating a version number until this member or type should be be included.
|
||||||
* or type should be ignored.
|
* The number is exclusive; annotated elements will be included if {@code gsonVersion < value}.
|
||||||
*/
|
*/
|
||||||
double value();
|
double value();
|
||||||
}
|
}
|
||||||
|
@ -240,9 +240,7 @@ public final class Excluder implements TypeAdapterFactory, Cloneable {
|
|||||||
private boolean isValidSince(Since annotation) {
|
private boolean isValidSince(Since annotation) {
|
||||||
if (annotation != null) {
|
if (annotation != null) {
|
||||||
double annotationVersion = annotation.value();
|
double annotationVersion = annotation.value();
|
||||||
if (annotationVersion > version) {
|
return version >= annotationVersion;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -250,9 +248,7 @@ public final class Excluder implements TypeAdapterFactory, Cloneable {
|
|||||||
private boolean isValidUntil(Until annotation) {
|
private boolean isValidUntil(Until annotation) {
|
||||||
if (annotation != null) {
|
if (annotation != null) {
|
||||||
double annotationVersion = annotation.value();
|
double annotationVersion = annotation.value();
|
||||||
if (annotationVersion <= version) {
|
return version < annotationVersion;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -16,20 +16,25 @@
|
|||||||
|
|
||||||
package com.google.gson;
|
package com.google.gson;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertNotSame;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
import com.google.gson.stream.JsonReader;
|
import com.google.gson.stream.JsonReader;
|
||||||
import com.google.gson.stream.JsonWriter;
|
import com.google.gson.stream.JsonWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import junit.framework.TestCase;
|
import org.junit.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@link GsonBuilder}.
|
* Unit tests for {@link GsonBuilder}.
|
||||||
*
|
*
|
||||||
* @author Inderjeet Singh
|
* @author Inderjeet Singh
|
||||||
*/
|
*/
|
||||||
public class GsonBuilderTest extends TestCase {
|
public class GsonBuilderTest {
|
||||||
private static final TypeAdapter<Object> NULL_TYPE_ADAPTER = new TypeAdapter<Object>() {
|
private static final TypeAdapter<Object> NULL_TYPE_ADAPTER = new TypeAdapter<Object>() {
|
||||||
@Override public void write(JsonWriter out, Object value) {
|
@Override public void write(JsonWriter out, Object value) {
|
||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
@ -39,6 +44,7 @@ public class GsonBuilderTest extends TestCase {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testCreatingMoreThanOnce() {
|
public void testCreatingMoreThanOnce() {
|
||||||
GsonBuilder builder = new GsonBuilder();
|
GsonBuilder builder = new GsonBuilder();
|
||||||
Gson gson = builder.create();
|
Gson gson = builder.create();
|
||||||
@ -61,6 +67,7 @@ public class GsonBuilderTest extends TestCase {
|
|||||||
* Gson instances should not be affected by subsequent modification of GsonBuilder
|
* Gson instances should not be affected by subsequent modification of GsonBuilder
|
||||||
* which created them.
|
* which created them.
|
||||||
*/
|
*/
|
||||||
|
@Test
|
||||||
public void testModificationAfterCreate() {
|
public void testModificationAfterCreate() {
|
||||||
GsonBuilder gsonBuilder = new GsonBuilder();
|
GsonBuilder gsonBuilder = new GsonBuilder();
|
||||||
Gson gson = gsonBuilder.create();
|
Gson gson = gsonBuilder.create();
|
||||||
@ -136,6 +143,7 @@ public class GsonBuilderTest extends TestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testExcludeFieldsWithModifiers() {
|
public void testExcludeFieldsWithModifiers() {
|
||||||
Gson gson = new GsonBuilder()
|
Gson gson = new GsonBuilder()
|
||||||
.excludeFieldsWithModifiers(Modifier.VOLATILE, Modifier.PRIVATE)
|
.excludeFieldsWithModifiers(Modifier.VOLATILE, Modifier.PRIVATE)
|
||||||
@ -151,6 +159,7 @@ public class GsonBuilderTest extends TestCase {
|
|||||||
String d = "d";
|
String d = "d";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testTransientFieldExclusion() {
|
public void testTransientFieldExclusion() {
|
||||||
Gson gson = new GsonBuilder()
|
Gson gson = new GsonBuilder()
|
||||||
.excludeFieldsWithModifiers()
|
.excludeFieldsWithModifiers()
|
||||||
@ -162,6 +171,7 @@ public class GsonBuilderTest extends TestCase {
|
|||||||
transient String a = "a";
|
transient String a = "a";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testRegisterTypeAdapterForCoreType() {
|
public void testRegisterTypeAdapterForCoreType() {
|
||||||
Type[] types = {
|
Type[] types = {
|
||||||
byte.class,
|
byte.class,
|
||||||
@ -176,6 +186,7 @@ public class GsonBuilderTest extends TestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testDisableJdkUnsafe() {
|
public void testDisableJdkUnsafe() {
|
||||||
Gson gson = new GsonBuilder()
|
Gson gson = new GsonBuilder()
|
||||||
.disableJdkUnsafe()
|
.disableJdkUnsafe()
|
||||||
@ -198,4 +209,22 @@ public class GsonBuilderTest extends TestCase {
|
|||||||
public ClassWithoutNoArgsConstructor(String s) {
|
public ClassWithoutNoArgsConstructor(String s) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetVersionInvalid() {
|
||||||
|
GsonBuilder builder = new GsonBuilder();
|
||||||
|
try {
|
||||||
|
builder.setVersion(Double.NaN);
|
||||||
|
fail();
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
assertEquals("Invalid version: NaN", e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
builder.setVersion(-0.1);
|
||||||
|
fail();
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
assertEquals("Invalid version: -0.1", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,40 +16,82 @@
|
|||||||
|
|
||||||
package com.google.gson;
|
package com.google.gson;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import com.google.gson.annotations.Since;
|
import com.google.gson.annotations.Since;
|
||||||
|
import com.google.gson.annotations.Until;
|
||||||
import com.google.gson.internal.Excluder;
|
import com.google.gson.internal.Excluder;
|
||||||
import junit.framework.TestCase;
|
import org.junit.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for the {@link Excluder} class.
|
* Unit tests for the {@link Excluder} class.
|
||||||
*
|
*
|
||||||
* @author Joel Leitch
|
* @author Joel Leitch
|
||||||
*/
|
*/
|
||||||
public class VersionExclusionStrategyTest extends TestCase {
|
public class VersionExclusionStrategyTest {
|
||||||
private static final double VERSION = 5.0D;
|
private static final double VERSION = 5.0D;
|
||||||
|
|
||||||
public void testClassAndFieldAreAtSameVersion() throws Exception {
|
@Test
|
||||||
|
public void testSameVersion() throws Exception {
|
||||||
Excluder excluder = Excluder.DEFAULT.withVersion(VERSION);
|
Excluder excluder = Excluder.DEFAULT.withVersion(VERSION);
|
||||||
assertFalse(excluder.excludeClass(MockObject.class, true));
|
assertFalse(excluder.excludeClass(MockClassSince.class, true));
|
||||||
assertFalse(excluder.excludeField(MockObject.class.getField("someField"), true));
|
assertFalse(excluder.excludeField(MockClassSince.class.getField("someField"), true));
|
||||||
|
|
||||||
|
// Until version is exclusive
|
||||||
|
assertTrue(excluder.excludeClass(MockClassUntil.class, true));
|
||||||
|
assertTrue(excluder.excludeField(MockClassUntil.class.getField("someField"), true));
|
||||||
|
|
||||||
|
assertFalse(excluder.excludeClass(MockClassBoth.class, true));
|
||||||
|
assertFalse(excluder.excludeField(MockClassBoth.class.getField("someField"), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testClassAndFieldAreBehindInVersion() throws Exception {
|
@Test
|
||||||
Excluder excluder = Excluder.DEFAULT.withVersion(VERSION + 1);
|
public void testNewerVersion() throws Exception {
|
||||||
assertFalse(excluder.excludeClass(MockObject.class, true));
|
Excluder excluder = Excluder.DEFAULT.withVersion(VERSION + 5);
|
||||||
assertFalse(excluder.excludeField(MockObject.class.getField("someField"), true));
|
assertFalse(excluder.excludeClass(MockClassSince.class, true));
|
||||||
|
assertFalse(excluder.excludeField(MockClassSince.class.getField("someField"), true));
|
||||||
|
|
||||||
|
assertTrue(excluder.excludeClass(MockClassUntil.class, true));
|
||||||
|
assertTrue(excluder.excludeField(MockClassUntil.class.getField("someField"), true));
|
||||||
|
|
||||||
|
assertTrue(excluder.excludeClass(MockClassBoth.class, true));
|
||||||
|
assertTrue(excluder.excludeField(MockClassBoth.class.getField("someField"), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testClassAndFieldAreAheadInVersion() throws Exception {
|
@Test
|
||||||
Excluder excluder = Excluder.DEFAULT.withVersion(VERSION - 1);
|
public void testOlderVersion() throws Exception {
|
||||||
assertTrue(excluder.excludeClass(MockObject.class, true));
|
Excluder excluder = Excluder.DEFAULT.withVersion(VERSION - 5);
|
||||||
assertTrue(excluder.excludeField(MockObject.class.getField("someField"), true));
|
assertTrue(excluder.excludeClass(MockClassSince.class, true));
|
||||||
|
assertTrue(excluder.excludeField(MockClassSince.class.getField("someField"), true));
|
||||||
|
|
||||||
|
assertFalse(excluder.excludeClass(MockClassUntil.class, true));
|
||||||
|
assertFalse(excluder.excludeField(MockClassUntil.class.getField("someField"), true));
|
||||||
|
|
||||||
|
assertTrue(excluder.excludeClass(MockClassBoth.class, true));
|
||||||
|
assertTrue(excluder.excludeField(MockClassBoth.class.getField("someField"), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Since(VERSION)
|
@Since(VERSION)
|
||||||
private static class MockObject {
|
private static class MockClassSince {
|
||||||
|
|
||||||
@Since(VERSION)
|
@Since(VERSION)
|
||||||
public final int someField = 0;
|
public final int someField = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Until(VERSION)
|
||||||
|
private static class MockClassUntil {
|
||||||
|
|
||||||
|
@Until(VERSION)
|
||||||
|
public final int someField = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Since(VERSION)
|
||||||
|
@Until(VERSION + 2)
|
||||||
|
private static class MockClassBoth {
|
||||||
|
|
||||||
|
@Since(VERSION)
|
||||||
|
@Until(VERSION + 2)
|
||||||
|
public final int someField = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,13 +15,17 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.gson.functional;
|
package com.google.gson.functional;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import com.google.gson.annotations.Since;
|
import com.google.gson.annotations.Since;
|
||||||
import com.google.gson.annotations.Until;
|
import com.google.gson.annotations.Until;
|
||||||
import com.google.gson.common.TestTypes.BagOfPrimitives;
|
import com.google.gson.common.TestTypes.BagOfPrimitives;
|
||||||
|
import org.junit.Test;
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Functional tests for versioning support in Gson.
|
* Functional tests for versioning support in Gson.
|
||||||
@ -29,47 +33,60 @@ import junit.framework.TestCase;
|
|||||||
* @author Inderjeet Singh
|
* @author Inderjeet Singh
|
||||||
* @author Joel Leitch
|
* @author Joel Leitch
|
||||||
*/
|
*/
|
||||||
public class VersioningTest extends TestCase {
|
public class VersioningTest {
|
||||||
private static final int A = 0;
|
private static final int A = 0;
|
||||||
private static final int B = 1;
|
private static final int B = 1;
|
||||||
private static final int C = 2;
|
private static final int C = 2;
|
||||||
private static final int D = 3;
|
private static final int D = 3;
|
||||||
|
|
||||||
private GsonBuilder builder;
|
private static Gson gsonWithVersion(double version) {
|
||||||
|
return new GsonBuilder().setVersion(version).create();
|
||||||
@Override
|
|
||||||
protected void setUp() throws Exception {
|
|
||||||
super.setUp();
|
|
||||||
builder = new GsonBuilder();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testVersionedUntilSerialization() {
|
public void testVersionedUntilSerialization() {
|
||||||
Version1 target = new Version1();
|
Version1 target = new Version1();
|
||||||
Gson gson = builder.setVersion(1.29).create();
|
Gson gson = gsonWithVersion(1.29);
|
||||||
String json = gson.toJson(target);
|
String json = gson.toJson(target);
|
||||||
assertTrue(json.contains("\"a\":" + A));
|
assertTrue(json.contains("\"a\":" + A));
|
||||||
|
|
||||||
gson = builder.setVersion(1.3).create();
|
gson = gsonWithVersion(1.3);
|
||||||
|
json = gson.toJson(target);
|
||||||
|
assertFalse(json.contains("\"a\":" + A));
|
||||||
|
|
||||||
|
gson = gsonWithVersion(1.31);
|
||||||
json = gson.toJson(target);
|
json = gson.toJson(target);
|
||||||
assertFalse(json.contains("\"a\":" + A));
|
assertFalse(json.contains("\"a\":" + A));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testVersionedUntilDeserialization() {
|
public void testVersionedUntilDeserialization() {
|
||||||
Gson gson = builder.setVersion(1.3).create();
|
|
||||||
String json = "{\"a\":3,\"b\":4,\"c\":5}";
|
String json = "{\"a\":3,\"b\":4,\"c\":5}";
|
||||||
|
|
||||||
|
Gson gson = gsonWithVersion(1.29);
|
||||||
Version1 version1 = gson.fromJson(json, Version1.class);
|
Version1 version1 = gson.fromJson(json, Version1.class);
|
||||||
|
assertEquals(3, version1.a);
|
||||||
|
|
||||||
|
gson = gsonWithVersion(1.3);
|
||||||
|
version1 = gson.fromJson(json, Version1.class);
|
||||||
|
assertEquals(A, version1.a);
|
||||||
|
|
||||||
|
gson = gsonWithVersion(1.31);
|
||||||
|
version1 = gson.fromJson(json, Version1.class);
|
||||||
assertEquals(A, version1.a);
|
assertEquals(A, version1.a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testVersionedClassesSerialization() {
|
public void testVersionedClassesSerialization() {
|
||||||
Gson gson = builder.setVersion(1.0).create();
|
Gson gson = gsonWithVersion(1.0);
|
||||||
String json1 = gson.toJson(new Version1());
|
String json1 = gson.toJson(new Version1());
|
||||||
String json2 = gson.toJson(new Version1_1());
|
String json2 = gson.toJson(new Version1_1());
|
||||||
assertEquals(json1, json2);
|
assertEquals(json1, json2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testVersionedClassesDeserialization() {
|
public void testVersionedClassesDeserialization() {
|
||||||
Gson gson = builder.setVersion(1.0).create();
|
Gson gson = gsonWithVersion(1.0);
|
||||||
String json = "{\"a\":3,\"b\":4,\"c\":5}";
|
String json = "{\"a\":3,\"b\":4,\"c\":5}";
|
||||||
Version1 version1 = gson.fromJson(json, Version1.class);
|
Version1 version1 = gson.fromJson(json, Version1.class);
|
||||||
assertEquals(3, version1.a);
|
assertEquals(3, version1.a);
|
||||||
@ -80,13 +97,15 @@ public class VersioningTest extends TestCase {
|
|||||||
assertEquals(C, version1_1.c);
|
assertEquals(C, version1_1.c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testIgnoreLaterVersionClassSerialization() {
|
public void testIgnoreLaterVersionClassSerialization() {
|
||||||
Gson gson = builder.setVersion(1.0).create();
|
Gson gson = gsonWithVersion(1.0);
|
||||||
assertEquals("null", gson.toJson(new Version1_2()));
|
assertEquals("null", gson.toJson(new Version1_2()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testIgnoreLaterVersionClassDeserialization() {
|
public void testIgnoreLaterVersionClassDeserialization() {
|
||||||
Gson gson = builder.setVersion(1.0).create();
|
Gson gson = gsonWithVersion(1.0);
|
||||||
String json = "{\"a\":3,\"b\":4,\"c\":5,\"d\":6}";
|
String json = "{\"a\":3,\"b\":4,\"c\":5,\"d\":6}";
|
||||||
Version1_2 version1_2 = gson.fromJson(json, Version1_2.class);
|
Version1_2 version1_2 = gson.fromJson(json, Version1_2.class);
|
||||||
// Since the class is versioned to be after 1.0, we expect null
|
// Since the class is versioned to be after 1.0, we expect null
|
||||||
@ -94,14 +113,16 @@ public class VersioningTest extends TestCase {
|
|||||||
assertNull(version1_2);
|
assertNull(version1_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testVersionedGsonWithUnversionedClassesSerialization() {
|
public void testVersionedGsonWithUnversionedClassesSerialization() {
|
||||||
Gson gson = builder.setVersion(1.0).create();
|
Gson gson = gsonWithVersion(1.0);
|
||||||
BagOfPrimitives target = new BagOfPrimitives(10, 20, false, "stringValue");
|
BagOfPrimitives target = new BagOfPrimitives(10, 20, false, "stringValue");
|
||||||
assertEquals(target.getExpectedJson(), gson.toJson(target));
|
assertEquals(target.getExpectedJson(), gson.toJson(target));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testVersionedGsonWithUnversionedClassesDeserialization() {
|
public void testVersionedGsonWithUnversionedClassesDeserialization() {
|
||||||
Gson gson = builder.setVersion(1.0).create();
|
Gson gson = gsonWithVersion(1.0);
|
||||||
String json = "{\"longValue\":10,\"intValue\":20,\"booleanValue\":false}";
|
String json = "{\"longValue\":10,\"intValue\":20,\"booleanValue\":false}";
|
||||||
|
|
||||||
BagOfPrimitives expected = new BagOfPrimitives();
|
BagOfPrimitives expected = new BagOfPrimitives();
|
||||||
@ -112,34 +133,45 @@ public class VersioningTest extends TestCase {
|
|||||||
assertEquals(expected, actual);
|
assertEquals(expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testVersionedGsonMixingSinceAndUntilSerialization() {
|
public void testVersionedGsonMixingSinceAndUntilSerialization() {
|
||||||
Gson gson = builder.setVersion(1.0).create();
|
Gson gson = gsonWithVersion(1.0);
|
||||||
SinceUntilMixing target = new SinceUntilMixing();
|
SinceUntilMixing target = new SinceUntilMixing();
|
||||||
String json = gson.toJson(target);
|
String json = gson.toJson(target);
|
||||||
assertFalse(json.contains("\"b\":" + B));
|
assertFalse(json.contains("\"b\":" + B));
|
||||||
|
|
||||||
gson = builder.setVersion(1.2).create();
|
gson = gsonWithVersion(1.2);
|
||||||
json = gson.toJson(target);
|
json = gson.toJson(target);
|
||||||
assertTrue(json.contains("\"b\":" + B));
|
assertTrue(json.contains("\"b\":" + B));
|
||||||
|
|
||||||
gson = builder.setVersion(1.3).create();
|
gson = gsonWithVersion(1.3);
|
||||||
|
json = gson.toJson(target);
|
||||||
|
assertFalse(json.contains("\"b\":" + B));
|
||||||
|
|
||||||
|
gson = gsonWithVersion(1.4);
|
||||||
json = gson.toJson(target);
|
json = gson.toJson(target);
|
||||||
assertFalse(json.contains("\"b\":" + B));
|
assertFalse(json.contains("\"b\":" + B));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testVersionedGsonMixingSinceAndUntilDeserialization() {
|
public void testVersionedGsonMixingSinceAndUntilDeserialization() {
|
||||||
String json = "{\"a\":5,\"b\":6}";
|
String json = "{\"a\":5,\"b\":6}";
|
||||||
Gson gson = builder.setVersion(1.0).create();
|
Gson gson = gsonWithVersion(1.0);
|
||||||
SinceUntilMixing result = gson.fromJson(json, SinceUntilMixing.class);
|
SinceUntilMixing result = gson.fromJson(json, SinceUntilMixing.class);
|
||||||
assertEquals(5, result.a);
|
assertEquals(5, result.a);
|
||||||
assertEquals(B, result.b);
|
assertEquals(B, result.b);
|
||||||
|
|
||||||
gson = builder.setVersion(1.2).create();
|
gson = gsonWithVersion(1.2);
|
||||||
result = gson.fromJson(json, SinceUntilMixing.class);
|
result = gson.fromJson(json, SinceUntilMixing.class);
|
||||||
assertEquals(5, result.a);
|
assertEquals(5, result.a);
|
||||||
assertEquals(6, result.b);
|
assertEquals(6, result.b);
|
||||||
|
|
||||||
gson = builder.setVersion(1.3).create();
|
gson = gsonWithVersion(1.3);
|
||||||
|
result = gson.fromJson(json, SinceUntilMixing.class);
|
||||||
|
assertEquals(5, result.a);
|
||||||
|
assertEquals(B, result.b);
|
||||||
|
|
||||||
|
gson = gsonWithVersion(1.4);
|
||||||
result = gson.fromJson(json, SinceUntilMixing.class);
|
result = gson.fromJson(json, SinceUntilMixing.class);
|
||||||
assertEquals(5, result.a);
|
assertEquals(5, result.a);
|
||||||
assertEquals(B, result.b);
|
assertEquals(B, result.b);
|
||||||
|
Loading…
Reference in New Issue
Block a user