| 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); |
| } |
| } |
| |