package com.fasterxml.jackson.databind.ser;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.*;
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.introspect.ClassIntrospector;
/**
* Unit tests for checking handling of SerializationConfig.
*/
public class TestConfig
extends BaseMapTest
{
/*
/**********************************************************
/* Helper beans
/**********************************************************
*/
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
@JsonSerialize(typing=JsonSerialize.Typing.STATIC)
final static class Config { }
final static class ConfigNone { }
static class AnnoBean {
public int getX() { return 1; }
@JsonProperty("y")
private int getY() { return 2; }
}
static class Indentable {
public int a = 3;
}
public static class SimpleBean {
public int x = 1;
}
/*
/**********************************************************
/* Main tests
/**********************************************************
*/
final static ObjectMapper MAPPER = new ObjectMapper();
/* Test to verify that we don't overflow number of features; if we
* hit the limit, need to change implementation -- this test just
* gives low-water mark
*/
public void testEnumIndexes()
{
int max = 0;
for (SerializationFeature f : SerializationFeature.values()) {
max = Math.max(max, f.ordinal());
}
if (max >= 31) { // 31 is actually ok; 32 not
fail("Max number of SerializationFeature enums reached: "+max);
}
}
public void testDefaults()
{
SerializationConfig cfg = MAPPER.getSerializationConfig();
// First, defaults:
assertTrue(cfg.isEnabled(MapperFeature.USE_ANNOTATIONS));
assertTrue(cfg.isEnabled(MapperFeature.AUTO_DETECT_GETTERS));
assertTrue(cfg.isEnabled(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS));
assertTrue(cfg.isEnabled(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS));
assertFalse(cfg.isEnabled(SerializationFeature.INDENT_OUTPUT));
assertFalse(cfg.isEnabled(MapperFeature.USE_STATIC_TYPING));
// since 1.3:
assertTrue(cfg.isEnabled(MapperFeature.AUTO_DETECT_IS_GETTERS));
// since 1.4
assertTrue(cfg.isEnabled(SerializationFeature.FAIL_ON_EMPTY_BEANS));
// since 1.5
assertTrue(cfg.isEnabled(MapperFeature.DEFAULT_VIEW_INCLUSION));
}
public void testOverrideIntrospectors()
{
SerializationConfig cfg = MAPPER.getSerializationConfig();
// and finally, ensure we could override introspectors
cfg = cfg.with((ClassIntrospector) null); // no way to verify tho
cfg = cfg.with((AnnotationIntrospector) null);
assertNull(cfg.getAnnotationIntrospector());
}
public void testMisc()
{
ObjectMapper m = new ObjectMapper();
m.setDateFormat(null); // just to execute the code path
assertNotNull(m.getSerializationConfig().toString()); // ditto
}
public void testIndentation() throws Exception
{
Map<String,Integer> map = new HashMap<String,Integer>();
map.put("a", Integer.valueOf(2));
String result = MAPPER.writer().with(SerializationFeature.INDENT_OUTPUT)
.writeValueAsString(map);
// 02-Jun-2009, tatu: not really a clean way but...
String lf = getLF();
assertEquals("{"+lf+" \"a\" : 2"+lf+"}", result);
}
public void testAnnotationsDisabled() throws Exception
{
// first: verify that annotation introspection is enabled by default
assertTrue(MAPPER.isEnabled(MapperFeature.USE_ANNOTATIONS));
Map<String,Object> result = writeAndMap(MAPPER, new AnnoBean());
assertEquals(2, result.size());
ObjectMapper m2 = new ObjectMapper();
m2.configure(MapperFeature.USE_ANNOTATIONS, false);
result = writeAndMap(m2, new AnnoBean());
assertEquals(1, result.size());
}
/**
* Test for verifying working of [JACKSON-191]
*/
public void testProviderConfig() throws Exception
{
ObjectMapper mapper = new ObjectMapper();
DefaultSerializerProvider prov = (DefaultSerializerProvider) mapper.getSerializerProvider();
assertEquals(0, prov.cachedSerializersCount());
// and then should get one constructed for:
Map<String,Object> result = this.writeAndMap(mapper, new AnnoBean());
assertEquals(2, result.size());
assertEquals(Integer.valueOf(1), result.get("x"));
assertEquals(Integer.valueOf(2), result.get("y"));
/* Note: it is 2 because we'll also get serializer for basic 'int', not
* just AnnoBean
*/
/* 12-Jan-2010, tatus: Actually, probably more, if and when we typing
* aspects are considered (depending on what is cached)
*/
int count = prov.cachedSerializersCount();
if (count < 2) {
fail("Should have at least 2 cached serializers, got "+count);
}
prov.flushCachedSerializers();
assertEquals(0, prov.cachedSerializersCount());
}
// Test for [Issue#12]
public void testIndentWithPassedGenerator() throws Exception
{
Indentable input = new Indentable();
assertEquals("{\"a\":3}", MAPPER.writeValueAsString(input));
String LF = getLF();
String INDENTED = "{"+LF+" \"a\" : 3"+LF+"}";
final ObjectWriter indentWriter = MAPPER.writer().with(SerializationFeature.INDENT_OUTPUT);
assertEquals(INDENTED, indentWriter.writeValueAsString(input));
// [Issue#12]
StringWriter sw = new StringWriter();
JsonGenerator jgen = MAPPER.getFactory().createGenerator(sw);
indentWriter.writeValue(jgen, input);
jgen.close();
assertEquals(INDENTED, sw.toString());
// and also with ObjectMapper itself
sw = new StringWriter();
ObjectMapper m2 = new ObjectMapper();
m2.enable(SerializationFeature.INDENT_OUTPUT);
jgen = m2.getFactory().createGenerator(sw);
m2.writeValue(jgen, input);
jgen.close();
assertEquals(INDENTED, sw.toString());
}
public void testNoAccessOverrides() throws Exception
{
ObjectMapper m = new ObjectMapper();
m.disable(MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS);
assertEquals("{\"x\":1}", m.writeValueAsString(new SimpleBean()));
}
public void testDateFormatConfig() throws Exception
{
ObjectMapper mapper = new ObjectMapper();
TimeZone tz1 = TimeZone.getTimeZone("America/Los_Angeles");
TimeZone tz2 = TimeZone.getTimeZone("Central Standard Time");
// sanity checks
assertEquals(tz1, tz1);
assertEquals(tz2, tz2);
if (tz1.equals(tz2)) {
fail();
}
mapper.setTimeZone(tz1);
assertEquals(tz1, mapper.getSerializationConfig().getTimeZone());
assertEquals(tz1, mapper.getDeserializationConfig().getTimeZone());
// also better stick via reader/writer as well
assertEquals(tz1, mapper.writer().getConfig().getTimeZone());
assertEquals(tz1, mapper.reader().getConfig().getTimeZone());
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
f.setTimeZone(tz2);
mapper.setDateFormat(f);
// should not change the timezone tho
assertEquals(tz1, mapper.getSerializationConfig().getTimeZone());
assertEquals(tz1, mapper.getDeserializationConfig().getTimeZone());
assertEquals(tz1, mapper.writer().getConfig().getTimeZone());
assertEquals(tz1, mapper.reader().getConfig().getTimeZone());
}
private final static String getLF() {
return System.getProperty("line.separator");
}
}