diff --git a/spring-cloud-contract-dependencies/pom.xml b/spring-cloud-contract-dependencies/pom.xml
index f34e81bb46..7c1b3107b2 100644
--- a/spring-cloud-contract-dependencies/pom.xml
+++ b/spring-cloud-contract-dependencies/pom.xml
@@ -15,7 +15,7 @@
Spring Cloud Contract Dependencies
2.1.7
- 0.4.7
+ 0.4.8
1.0.2.v20150114
diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/SpringCloudContractVerifierGradlePlugin.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/SpringCloudContractVerifierGradlePlugin.groovy
index 0d8bfae1fb..dbe01b6b7f 100644
--- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/SpringCloudContractVerifierGradlePlugin.groovy
+++ b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/SpringCloudContractVerifierGradlePlugin.groovy
@@ -94,7 +94,7 @@ class SpringCloudContractVerifierGradlePlugin implements Plugin {
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")
}
diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/complex-configuration/pom.xml b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/complex-configuration/pom.xml
index 601db4ead6..2ef9310d56 100644
--- a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/complex-configuration/pom.xml
+++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/complex-configuration/pom.xml
@@ -63,7 +63,7 @@
com.toomuchcoding.jsonassert
jsonassert
- 0.4.7
+ 0.4.8
test
diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/plugin-extension/pom.xml b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/plugin-extension/pom.xml
index e57964dd63..e03b81bc7a 100644
--- a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/plugin-extension/pom.xml
+++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/plugin-extension/pom.xml
@@ -63,7 +63,7 @@
com.toomuchcoding.jsonassert
jsonassert
- 0.4.7
+ 0.4.8
test
diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/spring-boot-groovy/pom.xml b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/spring-boot-groovy/pom.xml
index 6d0570cf4b..a0dc42aa9d 100644
--- a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/spring-boot-groovy/pom.xml
+++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/spring-boot-groovy/pom.xml
@@ -64,7 +64,7 @@
com.toomuchcoding.jsonassert
jsonassert
- 0.4.7
+ 0.4.8
test
diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/spring-boot-java/pom.xml b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/spring-boot-java/pom.xml
index e57964dd63..e03b81bc7a 100644
--- a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/spring-boot-java/pom.xml
+++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/spring-boot-java/pom.xml
@@ -63,7 +63,7 @@
com.toomuchcoding.jsonassert
jsonassert
- 0.4.7
+ 0.4.8
test
diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockRequestStubStrategy.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockRequestStubStrategy.groovy
index c8d1ebf080..2bb9de4c8f 100755
--- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockRequestStubStrategy.groovy
+++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockRequestStubStrategy.groovy
@@ -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 multipartPatterns = (request.multipart.clientValue as Map).collect {
(it.value instanceof NamedProperty
diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/util/DelegatingJsonVerifiable.java b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/util/DelegatingJsonVerifiable.java
index 0c5114e939..beba817b81 100644
--- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/util/DelegatingJsonVerifiable.java
+++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/util/DelegatingJsonVerifiable.java
@@ -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;
}
}
diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverter.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverter.groovy
index 39f84e0635..3763eb5e8b 100644
--- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverter.groovy
+++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverter.groovy
@@ -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)
}
diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/util/MethodBufferingJsonVerifiable.java b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/util/MethodBufferingJsonVerifiable.java
index 74ff5179b5..49e0c82982 100644
--- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/util/MethodBufferingJsonVerifiable.java
+++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/util/MethodBufferingJsonVerifiable.java
@@ -59,6 +59,9 @@ public interface MethodBufferingJsonVerifiable
@Override
MethodBufferingJsonVerifiable isNull();
+ @Override
+ MethodBufferingJsonVerifiable isEmpty();
+
@Override
MethodBufferingJsonVerifiable matches(String value);
diff --git a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy
index c758664c11..b307028149 100644
--- a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy
+++ b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy
@@ -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) }
+ }
}