diff --git a/docs/pom.xml b/docs/pom.xml
index 99972b5f3f..5eeb1fc5bb 100644
--- a/docs/pom.xml
+++ b/docs/pom.xml
@@ -35,6 +35,10 @@
docs
+
+ pl.project13.maven
+ git-commit-id-plugin
+
org.apache.maven.plugins
maven-dependency-plugin
diff --git a/docs/src/main/asciidoc/_project-features-contract.adoc b/docs/src/main/asciidoc/_project-features-contract.adoc
index 888208d444..9ddc5a94dd 100644
--- a/docs/src/main/asciidoc/_project-features-contract.adoc
+++ b/docs/src/main/asciidoc/_project-features-contract.adoc
@@ -166,6 +166,8 @@ include::{verifier_core_path}/src/test/resources/yml/contract.yml[tags=in_progre
----
====
+You can set the value of the `failOnInProgress` Spring Cloud Contract plugin property to ensure that your build will break when at least one contract in progress remains in your sources.
+
[[contract-dsl-passing-values-from-files]]
==== Passing Values from Files
diff --git a/docs/src/main/asciidoc/documentation-overview.adoc b/docs/src/main/asciidoc/documentation-overview.adoc
index 397b3b9628..1f7b66cb8f 100644
--- a/docs/src/main/asciidoc/documentation-overview.adoc
+++ b/docs/src/main/asciidoc/documentation-overview.adoc
@@ -12,9 +12,9 @@ as a map for the rest of the document.
The {project-full-name} reference guide is available as
-* {docs-url}/html[Multi-page HTML]
-* {docs-url}/htmlsingle[Single-page HTML]
-* {docs-url}/pdf/{project-name}.pdf[PDF]
+* {docs-url}reference/html[Multi-page HTML]
+* {docs-url}reference/htmlsingle[Single-page HTML]
+* {docs-url}reference/pdf/{project-name}.pdf[PDF]
Copies of this document may be made for your own use and for distribution to others,
provided that you do not charge any fee for such copies and further provided that each
diff --git a/docs/src/main/asciidoc/getting-started.adoc b/docs/src/main/asciidoc/getting-started.adoc
index 10959c3aab..57c841e0d1 100644
--- a/docs/src/main/asciidoc/getting-started.adoc
+++ b/docs/src/main/asciidoc/getting-started.adoc
@@ -202,11 +202,38 @@ As the implementation of the functionalities described by the contracts is not y
present, the tests fail.
To make them pass, you must add the correct implementation of either handling HTTP
-requests or messages. Also, you must add a correct base test class for auto-generated
+requests or messages. Also, you must add a base test class for auto-generated
tests to the project. This class is extended by all the auto-generated tests, and it
should contain all the setup information necessary to run them (for example `RestAssuredMockMvc`
controller setup or messaging test setup).
+The following example, from `pom.xml`, shows how to specify the base test class:
+
+====
+[src,xml]
+----
+
+
+
+ org.springframework.cloud
+ spring-cloud-contract-maven-plugin
+ 2.1.2.RELEASE
+ true
+
+ com.example.contractTest.BaseTestClass <1>
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+----
+<1> The `baseClassForTests` element lets you specify your base test class. It must be a child
+of a `configuration` element within `spring-cloud-contract-maven-plugin`.
+====
+
Once the implementation and the test base class are in place, the tests pass, and both the
application and the stub artifacts are built and installed in the local Maven repository.
You can now merge the changes, and you can publish both the application and the stub artifacts
@@ -320,9 +347,22 @@ portion of the file:
----
====
+[TIP]
+====
+The easiest way to get started is to go to https://start.spring.io[the Spring Initializr]
+and add "`Web`" and "`Contract Verifier`" as dependencies. Doing so pulls in the previously
+mentioned dependencies and everything else you need in the `pom.xml` file (except for
+setting the base test class, which we cover later in this section). The following image
+shows the settings to use in https://start.spring.io[the Spring Initializr]:
+
+image::start_spring_io_dependencies.png[width=800,alt=Spring Initializr with Web and Contract Verifier]
+====
+
Now you can add files with `REST/` messaging contracts
expressed in either Groovy DSL or YAML to the contracts directory, which is set by the
`contractsDslDir` property. By default, it is `$rootDir/src/test/resources/contracts`.
+Note that the file name does not matter. You can organize your contracts within this
+directory with whatever naming scheme you like.
For the HTTP stubs, a contract defines what kind of response should be returned for a
given request (taking into account the HTTP methods, URLs, headers, status codes, and so
@@ -385,7 +425,7 @@ response:
----
====
-In the case of messaging, you can define:
+If you need to use messaging, you can define:
* The input and output messages (taking into account from and where it
was sent, the message body, and the header).
@@ -412,7 +452,8 @@ Running `./mvnw clean install` automatically generates tests that verify the app
compliance with the added contracts. By default, the generated tests are under
`org.springframework.cloud.contract.verifier.tests.`.
-The generated tests may differ, depending on which framework and test type you have setup in your plugin.
+The generated tests may differ, depending on which framework and test type you have setup
+in your plugin.
In the next listing, you can find:
@@ -422,7 +463,10 @@ In the next listing, you can find:
Reactive, `Web-Flux`-based applications) set with the `WEBTESTCLIENT` test mode
- A Spock-based test with the `testFramework` property set to `SPOCK`
-The following listing shows all these samples:
+NOTE: You need only one of these test frameworks. MockMvc is the default. To use one
+of the other frameworks, add its library to your classpath.
+
+The following listing shows samples for all frameworks:
====
[source,java,indent=0,role="primary"]
@@ -531,13 +575,139 @@ As the implementation of the functionalities described by the contracts is not y
present, the tests fail.
To make them pass, you must add the correct implementation of handling either HTTP
-requests or messages. Also, you must add a correct base test class for auto-generated
+requests or messages. Also, you must add a base test class for auto-generated
tests to the project. This class is extended by all the auto-generated tests and should
contain all the setup necessary information needed to run them (for example,
`RestAssuredMockMvc` controller setup or messaging test setup).
+The following example, from `pom.xml`, shows how to specify the base test class:
+
+====
+[src,xml]
+----
+
+
+
+ org.springframework.cloud
+ spring-cloud-contract-maven-plugin
+ 2.1.2.RELEASE
+ true
+
+ com.example.contractTest.BaseTestClass <1>
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+----
+<1> The `baseClassForTests` element lets you specify your base test class. It must be a child
+of a `configuration` element within `spring-cloud-contract-maven-plugin`.
+====
+
+The following example shows a minimal (but functional) base test class:
+
+====
+[src,Java]
+----
+package com.example.contractTest;
+
+import org.junit.Before;
+
+import io.restassured.module.mockmvc.RestAssuredMockMvc;
+
+public class BaseTestClass {
+
+ @Before
+ public void setup() {
+ RestAssuredMockMvc.standaloneSetup(new FraudController());
+ }
+}
+----
+====
+
+This minimal class really is all you need to get your tests to work. It serves as a
+starting place to which the automatically generated tests attach.
+
+Now we can move on to the implementation. For that, we first need a data class, which we
+then use in our controller. The following listing shows the data class:
+
+====
+[src,Java]
+----
+package com.example.Test;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class LoanRequest {
+
+ @JsonProperty("client.id")
+ private String clientId;
+
+ private Long loanAmount;
+
+ public String getClientId() {
+ return clientId;
+ }
+
+ public void setClientId(String clientId) {
+ this.clientId = clientId;
+ }
+
+ public Long getLoanAmount() {
+ return loanAmount;
+ }
+
+ public void setLoanRequestAmount(Long loanAmount) {
+ this.loanAmount = loanAmount;
+ }
+}
+----
+====
+
+The preceding class provides an object in which we can store the parameters. Because the
+client ID in the contract is called `client.id`, we need to use the
+`@JsonProperty("client.id")` parameter to map it to the `clientId` field.
+
+Now we can move along to the controller, which the following listing shows:
+
+====
+[src,Java]
+----
+package com.example.docTest;
+
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class FraudController {
+
+ @PutMapping(value = "/fraudcheck", consumes="application/json", produces="application/json")
+ public String check(@RequestBody LoanRequest loanRequest) { <1>
+
+ if (loanRequest.getLoanAmount() > 10000) { <2>
+ return "{fraudCheckStatus: FRAUD, rejection.reason: Amount too high}"; <3>
+ } else {
+ return "{fraudCheckStatus: OK, acceptance.reason: Amount OK}"; <4>
+ }
+ }
+}
+----
+<1> We map the incoming parameters to a `LoanRequest` object.
+<2> We check the requested loan amount to see if it is too much.
+<3> If it is too much, we return the JSON (created with a simple string here) that the
+test expects.
+<4> If we had a test to catch when the amount is allowable, we could match it to this output.
+====
+
+The `FraudController` is about as simple as things get. You can do much more, including
+logging, validating the client ID, and so on.
+
Once the implementation and the test base class are in place, the tests pass, and both the
-application and the stub artifacts are built and installed in the local Maven repository.
+application and the stub artifacts are built and installed in the local Maven repository
Information about installing the stubs jar to the local repository appears in the logs, as
the following example shows:
diff --git a/docs/src/main/asciidoc/gradle-project.adoc b/docs/src/main/asciidoc/gradle-project.adoc
index 644ff58e66..1854cd170d 100644
--- a/docs/src/main/asciidoc/gradle-project.adoc
+++ b/docs/src/main/asciidoc/gradle-project.adoc
@@ -309,6 +309,7 @@ JAR is available offline, remotely, and so on).
* `deleteStubsAfterTest`: If set to `false`, do not remove any downloaded
contracts from temporary directories.
* `failOnNoContracts`: When enabled, will throw an exception when no contracts were found. Defaults to `true`.
+* `failOnInProgress`: If set to true then if any contracts that are in progress are found, will break the build. On the producer side you need to be explicit about the fact that you have contracts in progress and take into consideration that you might be causing false positive test execution results on the consumer side.. Defaults to `true`.
There is also the `contractRepository { ... }` closure that contains the following properties
diff --git a/docs/src/main/asciidoc/howto.adoc b/docs/src/main/asciidoc/howto.adoc
index 273ff81dfe..945001c37d 100644
--- a/docs/src/main/asciidoc/howto.adoc
+++ b/docs/src/main/asciidoc/howto.adoc
@@ -1448,4 +1448,11 @@ If you want to generate stubs at runtime for contracts, it's enough to switch th
If you want Stub Runner not to fail if no stubs were found, it's enough to switch the `generateStubs` property in the `@AutoConfigureStubRunner` annotation, or call the `withFailOnNoStubs(false)` method on the JUnit Rule or Extension. You can read more about this in <> of the documentation.
-If you want the plugins not to fail the build when no contracts were found, you can set the `failOnNoStubs` flag in Maven or call the `contractRepository { failOnNoStubs(false) }` Closure in Gradle.
\ No newline at end of file
+If you want the plugins not to fail the build when no contracts were found, you can set the `failOnNoStubs` flag in Maven or call the `contractRepository { failOnNoStubs(false) }` Closure in Gradle.
+
+[[how-to-mark-contract-in-progress]]
+== How can I Mark that a Contract Is in Progress
+
+If a contract is in progress, it means that the on the producer side tests will not be generated, but the stub will be. You can read more about this in <> of the documentation.
+
+In a CI build, before going to production, you would like to ensure that no in progress contracts are there on the classpath. That's because you may lead to false positives. That's why, by default, in the Spring Cloud Contract plugin, we set the value of `failOnInProgress` to `true`. If you want to allow such contracts when tests are to be generated, just set the flag to `false`.
\ No newline at end of file
diff --git a/docs/src/main/asciidoc/images/start_spring_io_dependencies.png b/docs/src/main/asciidoc/images/start_spring_io_dependencies.png
new file mode 100644
index 0000000000..0b4784234b
Binary files /dev/null and b/docs/src/main/asciidoc/images/start_spring_io_dependencies.png differ
diff --git a/docs/src/main/asciidoc/maven-project.adoc b/docs/src/main/asciidoc/maven-project.adoc
index 82607e4d47..e19f65b1be 100644
--- a/docs/src/main/asciidoc/maven-project.adoc
+++ b/docs/src/main/asciidoc/maven-project.adoc
@@ -17,6 +17,8 @@ following sections:
* <>
* <>
+You can also check the plugin's documentation link:../../spring-cloud-contract-maven-plugin/index.html[here].
+
[[maven-add-plugin]]
== Adding the Maven Plugin
@@ -223,6 +225,7 @@ extends `com.example.base.BaseClass`. This setting takes precedence over
* `contractsProperties`: A map that contains properties to be passed to Spring Cloud Contract
components. Those properties might be used by (for example) built-in or custom Stub Downloaders.
* `failOnNoContracts`: When enabled, will throw an exception when no contracts were found. Defaults to `true`.
+* `failOnInProgress`: If set to true then if any contracts that are in progress are found, will break the build. On the producer side you need to be explicit about the fact that you have contracts in progress and take into consideration that you might be causing false positive test execution results on the consumer side.. Defaults to `true`.
If you want to download your contract definitions from a Maven repository, you can use
the following options:
diff --git a/docs/src/main/asciidoc/index.htmlpdfadoc b/docs/src/main/asciidoc/spring-cloud-contract.pdfadoc
similarity index 100%
rename from docs/src/main/asciidoc/index.htmlpdfadoc
rename to docs/src/main/asciidoc/spring-cloud-contract.pdfadoc
diff --git a/spring-cloud-contract-dependencies/pom.xml b/spring-cloud-contract-dependencies/pom.xml
index 74097cd864..d08f4a5c31 100644
--- a/spring-cloud-contract-dependencies/pom.xml
+++ b/spring-cloud-contract-dependencies/pom.xml
@@ -15,7 +15,7 @@
spring-cloud-contract-dependencies
Spring Cloud Contract Dependencies
- 2.24.0
+ 2.24.1
0.4.13
4.0.0
3.3.9
diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/pom.xml b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/pom.xml
index 314c02e159..678d9bf343 100644
--- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/pom.xml
+++ b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/pom.xml
@@ -20,6 +20,7 @@
UTF-8
UTF-8
build
+ package
@@ -68,7 +69,7 @@
attach-artifacts
- package
+ ${build-helper-maven-plugin.phase}
attach-artifact
@@ -242,6 +243,7 @@
assemble
+ none
diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/ContractVerifierExtension.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/ContractVerifierExtension.groovy
index 208b310941..0bd6f3cf95 100644
--- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/ContractVerifierExtension.groovy
+++ b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/ContractVerifierExtension.groovy
@@ -145,6 +145,14 @@ class ContractVerifierExtension {
*/
boolean failOnNoContracts = true
+ /**
+ * If set to true then if any contracts that are in progress are found, will break the
+ * build. On the producer side you need to be explicit about the fact that you have
+ * contracts in progress and take into consideration that you might be causing false
+ * positive test execution results on the consumer side.
+ */
+ boolean failOnInProgress = true;
+
ContractRepository contractRepository = new ContractRepository()
/**
@@ -252,6 +260,10 @@ class ContractVerifierExtension {
this.failOnNoContracts = failOnNoContracts
}
+ void failOnInProgress(boolean failOnInProgress) {
+ this.failOnInProgress = failOnInProgress
+ }
+
ContractVerifierExtension copy() {
return new ContractVerifierExtension(
testFramework: this.testFramework,
@@ -272,6 +284,7 @@ class ContractVerifierExtension {
stubsSuffix: this.stubsSuffix,
assertJsonSize: this.assertJsonSize,
failOnNoContracts: this.failOnNoContracts,
+ failOnInProgress: this.failOnInProgress,
contractRepository: new ContractRepository(
repositoryUrl: this.contractRepository.repositoryUrl,
username: this.contractRepository.username,
diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/ExtensionToProperties.groovy b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/ExtensionToProperties.groovy
index 71099d0156..c6dd3dc560 100644
--- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/ExtensionToProperties.groovy
+++ b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/ExtensionToProperties.groovy
@@ -33,7 +33,8 @@ class ExtensionToProperties {
assertJsonSize: extension.getAssertJsonSize(),
packageWithBaseClasses: extension.getPackageWithBaseClasses(),
baseClassMappings: extension.getBaseClassMappings(),
- excludeBuildFolders: extension.getExcludeBuildFolders()
+ excludeBuildFolders: extension.getExcludeBuildFolders(),
+ failOnInProgress: extension.getFailOnInProgress()
)
}
}
diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties
index 26bf943554..b5d38ac0d9 100644
--- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties
+++ b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties
@@ -13,7 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
-wiremockVersion=2.24.0
+wiremockVersion=2.24.1
jsonAssertVersion=0.4.13
verifierVersion=2.2.0.BUILD-SNAPSHOT
groovyVersion=2.4.17
diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle.properties b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle.properties
index c2e8c39f6b..bdf083b1e9 100644
--- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle.properties
+++ b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle.properties
@@ -13,7 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
-wiremockVersion=2.24.0
+wiremockVersion=2.24.1
jsonAssertVersion=0.4.13
verifierVersion=2.2.0.BUILD-SNAPSHOT
bootVersion=2.2.0.BUILD-SNAPSHOT
diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle.properties b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle.properties
index c2e8c39f6b..bdf083b1e9 100644
--- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle.properties
+++ b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle.properties
@@ -13,7 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
-wiremockVersion=2.24.0
+wiremockVersion=2.24.1
jsonAssertVersion=0.4.13
verifierVersion=2.2.0.BUILD-SNAPSHOT
bootVersion=2.2.0.BUILD-SNAPSHOT
diff --git a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle.properties b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle.properties
index d4ec0dc989..964754f1e1 100644
--- a/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle.properties
+++ b/spring-cloud-contract-tools/spring-cloud-contract-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle.properties
@@ -13,7 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
-wiremockVersion=2.24.0
+wiremockVersion=2.24.1
jsonAssertVersion=0.4.13
verifierVersion=2.2.0.BUILD-SNAPSHOT
bootVersion=2.2.0.BUILD-SNAPSHOT
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 50a3f6c0fc..37d12eba1a 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
@@ -233,8 +233,17 @@ public class GenerateTestsMojo extends AbstractMojo {
* When enabled, this flag will tell stub runner to throw an exception when no stubs /
* contracts were found.
*/
- @Parameter(property = "failOnNoStubs", defaultValue = "true")
- private boolean failOnNoStubs;
+ @Parameter(property = "failOnNoContracts", defaultValue = "true")
+ private boolean failOnNoContracts;
+
+ /**
+ * If set to true then if any contracts that are in progress are found, will break the
+ * build. On the producer side you need to be explicit about the fact that you have
+ * contracts in progress and take into consideration that you might be causing false
+ * positive test execution results on the consumer side.
+ */
+ @Parameter(property = "failOnInProgress", defaultValue = "true")
+ private boolean failOnInProgress = true;
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
@@ -259,13 +268,14 @@ public class GenerateTestsMojo extends AbstractMojo {
getLog().info(
"Generating server tests source code for Spring Cloud Contract Verifier contract verification");
final ContractVerifierConfigProperties config = new ContractVerifierConfigProperties();
+ config.setFailOnInProgress(this.failOnInProgress);
// download contracts, unzip them and pass as output directory
File contractsDirectory = new MavenContractsDownloader(this.project,
this.contractDependency, this.contractsPath, this.contractsRepositoryUrl,
this.contractsMode, getLog(), this.contractsRepositoryUsername,
this.contractsRepositoryPassword, this.contractsRepositoryProxyHost,
this.contractsRepositoryProxyPort, this.deleteStubsAfterTest,
- this.contractsProperties, this.failOnNoStubs)
+ this.contractsProperties, this.failOnNoContracts)
.downloadAndUnpackContractsIfRequired(config,
this.contractsDirectory);
getLog().info(
diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/TestGenerator.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/TestGenerator.groovy
index 47fa5e6cba..0ef22f88d1 100755
--- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/TestGenerator.groovy
+++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/TestGenerator.groovy
@@ -89,6 +89,16 @@ class TestGenerator {
.build()
}
+ protected TestGenerator(ContractVerifierConfigProperties configProperties, SingleTestGenerator generator, FileSaver saver, ContractFileScanner contractFileScanner) {
+ this.configProperties = configProperties
+ if (configProperties.contractsDslDir == null) {
+ throw new ContractVerifierException("Stubs directory not found under " + configProperties.contractsDslDir)
+ }
+ this.generator = generator
+ this.saver = saver
+ this.contractFileScanner = contractFileScanner
+ }
+
int generate() {
generateTestClasses(basePackageName())
NamesUtil.recrusiveDirectoryToPackage(configProperties.generatedTestSourcesDir)
@@ -113,6 +123,15 @@ class TestGenerator {
void generateTestClasses(final String basePackageName) {
ListMultimap contracts = contractFileScanner.
findContracts()
+ Set>> inProgress = contracts.asMap().entrySet()
+ .findAll { Map.Entry> entry -> entry.value.any { it.anyInProgress() }}
+ if (!inProgress.isEmpty() && configProperties.failOnInProgress) {
+ throw new IllegalStateException("In progress contracts found in paths [" + inProgress.collect { it.key.toString() }.join(",") + "] and the switch [failOnInProgress] is set to [true]. Either unmark those contracts as in progress, or set the switch to [false].")
+ }
+ processAllNotInProgress(contracts,basePackageName)
+ }
+
+ @PackageScope Set>> processAllNotInProgress(ListMultimap contracts, String basePackageName) {
contracts.asMap().entrySet()
.findAll { Map.Entry> entry -> !entry.value.any { it.anyInProgress() }}
.each {
diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.java b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.java
index 3693d49a62..6d36151f44 100644
--- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.java
+++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.java
@@ -175,6 +175,14 @@ public class ContractVerifierConfigProperties {
*/
private boolean excludeBuildFolders;
+ /**
+ * If set to true then if any contracts that are in progress are found, will break the
+ * build. On the producer side you need to be explicit about the fact that you have
+ * contracts in progress and take into consideration that you might be causing false
+ * positive test execution results on the consumer side.
+ */
+ private boolean failOnInProgress = true;
+
@Deprecated
public void setTargetFramework(TestFramework targetFramework) {
log.warn("Please use the [testFramework] field. [targetFramework] is deprecated");
@@ -366,4 +374,12 @@ public class ContractVerifierConfigProperties {
this.excludeBuildFolders = excludeBuildFolders;
}
+ public boolean isFailOnInProgress() {
+ return this.failOnInProgress;
+ }
+
+ public void setFailOnInProgress(boolean failOnInProgress) {
+ this.failOnInProgress = failOnInProgress;
+ }
+
}
diff --git a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/TestGeneratorTests.java b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/TestGeneratorTests.java
new file mode 100644
index 0000000000..a0c0ac09b8
--- /dev/null
+++ b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/TestGeneratorTests.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2013-2019 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
+ *
+ * https://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.cloud.contract.verifier;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+import org.assertj.core.api.BDDAssertions;
+import org.junit.Test;
+import org.mockito.BDDMockito;
+import wiremock.com.google.common.collect.ArrayListMultimap;
+import wiremock.com.google.common.collect.ListMultimap;
+
+import org.springframework.cloud.contract.spec.Contract;
+import org.springframework.cloud.contract.verifier.builder.SingleTestGenerator;
+import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties;
+import org.springframework.cloud.contract.verifier.file.ContractFileScanner;
+import org.springframework.cloud.contract.verifier.file.ContractMetadata;
+
+public class TestGeneratorTests {
+
+ @Test
+ public void should_throw_exception_when_in_progress_contracts_found() {
+ // given:
+ ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties();
+ properties.setFailOnInProgress(true);
+ properties.setContractsDslDir(new File("."));
+ SingleTestGenerator singleTestGenerator = BDDMockito
+ .mock(SingleTestGenerator.class);
+ FileSaver fileSaver = BDDMockito.mock(FileSaver.class);
+ // and:
+ ArrayListMultimap multimap = ArrayListMultimap.create();
+ Path path = new File(".").toPath();
+ multimap.put(path,
+ new ContractMetadata(path, false, 0, null, Contract.make(it -> {
+ it.inProgress();
+ it.request(r -> {
+ r.method(r.GET());
+ r.url("/foo");
+ });
+ it.response(r -> {
+ r.status(r.OK());
+ });
+ })));
+ ContractFileScanner scanner = new ContractFileScanner(null, null, null) {
+ @Override
+ public ListMultimap findContracts() {
+ return multimap;
+ }
+ };
+ // and:
+ TestGenerator testGenerator = new TestGenerator(properties, singleTestGenerator,
+ fileSaver, scanner);
+
+ // then:
+ BDDAssertions.thenThrownBy(() -> {
+ // when:
+ testGenerator.generateTestClasses("com.example");
+ }).isInstanceOf(IllegalStateException.class)
+ .hasMessageContaining("In progress contracts found in");
+ }
+
+ @Test
+ public void should_not_throw_exception_when_in_progress_contracts_found_but_the_fail_on_in_progress_switch_is_off() {
+ // given:
+ ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties();
+ properties.setFailOnInProgress(false);
+ properties.setContractsDslDir(new File("."));
+ SingleTestGenerator singleTestGenerator = BDDMockito
+ .mock(SingleTestGenerator.class);
+ FileSaver fileSaver = BDDMockito.mock(FileSaver.class);
+ // and:
+ ArrayListMultimap multimap = ArrayListMultimap.create();
+ Path path = new File(".").toPath();
+ multimap.put(path,
+ new ContractMetadata(path, false, 0, null, Contract.make(it -> {
+ it.inProgress();
+ it.request(r -> {
+ r.method(r.GET());
+ r.url("/foo");
+ });
+ it.response(r -> {
+ r.status(r.OK());
+ });
+ })));
+ ContractFileScanner scanner = new ContractFileScanner(null, null, null) {
+ @Override
+ public ListMultimap findContracts() {
+ return multimap;
+ }
+ };
+ // and:
+ TestGenerator testGenerator = new TestGenerator(properties, singleTestGenerator,
+ fileSaver, scanner) {
+ @Override
+ Set>> processAllNotInProgress(
+ ListMultimap contracts,
+ String basePackageName) {
+ return null;
+ }
+ };
+
+ // when:
+ testGenerator.generateTestClasses("com.example");
+
+ // then: noExceptionThrown()
+ }
+
+}
diff --git a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGeneratorSpec.groovy b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGeneratorSpec.groovy
index 01f6c0b2e9..910ca8144d 100644
--- a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGeneratorSpec.groovy
+++ b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGeneratorSpec.groovy
@@ -16,14 +16,20 @@
package org.springframework.cloud.contract.verifier.builder
+import java.nio.file.Paths
+
import org.junit.Rule
import org.junit.rules.TemporaryFolder
import spock.lang.Issue
import spock.lang.Specification
+import wiremock.com.google.common.collect.ArrayListMultimap
+import org.springframework.cloud.contract.spec.Contract
+import org.springframework.cloud.contract.verifier.FileSaver
import org.springframework.cloud.contract.verifier.TestGenerator
import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties
import org.springframework.cloud.contract.verifier.config.TestFramework
+import org.springframework.cloud.contract.verifier.file.ContractFileScanner
import org.springframework.cloud.contract.verifier.file.ContractMetadata
import org.springframework.cloud.contract.verifier.util.SyntaxChecker
import org.springframework.util.FileSystemUtils