Asserting empty array in the response (#211)
with this change we're using new JSONAssert that allows to check if an array is empty fixes #203
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
<description>Spring Cloud Contract Dependencies</description>
|
||||
<properties>
|
||||
<wiremock.version>2.1.7</wiremock.version>
|
||||
<jsonassert.version>0.4.7</jsonassert.version>
|
||||
<jsonassert.version>0.4.8</jsonassert.version>
|
||||
<aether.version>1.0.2.v20150114</aether.version>
|
||||
</properties>
|
||||
<dependencyManagement>
|
||||
|
||||
@@ -94,7 +94,7 @@ class SpringCloudContractVerifierGradlePlugin implements Plugin<Project> {
|
||||
private void addProjectDependencies(Project project) {
|
||||
//TODO: Consider removing this at some point
|
||||
project.dependencies.add("testCompile", "com.github.tomakehurst:wiremock:2.1.7")
|
||||
project.dependencies.add("testCompile", "com.toomuchcoding.jsonassert:jsonassert:0.4.7")
|
||||
project.dependencies.add("testCompile", "com.toomuchcoding.jsonassert:jsonassert:0.4.8")
|
||||
project.dependencies.add("testCompile", "org.assertj:assertj-core:2.3.0")
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
<dependency>
|
||||
<groupId>com.toomuchcoding.jsonassert</groupId>
|
||||
<artifactId>jsonassert</artifactId>
|
||||
<version>0.4.7</version>
|
||||
<version>0.4.8</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
<dependency>
|
||||
<groupId>com.toomuchcoding.jsonassert</groupId>
|
||||
<artifactId>jsonassert</artifactId>
|
||||
<version>0.4.7</version>
|
||||
<version>0.4.8</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
<dependency>
|
||||
<groupId>com.toomuchcoding.jsonassert</groupId>
|
||||
<artifactId>jsonassert</artifactId>
|
||||
<version>0.4.7</version>
|
||||
<version>0.4.8</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- end::dependencies[] -->
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
<dependency>
|
||||
<groupId>com.toomuchcoding.jsonassert</groupId>
|
||||
<artifactId>jsonassert</artifactId>
|
||||
<version>0.4.7</version>
|
||||
<version>0.4.8</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
@@ -92,7 +92,7 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy {
|
||||
def originalBody = getMatchingStrategyFromBody(request.body)?.clientValue
|
||||
def body = JsonToJsonPathsConverter.removeMatchingJsonPaths(originalBody, request.matchers)
|
||||
JsonPaths values = JsonToJsonPathsConverter.transformToJsonPathWithStubsSideValuesAndNoArraySizeCheck(body)
|
||||
if (values.empty && !request.matchers?.hasMatchers()) {
|
||||
if ((values.empty && !request.matchers?.hasMatchers()) || onlySizeAssertionsArePresent(values)) {
|
||||
requestPattern.withRequestBody(WireMock.equalToJson(JsonOutput.toJson(getMatchingStrategy(request.body.clientValue).clientValue), false, false))
|
||||
} else {
|
||||
values.findAll{ !it.assertsSize() }.each {
|
||||
@@ -114,12 +114,15 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy {
|
||||
requestPattern.withRequestBody(convertToValuePattern(getMatchingStrategy(request.body.clientValue)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean onlySizeAssertionsArePresent(JsonPaths values) {
|
||||
return !values.empty && !request.matchers?.hasMatchers() && values.every { it.assertsSize() }
|
||||
}
|
||||
|
||||
private void appendMultipart(RequestPatternBuilder requestPattern) {
|
||||
if (!request.multipart) {
|
||||
return
|
||||
}
|
||||
|
||||
if (request.multipart.clientValue instanceof Map) {
|
||||
List<StringValuePattern> multipartPatterns = (request.multipart.clientValue as Map).collect {
|
||||
(it.value instanceof NamedProperty
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
|
||||
package org.springframework.cloud.contract.verifier.util;
|
||||
|
||||
import static org.apache.commons.lang3.StringEscapeUtils.escapeJava;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.toomuchcoding.jsonassert.JsonVerifiable;
|
||||
|
||||
import static org.apache.commons.lang3.StringEscapeUtils.escapeJava;
|
||||
|
||||
/**
|
||||
* Implementation of the {@link MethodBufferingJsonVerifiable} that contains a list
|
||||
* of String method commands that need to be executed to assert JSONs.
|
||||
@@ -187,6 +187,12 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable {
|
||||
return readyToCheck;
|
||||
}
|
||||
|
||||
@Override public MethodBufferingJsonVerifiable isEmpty() {
|
||||
DelegatingJsonVerifiable readyToCheck = new FinishedDelegatingJsonVerifiable(this.delegate.isEmpty(), this.methodsBuffer);
|
||||
readyToCheck.methodsBuffer.offer(".isEmpty()");
|
||||
return readyToCheck;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodBufferingJsonVerifiable matches(String value) {
|
||||
DelegatingJsonVerifiable readyToCheck = new FinishedDelegatingJsonVerifiable(this.delegate.matches(value), this.methodsBuffer);
|
||||
@@ -228,7 +234,7 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable {
|
||||
@Override
|
||||
public boolean assertsSize() {
|
||||
for (String s : this.methodsBuffer) {
|
||||
if (s.contains(".hasSize(")) {
|
||||
if (s.contains(".hasSize(") || s.contains(".isEmpty()")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ class JsonToJsonPathsConverter {
|
||||
traverseRecursively(Object, valueToAsserter(key.arrayField(), ContentUtils.returnParsedObject(it)),
|
||||
ContentUtils.returnParsedObject(it), closure)
|
||||
}
|
||||
} else if (value instanceof List) {
|
||||
} else if (value instanceof List && !value.empty) {
|
||||
MethodBufferingJsonVerifiable jsonPathVerifiable = createAsserterFromList(key, value)
|
||||
addSizeVerificationForListWithPrimitives(key, closure, value)
|
||||
value.each { def element ->
|
||||
@@ -192,7 +192,9 @@ class JsonToJsonPathsConverter {
|
||||
ContentUtils.returnParsedObject(element), closure)
|
||||
}
|
||||
return value
|
||||
} else if (key.isIteratingOverArray()) {
|
||||
} else if (value instanceof List && value.empty) {
|
||||
return runClosure(closure, key, value)
|
||||
} else if (key.isIteratingOverArray()) {
|
||||
traverseRecursively(Object, key.arrayField().contains(ContentUtils.returnParsedObject(value)),
|
||||
ContentUtils.returnParsedObject(value), closure)
|
||||
}
|
||||
@@ -292,6 +294,9 @@ class JsonToJsonPathsConverter {
|
||||
}
|
||||
|
||||
private boolean listContainsOnlyPrimitives(List list) {
|
||||
if (list.empty) {
|
||||
return false
|
||||
}
|
||||
return list.every { def element ->
|
||||
[String, Number, Boolean].any {
|
||||
it.isAssignableFrom(element.getClass())
|
||||
@@ -312,15 +317,22 @@ class JsonToJsonPathsConverter {
|
||||
Object entrykey, value ->
|
||||
def convertedValue = ContentUtils.returnParsedObject(value)
|
||||
[entrykey, traverseRecursively(parentType,
|
||||
convertedValue instanceof List ? listContainsOnlyPrimitives(convertedValue) ?
|
||||
parentKey.arrayField(entrykey) :
|
||||
parentKey.array(entrykey) :
|
||||
convertedValue instanceof List ? list(convertedValue, entrykey, parentKey) :
|
||||
convertedValue instanceof Map ? parentKey.field(new ShouldTraverse(entrykey)) :
|
||||
valueToAsserter(parentKey.field(entrykey), convertedValue)
|
||||
, convertedValue, closureToExecute)]
|
||||
}
|
||||
}
|
||||
|
||||
protected MethodBufferingJsonVerifiable list(List convertedValue, Object entrykey, MethodBufferingJsonVerifiable parentKey) {
|
||||
if (convertedValue.empty) {
|
||||
return parentKey.array(entrykey).isEmpty()
|
||||
}
|
||||
return listContainsOnlyPrimitives(convertedValue) ?
|
||||
parentKey.arrayField(entrykey) :
|
||||
parentKey.array(entrykey)
|
||||
}
|
||||
|
||||
private void traverseRecursivelyForKey(def json, MethodBufferingJsonVerifiable rootKey, Closure closure) {
|
||||
traverseRecursively(Map, rootKey, json, closure)
|
||||
}
|
||||
|
||||
@@ -59,6 +59,9 @@ public interface MethodBufferingJsonVerifiable
|
||||
@Override
|
||||
MethodBufferingJsonVerifiable isNull();
|
||||
|
||||
@Override
|
||||
MethodBufferingJsonVerifiable isEmpty();
|
||||
|
||||
@Override
|
||||
MethodBufferingJsonVerifiable matches(String value);
|
||||
|
||||
|
||||
@@ -2123,4 +2123,39 @@ World.'''"""
|
||||
"JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { Throwable t, OutputCapture capture -> t.message.contains("Cannot find matching method Script1#executedMethod") }
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | { Throwable t, OutputCapture capture -> t.message.contains("Truncated class file") && capture.toString().contains("path(executedMethod())") }
|
||||
}
|
||||
|
||||
@Issue('#203')
|
||||
def "should create an assertion for an empty list for [#methodBuilderName]"() {
|
||||
given:
|
||||
Contract contractDsl = Contract.make {
|
||||
request {
|
||||
method 'GET'
|
||||
url '/api/v1/xxxx'
|
||||
}
|
||||
response {
|
||||
status 200
|
||||
body([
|
||||
status: '200',
|
||||
list: [],
|
||||
foo: ["bar", "baz"]
|
||||
])
|
||||
}
|
||||
}
|
||||
MethodBodyBuilder builder = methodBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
and:
|
||||
builder.appendTo(blockBuilder)
|
||||
String test = blockBuilder.toString()
|
||||
when:
|
||||
SyntaxChecker.tryToCompile(methodBuilderName, test)
|
||||
then:
|
||||
test.contains('assertThatJson(parsedJson).array("list").isEmpty()')
|
||||
!test.contains('assertThatJson(parsedJson).array("foo").isEmpty()')
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) }
|
||||
"MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) }
|
||||
"JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) }
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user