Stop type determination from changing descriptor's type

Previously, when a field's type was automatically determined, the
type of the passed-in descriptor was changed. This could cause
problems if the descriptor was reused in another test.

This commit updates AbstractFieldsSnippet to create a copy of each
descriptor so that setting the determined type does not affect the
type of the original descriptor.

Closes gh-511
This commit is contained in:
Andy Wilkinson
2018-07-16 15:50:34 +01:00
parent 920ced0755
commit a2a9a7cb0f
3 changed files with 58 additions and 2 deletions

View File

@@ -24,6 +24,8 @@ import java.util.Map;
import org.springframework.http.MediaType;
import org.springframework.restdocs.operation.Operation;
import org.springframework.restdocs.snippet.Attributes;
import org.springframework.restdocs.snippet.Attributes.Attribute;
import org.springframework.restdocs.snippet.ModelCreationException;
import org.springframework.restdocs.snippet.SnippetException;
import org.springframework.restdocs.snippet.TemplatedSnippet;
@@ -184,10 +186,12 @@ public abstract class AbstractFieldsSnippet extends TemplatedSnippet {
validateFieldDocumentation(contentHandler);
List<FieldDescriptor> descriptorsToDocument = new ArrayList<>();
for (FieldDescriptor descriptor : this.fieldDescriptors) {
if (!descriptor.isIgnored()) {
try {
descriptor.type(contentHandler.determineFieldType(descriptor));
Object type = contentHandler.determineFieldType(descriptor);
descriptorsToDocument.add(copyWithType(descriptor, type));
}
catch (FieldDoesNotExistException ex) {
String message = "Cannot determine the type of the field '"
@@ -202,7 +206,7 @@ public abstract class AbstractFieldsSnippet extends TemplatedSnippet {
Map<String, Object> model = new HashMap<>();
List<Map<String, Object>> fields = new ArrayList<>();
model.put("fields", fields);
for (FieldDescriptor descriptor : this.fieldDescriptors) {
for (FieldDescriptor descriptor : descriptorsToDocument) {
if (!descriptor.isIgnored()) {
fields.add(createModelForDescriptor(descriptor));
}
@@ -340,4 +344,28 @@ public abstract class AbstractFieldsSnippet extends TemplatedSnippet {
return model;
}
private FieldDescriptor copyWithType(FieldDescriptor source, Object type) {
FieldDescriptor result = source instanceof SubsectionDescriptor
? new SubsectionDescriptor(source.getPath())
: new FieldDescriptor(source.getPath());
result.description(source.getDescription()).type(type)
.attributes(asArray(source.getAttributes()));
if (source.isIgnored()) {
result.ignored();
}
if (source.isOptional()) {
result.optional();
}
return result;
}
private static Attribute[] asArray(Map<String, Object> attributeMap) {
List<Attributes.Attribute> attributes = new ArrayList<>();
for (Map.Entry<String, Object> attribute : attributeMap.entrySet()) {
attributes
.add(Attributes.key(attribute.getKey()).value(attribute.getValue()));
}
return attributes.toArray(new Attribute[attributes.size()]);
}
}