Fix JSON field type resolution for top-level and nested array fields
Previously, the logic that determined the field’s type would incorrectly look at the contents of the array. For example, if the array contained one or more objects, the field’s type would be resolved as Object rather than Array. This commit updates JsonFieldPath to record when a path explicitly identifies an array so that the array itself is used to determine the field’s type rather than its contents. Closes gh-292
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package org.springframework.restdocs.payload;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -42,16 +43,24 @@ final class JsonFieldPath {
|
||||
|
||||
private final boolean precise;
|
||||
|
||||
private JsonFieldPath(String rawPath, List<String> segments, boolean precise) {
|
||||
private final boolean array;
|
||||
|
||||
private JsonFieldPath(String rawPath, List<String> segments, boolean precise,
|
||||
boolean array) {
|
||||
this.rawPath = rawPath;
|
||||
this.segments = segments;
|
||||
this.precise = precise;
|
||||
this.array = array;
|
||||
}
|
||||
|
||||
boolean isPrecise() {
|
||||
return this.precise;
|
||||
}
|
||||
|
||||
boolean isArray() {
|
||||
return this.array;
|
||||
}
|
||||
|
||||
List<String> getSegments() {
|
||||
return this.segments;
|
||||
}
|
||||
@@ -63,7 +72,8 @@ final class JsonFieldPath {
|
||||
|
||||
static JsonFieldPath compile(String path) {
|
||||
List<String> segments = extractSegments(path);
|
||||
return new JsonFieldPath(path, segments, matchesSingleValue(segments));
|
||||
return new JsonFieldPath(path, segments, matchesSingleValue(segments),
|
||||
isArraySegment(segments.get(segments.size() - 1)));
|
||||
}
|
||||
|
||||
static boolean isArraySegment(String segment) {
|
||||
@@ -71,8 +81,9 @@ final class JsonFieldPath {
|
||||
}
|
||||
|
||||
static boolean matchesSingleValue(List<String> segments) {
|
||||
for (String segment : segments) {
|
||||
if (isArraySegment(segment)) {
|
||||
Iterator<String> iterator = segments.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
if (isArraySegment(iterator.next()) && iterator.hasNext()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ final class JsonFieldProcessor {
|
||||
if (matches.isEmpty()) {
|
||||
throw new FieldDoesNotExistException(path);
|
||||
}
|
||||
if (path.isPrecise()) {
|
||||
if ((!path.isArray()) && path.isPrecise()) {
|
||||
return matches.get(0);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -44,7 +44,7 @@ class JsonFieldTypeResolver {
|
||||
}
|
||||
return commonType;
|
||||
}
|
||||
return determineFieldType(this.fieldProcessor.extract(fieldPath, payload));
|
||||
return determineFieldType(field);
|
||||
}
|
||||
|
||||
private JsonFieldType determineFieldType(Object fieldValue) {
|
||||
|
||||
Reference in New Issue
Block a user