1 package com.fasterxml.jackson.databind.ser; 2 3 import java.io.StringWriter; 4 import java.text.SimpleDateFormat; 5 import java.util.*; 6 7 import com.fasterxml.jackson.annotation.*; 8 import com.fasterxml.jackson.core.JsonGenerator; 9 import com.fasterxml.jackson.databind.*; 10 import com.fasterxml.jackson.databind.annotation.JsonSerialize; 11 import com.fasterxml.jackson.databind.introspect.ClassIntrospector; 12 13 /** 14 * Unit tests for checking handling of SerializationConfig. 15 */ 16 public class TestConfig 17 extends BaseMapTest 18 { 19 /* 20 /********************************************************** 21 /* Helper beans 22 /********************************************************** 23 */ 24 25 @JsonInclude(JsonInclude.Include.NON_DEFAULT) 26 @JsonSerialize(typing=JsonSerialize.Typing.STATIC) 27 final static class Config { } 28 29 final static class ConfigNone { } 30 31 static class AnnoBean { getX()32 public int getX() { return 1; } 33 @JsonProperty("y") getY()34 private int getY() { return 2; } 35 } 36 37 static class Indentable { 38 public int a = 3; 39 } 40 41 public static class SimpleBean { 42 public int x = 1; 43 } 44 45 /* 46 /********************************************************** 47 /* Main tests 48 /********************************************************** 49 */ 50 51 final static ObjectMapper MAPPER = new ObjectMapper(); 52 53 /* Test to verify that we don't overflow number of features; if we 54 * hit the limit, need to change implementation -- this test just 55 * gives low-water mark 56 */ testEnumIndexes()57 public void testEnumIndexes() 58 { 59 int max = 0; 60 61 for (SerializationFeature f : SerializationFeature.values()) { 62 max = Math.max(max, f.ordinal()); 63 } 64 if (max >= 31) { // 31 is actually ok; 32 not 65 fail("Max number of SerializationFeature enums reached: "+max); 66 } 67 } 68 testDefaults()69 public void testDefaults() 70 { 71 SerializationConfig cfg = MAPPER.getSerializationConfig(); 72 73 // First, defaults: 74 assertTrue(cfg.isEnabled(MapperFeature.USE_ANNOTATIONS)); 75 assertTrue(cfg.isEnabled(MapperFeature.AUTO_DETECT_GETTERS)); 76 assertTrue(cfg.isEnabled(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS)); 77 78 assertTrue(cfg.isEnabled(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)); 79 80 assertFalse(cfg.isEnabled(SerializationFeature.INDENT_OUTPUT)); 81 assertFalse(cfg.isEnabled(MapperFeature.USE_STATIC_TYPING)); 82 83 // since 1.3: 84 assertTrue(cfg.isEnabled(MapperFeature.AUTO_DETECT_IS_GETTERS)); 85 // since 1.4 86 87 assertTrue(cfg.isEnabled(SerializationFeature.FAIL_ON_EMPTY_BEANS)); 88 // since 1.5 89 assertTrue(cfg.isEnabled(MapperFeature.DEFAULT_VIEW_INCLUSION)); 90 91 } 92 testOverrideIntrospectors()93 public void testOverrideIntrospectors() 94 { 95 SerializationConfig cfg = MAPPER.getSerializationConfig(); 96 // and finally, ensure we could override introspectors 97 cfg = cfg.with((ClassIntrospector) null); // no way to verify tho 98 cfg = cfg.with((AnnotationIntrospector) null); 99 assertNull(cfg.getAnnotationIntrospector()); 100 } 101 testMisc()102 public void testMisc() 103 { 104 ObjectMapper m = new ObjectMapper(); 105 m.setDateFormat(null); // just to execute the code path 106 assertNotNull(m.getSerializationConfig().toString()); // ditto 107 } 108 testIndentation()109 public void testIndentation() throws Exception 110 { 111 Map<String,Integer> map = new HashMap<String,Integer>(); 112 map.put("a", Integer.valueOf(2)); 113 String result = MAPPER.writer().with(SerializationFeature.INDENT_OUTPUT) 114 .writeValueAsString(map); 115 // 02-Jun-2009, tatu: not really a clean way but... 116 String lf = getLF(); 117 assertEquals("{"+lf+" \"a\" : 2"+lf+"}", result); 118 } 119 testAnnotationsDisabled()120 public void testAnnotationsDisabled() throws Exception 121 { 122 // first: verify that annotation introspection is enabled by default 123 assertTrue(MAPPER.isEnabled(MapperFeature.USE_ANNOTATIONS)); 124 Map<String,Object> result = writeAndMap(MAPPER, new AnnoBean()); 125 assertEquals(2, result.size()); 126 127 ObjectMapper m2 = jsonMapperBuilder() 128 .configure(MapperFeature.USE_ANNOTATIONS, false) 129 .build(); 130 result = writeAndMap(m2, new AnnoBean()); 131 assertEquals(1, result.size()); 132 } 133 134 /** 135 * Test for verifying working of [JACKSON-191] 136 */ testProviderConfig()137 public void testProviderConfig() throws Exception 138 { 139 ObjectMapper mapper = new ObjectMapper(); 140 DefaultSerializerProvider prov = (DefaultSerializerProvider) mapper.getSerializerProvider(); 141 assertEquals(0, prov.cachedSerializersCount()); 142 // and then should get one constructed for: 143 Map<String,Object> result = this.writeAndMap(mapper, new AnnoBean()); 144 assertEquals(2, result.size()); 145 assertEquals(Integer.valueOf(1), result.get("x")); 146 assertEquals(Integer.valueOf(2), result.get("y")); 147 148 /* Note: it is 2 because we'll also get serializer for basic 'int', not 149 * just AnnoBean 150 */ 151 /* 12-Jan-2010, tatus: Actually, probably more, if and when we typing 152 * aspects are considered (depending on what is cached) 153 */ 154 int count = prov.cachedSerializersCount(); 155 if (count < 2) { 156 fail("Should have at least 2 cached serializers, got "+count); 157 } 158 prov.flushCachedSerializers(); 159 assertEquals(0, prov.cachedSerializersCount()); 160 } 161 162 // Test for [Issue#12] testIndentWithPassedGenerator()163 public void testIndentWithPassedGenerator() throws Exception 164 { 165 Indentable input = new Indentable(); 166 assertEquals("{\"a\":3}", MAPPER.writeValueAsString(input)); 167 String LF = getLF(); 168 String INDENTED = "{"+LF+" \"a\" : 3"+LF+"}"; 169 final ObjectWriter indentWriter = MAPPER.writer().with(SerializationFeature.INDENT_OUTPUT); 170 assertEquals(INDENTED, indentWriter.writeValueAsString(input)); 171 172 // [Issue#12] 173 StringWriter sw = new StringWriter(); 174 JsonGenerator jgen = MAPPER.createGenerator(sw); 175 indentWriter.writeValue(jgen, input); 176 jgen.close(); 177 assertEquals(INDENTED, sw.toString()); 178 179 // and also with ObjectMapper itself 180 sw = new StringWriter(); 181 ObjectMapper m2 = new ObjectMapper(); 182 m2.enable(SerializationFeature.INDENT_OUTPUT); 183 jgen = m2.createGenerator(sw); 184 m2.writeValue(jgen, input); 185 jgen.close(); 186 assertEquals(INDENTED, sw.toString()); 187 } 188 testNoAccessOverrides()189 public void testNoAccessOverrides() throws Exception 190 { 191 ObjectMapper m = jsonMapperBuilder() 192 .disable(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS) 193 .build(); 194 assertEquals("{\"x\":1}", m.writeValueAsString(new SimpleBean())); 195 } 196 testDateFormatConfig()197 public void testDateFormatConfig() throws Exception 198 { 199 ObjectMapper mapper = new ObjectMapper(); 200 TimeZone tz1 = TimeZone.getTimeZone("America/Los_Angeles"); 201 TimeZone tz2 = TimeZone.getTimeZone("Central Standard Time"); 202 203 // sanity checks 204 assertEquals(tz1, tz1); 205 assertEquals(tz2, tz2); 206 if (tz1.equals(tz2)) { 207 fail(); 208 } 209 210 mapper.setTimeZone(tz1); 211 assertEquals(tz1, mapper.getSerializationConfig().getTimeZone()); 212 assertEquals(tz1, mapper.getDeserializationConfig().getTimeZone()); 213 214 // also better stick via reader/writer as well 215 assertEquals(tz1, mapper.writer().getConfig().getTimeZone()); 216 assertEquals(tz1, mapper.reader().getConfig().getTimeZone()); 217 218 SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 219 f.setTimeZone(tz2); 220 mapper.setDateFormat(f); 221 222 // should not change the timezone tho 223 assertEquals(tz1, mapper.getSerializationConfig().getTimeZone()); 224 assertEquals(tz1, mapper.getDeserializationConfig().getTimeZone()); 225 assertEquals(tz1, mapper.writer().getConfig().getTimeZone()); 226 assertEquals(tz1, mapper.reader().getConfig().getTimeZone()); 227 } 228 getLF()229 private final static String getLF() { 230 return System.getProperty("line.separator"); 231 } 232 } 233