/* * 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 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.ExclusionStrategy; import com.google.gson.FieldAttributes; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.junit.Before; import org.junit.Test; /** * Performs some functional tests when Gson is instantiated with some common user defined * {@link ExclusionStrategy} objects. * * @author Inderjeet Singh * @author Joel Leitch */ public class ExclusionStrategyFunctionalTest { private static final ExclusionStrategy EXCLUDE_SAMPLE_OBJECT_FOR_TEST = new ExclusionStrategy() { @Override public boolean shouldSkipField(FieldAttributes f) { return false; } @Override public boolean shouldSkipClass(Class clazz) { return clazz == SampleObjectForTest.class; } }; private SampleObjectForTest src; @Before public void setUp() throws Exception { src = new SampleObjectForTest(); } @Test public void testExclusionStrategySerialization() throws Exception { Gson gson = createGson(new MyExclusionStrategy(String.class), true); String json = gson.toJson(src); assertFalse(json.contains("\"stringField\"")); assertFalse(json.contains("\"annotatedField\"")); assertTrue(json.contains("\"longField\"")); } @Test public void testExclusionStrategySerializationDoesNotImpactDeserialization() { String json = "{\"annotatedField\":1,\"stringField\":\"x\",\"longField\":2}"; Gson gson = createGson(new MyExclusionStrategy(String.class), true); SampleObjectForTest value = gson.fromJson(json, SampleObjectForTest.class); assertEquals(1, value.annotatedField); assertEquals("x", value.stringField); assertEquals(2, value.longField); } @Test public void testExclusionStrategyDeserialization() throws Exception { Gson gson = createGson(new MyExclusionStrategy(String.class), false); JsonObject json = new JsonObject(); json.add("annotatedField", new JsonPrimitive(src.annotatedField + 5)); json.add("stringField", new JsonPrimitive(src.stringField + "blah,blah")); json.add("longField", new JsonPrimitive(1212311L)); SampleObjectForTest target = gson.fromJson(json, SampleObjectForTest.class); assertEquals(1212311L, target.longField); // assert excluded fields are set to the defaults assertEquals(src.annotatedField, target.annotatedField); assertEquals(src.stringField, target.stringField); } @Test public void testExclusionStrategySerializationDoesNotImpactSerialization() throws Exception { Gson gson = createGson(new MyExclusionStrategy(String.class), false); String json = gson.toJson(src); assertTrue(json.contains("\"stringField\"")); assertTrue(json.contains("\"annotatedField\"")); assertTrue(json.contains("\"longField\"")); } @Test public void testExclusionStrategyWithMode() throws Exception { SampleObjectForTest testObj = new SampleObjectForTest( src.annotatedField + 5, src.stringField + "blah,blah", src.longField + 655L); Gson gson = createGson(new MyExclusionStrategy(String.class), false); JsonObject json = gson.toJsonTree(testObj).getAsJsonObject(); assertEquals(testObj.annotatedField, json.get("annotatedField").getAsInt()); assertEquals(testObj.stringField, json.get("stringField").getAsString()); assertEquals(testObj.longField, json.get("longField").getAsLong()); SampleObjectForTest target = gson.fromJson(json, SampleObjectForTest.class); assertEquals(testObj.longField, target.longField); // assert excluded fields are set to the defaults assertEquals(src.annotatedField, target.annotatedField); assertEquals(src.stringField, target.stringField); } @Test public void testExcludeTopLevelClassSerialization() { Gson gson = new GsonBuilder() .addSerializationExclusionStrategy(EXCLUDE_SAMPLE_OBJECT_FOR_TEST) .create(); assertEquals("null", gson.toJson(new SampleObjectForTest(), SampleObjectForTest.class)); } @Test public void testExcludeTopLevelClassSerializationDoesNotImpactDeserialization() { Gson gson = new GsonBuilder() .addSerializationExclusionStrategy(EXCLUDE_SAMPLE_OBJECT_FOR_TEST) .create(); String json = "{\"annotatedField\":1,\"stringField\":\"x\",\"longField\":2}"; SampleObjectForTest value = gson.fromJson(json, SampleObjectForTest.class); assertEquals(1, value.annotatedField); assertEquals("x", value.stringField); assertEquals(2, value.longField); } @Test public void testExcludeTopLevelClassDeserialization() { Gson gson = new GsonBuilder() .addDeserializationExclusionStrategy(EXCLUDE_SAMPLE_OBJECT_FOR_TEST) .create(); String json = "{\"annotatedField\":1,\"stringField\":\"x\",\"longField\":2}"; SampleObjectForTest value = gson.fromJson(json, SampleObjectForTest.class); assertNull(value); } @Test public void testExcludeTopLevelClassDeserializationDoesNotImpactSerialization() { Gson gson = new GsonBuilder() .addDeserializationExclusionStrategy(EXCLUDE_SAMPLE_OBJECT_FOR_TEST) .create(); String json = gson.toJson(new SampleObjectForTest(), SampleObjectForTest.class); assertTrue(json.contains("\"stringField\"")); assertTrue(json.contains("\"annotatedField\"")); assertTrue(json.contains("\"longField\"")); } private static Gson createGson(ExclusionStrategy exclusionStrategy, boolean serialization) { GsonBuilder gsonBuilder = new GsonBuilder(); if (serialization) { gsonBuilder.addSerializationExclusionStrategy(exclusionStrategy); } else { gsonBuilder.addDeserializationExclusionStrategy(exclusionStrategy); } return gsonBuilder .serializeNulls() .create(); } @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD}) private static @interface Foo { // Field tag only annotation } private static class SampleObjectForTest { @Foo private final int annotatedField; private final String stringField; private final long longField; public SampleObjectForTest() { this(5, "someDefaultValue", 12345L); } public SampleObjectForTest(int annotatedField, String stringField, long longField) { this.annotatedField = annotatedField; this.stringField = stringField; this.longField = longField; } } private static final class MyExclusionStrategy implements ExclusionStrategy { private final Class typeToSkip; private MyExclusionStrategy(Class typeToSkip) { this.typeToSkip = typeToSkip; } @Override public boolean shouldSkipClass(Class clazz) { return (clazz == typeToSkip); } @Override public boolean shouldSkipField(FieldAttributes f) { return f.getAnnotation(Foo.class) != null; } } }