Refine missing field detection logic for paths with multiple arrays
Previously, missing field detection worked correctly for paths containing a single array, but if the path contained multiple arrays the extracted value would be a list containing a single empty list. In this case the field would not be considered missing when, in fact it should have been. This commit updates the missing field detection logic to recursively examine the extracted value and, when it's a collection, the values that it contains. As a result, a field will be considered to be missing if it isn't present, if it's an empty collection, or if it's a collection that only contains empty collections or, to any depth, collections of empty collections. Closes gh-519
This commit is contained in:
@@ -86,8 +86,23 @@ class JsonContentHandler implements ContentHandler {
|
||||
}
|
||||
ExtractedField extracted = this.fieldProcessor.extract(candidate.getPath(),
|
||||
payload);
|
||||
return extracted.getValue() instanceof Collection
|
||||
&& ((Collection<?>) extracted.getValue()).isEmpty();
|
||||
return isEmptyCollection(extracted.getValue());
|
||||
}
|
||||
|
||||
private boolean isEmptyCollection(Object value) {
|
||||
if (!(value instanceof Collection)) {
|
||||
return false;
|
||||
}
|
||||
Collection<?> collection = (Collection<?>) value;
|
||||
if (collection.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
for (Object entry : collection) {
|
||||
if (!isEmptyCollection(entry)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -158,7 +158,7 @@ public class JsonContentHandlerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void describedFieldThatIsSometimesPresentChildOfOptionalArrayIsNotConsideredMissing() {
|
||||
public void describedSometimesPresentFieldThatIsChildOfSometimesPresentOptionalArrayIsNotConsideredMissing() {
|
||||
List<FieldDescriptor> missingFields = new JsonContentHandler(
|
||||
"{\"a\":[ {\"b\": \"bravo\"}, {\"b\": \"bravo\", \"c\": { \"d\": \"delta\"}}]}"
|
||||
.getBytes()).findMissingFields(
|
||||
@@ -167,4 +167,25 @@ public class JsonContentHandlerTests {
|
||||
assertThat(missingFields.size(), is(equalTo(0)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void describedMissingFieldThatIsChildOfNestedOptionalArrayThatIsEmptyIsNotConsideredMissing() {
|
||||
List<FieldDescriptor> missingFields = new JsonContentHandler(
|
||||
"{\"a\":[{\"b\":[]}]}".getBytes()).findMissingFields(
|
||||
Arrays.asList(new FieldDescriptor("a.[].b").optional(),
|
||||
new FieldDescriptor("a.[].b.[]").optional(),
|
||||
new FieldDescriptor("a.[].b.[].c")));
|
||||
assertThat(missingFields.size(), is(equalTo(0)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void describedMissingFieldThatIsChildOfNestedOptionalArrayThatContainsAnObjectIsConsideredMissing() {
|
||||
List<FieldDescriptor> missingFields = new JsonContentHandler(
|
||||
"{\"a\":[{\"b\":[{}]}]}".getBytes()).findMissingFields(
|
||||
Arrays.asList(new FieldDescriptor("a.[].b").optional(),
|
||||
new FieldDescriptor("a.[].b.[]").optional(),
|
||||
new FieldDescriptor("a.[].b.[].c")));
|
||||
assertThat(missingFields.size(), is(equalTo(1)));
|
||||
assertThat(missingFields.get(0).getPath(), is(equalTo("a.[].b.[].c")));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user