Merge branch '1.2.x'
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2015 the original author or authors.
|
||||
* Copyright 2014-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,7 +31,8 @@ public class FieldDoesNotExistException extends RuntimeException {
|
||||
*
|
||||
* @param fieldPath the path of the field that does not exist
|
||||
*/
|
||||
public FieldDoesNotExistException(JsonFieldPath fieldPath) {
|
||||
public FieldDoesNotExistException(String fieldPath) {
|
||||
super("The payload does not contain a field with the path '" + fieldPath + "'");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@ import java.util.List;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.restdocs.payload.JsonFieldPath.PathType;
|
||||
import org.springframework.restdocs.payload.JsonFieldProcessor.ExtractedField;
|
||||
|
||||
/**
|
||||
* A {@link PayloadSubsectionExtractor} that extracts the subsection of the JSON payload
|
||||
@@ -66,20 +68,20 @@ public class FieldPathPayloadSubsectionExtractor
|
||||
public byte[] extractSubsection(byte[] payload, MediaType contentType) {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
try {
|
||||
JsonFieldPath compiledPath = JsonFieldPath.compile(this.fieldPath);
|
||||
Object extracted = new JsonFieldProcessor().extract(compiledPath,
|
||||
objectMapper.readValue(payload, Object.class));
|
||||
if (extracted instanceof List && !compiledPath.isPrecise()) {
|
||||
List<?> extractedList = (List<?>) extracted;
|
||||
ExtractedField extractedField = new JsonFieldProcessor().extract(
|
||||
this.fieldPath, objectMapper.readValue(payload, Object.class));
|
||||
Object value = extractedField.getValue();
|
||||
if (value instanceof List && extractedField.getType() == PathType.MULTI) {
|
||||
List<?> extractedList = (List<?>) value;
|
||||
if (extractedList.size() == 1) {
|
||||
extracted = extractedList.get(0);
|
||||
value = extractedList.get(0);
|
||||
}
|
||||
else {
|
||||
throw new PayloadHandlingException(this.fieldPath
|
||||
+ " does not uniquely identify a subsection of the payload");
|
||||
}
|
||||
}
|
||||
return objectMapper.writeValueAsBytes(extracted);
|
||||
return objectMapper.writeValueAsBytes(value);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new PayloadHandlingException(ex);
|
||||
|
||||
@@ -52,8 +52,8 @@ class JsonContentHandler implements ContentHandler {
|
||||
List<FieldDescriptor> missingFields = new ArrayList<>();
|
||||
Object payload = readContent();
|
||||
for (FieldDescriptor fieldDescriptor : fieldDescriptors) {
|
||||
if (!fieldDescriptor.isOptional() && !this.fieldProcessor.hasField(
|
||||
JsonFieldPath.compile(fieldDescriptor.getPath()), payload)) {
|
||||
if (!fieldDescriptor.isOptional() && !this.fieldProcessor
|
||||
.hasField(fieldDescriptor.getPath(), payload)) {
|
||||
missingFields.add(fieldDescriptor);
|
||||
}
|
||||
}
|
||||
@@ -65,12 +65,11 @@ class JsonContentHandler implements ContentHandler {
|
||||
public String getUndocumentedContent(List<FieldDescriptor> fieldDescriptors) {
|
||||
Object content = readContent();
|
||||
for (FieldDescriptor fieldDescriptor : fieldDescriptors) {
|
||||
JsonFieldPath path = JsonFieldPath.compile(fieldDescriptor.getPath());
|
||||
if (describesSubsection(fieldDescriptor)) {
|
||||
this.fieldProcessor.removeSubsection(path, content);
|
||||
this.fieldProcessor.removeSubsection(fieldDescriptor.getPath(), content);
|
||||
}
|
||||
else {
|
||||
this.fieldProcessor.remove(path, content);
|
||||
this.fieldProcessor.remove(fieldDescriptor.getPath(), content);
|
||||
}
|
||||
}
|
||||
if (!isEmpty(content)) {
|
||||
@@ -107,7 +106,7 @@ class JsonContentHandler implements ContentHandler {
|
||||
@Override
|
||||
public Object determineFieldType(FieldDescriptor fieldDescriptor) {
|
||||
if (fieldDescriptor.getType() == null) {
|
||||
return this.fieldTypeResolver.resolveFieldType(fieldDescriptor.getPath(),
|
||||
return this.fieldTypeResolver.resolveFieldType(fieldDescriptor,
|
||||
readContent());
|
||||
}
|
||||
if (!(fieldDescriptor.getType() instanceof JsonFieldType)) {
|
||||
@@ -116,7 +115,7 @@ class JsonContentHandler implements ContentHandler {
|
||||
JsonFieldType descriptorFieldType = (JsonFieldType) fieldDescriptor.getType();
|
||||
try {
|
||||
JsonFieldType actualFieldType = this.fieldTypeResolver
|
||||
.resolveFieldType(fieldDescriptor.getPath(), readContent());
|
||||
.resolveFieldType(fieldDescriptor, readContent());
|
||||
if (descriptorFieldType == JsonFieldType.VARIES
|
||||
|| descriptorFieldType == actualFieldType
|
||||
|| (fieldDescriptor.isOptional()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2015 the original author or authors.
|
||||
* Copyright 2014-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,7 +27,6 @@ import java.util.regex.Pattern;
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Jeremy Rickard
|
||||
*
|
||||
*/
|
||||
final class JsonFieldPath {
|
||||
|
||||
@@ -41,24 +40,16 @@ final class JsonFieldPath {
|
||||
|
||||
private final List<String> segments;
|
||||
|
||||
private final boolean precise;
|
||||
private final PathType type;
|
||||
|
||||
private final boolean array;
|
||||
|
||||
private JsonFieldPath(String rawPath, List<String> segments, boolean precise,
|
||||
boolean array) {
|
||||
private JsonFieldPath(String rawPath, List<String> segments, PathType type) {
|
||||
this.rawPath = rawPath;
|
||||
this.segments = segments;
|
||||
this.precise = precise;
|
||||
this.array = array;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
boolean isPrecise() {
|
||||
return this.precise;
|
||||
}
|
||||
|
||||
boolean isArray() {
|
||||
return this.array;
|
||||
PathType getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
List<String> getSegments() {
|
||||
@@ -72,9 +63,8 @@ final class JsonFieldPath {
|
||||
|
||||
static JsonFieldPath compile(String path) {
|
||||
List<String> segments = extractSegments(path);
|
||||
String leafSegment = segments.get(segments.size() - 1);
|
||||
return new JsonFieldPath(path, segments, matchesSingleValue(segments),
|
||||
isArraySegment(leafSegment) || isWildcardSegment(leafSegment));
|
||||
return new JsonFieldPath(path, segments,
|
||||
matchesSingleValue(segments) ? PathType.SINGLE : PathType.MULTI);
|
||||
}
|
||||
|
||||
static boolean isArraySegment(String segment) {
|
||||
@@ -84,8 +74,9 @@ final class JsonFieldPath {
|
||||
static boolean matchesSingleValue(List<String> segments) {
|
||||
Iterator<String> iterator = segments.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
String next = iterator.next();
|
||||
if ((isArraySegment(next) || isWildcardSegment(next)) && iterator.hasNext()) {
|
||||
String segment = iterator.next();
|
||||
if ((isArraySegment(segment) && iterator.hasNext())
|
||||
|| isWildcardSegment(segment)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -132,4 +123,19 @@ final class JsonFieldPath {
|
||||
}
|
||||
return segments;
|
||||
}
|
||||
|
||||
static enum PathType {
|
||||
|
||||
/**
|
||||
* The path identifies a single item in the payload
|
||||
*/
|
||||
SINGLE,
|
||||
|
||||
/**
|
||||
* The path identifies multiple items in the payload
|
||||
*/
|
||||
MULTI;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.restdocs.payload.JsonFieldPath.PathType;
|
||||
|
||||
/**
|
||||
* A {@code JsonFieldProcessor} processes a payload's fields, allowing them to be
|
||||
* extracted and removed.
|
||||
@@ -31,15 +33,16 @@ import java.util.Map;
|
||||
*/
|
||||
final class JsonFieldProcessor {
|
||||
|
||||
boolean hasField(final JsonFieldPath fieldPath, Object payload) {
|
||||
boolean hasField(String path, Object payload) {
|
||||
HasFieldMatchCallback callback = new HasFieldMatchCallback();
|
||||
traverse(new ProcessingContext(payload, fieldPath), callback);
|
||||
traverse(new ProcessingContext(payload, JsonFieldPath.compile(path)), callback);
|
||||
return callback.fieldFound();
|
||||
}
|
||||
|
||||
Object extract(JsonFieldPath path, Object payload) {
|
||||
ExtractedField extract(String path, Object payload) {
|
||||
JsonFieldPath compiledPath = JsonFieldPath.compile(path);
|
||||
final List<Object> matches = new ArrayList<>();
|
||||
traverse(new ProcessingContext(payload, path), new MatchCallback() {
|
||||
traverse(new ProcessingContext(payload, compiledPath), new MatchCallback() {
|
||||
|
||||
@Override
|
||||
public void foundMatch(Match match) {
|
||||
@@ -55,44 +58,43 @@ final class JsonFieldProcessor {
|
||||
if (matches.isEmpty()) {
|
||||
throw new FieldDoesNotExistException(path);
|
||||
}
|
||||
if ((!path.isArray()) && path.isPrecise()) {
|
||||
return matches.get(0);
|
||||
}
|
||||
else {
|
||||
return matches;
|
||||
}
|
||||
return new ExtractedField(
|
||||
compiledPath.getType() == PathType.SINGLE ? matches.get(0) : matches,
|
||||
compiledPath.getType());
|
||||
}
|
||||
|
||||
void remove(final JsonFieldPath path, Object payload) {
|
||||
traverse(new ProcessingContext(payload, path), new MatchCallback() {
|
||||
void remove(String path, Object payload) {
|
||||
traverse(new ProcessingContext(payload, JsonFieldPath.compile(path)),
|
||||
new MatchCallback() {
|
||||
|
||||
@Override
|
||||
public void foundMatch(Match match) {
|
||||
match.remove();
|
||||
}
|
||||
@Override
|
||||
public void foundMatch(Match match) {
|
||||
match.remove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void absent() {
|
||||
@Override
|
||||
public void absent() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void removeSubsection(final JsonFieldPath path, Object payload) {
|
||||
traverse(new ProcessingContext(payload, path), new MatchCallback() {
|
||||
void removeSubsection(String path, Object payload) {
|
||||
traverse(new ProcessingContext(payload, JsonFieldPath.compile(path)),
|
||||
new MatchCallback() {
|
||||
|
||||
@Override
|
||||
public void foundMatch(Match match) {
|
||||
match.removeSubsection();
|
||||
}
|
||||
@Override
|
||||
public void foundMatch(Match match) {
|
||||
match.removeSubsection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void absent() {
|
||||
@Override
|
||||
public void absent() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private void traverse(ProcessingContext context, MatchCallback matchCallback) {
|
||||
@@ -115,6 +117,22 @@ final class JsonFieldProcessor {
|
||||
|
||||
private void handleCollectionPayload(Collection<?> collection,
|
||||
MatchCallback matchCallback, ProcessingContext context) {
|
||||
if (context.isLeaf()) {
|
||||
matchCallback.foundMatch(
|
||||
new LeafCollectionMatch(collection, context.getParentMatch()));
|
||||
}
|
||||
else {
|
||||
Iterator<?> items = collection.iterator();
|
||||
while (items.hasNext()) {
|
||||
Object item = items.next();
|
||||
traverse(context.descend(item, new CollectionMatch(items, collection,
|
||||
item, context.getParentMatch())), matchCallback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleWildcardPayload(Collection<?> collection,
|
||||
MatchCallback matchCallback, ProcessingContext context) {
|
||||
Iterator<?> items = collection.iterator();
|
||||
if (context.isLeaf()) {
|
||||
while (items.hasNext()) {
|
||||
@@ -147,7 +165,7 @@ final class JsonFieldProcessor {
|
||||
}
|
||||
}
|
||||
else if ("*".equals(context.getSegment())) {
|
||||
handleCollectionPayload(map.values(), matchCallback, context);
|
||||
handleWildcardPayload(map.values(), matchCallback, context);
|
||||
}
|
||||
else {
|
||||
matchCallback.absent();
|
||||
@@ -309,6 +327,51 @@ final class JsonFieldProcessor {
|
||||
|
||||
}
|
||||
|
||||
private static class LeafCollectionMatch implements Match {
|
||||
|
||||
private final Collection<?> collection;
|
||||
|
||||
private final Match parent;
|
||||
|
||||
public LeafCollectionMatch(Collection<?> collection, Match parent) {
|
||||
this.collection = collection;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<?> getValue() {
|
||||
return this.collection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
if (containsOnlyScalars(this.collection)) {
|
||||
this.collection.clear();
|
||||
if (this.parent != null) {
|
||||
this.parent.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeSubsection() {
|
||||
this.collection.clear();
|
||||
if (this.parent != null) {
|
||||
this.parent.removeSubsection();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean containsOnlyScalars(Collection<?> collection) {
|
||||
for (Object item : collection) {
|
||||
if (item instanceof Collection || item instanceof Map) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private interface MatchCallback {
|
||||
|
||||
void foundMatch(Match match);
|
||||
@@ -371,4 +434,25 @@ final class JsonFieldProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
static class ExtractedField {
|
||||
|
||||
private final Object value;
|
||||
|
||||
private final PathType type;
|
||||
|
||||
ExtractedField(Object value, PathType type) {
|
||||
this.value = value;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
Object getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
PathType getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2015 the original author or authors.
|
||||
* Copyright 2014-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,9 @@ package org.springframework.restdocs.payload;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.restdocs.payload.JsonFieldPath.PathType;
|
||||
import org.springframework.restdocs.payload.JsonFieldProcessor.ExtractedField;
|
||||
|
||||
/**
|
||||
* Resolves the type of a field in a JSON request or response payload.
|
||||
*
|
||||
@@ -28,23 +31,32 @@ class JsonFieldTypeResolver {
|
||||
|
||||
private final JsonFieldProcessor fieldProcessor = new JsonFieldProcessor();
|
||||
|
||||
JsonFieldType resolveFieldType(String path, Object payload) {
|
||||
JsonFieldPath fieldPath = JsonFieldPath.compile(path);
|
||||
Object field = this.fieldProcessor.extract(fieldPath, payload);
|
||||
if (field instanceof Collection && !fieldPath.isPrecise()) {
|
||||
JsonFieldType resolveFieldType(FieldDescriptor fieldDescriptor, Object payload) {
|
||||
ExtractedField extractedField = this.fieldProcessor
|
||||
.extract(fieldDescriptor.getPath(), payload);
|
||||
Object value = extractedField.getValue();
|
||||
if (value instanceof Collection && extractedField.getType() == PathType.MULTI) {
|
||||
JsonFieldType commonType = null;
|
||||
for (Object item : (Collection<?>) field) {
|
||||
for (Object item : (Collection<?>) value) {
|
||||
JsonFieldType fieldType = determineFieldType(item);
|
||||
if (commonType == null) {
|
||||
commonType = fieldType;
|
||||
}
|
||||
else if (fieldType != commonType && fieldType != JsonFieldType.NULL) {
|
||||
return JsonFieldType.VARIES;
|
||||
else if (fieldType != commonType) {
|
||||
if (!fieldDescriptor.isOptional()) {
|
||||
return JsonFieldType.VARIES;
|
||||
}
|
||||
if (commonType == JsonFieldType.NULL) {
|
||||
commonType = fieldType;
|
||||
}
|
||||
else if (fieldType != JsonFieldType.NULL) {
|
||||
return JsonFieldType.VARIES;
|
||||
}
|
||||
}
|
||||
}
|
||||
return commonType;
|
||||
}
|
||||
return determineFieldType(field);
|
||||
return determineFieldType(value);
|
||||
}
|
||||
|
||||
private JsonFieldType determineFieldType(Object fieldValue) {
|
||||
|
||||
@@ -44,7 +44,57 @@ public class JsonContentHandlerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeForOptionalFieldWithNullValueDoesNotHaveToMatch() throws IOException {
|
||||
public void typeForFieldWithNotNullAndThenNullValueMustMatch() throws IOException {
|
||||
this.thrown.expect(FieldTypesDoNotMatchException.class);
|
||||
new JsonContentHandler("{\"a\":[{\"id\":1},{\"id\":null}]}".getBytes())
|
||||
.determineFieldType(
|
||||
new FieldDescriptor("a[].id").type(JsonFieldType.STRING));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeForFieldWithNullAndThenNotNullValueMustMatch() throws IOException {
|
||||
this.thrown.expect(FieldTypesDoNotMatchException.class);
|
||||
new JsonContentHandler("{\"a\":[{\"id\":null},{\"id\":1}]}".getBytes())
|
||||
.determineFieldType(
|
||||
new FieldDescriptor("a.[].id").type(JsonFieldType.STRING));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeForOptionalFieldWithNumberAndThenNullValueIsNumber()
|
||||
throws IOException {
|
||||
Object fieldType = new JsonContentHandler(
|
||||
"{\"a\":[{\"id\":1},{\"id\":null}]}\"".getBytes())
|
||||
.determineFieldType(new FieldDescriptor("a[].id").optional());
|
||||
assertThat((JsonFieldType) fieldType, is(equalTo(JsonFieldType.NUMBER)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeForOptionalFieldWithNullAndThenNumberIsNumber() throws IOException {
|
||||
Object fieldType = new JsonContentHandler(
|
||||
"{\"a\":[{\"id\":null},{\"id\":1}]}".getBytes())
|
||||
.determineFieldType(new FieldDescriptor("a[].id").optional());
|
||||
assertThat((JsonFieldType) fieldType, is(equalTo(JsonFieldType.NUMBER)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeForFieldWithNumberAndThenNullValueIsVaries() throws IOException {
|
||||
Object fieldType = new JsonContentHandler(
|
||||
"{\"a\":[{\"id\":1},{\"id\":null}]}\"".getBytes())
|
||||
.determineFieldType(new FieldDescriptor("a[].id"));
|
||||
assertThat((JsonFieldType) fieldType, is(equalTo(JsonFieldType.VARIES)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeForFieldWithNullAndThenNumberIsVaries() throws IOException {
|
||||
Object fieldType = new JsonContentHandler(
|
||||
"{\"a\":[{\"id\":null},{\"id\":1}]}".getBytes())
|
||||
.determineFieldType(new FieldDescriptor("a[].id"));
|
||||
assertThat((JsonFieldType) fieldType, is(equalTo(JsonFieldType.VARIES)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeForOptionalFieldWithNullValueCanBeProvidedExplicitly()
|
||||
throws IOException {
|
||||
Object fieldType = new JsonContentHandler("{\"a\": null}".getBytes())
|
||||
.determineFieldType(
|
||||
new FieldDescriptor("a").type(JsonFieldType.STRING).optional());
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2015 the original author or authors.
|
||||
* Copyright 2014-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,10 +18,12 @@ package org.springframework.restdocs.payload;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.restdocs.payload.JsonFieldPath.PathType;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Tests for {@link JsonFieldPath}.
|
||||
@@ -32,59 +34,69 @@ import static org.junit.Assert.assertTrue;
|
||||
public class JsonFieldPathTests {
|
||||
|
||||
@Test
|
||||
public void singleFieldIsPreciseAndNotAnArray() {
|
||||
public void pathTypeOfSingleFieldIsSingle() {
|
||||
JsonFieldPath path = JsonFieldPath.compile("a");
|
||||
assertTrue(path.isPrecise());
|
||||
assertFalse(path.isArray());
|
||||
assertThat(path.getType(), is(equalTo(PathType.SINGLE)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singleNestedFieldIsPreciseAndNotAnArray() {
|
||||
public void pathTypeOfSingleNestedFieldIsSingle() {
|
||||
JsonFieldPath path = JsonFieldPath.compile("a.b");
|
||||
assertTrue(path.isPrecise());
|
||||
assertFalse(path.isArray());
|
||||
assertThat(path.getType(), is(equalTo(PathType.SINGLE)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void topLevelArrayIsPreciseAndAnArray() {
|
||||
public void pathTypeOfTopLevelArrayIsSingle() {
|
||||
JsonFieldPath path = JsonFieldPath.compile("[]");
|
||||
assertTrue(path.isPrecise());
|
||||
assertTrue(path.isArray());
|
||||
assertThat(path.getType(), is(equalTo(PathType.SINGLE)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fieldBeneathTopLevelArrayIsNotPreciseAndNotAnArray() {
|
||||
public void pathTypeOfFieldBeneathTopLevelArrayIsMulti() {
|
||||
JsonFieldPath path = JsonFieldPath.compile("[]a");
|
||||
assertFalse(path.isPrecise());
|
||||
assertFalse(path.isArray());
|
||||
assertThat(path.getType(), is(equalTo(PathType.MULTI)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void arrayIsPreciseAndAnArray() {
|
||||
public void pathTypeOfSingleNestedArrayIsSingle() {
|
||||
JsonFieldPath path = JsonFieldPath.compile("a[]");
|
||||
assertTrue(path.isPrecise());
|
||||
assertTrue(path.isArray());
|
||||
assertThat(path.getType(), is(equalTo(PathType.SINGLE)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nestedArrayIsPreciseAndAnArray() {
|
||||
public void pathTypeOfArrayBeneathNestedFieldsIsSingle() {
|
||||
JsonFieldPath path = JsonFieldPath.compile("a.b[]");
|
||||
assertTrue(path.isPrecise());
|
||||
assertTrue(path.isArray());
|
||||
assertThat(path.getType(), is(equalTo(PathType.SINGLE)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void arrayOfArraysIsNotPreciseAndIsAnArray() {
|
||||
public void pathTypeOfArrayOfArraysIsMulti() {
|
||||
JsonFieldPath path = JsonFieldPath.compile("a[][]");
|
||||
assertFalse(path.isPrecise());
|
||||
assertTrue(path.isArray());
|
||||
assertThat(path.getType(), is(equalTo(PathType.MULTI)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fieldBeneathAnArrayIsNotPreciseAndIsNotAnArray() {
|
||||
public void pathTypeOfFieldBeneathAnArrayIsMulti() {
|
||||
JsonFieldPath path = JsonFieldPath.compile("a[].b");
|
||||
assertFalse(path.isPrecise());
|
||||
assertFalse(path.isArray());
|
||||
assertThat(path.getType(), is(equalTo(PathType.MULTI)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pathTypeOfFieldBeneathTopLevelWildcardIsMulti() {
|
||||
JsonFieldPath path = JsonFieldPath.compile("*.a");
|
||||
assertThat(path.getType(), is(equalTo(PathType.MULTI)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pathTypeOfFieldBeneathNestedWildcardIsMulti() {
|
||||
JsonFieldPath path = JsonFieldPath.compile("a.*.b");
|
||||
assertThat(path.getType(), is(equalTo(PathType.MULTI)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pathTypeOfLeafWidlcardIsMulti() {
|
||||
JsonFieldPath path = JsonFieldPath.compile("a.*");
|
||||
assertThat(path.getType(), is(equalTo(PathType.MULTI)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -157,18 +169,4 @@ public class JsonFieldPathTests {
|
||||
contains("a", "b", "*", "c"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fieldBeneathTopLevelWildcardIsNotPreciseAndNotAnArray() {
|
||||
JsonFieldPath path = JsonFieldPath.compile("*.a");
|
||||
assertFalse(path.isPrecise());
|
||||
assertFalse(path.isArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fieldBeneathNestedWildcardIsNotPreciseAndNotAnArray() {
|
||||
JsonFieldPath path = JsonFieldPath.compile("a.*.b");
|
||||
assertFalse(path.isPrecise());
|
||||
assertFalse(path.isArray());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.restdocs.payload;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
@@ -48,7 +49,7 @@ public class JsonFieldProcessorTests {
|
||||
public void extractTopLevelMapEntry() {
|
||||
Map<String, Object> payload = new HashMap<>();
|
||||
payload.put("a", "alpha");
|
||||
assertThat(this.fieldProcessor.extract(JsonFieldPath.compile("a"), payload),
|
||||
assertThat(this.fieldProcessor.extract("a", payload).getValue(),
|
||||
equalTo((Object) "alpha"));
|
||||
}
|
||||
|
||||
@@ -58,7 +59,7 @@ public class JsonFieldProcessorTests {
|
||||
Map<String, Object> alpha = new HashMap<>();
|
||||
payload.put("a", alpha);
|
||||
alpha.put("b", "bravo");
|
||||
assertThat(this.fieldProcessor.extract(JsonFieldPath.compile("a.b"), payload),
|
||||
assertThat(this.fieldProcessor.extract("a.b", payload).getValue(),
|
||||
equalTo((Object) "bravo"));
|
||||
}
|
||||
|
||||
@@ -69,7 +70,7 @@ public class JsonFieldProcessorTests {
|
||||
bravo.put("b", "bravo");
|
||||
payload.add(bravo);
|
||||
payload.add(bravo);
|
||||
assertThat(this.fieldProcessor.extract(JsonFieldPath.compile("[]"), payload),
|
||||
assertThat(this.fieldProcessor.extract("[]", payload).getValue(),
|
||||
equalTo((Object) payload));
|
||||
}
|
||||
|
||||
@@ -80,7 +81,7 @@ public class JsonFieldProcessorTests {
|
||||
bravo.put("b", "bravo");
|
||||
List<Map<String, Object>> alpha = Arrays.asList(bravo, bravo);
|
||||
payload.put("a", alpha);
|
||||
assertThat(this.fieldProcessor.extract(JsonFieldPath.compile("a"), payload),
|
||||
assertThat(this.fieldProcessor.extract("a", payload).getValue(),
|
||||
equalTo((Object) alpha));
|
||||
}
|
||||
|
||||
@@ -91,7 +92,7 @@ public class JsonFieldProcessorTests {
|
||||
bravo.put("b", "bravo");
|
||||
List<Map<String, Object>> alpha = Arrays.asList(bravo, bravo);
|
||||
payload.put("a", alpha);
|
||||
assertThat(this.fieldProcessor.extract(JsonFieldPath.compile("a[]"), payload),
|
||||
assertThat(this.fieldProcessor.extract("a[]", payload).getValue(),
|
||||
equalTo((Object) alpha));
|
||||
}
|
||||
|
||||
@@ -102,7 +103,7 @@ public class JsonFieldProcessorTests {
|
||||
entry.put("b", "bravo");
|
||||
List<Map<String, Object>> alpha = Arrays.asList(entry, entry);
|
||||
payload.put("a", alpha);
|
||||
assertThat(this.fieldProcessor.extract(JsonFieldPath.compile("a[].b"), payload),
|
||||
assertThat(this.fieldProcessor.extract("a[].b", payload).getValue(),
|
||||
equalTo((Object) Arrays.asList("bravo", "bravo")));
|
||||
}
|
||||
|
||||
@@ -114,7 +115,7 @@ public class JsonFieldProcessorTests {
|
||||
List<Map<String, Object>> alpha = Arrays.asList(entry,
|
||||
new HashMap<String, Object>());
|
||||
payload.put("a", alpha);
|
||||
assertThat(this.fieldProcessor.extract(JsonFieldPath.compile("a[].b"), payload),
|
||||
assertThat(this.fieldProcessor.extract("a[].b", payload).getValue(),
|
||||
equalTo((Object) Arrays.asList("bravo")));
|
||||
}
|
||||
|
||||
@@ -127,7 +128,7 @@ public class JsonFieldProcessorTests {
|
||||
nullField.put("b", null);
|
||||
List<Map<String, Object>> alpha = Arrays.asList(nonNullField, nullField);
|
||||
payload.put("a", alpha);
|
||||
assertThat(this.fieldProcessor.extract(JsonFieldPath.compile("a[].b"), payload),
|
||||
assertThat(this.fieldProcessor.extract("a[].b", payload).getValue(),
|
||||
equalTo((Object) Arrays.asList("bravo", null)));
|
||||
}
|
||||
|
||||
@@ -140,8 +141,9 @@ public class JsonFieldProcessorTests {
|
||||
List<List<Map<String, String>>> alpha = Arrays
|
||||
.asList(Arrays.asList(entry1, entry2), Arrays.asList(entry3));
|
||||
payload.put("a", alpha);
|
||||
assertThat(this.fieldProcessor.extract(JsonFieldPath.compile("a[][]"), payload),
|
||||
equalTo((Object) Arrays.asList(entry1, entry2, entry3)));
|
||||
assertThat(this.fieldProcessor.extract("a[][]", payload).getValue(),
|
||||
equalTo((Object) Arrays.asList(Arrays.asList(entry1, entry2),
|
||||
Arrays.asList(entry3))));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -153,8 +155,7 @@ public class JsonFieldProcessorTests {
|
||||
List<List<Map<String, String>>> alpha = Arrays
|
||||
.asList(Arrays.asList(entry1, entry2), Arrays.asList(entry3));
|
||||
payload.put("a", alpha);
|
||||
assertThat(
|
||||
this.fieldProcessor.extract(JsonFieldPath.compile("a[][].id"), payload),
|
||||
assertThat(this.fieldProcessor.extract("a[][].id", payload).getValue(),
|
||||
equalTo((Object) Arrays.asList("1", "2", "3")));
|
||||
}
|
||||
|
||||
@@ -167,30 +168,28 @@ public class JsonFieldProcessorTests {
|
||||
List<List<Map<String, Object>>> alpha = Arrays
|
||||
.asList(Arrays.asList(entry1, entry2), Arrays.asList(entry3));
|
||||
payload.put("a", alpha);
|
||||
assertThat(
|
||||
this.fieldProcessor.extract(JsonFieldPath.compile("a[][].ids"), payload),
|
||||
assertThat(this.fieldProcessor.extract("a[][].ids", payload).getValue(),
|
||||
equalTo((Object) Arrays.asList(Arrays.asList(1, 2), Arrays.asList(3),
|
||||
Arrays.asList(4))));
|
||||
}
|
||||
|
||||
@Test(expected = FieldDoesNotExistException.class)
|
||||
public void nonExistentTopLevelField() {
|
||||
this.fieldProcessor.extract(JsonFieldPath.compile("a"),
|
||||
new HashMap<String, Object>());
|
||||
this.fieldProcessor.extract("a", Collections.emptyMap()).getValue();
|
||||
}
|
||||
|
||||
@Test(expected = FieldDoesNotExistException.class)
|
||||
public void nonExistentNestedField() {
|
||||
HashMap<String, Object> payload = new HashMap<>();
|
||||
payload.put("a", new HashMap<String, Object>());
|
||||
this.fieldProcessor.extract(JsonFieldPath.compile("a.b"), payload);
|
||||
this.fieldProcessor.extract("a.b", payload).getValue();
|
||||
}
|
||||
|
||||
@Test(expected = FieldDoesNotExistException.class)
|
||||
public void nonExistentNestedFieldWhenParentIsNotAMap() {
|
||||
HashMap<String, Object> payload = new HashMap<>();
|
||||
payload.put("a", 5);
|
||||
this.fieldProcessor.extract(JsonFieldPath.compile("a.b"), payload);
|
||||
this.fieldProcessor.extract("a.b", payload).getValue();
|
||||
}
|
||||
|
||||
@Test(expected = FieldDoesNotExistException.class)
|
||||
@@ -199,20 +198,20 @@ public class JsonFieldProcessorTests {
|
||||
HashMap<String, Object> alpha = new HashMap<>();
|
||||
alpha.put("b", Arrays.asList(new HashMap<String, Object>()));
|
||||
payload.put("a", alpha);
|
||||
this.fieldProcessor.extract(JsonFieldPath.compile("a.b.c"), payload);
|
||||
this.fieldProcessor.extract("a.b.c", payload).getValue();
|
||||
}
|
||||
|
||||
@Test(expected = FieldDoesNotExistException.class)
|
||||
public void nonExistentArrayField() {
|
||||
HashMap<String, Object> payload = new HashMap<>();
|
||||
this.fieldProcessor.extract(JsonFieldPath.compile("a[]"), payload);
|
||||
this.fieldProcessor.extract("a[]", payload).getValue();
|
||||
}
|
||||
|
||||
@Test(expected = FieldDoesNotExistException.class)
|
||||
public void nonExistentArrayFieldAsTypeDoesNotMatch() {
|
||||
HashMap<String, Object> payload = new HashMap<>();
|
||||
payload.put("a", 5);
|
||||
this.fieldProcessor.extract(JsonFieldPath.compile("a[]"), payload);
|
||||
this.fieldProcessor.extract("a[]", payload).getValue();
|
||||
}
|
||||
|
||||
@Test(expected = FieldDoesNotExistException.class)
|
||||
@@ -221,14 +220,14 @@ public class JsonFieldProcessorTests {
|
||||
HashMap<String, Object> alpha = new HashMap<>();
|
||||
alpha.put("b", Arrays.asList(new HashMap<String, Object>()));
|
||||
payload.put("a", alpha);
|
||||
this.fieldProcessor.extract(JsonFieldPath.compile("a.b[].id"), payload);
|
||||
this.fieldProcessor.extract("a.b[].id", payload).getValue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removeTopLevelMapEntry() {
|
||||
Map<String, Object> payload = new HashMap<>();
|
||||
payload.put("a", "alpha");
|
||||
this.fieldProcessor.remove(JsonFieldPath.compile("a"), payload);
|
||||
this.fieldProcessor.remove("a", payload);
|
||||
assertThat(payload.size(), equalTo(0));
|
||||
}
|
||||
|
||||
@@ -238,7 +237,7 @@ public class JsonFieldProcessorTests {
|
||||
Map<String, Object> alpha = new HashMap<>();
|
||||
payload.put("a", alpha);
|
||||
alpha.put("b", "bravo");
|
||||
this.fieldProcessor.remove(JsonFieldPath.compile("a"), payload);
|
||||
this.fieldProcessor.remove("a", payload);
|
||||
assertThat(payload.size(), equalTo(1));
|
||||
}
|
||||
|
||||
@@ -248,7 +247,7 @@ public class JsonFieldProcessorTests {
|
||||
Map<String, Object> alpha = new HashMap<>();
|
||||
payload.put("a", alpha);
|
||||
alpha.put("b", "bravo");
|
||||
this.fieldProcessor.removeSubsection(JsonFieldPath.compile("a"), payload);
|
||||
this.fieldProcessor.removeSubsection("a", payload);
|
||||
assertThat(payload.size(), equalTo(0));
|
||||
}
|
||||
|
||||
@@ -258,7 +257,7 @@ public class JsonFieldProcessorTests {
|
||||
Map<String, Object> alpha = new HashMap<>();
|
||||
payload.put("a", alpha);
|
||||
alpha.put("b", "bravo");
|
||||
this.fieldProcessor.remove(JsonFieldPath.compile("a.b"), payload);
|
||||
this.fieldProcessor.remove("a.b", payload);
|
||||
assertThat(payload.size(), equalTo(0));
|
||||
}
|
||||
|
||||
@@ -267,7 +266,7 @@ public class JsonFieldProcessorTests {
|
||||
public void removeItemsInArray() throws IOException {
|
||||
Map<String, Object> payload = new ObjectMapper()
|
||||
.readValue("{\"a\": [{\"b\":\"bravo\"},{\"b\":\"bravo\"}]}", Map.class);
|
||||
this.fieldProcessor.remove(JsonFieldPath.compile("a[].b"), payload);
|
||||
this.fieldProcessor.remove("a[].b", payload);
|
||||
assertThat(payload.size(), equalTo(0));
|
||||
}
|
||||
|
||||
@@ -276,7 +275,7 @@ public class JsonFieldProcessorTests {
|
||||
public void removeItemsInNestedArray() throws IOException {
|
||||
Map<String, Object> payload = new ObjectMapper()
|
||||
.readValue("{\"a\": [[{\"id\":1},{\"id\":2}], [{\"id\":3}]]}", Map.class);
|
||||
this.fieldProcessor.remove(JsonFieldPath.compile("a[][].id"), payload);
|
||||
this.fieldProcessor.remove("a[][].id", payload);
|
||||
assertThat(payload.size(), equalTo(0));
|
||||
}
|
||||
|
||||
@@ -285,7 +284,7 @@ public class JsonFieldProcessorTests {
|
||||
public void removeDoesNotRemoveArrayWithMapEntries() throws IOException {
|
||||
Map<String, Object> payload = new ObjectMapper()
|
||||
.readValue("{\"a\": [{\"b\":\"bravo\"},{\"b\":\"bravo\"}]}", Map.class);
|
||||
this.fieldProcessor.remove(JsonFieldPath.compile("a[]"), payload);
|
||||
this.fieldProcessor.remove("a[]", payload);
|
||||
assertThat(payload.size(), equalTo(1));
|
||||
}
|
||||
|
||||
@@ -294,7 +293,7 @@ public class JsonFieldProcessorTests {
|
||||
public void removeDoesNotRemoveArrayWithListEntries() throws IOException {
|
||||
Map<String, Object> payload = new ObjectMapper().readValue("{\"a\": [[2],[3]]}",
|
||||
Map.class);
|
||||
this.fieldProcessor.remove(JsonFieldPath.compile("a[]"), payload);
|
||||
this.fieldProcessor.remove("a[]", payload);
|
||||
assertThat(payload.size(), equalTo(1));
|
||||
}
|
||||
|
||||
@@ -303,7 +302,7 @@ public class JsonFieldProcessorTests {
|
||||
public void removeRemovesArrayWithOnlyScalarEntries() throws IOException {
|
||||
Map<String, Object> payload = new ObjectMapper()
|
||||
.readValue("{\"a\": [\"bravo\", \"charlie\"]}", Map.class);
|
||||
this.fieldProcessor.remove(JsonFieldPath.compile("a"), payload);
|
||||
this.fieldProcessor.remove("a", payload);
|
||||
assertThat(payload.size(), equalTo(0));
|
||||
}
|
||||
|
||||
@@ -312,7 +311,7 @@ public class JsonFieldProcessorTests {
|
||||
public void removeSubsectionRemovesArrayWithMapEntries() throws IOException {
|
||||
Map<String, Object> payload = new ObjectMapper()
|
||||
.readValue("{\"a\": [{\"b\":\"bravo\"},{\"b\":\"bravo\"}]}", Map.class);
|
||||
this.fieldProcessor.removeSubsection(JsonFieldPath.compile("a[]"), payload);
|
||||
this.fieldProcessor.removeSubsection("a[]", payload);
|
||||
assertThat(payload.size(), equalTo(0));
|
||||
}
|
||||
|
||||
@@ -321,7 +320,7 @@ public class JsonFieldProcessorTests {
|
||||
public void removeSubsectionRemovesArrayWithListEntries() throws IOException {
|
||||
Map<String, Object> payload = new ObjectMapper().readValue("{\"a\": [[2],[3]]}",
|
||||
Map.class);
|
||||
this.fieldProcessor.removeSubsection(JsonFieldPath.compile("a[]"), payload);
|
||||
this.fieldProcessor.removeSubsection("a[]", payload);
|
||||
assertThat(payload.size(), equalTo(0));
|
||||
}
|
||||
|
||||
@@ -331,8 +330,7 @@ public class JsonFieldProcessorTests {
|
||||
Map<String, Object> alpha = new HashMap<>();
|
||||
payload.put("a.key", alpha);
|
||||
alpha.put("b.key", "bravo");
|
||||
assertThat(this.fieldProcessor
|
||||
.extract(JsonFieldPath.compile("['a.key']['b.key']"), payload),
|
||||
assertThat(this.fieldProcessor.extract("['a.key']['b.key']", payload).getValue(),
|
||||
equalTo((Object) "bravo"));
|
||||
}
|
||||
|
||||
@@ -346,8 +344,7 @@ public class JsonFieldProcessorTests {
|
||||
Map<String, Object> charlie = new LinkedHashMap<>();
|
||||
charlie.put("b", "bravo2");
|
||||
payload.put("c", charlie);
|
||||
assertThat((List<String>) this.fieldProcessor
|
||||
.extract(JsonFieldPath.compile("*.b"), payload),
|
||||
assertThat((List<String>) this.fieldProcessor.extract("*.b", payload).getValue(),
|
||||
contains("bravo1", "bravo2"));
|
||||
}
|
||||
|
||||
@@ -361,8 +358,8 @@ public class JsonFieldProcessorTests {
|
||||
bravo.put("b", "bravo");
|
||||
alpha.put("one", bravo);
|
||||
alpha.put("two", bravo);
|
||||
assertThat((List<String>) this.fieldProcessor
|
||||
.extract(JsonFieldPath.compile("a.*.b"), payload),
|
||||
assertThat(
|
||||
(List<String>) this.fieldProcessor.extract("a.*.b", payload).getValue(),
|
||||
contains("bravo", "bravo"));
|
||||
}
|
||||
|
||||
@@ -376,8 +373,8 @@ public class JsonFieldProcessorTests {
|
||||
Map<String, Object> charlie = new HashMap<>();
|
||||
charlie.put("b", "bravo2");
|
||||
payload.put("c", charlie);
|
||||
assertThat((List<String>) this.fieldProcessor
|
||||
.extract(JsonFieldPath.compile("a.*"), payload), contains("bravo1"));
|
||||
assertThat((List<String>) this.fieldProcessor.extract("a.*", payload).getValue(),
|
||||
contains("bravo1"));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -388,8 +385,7 @@ public class JsonFieldProcessorTests {
|
||||
payload.put("a", alpha);
|
||||
alpha.put("b", "bravo1");
|
||||
alpha.put("c", "charlie");
|
||||
assertThat((List<String>) this.fieldProcessor
|
||||
.extract(JsonFieldPath.compile("a.*"), payload),
|
||||
assertThat((List<String>) this.fieldProcessor.extract("a.*", payload).getValue(),
|
||||
contains("bravo1", "charlie"));
|
||||
}
|
||||
|
||||
@@ -400,7 +396,7 @@ public class JsonFieldProcessorTests {
|
||||
payload.put("a", alpha);
|
||||
alpha.put("b", "bravo1");
|
||||
alpha.put("c", "charlie");
|
||||
this.fieldProcessor.remove(JsonFieldPath.compile("a.*"), payload);
|
||||
this.fieldProcessor.remove("a.*", payload);
|
||||
assertThat(payload.size(), equalTo(0));
|
||||
}
|
||||
|
||||
@@ -411,7 +407,7 @@ public class JsonFieldProcessorTests {
|
||||
payload.put("a", alpha);
|
||||
alpha.put("b", "bravo1");
|
||||
alpha.put("c", "charlie");
|
||||
this.fieldProcessor.remove(JsonFieldPath.compile("*.b"), payload);
|
||||
this.fieldProcessor.remove("*.b", payload);
|
||||
assertThat(alpha, not(hasKey("b")));
|
||||
}
|
||||
|
||||
@@ -427,7 +423,7 @@ public class JsonFieldProcessorTests {
|
||||
Map<String, Object> bravo2 = new LinkedHashMap<>();
|
||||
bravo2.put("b", "bravo");
|
||||
alpha.put("two", bravo2);
|
||||
this.fieldProcessor.remove(JsonFieldPath.compile("a.*.b"), payload);
|
||||
this.fieldProcessor.remove("a.*.b", payload);
|
||||
assertThat(payload.size(), equalTo(1));
|
||||
assertThat(payload, hasEntry("c", (Object) "charlie"));
|
||||
}
|
||||
@@ -436,24 +432,21 @@ public class JsonFieldProcessorTests {
|
||||
public void hasFieldIsTrueForNonNullFieldInMap() throws Exception {
|
||||
Map<String, Object> payload = new HashMap<>();
|
||||
payload.put("a", "alpha");
|
||||
assertThat(this.fieldProcessor.hasField(JsonFieldPath.compile("a"), payload),
|
||||
is(true));
|
||||
assertThat(this.fieldProcessor.hasField("a", payload), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasFieldIsTrueForNullFieldInMap() throws Exception {
|
||||
Map<String, Object> payload = new HashMap<>();
|
||||
payload.put("a", null);
|
||||
assertThat(this.fieldProcessor.hasField(JsonFieldPath.compile("a"), payload),
|
||||
is(true));
|
||||
assertThat(this.fieldProcessor.hasField("a", payload), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasFieldIsFalseForAbsentFieldInMap() throws Exception {
|
||||
Map<String, Object> payload = new HashMap<>();
|
||||
payload.put("a", null);
|
||||
assertThat(this.fieldProcessor.hasField(JsonFieldPath.compile("b"), payload),
|
||||
is(false));
|
||||
assertThat(this.fieldProcessor.hasField("b", payload), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -462,8 +455,7 @@ public class JsonFieldProcessorTests {
|
||||
Map<String, Object> nested = new HashMap<>();
|
||||
nested.put("b", "bravo");
|
||||
payload.put("a", Arrays.asList(nested, nested, nested));
|
||||
assertThat(this.fieldProcessor.hasField(JsonFieldPath.compile("a.[].b"), payload),
|
||||
is(true));
|
||||
assertThat(this.fieldProcessor.hasField("a.[].b", payload), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -472,8 +464,7 @@ public class JsonFieldProcessorTests {
|
||||
Map<String, Object> nested = new HashMap<>();
|
||||
nested.put("b", null);
|
||||
payload.put("a", Arrays.asList(nested, nested, nested));
|
||||
assertThat(this.fieldProcessor.hasField(JsonFieldPath.compile("a.[].b"), payload),
|
||||
is(true));
|
||||
assertThat(this.fieldProcessor.hasField("a.[].b", payload), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -482,8 +473,7 @@ public class JsonFieldProcessorTests {
|
||||
Map<String, Object> nested = new HashMap<>();
|
||||
nested.put("b", "bravo");
|
||||
payload.put("a", Arrays.asList(nested, nested, nested));
|
||||
assertThat(this.fieldProcessor.hasField(JsonFieldPath.compile("a.[].c"), payload),
|
||||
is(false));
|
||||
assertThat(this.fieldProcessor.hasField("a.[].c", payload), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -492,8 +482,7 @@ public class JsonFieldProcessorTests {
|
||||
Map<String, Object> nested = new HashMap<>();
|
||||
nested.put("b", "bravo");
|
||||
payload.put("a", Arrays.asList(nested, new HashMap<>(), nested));
|
||||
assertThat(this.fieldProcessor.hasField(JsonFieldPath.compile("a.[].b"), payload),
|
||||
is(false));
|
||||
assertThat(this.fieldProcessor.hasField("a.[].b", payload), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -504,8 +493,7 @@ public class JsonFieldProcessorTests {
|
||||
Map<String, Object> fieldNull = new HashMap<>();
|
||||
fieldNull.put("b", null);
|
||||
payload.put("a", Arrays.asList(fieldPresent, fieldPresent, fieldNull));
|
||||
assertThat(this.fieldProcessor.hasField(JsonFieldPath.compile("a.[].b"), payload),
|
||||
is(false));
|
||||
assertThat(this.fieldProcessor.hasField("a.[].b", payload), is(false));
|
||||
}
|
||||
|
||||
private Map<String, String> createEntry(String... pairs) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2015 the original author or authors.
|
||||
* Copyright 2014-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,7 +32,6 @@ import static org.junit.Assert.assertThat;
|
||||
* Tests for {@link JsonFieldTypeResolver}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*
|
||||
*/
|
||||
public class JsonFieldTypeResolverTests {
|
||||
|
||||
@@ -49,7 +48,7 @@ public class JsonFieldTypeResolverTests {
|
||||
@Test
|
||||
public void topLevelArray() throws IOException {
|
||||
assertThat(
|
||||
this.fieldTypeResolver.resolveFieldType("[]",
|
||||
this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("[]"),
|
||||
new ObjectMapper().readValue("[{\"a\":\"alpha\"}]", List.class)),
|
||||
equalTo(JsonFieldType.ARRAY));
|
||||
}
|
||||
@@ -57,11 +56,27 @@ public class JsonFieldTypeResolverTests {
|
||||
@Test
|
||||
public void nestedArray() throws IOException {
|
||||
assertThat(
|
||||
this.fieldTypeResolver.resolveFieldType("a[]",
|
||||
this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[]"),
|
||||
createPayload("{\"a\": [{\"b\":\"bravo\"}]}")),
|
||||
equalTo(JsonFieldType.ARRAY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void arrayNestedBeneathAnArray() throws IOException {
|
||||
assertThat(
|
||||
this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].b[]"),
|
||||
createPayload("{\"a\": [{\"b\": [ 1, 2 ]}]}")),
|
||||
equalTo(JsonFieldType.ARRAY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void specificFieldOfObjectInArrayNestedBeneathAnArray() throws IOException {
|
||||
assertThat(
|
||||
this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].b[].c"),
|
||||
createPayload("{\"a\": [{\"b\": [ {\"c\": 5}, {\"c\": 5}]}]}")),
|
||||
equalTo(JsonFieldType.NUMBER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void booleanField() throws IOException {
|
||||
assertFieldType(JsonFieldType.BOOLEAN, "true");
|
||||
@@ -90,7 +105,7 @@ public class JsonFieldTypeResolverTests {
|
||||
@Test
|
||||
public void nestedField() throws IOException {
|
||||
assertThat(
|
||||
this.fieldTypeResolver.resolveFieldType("a.b.c",
|
||||
this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a.b.c"),
|
||||
createPayload("{\"a\":{\"b\":{\"c\":{}}}}")),
|
||||
equalTo(JsonFieldType.OBJECT));
|
||||
}
|
||||
@@ -98,7 +113,7 @@ public class JsonFieldTypeResolverTests {
|
||||
@Test
|
||||
public void multipleFieldsWithSameType() throws IOException {
|
||||
assertThat(
|
||||
this.fieldTypeResolver.resolveFieldType("a[].id",
|
||||
this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id"),
|
||||
createPayload("{\"a\":[{\"id\":1},{\"id\":2}]}")),
|
||||
equalTo(JsonFieldType.NUMBER));
|
||||
}
|
||||
@@ -106,7 +121,7 @@ public class JsonFieldTypeResolverTests {
|
||||
@Test
|
||||
public void multipleFieldsWithDifferentTypes() throws IOException {
|
||||
assertThat(
|
||||
this.fieldTypeResolver.resolveFieldType("a[].id",
|
||||
this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id"),
|
||||
createPayload("{\"a\":[{\"id\":1},{\"id\":true}]}")),
|
||||
equalTo(JsonFieldType.VARIES));
|
||||
}
|
||||
@@ -114,7 +129,17 @@ public class JsonFieldTypeResolverTests {
|
||||
@Test
|
||||
public void multipleFieldsWithDifferentTypesAndSometimesAbsent() throws IOException {
|
||||
assertThat(
|
||||
this.fieldTypeResolver.resolveFieldType("a[].id",
|
||||
this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id"),
|
||||
createPayload("{\"a\":[{\"id\":1},{\"id\":true}, { }]}")),
|
||||
equalTo(JsonFieldType.VARIES));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleFieldsWithDifferentTypesAndSometimesAbsentWhenOptionalResolvesToVaries()
|
||||
throws IOException {
|
||||
assertThat(
|
||||
this.fieldTypeResolver.resolveFieldType(
|
||||
new FieldDescriptor("a[].id").optional(),
|
||||
createPayload("{\"a\":[{\"id\":1},{\"id\":true}, { }]}")),
|
||||
equalTo(JsonFieldType.VARIES));
|
||||
}
|
||||
@@ -122,7 +147,7 @@ public class JsonFieldTypeResolverTests {
|
||||
@Test
|
||||
public void multipleFieldsWhenSometimesAbsent() throws IOException {
|
||||
assertThat(
|
||||
this.fieldTypeResolver.resolveFieldType("a[].id",
|
||||
this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id"),
|
||||
createPayload("{\"a\":[{\"id\":1},{ }]}")),
|
||||
equalTo(JsonFieldType.NUMBER));
|
||||
}
|
||||
@@ -130,24 +155,54 @@ public class JsonFieldTypeResolverTests {
|
||||
@Test
|
||||
public void multipleFieldsWithDifferentTypesAndSometimesNull() throws IOException {
|
||||
assertThat(
|
||||
this.fieldTypeResolver.resolveFieldType("a[].id",
|
||||
this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id"),
|
||||
createPayload(
|
||||
"{\"a\":[{\"id\":1},{\"id\":true}, {\"id\":null}]}")),
|
||||
equalTo(JsonFieldType.VARIES));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleFieldsWhenSometimesNull() throws IOException {
|
||||
public void multipleFieldsWhenNotNullThenNullWhenRequiredHasVariesType()
|
||||
throws IOException {
|
||||
assertThat(
|
||||
this.fieldTypeResolver.resolveFieldType("a[].id",
|
||||
this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id"),
|
||||
createPayload("{\"a\":[{\"id\":1},{\"id\":null}]}")),
|
||||
equalTo(JsonFieldType.VARIES));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleFieldsWhenNotNullThenNullWhenOptionalHasSpecificType()
|
||||
throws IOException {
|
||||
assertThat(
|
||||
this.fieldTypeResolver.resolveFieldType(
|
||||
new FieldDescriptor("a[].id").optional(),
|
||||
createPayload("{\"a\":[{\"id\":1},{\"id\":null}]}")),
|
||||
equalTo(JsonFieldType.NUMBER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleFieldsWhenNullThenNotNullWhenRequiredHasVariesType()
|
||||
throws IOException {
|
||||
assertThat(
|
||||
this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id"),
|
||||
createPayload("{\"a\":[{\"id\":null},{\"id\":1}]}")),
|
||||
equalTo(JsonFieldType.VARIES));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleFieldsWhenNullThenNotNullWhenOptionalHasSpecificType()
|
||||
throws IOException {
|
||||
assertThat(
|
||||
this.fieldTypeResolver.resolveFieldType(
|
||||
new FieldDescriptor("a[].id").optional(),
|
||||
createPayload("{\"a\":[{\"id\":null},{\"id\":1}]}")),
|
||||
equalTo(JsonFieldType.NUMBER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleFieldsWhenEitherNullOrAbsent() throws IOException {
|
||||
assertThat(
|
||||
this.fieldTypeResolver.resolveFieldType("a[].id",
|
||||
this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id"),
|
||||
createPayload("{\"a\":[{},{\"id\":null}]}")),
|
||||
equalTo(JsonFieldType.NULL));
|
||||
}
|
||||
@@ -155,7 +210,7 @@ public class JsonFieldTypeResolverTests {
|
||||
@Test
|
||||
public void multipleFieldsThatAreAllNull() throws IOException {
|
||||
assertThat(
|
||||
this.fieldTypeResolver.resolveFieldType("a[].id",
|
||||
this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].id"),
|
||||
createPayload("{\"a\":[{\"id\":null},{\"id\":null}]}")),
|
||||
equalTo(JsonFieldType.NULL));
|
||||
}
|
||||
@@ -166,7 +221,8 @@ public class JsonFieldTypeResolverTests {
|
||||
this.thrownException.expect(FieldDoesNotExistException.class);
|
||||
this.thrownException.expectMessage(
|
||||
"The payload does not contain a field with the path 'a.b'");
|
||||
this.fieldTypeResolver.resolveFieldType("a.b", createPayload("{\"a\":{}}"));
|
||||
this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a.b"),
|
||||
createPayload("{\"a\":{}}"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -175,13 +231,47 @@ public class JsonFieldTypeResolverTests {
|
||||
this.thrownException.expect(FieldDoesNotExistException.class);
|
||||
this.thrownException.expectMessage(
|
||||
"The payload does not contain a field with the path 'a[].b'");
|
||||
this.fieldTypeResolver.resolveFieldType("a[].b",
|
||||
this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a[].b"),
|
||||
createPayload("{\"a\":[{\"c\":1},{\"c\":2}]}"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void leafWildcardWithCommonType() throws IOException {
|
||||
assertThat(
|
||||
this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a.*"),
|
||||
createPayload("{\"a\": {\"b\": 5, \"c\": 6}}")),
|
||||
equalTo(JsonFieldType.NUMBER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void leafWildcardWithVaryingType() throws IOException {
|
||||
assertThat(
|
||||
this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a.*"),
|
||||
createPayload("{\"a\": {\"b\": 5, \"c\": \"six\"}}")),
|
||||
equalTo(JsonFieldType.VARIES));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void intermediateWildcardWithCommonType() throws IOException {
|
||||
assertThat(
|
||||
this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a.*.d"),
|
||||
createPayload(
|
||||
"{\"a\": {\"b\": {\"d\": 4}, \"c\": {\"d\": 5}}}}")),
|
||||
equalTo(JsonFieldType.NUMBER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void intermediateWildcardWithVaryingType() throws IOException {
|
||||
assertThat(
|
||||
this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("a.*.d"),
|
||||
createPayload(
|
||||
"{\"a\": {\"b\": {\"d\": 4}, \"c\": {\"d\": \"four\"}}}}")),
|
||||
equalTo(JsonFieldType.VARIES));
|
||||
}
|
||||
|
||||
private void assertFieldType(JsonFieldType expectedType, String jsonValue)
|
||||
throws IOException {
|
||||
assertThat(this.fieldTypeResolver.resolveFieldType("field",
|
||||
assertThat(this.fieldTypeResolver.resolveFieldType(new FieldDescriptor("field"),
|
||||
createSimplePayload(jsonValue)), equalTo(expectedType));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user