diff --git a/pom.xml b/pom.xml
index 8b9841716a..f0e517233f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -190,6 +190,32 @@
+
+
+ org.apache.maven.plugins
+ maven-clean-plugin
+ 3.0.0
+
+
+
+ target
+
+
+ ${env.HOME}/.m2/repository/com/example/
+
+ **/*
+
+
+
+ ${env.HOME}/.m2/repository/org/springframework/cloud/contract/verifier/stubs/
+
+ **/*
+
+
+
+
+
+
diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelPredicate.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelPredicate.java
index 985ee3e66a..d0174bbba6 100644
--- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelPredicate.java
+++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelPredicate.java
@@ -55,7 +55,8 @@ class StubRunnerCamelPredicate implements Predicate {
}
Object inputMessage = exchange.getIn().getBody();
JsonPaths jsonPaths = JsonToJsonPathsConverter
- .transformToJsonPathWithStubsSideValues(groovyDsl.getInput().getMessageBody());
+ .transformToJsonPathWithStubsSideValuesAndNoArraySizeCheck(
+ groovyDsl.getInput().getMessageBody());
DocumentContext parsedJson;
try {
parsedJson = JsonPath
diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.java
index d69147cd24..12a567e4c2 100644
--- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.java
+++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.java
@@ -55,7 +55,7 @@ class StubRunnerIntegrationMessageSelector implements MessageSelector {
}
Object inputMessage = message.getPayload();
JsonPaths jsonPaths = JsonToJsonPathsConverter
- .transformToJsonPathWithStubsSideValues(
+ .transformToJsonPathWithStubsSideValuesAndNoArraySizeCheck(
groovyDsl.getInput().getMessageBody());
DocumentContext parsedJson;
try {
diff --git a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamMessageSelector.java b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamMessageSelector.java
index 9292707667..a448536aa4 100644
--- a/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamMessageSelector.java
+++ b/spring-cloud-contract-stub-runner/src/main/java/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamMessageSelector.java
@@ -55,7 +55,7 @@ class StubRunnerStreamMessageSelector implements MessageSelector {
}
Object inputMessage = message.getPayload();
JsonPaths jsonPaths = JsonToJsonPathsConverter
- .transformToJsonPathWithStubsSideValues(
+ .transformToJsonPathWithStubsSideValuesAndNoArraySizeCheck(
groovyDsl.getInput().getMessageBody());
DocumentContext parsedJson;
try {
diff --git a/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverter.groovy b/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverter.groovy
index 3fe90afb25..cae1b34b86 100644
--- a/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverter.groovy
+++ b/spring-cloud-contract-tools/spring-cloud-contract-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverter.groovy
@@ -21,7 +21,6 @@ import org.springframework.cloud.contract.verifier.dsl.wiremock.WireMockStubStra
import org.springframework.cloud.contract.verifier.file.ContractMetadata
import java.nio.charset.StandardCharsets
-
/**
* Converts DSLs to WireMock stubs
*
@@ -33,6 +32,7 @@ class DslToWireMockClientConverter extends DslToWireMockConverter {
@Override
String convertContent(String rootName, ContractMetadata contract) {
String dslContent = contract.path.getText(StandardCharsets.UTF_8.toString())
- return new WireMockStubStrategy(rootName, contract, createGroovyDSLFromStringContent(dslContent)).toWireMockClientStub()
+ return new WireMockStubStrategy(rootName, contract,
+ createGroovyDSLFromStringContent(dslContent)).toWireMockClientStub()
}
}
diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateWireMockClientStubsFromDslTask.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateWireMockClientStubsFromDslTask.groovy
index e87a0422cd..a3693e28c8 100644
--- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateWireMockClientStubsFromDslTask.groovy
+++ b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateWireMockClientStubsFromDslTask.groovy
@@ -47,7 +47,8 @@ class GenerateWireMockClientStubsFromDslTask extends ConventionTask {
ContractVerifierConfigProperties props = getConfigProperties()
File outMappingsDir = props.stubsOutputDir != null ? new File(props.stubsOutputDir, DEFAULT_MAPPINGS_FOLDER)
: new File(project.buildDir, "stubs/$DEFAULT_MAPPINGS_FOLDER")
- RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWireMockClientConverter(),
+ RecursiveFilesConverter converter = new RecursiveFilesConverter(
+ new DslToWireMockClientConverter(),
getConfigProperties(), outMappingsDir)
converter.processFiles()
}
diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/GenerateTestsMojo.java b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/GenerateTestsMojo.java
index fd6c43ea98..3e90e34e5c 100644
--- a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/GenerateTestsMojo.java
+++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/main/java/org/springframework/cloud/contract/maven/verifier/GenerateTestsMojo.java
@@ -80,6 +80,14 @@ public class GenerateTestsMojo extends AbstractMojo {
@Parameter
private List excludedFiles;
+ /**
+ * Incubating feature. You can check the size of JSON arrays. If not turned on
+ * explicitly will be disabled.
+ */
+ @Parameter(property = "spring.cloud.contract.verifier.assert.size",
+ defaultValue = "false")
+ private boolean assertJsonSize;
+
/**
* Patterns for which Spring Cloud Contract Verifier should generate @Ignored tests
*/
@@ -119,6 +127,7 @@ public class GenerateTestsMojo extends AbstractMojo {
config.setStaticImports(staticImports);
config.setIgnoredFiles(ignoredFiles);
config.setExcludedFiles(excludedFiles);
+ config.setAssertJsonSize(assertJsonSize);
project.addTestCompileSourceRoot(generatedTestSourcesDir.getAbsolutePath());
if (getLog().isInfoEnabled()) {
getLog().info(
@@ -155,4 +164,11 @@ public class GenerateTestsMojo extends AbstractMojo {
this.ignoredFiles = ignoredFiles;
}
+ public boolean isAssertJsonSize() {
+ return assertJsonSize;
+ }
+
+ public void setAssertJsonSize(boolean assertJsonSize) {
+ this.assertJsonSize = assertJsonSize;
+ }
}
diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/java/org/springframework/cloud/contract/maven/verifier/PluginUnitTest.java b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/java/org/springframework/cloud/contract/maven/verifier/PluginUnitTest.java
index 4c4b6804a3..60e7959978 100644
--- a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/java/org/springframework/cloud/contract/maven/verifier/PluginUnitTest.java
+++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/java/org/springframework/cloud/contract/maven/verifier/PluginUnitTest.java
@@ -18,6 +18,7 @@ package org.springframework.cloud.contract.maven.verifier;
import java.io.File;
+import org.apache.commons.io.FileUtils;
import org.junit.Rule;
import org.junit.Test;
@@ -27,6 +28,7 @@ import io.takari.maven.testing.TestResources;
import static io.takari.maven.testing.TestMavenRuntime.newParameter;
import static io.takari.maven.testing.TestResources.assertFilesNotPresent;
import static io.takari.maven.testing.TestResources.assertFilesPresent;
+import static org.assertj.core.api.BDDAssertions.then;
public class PluginUnitTest {
@@ -58,6 +60,7 @@ public class PluginUnitTest {
assertFilesPresent(basedir, "target/stubs/contracts/Sample.groovy");
assertFilesPresent(basedir, "target/stubs/contracts/Messaging.groovy");
}
+
@Test
public void shouldGenerateWireMockStubsInSelectedLocation() throws Exception {
File basedir = resources.getBasedir("basic");
@@ -89,6 +92,26 @@ public class PluginUnitTest {
"target/generated-test-sources/contracts/org/springframework/cloud/contract/verifier/tests/ContractVerifierTest.java");
}
+ @Test
+ public void shouldGenerateContractTestsWithoutArraySize() throws Exception {
+ File basedir = resources.getBasedir("basic");
+ maven.executeMojo(basedir, "generateTests");
+ assertFilesPresent(basedir,
+ "target/generated-test-sources/contracts/org/springframework/cloud/contract/verifier/tests/ContractVerifierTest.java");
+ File test = new File(basedir, "target/generated-test-sources/contracts/org/springframework/cloud/contract/verifier/tests/ContractVerifierTest.java");
+ then(FileUtils.readFileToString(test)).doesNotContain("hasSize(4)");
+ }
+
+ @Test
+ public void shouldGenerateContractTestsWithArraySize() throws Exception {
+ File basedir = resources.getBasedir("basic");
+ maven.executeMojo(basedir, "generateTests", newParameter("assertJsonSize", "true"));
+ assertFilesPresent(basedir,
+ "target/generated-test-sources/contracts/org/springframework/cloud/contract/verifier/tests/ContractVerifierTest.java");
+ File test = new File(basedir, "target/generated-test-sources/contracts/org/springframework/cloud/contract/verifier/tests/ContractVerifierTest.java");
+ then(FileUtils.readFileToString(test)).contains("hasSize(4)");
+ }
+
@Test
public void shouldGenerateStubs() throws Exception {
File basedir = resources.getBasedir("generatedStubs");
diff --git a/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/basic/src/test/resources/contracts/WithList.groovy b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/basic/src/test/resources/contracts/WithList.groovy
new file mode 100644
index 0000000000..f542a19e9a
--- /dev/null
+++ b/spring-cloud-contract-tools/spring-cloud-contract-maven-plugin/src/test/projects/basic/src/test/resources/contracts/WithList.groovy
@@ -0,0 +1,34 @@
+/**
+ *
+ * Copyright 2013-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.
+ */
+org.springframework.cloud.contract.spec.Contract.make {
+ request {
+ method 'POST'
+ url('/users') {
+
+ }
+ headers {
+ header 'Content-Type': 'application/json'
+ }
+ }
+ response {
+ status 200
+ headers {
+ header 'Location': '/users/john'
+ }
+ body '''{ "list" : [ "login", "john", "name", "John The Contract" ] }'''
+ }
+}
\ No newline at end of file
diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.groovy
index 366c9c4c96..6e34af897e 100644
--- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.groovy
+++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.groovy
@@ -100,6 +100,6 @@ class ContractVerifierConfigProperties {
* Incubating feature. You can check the size of JSON arrays. If not turned on
* explicitly will be disabled.
*/
- Boolean assertJsonSize
+ Boolean assertJsonSize = false
}
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 c156ec3aaa..2725e8c158 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
@@ -75,7 +75,8 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy {
}
ContentType contentType = tryToGetContentType(request.body.clientValue, request.headers)
if (contentType == ContentType.JSON) {
- JsonPaths values = JsonToJsonPathsConverter.transformToJsonPathWithStubsSideValues(getMatchingStrategyFromBody(request.body)?.clientValue)
+ JsonPaths values = JsonToJsonPathsConverter.transformToJsonPathWithStubsSideValuesAndNoArraySizeCheck(
+ getMatchingStrategyFromBody(request.body)?.clientValue)
if (values.empty) {
requestPattern.withRequestBody(WireMock.equalToJson(JsonOutput.toJson(getMatchingStrategy(request.body.clientValue).clientValue), false, false))
} else {
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 7825035622..35ecbdc3e8 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
@@ -53,14 +53,20 @@ class JsonToJsonPathsConverter {
JsonToJsonPathsConverter() {
this.configProperties = new ContractVerifierConfigProperties()
+ log.debug("Creating JsonToJsonPaths converter with default properties")
}
- public static JsonPaths transformToJsonPathWithTestsSideValues(def json) {
- return new JsonToJsonPathsConverter().transformToJsonPathWithValues(json, SERVER_SIDE)
+ public JsonPaths transformToJsonPathWithTestsSideValues(def json) {
+ return transformToJsonPathWithValues(json, SERVER_SIDE)
}
- public static JsonPaths transformToJsonPathWithStubsSideValues(def json) {
- return new JsonToJsonPathsConverter().transformToJsonPathWithValues(json, CLIENT_SIDE)
+ public JsonPaths transformToJsonPathWithStubsSideValues(def json) {
+ return transformToJsonPathWithValues(json, CLIENT_SIDE)
+ }
+
+ public static JsonPaths transformToJsonPathWithStubsSideValuesAndNoArraySizeCheck(def json) {
+ return new JsonToJsonPathsConverter()
+ .transformToJsonPathWithValues(json, CLIENT_SIDE)
}
private JsonPaths transformToJsonPathWithValues(def json, boolean clientSide) {
@@ -134,14 +140,19 @@ class JsonToJsonPathsConverter {
// Size verification: https://github.com/Codearte/accurest/issues/279
private void addSizeVerificationForListWithPrimitives(MethodBufferingJsonVerifiable key, Closure closure, List value) {
- Boolean systemPropValue = Boolean.parseBoolean(System.getProperty(SIZE_ASSERTION_SYSTEM_PROP, "false"))
+ String systemPropValue = System.getProperty(SIZE_ASSERTION_SYSTEM_PROP)
Boolean configPropValue = configProperties.assertJsonSize
- boolean configPropSet = configPropValue != null
- if (configPropSet && !configPropValue) {
- return
- } else if (!configPropSet && systemPropValue) {
+ if ((systemPropValue != null && Boolean.parseBoolean(systemPropValue)) ||
+ configPropValue) {
+ addArraySizeCheck(key, value, closure)
+ } else {
+ log.debug("Turning off the incubating feature of JSON array check. " +
+ "System property [$systemPropValue]. Config property [$configPropValue]")
return
}
+ }
+
+ private void addArraySizeCheck(MethodBufferingJsonVerifiable key, List value, Closure closure) {
log.debug("WARNING: Turning on the incubating feature of JSON array check")
if (isRootElement(key) || key.assertsConcreteValue()) {
if (value.size() > 0) {
diff --git a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientMethodBuilderSpec.groovy b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientMethodBuilderSpec.groovy
index 849c06591d..46569c0a0a 100644
--- a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientMethodBuilderSpec.groovy
+++ b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientMethodBuilderSpec.groovy
@@ -18,11 +18,12 @@ package org.springframework.cloud.contract.verifier.builder
import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties
import org.springframework.cloud.contract.verifier.dsl.WireMockStubVerifier
-import org.springframework.cloud.contract.verifier.file.ContractMetadata
import org.springframework.cloud.contract.verifier.dsl.wiremock.WireMockStubStrategy
+import org.springframework.cloud.contract.verifier.file.ContractMetadata
import spock.lang.Issue
import spock.lang.Shared
import spock.lang.Specification
+import spock.util.environment.RestoreSystemProperties
class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStubVerifier {
@@ -114,6 +115,43 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
BlockBuilder blockBuilder = new BlockBuilder(" ")
when:
builder.appendTo(blockBuilder)
+ then:
+ blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""")
+ blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").contains("a").isEqualTo("sth")""")
+ blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").contains("b").isEqualTo("sthElse")""")
+ and:
+ stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new ContractMetadata(null, false, 0, null), contractDsl).toWireMockClientStub())
+ where:
+ methodBuilderName | methodBuilder
+ "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) }
+ "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) }
+ }
+
+ @Issue("#79")
+ @RestoreSystemProperties
+ def "should generate assertions for simple response body constructed from map with a list with #methodBuilderName with array size check"() {
+ given:
+ System.setProperty('spring.cloud.contract.verifier.assert.size', 'true')
+ org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make {
+ request {
+ method "GET"
+ url "test"
+ }
+ response {
+ status 200
+ body(
+ property1: 'a',
+ property2: [
+ [a: 'sth'],
+ [b: 'sthElse']
+ ]
+ )
+ }
+ }
+ MethodBodyBuilder builder = methodBuilder(contractDsl)
+ BlockBuilder blockBuilder = new BlockBuilder(" ")
+ when:
+ builder.appendTo(blockBuilder)
then:
blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""")
blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").contains("a").isEqualTo("sth")""")
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 58a44e8193..a46d9c3a76 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
@@ -22,6 +22,7 @@ import org.springframework.cloud.contract.verifier.dsl.WireMockStubVerifier
import spock.lang.Issue
import spock.lang.Shared
import spock.lang.Specification
+import spock.util.environment.RestoreSystemProperties
import java.util.regex.Pattern
/**
@@ -186,6 +187,43 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
then:
blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""")
blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").contains("a").isEqualTo("sth")""")
+ blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").contains("b").isEqualTo("sthElse")""")
+ and:
+ stubMappingIsValidWireMockStub(contractDsl)
+ where:
+ methodBuilderName | methodBuilder
+ "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) }
+ "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) }
+ }
+
+ @Issue("#79")
+ @RestoreSystemProperties
+ def "should generate assertions for simple response body constructed from map with a list with #methodBuilderName with array size check"() {
+ given:
+ System.setProperty('spring.cloud.contract.verifier.assert.size', 'true')
+ Contract contractDsl = Contract.make {
+ request {
+ method "GET"
+ url "test"
+ }
+ response {
+ status 200
+ body(
+ property1: 'a',
+ property2: [
+ [a: 'sth'],
+ [b: 'sthElse']
+ ]
+ )
+ }
+ }
+ MethodBodyBuilder builder = methodBuilder(contractDsl)
+ BlockBuilder blockBuilder = new BlockBuilder(" ")
+ when:
+ builder.appendTo(blockBuilder)
+ then:
+ blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""")
+ blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").contains("a").isEqualTo("sth")""")
blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").hasSize(2)""")
blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").contains("b").isEqualTo("sthElse")""")
and:
@@ -1271,6 +1309,41 @@ World.'''"""
when:
builder.then(blockBuilder)
def test = blockBuilder.toString()
+ then:
+ test.contains('assertThatJson(parsedJson).arrayField().contains("Java8").value()')
+ test.contains('assertThatJson(parsedJson).arrayField().contains("Spring").value()')
+ test.contains('assertThatJson(parsedJson).arrayField().contains("Java").value()')
+ test.contains('assertThatJson(parsedJson).arrayField().contains("Stream").value()')
+ test.contains('assertThatJson(parsedJson).arrayField().contains("SpringBoot").value()')
+ where:
+ methodBuilderName | methodBuilder
+ "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) }
+ "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) }
+ }
+
+ @Issue('266')
+ @RestoreSystemProperties
+ def "should generate proper test code with top level array using #methodBuilderName with array size check"() {
+ given:
+ System.setProperty('spring.cloud.contract.verifier.assert.size', 'true')
+ Contract contractDsl = Contract.make {
+ request {
+ method 'GET'
+ urlPath '/api/tags'
+ }
+ response {
+ status 200
+ body(["Java", "Java8", "Spring", "SpringBoot", "Stream"])
+ headers {
+ header('Content-Type': 'application/json;charset=UTF-8')
+ }
+ }
+ }
+ MethodBodyBuilder builder = methodBuilder(contractDsl)
+ BlockBuilder blockBuilder = new BlockBuilder(" ")
+ when:
+ builder.then(blockBuilder)
+ def test = blockBuilder.toString()
then:
test.contains('assertThatJson(parsedJson).hasSize(5)')
test.contains('assertThatJson(parsedJson).arrayField().contains("Java8").value()')
@@ -1306,7 +1379,6 @@ World.'''"""
builder.then(blockBuilder)
def test = blockBuilder.toString()
then:
- test.contains('assertThatJson(parsedJson).hasSize(2)')
test.contains('assertThatJson(parsedJson).array().arrayField().isEqualTo("Programming").value()')
test.contains('assertThatJson(parsedJson).array().arrayField().isEqualTo("Java").value()')
test.contains('assertThatJson(parsedJson).array().arrayField().isEqualTo("Spring").value()')
diff --git a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverterSpec.groovy b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverterSpec.groovy
index aefe865f00..fb2e4152b3 100644
--- a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverterSpec.groovy
+++ b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverterSpec.groovy
@@ -25,6 +25,7 @@ import groovy.json.JsonOutput
import groovy.json.JsonSlurper
import net.minidev.json.JSONArray
import spock.lang.Specification
+import spock.util.environment.RestoreSystemProperties
import java.util.regex.Pattern
@@ -369,6 +370,36 @@ class JsonToJsonPathsConverterSpec extends Specification {
it.method()== """.array("property2").contains("a").isEqualTo("sth")""" &&
it.jsonPath() == """\$.property2[*][?(@.a == 'sth')]"""
}
+ pathAndValues.find {
+ it.method()== """.array("property2").contains("b").isEqualTo("sthElse")""" &&
+ it.jsonPath() == """\$.property2[*][?(@.b == 'sthElse')]"""
+ }
+ and:
+ pathAndValues.size() == 3
+ }
+
+ @RestoreSystemProperties
+ def "should generate assertions for simple response body constructed from map with a list with array size check"() {
+ given:
+ System.setProperty('spring.cloud.contract.verifier.assert.size', 'true')
+ Map json = [
+ property1: 'a',
+ property2: [
+ [a: 'sth'],
+ [b: 'sthElse']
+ ]
+ ]
+ when:
+ JsonPaths pathAndValues = new JsonToJsonPathsConverter().transformToJsonPathWithTestsSideValues(json)
+ then:
+ pathAndValues.find {
+ it.method()== """.field("property1").isEqualTo("a")""" &&
+ it.jsonPath() == """\$[?(@.property1 == 'a')]"""
+ }
+ pathAndValues.find {
+ it.method()== """.array("property2").contains("a").isEqualTo("sth")""" &&
+ it.jsonPath() == """\$.property2[*][?(@.a == 'sth')]"""
+ }
pathAndValues.find {
it.method()== """.array("property2").hasSize(2)""" &&
it.jsonPath() == """\$.property2[*]"""
@@ -410,6 +441,32 @@ class JsonToJsonPathsConverterSpec extends Specification {
{
"property1": "a"
},
+ {
+ "property2": "b"
+ }]"""
+ when:
+ JsonPaths pathAndValues = new JsonToJsonPathsConverter().transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json))
+ then:
+ pathAndValues.find {
+ it.method()== """.array().contains("property1").isEqualTo("a")""" &&
+ it.jsonPath() == """\$[*][?(@.property1 == 'a')]"""
+ }
+ pathAndValues.find {
+ it.method()== """.array().contains("property2").isEqualTo("b")""" &&
+ it.jsonPath() == """\$[*][?(@.property2 == 'b')]"""
+ }
+ and:
+ pathAndValues.size() == 2
+ }
+
+ @RestoreSystemProperties
+ def "should generate assertions for array in response body with array size check"() {
+ given:
+ System.setProperty('spring.cloud.contract.verifier.assert.size', 'true')
+ String json = """[
+ {
+ "property1": "a"
+ },
{
"property2": "b"
}]"""
@@ -439,6 +496,31 @@ class JsonToJsonPathsConverterSpec extends Specification {
{ "property2": "test1"},
{ "property3": "test2"}
]
+}"""
+ when:
+ JsonPaths pathAndValues = new JsonToJsonPathsConverter().transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json))
+ then:
+ pathAndValues.find {
+ it.method()== """.array("property1").contains("property2").isEqualTo("test1")""" &&
+ it.jsonPath() == """\$.property1[*][?(@.property2 == 'test1')]"""
+ }
+ pathAndValues.find {
+ it.method()== """.array("property1").contains("property3").isEqualTo("test2")""" &&
+ it.jsonPath() == """\$.property1[*][?(@.property3 == 'test2')]"""
+ }
+ and:
+ pathAndValues.size() == 2
+ }
+
+ @RestoreSystemProperties
+ def "should generate assertions for array inside response body element with array size check"() {
+ given:
+ System.setProperty('spring.cloud.contract.verifier.assert.size', 'true')
+ String json = """{
+ "property1": [
+ { "property2": "test1"},
+ { "property3": "test2"}
+ ]
}"""
when:
JsonPaths pathAndValues = new JsonToJsonPathsConverter().transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json))
@@ -517,7 +599,6 @@ class JsonToJsonPathsConverterSpec extends Specification {
pathAndValues.size() == 1
}
-
def "should work with more complex stuff and jsonpaths"() {
given:
Map json = [
@@ -537,6 +618,31 @@ class JsonToJsonPathsConverterSpec extends Specification {
it.method()== """.array("errors").contains("message").isEqualTo("incorrect_format")""" &&
it.jsonPath() == """\$.errors[*][?(@.message == 'incorrect_format')]"""
}
+ and:
+ pathAndValues.size() == 2
+ }
+
+ @RestoreSystemProperties
+ def "should work with more complex stuff and jsonpaths with array size check"() {
+ given:
+ System.setProperty('spring.cloud.contract.verifier.assert.size', 'true')
+ Map json = [
+ errors: [
+ [property: "bank_account_number",
+ message: "incorrect_format"]
+ ]
+ ]
+ when:
+ JsonPaths pathAndValues = new JsonToJsonPathsConverter().transformToJsonPathWithTestsSideValues(json)
+ then:
+ pathAndValues.find {
+ it.method()== """.array("errors").contains("property").isEqualTo("bank_account_number")""" &&
+ it.jsonPath() == """\$.errors[*][?(@.property == 'bank_account_number')]"""
+ }
+ pathAndValues.find {
+ it.method()== """.array("errors").contains("message").isEqualTo("incorrect_format")""" &&
+ it.jsonPath() == """\$.errors[*][?(@.message == 'incorrect_format')]"""
+ }
pathAndValues.find {
it.method()== """.array("errors").hasSize(1)""" &&
it.jsonPath() == """\$.errors[*]"""
@@ -581,6 +687,52 @@ class JsonToJsonPathsConverterSpec extends Specification {
it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().arrayField().isEqualTo(38.791645)""" &&
it.jsonPath() == """\$[*].place.bounding_box.coordinates[*][*][?(@ == 38.791645)]"""
}
+ and:
+ pathAndValues.size() == 4
+ and:
+ pathAndValues.each {
+ JsonAssertion.assertThat(json).matchesJsonPath(it.jsonPath())
+ }
+ }
+
+ @RestoreSystemProperties
+ def "should manage to parse a double array with array size check"() {
+ given:
+ System.setProperty('spring.cloud.contract.verifier.assert.size', 'true')
+ String json = '''
+ [{
+ "place":
+ {
+ "bounding_box":
+ {
+ "coordinates":
+ [[
+ [-77.119759,38.995548],
+ [-76.909393,38.791645]
+ ]]
+ }
+ }
+ }]
+ '''
+ when:
+ JsonPaths pathAndValues = new JsonToJsonPathsConverter().transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json))
+ then:
+ pathAndValues.find {
+ it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().arrayField().isEqualTo(38.995548)""" &&
+ it.jsonPath() == """\$[*].place.bounding_box.coordinates[*][*][?(@ == 38.995548)]"""
+ }
+ pathAndValues.find {
+ it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().arrayField().isEqualTo(-77.119759)""" &&
+ it.jsonPath() == """\$[*].place.bounding_box.coordinates[*][*][?(@ == -77.119759)]"""
+ }
+ pathAndValues.find {
+ it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().arrayField().isEqualTo(-76.909393)""" &&
+ it.jsonPath() == """\$[*].place.bounding_box.coordinates[*][*][?(@ == -76.909393)]"""
+ }
+ pathAndValues.find {
+ it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().arrayField().isEqualTo(38.791645)""" &&
+ it.jsonPath() == """\$[*].place.bounding_box.coordinates[*][*][?(@ == 38.791645)]"""
+ }
pathAndValues.find {
it.method()== """.hasSize(1)""" &&
it.jsonPath() == """\$"""