| /* |
| * 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.InstanceCreator; |
| import com.google.gson.JsonElement; |
| import com.google.gson.JsonObject; |
| import com.google.gson.JsonParseException; |
| import com.google.gson.JsonSerializationContext; |
| import com.google.gson.JsonSerializer; |
| import com.google.gson.common.TestTypes.ArrayOfObjects; |
| import com.google.gson.common.TestTypes.BagOfPrimitiveWrappers; |
| import com.google.gson.common.TestTypes.BagOfPrimitives; |
| import com.google.gson.common.TestTypes.ClassWithArray; |
| import com.google.gson.common.TestTypes.ClassWithNoFields; |
| import com.google.gson.common.TestTypes.ClassWithObjects; |
| import com.google.gson.common.TestTypes.ClassWithTransientFields; |
| import com.google.gson.common.TestTypes.Nested; |
| import com.google.gson.common.TestTypes.PrimitiveArray; |
| import com.google.gson.internal.JavaVersion; |
| import com.google.gson.reflect.TypeToken; |
| import java.lang.reflect.Type; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Date; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Locale; |
| import java.util.Map; |
| import java.util.TimeZone; |
| import junit.framework.TestCase; |
| |
| /** |
| * Functional tests for Json serialization and deserialization of regular classes. |
| * |
| * @author Inderjeet Singh |
| * @author Joel Leitch |
| */ |
| public class ObjectTest extends TestCase { |
| private Gson gson; |
| private TimeZone oldTimeZone; |
| private Locale oldLocale; |
| |
| @Override |
| protected void setUp() throws Exception { |
| super.setUp(); |
| gson = new Gson(); |
| |
| oldTimeZone = TimeZone.getDefault(); |
| TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles")); |
| oldLocale = Locale.getDefault(); |
| Locale.setDefault(Locale.US); |
| } |
| |
| @Override |
| protected void tearDown() throws Exception { |
| TimeZone.setDefault(oldTimeZone); |
| Locale.setDefault(oldLocale); |
| super.tearDown(); |
| } |
| |
| public void testJsonInSingleQuotesDeserialization() { |
| String json = "{'stringValue':'no message','intValue':10,'longValue':20}"; |
| BagOfPrimitives target = gson.fromJson(json, BagOfPrimitives.class); |
| assertEquals("no message", target.stringValue); |
| assertEquals(10, target.intValue); |
| assertEquals(20, target.longValue); |
| } |
| |
| public void testJsonInMixedQuotesDeserialization() { |
| String json = "{\"stringValue\":'no message','intValue':10,'longValue':20}"; |
| BagOfPrimitives target = gson.fromJson(json, BagOfPrimitives.class); |
| assertEquals("no message", target.stringValue); |
| assertEquals(10, target.intValue); |
| assertEquals(20, target.longValue); |
| } |
| |
| public void testBagOfPrimitivesSerialization() throws Exception { |
| BagOfPrimitives target = new BagOfPrimitives(10, 20, false, "stringValue"); |
| assertEquals(target.getExpectedJson(), gson.toJson(target)); |
| } |
| |
| public void testBagOfPrimitivesDeserialization() throws Exception { |
| BagOfPrimitives src = new BagOfPrimitives(10, 20, false, "stringValue"); |
| String json = src.getExpectedJson(); |
| BagOfPrimitives target = gson.fromJson(json, BagOfPrimitives.class); |
| assertEquals(json, target.getExpectedJson()); |
| } |
| |
| public void testBagOfPrimitiveWrappersSerialization() throws Exception { |
| BagOfPrimitiveWrappers target = new BagOfPrimitiveWrappers(10L, 20, false); |
| assertEquals(target.getExpectedJson(), gson.toJson(target)); |
| } |
| |
| public void testBagOfPrimitiveWrappersDeserialization() throws Exception { |
| BagOfPrimitiveWrappers target = new BagOfPrimitiveWrappers(10L, 20, false); |
| String jsonString = target.getExpectedJson(); |
| target = gson.fromJson(jsonString, BagOfPrimitiveWrappers.class); |
| assertEquals(jsonString, target.getExpectedJson()); |
| } |
| |
| public void testClassWithTransientFieldsSerialization() throws Exception { |
| ClassWithTransientFields<Long> target = new ClassWithTransientFields<>(1L); |
| assertEquals(target.getExpectedJson(), gson.toJson(target)); |
| } |
| |
| public void testClassWithTransientFieldsDeserialization() throws Exception { |
| String json = "{\"longValue\":[1]}"; |
| ClassWithTransientFields<?> target = gson.fromJson(json, ClassWithTransientFields.class); |
| assertEquals(json, target.getExpectedJson()); |
| } |
| |
| public void testClassWithTransientFieldsDeserializationTransientFieldsPassedInJsonAreIgnored() |
| throws Exception { |
| String json = "{\"transientLongValue\":1,\"longValue\":[1]}"; |
| ClassWithTransientFields<?> target = gson.fromJson(json, ClassWithTransientFields.class); |
| assertFalse(target.transientLongValue != 1); |
| } |
| |
| public void testClassWithNoFieldsSerialization() throws Exception { |
| assertEquals("{}", gson.toJson(new ClassWithNoFields())); |
| } |
| |
| public void testClassWithNoFieldsDeserialization() throws Exception { |
| String json = "{}"; |
| ClassWithNoFields target = gson.fromJson(json, ClassWithNoFields.class); |
| ClassWithNoFields expected = new ClassWithNoFields(); |
| assertEquals(expected, target); |
| } |
| |
| public void testNestedSerialization() throws Exception { |
| Nested target = new Nested(new BagOfPrimitives(10, 20, false, "stringValue"), |
| new BagOfPrimitives(30, 40, true, "stringValue")); |
| assertEquals(target.getExpectedJson(), gson.toJson(target)); |
| } |
| |
| public void testNestedDeserialization() throws Exception { |
| String json = "{\"primitive1\":{\"longValue\":10,\"intValue\":20,\"booleanValue\":false," |
| + "\"stringValue\":\"stringValue\"},\"primitive2\":{\"longValue\":30,\"intValue\":40," |
| + "\"booleanValue\":true,\"stringValue\":\"stringValue\"}}"; |
| Nested target = gson.fromJson(json, Nested.class); |
| assertEquals(json, target.getExpectedJson()); |
| } |
| public void testNullSerialization() throws Exception { |
| assertEquals("null", gson.toJson(null)); |
| } |
| |
| public void testEmptyStringDeserialization() throws Exception { |
| Object object = gson.fromJson("", Object.class); |
| assertNull(object); |
| } |
| |
| public void testTruncatedDeserialization() { |
| try { |
| gson.fromJson("[\"a\", \"b\",", new TypeToken<List<String>>() {}.getType()); |
| fail(); |
| } catch (JsonParseException expected) { |
| } |
| } |
| |
| public void testNullDeserialization() throws Exception { |
| String myNullObject = null; |
| Object object = gson.fromJson(myNullObject, Object.class); |
| assertNull(object); |
| } |
| |
| public void testNullFieldsSerialization() throws Exception { |
| Nested target = new Nested(new BagOfPrimitives(10, 20, false, "stringValue"), null); |
| assertEquals(target.getExpectedJson(), gson.toJson(target)); |
| } |
| |
| public void testNullFieldsDeserialization() throws Exception { |
| String json = "{\"primitive1\":{\"longValue\":10,\"intValue\":20,\"booleanValue\":false" |
| + ",\"stringValue\":\"stringValue\"}}"; |
| Nested target = gson.fromJson(json, Nested.class); |
| assertEquals(json, target.getExpectedJson()); |
| } |
| |
| public void testArrayOfObjectsSerialization() throws Exception { |
| ArrayOfObjects target = new ArrayOfObjects(); |
| assertEquals(target.getExpectedJson(), gson.toJson(target)); |
| } |
| |
| public void testArrayOfObjectsDeserialization() throws Exception { |
| String json = new ArrayOfObjects().getExpectedJson(); |
| ArrayOfObjects target = gson.fromJson(json, ArrayOfObjects.class); |
| assertEquals(json, target.getExpectedJson()); |
| } |
| |
| public void testArrayOfArraysSerialization() throws Exception { |
| ArrayOfArrays target = new ArrayOfArrays(); |
| assertEquals(target.getExpectedJson(), gson.toJson(target)); |
| } |
| |
| public void testArrayOfArraysDeserialization() throws Exception { |
| String json = new ArrayOfArrays().getExpectedJson(); |
| ArrayOfArrays target = gson.fromJson(json, ArrayOfArrays.class); |
| assertEquals(json, target.getExpectedJson()); |
| } |
| |
| public void testArrayOfObjectsAsFields() throws Exception { |
| ClassWithObjects classWithObjects = new ClassWithObjects(); |
| BagOfPrimitives bagOfPrimitives = new BagOfPrimitives(); |
| String stringValue = "someStringValueInArray"; |
| String classWithObjectsJson = gson.toJson(classWithObjects); |
| String bagOfPrimitivesJson = gson.toJson(bagOfPrimitives); |
| |
| ClassWithArray classWithArray = new ClassWithArray( |
| new Object[] { stringValue, classWithObjects, bagOfPrimitives }); |
| String json = gson.toJson(classWithArray); |
| |
| assertTrue(json.contains(classWithObjectsJson)); |
| assertTrue(json.contains(bagOfPrimitivesJson)); |
| assertTrue(json.contains("\"" + stringValue + "\"")); |
| } |
| |
| /** |
| * Created in response to Issue 14: http://code.google.com/p/google-gson/issues/detail?id=14 |
| */ |
| public void testNullArraysDeserialization() throws Exception { |
| String json = "{\"array\": null}"; |
| ClassWithArray target = gson.fromJson(json, ClassWithArray.class); |
| assertNull(target.array); |
| } |
| |
| /** |
| * Created in response to Issue 14: http://code.google.com/p/google-gson/issues/detail?id=14 |
| */ |
| public void testNullObjectFieldsDeserialization() throws Exception { |
| String json = "{\"bag\": null}"; |
| ClassWithObjects target = gson.fromJson(json, ClassWithObjects.class); |
| assertNull(target.bag); |
| } |
| |
| public void testEmptyCollectionInAnObjectDeserialization() throws Exception { |
| String json = "{\"children\":[]}"; |
| ClassWithCollectionField target = gson.fromJson(json, ClassWithCollectionField.class); |
| assertNotNull(target); |
| assertTrue(target.children.isEmpty()); |
| } |
| |
| private static class ClassWithCollectionField { |
| Collection<String> children = new ArrayList<>(); |
| } |
| |
| public void testPrimitiveArrayInAnObjectDeserialization() throws Exception { |
| String json = "{\"longArray\":[0,1,2,3,4,5,6,7,8,9]}"; |
| PrimitiveArray target = gson.fromJson(json, PrimitiveArray.class); |
| assertEquals(json, target.getExpectedJson()); |
| } |
| |
| /** |
| * Created in response to Issue 14: http://code.google.com/p/google-gson/issues/detail?id=14 |
| */ |
| public void testNullPrimitiveFieldsDeserialization() throws Exception { |
| String json = "{\"longValue\":null}"; |
| BagOfPrimitives target = gson.fromJson(json, BagOfPrimitives.class); |
| assertEquals(BagOfPrimitives.DEFAULT_VALUE, target.longValue); |
| } |
| |
| public void testEmptyCollectionInAnObjectSerialization() throws Exception { |
| ClassWithCollectionField target = new ClassWithCollectionField(); |
| assertEquals("{\"children\":[]}", gson.toJson(target)); |
| } |
| |
| public void testPrivateNoArgConstructorDeserialization() throws Exception { |
| ClassWithPrivateNoArgsConstructor target = |
| gson.fromJson("{\"a\":20}", ClassWithPrivateNoArgsConstructor.class); |
| assertEquals(20, target.a); |
| } |
| |
| public void testAnonymousLocalClassesSerialization() throws Exception { |
| assertEquals("null", gson.toJson(new ClassWithNoFields() { |
| // empty anonymous class |
| })); |
| } |
| |
| public void testAnonymousLocalClassesCustomSerialization() throws Exception { |
| gson = new GsonBuilder() |
| .registerTypeHierarchyAdapter(ClassWithNoFields.class, |
| new JsonSerializer<ClassWithNoFields>() { |
| @Override public JsonElement serialize( |
| ClassWithNoFields src, Type typeOfSrc, JsonSerializationContext context) { |
| return new JsonObject(); |
| } |
| }).create(); |
| |
| assertEquals("null", gson.toJson(new ClassWithNoFields() { |
| // empty anonymous class |
| })); |
| } |
| |
| public void testPrimitiveArrayFieldSerialization() { |
| PrimitiveArray target = new PrimitiveArray(new long[] { 1L, 2L, 3L }); |
| assertEquals(target.getExpectedJson(), gson.toJson(target)); |
| } |
| |
| /** |
| * Tests that a class field with type Object can be serialized properly. |
| * See issue 54 |
| */ |
| public void testClassWithObjectFieldSerialization() { |
| ClassWithObjectField obj = new ClassWithObjectField(); |
| obj.member = "abc"; |
| String json = gson.toJson(obj); |
| assertTrue(json.contains("abc")); |
| } |
| |
| private static class ClassWithObjectField { |
| @SuppressWarnings("unused") |
| Object member; |
| } |
| |
| public void testInnerClassSerialization() { |
| Parent p = new Parent(); |
| Parent.Child c = p.new Child(); |
| String json = gson.toJson(c); |
| assertTrue(json.contains("value2")); |
| assertFalse(json.contains("value1")); |
| } |
| |
| public void testInnerClassDeserialization() { |
| final Parent p = new Parent(); |
| Gson gson = new GsonBuilder().registerTypeAdapter( |
| Parent.Child.class, new InstanceCreator<Parent.Child>() { |
| @Override public Parent.Child createInstance(Type type) { |
| return p.new Child(); |
| } |
| }).create(); |
| String json = "{'value2':3}"; |
| Parent.Child c = gson.fromJson(json, Parent.Child.class); |
| assertEquals(3, c.value2); |
| } |
| |
| private static class Parent { |
| @SuppressWarnings("unused") |
| int value1 = 1; |
| private class Child { |
| int value2 = 2; |
| } |
| } |
| |
| private static class ArrayOfArrays { |
| private final BagOfPrimitives[][] elements; |
| public ArrayOfArrays() { |
| elements = new BagOfPrimitives[3][2]; |
| for (int i = 0; i < elements.length; ++i) { |
| BagOfPrimitives[] row = elements[i]; |
| for (int j = 0; j < row.length; ++j) { |
| row[j] = new BagOfPrimitives(i+j, i*j, false, i+"_"+j); |
| } |
| } |
| } |
| public String getExpectedJson() { |
| StringBuilder sb = new StringBuilder("{\"elements\":["); |
| boolean first = true; |
| for (BagOfPrimitives[] row : elements) { |
| if (first) { |
| first = false; |
| } else { |
| sb.append(","); |
| } |
| boolean firstOfRow = true; |
| sb.append("["); |
| for (BagOfPrimitives element : row) { |
| if (firstOfRow) { |
| firstOfRow = false; |
| } else { |
| sb.append(","); |
| } |
| sb.append(element.getExpectedJson()); |
| } |
| sb.append("]"); |
| } |
| sb.append("]}"); |
| return sb.toString(); |
| } |
| } |
| |
| private static class ClassWithPrivateNoArgsConstructor { |
| public int a; |
| private ClassWithPrivateNoArgsConstructor() { |
| a = 10; |
| } |
| } |
| |
| /** |
| * In response to Issue 41 http://code.google.com/p/google-gson/issues/detail?id=41 |
| */ |
| public void testObjectFieldNamesWithoutQuotesDeserialization() { |
| String json = "{longValue:1,'booleanValue':true,\"stringValue\":'bar'}"; |
| BagOfPrimitives bag = gson.fromJson(json, BagOfPrimitives.class); |
| assertEquals(1, bag.longValue); |
| assertTrue(bag.booleanValue); |
| assertEquals("bar", bag.stringValue); |
| } |
| |
| public void testStringFieldWithNumberValueDeserialization() { |
| String json = "{\"stringValue\":1}"; |
| BagOfPrimitives bag = gson.fromJson(json, BagOfPrimitives.class); |
| assertEquals("1", bag.stringValue); |
| |
| json = "{\"stringValue\":1.5E+6}"; |
| bag = gson.fromJson(json, BagOfPrimitives.class); |
| assertEquals("1.5E+6", bag.stringValue); |
| |
| json = "{\"stringValue\":true}"; |
| bag = gson.fromJson(json, BagOfPrimitives.class); |
| assertEquals("true", bag.stringValue); |
| } |
| |
| /** |
| * Created to reproduce issue 140 |
| */ |
| public void testStringFieldWithEmptyValueSerialization() { |
| ClassWithEmptyStringFields target = new ClassWithEmptyStringFields(); |
| target.a = "5794749"; |
| String json = gson.toJson(target); |
| assertTrue(json.contains("\"a\":\"5794749\"")); |
| assertTrue(json.contains("\"b\":\"\"")); |
| assertTrue(json.contains("\"c\":\"\"")); |
| } |
| |
| /** |
| * Created to reproduce issue 140 |
| */ |
| public void testStringFieldWithEmptyValueDeserialization() { |
| String json = "{a:\"5794749\",b:\"\",c:\"\"}"; |
| ClassWithEmptyStringFields target = gson.fromJson(json, ClassWithEmptyStringFields.class); |
| assertEquals("5794749", target.a); |
| assertEquals("", target.b); |
| assertEquals("", target.c); |
| } |
| |
| private static class ClassWithEmptyStringFields { |
| String a = ""; |
| String b = ""; |
| String c = ""; |
| } |
| |
| public void testJsonObjectSerialization() { |
| Gson gson = new GsonBuilder().serializeNulls().create(); |
| JsonObject obj = new JsonObject(); |
| String json = gson.toJson(obj); |
| assertEquals("{}", json); |
| } |
| |
| /** |
| * Test for issue 215. |
| */ |
| public void testSingletonLists() { |
| Gson gson = new Gson(); |
| Product product = new Product(); |
| assertEquals("{\"attributes\":[],\"departments\":[]}", |
| gson.toJson(product)); |
| gson.fromJson(gson.toJson(product), Product.class); |
| |
| product.departments.add(new Department()); |
| assertEquals("{\"attributes\":[],\"departments\":[{\"name\":\"abc\",\"code\":\"123\"}]}", |
| gson.toJson(product)); |
| gson.fromJson(gson.toJson(product), Product.class); |
| |
| product.attributes.add("456"); |
| assertEquals("{\"attributes\":[\"456\"],\"departments\":[{\"name\":\"abc\",\"code\":\"123\"}]}", |
| gson.toJson(product)); |
| gson.fromJson(gson.toJson(product), Product.class); |
| } |
| |
| // http://code.google.com/p/google-gson/issues/detail?id=270 |
| public void testDateAsMapObjectField() { |
| HasObjectMap a = new HasObjectMap(); |
| a.map.put("date", new Date(0)); |
| if (JavaVersion.isJava9OrLater()) { |
| assertEquals("{\"map\":{\"date\":\"Dec 31, 1969, 4:00:00 PM\"}}", gson.toJson(a)); |
| } else { |
| assertEquals("{\"map\":{\"date\":\"Dec 31, 1969 4:00:00 PM\"}}", gson.toJson(a)); |
| } |
| } |
| |
| public class HasObjectMap { |
| Map<String, Object> map = new HashMap<>(); |
| } |
| |
| static final class Department { |
| public String name = "abc"; |
| public String code = "123"; |
| } |
| |
| static final class Product { |
| private List<String> attributes = new ArrayList<>(); |
| private List<Department> departments = new ArrayList<>(); |
| } |
| } |