Sync docs from master to gh-pages
This commit is contained in:
@@ -145,7 +145,7 @@ visible in your Groovy files. The following examples show how to test the depend
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><scope></span>test<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></scope></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></dependency></span></pre><p class="primary">
|
||||
</p><p class="secondary"><b>Gradle. </b>
|
||||
</p><pre class="programlisting">testCompile(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"com.example:beer-common:0.0.1-SNAPSHOT"</span>)</pre><p class="secondary">
|
||||
</p><pre class="programlisting">testCompile(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"com.example:beer-common:0.0.1.BUILD-SNAPSHOT"</span>)</pre><p class="secondary">
|
||||
</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_test_a_dependency_in_the_plugins_dependencies" href="#_test_a_dependency_in_the_plugins_dependencies"></a>9.1.4 Test a Dependency in the Plugin’s Dependencies</h3></div></div></div><p>Now, you must add the dependency for the plugin to reuse at runtime, as shown in the
|
||||
following example:</p><p class="primary"><b>Maven. </b>
|
||||
</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><plugin></span>
|
||||
@@ -172,7 +172,7 @@ following example:</p><p class="primary"><b>Maven. </b>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></dependencies></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></plugin></span></pre><p class="primary">
|
||||
</p><p class="secondary"><b>Gradle. </b>
|
||||
</p><pre class="programlisting">classpath <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"com.example:beer-common:0.0.1-SNAPSHOT"</span></pre><p class="secondary">
|
||||
</p><pre class="programlisting">classpath <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"com.example:beer-common:0.0.1.BUILD-SNAPSHOT"</span></pre><p class="secondary">
|
||||
</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_referencing_classes_in_dsls" href="#_referencing_classes_in_dsls"></a>9.1.5 Referencing classes in DSLs</h3></div></div></div><p>You can now reference your classes in your DSL, as shown in the following example:</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">package</span> contracts.beer.rest
|
||||
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">import</span> com.example.ConsumerUtils
|
||||
@@ -214,4 +214,4 @@ then:
|
||||
contentType(applicationJson())
|
||||
}
|
||||
}
|
||||
}</pre></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi_contract-dsl.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="multi__using_the_pluggable_architecture.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">8. Contract DSL </td><td width="20%" align="center"><a accesskey="h" href="multi_spring-cloud-contract.html">Home</a></td><td width="40%" align="right" valign="top"> 10. Using the Pluggable Architecture</td></tr></table></div></body></html>
|
||||
}</pre><div class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Important"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="images/important.png"></td><th align="left">Important</th></tr><tr><td align="left" valign="top"><p>You can set the Spring Cloud Contract plugin up by setting <code class="literal">convertToYaml</code> to <code class="literal">true</code>. That way you will NOT have to add the dependency with the extended functionality to the consumer side, since the consumer side will be using YAML contracts instead of Groovy ones.</p></td></tr></table></div></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="multi_contract-dsl.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="multi__using_the_pluggable_architecture.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">8. Contract DSL </td><td width="20%" align="center"><a accesskey="h" href="multi_spring-cloud-contract.html">Home</a></td><td width="40%" align="right" valign="top"> 10. Using the Pluggable Architecture</td></tr></table></div></body></html>
|
||||
@@ -457,10 +457,95 @@ the `publish` task is executed
|
||||
publish.dependsOn("publishStubsToScm")</pre><p>
|
||||
</p><p>With such a setup:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">Git project will be cloned to a temporary directory</li><li class="listitem">The SCM stub downloader will go to <code class="literal">META-INF/groupId/artifactId/version/contracts</code> folder
|
||||
to find contracts. E.g. for <code class="literal">com.example:foo:1.0.0</code> the path would be
|
||||
<code class="literal">META-INF/com.example/foo/1.0.0/contracts</code></li><li class="listitem">Tests will be generated from the contracts</li><li class="listitem">Stubs will be created from the contracts</li><li class="listitem">Once the tests pass, the stubs will be committed in the cloned repository</li><li class="listitem">Finally, a push will be done to that repo’s <code class="literal">origin</code></li></ul></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="_keeping_contracts_with_the_producer_and_stubs_in_an_external_repository" href="#_keeping_contracts_with_the_producer_and_stubs_in_an_external_repository"></a>Keeping contracts with the producer and stubs in an external repository</h4></div></div></div><p>It is also possible to keep the contracts in the producer repository, but keep the stubs in an external git repo.
|
||||
<code class="literal">META-INF/com.example/foo/1.0.0/contracts</code></li><li class="listitem">Tests will be generated from the contracts</li><li class="listitem">Stubs will be created from the contracts</li><li class="listitem">Once the tests pass, the stubs will be committed in the cloned repository</li><li class="listitem">Finally, a push will be done to that repo’s <code class="literal">origin</code></li></ul></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_producer_with_contracts_stored_locally" href="#_producer_with_contracts_stored_locally"></a>3.6.3 Producer with contracts stored locally</h3></div></div></div><p>Another option to use the SCM as the destination for stubs and contracts is to store the contracts locally, with the producer, and only push the contracts and the stubs to SCM. Below, you can find the setup required to achieve this using Maven and Gradle.</p><p><b>Maven. </b>
|
||||
</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><plugin></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><groupId></span>org.springframework.cloud<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></groupId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><artifactId></span>spring-cloud-contract-maven-plugin<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></artifactId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><version></span>${spring-cloud-contract.version}<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></version></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><extensions></span>true<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></extensions></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!-- In the default configuration, we want to use the contracts stored locally --></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><configuration></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><baseClassMappings></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><baseClassMapping></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><contractPackageRegex></span>.*messaging.*<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></contractPackageRegex></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><baseClassFQN></span>com.example.BeerMessagingBase<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></baseClassFQN></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></baseClassMapping></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><baseClassMapping></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><contractPackageRegex></span>.*rest.*<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></contractPackageRegex></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><baseClassFQN></span>com.example.BeerRestBase<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></baseClassFQN></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></baseClassMapping></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></baseClassMappings></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><basePackageForTests></span>com.example<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></basePackageForTests></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></configuration></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><executions></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><execution></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><phase></span>package<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></phase></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><goals></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!-- By default we will not push the stubs back to SCM,
|
||||
you have to explicitly add it as a goal --></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><goal></span>pushStubsToScm<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></goal></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></goals></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><configuration></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!-- We want to pick contracts from a Git repository --></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><contractsRepositoryUrl></span>git://file://${env.ROOT}/target/contract_empty_git/<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></contractsRepositoryUrl></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!-- Example of URL via git protocol --></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!--<contractsRepositoryUrl>git://git@github.com:spring-cloud-samples/spring-cloud-contract-samples.git</contractsRepositoryUrl>--></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!-- Example of URL via http protocol --></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!--<contractsRepositoryUrl>git://https://github.com/spring-cloud-samples/spring-cloud-contract-samples.git</contractsRepositoryUrl>--></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!-- We reuse the contract dependency section to set up the path
|
||||
to the folder that contains the contract definitions. In our case the
|
||||
path will be /groupId/artifactId/version/contracts --></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><contractDependency></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><groupId></span>${project.groupId}<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></groupId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><artifactId></span>${project.artifactId}<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></artifactId></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><version></span>${project.version}<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></version></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></contractDependency></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment"><!-- The mode can't be classpath --></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><contractsMode></span>LOCAL<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></contractsMode></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></configuration></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></execution></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></executions></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></plugin></span></pre><p>
|
||||
</p><p><b>Gradle. </b>
|
||||
</p><pre class="programlisting">contracts {
|
||||
// Base package for generated tests
|
||||
basePackageForTests = "com.example"
|
||||
baseClassMappings {
|
||||
baseClassMapping(".*messaging.*", "com.example.BeerMessagingBase")
|
||||
baseClassMapping(".*rest.*", "com.example.BeerRestBase")
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
In this scenario we want to publish stubs to SCM whenever
|
||||
the `publish` task is executed
|
||||
*/
|
||||
publishStubsToScm {
|
||||
// We want to modify the default set up of the plugin when publish stubs to scm is called
|
||||
customize {
|
||||
// We want to pick contracts from a Git repository
|
||||
contractDependency {
|
||||
stringNotation = "${project.group}:${project.name}:${project.version}"
|
||||
}
|
||||
/*
|
||||
We reuse the contract dependency section to set up the path
|
||||
to the folder that contains the contract definitions. In our case the
|
||||
path will be /groupId/artifactId/version/contracts
|
||||
*/
|
||||
contractRepository {
|
||||
repositoryUrl = "git://file://${System.getenv("ROOT")}/target/contract_empty_git/"
|
||||
}
|
||||
// The mode can't be classpath
|
||||
contractsMode = "LOCAL"
|
||||
}
|
||||
}
|
||||
|
||||
publish.dependsOn("publishStubsToScm")
|
||||
publishToMavenLocal.dependsOn("publishStubsToScm")</pre><p>
|
||||
</p><p>With such a setup:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">Contracts from the default <code class="literal">src/test/resources/contracts</code> directory will be picked</li><li class="listitem">Tests will be generated from the contracts</li><li class="listitem">Stubs will be created from the contracts</li><li class="listitem"><p class="simpara">Once the tests pass</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem">Git project will be cloned to a temporary directory</li><li class="listitem">The stubs and contracts will be committed in the cloned repository</li></ul></div></li><li class="listitem">Finally, a push will be done to that repo’s <code class="literal">origin</code></li></ul></div><div class="section"><div class="titlepage"><div><div><h4 class="title"><a name="_keeping_contracts_with_the_producer_and_stubs_in_an_external_repository" href="#_keeping_contracts_with_the_producer_and_stubs_in_an_external_repository"></a>Keeping contracts with the producer and stubs in an external repository</h4></div></div></div><p>It is also possible to keep the contracts in the producer repository, but keep the stubs in an external git repo.
|
||||
This is most useful when you want to use the base consumer-producer collaboration flow, but do not have a possibility to
|
||||
use an artifact repository for storing the stubs.</p><p>In order to do that, use the usual producer setup, and then add the <code class="literal">pushStubsToScm</code> goal and set
|
||||
<code class="literal">contractsRepositoryUrl</code> to the repository where you want to keep the stubs.</p></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_consumer_2" href="#_consumer_2"></a>3.6.3 Consumer</h3></div></div></div><p>On the consumer side when passing the <code class="literal">repositoryRoot</code> parameter,
|
||||
<code class="literal">contractsRepositoryUrl</code> to the repository where you want to keep the stubs.</p></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="_consumer_2" href="#_consumer_2"></a>3.6.4 Consumer</h3></div></div></div><p>On the consumer side when passing the <code class="literal">repositoryRoot</code> parameter,
|
||||
either from the <code class="literal">@AutoConfigureStubRunner</code> annotation, the
|
||||
JUnit rule, JUnit 5 extension or properties, it’s enough to pass the URL of the
|
||||
SCM repository, prefixed with the protocol. For example</p><pre class="programlisting">@AutoConfigureStubRunner(
|
||||
|
||||
@@ -638,6 +638,7 @@ First, add the <code class="literal">Spring Cloud Contract</code> BOM.</p><pre c
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><extensions></span>true<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></extensions></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><configuration></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><packageWithBaseClasses></span>com.example.fraud<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></packageWithBaseClasses></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><convertToYaml></span>true<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></convertToYaml></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></configuration></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></plugin></span></pre><p>Since the plugin was added, you get the <code class="literal">Spring Cloud Contract Verifier</code> features which,
|
||||
from the provided contracts:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">generate and run tests</li><li class="listitem">produce and install stubs</li></ul></div><p>You do not want to generate tests since you, as the consumer, want only to play with the
|
||||
@@ -703,6 +704,7 @@ $ git pull https://your-git-server.com/server-side-fork.git contract-change-pr</
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><extensions></span>true<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></extensions></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><configuration></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><packageWithBaseClasses></span>com.example.fraud<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></packageWithBaseClasses></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><convertToYaml></span>true<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></convertToYaml></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></configuration></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></plugin></span></pre><div class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Important"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="images/important.png"></td><th align="left">Important</th></tr><tr><td align="left" valign="top"><p>This example uses "convention based" naming by setting the
|
||||
<code class="literal">packageWithBaseClasses</code> property. Doing so means that the two last packages combine to
|
||||
|
||||
@@ -144,7 +144,7 @@ closure to set it up.</li><li class="listitem"><span class="strong"><strong>cont
|
||||
downloaded, the path defaults to <code class="literal">groupid/artifactid</code> where <code class="literal">groupid</code> is slash
|
||||
separated. Otherwise, it scans contracts under the provided directory.</li><li class="listitem"><span class="strong"><strong>contractsMode</strong></span>: Specifies the mode of downloading contracts (whether the
|
||||
JAR is available offline, remotely etc.)</li><li class="listitem"><span class="strong"><strong>deleteStubsAfterTest</strong></span>: If set to <code class="literal">false</code> will not remove any downloaded
|
||||
contracts from temporary directories</li></ul></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="gradle-single-base-class" href="#gradle-single-base-class"></a>4.1.10 Single Base Class for All Tests</h3></div></div></div><p>When using Spring Cloud Contract Verifier in default MockMvc, you need to create a base
|
||||
contracts from temporary directories</li></ul></div><p>Below you can find a list of experimental features you can turn on via the plugin:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><span class="strong"><strong>convertToYaml</strong></span>: converts all DSLs to the declarative, YAML format. This can be extremely useful when you’re using external libraries in your Groovy DSLs. By turning this feature on (by setting it to <code class="literal">true</code>) you will not need to add the library dependency on the consumer side.</li><li class="listitem"><span class="strong"><strong>assertJsonSize</strong></span>: You can check the size of JSON arrays in the generated tests. This feature is disabled by default.</li></ul></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="gradle-single-base-class" href="#gradle-single-base-class"></a>4.1.10 Single Base Class for All Tests</h3></div></div></div><p>When using Spring Cloud Contract Verifier in default MockMvc, you need to create a base
|
||||
specification for all generated acceptance tests. In this class, you need to point to an
|
||||
endpoint, which should be verified.</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">abstract</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">class</span> BaseMockMvcSpec <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">extends</span> Specification {
|
||||
|
||||
@@ -231,6 +231,7 @@ following sections:</p><div class="itemizedlist"><ul class="itemizedlist" style=
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><extensions></span>true<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></extensions></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><configuration></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><packageWithBaseClasses></span>com.example.fraud<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></packageWithBaseClasses></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"><convertToYaml></span>true<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></convertToYaml></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></configuration></span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-tag"></plugin></span></pre><p>You can read more in the
|
||||
<a class="link" href="https://cloud.spring.io/spring-cloud-static/spring-cloud-contract/2.0.0.RELEASE/spring-cloud-contract-maven-plugin/" target="_top">Spring
|
||||
@@ -388,7 +389,7 @@ the following options:</p><div class="itemizedlist"><ul class="itemizedlist" sty
|
||||
Defaults to <code class="literal">groupid/artifactid</code> where <code class="literal">gropuid</code> is slash separated.</li><li class="listitem"><span class="strong"><strong>contractsMode</strong></span>: Picks the mode in which stubs will be found and registered</li><li class="listitem"><span class="strong"><strong>deleteStubsAfterTest</strong></span>: If set to <code class="literal">false</code> will not remove any downloaded
|
||||
contracts from temporary directories</li><li class="listitem"><span class="strong"><strong>contractsRepositoryUrl</strong></span>: URL to a repo with the artifacts that have contracts. If it is not provided,
|
||||
use the current Maven ones.</li><li class="listitem"><span class="strong"><strong>contractsRepositoryUsername</strong></span>: The user name to be used to connect to the repo with contracts.</li><li class="listitem"><span class="strong"><strong>contractsRepositoryPassword</strong></span>: The password to be used to connect to the repo with contracts.</li><li class="listitem"><span class="strong"><strong>contractsRepositoryProxyHost</strong></span>: The proxy host to be used to connect to the repo with contracts.</li><li class="listitem"><span class="strong"><strong>contractsRepositoryProxyPort</strong></span>: The proxy port to be used to connect to the repo with contracts.</li></ul></div><p>We cache only non-snapshot, explicitly provided versions (for example
|
||||
<code class="literal">+</code> or <code class="literal">1.0.0.BUILD-SNAPSHOT</code> won’t get cached). By default, this feature is turned on.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="maven-single-base" href="#maven-single-base"></a>4.2.8 Single Base Class for All Tests</h3></div></div></div><p>When using Spring Cloud Contract Verifier in default MockMvc, you need to create a base
|
||||
<code class="literal">+</code> or <code class="literal">1.0.0.BUILD-SNAPSHOT</code> won’t get cached). By default, this feature is turned on.</p><p>Below you can find a list of experimental features you can turn on via the plugin:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><span class="strong"><strong>convertToYaml</strong></span>: converts all DSLs to the declarative, YAML format. This can be extremely useful when you’re using external libraries in your Groovy DSLs. By turning this feature on (by setting it to <code class="literal">true</code>) you will not need to add the library dependency on the consumer side.</li><li class="listitem"><span class="strong"><strong>assertJsonSize</strong></span>: You can check the size of JSON arrays in the generated tests. This feature is disabled by default.</li></ul></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="maven-single-base" href="#maven-single-base"></a>4.2.8 Single Base Class for All Tests</h3></div></div></div><p>When using Spring Cloud Contract Verifier in default MockMvc, you need to create a base
|
||||
specification for all generated acceptance tests. In this class, you need to point to an
|
||||
endpoint, which should be verified.</p><pre class="programlisting"><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">package</span> org.mycompany.tests
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -656,80 +656,80 @@ use in your contracts, as shown in the following example:</p><pre class="program
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> Pattern.compile(values.collect({<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"^$it\$"</span>}).join(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"|"</span>))
|
||||
}
|
||||
|
||||
Pattern onlyAlphaUnicode() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> ONLY_ALPHA_UNICODE
|
||||
RegexProperty onlyAlphaUnicode() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> RegexProperty(ONLY_ALPHA_UNICODE).asString()
|
||||
}
|
||||
|
||||
Pattern alphaNumeric() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> ALPHA_NUMERIC
|
||||
RegexProperty alphaNumeric() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> RegexProperty(ALPHA_NUMERIC).asString()
|
||||
}
|
||||
|
||||
Pattern number() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> NUMBER
|
||||
RegexProperty number() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> RegexProperty(NUMBER).asDouble()
|
||||
}
|
||||
|
||||
Pattern positiveInt() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> POSITIVE_INT
|
||||
RegexProperty positiveInt() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> RegexProperty(POSITIVE_INT).asInteger()
|
||||
}
|
||||
|
||||
Pattern anyBoolean() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> TRUE_OR_FALSE
|
||||
RegexProperty anyBoolean() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> RegexProperty(TRUE_OR_FALSE).asBooleanType()
|
||||
}
|
||||
|
||||
Pattern anInteger() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> INTEGER
|
||||
RegexProperty anInteger() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> RegexProperty(INTEGER).asInteger()
|
||||
}
|
||||
|
||||
Pattern aDouble() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> DOUBLE
|
||||
RegexProperty aDouble() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> RegexProperty(DOUBLE).asDouble()
|
||||
}
|
||||
|
||||
Pattern ipAddress() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> IP_ADDRESS
|
||||
RegexProperty ipAddress() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> RegexProperty(IP_ADDRESS).asString()
|
||||
}
|
||||
|
||||
Pattern hostname() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> HOSTNAME_PATTERN
|
||||
RegexProperty hostname() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> RegexProperty(HOSTNAME_PATTERN).asString()
|
||||
}
|
||||
|
||||
Pattern email() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> EMAIL
|
||||
RegexProperty email() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> RegexProperty(EMAIL).asString()
|
||||
}
|
||||
|
||||
Pattern url() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> URL
|
||||
RegexProperty url() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> RegexProperty(URL).asString()
|
||||
}
|
||||
|
||||
Pattern httpsUrl() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> HTTPS_URL
|
||||
RegexProperty httpsUrl() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> RegexProperty(HTTPS_URL).asString()
|
||||
}
|
||||
|
||||
Pattern uuid(){
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> UUID
|
||||
RegexProperty uuid(){
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> RegexProperty(UUID).asString()
|
||||
}
|
||||
|
||||
Pattern isoDate() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> ANY_DATE
|
||||
RegexProperty isoDate() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> RegexProperty(ANY_DATE).asString()
|
||||
}
|
||||
|
||||
Pattern isoDateTime() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> ANY_DATE_TIME
|
||||
RegexProperty isoDateTime() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> RegexProperty(ANY_DATE_TIME).asString()
|
||||
}
|
||||
|
||||
Pattern isoTime() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> ANY_TIME
|
||||
RegexProperty isoTime() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> RegexProperty(ANY_TIME).asString()
|
||||
}
|
||||
|
||||
Pattern iso8601WithOffset() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> ISO8601_WITH_OFFSET
|
||||
RegexProperty iso8601WithOffset() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> RegexProperty(ISO8601_WITH_OFFSET).asString()
|
||||
}
|
||||
|
||||
Pattern nonEmpty() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> NON_EMPTY
|
||||
RegexProperty nonEmpty() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> RegexProperty(NON_EMPTY).asString()
|
||||
}
|
||||
|
||||
Pattern nonBlank() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> NON_BLANK
|
||||
RegexProperty nonBlank() {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">return</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">new</span> RegexProperty(NON_BLANK).asString()
|
||||
}</pre><p>In your contract, you can use it as shown in the following example:</p><pre class="programlisting">Contract dslWithOptionalsInString = Contract.make {
|
||||
priority <span class="hl-number">1</span>
|
||||
request {
|
||||
@@ -1109,7 +1109,7 @@ This section is present in the <code class="literal">response</code> or <code cl
|
||||
contract.</li></ul></div><p>Currently, Spring Cloud Contract Verifier supports only JSON Path-based matchers with the
|
||||
following matching possibilities:</p><div class="itemizedlist"><p class="title"><b>Groovy DSL</b></p><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p class="simpara">For the stubs(in tests on the Consumer’s side):</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><code class="literal">byEquality()</code>: The value taken from the consumer’s request via the provided JSON Path must be
|
||||
equal to the value provided in the contract.</li><li class="listitem"><code class="literal">byRegex(…​)</code>: The value taken from the consumer’s request via the provided JSON Path must
|
||||
match the regex.</li><li class="listitem"><code class="literal">byDate()</code>: The value taken from the consumer’s request via the provided JSON Path must
|
||||
match the regex. You can also pass the type of the expected matched value (e.g. <code class="literal">asString()</code>, <code class="literal">asLong()</code> etc.)</li><li class="listitem"><code class="literal">byDate()</code>: The value taken from the consumer’s request via the provided JSON Path must
|
||||
match the regex for an ISO Date value.</li><li class="listitem"><code class="literal">byTimestamp()</code>: The value taken from the consumer’s request via the provided JSON Path must
|
||||
match the regex for an ISO DateTime value.</li><li class="listitem"><code class="literal">byTime()</code>: The value taken from the consumer’s request via the provided JSON Path must
|
||||
match the regex for an ISO Time value.</li></ul></div></li><li class="listitem"><p class="simpara">For the verification(in generated tests on the Producer’s side):</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><code class="literal">byEquality()</code>: The value taken from the producer’s response via the provided JSON Path must be
|
||||
@@ -1119,7 +1119,7 @@ the regex for an ISO Date value.</li><li class="listitem"><code class="literal">
|
||||
match the regex for an ISO DateTime value.</li><li class="listitem"><code class="literal">byTime()</code>: The value taken from the producer’s response via the provided JSON Path must match
|
||||
the regex for an ISO Time value.</li><li class="listitem"><code class="literal">byType()</code>: The value taken from the producer’s response via the provided JSON Path needs to be
|
||||
of the same type as the type defined in the body of the response in the contract.
|
||||
<code class="literal">byType</code> can take a closure, in which you can set <code class="literal">minOccurrence</code> and <code class="literal">maxOccurrence</code>.
|
||||
<code class="literal">byType</code> can take a closure, in which you can set <code class="literal">minOccurrence</code> and <code class="literal">maxOccurrence</code>. For the request side, you should use the closure to assert size of the collection.
|
||||
That way, you can assert the size of the flattened collection. To check the size of an
|
||||
unflattened collection, use a custom method with the <code class="literal">byCommand(…​)</code> testMatcher.</li><li class="listitem"><p class="simpara"><code class="literal">byCommand(…​)</code>: The value taken from the producer’s response via the provided JSON Path is
|
||||
passed as an input to the custom method that you provide. For example,
|
||||
@@ -1128,11 +1128,12 @@ JSON Path gets passed. The type of the object read from the JSON can be one of t
|
||||
following, depending on the JSON path:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: square; "><li class="listitem"><code class="literal">String</code>: If you point to a <code class="literal">String</code> value.</li><li class="listitem"><code class="literal">JSONArray</code>: If you point to a <code class="literal">List</code>.</li><li class="listitem"><code class="literal">Map</code>: If you point to a <code class="literal">Map</code>.</li><li class="listitem"><code class="literal">Number</code>: If you point to <code class="literal">Integer</code>, <code class="literal">Double</code>, or other kind of number.</li><li class="listitem"><code class="literal">Boolean</code>: If you point to a <code class="literal">Boolean</code>.</li></ul></div></li><li class="listitem"><code class="literal">byNull()</code>: The value taken from the response via the provided JSON Path must be null</li></ul></div></li></ul></div><p><b>YAML. </b><span class="emphasis"><em>Please read the Groovy section for detailed explanation of
|
||||
what the types mean</em></span></p><p>For YAML the structure of a matcher looks like this</p><pre class="programlisting">- path: $.foo
|
||||
type: by_regex
|
||||
value: bar</pre><p>Or if you want to use one of the predefined regular expressions
|
||||
value: bar
|
||||
regexType: as_string</pre><p>Or if you want to use one of the predefined regular expressions
|
||||
<code class="literal">[only_alpha_unicode, number, any_boolean, ip_address, hostname,
|
||||
email, url, uuid, iso_date, iso_date_time, iso_time, iso_8601_with_offset, non_empty, non_blank]</code>:</p><pre class="programlisting">- path: $.foo
|
||||
type: by_regex
|
||||
predefined: only_alpha_unicode</pre><p>Below you can find the allowed list of `type`s.</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p class="simpara">For <code class="literal">stubMatchers</code>:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><code class="literal">by_equality</code></li><li class="listitem"><code class="literal">by_regex</code></li><li class="listitem"><code class="literal">by_date</code></li><li class="listitem"><code class="literal">by_timestamp</code></li><li class="listitem"><code class="literal">by_time</code></li></ul></div></li><li class="listitem"><p class="simpara">For <code class="literal">testMatchers</code>:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><code class="literal">by_equality</code></li><li class="listitem"><code class="literal">by_regex</code></li><li class="listitem"><code class="literal">by_date</code></li><li class="listitem"><code class="literal">by_timestamp</code></li><li class="listitem"><code class="literal">by_time</code></li><li class="listitem"><p class="simpara"><code class="literal">by_type</code></p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: square; "><li class="listitem">there are 2 additional fields accepted: <code class="literal">minOccurrence</code> and <code class="literal">maxOccurrence</code>.</li></ul></div></li><li class="listitem"><code class="literal">by_command</code></li><li class="listitem"><code class="literal">by_null</code></li></ul></div></li></ul></div><p>Consider the following example:</p><p><b>Groovy DSL. </b>
|
||||
predefined: only_alpha_unicode</pre><p>Below you can find the allowed list of `type`s.</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p class="simpara">For <code class="literal">stubMatchers</code>:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><code class="literal">by_equality</code></li><li class="listitem"><code class="literal">by_regex</code></li><li class="listitem"><code class="literal">by_date</code></li><li class="listitem"><code class="literal">by_timestamp</code></li><li class="listitem"><code class="literal">by_time</code></li><li class="listitem"><p class="simpara"><code class="literal">by_type</code></p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: square; "><li class="listitem">there are 2 additional fields accepted: <code class="literal">minOccurrence</code> and <code class="literal">maxOccurrence</code>.</li></ul></div></li></ul></div></li><li class="listitem"><p class="simpara">For <code class="literal">testMatchers</code>:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><code class="literal">by_equality</code></li><li class="listitem"><code class="literal">by_regex</code></li><li class="listitem"><code class="literal">by_date</code></li><li class="listitem"><code class="literal">by_timestamp</code></li><li class="listitem"><code class="literal">by_time</code></li><li class="listitem"><p class="simpara"><code class="literal">by_type</code></p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: square; "><li class="listitem">there are 2 additional fields accepted: <code class="literal">minOccurrence</code> and <code class="literal">maxOccurrence</code>.</li></ul></div></li><li class="listitem"><code class="literal">by_command</code></li><li class="listitem"><code class="literal">by_null</code></li></ul></div></li></ul></div><p>You can also define which type the regular expression corresponds to via the <code class="literal">regexType</code> field. Below you can find the allowed list of regular expression types:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">as_integer</li><li class="listitem">as_double</li><li class="listitem">as_float,</li><li class="listitem">as_long</li><li class="listitem">as_short</li><li class="listitem">as_boolean</li><li class="listitem">as_string</li></ul></div><p>Consider the following example:</p><p><b>Groovy DSL. </b>
|
||||
</p><pre class="programlisting">Contract contractDsl = Contract.make {
|
||||
request {
|
||||
method <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'GET'</span>
|
||||
@@ -1152,12 +1153,12 @@ email, url, uuid, iso_date, iso_date_time, iso_time, iso_8601_with_offset, non_e
|
||||
]
|
||||
])
|
||||
bodyMatchers {
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.duck'</span>, byRegex(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"[0-9]{3}"</span>))
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.duck'</span>, byRegex(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"[0-9]{3}"</span>).asInteger())
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.duck'</span>, byEquality())
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.alpha'</span>, byRegex(onlyAlphaUnicode()))
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.alpha'</span>, byRegex(onlyAlphaUnicode()).asString())
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.alpha'</span>, byEquality())
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.number'</span>, byRegex(number()))
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.aBoolean'</span>, byRegex(anyBoolean()))
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.number'</span>, byRegex(number()).asInteger())
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.aBoolean'</span>, byRegex(anyBoolean()).asBooleanType())
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.date'</span>, byDate())
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.dateTime'</span>, byTimestamp())
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.time'</span>, byTime())
|
||||
@@ -1201,18 +1202,18 @@ email, url, uuid, iso_date, iso_date_time, iso_time, iso_8601_with_offset, non_e
|
||||
])
|
||||
bodyMatchers {
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// asserts the jsonpath value against manual regex</span>
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.duck'</span>, byRegex(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"[0-9]{3}"</span>))
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.duck'</span>, byRegex(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"[0-9]{3}"</span>).asInteger())
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// asserts the jsonpath value against the provided value</span>
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.duck'</span>, byEquality())
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// asserts the jsonpath value against some default regex</span>
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.alpha'</span>, byRegex(onlyAlphaUnicode()))
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.alpha'</span>, byRegex(onlyAlphaUnicode()).asString())
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.alpha'</span>, byEquality())
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.number'</span>, byRegex(number()))
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.positiveInteger'</span>, byRegex(anInteger()))
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.negativeInteger'</span>, byRegex(anInteger()))
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.positiveDecimalNumber'</span>, byRegex(aDouble()))
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.negativeDecimalNumber'</span>, byRegex(aDouble()))
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.aBoolean'</span>, byRegex(anyBoolean()))
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.number'</span>, byRegex(number()).asInteger())
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.positiveInteger'</span>, byRegex(anInteger()).asInteger())
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.negativeInteger'</span>, byRegex(anInteger()).asInteger())
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.positiveDecimalNumber'</span>, byRegex(aDouble()).asDouble())
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.negativeDecimalNumber'</span>, byRegex(aDouble()).asDouble())
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.aBoolean'</span>, byRegex(anyBoolean()).asBooleanType())
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-comment">// asserts vs inbuilt time related regex</span>
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.date'</span>, byDate())
|
||||
jsonPath(<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'$.dateTime'</span>, byTimestamp())
|
||||
@@ -1282,6 +1283,20 @@ email, url, uuid, iso_date, iso_date_time, iso_time, iso_8601_with_offset, non_e
|
||||
key:
|
||||
"complex.key": 'foo'
|
||||
nullValue: null
|
||||
valueWithMin:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
valueWithMax:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
valueWithMinMax:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
valueWithMinEmpty: []
|
||||
valueWithMaxEmpty: []
|
||||
matchers:
|
||||
url:
|
||||
regex: /get/[0-9]
|
||||
@@ -1344,6 +1359,16 @@ email, url, uuid, iso_date, iso_date_time, iso_time, iso_8601_with_offset, non_e
|
||||
type: by_equality
|
||||
- path: $.nullvalue
|
||||
type: by_null
|
||||
- path: $.valueWithMin
|
||||
type: by_type
|
||||
minOccurrence: 1
|
||||
- path: $.valueWithMax
|
||||
type: by_type
|
||||
maxOccurrence: 3
|
||||
- path: $.valueWithMinMax
|
||||
type: by_type
|
||||
minOccurrence: 1
|
||||
maxOccurrence: 3
|
||||
response:
|
||||
status: 200
|
||||
cookies:
|
||||
@@ -1491,51 +1516,60 @@ statically imported to your tests. Notice that the <code class="literal">byComma
|
||||
the method name and passed the proper JSON path as a parameter to it.</p></td></tr></table></div><p>The resulting WireMock stub is in the following example:</p><pre class="programlisting"> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">''</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'
|
||||
</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"request"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"urlPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"/get"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">,</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"method"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"POST"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">,</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"headers"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Content-Type"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matches"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"application/json.*"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">}</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"bodyPatterns"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">[</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$[?(@.['valueWithoutAMatcher'] == 'foo')]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$[?(@.['valueWithTypeMatch'] == 'string')]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$.['list'].['some'].['nested'][?(@.['anothervalue'] == 4)]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$.['list'].['someother'].['nested'][?(@.['anothervalue'] == 4)]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$.['list'].['someother'].['nested'][?(@.['json'] == 'with value')]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$[?(@.duck =~ /([0-9]{3})/)]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$[?(@.duck == 123)]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$[?(@.alpha =~ /([\\\\p{L}]*)/)]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$[?(@.alpha == 'abc')]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$[?(@.number =~ /(-?(\\\\d*\\\\.\\\\d+|\\\\d+))/)]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$[?(@.aBoolean =~ /((true|false))/)]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$[?(@.date =~ /((\\\\d\\\\d\\\\d\\\\d)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01]))/)]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$[?(@.dateTime =~ /(([0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9]))/)]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$[?(@.time =~ /((2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9]))/)]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$.list.some.nested[?(@.json =~ /(.*)/)]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">}</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">]</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"urlPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"/get"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">,</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"method"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"POST"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">,</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"headers"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Content-Type"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matches"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"application/json.*"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">}</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"bodyPatterns"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">[</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$.['list'].['some'].['nested'][?(@.['anothervalue'] == 4)]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$[?(@.['valueWithoutAMatcher'] == 'foo')]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$[?(@.['valueWithTypeMatch'] == 'string')]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$.['list'].['someother'].['nested'][?(@.['json'] == 'with value')]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$.['list'].['someother'].['nested'][?(@.['anothervalue'] == 4)]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$[?(@.duck =~ /([0-9]{3})/)]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$[?(@.duck == 123)]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$[?(@.alpha =~ /([\\\\p{L}]*)/)]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$[?(@.alpha == 'abc')]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$[?(@.number =~ /(-?(\\\\d*\\\\.\\\\d+|\\\\d+))/)]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$[?(@.aBoolean =~ /((true|false))/)]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$[?(@.date =~ /((\\\\d\\\\d\\\\d\\\\d)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01]))/)]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$[?(@.dateTime =~ /(([0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9]))/)]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$[?(@.time =~ /((2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9]))/)]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$.list.some.nested[?(@.json =~ /(.*)/)]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$[?(@.valueWithMin.size() >= 1)]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$[?(@.valueWithMax.size() <= 3)]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$[?(@.valueWithMinMax.size() >= 1 && @.valueWithMinMax.size() <= 3)]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"matchesJsonPath"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"$[?(@.valueWithOccurrence.size() >= 4 && @.valueWithOccurrence.size() <= 4)]"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">}</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">]</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"response"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"status"</span> : <span class="hl-number">200</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">,</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"body"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"{\\"</span>date\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">":\\"</span><span class="hl-number">2017</span>-<span class="hl-number">01</span>-<span class="hl-number">01</span>\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">",\\"</span>dateTime\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">":\\"</span><span class="hl-number">2017</span>-<span class="hl-number">01</span>-<span class="hl-number">01</span>T01:<span class="hl-number">23</span>:<span class="hl-number">45</span>\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">",\\"</span>number\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">":123,\\"</span>aBoolean\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">":true,\\"</span>duck\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">":123,\\"</span>alpha\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">":\\"</span>abc\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">",\\"</span>valueWithMin\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">":[1,2,3],\\"</span>time\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">":\\"</span><span class="hl-number">01</span>:<span class="hl-number">02</span>:<span class="hl-number">34</span>\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">",\\"</span>valueWithTypeMatch\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">":\\"</span>string\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">",\\"</span>valueWithMax\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">":[1,2,3],\\"</span>valueWithMinMax\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">":[1,2,3],\\"</span>valueWithoutAMatcher\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">":\\"</span>foo\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"}"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">,</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"headers"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Content-Type"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"application/json"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">}</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"status"</span> : <span class="hl-number">200</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">,</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"body"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"{\\"</span>date\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">":\\"</span><span class="hl-number">2017</span>-<span class="hl-number">01</span>-<span class="hl-number">01</span>\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">",\\"</span>dateTime\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">":\\"</span><span class="hl-number">2017</span>-<span class="hl-number">01</span>-<span class="hl-number">01</span>T01:<span class="hl-number">23</span>:<span class="hl-number">45</span>\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">",\\"</span>aBoolean\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">":true,\\"</span>valueWithMax\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">":[1,2,3],\\"</span>valueWithOccurrence\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">":[1,2,3,4],\\"</span>number\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">":123,\\"</span>duck\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">":123,\\"</span>alpha\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">":\\"</span>abc\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">",\\"</span>valueWithMin\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">":[1,2,3],\\"</span>time\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">":\\"</span><span class="hl-number">01</span>:<span class="hl-number">02</span>:<span class="hl-number">34</span>\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">",\\"</span>valueWithTypeMatch\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">":\\"</span>string\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">",\\"</span>valueWithMinMax\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">":[1,2,3],\\"</span>valueWithoutAMatcher\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">":\\"</span>foo\\<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"}"</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">,</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"headers"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">{</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"Content-Type"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"application/json"</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">},</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"transformers"</span> : <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">[</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">"response-template"</span> <span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">]</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">}</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-keyword">}</span>
|
||||
<span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">''</span><span xmlns:d="http://docbook.org/ns/docbook" class="hl-string">'</span></pre><div class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><table border="0" summary="Important"><tr><td rowspan="2" align="center" valign="top" width="25"><img alt="[Important]" src="images/important.png"></td><th align="left">Important</th></tr><tr><td align="left" valign="top"><p>If you use a <code class="literal">matcher</code>, then the part of the request and response that the
|
||||
@@ -1876,11 +1910,16 @@ request:
|
||||
url: /users/1
|
||||
response:
|
||||
status: 200
|
||||
|
||||
---
|
||||
request:
|
||||
method: POST
|
||||
url: /users/2
|
||||
response:
|
||||
status: 200
|
||||
---
|
||||
request:
|
||||
method: POST
|
||||
url: /users/3
|
||||
response:
|
||||
status: 200</pre><p>
|
||||
</p><p>In the preceding example, one contract has the <code class="literal">name</code> field and the other does not. This
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -4,7 +4,7 @@
|
||||
<book xmlns="http://docbook.org/ns/docbook" xmlns:xl="http://www.w3.org/1999/xlink" version="5.0" xml:lang="en">
|
||||
<info>
|
||||
<title>Spring Cloud Contract</title>
|
||||
<date>2018-12-12</date>
|
||||
<date>2018-11-18</date>
|
||||
</info>
|
||||
<preface>
|
||||
<title></title>
|
||||
@@ -1082,6 +1082,7 @@ First, add the <literal>Spring Cloud Contract</literal> BOM.</simpara>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<packageWithBaseClasses>com.example.fraud</packageWithBaseClasses>
|
||||
<convertToYaml>true</convertToYaml>
|
||||
</configuration>
|
||||
</plugin></programlisting>
|
||||
<simpara>Since the plugin was added, you get the <literal>Spring Cloud Contract Verifier</literal> features which,
|
||||
@@ -1190,6 +1191,7 @@ $ git pull https://your-git-server.com/server-side-fork.git contract-change-pr</
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<packageWithBaseClasses>com.example.fraud</packageWithBaseClasses>
|
||||
<convertToYaml>true</convertToYaml>
|
||||
</configuration>
|
||||
</plugin></programlisting>
|
||||
<important>
|
||||
@@ -2066,6 +2068,129 @@ to find contracts. E.g. for <literal>com.example:foo:1.0.0</literal> the path wo
|
||||
<simpara>Finally, a push will be done to that repo’s <literal>origin</literal></simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
<section xml:id="_producer_with_contracts_stored_locally">
|
||||
<title>Producer with contracts stored locally</title>
|
||||
<simpara>Another option to use the SCM as the destination for stubs and contracts is to store the contracts locally, with the producer, and only push the contracts and the stubs to SCM. Below, you can find the setup required to achieve this using Maven and Gradle.</simpara>
|
||||
<formalpara>
|
||||
<title>Maven</title>
|
||||
<para>
|
||||
<programlisting language="xml" linenumbering="unnumbered"><plugin>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-contract-maven-plugin</artifactId>
|
||||
<version>${spring-cloud-contract.version}</version>
|
||||
<extensions>true</extensions>
|
||||
<!-- In the default configuration, we want to use the contracts stored locally -->
|
||||
<configuration>
|
||||
<baseClassMappings>
|
||||
<baseClassMapping>
|
||||
<contractPackageRegex>.*messaging.*</contractPackageRegex>
|
||||
<baseClassFQN>com.example.BeerMessagingBase</baseClassFQN>
|
||||
</baseClassMapping>
|
||||
<baseClassMapping>
|
||||
<contractPackageRegex>.*rest.*</contractPackageRegex>
|
||||
<baseClassFQN>com.example.BeerRestBase</baseClassFQN>
|
||||
</baseClassMapping>
|
||||
</baseClassMappings>
|
||||
<basePackageForTests>com.example</basePackageForTests>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<!-- By default we will not push the stubs back to SCM,
|
||||
you have to explicitly add it as a goal -->
|
||||
<goal>pushStubsToScm</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<!-- We want to pick contracts from a Git repository -->
|
||||
<contractsRepositoryUrl>git://file://${env.ROOT}/target/contract_empty_git/</contractsRepositoryUrl>
|
||||
<!-- Example of URL via git protocol -->
|
||||
<!--<contractsRepositoryUrl>git://git@github.com:spring-cloud-samples/spring-cloud-contract-samples.git</contractsRepositoryUrl>-->
|
||||
<!-- Example of URL via http protocol -->
|
||||
<!--<contractsRepositoryUrl>git://https://github.com/spring-cloud-samples/spring-cloud-contract-samples.git</contractsRepositoryUrl>-->
|
||||
<!-- We reuse the contract dependency section to set up the path
|
||||
to the folder that contains the contract definitions. In our case the
|
||||
path will be /groupId/artifactId/version/contracts -->
|
||||
<contractDependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>${project.artifactId}</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</contractDependency>
|
||||
<!-- The mode can't be classpath -->
|
||||
<contractsMode>LOCAL</contractsMode>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin></programlisting>
|
||||
</para>
|
||||
</formalpara>
|
||||
<formalpara>
|
||||
<title>Gradle</title>
|
||||
<para>
|
||||
<programlisting language="xml" linenumbering="unnumbered">contracts {
|
||||
// Base package for generated tests
|
||||
basePackageForTests = "com.example"
|
||||
baseClassMappings {
|
||||
baseClassMapping(".*messaging.*", "com.example.BeerMessagingBase")
|
||||
baseClassMapping(".*rest.*", "com.example.BeerRestBase")
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
In this scenario we want to publish stubs to SCM whenever
|
||||
the `publish` task is executed
|
||||
*/
|
||||
publishStubsToScm {
|
||||
// We want to modify the default set up of the plugin when publish stubs to scm is called
|
||||
customize {
|
||||
// We want to pick contracts from a Git repository
|
||||
contractDependency {
|
||||
stringNotation = "${project.group}:${project.name}:${project.version}"
|
||||
}
|
||||
/*
|
||||
We reuse the contract dependency section to set up the path
|
||||
to the folder that contains the contract definitions. In our case the
|
||||
path will be /groupId/artifactId/version/contracts
|
||||
*/
|
||||
contractRepository {
|
||||
repositoryUrl = "git://file://${System.getenv("ROOT")}/target/contract_empty_git/"
|
||||
}
|
||||
// The mode can't be classpath
|
||||
contractsMode = "LOCAL"
|
||||
}
|
||||
}
|
||||
|
||||
publish.dependsOn("publishStubsToScm")
|
||||
publishToMavenLocal.dependsOn("publishStubsToScm")</programlisting>
|
||||
</para>
|
||||
</formalpara>
|
||||
<simpara>With such a setup:</simpara>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara>Contracts from the default <literal>src/test/resources/contracts</literal> directory will be picked</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>Tests will be generated from the contracts</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>Stubs will be created from the contracts</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>Once the tests pass</simpara>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara>Git project will be cloned to a temporary directory</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>The stubs and contracts will be committed in the cloned repository</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>Finally, a push will be done to that repo’s <literal>origin</literal></simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<section xml:id="_keeping_contracts_with_the_producer_and_stubs_in_an_external_repository">
|
||||
<title>Keeping contracts with the producer and stubs in an external repository</title>
|
||||
<simpara>It is also possible to keep the contracts in the producer repository, but keep the stubs in an external git repo.
|
||||
@@ -2644,6 +2769,15 @@ JAR is available offline, remotely etc.)</simpara>
|
||||
contracts from temporary directories</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<simpara>Below you can find a list of experimental features you can turn on via the plugin:</simpara>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara><emphasis role="strong">convertToYaml</emphasis>: converts all DSLs to the declarative, YAML format. This can be extremely useful when you’re using external libraries in your Groovy DSLs. By turning this feature on (by setting it to <literal>true</literal>) you will not need to add the library dependency on the consumer side.</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><emphasis role="strong">assertJsonSize</emphasis>: You can check the size of JSON arrays in the generated tests. This feature is disabled by default.</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
<section xml:id="gradle-single-base-class">
|
||||
<title>Single Base Class for All Tests</title>
|
||||
@@ -2827,6 +2961,7 @@ following sections:</simpara>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<packageWithBaseClasses>com.example.fraud</packageWithBaseClasses>
|
||||
<convertToYaml>true</convertToYaml>
|
||||
</configuration>
|
||||
</plugin></programlisting>
|
||||
<simpara>You can read more in the
|
||||
@@ -3089,6 +3224,15 @@ use the current Maven ones.</simpara>
|
||||
</itemizedlist>
|
||||
<simpara>We cache only non-snapshot, explicitly provided versions (for example
|
||||
<literal>+</literal> or <literal>1.0.0.BUILD-SNAPSHOT</literal> won’t get cached). By default, this feature is turned on.</simpara>
|
||||
<simpara>Below you can find a list of experimental features you can turn on via the plugin:</simpara>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara><emphasis role="strong">convertToYaml</emphasis>: converts all DSLs to the declarative, YAML format. This can be extremely useful when you’re using external libraries in your Groovy DSLs. By turning this feature on (by setting it to <literal>true</literal>) you will not need to add the library dependency on the consumer side.</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><emphasis role="strong">assertJsonSize</emphasis>: You can check the size of JSON arrays in the generated tests. This feature is disabled by default.</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
<section xml:id="maven-single-base">
|
||||
<title>Single Base Class for All Tests</title>
|
||||
@@ -6894,80 +7038,80 @@ protected static Pattern anyOf(String... values){
|
||||
return Pattern.compile(values.collect({"^$it\$"}).join("|"))
|
||||
}
|
||||
|
||||
Pattern onlyAlphaUnicode() {
|
||||
return ONLY_ALPHA_UNICODE
|
||||
RegexProperty onlyAlphaUnicode() {
|
||||
return new RegexProperty(ONLY_ALPHA_UNICODE).asString()
|
||||
}
|
||||
|
||||
Pattern alphaNumeric() {
|
||||
return ALPHA_NUMERIC
|
||||
RegexProperty alphaNumeric() {
|
||||
return new RegexProperty(ALPHA_NUMERIC).asString()
|
||||
}
|
||||
|
||||
Pattern number() {
|
||||
return NUMBER
|
||||
RegexProperty number() {
|
||||
return new RegexProperty(NUMBER).asDouble()
|
||||
}
|
||||
|
||||
Pattern positiveInt() {
|
||||
return POSITIVE_INT
|
||||
RegexProperty positiveInt() {
|
||||
return new RegexProperty(POSITIVE_INT).asInteger()
|
||||
}
|
||||
|
||||
Pattern anyBoolean() {
|
||||
return TRUE_OR_FALSE
|
||||
RegexProperty anyBoolean() {
|
||||
return new RegexProperty(TRUE_OR_FALSE).asBooleanType()
|
||||
}
|
||||
|
||||
Pattern anInteger() {
|
||||
return INTEGER
|
||||
RegexProperty anInteger() {
|
||||
return new RegexProperty(INTEGER).asInteger()
|
||||
}
|
||||
|
||||
Pattern aDouble() {
|
||||
return DOUBLE
|
||||
RegexProperty aDouble() {
|
||||
return new RegexProperty(DOUBLE).asDouble()
|
||||
}
|
||||
|
||||
Pattern ipAddress() {
|
||||
return IP_ADDRESS
|
||||
RegexProperty ipAddress() {
|
||||
return new RegexProperty(IP_ADDRESS).asString()
|
||||
}
|
||||
|
||||
Pattern hostname() {
|
||||
return HOSTNAME_PATTERN
|
||||
RegexProperty hostname() {
|
||||
return new RegexProperty(HOSTNAME_PATTERN).asString()
|
||||
}
|
||||
|
||||
Pattern email() {
|
||||
return EMAIL
|
||||
RegexProperty email() {
|
||||
return new RegexProperty(EMAIL).asString()
|
||||
}
|
||||
|
||||
Pattern url() {
|
||||
return URL
|
||||
RegexProperty url() {
|
||||
return new RegexProperty(URL).asString()
|
||||
}
|
||||
|
||||
Pattern httpsUrl() {
|
||||
return HTTPS_URL
|
||||
RegexProperty httpsUrl() {
|
||||
return new RegexProperty(HTTPS_URL).asString()
|
||||
}
|
||||
|
||||
Pattern uuid(){
|
||||
return UUID
|
||||
RegexProperty uuid(){
|
||||
return new RegexProperty(UUID).asString()
|
||||
}
|
||||
|
||||
Pattern isoDate() {
|
||||
return ANY_DATE
|
||||
RegexProperty isoDate() {
|
||||
return new RegexProperty(ANY_DATE).asString()
|
||||
}
|
||||
|
||||
Pattern isoDateTime() {
|
||||
return ANY_DATE_TIME
|
||||
RegexProperty isoDateTime() {
|
||||
return new RegexProperty(ANY_DATE_TIME).asString()
|
||||
}
|
||||
|
||||
Pattern isoTime() {
|
||||
return ANY_TIME
|
||||
RegexProperty isoTime() {
|
||||
return new RegexProperty(ANY_TIME).asString()
|
||||
}
|
||||
|
||||
Pattern iso8601WithOffset() {
|
||||
return ISO8601_WITH_OFFSET
|
||||
RegexProperty iso8601WithOffset() {
|
||||
return new RegexProperty(ISO8601_WITH_OFFSET).asString()
|
||||
}
|
||||
|
||||
Pattern nonEmpty() {
|
||||
return NON_EMPTY
|
||||
RegexProperty nonEmpty() {
|
||||
return new RegexProperty(NON_EMPTY).asString()
|
||||
}
|
||||
|
||||
Pattern nonBlank() {
|
||||
return NON_BLANK
|
||||
RegexProperty nonBlank() {
|
||||
return new RegexProperty(NON_BLANK).asString()
|
||||
}</programlisting>
|
||||
<simpara>In your contract, you can use it as shown in the following example:</simpara>
|
||||
<programlisting language="groovy" linenumbering="unnumbered">Contract dslWithOptionalsInString = Contract.make {
|
||||
@@ -7539,7 +7683,7 @@ equal to the value provided in the contract.</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>byRegex(…​)</literal>: The value taken from the consumer’s request via the provided JSON Path must
|
||||
match the regex.</simpara>
|
||||
match the regex. You can also pass the type of the expected matched value (e.g. <literal>asString()</literal>, <literal>asLong()</literal> etc.)</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>byDate()</literal>: The value taken from the consumer’s request via the provided JSON Path must
|
||||
@@ -7581,7 +7725,7 @@ the regex for an ISO Time value.</simpara>
|
||||
<listitem>
|
||||
<simpara><literal>byType()</literal>: The value taken from the producer’s response via the provided JSON Path needs to be
|
||||
of the same type as the type defined in the body of the response in the contract.
|
||||
<literal>byType</literal> can take a closure, in which you can set <literal>minOccurrence</literal> and <literal>maxOccurrence</literal>.
|
||||
<literal>byType</literal> can take a closure, in which you can set <literal>minOccurrence</literal> and <literal>maxOccurrence</literal>. For the request side, you should use the closure to assert size of the collection.
|
||||
That way, you can assert the size of the flattened collection. To check the size of an
|
||||
unflattened collection, use a custom method with the <literal>byCommand(…​)</literal> testMatcher.</simpara>
|
||||
</listitem>
|
||||
@@ -7623,7 +7767,8 @@ what the types mean</emphasis></para>
|
||||
<simpara>For YAML the structure of a matcher looks like this</simpara>
|
||||
<programlisting language="yml" linenumbering="unnumbered">- path: $.foo
|
||||
type: by_regex
|
||||
value: bar</programlisting>
|
||||
value: bar
|
||||
regexType: as_string</programlisting>
|
||||
<simpara>Or if you want to use one of the predefined regular expressions
|
||||
<literal>[only_alpha_unicode, number, any_boolean, ip_address, hostname,
|
||||
email, url, uuid, iso_date, iso_date_time, iso_time, iso_8601_with_offset, non_empty, non_blank]</literal>:</simpara>
|
||||
@@ -7650,6 +7795,14 @@ email, url, uuid, iso_date, iso_date_time, iso_time, iso_8601_with_offset, non_e
|
||||
<listitem>
|
||||
<simpara><literal>by_time</literal></simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara><literal>by_type</literal></simpara>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara>there are 2 additional fields accepted: <literal>minOccurrence</literal> and <literal>maxOccurrence</literal>.</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
<listitem>
|
||||
@@ -7687,6 +7840,30 @@ email, url, uuid, iso_date, iso_date_time, iso_time, iso_8601_with_offset, non_e
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<simpara>You can also define which type the regular expression corresponds to via the <literal>regexType</literal> field. Below you can find the allowed list of regular expression types:</simpara>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<simpara>as_integer</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>as_double</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>as_float,</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>as_long</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>as_short</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>as_boolean</simpara>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<simpara>as_string</simpara>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<simpara>Consider the following example:</simpara>
|
||||
<formalpara>
|
||||
<title>Groovy DSL</title>
|
||||
@@ -7710,12 +7887,12 @@ email, url, uuid, iso_date, iso_date_time, iso_time, iso_8601_with_offset, non_e
|
||||
]
|
||||
])
|
||||
bodyMatchers {
|
||||
jsonPath('$.duck', byRegex("[0-9]{3}"))
|
||||
jsonPath('$.duck', byRegex("[0-9]{3}").asInteger())
|
||||
jsonPath('$.duck', byEquality())
|
||||
jsonPath('$.alpha', byRegex(onlyAlphaUnicode()))
|
||||
jsonPath('$.alpha', byRegex(onlyAlphaUnicode()).asString())
|
||||
jsonPath('$.alpha', byEquality())
|
||||
jsonPath('$.number', byRegex(number()))
|
||||
jsonPath('$.aBoolean', byRegex(anyBoolean()))
|
||||
jsonPath('$.number', byRegex(number()).asInteger())
|
||||
jsonPath('$.aBoolean', byRegex(anyBoolean()).asBooleanType())
|
||||
jsonPath('$.date', byDate())
|
||||
jsonPath('$.dateTime', byTimestamp())
|
||||
jsonPath('$.time', byTime())
|
||||
@@ -7759,18 +7936,18 @@ email, url, uuid, iso_date, iso_date_time, iso_time, iso_8601_with_offset, non_e
|
||||
])
|
||||
bodyMatchers {
|
||||
// asserts the jsonpath value against manual regex
|
||||
jsonPath('$.duck', byRegex("[0-9]{3}"))
|
||||
jsonPath('$.duck', byRegex("[0-9]{3}").asInteger())
|
||||
// asserts the jsonpath value against the provided value
|
||||
jsonPath('$.duck', byEquality())
|
||||
// asserts the jsonpath value against some default regex
|
||||
jsonPath('$.alpha', byRegex(onlyAlphaUnicode()))
|
||||
jsonPath('$.alpha', byRegex(onlyAlphaUnicode()).asString())
|
||||
jsonPath('$.alpha', byEquality())
|
||||
jsonPath('$.number', byRegex(number()))
|
||||
jsonPath('$.positiveInteger', byRegex(anInteger()))
|
||||
jsonPath('$.negativeInteger', byRegex(anInteger()))
|
||||
jsonPath('$.positiveDecimalNumber', byRegex(aDouble()))
|
||||
jsonPath('$.negativeDecimalNumber', byRegex(aDouble()))
|
||||
jsonPath('$.aBoolean', byRegex(anyBoolean()))
|
||||
jsonPath('$.number', byRegex(number()).asInteger())
|
||||
jsonPath('$.positiveInteger', byRegex(anInteger()).asInteger())
|
||||
jsonPath('$.negativeInteger', byRegex(anInteger()).asInteger())
|
||||
jsonPath('$.positiveDecimalNumber', byRegex(aDouble()).asDouble())
|
||||
jsonPath('$.negativeDecimalNumber', byRegex(aDouble()).asDouble())
|
||||
jsonPath('$.aBoolean', byRegex(anyBoolean()).asBooleanType())
|
||||
// asserts vs inbuilt time related regex
|
||||
jsonPath('$.date', byDate())
|
||||
jsonPath('$.dateTime', byTimestamp())
|
||||
@@ -7844,6 +8021,20 @@ email, url, uuid, iso_date, iso_date_time, iso_time, iso_8601_with_offset, non_e
|
||||
key:
|
||||
"complex.key": 'foo'
|
||||
nullValue: null
|
||||
valueWithMin:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
valueWithMax:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
valueWithMinMax:
|
||||
- 1
|
||||
- 2
|
||||
- 3
|
||||
valueWithMinEmpty: []
|
||||
valueWithMaxEmpty: []
|
||||
matchers:
|
||||
url:
|
||||
regex: /get/[0-9]
|
||||
@@ -7906,6 +8097,16 @@ email, url, uuid, iso_date, iso_date_time, iso_time, iso_8601_with_offset, non_e
|
||||
type: by_equality
|
||||
- path: $.nullvalue
|
||||
type: by_null
|
||||
- path: $.valueWithMin
|
||||
type: by_type
|
||||
minOccurrence: 1
|
||||
- path: $.valueWithMax
|
||||
type: by_type
|
||||
maxOccurrence: 3
|
||||
- path: $.valueWithMinMax
|
||||
type: by_type
|
||||
minOccurrence: 1
|
||||
maxOccurrence: 3
|
||||
response:
|
||||
status: 200
|
||||
cookies:
|
||||
@@ -8077,51 +8278,60 @@ the method name and passed the proper JSON path as a parameter to it.</simpara>
|
||||
<programlisting language="json" linenumbering="unnumbered"> '''
|
||||
{
|
||||
"request" : {
|
||||
"urlPath" : "/get",
|
||||
"method" : "POST",
|
||||
"headers" : {
|
||||
"Content-Type" : {
|
||||
"matches" : "application/json.*"
|
||||
}
|
||||
},
|
||||
"bodyPatterns" : [ {
|
||||
"matchesJsonPath" : "$[?(@.['valueWithoutAMatcher'] == 'foo')]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.['valueWithTypeMatch'] == 'string')]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$.['list'].['some'].['nested'][?(@.['anothervalue'] == 4)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$.['list'].['someother'].['nested'][?(@.['anothervalue'] == 4)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$.['list'].['someother'].['nested'][?(@.['json'] == 'with value')]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.duck =~ /([0-9]{3})/)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.duck == 123)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.alpha =~ /([\\\\p{L}]*)/)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.alpha == 'abc')]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.number =~ /(-?(\\\\d*\\\\.\\\\d+|\\\\d+))/)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.aBoolean =~ /((true|false))/)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.date =~ /((\\\\d\\\\d\\\\d\\\\d)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01]))/)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.dateTime =~ /(([0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9]))/)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.time =~ /((2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9]))/)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$.list.some.nested[?(@.json =~ /(.*)/)]"
|
||||
} ]
|
||||
"urlPath" : "/get",
|
||||
"method" : "POST",
|
||||
"headers" : {
|
||||
"Content-Type" : {
|
||||
"matches" : "application/json.*"
|
||||
}
|
||||
},
|
||||
"bodyPatterns" : [ {
|
||||
"matchesJsonPath" : "$.['list'].['some'].['nested'][?(@.['anothervalue'] == 4)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.['valueWithoutAMatcher'] == 'foo')]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.['valueWithTypeMatch'] == 'string')]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$.['list'].['someother'].['nested'][?(@.['json'] == 'with value')]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$.['list'].['someother'].['nested'][?(@.['anothervalue'] == 4)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.duck =~ /([0-9]{3})/)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.duck == 123)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.alpha =~ /([\\\\p{L}]*)/)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.alpha == 'abc')]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.number =~ /(-?(\\\\d*\\\\.\\\\d+|\\\\d+))/)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.aBoolean =~ /((true|false))/)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.date =~ /((\\\\d\\\\d\\\\d\\\\d)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01]))/)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.dateTime =~ /(([0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9]))/)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.time =~ /((2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9]))/)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$.list.some.nested[?(@.json =~ /(.*)/)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.valueWithMin.size() >= 1)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.valueWithMax.size() <= 3)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.valueWithMinMax.size() >= 1 && @.valueWithMinMax.size() <= 3)]"
|
||||
}, {
|
||||
"matchesJsonPath" : "$[?(@.valueWithOccurrence.size() >= 4 && @.valueWithOccurrence.size() <= 4)]"
|
||||
} ]
|
||||
},
|
||||
"response" : {
|
||||
"status" : 200,
|
||||
"body" : "{\\"date\\":\\"2017-01-01\\",\\"dateTime\\":\\"2017-01-01T01:23:45\\",\\"number\\":123,\\"aBoolean\\":true,\\"duck\\":123,\\"alpha\\":\\"abc\\",\\"valueWithMin\\":[1,2,3],\\"time\\":\\"01:02:34\\",\\"valueWithTypeMatch\\":\\"string\\",\\"valueWithMax\\":[1,2,3],\\"valueWithMinMax\\":[1,2,3],\\"valueWithoutAMatcher\\":\\"foo\\"}",
|
||||
"headers" : {
|
||||
"Content-Type" : "application/json"
|
||||
}
|
||||
"status" : 200,
|
||||
"body" : "{\\"date\\":\\"2017-01-01\\",\\"dateTime\\":\\"2017-01-01T01:23:45\\",\\"aBoolean\\":true,\\"valueWithMax\\":[1,2,3],\\"valueWithOccurrence\\":[1,2,3,4],\\"number\\":123,\\"duck\\":123,\\"alpha\\":\\"abc\\",\\"valueWithMin\\":[1,2,3],\\"time\\":\\"01:02:34\\",\\"valueWithTypeMatch\\":\\"string\\",\\"valueWithMinMax\\":[1,2,3],\\"valueWithoutAMatcher\\":\\"foo\\"}",
|
||||
"headers" : {
|
||||
"Content-Type" : "application/json"
|
||||
},
|
||||
"transformers" : [ "response-template" ]
|
||||
}
|
||||
}
|
||||
'''</programlisting>
|
||||
@@ -8610,11 +8820,16 @@ request:
|
||||
url: /users/1
|
||||
response:
|
||||
status: 200
|
||||
|
||||
---
|
||||
request:
|
||||
method: POST
|
||||
url: /users/2
|
||||
response:
|
||||
status: 200
|
||||
---
|
||||
request:
|
||||
method: POST
|
||||
url: /users/3
|
||||
response:
|
||||
status: 200</programlisting>
|
||||
</para>
|
||||
@@ -8974,7 +9189,7 @@ visible in your Groovy files. The following examples show how to test the depend
|
||||
<formalpara role="secondary">
|
||||
<title>Gradle</title>
|
||||
<para>
|
||||
<programlisting language="groovy" linenumbering="unnumbered">testCompile("com.example:beer-common:0.0.1-SNAPSHOT")</programlisting>
|
||||
<programlisting language="groovy" linenumbering="unnumbered">testCompile("com.example:beer-common:0.0.1.BUILD-SNAPSHOT")</programlisting>
|
||||
</para>
|
||||
</formalpara>
|
||||
</section>
|
||||
@@ -9013,7 +9228,7 @@ following example:</simpara>
|
||||
<formalpara role="secondary">
|
||||
<title>Gradle</title>
|
||||
<para>
|
||||
<programlisting language="groovy" linenumbering="unnumbered">classpath "com.example:beer-common:0.0.1-SNAPSHOT"</programlisting>
|
||||
<programlisting language="groovy" linenumbering="unnumbered">classpath "com.example:beer-common:0.0.1.BUILD-SNAPSHOT"</programlisting>
|
||||
</para>
|
||||
</formalpara>
|
||||
</section>
|
||||
@@ -9062,6 +9277,9 @@ then:
|
||||
}
|
||||
}
|
||||
}</programlisting>
|
||||
<important>
|
||||
<simpara>You can set the Spring Cloud Contract plugin up by setting <literal>convertToYaml</literal> to <literal>true</literal>. That way you will NOT have to add the dependency with the extended functionality to the consumer side, since the consumer side will be using YAML contracts instead of Groovy ones.</simpara>
|
||||
</important>
|
||||
</section>
|
||||
</section>
|
||||
</chapter>
|
||||
|
||||
Reference in New Issue
Block a user