blob: 7679745bd37a7b3d95a5dd70cd1cf7d99abe7ef8 [file] [log] [blame]
Tatu Salorantad00e63c2016-08-30 23:00:16 -07001package com.fasterxml.jackson.databind.deser;
2
3import java.io.*;
4import java.math.BigDecimal;
5import java.math.BigInteger;
6
7import org.junit.Assert;
8
9import com.fasterxml.jackson.annotation.JsonCreator;
10import com.fasterxml.jackson.annotation.JsonProperty;
11import com.fasterxml.jackson.core.*;
12import com.fasterxml.jackson.databind.*;
13
14/**
15 * Unit tests for verifying handling of simple basic non-structured
16 * types; primitives (and/or their wrappers), Strings.
17 */
18public class JDKScalarsTest
19 extends BaseMapTest
20{
21 final static String NAN_STRING = "NaN";
22
23 final static class BooleanBean {
24 boolean _v;
25 void setV(boolean v) { _v = v; }
26 }
27
28 static class BooleanWrapper {
29 public Boolean wrapper;
30 public boolean primitive;
31
32 protected Boolean ctor;
33
34 @JsonCreator
35 public BooleanWrapper(@JsonProperty("ctor") Boolean foo) {
36 ctor = foo;
37 }
38 }
39
40 static class IntBean {
41 int _v;
42 void setV(int v) { _v = v; }
43 }
44
45 final static class DoubleBean {
46 double _v;
47 void setV(double v) { _v = v; }
48 }
49
50 final static class FloatBean {
51 float _v;
52 void setV(float v) { _v = v; }
53 }
54
55 final static class CharacterBean {
56 char _v;
57 void setV(char v) { _v = v; }
58 char getV() { return _v; }
59 }
60
61 final static class CharacterWrapperBean {
62 Character _v;
63 void setV(Character v) { _v = v; }
64 Character getV() { return _v; }
65 }
66
67 /**
68 * Also, let's ensure that it's ok to override methods.
69 */
70 static class IntBean2
71 extends IntBean
72 {
73 @Override
74 void setV(int v2) { super.setV(v2+1); }
75 }
76
77 static class PrimitivesBean
78 {
79 public boolean booleanValue = true;
80 public byte byteValue = 3;
81 public char charValue = 'a';
82 public short shortValue = 37;
83 public int intValue = 1;
84 public long longValue = 100L;
85 public float floatValue = 0.25f;
86 public double doubleValue = -1.0;
87 }
88
89 static class WrappersBean
90 {
91 public Boolean booleanValue;
92 public Byte byteValue;
93 public Character charValue;
94 public Short shortValue;
95 public Integer intValue;
96 public Long longValue;
97 public Float floatValue;
98 public Double doubleValue;
99 }
100
101 private final ObjectMapper MAPPER = new ObjectMapper();
102
103 /*
104 /**********************************************************
105 /* Scalar tests for boolean
106 /**********************************************************
107 */
108
109 public void testBooleanPrimitive() throws Exception
110 {
111 // first, simple case:
112 BooleanBean result = MAPPER.readValue(new StringReader("{\"v\":true}"), BooleanBean.class);
113 assertTrue(result._v);
Tatu Salorantad00e63c2016-08-30 23:00:16 -0700114 result = MAPPER.readValue(new StringReader("{\"v\":null}"), BooleanBean.class);
115 assertNotNull(result);
116 assertFalse(result._v);
Tatu Saloranta75b70492017-01-06 19:57:55 -0800117 // [databind#1480]
118 result = MAPPER.readValue(new StringReader("{\"v\":1}"), BooleanBean.class);
119 assertNotNull(result);
120 assertTrue(result._v);
Tatu Salorantad00e63c2016-08-30 23:00:16 -0700121
122 // should work with arrays too..
123 boolean[] array = MAPPER.readValue(new StringReader("[ null ]"), boolean[].class);
124 assertNotNull(array);
125 assertEquals(1, array.length);
126 assertFalse(array[0]);
Tatu Saloranta75b70492017-01-06 19:57:55 -0800127
128 }
Tatu Salorantad00e63c2016-08-30 23:00:16 -0700129
Tatu Saloranta75b70492017-01-06 19:57:55 -0800130 public void testBooleanPrimitiveArrayUnwrap() throws Exception
131 {
132 // [databind#381]
Tatu Salorantad00e63c2016-08-30 23:00:16 -0700133 final ObjectMapper mapper = new ObjectMapper();
134 mapper.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
Tatu Saloranta75b70492017-01-06 19:57:55 -0800135 BooleanBean result = mapper.readValue(new StringReader("{\"v\":[true]}"), BooleanBean.class);
Tatu Salorantad00e63c2016-08-30 23:00:16 -0700136 assertTrue(result._v);
137
138 try {
139 mapper.readValue(new StringReader("[{\"v\":[true,true]}]"), BooleanBean.class);
140 fail("Did not throw exception while reading a value from a multi value array with UNWRAP_SINGLE_VALUE_ARRAY feature enabled");
141 } catch (JsonMappingException exp) {
142 //threw exception as required
143 }
144
145 result = mapper.readValue(new StringReader("{\"v\":[null]}"), BooleanBean.class);
146 assertNotNull(result);
147 assertFalse(result._v);
148
149 result = mapper.readValue(new StringReader("[{\"v\":[null]}]"), BooleanBean.class);
150 assertNotNull(result);
151 assertFalse(result._v);
152
Tatu Saloranta75b70492017-01-06 19:57:55 -0800153 boolean[] array = mapper.readValue(new StringReader("[ [ null ] ]"), boolean[].class);
Tatu Salorantad00e63c2016-08-30 23:00:16 -0700154 assertNotNull(array);
155 assertEquals(1, array.length);
156 assertFalse(array[0]);
157 }
158
159 /**
160 * Simple unit test to verify that we can map boolean values to
161 * java.lang.Boolean.
162 */
163 public void testBooleanWrapper() throws Exception
164 {
165 Boolean result = MAPPER.readValue(new StringReader("true"), Boolean.class);
166 assertEquals(Boolean.TRUE, result);
167 result = MAPPER.readValue(new StringReader("false"), Boolean.class);
168 assertEquals(Boolean.FALSE, result);
169
170 // should accept ints too, (0 == false, otherwise true)
Tatu Saloranta75b70492017-01-06 19:57:55 -0800171 result = MAPPER.readValue("0", Boolean.class);
Tatu Salorantad00e63c2016-08-30 23:00:16 -0700172 assertEquals(Boolean.FALSE, result);
Tatu Saloranta75b70492017-01-06 19:57:55 -0800173 result = MAPPER.readValue("1", Boolean.class);
Tatu Salorantad00e63c2016-08-30 23:00:16 -0700174 assertEquals(Boolean.TRUE, result);
175 }
176
177 // Test for verifying that Long values are coerced to boolean correctly as well
178 public void testLongToBoolean() throws Exception
179 {
180 long value = 1L + Integer.MAX_VALUE;
181 BooleanWrapper b = MAPPER.readValue("{\"primitive\" : "+value+", \"wrapper\":"+value+", \"ctor\":"+value+"}",
182 BooleanWrapper.class);
183 assertEquals(Boolean.TRUE, b.wrapper);
184 assertTrue(b.primitive);
185 assertEquals(Boolean.TRUE, b.ctor);
Tatu Saloranta05118942016-10-13 20:31:37 -0700186
187 // but ensure we can also get `false`
188 b = MAPPER.readValue("{\"primitive\" : 0 , \"wrapper\":0, \"ctor\":0}",
189 BooleanWrapper.class);
190 assertEquals(Boolean.FALSE, b.wrapper);
191 assertFalse(b.primitive);
192 assertEquals(Boolean.FALSE, b.ctor);
Tatu Salorantad00e63c2016-08-30 23:00:16 -0700193 }
194
195 /*
196 /**********************************************************
197 /* Scalar tests for integral types
198 /**********************************************************
199 */
200
201 public void testIntPrimitive() throws Exception
202 {
203 // first, simple case:
204 IntBean result = MAPPER.readValue(new StringReader("{\"v\":3}"), IntBean.class);
205 assertEquals(3, result._v);
206 result = MAPPER.readValue(new StringReader("{\"v\":null}"), IntBean.class);
207 assertNotNull(result);
208 assertEquals(0, result._v);
209
210 // should work with arrays too..
211 int[] array = MAPPER.readValue(new StringReader("[ null ]"), int[].class);
212 assertNotNull(array);
213 assertEquals(1, array.length);
214 assertEquals(0, array[0]);
215
216 // [Issue#381]
217 final ObjectMapper mapper = new ObjectMapper();
218 mapper.disable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
219 try {
220 mapper.readValue(new StringReader("{\"v\":[3]}"), IntBean.class);
221 fail("Did not throw exception when reading a value from a single value array with the UNWRAP_SINGLE_VALUE_ARRAYS feature disabled");
222 } catch (JsonMappingException exp) {
223 //Correctly threw exception
224 }
225
226 mapper.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
227
228 result = mapper.readValue(new StringReader("{\"v\":[3]}"), IntBean.class);
229 assertEquals(3, result._v);
230
231 result = mapper.readValue(new StringReader("[{\"v\":[3]}]"), IntBean.class);
232 assertEquals(3, result._v);
233
234 try {
235 mapper.readValue("[{\"v\":[3,3]}]", IntBean.class);
236 fail("Did not throw exception while reading a value from a multi value array with UNWRAP_SINGLE_VALUE_ARRAY feature enabled");
237 } catch (JsonMappingException exp) {
238 //threw exception as required
239 }
240
241 result = mapper.readValue("{\"v\":[null]}", IntBean.class);
242 assertNotNull(result);
243 assertEquals(0, result._v);
244
245 array = mapper.readValue("[ [ null ] ]", int[].class);
246 assertNotNull(array);
247 assertEquals(1, array.length);
248 assertEquals(0, array[0]);
249 }
250
251 public void testByteWrapper() throws Exception
252 {
253 Byte result = MAPPER.readValue(new StringReader(" -42\t"), Byte.class);
254 assertEquals(Byte.valueOf((byte)-42), result);
255
256 // Also: should be able to coerce floats, strings:
257 result = MAPPER.readValue(new StringReader(" \"-12\""), Byte.class);
258 assertEquals(Byte.valueOf((byte)-12), result);
259
260 result = MAPPER.readValue(new StringReader(" 39.07"), Byte.class);
261 assertEquals(Byte.valueOf((byte)39), result);
262 }
263
264 public void testShortWrapper() throws Exception
265 {
266 Short result = MAPPER.readValue(new StringReader("37"), Short.class);
267 assertEquals(Short.valueOf((short)37), result);
268
269 // Also: should be able to coerce floats, strings:
270 result = MAPPER.readValue(new StringReader(" \"-1009\""), Short.class);
271 assertEquals(Short.valueOf((short)-1009), result);
272
273 result = MAPPER.readValue(new StringReader("-12.9"), Short.class);
274 assertEquals(Short.valueOf((short)-12), result);
275 }
276
277 public void testCharacterWrapper() throws Exception
278 {
279 // First: canonical value is 1-char string
280 Character result = MAPPER.readValue(new StringReader("\"a\""), Character.class);
281 assertEquals(Character.valueOf('a'), result);
282
283 // But can also pass in ascii code
284 result = MAPPER.readValue(new StringReader(" "+((int) 'X')), Character.class);
285 assertEquals(Character.valueOf('X'), result);
286
287 final CharacterWrapperBean wrapper = MAPPER.readValue(new StringReader("{\"v\":null}"), CharacterWrapperBean.class);
288 assertNotNull(wrapper);
289 assertNull(wrapper.getV());
290
291 final ObjectMapper mapper = new ObjectMapper();
292 mapper.enable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES);
293 try {
294 mapper.readValue("{\"v\":null}", CharacterBean.class);
295 fail("Attempting to deserialize a 'null' JSON reference into a 'char' property did not throw an exception");
296 } catch (JsonMappingException exp) {
297 //Exception thrown as required
298 }
299
300 mapper.disable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES);
301 final CharacterBean charBean = MAPPER.readValue(new StringReader("{\"v\":null}"), CharacterBean.class);
302 assertNotNull(wrapper);
303 assertEquals('\u0000', charBean.getV());
304 }
305
306 public void testIntWrapper() throws Exception
307 {
308 Integer result = MAPPER.readValue(new StringReader(" -42\t"), Integer.class);
309 assertEquals(Integer.valueOf(-42), result);
310
311 // Also: should be able to coerce floats, strings:
312 result = MAPPER.readValue(new StringReader(" \"-1200\""), Integer.class);
313 assertEquals(Integer.valueOf(-1200), result);
314
315 result = MAPPER.readValue(new StringReader(" 39.07"), Integer.class);
316 assertEquals(Integer.valueOf(39), result);
317 }
318
319 public void testLongWrapper() throws Exception
320 {
321 Long result = MAPPER.readValue(new StringReader("12345678901"), Long.class);
322 assertEquals(Long.valueOf(12345678901L), result);
323
324 // Also: should be able to coerce floats, strings:
325 result = MAPPER.readValue(new StringReader(" \"-9876\""), Long.class);
326 assertEquals(Long.valueOf(-9876), result);
327
328 result = MAPPER.readValue(new StringReader("1918.3"), Long.class);
329 assertEquals(Long.valueOf(1918), result);
330 }
331
332 /**
333 * Beyond simple case, let's also ensure that method overriding works as
334 * expected.
335 */
336 public void testIntWithOverride() throws Exception
337 {
338 IntBean2 result = MAPPER.readValue(new StringReader("{\"v\":8}"), IntBean2.class);
339 assertEquals(9, result._v);
340 }
341
342 /*
343 /**********************************************************
344 /* Scalar tests for floating point types
345 /**********************************************************
346 */
347
348 public void testDoublePrimitive() throws Exception
349 {
350 // first, simple case:
351 // bit tricky with binary fps but...
352 final double value = 0.016;
353 DoubleBean result = MAPPER.readValue(new StringReader("{\"v\":"+value+"}"), DoubleBean.class);
354 assertEquals(value, result._v);
355 // then [JACKSON-79]:
356 result = MAPPER.readValue(new StringReader("{\"v\":null}"), DoubleBean.class);
357 assertNotNull(result);
358 assertEquals(0.0, result._v);
359
360 // should work with arrays too..
361 double[] array = MAPPER.readValue(new StringReader("[ null ]"), double[].class);
362 assertNotNull(array);
363 assertEquals(1, array.length);
364 assertEquals(0.0, array[0]);
365 }
366
367 /* Note: dealing with floating-point values is tricky; not sure if
368 * we can really use equality tests here... JDK does have decent
369 * conversions though, to retain accuracy and round-trippability.
370 * But still...
371 */
372 public void testFloatWrapper() throws Exception
373 {
374 // Also: should be able to coerce floats, strings:
375 String[] STRS = new String[] {
376 "1.0", "0.0", "-0.3", "0.7", "42.012", "-999.0", NAN_STRING
377 };
378
379 for (String str : STRS) {
380 Float exp = Float.valueOf(str);
381 Float result;
382
383 if (NAN_STRING != str) {
384 // First, as regular floating point value
385 result = MAPPER.readValue(new StringReader(str), Float.class);
386 assertEquals(exp, result);
387 }
388
389 // and then as coerced String:
390 result = MAPPER.readValue(new StringReader(" \""+str+"\""), Float.class);
391 assertEquals(exp, result);
392 }
393 }
394
395 public void testDoubleWrapper() throws Exception
396 {
397 // Also: should be able to coerce doubles, strings:
398 String[] STRS = new String[] {
399 "1.0", "0.0", "-0.3", "0.7", "42.012", "-999.0", NAN_STRING
400 };
401
402 for (String str : STRS) {
403 Double exp = Double.valueOf(str);
404 Double result;
405
406 // First, as regular double value
407 if (NAN_STRING != str) {
408 result = MAPPER.readValue(str, Double.class);
409 assertEquals(exp, result);
410 }
411 // and then as coerced String:
412 result = MAPPER.readValue(new StringReader(" \""+str+"\""), Double.class);
413 assertEquals(exp, result);
414 }
415 }
416
417 public void testDoubleAsArray() throws Exception
418 {
419 final ObjectMapper mapper = new ObjectMapper();
420 mapper.disable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
421 final double value = 0.016;
422 try {
423 mapper.readValue(new StringReader("{\"v\":[" + value + "]}"), DoubleBean.class);
424 fail("Did not throw exception when reading a value from a single value array with the UNWRAP_SINGLE_VALUE_ARRAYS feature disabled");
425 } catch (JsonMappingException exp) {
426 //Correctly threw exception
427 }
428
429 mapper.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
430
431 DoubleBean result = mapper.readValue(new StringReader("{\"v\":[" + value + "]}"),
432 DoubleBean.class);
433 assertEquals(value, result._v);
434
435 result = mapper.readValue(new StringReader("[{\"v\":[" + value + "]}]"), DoubleBean.class);
436 assertEquals(value, result._v);
437
438 try {
439 mapper.readValue(new StringReader("[{\"v\":[" + value + "," + value + "]}]"), DoubleBean.class);
440 fail("Did not throw exception while reading a value from a multi value array with UNWRAP_SINGLE_VALUE_ARRAY feature enabled");
441 } catch (JsonMappingException exp) {
442 //threw exception as required
443 }
444
445 result = mapper.readValue(new StringReader("{\"v\":[null]}"), DoubleBean.class);
446 assertNotNull(result);
447 assertEquals(0d, result._v);
448
449 double[] array = mapper.readValue(new StringReader("[ [ null ] ]"), double[].class);
450 assertNotNull(array);
451 assertEquals(1, array.length);
452 assertEquals(0d, array[0]);
453 }
454
455 public void testDoublePrimitiveNonNumeric() throws Exception
456 {
457 // first, simple case:
458 // bit tricky with binary fps but...
459 double value = Double.POSITIVE_INFINITY;
460 DoubleBean result = MAPPER.readValue(new StringReader("{\"v\":\""+value+"\"}"), DoubleBean.class);
461 assertEquals(value, result._v);
462
463 // should work with arrays too..
464 double[] array = MAPPER.readValue(new StringReader("[ \"Infinity\" ]"), double[].class);
465 assertNotNull(array);
466 assertEquals(1, array.length);
467 assertEquals(Double.POSITIVE_INFINITY, array[0]);
468 }
469
470 public void testFloatPrimitiveNonNumeric() throws Exception
471 {
472 // bit tricky with binary fps but...
473 float value = Float.POSITIVE_INFINITY;
474 FloatBean result = MAPPER.readValue(new StringReader("{\"v\":\""+value+"\"}"), FloatBean.class);
475 assertEquals(value, result._v);
476
477 // should work with arrays too..
478 float[] array = MAPPER.readValue(new StringReader("[ \"Infinity\" ]"), float[].class);
479 assertNotNull(array);
480 assertEquals(1, array.length);
481 assertEquals(Float.POSITIVE_INFINITY, array[0]);
482 }
483
484 /*
485 /**********************************************************
486 /* Scalar tests, other
487 /**********************************************************
488 */
489
490 public void testEmptyToNullCoercionForPrimitives() throws Exception {
491 _testEmptyToNullCoercion(int.class, Integer.valueOf(0));
492 _testEmptyToNullCoercion(long.class, Long.valueOf(0));
493 _testEmptyToNullCoercion(double.class, Double.valueOf(0.0));
494 _testEmptyToNullCoercion(float.class, Float.valueOf(0.0f));
495 }
496
497 private void _testEmptyToNullCoercion(Class<?> primType, Object emptyValue) throws Exception
498 {
499 final String EMPTY = "\"\"";
500
501 // as per [databind#1095] should only allow coercion from empty String,
502 // if `null` is acceptable
503 ObjectReader intR = MAPPER.readerFor(primType);
504 assertEquals(emptyValue, intR.readValue(EMPTY));
505 try {
506 intR.with(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES)
507 .readValue("\"\"");
508 fail("Should not have passed");
509 } catch (JsonMappingException e) {
510 verifyException(e, "Can not map Empty String");
511 }
512 }
513
514 public void testBase64Variants() throws Exception
515 {
516 final byte[] INPUT = "abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmnopqrstuvwxyz1234567890X".getBytes("UTF-8");
517
518 // default encoding is "MIME, no linefeeds", so:
519 Assert.assertArrayEquals(INPUT, MAPPER.readValue(
520 quote("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY3ODkwYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY3ODkwWA=="),
521 byte[].class));
522 ObjectReader reader = MAPPER.readerFor(byte[].class);
523 Assert.assertArrayEquals(INPUT, (byte[]) reader.with(Base64Variants.MIME_NO_LINEFEEDS).readValue(
524 quote("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY3ODkwYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY3ODkwWA=="
525 )));
526
527 // but others should be slightly different
528 Assert.assertArrayEquals(INPUT, (byte[]) reader.with(Base64Variants.MIME).readValue(
529 quote("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY3ODkwYWJjZGVmZ2hpamtsbW5vcHFyc3R1\\ndnd4eXoxMjM0NTY3ODkwWA=="
530 )));
531 Assert.assertArrayEquals(INPUT, (byte[]) reader.with(Base64Variants.MODIFIED_FOR_URL).readValue(
532 quote("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY3ODkwYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY3ODkwWA"
533 )));
534 // PEM mandates 64 char lines:
535 Assert.assertArrayEquals(INPUT, (byte[]) reader.with(Base64Variants.PEM).readValue(
536 quote("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY3ODkwYWJjZGVmZ2hpamts\\nbW5vcHFyc3R1dnd4eXoxMjM0NTY3ODkwWA=="
537 )));
538 }
539 /*
540 /**********************************************************
541 /* Simple non-primitive types
542 /**********************************************************
543 */
544
545 public void testSingleString() throws Exception
546 {
547 String value = "FOO!";
548 String result = MAPPER.readValue(new StringReader("\""+value+"\""), String.class);
549 assertEquals(value, result);
550 }
551
552 public void testSingleStringWrapped() throws Exception
553 {
554 final ObjectMapper mapper = new ObjectMapper();
555 mapper.disable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
556
557 String value = "FOO!";
558 try {
559 mapper.readValue(new StringReader("[\""+value+"\"]"), String.class);
560 fail("Exception not thrown when attempting to unwrap a single value 'String' array into a simple String");
561 } catch (JsonMappingException exp) {
562 //exception thrown correctly
563 }
564
565 mapper.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
566
567 try {
568 mapper.readValue(new StringReader("[\""+value+"\",\""+value+"\"]"), String.class);
569 fail("Exception not thrown when attempting to unwrap a single value 'String' array that contained more than one value into a simple String");
570 } catch (JsonMappingException exp) {
571 //exception thrown correctly
572 }
573
574 String result = mapper.readValue(new StringReader("[\""+value+"\"]"), String.class);
575 assertEquals(value, result);
576 }
577
578 public void testBigDecimal() throws Exception
579 {
580 final ObjectMapper mapper = objectMapper();
581 mapper.disable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
582
583 BigDecimal value = new BigDecimal("0.001");
584 BigDecimal result = mapper.readValue(value.toString(), BigDecimal.class);
585 assertEquals(value, result);
586 try {
587 mapper.readValue("[" + value.toString() + "]", BigDecimal.class);
588 fail("Exception was not thrown when attempting to read a single value array of BigDecimal when UNWRAP_SINGLE_VALUE_ARRAYS feature is disabled");
589 } catch (JsonMappingException exp) {
590 //Exception was thrown correctly
591 }
592
593 mapper.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
594 result = mapper.readValue("[" + value.toString() + "]", BigDecimal.class);
595 assertEquals(value, result);
596
597 try {
598 mapper.readValue("[" + value.toString() + "," + value.toString() + "]", BigDecimal.class);
599 fail("Exception was not thrown when attempting to read a muti value array of BigDecimal when UNWRAP_SINGLE_VALUE_ARRAYS feature is enabled");
600 } catch (JsonMappingException exp) {
601 //Exception was thrown correctly
602 }
603 }
604
605 public void testBigInteger() throws Exception
606 {
607 final ObjectMapper mapper = objectMapper();
608 mapper.disable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
609
610 BigInteger value = new BigInteger("-1234567890123456789012345567809");
611 BigInteger result = mapper.readValue(new StringReader(value.toString()), BigInteger.class);
612 assertEquals(value, result);
613
614 //Issue#381
615 try {
616 mapper.readValue("[" + value.toString() + "]", BigInteger.class);
617 fail("Exception was not thrown when attempting to read a single value array of BigInteger when UNWRAP_SINGLE_VALUE_ARRAYS feature is disabled");
618 } catch (JsonMappingException exp) {
619 //Exception was thrown correctly
620 }
621
622 mapper.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
623 result = mapper.readValue("[" + value.toString() + "]", BigInteger.class);
624 assertEquals(value, result);
625
626 try {
627 mapper.readValue("[" + value.toString() + "," + value.toString() + "]", BigInteger.class);
628 fail("Exception was not thrown when attempting to read a muti value array of BigInteger when UNWRAP_SINGLE_VALUE_ARRAYS feature is enabled");
629 } catch (JsonMappingException exp) {
630 //Exception was thrown correctly
631 }
632 }
633
634 /*
635 /**********************************************************
636 /* Sequence tests
637 /**********************************************************
638 */
639
640 /**
641 * Then a unit test to verify that we can conveniently bind sequence of
642 * space-separate simple values
643 */
644 public void testSequenceOfInts() throws Exception
645 {
646 final int NR_OF_INTS = 100;
647
648 StringBuilder sb = new StringBuilder();
649 for (int i = 0; i < NR_OF_INTS; ++i) {
650 sb.append(" ");
651 sb.append(i);
652 }
653 JsonParser jp = MAPPER.getFactory().createParser(sb.toString());
654 for (int i = 0; i < NR_OF_INTS; ++i) {
655 Integer result = MAPPER.readValue(jp, Integer.class);
656 assertEquals(Integer.valueOf(i), result);
657 }
658 jp.close();
659 }
660
661 /*
662 /**********************************************************
663 /* Single-element as array tests
664 /**********************************************************
665 */
666
667 // [databind#381]
668 public void testSingleElementScalarArrays() throws Exception {
669 final int intTest = 932832;
670 final double doubleTest = 32.3234;
671 final long longTest = 2374237428374293423L;
672 final short shortTest = (short) intTest;
673 final float floatTest = 84.3743f;
674 final byte byteTest = (byte) 43;
675 final char charTest = 'c';
676
677 final ObjectMapper mapper = new ObjectMapper();
678 mapper.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
679
680 final int intValue = mapper.readValue(asArray(intTest), Integer.TYPE);
681 assertEquals(intTest, intValue);
682 final Integer integerWrapperValue = mapper.readValue(asArray(Integer.valueOf(intTest)), Integer.class);
683 assertEquals(Integer.valueOf(intTest), integerWrapperValue);
684
685 final double doubleValue = mapper.readValue(asArray(doubleTest), Double.class);
686 assertEquals(doubleTest, doubleValue);
687 final Double doubleWrapperValue = mapper.readValue(asArray(Double.valueOf(doubleTest)), Double.class);
688 assertEquals(Double.valueOf(doubleTest), doubleWrapperValue);
689
690 final long longValue = mapper.readValue(asArray(longTest), Long.TYPE);
691 assertEquals(longTest, longValue);
692 final Long longWrapperValue = mapper.readValue(asArray(Long.valueOf(longTest)), Long.class);
693 assertEquals(Long.valueOf(longTest), longWrapperValue);
694
695 final short shortValue = mapper.readValue(asArray(shortTest), Short.TYPE);
696 assertEquals(shortTest, shortValue);
697 final Short shortWrapperValue = mapper.readValue(asArray(Short.valueOf(shortTest)), Short.class);
698 assertEquals(Short.valueOf(shortTest), shortWrapperValue);
699
700 final float floatValue = mapper.readValue(asArray(floatTest), Float.TYPE);
701 assertEquals(floatTest, floatValue);
702 final Float floatWrapperValue = mapper.readValue(asArray(Float.valueOf(floatTest)), Float.class);
703 assertEquals(Float.valueOf(floatTest), floatWrapperValue);
704
705 final byte byteValue = mapper.readValue(asArray(byteTest), Byte.TYPE);
706 assertEquals(byteTest, byteValue);
707 final Byte byteWrapperValue = mapper.readValue(asArray(Byte.valueOf(byteTest)), Byte.class);
708 assertEquals(Byte.valueOf(byteTest), byteWrapperValue);
709
710 final char charValue = mapper.readValue(asArray(quote(String.valueOf(charTest))), Character.TYPE);
711 assertEquals(charTest, charValue);
712 final Character charWrapperValue = mapper.readValue(asArray(quote(String.valueOf(charTest))), Character.class);
713 assertEquals(Character.valueOf(charTest), charWrapperValue);
714
715 final boolean booleanTrueValue = mapper.readValue(asArray(true), Boolean.TYPE);
716 assertTrue(booleanTrueValue);
717
718 final boolean booleanFalseValue = mapper.readValue(asArray(false), Boolean.TYPE);
719 assertFalse(booleanFalseValue);
720
721 final Boolean booleanWrapperTrueValue = mapper.readValue(asArray(Boolean.valueOf(true)), Boolean.class);
722 assertEquals(Boolean.TRUE, booleanWrapperTrueValue);
723 }
724
725 public void testSingleElementArrayDisabled() throws Exception {
726 final ObjectMapper mapper = new ObjectMapper();
727 mapper.disable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
728 try {
729 mapper.readValue("[42]", Integer.class);
730 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
731 } catch (JsonMappingException exp) {
732 //Exception was thrown correctly
733 }
734 try {
735 mapper.readValue("[42]", Integer.TYPE);
736 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
737 } catch (JsonMappingException exp) {
738 //Exception was thrown correctly
739 }
740
741 try {
742 mapper.readValue("[42.273]", Double.class);
743 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
744 } catch (JsonMappingException exp) {
745 //Exception was thrown correctly
746 }
747 try {
748 mapper.readValue("[42.2723]", Double.TYPE);
749 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
750 } catch (JsonMappingException exp) {
751 //Exception was thrown correctly
752 }
753
754 try {
755 mapper.readValue("[42342342342342]", Long.class);
756 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
757 } catch (JsonMappingException exp) {
758 //Exception was thrown correctly
759 }
760 try {
761 mapper.readValue("[42342342342342342]", Long.TYPE);
762 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
763 } catch (JsonMappingException exp) {
764 //Exception was thrown correctly
765 }
766
767 try {
768 mapper.readValue("[42]", Short.class);
769 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
770 } catch (JsonMappingException exp) {
771 //Exception was thrown correctly
772 }
773 try {
774 mapper.readValue("[42]", Short.TYPE);
775 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
776 } catch (JsonMappingException exp) {
777 //Exception was thrown correctly
778 }
779
780 try {
781 mapper.readValue("[327.2323]", Float.class);
782 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
783 } catch (JsonMappingException exp) {
784 //Exception was thrown correctly
785 }
786 try {
787 mapper.readValue("[82.81902]", Float.TYPE);
788 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
789 } catch (JsonMappingException exp) {
790 //Exception was thrown correctly
791 }
792
793 try {
794 mapper.readValue("[22]", Byte.class);
795 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
796 } catch (JsonMappingException exp) {
797 //Exception was thrown correctly
798 }
799 try {
800 mapper.readValue("[22]", Byte.TYPE);
801 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
802 } catch (JsonMappingException exp) {
803 //Exception was thrown correctly
804 }
805
806 try {
807 mapper.readValue("['d']", Character.class);
808 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
809 } catch (JsonMappingException exp) {
810 //Exception was thrown correctly
811 }
812 try {
813 mapper.readValue("['d']", Character.TYPE);
814 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
815 } catch (JsonMappingException exp) {
816 //Exception was thrown correctly
817 }
818
819 try {
820 mapper.readValue("[true]", Boolean.class);
821 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
822 } catch (JsonMappingException exp) {
823 //Exception was thrown correctly
824 }
825 try {
826 mapper.readValue("[true]", Boolean.TYPE);
827 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
828 } catch (JsonMappingException exp) {
829 //Exception was thrown correctly
830 }
831 }
832
833 public void testMultiValueArrayException() throws IOException {
834 final ObjectMapper mapper = new ObjectMapper();
835 mapper.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
836
837 try {
838 mapper.readValue("[42,42]", Integer.class);
839 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
840 } catch (JsonMappingException exp) {
841 //Exception was thrown correctly
842 }
843 try {
844 mapper.readValue("[42,42]", Integer.TYPE);
845 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
846 } catch (JsonMappingException exp) {
847 //Exception was thrown correctly
848 }
849
850 try {
851 mapper.readValue("[42.273,42.273]", Double.class);
852 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
853 } catch (JsonMappingException exp) {
854 //Exception was thrown correctly
855 }
856 try {
857 mapper.readValue("[42.2723,42.273]", Double.TYPE);
858 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
859 } catch (JsonMappingException exp) {
860 //Exception was thrown correctly
861 }
862
863 try {
864 mapper.readValue("[42342342342342,42342342342342]", Long.class);
865 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
866 } catch (JsonMappingException exp) {
867 //Exception was thrown correctly
868 }
869 try {
870 mapper.readValue("[42342342342342342,42342342342342]", Long.TYPE);
871 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
872 } catch (JsonMappingException exp) {
873 //Exception was thrown correctly
874 }
875
876 try {
877 mapper.readValue("[42,42]", Short.class);
878 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
879 } catch (JsonMappingException exp) {
880 //Exception was thrown correctly
881 }
882 try {
883 mapper.readValue("[42,42]", Short.TYPE);
884 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
885 } catch (JsonMappingException exp) {
886 //Exception was thrown correctly
887 }
888
889 try {
890 mapper.readValue("[327.2323,327.2323]", Float.class);
891 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
892 } catch (JsonMappingException exp) {
893 //Exception was thrown correctly
894 }
895 try {
896 mapper.readValue("[82.81902,327.2323]", Float.TYPE);
897 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
898 } catch (JsonMappingException exp) {
899 //Exception was thrown correctly
900 }
901
902 try {
903 mapper.readValue("[22,23]", Byte.class);
904 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
905 } catch (JsonMappingException exp) {
906 //Exception was thrown correctly
907 }
908 try {
909 mapper.readValue("[22,23]", Byte.TYPE);
910 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
911 } catch (JsonMappingException exp) {
912 //Exception was thrown correctly
913 }
914
915 try {
916 mapper.readValue(asArray(quote("c") + "," + quote("d")), Character.class);
917
918 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
919 } catch (JsonMappingException exp) {
920 //Exception was thrown correctly
921 }
922 try {
923 mapper.readValue(asArray(quote("c") + "," + quote("d")), Character.TYPE);
924 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
925 } catch (JsonMappingException exp) {
926 //Exception was thrown correctly
927 }
928
929 try {
930 mapper.readValue("[true,false]", Boolean.class);
931 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
932 } catch (JsonMappingException exp) {
933 //Exception was thrown correctly
934 }
935 try {
936 mapper.readValue("[true,false]", Boolean.TYPE);
937 fail("Single value array didn't throw an exception when DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS is disabled");
938 } catch (JsonMappingException exp) {
939 //Exception was thrown correctly
940 }
941 }
942
943 private static String asArray(Object value) {
944 final String stringVal = value.toString();
945 return new StringBuilder(stringVal.length() + 2).append("[").append(stringVal).append("]").toString();
946 }
947
948 /*
949 /**********************************************************
950 /* Empty String coercion, handling
951 /**********************************************************
952 */
953
954 // by default, should return nulls, n'est pas?
955 public void testEmptyStringForWrappers() throws IOException
956 {
957 WrappersBean bean;
958
959 // by default, ok to rely on defaults
960 bean = MAPPER.readValue("{\"booleanValue\":\"\"}", WrappersBean.class);
961 assertNull(bean.booleanValue);
962 bean = MAPPER.readValue("{\"byteValue\":\"\"}", WrappersBean.class);
963 assertNull(bean.byteValue);
964
965 // char/Character is different... not sure if this should work or not:
966 bean = MAPPER.readValue("{\"charValue\":\"\"}", WrappersBean.class);
967 assertNull(bean.charValue);
968
969 bean = MAPPER.readValue("{\"shortValue\":\"\"}", WrappersBean.class);
970 assertNull(bean.shortValue);
971 bean = MAPPER.readValue("{\"intValue\":\"\"}", WrappersBean.class);
972 assertNull(bean.intValue);
973 bean = MAPPER.readValue("{\"longValue\":\"\"}", WrappersBean.class);
974 assertNull(bean.longValue);
975 bean = MAPPER.readValue("{\"floatValue\":\"\"}", WrappersBean.class);
976 assertNull(bean.floatValue);
977 bean = MAPPER.readValue("{\"doubleValue\":\"\"}", WrappersBean.class);
978 assertNull(bean.doubleValue);
979 }
980
981 public void testEmptyStringForPrimitives() throws IOException
982 {
983 PrimitivesBean bean;
984 bean = MAPPER.readValue("{\"booleanValue\":\"\"}", PrimitivesBean.class);
985 assertFalse(bean.booleanValue);
986 bean = MAPPER.readValue("{\"byteValue\":\"\"}", PrimitivesBean.class);
987 assertEquals((byte) 0, bean.byteValue);
988 bean = MAPPER.readValue("{\"charValue\":\"\"}", PrimitivesBean.class);
989 assertEquals((char) 0, bean.charValue);
990 bean = MAPPER.readValue("{\"shortValue\":\"\"}", PrimitivesBean.class);
991 assertEquals((short) 0, bean.shortValue);
992 bean = MAPPER.readValue("{\"intValue\":\"\"}", PrimitivesBean.class);
993 assertEquals(0, bean.intValue);
994 bean = MAPPER.readValue("{\"longValue\":\"\"}", PrimitivesBean.class);
995 assertEquals(0L, bean.longValue);
996 bean = MAPPER.readValue("{\"floatValue\":\"\"}", PrimitivesBean.class);
997 assertEquals(0.0f, bean.floatValue);
998 bean = MAPPER.readValue("{\"doubleValue\":\"\"}", PrimitivesBean.class);
999 assertEquals(0.0, bean.doubleValue);
1000 }
1001}
1002