Cause a failure when field's documented and actual types do not match
Closes gh-276
This commit is contained in:
@@ -100,8 +100,15 @@ public abstract class AbstractFieldsSnippet extends TemplatedSnippet {
|
||||
validateFieldDocumentation(contentHandler);
|
||||
|
||||
for (FieldDescriptor descriptor : this.fieldDescriptors) {
|
||||
if (descriptor.getType() == null) {
|
||||
descriptor.type(contentHandler.determineFieldType(descriptor.getPath()));
|
||||
try {
|
||||
descriptor.type(contentHandler.determineFieldType(descriptor));
|
||||
}
|
||||
catch (FieldDoesNotExistException ex) {
|
||||
String message = "Cannot determine the type of the field '"
|
||||
+ descriptor.getPath() + "' as it is not present in the "
|
||||
+ "payload. Please provide a type using "
|
||||
+ "FieldDescriptor.type(Object type).";
|
||||
throw new FieldTypeRequiredException(message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,12 +50,12 @@ interface ContentHandler {
|
||||
String getUndocumentedContent(List<FieldDescriptor> fieldDescriptors);
|
||||
|
||||
/**
|
||||
* Returns the type of the field with the given {@code path} based on the content of
|
||||
* the payload.
|
||||
* Returns the type of the field that is described by the given
|
||||
* {@code fieldDescriptor} based on the content of the payload.
|
||||
*
|
||||
* @param path the field path
|
||||
* @param fieldDescriptor the field descriptor
|
||||
* @return the type of the field
|
||||
*/
|
||||
Object determineFieldType(String path);
|
||||
Object determineFieldType(FieldDescriptor fieldDescriptor);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2014-2016 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.restdocs.payload;
|
||||
|
||||
/**
|
||||
* A {@code FieldTypesDoNotMatchException} is thrown when the documented and actual types
|
||||
* of a field do not match.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
class FieldTypesDoNotMatchException extends RuntimeException {
|
||||
|
||||
/**
|
||||
* Creates a new {@code FieldTypesDoNotMatchException} for the field described by the
|
||||
* given {@code fieldDescriptor} that has the given {@code actualType}.
|
||||
*
|
||||
* @param fieldDescriptor the field
|
||||
* @param actualType the actual type of the field
|
||||
*/
|
||||
FieldTypesDoNotMatchException(FieldDescriptor fieldDescriptor, Object actualType) {
|
||||
super("The documented type of the field '" + fieldDescriptor.getPath() + "' is "
|
||||
+ fieldDescriptor.getType() + " but the actual type is " + actualType);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -34,6 +34,8 @@ class JsonContentHandler implements ContentHandler {
|
||||
|
||||
private final JsonFieldProcessor fieldProcessor = new JsonFieldProcessor();
|
||||
|
||||
private final JsonFieldTypeResolver fieldTypeResolver = new JsonFieldTypeResolver();
|
||||
|
||||
private final ObjectMapper objectMapper = new ObjectMapper()
|
||||
.enable(SerializationFeature.INDENT_OUTPUT);
|
||||
|
||||
@@ -93,15 +95,26 @@ class JsonContentHandler implements ContentHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object determineFieldType(String path) {
|
||||
public Object determineFieldType(FieldDescriptor fieldDescriptor) {
|
||||
if (fieldDescriptor.getType() == null) {
|
||||
return this.fieldTypeResolver.resolveFieldType(fieldDescriptor.getPath(),
|
||||
readContent());
|
||||
}
|
||||
if (!(fieldDescriptor.getType() instanceof JsonFieldType)) {
|
||||
return fieldDescriptor.getType();
|
||||
}
|
||||
JsonFieldType descriptorFieldType = (JsonFieldType) fieldDescriptor.getType();
|
||||
try {
|
||||
return new JsonFieldTypeResolver().resolveFieldType(path, readContent());
|
||||
JsonFieldType actualFieldType = this.fieldTypeResolver
|
||||
.resolveFieldType(fieldDescriptor.getPath(), readContent());
|
||||
if (descriptorFieldType == JsonFieldType.VARIES
|
||||
|| descriptorFieldType == actualFieldType) {
|
||||
return descriptorFieldType;
|
||||
}
|
||||
throw new FieldTypesDoNotMatchException(fieldDescriptor, actualFieldType);
|
||||
}
|
||||
catch (FieldDoesNotExistException ex) {
|
||||
String message = "Cannot determine the type of the field '" + path + "' as"
|
||||
+ " it is not present in the payload. Please provide a type using"
|
||||
+ " FieldDescriptor.type(Object type).";
|
||||
throw new FieldTypeRequiredException(message);
|
||||
return fieldDescriptor.getType();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -153,15 +153,14 @@ class XmlContentHandler implements ContentHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object determineFieldType(String path) {
|
||||
try {
|
||||
return new JsonFieldTypeResolver().resolveFieldType(path, readPayload());
|
||||
public Object determineFieldType(FieldDescriptor fieldDescriptor) {
|
||||
if (fieldDescriptor.getType() != null) {
|
||||
return fieldDescriptor.getType();
|
||||
}
|
||||
catch (FieldDoesNotExistException ex) {
|
||||
String message = "Cannot determine the type of the field '" + path + "' as"
|
||||
+ " it is not present in the payload. Please provide a type using"
|
||||
+ " FieldDescriptor.type(Object type).";
|
||||
throw new FieldTypeRequiredException(message);
|
||||
else {
|
||||
throw new FieldTypeRequiredException("The type of a field in an XML payload "
|
||||
+ "cannot be determined automatically. Please provide a type using "
|
||||
+ "FieldDescriptor.type(Object type)");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user