/core/src/test/java/org/jclouds/json/JsonTest.java
Java | 214 lines | 165 code | 29 blank | 20 comment | 15 complexity | 98bd958d263d8825bb3760cae8e8a160 MD5 | raw file
1/**
2 * Licensed to jclouds, Inc. (jclouds) under one or more
3 * contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. jclouds licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19package org.jclouds.json;
20
21import static com.google.common.io.BaseEncoding.base16;
22import static com.google.common.primitives.Bytes.asList;
23import static org.testng.Assert.assertEquals;
24
25import java.util.List;
26import java.util.Map;
27import java.util.Properties;
28
29import org.jclouds.json.config.GsonModule;
30import org.jclouds.json.config.GsonModule.DefaultExclusionStrategy;
31import org.testng.annotations.Test;
32
33import com.google.common.collect.ImmutableList;
34import com.google.common.collect.ImmutableMap;
35import com.google.common.collect.Maps;
36import com.google.gson.FieldAttributes;
37import com.google.inject.AbstractModule;
38import com.google.inject.Guice;
39import com.google.inject.TypeLiteral;
40
41@Test
42public class JsonTest {
43 private Json json = Guice.createInjector(new GsonModule()).getInstance(Json.class);
44
45 private static class ObjectNoDefaultConstructor {
46 private final String stringValue;
47 private final int intValue;
48
49 public ObjectNoDefaultConstructor(String stringValue, int intValue) {
50 this.stringValue = stringValue;
51 this.intValue = intValue;
52 }
53
54 @Override
55 public int hashCode() {
56 final int prime = 31;
57 int result = 1;
58 result = prime * result + intValue;
59 result = prime * result + ((stringValue == null) ? 0 : stringValue.hashCode());
60 return result;
61 }
62
63 @Override
64 public boolean equals(Object obj) {
65 if (this == obj)
66 return true;
67 if (obj == null)
68 return false;
69 if (getClass() != obj.getClass())
70 return false;
71 ObjectNoDefaultConstructor other = (ObjectNoDefaultConstructor) obj;
72 if (intValue != other.intValue)
73 return false;
74 if (stringValue == null) {
75 if (other.stringValue != null)
76 return false;
77 } else if (!stringValue.equals(other.stringValue))
78 return false;
79 return true;
80 }
81 }
82
83 public void testObjectNoDefaultConstructor() {
84 ObjectNoDefaultConstructor obj = new ObjectNoDefaultConstructor("foo", 1);
85 assertEquals(json.toJson(obj), "{\"stringValue\":\"foo\",\"intValue\":1}");
86 ObjectNoDefaultConstructor obj2 = json.fromJson(json.toJson(obj), ObjectNoDefaultConstructor.class);
87 assertEquals(obj2, obj);
88 assertEquals(json.toJson(obj2), json.toJson(obj));
89 }
90
91 static class ExcludeStringValue implements DefaultExclusionStrategy {
92 public boolean shouldSkipClass(Class<?> clazz) {
93 return false;
94 }
95
96 public boolean shouldSkipField(FieldAttributes f) {
97 return f.getName().equals("stringValue");
98 }
99 }
100
101 public void testExcluder() {
102 Json excluder = Guice.createInjector(new GsonModule(), new AbstractModule() {
103 protected void configure() {
104 bind(DefaultExclusionStrategy.class).to(ExcludeStringValue.class);
105 }
106 }).getInstance(Json.class);
107 ObjectNoDefaultConstructor obj = new ObjectNoDefaultConstructor("foo", 1);
108 assertEquals(excluder.toJson(obj), "{\"intValue\":1}");
109 }
110
111 private static class EnumInside {
112 private static enum Test {
113 FOO, BAR;
114 }
115
116 private Test enumValue;
117 }
118
119 private static class ByteList {
120 List<Byte> checksum;
121 }
122
123 public void testByteList() {
124 ByteList bl = new ByteList();
125 bl.checksum = asList(base16().lowerCase().decode("1dda05ed139664f1f89b9dec482b77c0"));
126 assertEquals(json.toJson(bl), "{\"checksum\":\"1dda05ed139664f1f89b9dec482b77c0\"}");
127 assertEquals(json.fromJson(json.toJson(bl), ByteList.class).checksum, bl.checksum);
128 }
129
130 public void testPropertiesSerializesDefaults() {
131 Properties props = new Properties();
132 props.put("string", "string");
133 props.put("number", "1");
134 props.put("boolean", "true");
135 assertEquals(json.toJson(props), "{\"string\":\"string\",\"boolean\":\"true\",\"number\":\"1\"}");
136 Properties props3 = new Properties(props);
137 assertEquals(json.toJson(props3), "{\"string\":\"string\",\"boolean\":\"true\",\"number\":\"1\"}");
138 Properties props2 = json.fromJson(json.toJson(props), Properties.class);
139 assertEquals(props2, props);
140 assertEquals(json.toJson(props2), json.toJson(props));
141 }
142
143 public void testMapStringObjectWithAllValidValuesOneDeep() {
144 Map<String, Object> map = Maps.newHashMap();
145 map.put("string", "string");
146 map.put("number", 1.0);
147 map.put("boolean", true);
148 map.put("map", ImmutableMap.of("key", "value"));
149 map.put("list", ImmutableList.of("key", "value"));
150 assertEquals(json.toJson(map),
151 "{\"string\":\"string\",\"map\":{\"key\":\"value\"},\"list\":[\"key\",\"value\"],\"boolean\":true,\"number\":1.0}");
152 Map<String, Object> map2 = json.fromJson(json.toJson(map), new TypeLiteral<Map<String, Object>>() {
153 }.getType());
154 assertEquals(map2, map);
155 assertEquals(json.toJson(map2), json.toJson(map));
156 }
157
158 public void testMapStringObjectWithNumericalKeysConvertToStrings() {
159 Map<String, Object> map = ImmutableMap.<String, Object> of("map", ImmutableMap.of(1, "value"));
160 assertEquals(json.toJson(map), "{\"map\":{\"1\":\"value\"}}");
161 Map<String, Object> map2 = json.fromJson(json.toJson(map), new TypeLiteral<Map<String, Object>>() {
162 }.getType());
163 // note conversion.. ensures valid
164 assertEquals(map2, ImmutableMap.<String, Object> of("map", ImmutableMap.of("1", "value")));
165 assertEquals(json.toJson(map2), json.toJson(map));
166 }
167
168 public void testMapStringObjectWithBooleanKeysConvertToStrings() {
169 Map<String, Object> map = ImmutableMap.<String, Object> of("map", ImmutableMap.of(true, "value"));
170 assertEquals(json.toJson(map), "{\"map\":{\"true\":\"value\"}}");
171 Map<String, Object> map2 = json.fromJson(json.toJson(map), new TypeLiteral<Map<String, Object>>() {
172 }.getType());
173 // note conversion.. ensures valid
174 assertEquals(map2, ImmutableMap.<String, Object> of("map", ImmutableMap.of("true", "value")));
175 assertEquals(json.toJson(map2), json.toJson(map));
176 }
177
178 public void testDeserializeEnum() {
179 assertEquals(json.fromJson("{enumValue : \"FOO\"}", EnumInside.class).enumValue, EnumInside.Test.FOO);
180 }
181
182 @Test(expectedExceptions = IllegalArgumentException.class)
183 public void testDeserializeEnumWhenBadValue() {
184 assertEquals(json.fromJson("{enumValue : \"s\"}", EnumInside.class).enumValue, EnumInside.Test.FOO);
185 }
186
187 private static class EnumInsideWithParser {
188 private static enum Test {
189 FOO, BAR, UNRECOGNIZED;
190
191 @SuppressWarnings("unused")
192 public static Test fromValue(String state) {
193 try {
194 return valueOf(state);
195 } catch (IllegalArgumentException e) {
196 return UNRECOGNIZED;
197 }
198 }
199 }
200
201 private Test enumValue;
202 }
203
204 public void testDeserializeEnumWithParser() {
205 assertEquals(json.fromJson("{enumValue : \"FOO\"}", EnumInsideWithParser.class).enumValue,
206 EnumInsideWithParser.Test.FOO);
207 }
208
209 public void testDeserializeEnumWithParserAndBadValue() {
210 assertEquals(json.fromJson("{enumValue : \"sd\"}", EnumInsideWithParser.class).enumValue,
211 EnumInsideWithParser.Test.UNRECOGNIZED);
212 }
213
214}