Skip to content

Commit

Permalink
per code review, add test specifically from issue where default mappe…
Browse files Browse the repository at this point in the history
…r is used
  • Loading branch information
kupci committed Sep 9, 2019
1 parent 812a598 commit 44bd669
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ public LocalDate deserialize(JsonParser parser, DeserializationContext context)
if (parser.hasToken(JsonToken.VALUE_STRING)) {
String string = parser.getText().trim();
if (string.length() == 0) {
if (!isLenient()) {
return _failForNotLenient(parser, context, JsonToken.VALUE_STRING);
}
return null;
}
// as per [datatype-jsr310#37], only check for optional (and, incorrect...) time marker 'T'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,21 @@ public LocalDateTimeDeserializer(DateTimeFormatter formatter) {
super(LocalDateTime.class, formatter);
}

/**
* Since 2.10
*/
protected LocalDateTimeDeserializer(LocalDateTimeDeserializer base, Boolean leniency) {
super(base, leniency);
}

@Override
protected LocalDateTimeDeserializer withDateFormat(DateTimeFormatter formatter) {
return new LocalDateTimeDeserializer(formatter);
}

// !!! TODO: lenient vs strict?
@Override
protected LocalDateTimeDeserializer withLeniency(Boolean leniency) {
return this;
return new LocalDateTimeDeserializer(this, leniency);
}

@Override
Expand All @@ -69,6 +75,9 @@ public LocalDateTime deserialize(JsonParser parser, DeserializationContext conte
if (parser.hasTokenId(JsonTokenId.ID_STRING)) {
String string = parser.getText().trim();
if (string.length() == 0) {
if (!isLenient()) {
return _failForNotLenient(parser, context, JsonToken.VALUE_STRING);
}
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
import java.time.Month;
import java.time.ZoneOffset;
import java.time.temporal.Temporal;
import java.util.Map;

import com.fasterxml.jackson.core.type.TypeReference;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
Expand All @@ -27,6 +29,7 @@ public class LocalDateDeserTest extends ModuleTestBase
{
private final ObjectMapper MAPPER = newMapper();
private final ObjectReader READER = MAPPER.readerFor(LocalDate.class);
private final TypeReference<Map<String, LocalDate>> MAP_TYPE_REF = new TypeReference<Map<String, LocalDate>>() { };

final static class Wrapper {
@JsonFormat(pattern="yyyy_MM_dd'T'HH:mmZ",
Expand Down Expand Up @@ -159,6 +162,58 @@ public void testStricDeserializeFromInt() throws Exception
// be content with just one...
}

/*
/**********************************************************
/* Tests for empty string handling
*/
/**********************************************************
*/

@Test
public void testLenientDeserializeFromEmptyString() throws Exception {

String key = "date";
ObjectMapper mapper = newMapper();
ObjectReader objectReader = mapper.readerFor(MAP_TYPE_REF);

String dateValAsNullStr = null;
String dateValAsEmptyStr = "";

String valueFromNullStr = mapper.writeValueAsString(asMap(key, dateValAsNullStr));
Map<String, LocalDate> actualMapFromNullStr = objectReader.readValue(valueFromNullStr);
LocalDate actualDateFromNullStr = actualMapFromNullStr.get(key);
assertNull(actualDateFromNullStr);

String valueFromEmptyStr = mapper.writeValueAsString(asMap(key, dateValAsEmptyStr));
Map<String, LocalDate> actualMapFromEmptyStr = objectReader.readValue(valueFromEmptyStr);
LocalDate actualDateFromEmptyStr = actualMapFromEmptyStr.get(key);
assertEquals("empty string failed to deserialize to null with lenient setting",actualDateFromNullStr, actualDateFromEmptyStr);
}

@Test( expected = MismatchedInputException.class)
public void testStrictDeserializFromEmptyString() throws Exception {

final String key = "date";
final ObjectMapper mapper = mapperBuilder()
.withConfigOverride(LocalDate.class,
c -> c.setFormat(JsonFormat.Value.forLeniency(false))
)
.build();
final ObjectReader objectReader = mapper.readerFor(MAP_TYPE_REF);
final String dateValAsNullStr = null;

// even with strict, null value should be deserialized without throwing an exception
String valueFromNullStr = mapper.writeValueAsString(asMap(key, dateValAsNullStr));
Map<String, LocalDate> actualMapFromNullStr = objectReader.readValue(valueFromNullStr);
assertNull(actualMapFromNullStr.get(key));

String dateValAsEmptyStr = "";
// TODO: nothing stops us from writing an empty string, maybe there should be a check there too?
String valueFromEmptyStr = mapper.writeValueAsString(asMap("date", dateValAsEmptyStr));
// with strict, deserializing an empty string is not permitted
objectReader.readValue(valueFromEmptyStr);
}

/*
/**********************************************************
/* Tests for alternate array handling
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,14 @@
import java.time.temporal.Temporal;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.TimeZone;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.DeserializationProblemHandler;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
Expand All @@ -46,6 +49,7 @@ public class LocalDateTimeDeserTest
{
private final static ObjectMapper MAPPER = newMapper();
private final static ObjectReader READER = MAPPER.readerFor(LocalDateTime.class);
private final TypeReference<Map<String, LocalDateTime>> MAP_TYPE_REF = new TypeReference<Map<String, LocalDateTime>>() { };

/*
/**********************************************************
Expand Down Expand Up @@ -174,6 +178,58 @@ public void testBadDeserializationAsString01() throws Throwable
}
}

/*
/**********************************************************
/* Tests for empty string handling
*/
/**********************************************************
*/

@Test
public void testLenientDeserializeFromEmptyString() throws Exception {

String key = "datetime";
ObjectMapper mapper = newMapper();
ObjectReader objectReader = mapper.readerFor(MAP_TYPE_REF);

String dateValAsNullStr = null;
String dateValAsEmptyStr = "";

String valueFromNullStr = mapper.writeValueAsString(asMap(key, dateValAsNullStr));
Map<String, LocalDateTime> actualMapFromNullStr = objectReader.readValue(valueFromNullStr);
LocalDateTime actualDateFromNullStr = actualMapFromNullStr.get(key);
assertNull(actualDateFromNullStr);

String valueFromEmptyStr = mapper.writeValueAsString(asMap(key, dateValAsEmptyStr));
Map<String, LocalDateTime> actualMapFromEmptyStr = objectReader.readValue(valueFromEmptyStr);
LocalDateTime actualDateFromEmptyStr = actualMapFromEmptyStr.get(key);
assertEquals("empty string failed to deserialize to null with lenient setting",actualDateFromNullStr, actualDateFromEmptyStr);
}

@Test( expected = MismatchedInputException.class)
public void testStrictDeserializFromEmptyString() throws Exception {

final String key = "datetime";
final ObjectMapper mapper = mapperBuilder()
.withConfigOverride(LocalDateTime.class,
c -> c.setFormat(JsonFormat.Value.forLeniency(false))
)
.build();
final ObjectReader objectReader = mapper.readerFor(MAP_TYPE_REF);
final String dateValAsNullStr = null;

// even with strict, null value should be deserialized without throwing an exception
String valueFromNullStr = mapper.writeValueAsString(asMap(key, dateValAsNullStr));
Map<String, LocalDateTime> actualMapFromNullStr = objectReader.readValue(valueFromNullStr);
assertNull(actualMapFromNullStr.get(key));

String dateValAsEmptyStr = "";
// TODO: nothing stops us from writing an empty string, maybe there should be a check there too?
String valueFromEmptyStr = mapper.writeValueAsString(asMap("date", dateValAsEmptyStr));
// with strict, deserializing an empty string is not permitted
objectReader.readValue(valueFromEmptyStr);
}

/*
/**********************************************************
/* Tests for alternate array handling
Expand Down

1 comment on commit 44bd669

@kupci
Copy link
Member Author

@kupci kupci commented on 44bd669 Sep 9, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If 'strict', treat empty string as invalid format, so that LocalDateDeserializer and LocalDateTimeDeserializer report this as an error instead of mapping to null.

Please sign in to comment.