blob: 7679745bd37a7b3d95a5dd70cd1cf7d99abe7ef8 [file] [log] [blame]
package com.fasterxml.jackson.databind.deser;
import java.io.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import org.junit.Assert;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
/**
* Unit tests for verifying handling of simple basic non-structured
* types; primitives (and/or their wrappers), Strings.
*/
public class JDKScalarsTest
extends BaseMapTest
{
final static String NAN_STRING = "NaN";
final static class BooleanBean {
boolean _v;
void setV(boolean v) { _v = v; }
}
static class BooleanWrapper {
public Boolean wrapper;
public boolean primitive;
protected Boolean ctor;
@JsonCreator
public BooleanWrapper(@JsonProperty("ctor") Boolean foo) {
ctor = foo;
}
}
static class IntBean {
int _v;
void setV(int v) { _v = v; }
}
final static class DoubleBean {
double _v;
void setV(double v) { _v = v; }
}
final static class FloatBean {
float _v;
void setV(float v) { _v = v; }
}
final static class CharacterBean {
char _v;
void setV(char v) { _v = v; }
char getV() { return _v; }
}
final static class CharacterWrapperBean {
Character _v;
void setV(Character v) { _v = v; }
Character getV() { return _v; }
}
/**
* Also, let's ensure that it's ok to override methods.
*/
static class IntBean2
extends IntBean
{
@Override
void setV(int v2) { super.setV(v2+1); }
}
static class PrimitivesBean
{
public boolean booleanValue = true;
public byte byteValue = 3;
public char charValue = 'a';
public short shortValue = 37;
public int intValue = 1;
public long longValue = 100L;
public float floatValue = 0.25f;
public double doubleValue = -1.0;
}
static class WrappersBean
{
public Boolean booleanValue;
public Byte byteValue;
public Character charValue;
public Short shortValue;
public Integer intValue;
public Long longValue;
public Float floatValue;
public Double doubleValue;
}
private final ObjectMapper MAPPER = new ObjectMapper();
/*
/**********************************************************
/* Scalar tests for boolean
/**********************************************************
*/
public void testBooleanPrimitive() throws Exception
{
// first, simple case:
BooleanBean result = MAPPER.readValue(new StringReader("{\"v\":true}"), BooleanBean.class);
assertTrue(result._v);
result = MAPPER.readValue(new StringReader("{\"v\":null}"), BooleanBean.class);
assertNotNull(result);
assertFalse(result._v);
// [databind#1480]
result = MAPPER.readValue(new StringReader("{\"v\":1}"), BooleanBean.class);
assertNotNull(result);
assertTrue(result._v);
// should work with arrays too..
boolean[] array = MAPPER.readValue(new StringReader("[ null ]"), boolean[].class);
assertNotNull(array);
assertEquals(1, array.length);
assertFalse(array[0]);
}
public void testBooleanPrimitiveArrayUnwrap() throws Exception
{
// [databind#381]
final ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
BooleanBean result = mapper.readValue(new StringReader("{\"v\":[true]}"), BooleanBean.class);
assertTrue(result._v);
try {
mapper.readValue(new StringReader("[{\"v\":[true,true]}]"), BooleanBean.class);
fail("Did not throw exception while reading a value from a multi value array with UNWRAP_SINGLE_VALUE_ARRAY feature enabled");
} catch (JsonMappingException exp) {
//threw exception as required
}
result = mapper.readValue(new StringReader("{\"v\":[null]}"), BooleanBean.class);
assertNotNull(result);
assertFalse(result._v);
result = mapper.readValue(new StringReader("[{\"v\":[null]}]"), BooleanBean.class);
assertNotNull(result);
assertFalse(result._v);
boolean[] array = mapper.readValue(new StringReader("[ [ null ] ]"), boolean[].class);
assertNotNull(array);
assertEquals(1, array.length);
assertFalse(array[0]);
}
/**
* Simple unit test to verify that we can map boolean values to
* java.lang.Boolean.
*/
public void testBooleanWrapper() throws Exception
{
Boolean result = MAPPER.readValue(new StringReader("true"), Boolean.class);
assertEquals(Boolean.TRUE, result);
result = MAPPER.readValue(new StringReader("false"), Boolean.class);
assertEquals(Boolean.FALSE, result);
// should accept ints too, (0 == false, otherwise true)
result = MAPPER.readValue("0", Boolean.class);
assertEquals(Boolean.FALSE, result);
result = MAPPER.readValue("1", Boolean.class);
assertEquals(Boolean.TRUE, result);
}
// Test for verifying that Long values are coerced to boolean correctly as well
public void testLongToBoolean() throws Exception
{
long value = 1L + Integer.MAX_VALUE;
BooleanWrapper b = MAPPER.readValue("{\"primitive\" : "+value+", \"wrapper\":"+value+", \"ctor\":"+value+"}",
BooleanWrapper.class);
assertEquals(Boolean.TRUE, b.wrapper);
assertTrue(b.primitive);
assertEquals(Boolean.TRUE, b.ctor);
// but ensure we can also get `false`
b = MAPPER.readValue("{\"primitive\" : 0 , \"wrapper\":0, \"ctor\":0}",
BooleanWrapper.class);
assertEquals(Boolean.FALSE, b.wrapper);
assertFalse(b.primitive);
assertEquals(Boolean.FALSE, b.ctor);
}
/*
/**********************************************************
/* Scalar tests for integral types
/**********************************************************
*/
public void testIntPrimitive() throws Exception
{
// first, simple case:
IntBean result = MAPPER.readValue(new StringReader("{\"v\":3}"), IntBean.class);
assertEquals(3, result._v);
result = MAPPER.readValue(new StringReader("{\"v\":null}"), IntBean.class);
assertNotNull(result);
assertEquals(0, result._v);
// should work with arrays too..
int[] array = MAPPER.readValue(new StringReader("[ null ]"), int[].class);
assertNotNull(array);
assertEquals(1, array.length);
assertEquals(0, array[0]);
// [Issue#381]
final ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
try {
mapper.readValue(new StringReader("{\"v\":[3]}"), IntBean.class);
fail("Did not throw exception when reading a value from a single value array with the UNWRAP_SINGLE_VALUE_ARRAYS feature disabled");
} catch (JsonMappingException exp) {
//Correctly threw exception
}
mapper.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
result = mapper.readValue(new StringReader("{\"v\":[3]}"), IntBean.class);
assertEquals(3, result._v);
result = mapper.readValue(new StringReader("[{\"v\":[3]}]"), IntBean.class);
assertEquals(3, result._v);
try {
mapper.readValue("[{\"v\":[3,3]}]", IntBean.class);
fail("Did not throw exception while reading a value from a multi value array with UNWRAP_SINGLE_VALUE_ARRAY feature enabled");
} catch (JsonMappingException exp) {
//threw exception as required
}
result = mapper.readValue("{\"v\":[null]}", IntBean.class);
assertNotNull(result);
assertEquals(0, result._v);
array = mapper.readValue("[ [ null ] ]", int[].class);
assertNotNull(array);
assertEquals(1, array.length);
assertEquals(0, array[0]);
}
public void testByteWrapper() throws Exception
{
Byte result = MAPPER.readValue(new StringReader(" -42\t"), Byte.class);
assertEquals(Byte.valueOf((byte)-42), result);
// Also: should be able to coerce floats, strings:
result = MAPPER.readValue(new StringReader(" \"-12\""), Byte.class);
assertEquals(Byte.valueOf((byte)-12), result);
result = MAPPER.readValue(new StringReader(" 39.07"), Byte.class);
assertEquals(Byte.valueOf((byte)39), result);
}
public void testShortWrapper() throws Exception
{
Short result = MAPPER.readValue(new StringReader("37"), Short.class);
assertEquals(Short.valueOf((short)37), result);
// Also: should be able to coerce floats, strings:
result = MAPPER.readValue(new StringReader(" \"-1009\""), Short.class);
assertEquals(Short.valueOf((short)-1009), result);
result = MAPPER.readValue(new StringReader("-12.9"), Short.class);
assertEquals(Short.valueOf((short)-12), result);
}
public void testCharacterWrapper() throws Exception
{
// First: canonical value is 1-char string
Character result = MAPPER.readValue(new StringReader("\"a\""), Character.class);
assertEquals(Character.valueOf('a'), result);
// But can also pass in ascii code
result = MAPPER.readValue(new StringReader(" "+((int) 'X')), Character.class);
assertEquals(Character.valueOf('X'), result);
final CharacterWrapperBean wrapper = MAPPER.readValue(new StringReader("{\"v\":null}"), CharacterWrapperBean.class);
assertNotNull(wrapper);
assertNull(wrapper.getV());
final ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES);
try {
mapper.readValue("{\"v\":null}", CharacterBean.class);
fail("Attempting to deserialize a 'null' JSON reference into a 'char' property did not throw an exception");
} catch (JsonMappingException exp) {
//Exception thrown as required
}
mapper.disable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES);
final CharacterBean charBean = MAPPER.readValue(new StringReader("{\"v\":null}"), CharacterBean.class);
assertNotNull(wrapper);
assertEquals('\u0000', charBean.getV());
}
public void testIntWrapper() throws Exception
{
Integer result = MAPPER.readValue(new StringReader(" -42\t"), Integer.class);
assertEquals(Integer.valueOf(-42), result);
// Also: should be able to coerce floats, strings:
result = MAPPER.readValue(new StringReader(" \"-1200\""), Integer.class);
assertEquals(Integer.valueOf(-1200), result);
result = MAPPER.readValue(new StringReader(" 39.07"), Integer.class);
assertEquals(Integer.valueOf(39), result);
}
public void testLongWrapper() throws Exception
{
Long result = MAPPER.readValue(new StringReader("12345678901"), Long.class);
assertEquals(Long.valueOf(12345678901L), result);
// Also: should be able to coerce floats, strings:
result = MAPPER.readValue(new StringReader(" \"-9876\""), Long.class);
assertEquals(Long.valueOf(-9876), result);
result = MAPPER.readValue(new StringReader("1918.3"), Long.class);
assertEquals(Long.valueOf(1918), result);
}
/**
* Beyond simple case, let's also ensure that method overriding works as
* expected.
*/
public void testIntWithOverride() throws Exception
{
IntBean2 result = MAPPER.readValue(new StringReader("{\"v\":8}"), IntBean2.class);
assertEquals(9, result._v);
}
/*
/**********************************************************
/* Scalar tests for floating point types
/**********************************************************
*/
public void testDoublePrimitive() throws Exception
{
// first, simple case:
// bit tricky with binary fps but...
final double value = 0.016;
DoubleBean result = MAPPER.readValue(new StringReader("{\"v\":"+value+"}"), DoubleBean.class);
assertEquals(value, result._v);
// then [JACKSON-79]:
result = MAPPER.readValue(new StringReader("{\"v\":null}"), DoubleBean.class);
assertNotNull(result);
assertEquals(0.0, result._v);
// should work with arrays too..
double[] array = MAPPER.readValue(new StringReader("[ null ]"), double[].class);
assertNotNull(array);
assertEquals(1, array.length);
assertEquals(0.0, array[0]);
}
/* Note: dealing with floating-point values is tricky; not sure if
* we can really use equality tests here... JDK does have decent
* conversions though, to retain accuracy and round-trippability.
* But still...
*/
public void testFloatWrapper() throws Exception
{
// Also: should be able to coerce floats, strings:
String[] STRS = new String[] {
"1.0", "0.0", "-0.3", "0.7", "42.012", "-999.0", NAN_STRING
};
for (String str : STRS) {
Float exp = Float.valueOf(str);
Float result;
if (NAN_STRING != str) {
// First, as regular floating point value
result = MAPPER.readValue(new StringReader(str), Float.class);
assertEquals(exp, result);
}
// and then as coerced String:
result = MAPPER.readValue(new StringReader(" \""+str+"\""), Float.class);
assertEquals(exp, result);
}
}
public void testDoubleWrapper() throws Exception
{
// Also: should be able to coerce doubles, strings:
String[] STRS = new String[] {
"1.0", "0.0", "-0.3", "0.7", "42.012", "-999.0", NAN_STRING
};
for (String str : STRS) {
Double exp = Double.valueOf(str);
Double result;
// First, as regular double value
if (NAN_STRING != str) {
result = MAPPER.readValue(str, Double.class);
assertEquals(exp, result);
}
// and then as coerced String:
result = MAPPER.readValue(new StringReader(" \""+str+"\""), Double.class);
assertEquals(exp, result);
}
}
public void testDoubleAsArray() throws Exception
{
final ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
final double value = 0.016;
try {
mapper.readValue(new StringReader("{\"v\":[" + value + "]}"), DoubleBean.class);
fail("Did not throw exception when reading a value from a single value array with the UNWRAP_SINGLE_VALUE_ARRAYS feature disabled");
} catch (JsonMappingException exp) {
//Correctly threw exception
}
mapper.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
DoubleBean result = mapper.readValue(new StringReader("{\"v\":[" + value + "]}"),
DoubleBean.class);
assertEquals(value, result._v);
result = mapper.readValue(new StringReader("[{\"v\":[" + value + "]}]"), DoubleBean.class);
assertEquals(value, result._v);
try {
mapper.readValue(new StringReader("[{\"v\":[" + value + "," + value + "]}]"), DoubleBean.class);
fail("Did not throw exception while reading a value from a multi value array with UNWRAP_SINGLE_VALUE_ARRAY feature enabled");
} catch (JsonMappingException exp) {
//threw exception as required
}
result = mapper.readValue(new StringReader("{\"v\":[null]}"), DoubleBean.class);
assertNotNull(result);
assertEquals(0d, result._v);
double[] array = mapper.readValue(new StringReader("[ [ null ] ]"), double[].class);
assertNotNull(array);
assertEquals(1, array.length);
assertEquals(0d, array[0]);
}
public void testDoublePrimitiveNonNumeric() throws Exception
{
// first, simple case:
// bit tricky with binary fps but...
double value = Double.POSITIVE_INFINITY;
DoubleBean result = MAPPER.readValue(new StringReader("{\"v\":\""+value+"\"}"), DoubleBean.class);
assertEquals(value, result._v);
// should work with arrays too..
double[] array = MAPPER.readValue(new StringReader("[ \"Infinity\" ]"), double[].class);
assertNotNull(array);
assertEquals(1, array.length);
assertEquals(Double.POSITIVE_INFINITY, array[0]);
}
public void testFloatPrimitiveNonNumeric() throws Exception
{
// bit tricky with binary fps but...
float value = Float.POSITIVE_INFINITY;
FloatBean result = MAPPER.readValue(new StringReader("{\"v\":\""+value+"\"}"), FloatBean.class);
assertEquals(value, result._v);
// should work with arrays too..
float[] array = MAPPER.readValue(new StringReader("[ \"Infinity\" ]"), float[].class);
assertNotNull(array);
assertEquals(1, array.length);
assertEquals(Float.POSITIVE_INFINITY, array[0]);
}
/*
/**********************************************************
/* Scalar tests, other
/**********************************************************
*/
public void testEmptyToNullCoercionForPrimitives() throws Exception {
_testEmptyToNullCoercion(int.class, Integer.valueOf(0));
_testEmptyToNullCoercion(long.class, Long.valueOf(0));
_testEmptyToNullCoercion(double.class, Double.valueOf(0.0));
_testEmptyToNullCoercion(float.class, Float.valueOf(0.0f));
}
private void _testEmptyToNullCoercion(Class<?> primType, Object emptyValue) throws Exception
{
final String EMPTY = "\"\"";
// as per [databind#1095] should only allow coercion from empty String,
// if `null` is acceptable
ObjectReader intR = MAPPER.readerFor(primType);
assertEquals(emptyValue, intR.readValue(EMPTY));
try {
intR.with(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES)
.readValue("\"\"");
fail("Should not have passed");
} catch (JsonMappingException e) {
verifyException(e, "Can not map Empty String");
}
}
public void testBase64Variants() throws Exception
{
final byte[] INPUT = "abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890X".getBytes("UTF-8");
// default encoding is "MIME, no linefeeds", so:
Assert.assertArrayEquals(INPUT, MAPPER.readValue(
quote("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY3ODkwYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY3ODkwWA=="),
byte[].class));
ObjectReader reader = MAPPER.readerFor(byte[].class);
Assert.assertArrayEquals(INPUT, (byte[]) reader.with(Base64Variants.MIME_NO_LINEFEEDS).readValue(
quote("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY3ODkwYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY3ODkwWA=="
)));
// but others should be slightly different
Assert.assertArrayEquals(INPUT, (byte[]) reader.with(Base64Variants.MIME).readValue(
quote("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY3ODkwYWJjZGVmZ2hpamtsbW5vcHFyc3R1\\ndnd4eXoxMjM0NTY3ODkwWA=="
)));
Assert.assertArrayEquals(INPUT, (byte[]) reader.with(Base64Variants.MODIFIED_FOR_URL).readValue(
quote("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY3ODkwYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY3ODkwWA"
)));
// PEM mandates 64 char lines:
Assert.assertArrayEquals(INPUT, (byte[]) reader.with(Base64Variants.PEM).readValue(
quote("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY3ODkwYWJjZGVmZ2hpamts\\nbW5vcHFyc3R1dnd4eXoxMjM0NTY3ODkwWA=="
)));
}
/*
/**********************************************************
/* Simple non-primitive types
/**********************************************************
*/
public void testSingleString() throws Exception
{
String value = "FOO!";
String result = MAPPER.readValue(new StringReader("\""+value+"\""), String.class);
assertEquals(value, result);
}
public void testSingleStringWrapped() throws Exception
{
final ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
String value = "FOO!";
try {
mapper.readValue(new StringReader("[\""+value+"\"]"), String.class);
fail("Exception not thrown when attempting to unwrap a single value 'String' array into a simple String");
} catch (JsonMappingException exp) {
//exception thrown correctly
}
mapper.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
try {
mapper.readValue(new StringReader("[\""+value+"\",\""+value+"\"]"), String.class);
fail("Exception not thrown when attempting to unwrap a single value 'String' array that contained more than one value into a simple String");
} catch (JsonMappingException exp) {
//exception thrown correctly
}
String result = mapper.readValue(new StringReader("[\""+value+"\"]"), String.class);
assertEquals(value, result);
}
public void testBigDecimal() throws Exception
{
final ObjectMapper mapper = objectMapper();
mapper.disable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
BigDecimal value = new BigDecimal("0.001");
BigDecimal result = mapper.readValue(value.toString(), BigDecimal.class);
assertEquals(value, result);
try {
mapper.readValue("[" + value.toString() + "]", BigDecimal.class);
fail("Exception was not thrown when attempting to read a single value array of BigDecimal when UNWRAP_SINGLE_VALUE_ARRAYS feature is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
mapper.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
result = mapper.readValue("[" + value.toString() + "]", BigDecimal.class);
assertEquals(value, result);
try {
mapper.readValue("[" + value.toString() + "," + value.toString() + "]", BigDecimal.class);
fail("Exception was not thrown when attempting to read a muti value array of BigDecimal when UNWRAP_SINGLE_VALUE_ARRAYS feature is enabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
}
public void testBigInteger() throws Exception
{
final ObjectMapper mapper = objectMapper();
mapper.disable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
BigInteger value = new BigInteger("-1234567890123456789012345567809");
BigInteger result = mapper.readValue(new StringReader(value.toString()), BigInteger.class);
assertEquals(value, result);
//Issue#381
try {
mapper.readValue("[" + value.toString() + "]", BigInteger.class);
fail("Exception was not thrown when attempting to read a single value array of BigInteger when UNWRAP_SINGLE_VALUE_ARRAYS feature is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
mapper.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
result = mapper.readValue("[" + value.toString() + "]", BigInteger.class);
assertEquals(value, result);
try {
mapper.readValue("[" + value.toString() + "," + value.toString() + "]", BigInteger.class);
fail("Exception was not thrown when attempting to read a muti value array of BigInteger when UNWRAP_SINGLE_VALUE_ARRAYS feature is enabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
}
/*
/**********************************************************
/* Sequence tests
/**********************************************************
*/
/**
* Then a unit test to verify that we can conveniently bind sequence of
* space-separate simple values
*/
public void testSequenceOfInts() throws Exception
{
final int NR_OF_INTS = 100;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < NR_OF_INTS; ++i) {
sb.append(" ");
sb.append(i);
}
JsonParser jp = MAPPER.getFactory().createParser(sb.toString());
for (int i = 0; i < NR_OF_INTS; ++i) {
Integer result = MAPPER.readValue(jp, Integer.class);
assertEquals(Integer.valueOf(i), result);
}
jp.close();
}
/*
/**********************************************************
/* Single-element as array tests
/**********************************************************
*/
// [databind#381]
public void testSingleElementScalarArrays() throws Exception {
final int intTest = 932832;
final double doubleTest = 32.3234;
final long longTest = 2374237428374293423L;
final short shortTest = (short) intTest;
final float floatTest = 84.3743f;
final byte byteTest = (byte) 43;
final char charTest = 'c';
final ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
final int intValue = mapper.readValue(asArray(intTest), Integer.TYPE);
assertEquals(intTest, intValue);
final Integer integerWrapperValue = mapper.readValue(asArray(Integer.valueOf(intTest)), Integer.class);
assertEquals(Integer.valueOf(intTest), integerWrapperValue);
final double doubleValue = mapper.readValue(asArray(doubleTest), Double.class);
assertEquals(doubleTest, doubleValue);
final Double doubleWrapperValue = mapper.readValue(asArray(Double.valueOf(doubleTest)), Double.class);
assertEquals(Double.valueOf(doubleTest), doubleWrapperValue);
final long longValue = mapper.readValue(asArray(longTest), Long.TYPE);
assertEquals(longTest, longValue);
final Long longWrapperValue = mapper.readValue(asArray(Long.valueOf(longTest)), Long.class);
assertEquals(Long.valueOf(longTest), longWrapperValue);
final short shortValue = mapper.readValue(asArray(shortTest), Short.TYPE);
assertEquals(shortTest, shortValue);
final Short shortWrapperValue = mapper.readValue(asArray(Short.valueOf(shortTest)), Short.class);
assertEquals(Short.valueOf(shortTest), shortWrapperValue);
final float floatValue = mapper.readValue(asArray(floatTest), Float.TYPE);
assertEquals(floatTest, floatValue);
final Float floatWrapperValue = mapper.readValue(asArray(Float.valueOf(floatTest)), Float.class);
assertEquals(Float.valueOf(floatTest), floatWrapperValue);
final byte byteValue = mapper.readValue(asArray(byteTest), Byte.TYPE);
assertEquals(byteTest, byteValue);
final Byte byteWrapperValue = mapper.readValue(asArray(Byte.valueOf(byteTest)), Byte.class);
assertEquals(Byte.valueOf(byteTest), byteWrapperValue);
final char charValue = mapper.readValue(asArray(quote(String.valueOf(charTest))), Character.TYPE);
assertEquals(charTest, charValue);
final Character charWrapperValue = mapper.readValue(asArray(quote(String.valueOf(charTest))), Character.class);
assertEquals(Character.valueOf(charTest), charWrapperValue);
final boolean booleanTrueValue = mapper.readValue(asArray(true), Boolean.TYPE);
assertTrue(booleanTrueValue);
final boolean booleanFalseValue = mapper.readValue(asArray(false), Boolean.TYPE);
assertFalse(booleanFalseValue);
final Boolean booleanWrapperTrueValue = mapper.readValue(asArray(Boolean.valueOf(true)), Boolean.class);
assertEquals(Boolean.TRUE, booleanWrapperTrueValue);
}
public void testSingleElementArrayDisabled() throws Exception {
final ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
try {
mapper.readValue("[42]", Integer.class);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue("[42]", Integer.TYPE);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue("[42.273]", Double.class);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue("[42.2723]", Double.TYPE);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue("[42342342342342]", Long.class);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue("[42342342342342342]", Long.TYPE);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue("[42]", Short.class);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue("[42]", Short.TYPE);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue("[327.2323]", Float.class);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue("[82.81902]", Float.TYPE);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue("[22]", Byte.class);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue("[22]", Byte.TYPE);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue("['d']", Character.class);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue("['d']", Character.TYPE);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue("[true]", Boolean.class);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue("[true]", Boolean.TYPE);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
}
public void testMultiValueArrayException() throws IOException {
final ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
try {
mapper.readValue("[42,42]", Integer.class);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue("[42,42]", Integer.TYPE);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue("[42.273,42.273]", Double.class);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue("[42.2723,42.273]", Double.TYPE);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue("[42342342342342,42342342342342]", Long.class);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue("[42342342342342342,42342342342342]", Long.TYPE);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue("[42,42]", Short.class);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue("[42,42]", Short.TYPE);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue("[327.2323,327.2323]", Float.class);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue("[82.81902,327.2323]", Float.TYPE);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue("[22,23]", Byte.class);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue("[22,23]", Byte.TYPE);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue(asArray(quote("c") + "," + quote("d")), Character.class);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue(asArray(quote("c") + "," + quote("d")), Character.TYPE);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue("[true,false]", Boolean.class);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
try {
mapper.readValue("[true,false]", Boolean.TYPE);
fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
} catch (JsonMappingException exp) {
//Exception was thrown correctly
}
}
private static String asArray(Object value) {
final String stringVal = value.toString();
return new StringBuilder(stringVal.length() + 2).append("[").append(stringVal).append("]").toString();
}
/*
/**********************************************************
/* Empty String coercion, handling
/**********************************************************
*/
// by default, should return nulls, n'est pas?
public void testEmptyStringForWrappers() throws IOException
{
WrappersBean bean;
// by default, ok to rely on defaults
bean = MAPPER.readValue("{\"booleanValue\":\"\"}", WrappersBean.class);
assertNull(bean.booleanValue);
bean = MAPPER.readValue("{\"byteValue\":\"\"}", WrappersBean.class);
assertNull(bean.byteValue);
// char/Character is different... not sure if this should work or not:
bean = MAPPER.readValue("{\"charValue\":\"\"}", WrappersBean.class);
assertNull(bean.charValue);
bean = MAPPER.readValue("{\"shortValue\":\"\"}", WrappersBean.class);
assertNull(bean.shortValue);
bean = MAPPER.readValue("{\"intValue\":\"\"}", WrappersBean.class);
assertNull(bean.intValue);
bean = MAPPER.readValue("{\"longValue\":\"\"}", WrappersBean.class);
assertNull(bean.longValue);
bean = MAPPER.readValue("{\"floatValue\":\"\"}", WrappersBean.class);
assertNull(bean.floatValue);
bean = MAPPER.readValue("{\"doubleValue\":\"\"}", WrappersBean.class);
assertNull(bean.doubleValue);
}
public void testEmptyStringForPrimitives() throws IOException
{
PrimitivesBean bean;
bean = MAPPER.readValue("{\"booleanValue\":\"\"}", PrimitivesBean.class);
assertFalse(bean.booleanValue);
bean = MAPPER.readValue("{\"byteValue\":\"\"}", PrimitivesBean.class);
assertEquals((byte) 0, bean.byteValue);
bean = MAPPER.readValue("{\"charValue\":\"\"}", PrimitivesBean.class);
assertEquals((char) 0, bean.charValue);
bean = MAPPER.readValue("{\"shortValue\":\"\"}", PrimitivesBean.class);
assertEquals((short) 0, bean.shortValue);
bean = MAPPER.readValue("{\"intValue\":\"\"}", PrimitivesBean.class);
assertEquals(0, bean.intValue);
bean = MAPPER.readValue("{\"longValue\":\"\"}", PrimitivesBean.class);
assertEquals(0L, bean.longValue);
bean = MAPPER.readValue("{\"floatValue\":\"\"}", PrimitivesBean.class);
assertEquals(0.0f, bean.floatValue);
bean = MAPPER.readValue("{\"doubleValue\":\"\"}", PrimitivesBean.class);
assertEquals(0.0, bean.doubleValue);
}
}