Merge branch '1.2.x'

This commit is contained in:
Andy Wilkinson
2017-09-23 16:41:05 +01:00
10 changed files with 427 additions and 197 deletions

View File

@@ -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 + "'");
}
}

View File

@@ -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);

View File

@@ -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()

View File

@@ -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;
}
}

View File

@@ -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;
}
}
}

View File

@@ -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) {

View File

@@ -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());

View File

@@ -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());
}
}

View File

@@ -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) {

View File

@@ -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));
}