Fixed equals and hashcode
This commit is contained in:
@@ -40,15 +40,43 @@ class Contract {
|
|||||||
* take precedence
|
* take precedence
|
||||||
*/
|
*/
|
||||||
Integer priority
|
Integer priority
|
||||||
|
/**
|
||||||
|
* The HTTP request part of the contract
|
||||||
|
*/
|
||||||
Request request
|
Request request
|
||||||
|
/**
|
||||||
|
* The HTTP response part of the contract
|
||||||
|
*/
|
||||||
Response response
|
Response response
|
||||||
|
/**
|
||||||
|
* The label by which you'll reference the contract on the message consumer side
|
||||||
|
*/
|
||||||
String label
|
String label
|
||||||
|
/**
|
||||||
|
* Description of a contract. May be used in the documentation generation.
|
||||||
|
*/
|
||||||
String description
|
String description
|
||||||
|
/**
|
||||||
|
* Name of the generated test / stub. If not provided then the file name will be used.
|
||||||
|
* If you have multiple contracts in a single file and you don't provide this value
|
||||||
|
* then a prefix will be added to the file with the index number while iterating
|
||||||
|
* over the collection of contracts.
|
||||||
|
*
|
||||||
|
* Remember to have a unique name for every single contract. Otherwise you might
|
||||||
|
* generate tests that have two identical methods or you will override the stubs.
|
||||||
|
*/
|
||||||
|
String name
|
||||||
|
/**
|
||||||
|
* The input side of a messaging contract.
|
||||||
|
*/
|
||||||
Input input
|
Input input
|
||||||
|
/**
|
||||||
|
* The output side of a messaging contract.
|
||||||
|
*/
|
||||||
OutputMessage outputMessage
|
OutputMessage outputMessage
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the contract should be ignored or not
|
* Whether the contract should be ignored or not.
|
||||||
*/
|
*/
|
||||||
boolean ignored
|
boolean ignored
|
||||||
|
|
||||||
@@ -68,6 +96,10 @@ class Contract {
|
|||||||
this.priority = priority
|
this.priority = priority
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void name(String name) {
|
||||||
|
this.name = name
|
||||||
|
}
|
||||||
|
|
||||||
void label(String label) {
|
void label(String label) {
|
||||||
this.label = label
|
this.label = label
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ import groovy.transform.ToString
|
|||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@ToString(includePackage = false, includeFields = true, includeNames = true)
|
@ToString(includePackage = false, includeFields = true, includeNames = true, includeSuper = true)
|
||||||
@EqualsAndHashCode(includeFields = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@CompileStatic
|
@CompileStatic
|
||||||
class Body extends DslProperty {
|
class Body extends DslProperty {
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
package org.springframework.cloud.contract.spec.internal
|
package org.springframework.cloud.contract.spec.internal
|
||||||
|
|
||||||
import groovy.transform.CompileStatic
|
import groovy.transform.CompileStatic
|
||||||
|
import groovy.transform.EqualsAndHashCode
|
||||||
|
import groovy.transform.ToString
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a client side {@link DslProperty}
|
* Represents a client side {@link DslProperty}
|
||||||
@@ -24,6 +26,8 @@ import groovy.transform.CompileStatic
|
|||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@CompileStatic
|
@CompileStatic
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString(includeSuper = true)
|
||||||
class ClientDslProperty extends DslProperty {
|
class ClientDslProperty extends DslProperty {
|
||||||
|
|
||||||
ClientDslProperty(Object singleValue) {
|
ClientDslProperty(Object singleValue) {
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import groovy.transform.PackageScope
|
|||||||
import groovy.transform.TypeChecked
|
import groovy.transform.TypeChecked
|
||||||
|
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains useful common methods for the DSL.
|
* Contains useful common methods for the DSL.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -19,14 +19,13 @@ package org.springframework.cloud.contract.spec.internal
|
|||||||
import groovy.transform.CompileStatic
|
import groovy.transform.CompileStatic
|
||||||
import groovy.transform.EqualsAndHashCode
|
import groovy.transform.EqualsAndHashCode
|
||||||
import groovy.transform.ToString
|
import groovy.transform.ToString
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an element of a DSL that can contain client or sever side values
|
* Represents an element of a DSL that can contain client or sever side values
|
||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@CompileStatic
|
@CompileStatic
|
||||||
@EqualsAndHashCode(includeFields = true)
|
@EqualsAndHashCode
|
||||||
@ToString(includePackage = false, includeNames = true)
|
@ToString(includePackage = false, includeNames = true)
|
||||||
class DslProperty<T> {
|
class DslProperty<T> {
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package org.springframework.cloud.contract.spec.internal
|
package org.springframework.cloud.contract.spec.internal
|
||||||
|
|
||||||
import groovy.transform.CompileStatic
|
import groovy.transform.CompileStatic
|
||||||
|
import groovy.transform.EqualsAndHashCode
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a property that will become an executable method in the
|
* Represents a property that will become an executable method in the
|
||||||
@@ -25,6 +26,7 @@ import groovy.transform.CompileStatic
|
|||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@CompileStatic
|
@CompileStatic
|
||||||
|
@EqualsAndHashCode
|
||||||
class ExecutionProperty {
|
class ExecutionProperty {
|
||||||
|
|
||||||
private static final String PLACEHOLDER_VALUE = '\\$it'
|
private static final String PLACEHOLDER_VALUE = '\\$it'
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ import groovy.transform.ToString
|
|||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@EqualsAndHashCode(includeFields = true)
|
@EqualsAndHashCode(includeFields = true, callSuper = true)
|
||||||
@ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true)
|
@ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true, includeSuper = true)
|
||||||
@CompileStatic
|
@CompileStatic
|
||||||
class Header extends DslProperty {
|
class Header extends DslProperty {
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import groovy.transform.ToString
|
|||||||
* @since 1.0.2
|
* @since 1.0.2
|
||||||
*/
|
*/
|
||||||
@CompileStatic
|
@CompileStatic
|
||||||
@EqualsAndHashCode
|
@EqualsAndHashCode(includeFields = true)
|
||||||
@ToString(includePackage = false)
|
@ToString(includePackage = false)
|
||||||
class HttpMethods {
|
class HttpMethods {
|
||||||
|
|
||||||
|
|||||||
@@ -88,6 +88,8 @@ class Input extends Common {
|
|||||||
return new DslProperty(client.clientValue, clientValue)
|
return new DslProperty(client.clientValue, clientValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EqualsAndHashCode(includeFields = true, callSuper = true)
|
||||||
|
@ToString(includeSuper = true)
|
||||||
static class BodyType extends DslProperty {
|
static class BodyType extends DslProperty {
|
||||||
|
|
||||||
BodyType(Object clientValue, Object serverValue) {
|
BodyType(Object clientValue, Object serverValue) {
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ import groovy.transform.ToString;
|
|||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@EqualsAndHashCode(includeFields = true)
|
@EqualsAndHashCode(includeFields = true, callSuper = true)
|
||||||
@ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true)
|
@ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true, includeSuper = true)
|
||||||
@CompileStatic
|
@CompileStatic
|
||||||
class MatchingStrategy extends DslProperty {
|
class MatchingStrategy extends DslProperty {
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ import groovy.transform.CompileStatic
|
|||||||
import groovy.transform.EqualsAndHashCode
|
import groovy.transform.EqualsAndHashCode
|
||||||
import groovy.transform.ToString
|
import groovy.transform.ToString
|
||||||
|
|
||||||
@ToString(includePackage = false, includeFields = true, includeNames = true)
|
@ToString(includePackage = false, includeFields = true, includeNames = true, includeSuper = true)
|
||||||
@EqualsAndHashCode(includeFields = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@CompileStatic
|
@CompileStatic
|
||||||
class Multipart extends DslProperty {
|
class Multipart extends DslProperty {
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import groovy.transform.CompileStatic
|
|||||||
import groovy.transform.PackageScope
|
import groovy.transform.PackageScope
|
||||||
|
|
||||||
import java.util.regex.Pattern
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Marcin Grzejszczak
|
* @author Marcin Grzejszczak
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ import static org.springframework.cloud.contract.spec.util.ValidateUtils.validat
|
|||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@EqualsAndHashCode(includeFields = true)
|
@EqualsAndHashCode(includeFields = true, callSuper = true)
|
||||||
@ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true)
|
@ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true, includeSuper = true)
|
||||||
@CompileStatic
|
@CompileStatic
|
||||||
class QueryParameter extends DslProperty {
|
class QueryParameter extends DslProperty {
|
||||||
|
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ class Request extends Common {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@CompileStatic
|
@CompileStatic
|
||||||
@EqualsAndHashCode
|
@EqualsAndHashCode(includeFields = true)
|
||||||
@ToString(includePackage = false)
|
@ToString(includePackage = false)
|
||||||
private class ServerRequest extends Request {
|
private class ServerRequest extends Request {
|
||||||
ServerRequest(Request request) {
|
ServerRequest(Request request) {
|
||||||
@@ -222,7 +222,7 @@ class Request extends Common {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@CompileStatic
|
@CompileStatic
|
||||||
@EqualsAndHashCode
|
@EqualsAndHashCode(includeFields = true)
|
||||||
@ToString(includePackage = false)
|
@ToString(includePackage = false)
|
||||||
private class ClientRequest extends Request {
|
private class ClientRequest extends Request {
|
||||||
ClientRequest(Request request) {
|
ClientRequest(Request request) {
|
||||||
@@ -231,7 +231,7 @@ class Request extends Common {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@CompileStatic
|
@CompileStatic
|
||||||
@EqualsAndHashCode
|
@EqualsAndHashCode(includeFields = true)
|
||||||
@ToString(includePackage = false)
|
@ToString(includePackage = false)
|
||||||
private class RequestHeaders extends Headers {
|
private class RequestHeaders extends Headers {
|
||||||
|
|
||||||
@@ -243,7 +243,7 @@ class Request extends Common {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@CompileStatic
|
@CompileStatic
|
||||||
@EqualsAndHashCode
|
@EqualsAndHashCode(includeFields = true)
|
||||||
@ToString(includePackage = false)
|
@ToString(includePackage = false)
|
||||||
private class ClientPatternValueDslProperty extends PatternValueDslProperty<ClientDslProperty> {
|
private class ClientPatternValueDslProperty extends PatternValueDslProperty<ClientDslProperty> {
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import java.util.regex.Pattern
|
|||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@TypeChecked
|
@TypeChecked
|
||||||
@EqualsAndHashCode
|
@EqualsAndHashCode(includeFields = true)
|
||||||
@ToString(includePackage = false, includeFields = true)
|
@ToString(includePackage = false, includeFields = true)
|
||||||
class Response extends Common {
|
class Response extends Common {
|
||||||
|
|
||||||
@@ -120,7 +120,7 @@ class Response extends Common {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@CompileStatic
|
@CompileStatic
|
||||||
@EqualsAndHashCode
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@ToString(includePackage = false)
|
@ToString(includePackage = false)
|
||||||
private class ServerResponse extends Response {
|
private class ServerResponse extends Response {
|
||||||
ServerResponse(Response request) {
|
ServerResponse(Response request) {
|
||||||
@@ -129,7 +129,7 @@ class Response extends Common {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@CompileStatic
|
@CompileStatic
|
||||||
@EqualsAndHashCode
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@ToString(includePackage = false)
|
@ToString(includePackage = false)
|
||||||
private class ClientResponse extends Response {
|
private class ClientResponse extends Response {
|
||||||
ClientResponse(Response request) {
|
ClientResponse(Response request) {
|
||||||
@@ -138,7 +138,7 @@ class Response extends Common {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@CompileStatic
|
@CompileStatic
|
||||||
@EqualsAndHashCode
|
@EqualsAndHashCode(includeFields = true)
|
||||||
@ToString(includePackage = false)
|
@ToString(includePackage = false)
|
||||||
private class ResponseHeaders extends Headers {
|
private class ResponseHeaders extends Headers {
|
||||||
|
|
||||||
@@ -150,7 +150,7 @@ class Response extends Common {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@CompileStatic
|
@CompileStatic
|
||||||
@EqualsAndHashCode
|
@EqualsAndHashCode(includeFields = true)
|
||||||
@ToString(includePackage = false)
|
@ToString(includePackage = false)
|
||||||
private class ServerPatternValueDslProperty extends PatternValueDslProperty<ServerDslProperty> {
|
private class ServerPatternValueDslProperty extends PatternValueDslProperty<ServerDslProperty> {
|
||||||
|
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ import groovy.transform.ToString
|
|||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@CompileStatic
|
@CompileStatic
|
||||||
@EqualsAndHashCode(includeFields = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@ToString(includePackage = false)
|
@ToString(includePackage = false, includeSuper = true)
|
||||||
class ServerDslProperty extends DslProperty {
|
class ServerDslProperty extends DslProperty {
|
||||||
|
|
||||||
ServerDslProperty(Object singleValue) {
|
ServerDslProperty(Object singleValue) {
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ import static org.springframework.cloud.contract.spec.util.ValidateUtils.validat
|
|||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@ToString(includePackage = false, includeFields = true, includeNames = true)
|
@ToString(includePackage = false, includeFields = true, includeNames = true, includeSuper = true)
|
||||||
@EqualsAndHashCode(includeFields = true)
|
@EqualsAndHashCode(includeFields = true, callSuper = true)
|
||||||
@CompileStatic
|
@CompileStatic
|
||||||
class Url extends DslProperty {
|
class Url extends DslProperty {
|
||||||
|
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ import groovy.transform.ToString
|
|||||||
*
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@ToString(includePackage = false, includeFields = true, includeNames = true)
|
@ToString(includePackage = false, includeFields = true, includeNames = true, includeSuper = true)
|
||||||
@EqualsAndHashCode(includeFields = true)
|
@EqualsAndHashCode(includeFields = true, callSuper = true)
|
||||||
@CompileStatic
|
@CompileStatic
|
||||||
class UrlPath extends Url {
|
class UrlPath extends Url {
|
||||||
|
|
||||||
|
|||||||
@@ -102,4 +102,154 @@ then:
|
|||||||
}
|
}
|
||||||
// end::ignored[]
|
// end::ignored[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def 'should make equals and hashcode work properly for URL'() {
|
||||||
|
expect:
|
||||||
|
def a = Contract.make {
|
||||||
|
request {
|
||||||
|
url("/1")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
def b = Contract.make {
|
||||||
|
request {
|
||||||
|
url("/1")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a == b
|
||||||
|
}
|
||||||
|
|
||||||
|
def 'should make equals and hashcode work properly for URL with consumer producer'() {
|
||||||
|
expect:
|
||||||
|
Contract.make {
|
||||||
|
request {
|
||||||
|
url($(c("/1"), p("/1")))
|
||||||
|
}
|
||||||
|
} == Contract.make {
|
||||||
|
request {
|
||||||
|
url($(c("/1"), p("/1")))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def 'should return true when comparing two equal contracts with gstring'() {
|
||||||
|
expect:
|
||||||
|
int index = 1
|
||||||
|
def a = Contract.make {
|
||||||
|
request {
|
||||||
|
method(PUT())
|
||||||
|
headers {
|
||||||
|
contentType(applicationJson())
|
||||||
|
}
|
||||||
|
url "/${index}"
|
||||||
|
}
|
||||||
|
response {
|
||||||
|
status 200
|
||||||
|
}
|
||||||
|
}
|
||||||
|
def b = Contract.make {
|
||||||
|
request {
|
||||||
|
method(PUT())
|
||||||
|
headers {
|
||||||
|
contentType(applicationJson())
|
||||||
|
}
|
||||||
|
url "/${index}"
|
||||||
|
}
|
||||||
|
response {
|
||||||
|
status 200
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a == b
|
||||||
|
}
|
||||||
|
|
||||||
|
def 'should return false when comparing two unequal contracts with gstring'() {
|
||||||
|
expect:
|
||||||
|
int index = 1
|
||||||
|
def a = Contract.make {
|
||||||
|
request {
|
||||||
|
method(PUT())
|
||||||
|
headers {
|
||||||
|
contentType(applicationJson())
|
||||||
|
}
|
||||||
|
url "/${index}"
|
||||||
|
}
|
||||||
|
response {
|
||||||
|
status 200
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int index2 = 2
|
||||||
|
def b = Contract.make {
|
||||||
|
request {
|
||||||
|
method(PUT())
|
||||||
|
headers {
|
||||||
|
contentType(applicationJson())
|
||||||
|
}
|
||||||
|
url "/${index2}"
|
||||||
|
}
|
||||||
|
response {
|
||||||
|
status 200
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a != b
|
||||||
|
}
|
||||||
|
|
||||||
|
def 'should return true when comparing two equal complex contracts'() {
|
||||||
|
expect:
|
||||||
|
def a = Contract.make {
|
||||||
|
request {
|
||||||
|
method 'GET'
|
||||||
|
url '/path'
|
||||||
|
headers {
|
||||||
|
header('Accept': $(
|
||||||
|
consumer(regex('text/.*')),
|
||||||
|
producer('text/plain')
|
||||||
|
))
|
||||||
|
header('X-Custom-Header': $(
|
||||||
|
consumer(regex('^.*2134.*$')),
|
||||||
|
producer('121345')
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
response {
|
||||||
|
status 200
|
||||||
|
body(
|
||||||
|
id: [value: '132'],
|
||||||
|
surname: 'Kowalsky',
|
||||||
|
name: 'Jan',
|
||||||
|
created: '2014-02-02 12:23:43'
|
||||||
|
)
|
||||||
|
headers {
|
||||||
|
header 'Content-Type': 'text/plain'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
def b = Contract.make {
|
||||||
|
request {
|
||||||
|
method 'GET'
|
||||||
|
url '/path'
|
||||||
|
headers {
|
||||||
|
header('Accept': $(
|
||||||
|
consumer(regex('text/.*')),
|
||||||
|
producer('text/plain')
|
||||||
|
))
|
||||||
|
header('X-Custom-Header': $(
|
||||||
|
consumer(regex('^.*2134.*$')),
|
||||||
|
producer('121345')
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
response {
|
||||||
|
status 200
|
||||||
|
body(
|
||||||
|
id: [value: '132'],
|
||||||
|
surname: 'Kowalsky',
|
||||||
|
name: 'Jan',
|
||||||
|
created: '2014-02-02 12:23:43'
|
||||||
|
)
|
||||||
|
headers {
|
||||||
|
header 'Content-Type': 'text/plain'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a == b
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ class StubRepository {
|
|||||||
File file = path.toFile();
|
File file = path.toFile();
|
||||||
if (isContractDescriptor(file)) {
|
if (isContractDescriptor(file)) {
|
||||||
mappingDescriptors
|
mappingDescriptors
|
||||||
.add(ContractVerifierDslConverter.convert(file));
|
.addAll(ContractVerifierDslConverter.convertAsCollection(file));
|
||||||
}
|
}
|
||||||
return super.visitFile(path, attrs);
|
return super.visitFile(path, attrs);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package org.springframework.cloud.contract.verifier.converter
|
package org.springframework.cloud.contract.verifier.converter
|
||||||
|
|
||||||
import groovy.transform.CompileStatic
|
import groovy.transform.CompileStatic
|
||||||
|
import org.springframework.cloud.contract.spec.Contract
|
||||||
import org.springframework.cloud.contract.verifier.file.ContractMetadata
|
import org.springframework.cloud.contract.verifier.file.ContractMetadata
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,7 +47,9 @@ interface SingleFileConverter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the name of the converted stub file. If you have multiple contracts
|
* Returns the name of the converted stub file. If you have multiple contracts
|
||||||
* in a single file then a prefix will be added to the generated file.
|
* in a single file then a prefix will be added to the generated file. If you
|
||||||
|
* provide the {@link Contract#name} field then that field will override the
|
||||||
|
* generated file name.
|
||||||
*
|
*
|
||||||
* Example: name of file with 2 contracts is {@code foo.groovy}, it will be
|
* Example: name of file with 2 contracts is {@code foo.groovy}, it will be
|
||||||
* converted by the implementation to {@code foo.json}. The recursive file
|
* converted by the implementation to {@code foo.json}. The recursive file
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import groovy.transform.CompileStatic
|
|||||||
import org.springframework.cloud.contract.spec.Contract
|
import org.springframework.cloud.contract.spec.Contract
|
||||||
import org.springframework.cloud.contract.verifier.dsl.wiremock.WireMockStubStrategy
|
import org.springframework.cloud.contract.verifier.dsl.wiremock.WireMockStubStrategy
|
||||||
import org.springframework.cloud.contract.verifier.file.ContractMetadata
|
import org.springframework.cloud.contract.verifier.file.ContractMetadata
|
||||||
|
import org.springframework.cloud.contract.verifier.util.NamesUtil
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
|
|
||||||
@@ -49,7 +50,7 @@ class DslToWireMockClientConverter extends DslToWireMockConverter {
|
|||||||
}
|
}
|
||||||
List<String> convertedContracts = []
|
List<String> convertedContracts = []
|
||||||
contract.convertedContract.eachWithIndex { Contract dsl, int index ->
|
contract.convertedContract.eachWithIndex { Contract dsl, int index ->
|
||||||
String name = "${rootName}_${index}"
|
String name = dsl.name ? NamesUtil.convertIllegalPackageChars(dsl.name) : "${rootName}_${index}"
|
||||||
convertedContracts << convertASingleContract(name, contract, dsl)
|
convertedContracts << convertASingleContract(name, contract, dsl)
|
||||||
}
|
}
|
||||||
return convertedContracts
|
return convertedContracts
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ abstract class DslToWireMockConverter implements SingleFileConverter {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
protected List<Contract> createGroovyDSLFromStringContent(String groovyDslAsString) {
|
protected Collection<Contract> createGroovyDSLFromStringContent(String groovyDslAsString) {
|
||||||
return ContractVerifierDslConverter.convertAsCollection(groovyDslAsString)
|
return ContractVerifierDslConverter.convertAsCollection(groovyDslAsString)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import org.springframework.cloud.contract.verifier.converter.SingleFileConverter
|
|||||||
import org.springframework.cloud.contract.verifier.converter.SingleFileConvertersHolder
|
import org.springframework.cloud.contract.verifier.converter.SingleFileConvertersHolder
|
||||||
import org.springframework.cloud.contract.verifier.file.ContractFileScanner
|
import org.springframework.cloud.contract.verifier.file.ContractFileScanner
|
||||||
import org.springframework.cloud.contract.verifier.file.ContractMetadata
|
import org.springframework.cloud.contract.verifier.file.ContractMetadata
|
||||||
|
import org.springframework.cloud.contract.verifier.util.NamesUtil
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
@@ -94,7 +95,7 @@ class RecursiveFilesConverter {
|
|||||||
}
|
}
|
||||||
Path absoluteTargetPath = createAndReturnTargetDirectory(sourceFile)
|
Path absoluteTargetPath = createAndReturnTargetDirectory(sourceFile)
|
||||||
File newJsonFile = createTargetFileWithProperName(singleFileConverter, absoluteTargetPath,
|
File newJsonFile = createTargetFileWithProperName(singleFileConverter, absoluteTargetPath,
|
||||||
sourceFile, contractsSize, index)
|
sourceFile, contractsSize, index, dsl)
|
||||||
newJsonFile.setText(convertedContent, StandardCharsets.UTF_8.toString())
|
newJsonFile.setText(convertedContent, StandardCharsets.UTF_8.toString())
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -112,11 +113,22 @@ class RecursiveFilesConverter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private File createTargetFileWithProperName(SingleFileConverter singleFileConverter, Path absoluteTargetPath,
|
private File createTargetFileWithProperName(SingleFileConverter singleFileConverter, Path absoluteTargetPath,
|
||||||
File sourceFile, int contractsSize, int index) {
|
File sourceFile, int contractsSize, int index, Contract dsl) {
|
||||||
String generatedName = singleFileConverter.generateOutputFileNameForInput(sourceFile.name)
|
String name = generateName(dsl, contractsSize, singleFileConverter, sourceFile, index)
|
||||||
String name = contractsSize == 1 ? generatedName : "${index}_${generatedName}"
|
|
||||||
File newJsonFile = new File(absoluteTargetPath.toFile(), name)
|
File newJsonFile = new File(absoluteTargetPath.toFile(), name)
|
||||||
log.info("Creating new json [$newJsonFile.path]")
|
log.info("Creating new stub [$newJsonFile.path]")
|
||||||
return newJsonFile
|
return newJsonFile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String generateName(Contract dsl, int contractsSize, SingleFileConverter converter,
|
||||||
|
File sourceFile, int index) {
|
||||||
|
String generatedName = converter.generateOutputFileNameForInput(sourceFile.name)
|
||||||
|
String extension = NamesUtil.afterLastDot(generatedName)
|
||||||
|
if (dsl.name) {
|
||||||
|
return "${dsl.name}.${extension}"
|
||||||
|
} else if (contractsSize == 1) {
|
||||||
|
return generatedName
|
||||||
|
}
|
||||||
|
return "${index}_${generatedName}"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ class RecursiveFilesConverterSpec extends Specification {
|
|||||||
private static
|
private static
|
||||||
final Set<Path> EXPECTED_TARGET_FILES = [Paths.get("dslRoot.json"), Paths.get("dir1/dsl1.json"),
|
final Set<Path> EXPECTED_TARGET_FILES = [Paths.get("dslRoot.json"), Paths.get("dir1/dsl1.json"),
|
||||||
Paths.get("dir1/dsl1b.json"), Paths.get("dir2/dsl2.json"),
|
Paths.get("dir1/dsl1b.json"), Paths.get("dir2/dsl2.json"),
|
||||||
Paths.get("dir1/0_dsl1_list.json"), Paths.get("dir1/1_dsl1_list.json")]
|
Paths.get("dir1/0_dsl1_list.json"), Paths.get("dir1/1_dsl1_list.json"),
|
||||||
|
Paths.get("dir1/shouldHaveIndex1.json"), Paths.get("dir1/shouldHaveIndex2.json")]
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public TemporaryFolder tmpFolder = new TemporaryFolder();
|
public TemporaryFolder tmpFolder = new TemporaryFolder();
|
||||||
|
|||||||
@@ -17,10 +17,12 @@
|
|||||||
package org.springframework.cloud.contract.verifier.wiremock
|
package org.springframework.cloud.contract.verifier.wiremock
|
||||||
|
|
||||||
import com.github.tomakehurst.wiremock.stubbing.StubMapping
|
import com.github.tomakehurst.wiremock.stubbing.StubMapping
|
||||||
import org.springframework.cloud.contract.verifier.util.ContractVerifierDslConverter
|
|
||||||
import org.springframework.cloud.contract.spec.Contract
|
import org.springframework.cloud.contract.spec.Contract
|
||||||
|
import org.springframework.cloud.contract.verifier.util.ContractVerifierDslConverter
|
||||||
import spock.lang.Specification
|
import spock.lang.Specification
|
||||||
|
|
||||||
|
import java.util.regex.Pattern
|
||||||
|
|
||||||
class WireMockToDslConverterSpec extends Specification {
|
class WireMockToDslConverterSpec extends Specification {
|
||||||
|
|
||||||
def 'should produce a Groovy DSL from WireMock stub'() {
|
def 'should produce a Groovy DSL from WireMock stub'() {
|
||||||
@@ -69,12 +71,14 @@ class WireMockToDslConverterSpec extends Specification {
|
|||||||
}
|
}
|
||||||
response {
|
response {
|
||||||
status 200
|
status 200
|
||||||
body(
|
body("""{
|
||||||
id: [value: '132'],
|
"id": {
|
||||||
surname: 'Kowalsky',
|
"value": "132"
|
||||||
name: 'Jan',
|
},
|
||||||
created: '2014-02-02 12:23:43'
|
"surname": "Kowalsky",
|
||||||
)
|
"name": "Jan",
|
||||||
|
"created": "2014-02-02 12:23:43"
|
||||||
|
}""")
|
||||||
headers {
|
headers {
|
||||||
header 'Content-Type': 'text/plain'
|
header 'Content-Type': 'text/plain'
|
||||||
|
|
||||||
@@ -84,10 +88,12 @@ class WireMockToDslConverterSpec extends Specification {
|
|||||||
when:
|
when:
|
||||||
String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub)
|
String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub)
|
||||||
then:
|
then:
|
||||||
ContractVerifierDslConverter.convert(
|
def a = ContractVerifierDslConverter.convert(
|
||||||
"""org.springframework.cloud.contract.spec.Contract.make {
|
"""org.springframework.cloud.contract.spec.Contract.make {
|
||||||
$groovyDsl
|
$groovyDsl
|
||||||
}""") == expectedGroovyDsl
|
}""")
|
||||||
|
def b = expectedGroovyDsl
|
||||||
|
a == b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -97,7 +103,7 @@ class WireMockToDslConverterSpec extends Specification {
|
|||||||
{
|
{
|
||||||
"request": {
|
"request": {
|
||||||
"method": "DELETE",
|
"method": "DELETE",
|
||||||
"urlPattern": "/credit-card-verification-data/[0-9]+",
|
"urlPattern": "1",
|
||||||
"headers": {
|
"headers": {
|
||||||
"Content-Type": {
|
"Content-Type": {
|
||||||
"equalTo": "application/vnd.mymoid-adapter.v2+json; charset=UTF-8"
|
"equalTo": "application/vnd.mymoid-adapter.v2+json; charset=UTF-8"
|
||||||
@@ -119,29 +125,30 @@ class WireMockToDslConverterSpec extends Specification {
|
|||||||
Contract expectedGroovyDsl = Contract.make {
|
Contract expectedGroovyDsl = Contract.make {
|
||||||
request {
|
request {
|
||||||
method 'DELETE'
|
method 'DELETE'
|
||||||
url $(consumer(~/\/credit-card-verification-data\/[0-9]+/), producer('/credit-card-verification-data/1'))
|
url $(consumer(~/1/), producer('1'))
|
||||||
headers {
|
headers {
|
||||||
header('Content-Type': 'application/vnd.mymoid-adapter.v2+json; charset=UTF-8')
|
header('Content-Type': 'application/vnd.mymoid-adapter.v2+json; charset=UTF-8')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
response {
|
response {
|
||||||
status 200
|
status 200
|
||||||
body("""{
|
body( """{
|
||||||
"status": "OK"
|
"status": "OK"
|
||||||
}""")
|
}""")
|
||||||
headers {
|
headers {
|
||||||
header 'Content-Type': 'application/json'
|
header 'Content-Type': 'application/json'
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
when:
|
when:
|
||||||
String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub)
|
String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub)
|
||||||
then:
|
then:
|
||||||
ContractVerifierDslConverter.convert(
|
def a = ContractVerifierDslConverter.convert(
|
||||||
"""org.springframework.cloud.contract.spec.Contract.make {
|
"""org.springframework.cloud.contract.spec.Contract.make {
|
||||||
$groovyDsl
|
$groovyDsl
|
||||||
}""") == expectedGroovyDsl
|
}""")
|
||||||
|
def b = expectedGroovyDsl
|
||||||
|
(a.request.url.clientValue as Pattern).pattern() == (b.request.url.clientValue as Pattern).pattern()
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'should convert WireMock stub with response body containing integer'() {
|
def 'should convert WireMock stub with response body containing integer'() {
|
||||||
@@ -230,11 +237,14 @@ class WireMockToDslConverterSpec extends Specification {
|
|||||||
}
|
}
|
||||||
response {
|
response {
|
||||||
status 200
|
status 200
|
||||||
body([
|
body( """[
|
||||||
[a: 1, c: '3'],
|
{
|
||||||
'b',
|
"a": 1,
|
||||||
'a'
|
"c": "3"
|
||||||
])
|
},
|
||||||
|
"b",
|
||||||
|
"a"
|
||||||
|
]""")
|
||||||
headers {
|
headers {
|
||||||
header 'Content-Type': 'application/json'
|
header 'Content-Type': 'application/json'
|
||||||
}
|
}
|
||||||
@@ -282,26 +292,26 @@ class WireMockToDslConverterSpec extends Specification {
|
|||||||
response {
|
response {
|
||||||
status 200
|
status 200
|
||||||
body("""[
|
body("""[
|
||||||
{
|
{
|
||||||
"amount": 1.01,
|
"amount": 1.01,
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"info": {
|
"info": {
|
||||||
"title": "title1",
|
"title": "title1",
|
||||||
"payload": null
|
"payload": null
|
||||||
},
|
},
|
||||||
"booleanvalue": true,
|
"booleanvalue": true,
|
||||||
"user": null
|
"user": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"amount": 2.01,
|
"amount": 2.01,
|
||||||
"name": "Name2",
|
"name": "Name2",
|
||||||
"info": {
|
"info": {
|
||||||
"title": "title2",
|
"title": "title2",
|
||||||
"payload": null
|
"payload": null
|
||||||
},
|
},
|
||||||
"booleanvalue": true,
|
"booleanvalue": true,
|
||||||
"user": null
|
"user": null
|
||||||
}
|
}
|
||||||
]""")
|
]""")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -337,7 +347,7 @@ class WireMockToDslConverterSpec extends Specification {
|
|||||||
request {
|
request {
|
||||||
method 'POST'
|
method 'POST'
|
||||||
url '/test'
|
url '/test'
|
||||||
body ('''{"property1":"abc","property2":"2017-01","property3":"666","property4":1428566412}''')
|
body ('''{"property1":"abc", "property2":"2017-01", "property3":"666", "property4":1428566412}''')
|
||||||
}
|
}
|
||||||
response {
|
response {
|
||||||
status 200
|
status 200
|
||||||
@@ -359,15 +369,15 @@ class WireMockToDslConverterSpec extends Specification {
|
|||||||
String wireMockStub = '''\
|
String wireMockStub = '''\
|
||||||
{
|
{
|
||||||
"request": {
|
"request": {
|
||||||
"method": "POST",
|
"method": "POST",
|
||||||
"url": "/test",
|
"url": "/test",
|
||||||
"bodyPatterns": [{
|
"bodyPatterns": [{
|
||||||
"matches": "[0-9]{5}"
|
"matches": "1"
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
"response": {
|
"response": {
|
||||||
"status": 200
|
"status": 200
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'''
|
'''
|
||||||
and:
|
and:
|
||||||
@@ -377,7 +387,7 @@ class WireMockToDslConverterSpec extends Specification {
|
|||||||
request {
|
request {
|
||||||
method 'POST'
|
method 'POST'
|
||||||
url '/test'
|
url '/test'
|
||||||
body $(consumer(~/[0-9]{5}/), producer('12345'))
|
body $(consumer(~/1/), producer('1'))
|
||||||
}
|
}
|
||||||
response {
|
response {
|
||||||
status 200
|
status 200
|
||||||
@@ -391,7 +401,7 @@ class WireMockToDslConverterSpec extends Specification {
|
|||||||
$groovyDsl
|
$groovyDsl
|
||||||
}""")
|
}""")
|
||||||
and:
|
and:
|
||||||
evaluatedGroovyDsl == expectedGroovyDsl
|
(evaluatedGroovyDsl.request.body.clientValue as Pattern).pattern() == (expectedGroovyDsl.request.body.clientValue as Pattern).pattern()
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'should convert WireMock stub with request body with equalToJson'() {
|
def 'should convert WireMock stub with request body with equalToJson'() {
|
||||||
@@ -418,7 +428,7 @@ class WireMockToDslConverterSpec extends Specification {
|
|||||||
request {
|
request {
|
||||||
method 'POST'
|
method 'POST'
|
||||||
url '/test'
|
url '/test'
|
||||||
body '''{"pan":"4855141150107894","expirationDate":"2017-01","dcvx":"178"}'''
|
body '''{"pan":"4855141150107894", "expirationDate":"2017-01", "dcvx":"178"}'''
|
||||||
}
|
}
|
||||||
response {
|
response {
|
||||||
status 200
|
status 200
|
||||||
@@ -458,7 +468,7 @@ class WireMockToDslConverterSpec extends Specification {
|
|||||||
request {
|
request {
|
||||||
method 'POST'
|
method 'POST'
|
||||||
url '/test'
|
url '/test'
|
||||||
body '''{"pan":"4855141150107894","expirationDate":"2017-01","dcvx":"178"}'''
|
body '''{"pan":"4855141150107894", "expirationDate":"2017-01", "dcvx":"178"}'''
|
||||||
}
|
}
|
||||||
response {
|
response {
|
||||||
status 200
|
status 200
|
||||||
@@ -483,7 +493,7 @@ class WireMockToDslConverterSpec extends Specification {
|
|||||||
"url" : "/test",
|
"url" : "/test",
|
||||||
"method" : "POST",
|
"method" : "POST",
|
||||||
"bodyPatterns" : [ {
|
"bodyPatterns" : [ {
|
||||||
"matches" : "[0-9]{2}"
|
"matches" : "1"
|
||||||
} ]
|
} ]
|
||||||
},
|
},
|
||||||
"response" : {
|
"response" : {
|
||||||
@@ -498,7 +508,7 @@ class WireMockToDslConverterSpec extends Specification {
|
|||||||
request {
|
request {
|
||||||
method 'POST'
|
method 'POST'
|
||||||
url '/test'
|
url '/test'
|
||||||
body $(consumer(~/[0-9]{2}/), producer('12'))
|
body $(consumer(~/1/), producer('1'))
|
||||||
}
|
}
|
||||||
response {
|
response {
|
||||||
status 200
|
status 200
|
||||||
@@ -512,7 +522,7 @@ class WireMockToDslConverterSpec extends Specification {
|
|||||||
$groovyDsl
|
$groovyDsl
|
||||||
}""")
|
}""")
|
||||||
and:
|
and:
|
||||||
evaluatedGroovyDsl == expectedGroovyDsl
|
(evaluatedGroovyDsl.request.body.clientValue as Pattern).pattern() == (expectedGroovyDsl.request.body.clientValue as Pattern).pattern()
|
||||||
}
|
}
|
||||||
|
|
||||||
def 'should convert WireMock stub with priorities'() {
|
def 'should convert WireMock stub with priorities'() {
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import org.springframework.cloud.contract.spec.Contract
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2013-2016 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(1..2).collect { int index ->
|
||||||
|
Contract.make {
|
||||||
|
name("shouldHaveIndex${index}")
|
||||||
|
request {
|
||||||
|
method(PUT())
|
||||||
|
headers {
|
||||||
|
contentType(applicationJson())
|
||||||
|
}
|
||||||
|
url "/${index}"
|
||||||
|
}
|
||||||
|
response {
|
||||||
|
status 200
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -113,16 +113,17 @@ class JavaTestGenerator implements SingleTestGenerator {
|
|||||||
log.debug("Stub content from file [${stubsFile.text}]")
|
log.debug("Stub content from file [${stubsFile.text}]")
|
||||||
}
|
}
|
||||||
List<Contract> stubContents = metadata.convertedContract
|
List<Contract> stubContents = metadata.convertedContract
|
||||||
dsls << stubContents.collectEntries { Contract stubContent ->
|
Map<ParsedDsl, TestType> entries = stubContents.collectEntries { Contract stubContent ->
|
||||||
TestType testType = (stubContent.input || stubContent.outputMessage) ? TestType.MESSAGING : TestType.HTTP
|
TestType testType = (stubContent.input || stubContent.outputMessage) ? TestType.MESSAGING : TestType.HTTP
|
||||||
return [(new ParsedDsl(metadata, stubContent, stubsFile)): testType]
|
return [(new ParsedDsl(metadata, stubContent, stubsFile)): testType]
|
||||||
}
|
}
|
||||||
|
dsls.putAll(entries)
|
||||||
}
|
}
|
||||||
return dsls
|
return dsls
|
||||||
}
|
}
|
||||||
|
|
||||||
@Canonical
|
@Canonical
|
||||||
@EqualsAndHashCode
|
@EqualsAndHashCode(includeFields = true)
|
||||||
private static class ParsedDsl {
|
private static class ParsedDsl {
|
||||||
ContractMetadata contract
|
ContractMetadata contract
|
||||||
Contract groovyDsl
|
Contract groovyDsl
|
||||||
|
|||||||
@@ -57,10 +57,24 @@ class MethodBuilder {
|
|||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("Stub content Groovy DSL [$stubContent]")
|
log.debug("Stub content Groovy DSL [$stubContent]")
|
||||||
}
|
}
|
||||||
String methodName = NamesUtil.camelCase(NamesUtil.toLastDot(NamesUtil.afterLast(stubsFile.path, File.separator)))
|
String methodName = methodName(contract, stubsFile, stubContent)
|
||||||
return new MethodBuilder(methodName, stubContent, configProperties, contract.ignored || stubContent.ignored)
|
return new MethodBuilder(methodName, stubContent, configProperties, contract.ignored || stubContent.ignored)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String methodName(ContractMetadata contract, File stubsFile, Contract stubContent) {
|
||||||
|
if (stubContent.name) {
|
||||||
|
return NamesUtil.camelCase(stubContent.name)
|
||||||
|
} else if (contract.convertedContract.size() > 1) {
|
||||||
|
int index = contract.convertedContract.findIndexOf { it == stubContent}
|
||||||
|
return "${camelCasedMethodFromFileName(stubsFile)}_${index}"
|
||||||
|
}
|
||||||
|
return camelCasedMethodFromFileName(stubsFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String camelCasedMethodFromFileName(File stubsFile) {
|
||||||
|
return NamesUtil.camelCase(NamesUtil.toLastDot(NamesUtil.afterLast(stubsFile.path, File.separator)))
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Appends to the {@link BlockBuilder} the contents of the test
|
* Appends to the {@link BlockBuilder} the contents of the test
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package org.springframework.cloud.contract.verifier.file
|
package org.springframework.cloud.contract.verifier.file
|
||||||
|
|
||||||
import groovy.transform.CompileStatic
|
import groovy.transform.CompileStatic
|
||||||
|
import groovy.transform.EqualsAndHashCode
|
||||||
import groovy.transform.ToString
|
import groovy.transform.ToString
|
||||||
import org.springframework.cloud.contract.spec.Contract
|
import org.springframework.cloud.contract.spec.Contract
|
||||||
import org.springframework.cloud.contract.verifier.util.ContractVerifierDslConverter
|
import org.springframework.cloud.contract.verifier.util.ContractVerifierDslConverter
|
||||||
@@ -30,6 +31,7 @@ import java.nio.file.Path
|
|||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
@CompileStatic
|
@CompileStatic
|
||||||
|
@EqualsAndHashCode
|
||||||
@ToString
|
@ToString
|
||||||
class ContractMetadata {
|
class ContractMetadata {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ class ContractVerifierDslConverter {
|
|||||||
return new GroovyShell(ContractVerifierDslConverter.classLoader, new Binding(), new CompilerConfiguration(sourceEncoding: 'UTF-8'))
|
return new GroovyShell(ContractVerifierDslConverter.classLoader, new Binding(), new CompilerConfiguration(sourceEncoding: 'UTF-8'))
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<Contract> listOfContracts(object) {
|
private static Collection<Contract> listOfContracts(object) {
|
||||||
if (object instanceof Collection) {
|
if (object instanceof Collection) {
|
||||||
return object as Collection<Contract>
|
return object as Collection<Contract>
|
||||||
} else if (!object instanceof Contract) {
|
} else if (!object instanceof Contract) {
|
||||||
|
|||||||
@@ -106,6 +106,6 @@ class NamesUtil {
|
|||||||
* Converts illegal package characters to underscores
|
* Converts illegal package characters to underscores
|
||||||
*/
|
*/
|
||||||
static String convertIllegalPackageChars(String packageName) {
|
static String convertIllegalPackageChars(String packageName) {
|
||||||
return packageName.replace('-', '_')
|
return packageName.replace('-', '_').replace(" ", "_")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
|||||||
Contract dslWithOptionalsInString = Contract.make {
|
Contract dslWithOptionalsInString = Contract.make {
|
||||||
priority 1
|
priority 1
|
||||||
request {
|
request {
|
||||||
method 'POST'
|
method POST()
|
||||||
url '/users/password'
|
url '/users/password'
|
||||||
headers {
|
headers {
|
||||||
contentType(applicationJson())
|
contentType(applicationJson())
|
||||||
@@ -65,7 +65,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
|||||||
Contract dslWithOptionals = Contract.make {
|
Contract dslWithOptionals = Contract.make {
|
||||||
priority 1
|
priority 1
|
||||||
request {
|
request {
|
||||||
method 'POST'
|
method POST()
|
||||||
url '/users/password'
|
url '/users/password'
|
||||||
headers {
|
headers {
|
||||||
contentType(applicationJson())
|
contentType(applicationJson())
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import spock.lang.Specification
|
|||||||
|
|
||||||
import static org.springframework.cloud.contract.verifier.config.TestFramework.JUNIT
|
import static org.springframework.cloud.contract.verifier.config.TestFramework.JUNIT
|
||||||
import static org.springframework.cloud.contract.verifier.config.TestFramework.SPOCK
|
import static org.springframework.cloud.contract.verifier.config.TestFramework.SPOCK
|
||||||
import static org.springframework.cloud.contract.verifier.util.ContractVerifierDslConverter.convert
|
import static org.springframework.cloud.contract.verifier.util.ContractVerifierDslConverter.convertAsCollection
|
||||||
|
|
||||||
class SingleTestGeneratorSpec extends Specification {
|
class SingleTestGeneratorSpec extends Specification {
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ class SingleTestGeneratorSpec extends Specification {
|
|||||||
given:
|
given:
|
||||||
ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties();
|
ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties();
|
||||||
properties.targetFramework = testFramework
|
properties.targetFramework = testFramework
|
||||||
ContractMetadata contract = new ContractMetadata(file.toPath(), true, 1, 2, convert(file))
|
ContractMetadata contract = new ContractMetadata(file.toPath(), true, 1, 2, convertAsCollection(file))
|
||||||
contract.ignored >> true
|
contract.ignored >> true
|
||||||
contract.order >> 2
|
contract.order >> 2
|
||||||
JavaTestGenerator testGenerator = new JavaTestGenerator()
|
JavaTestGenerator testGenerator = new JavaTestGenerator()
|
||||||
@@ -86,7 +86,7 @@ class SingleTestGeneratorSpec extends Specification {
|
|||||||
ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties();
|
ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties();
|
||||||
properties.testMode = TestMode.JAXRSCLIENT
|
properties.testMode = TestMode.JAXRSCLIENT
|
||||||
properties.targetFramework = testFramework
|
properties.targetFramework = testFramework
|
||||||
ContractMetadata contract = new ContractMetadata(file.toPath(), true, 1, 2, convert(file))
|
ContractMetadata contract = new ContractMetadata(file.toPath(), true, 1, 2, convertAsCollection(file))
|
||||||
contract.ignored >> true
|
contract.ignored >> true
|
||||||
contract.order >> 2
|
contract.order >> 2
|
||||||
JavaTestGenerator testGenerator = new JavaTestGenerator()
|
JavaTestGenerator testGenerator = new JavaTestGenerator()
|
||||||
@@ -124,11 +124,11 @@ class SingleTestGeneratorSpec extends Specification {
|
|||||||
and:
|
and:
|
||||||
ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties();
|
ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties();
|
||||||
properties.targetFramework = testFramework
|
properties.targetFramework = testFramework
|
||||||
ContractMetadata contract = new ContractMetadata(file.toPath(), true, 1, 2, convert(file))
|
ContractMetadata contract = new ContractMetadata(file.toPath(), true, 1, 2, convertAsCollection(file))
|
||||||
contract.ignored >> true
|
contract.ignored >> true
|
||||||
contract.order >> 2
|
contract.order >> 2
|
||||||
and:
|
and:
|
||||||
ContractMetadata contract2 = new ContractMetadata(secondFile.toPath(), true, 1, 2, convert(secondFile))
|
ContractMetadata contract2 = new ContractMetadata(secondFile.toPath(), true, 1, 2, convertAsCollection(secondFile))
|
||||||
contract2.ignored >> true
|
contract2.ignored >> true
|
||||||
contract2.order >> 2
|
contract2.order >> 2
|
||||||
and:
|
and:
|
||||||
@@ -167,7 +167,7 @@ class SingleTestGeneratorSpec extends Specification {
|
|||||||
ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties();
|
ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties();
|
||||||
properties.targetFramework = testFramework
|
properties.targetFramework = testFramework
|
||||||
and:
|
and:
|
||||||
ContractMetadata contract2 = new ContractMetadata(secondFile.toPath(), true, 1, 2, convert(file))
|
ContractMetadata contract2 = new ContractMetadata(secondFile.toPath(), true, 1, 2, convertAsCollection(file))
|
||||||
contract2.ignored >> false
|
contract2.ignored >> false
|
||||||
contract2.order >> 2
|
contract2.order >> 2
|
||||||
and:
|
and:
|
||||||
@@ -186,5 +186,98 @@ class SingleTestGeneratorSpec extends Specification {
|
|||||||
SPOCK | spockClassStrings
|
SPOCK | spockClassStrings
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def "should pick the contract's name as the test method"() {
|
||||||
|
given:
|
||||||
|
File secondFile = tmpFolder.newFile()
|
||||||
|
secondFile.write("""
|
||||||
|
org.springframework.cloud.contract.spec.Contract.make {
|
||||||
|
name("MySuperMethod")
|
||||||
|
request {
|
||||||
|
method 'PUT'
|
||||||
|
url 'url'
|
||||||
|
}
|
||||||
|
response {
|
||||||
|
status 200
|
||||||
|
}
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
and:
|
||||||
|
ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties();
|
||||||
|
properties.targetFramework = testFramework
|
||||||
|
ContractMetadata contract = new ContractMetadata(secondFile.toPath(), false, 1, null, convertAsCollection(secondFile))
|
||||||
|
JavaTestGenerator testGenerator = new JavaTestGenerator()
|
||||||
|
when:
|
||||||
|
String clazz = testGenerator.buildClass(properties, [contract], "test", "test", 'com/foo')
|
||||||
|
then:
|
||||||
|
clazz.contains("validate_mySuperMethod()")
|
||||||
|
where:
|
||||||
|
testFramework << [JUNIT, SPOCK]
|
||||||
|
}
|
||||||
|
|
||||||
|
def "should pick the contract's name as the test method when there are multiple contracts"() {
|
||||||
|
given:
|
||||||
|
File secondFile = tmpFolder.newFile()
|
||||||
|
secondFile.write('''
|
||||||
|
(1..2).collect { int index ->
|
||||||
|
org.springframework.cloud.contract.spec.Contract.make {
|
||||||
|
name("shouldHaveIndex${index}")
|
||||||
|
request {
|
||||||
|
method(PUT())
|
||||||
|
headers {
|
||||||
|
contentType(applicationJson())
|
||||||
|
}
|
||||||
|
url "/${index}"
|
||||||
|
}
|
||||||
|
response {
|
||||||
|
status 200
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}''')
|
||||||
|
and:
|
||||||
|
ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties();
|
||||||
|
properties.targetFramework = testFramework
|
||||||
|
ContractMetadata contract = new ContractMetadata(secondFile.toPath(), false, 1, null, convertAsCollection(secondFile))
|
||||||
|
JavaTestGenerator testGenerator = new JavaTestGenerator()
|
||||||
|
when:
|
||||||
|
String clazz = testGenerator.buildClass(properties, [contract], "test", "test", 'com/foo')
|
||||||
|
then:
|
||||||
|
clazz.contains("validate_shouldHaveIndex1()")
|
||||||
|
clazz.contains("validate_shouldHaveIndex2()")
|
||||||
|
where:
|
||||||
|
testFramework << [JUNIT, SPOCK]
|
||||||
|
}
|
||||||
|
|
||||||
|
def "should generate the test method when there are multiple contracts without name field"() {
|
||||||
|
given:
|
||||||
|
File secondFile = tmpFolder.newFile()
|
||||||
|
secondFile.write('''
|
||||||
|
(1..2).collect { int index ->
|
||||||
|
org.springframework.cloud.contract.spec.Contract.make {
|
||||||
|
request {
|
||||||
|
method(PUT())
|
||||||
|
headers {
|
||||||
|
contentType(applicationJson())
|
||||||
|
}
|
||||||
|
url "/${index}"
|
||||||
|
}
|
||||||
|
response {
|
||||||
|
status 200
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}''')
|
||||||
|
and:
|
||||||
|
ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties();
|
||||||
|
properties.targetFramework = testFramework
|
||||||
|
ContractMetadata contract = new ContractMetadata(secondFile.toPath(), false, 1, null, convertAsCollection(secondFile))
|
||||||
|
JavaTestGenerator testGenerator = new JavaTestGenerator()
|
||||||
|
when:
|
||||||
|
String clazz = testGenerator.buildClass(properties, [contract], "test", "test", 'com/foo')
|
||||||
|
then:
|
||||||
|
clazz.contains("_0() throws Exception")
|
||||||
|
clazz.contains("_1() throws Exception")
|
||||||
|
where:
|
||||||
|
testFramework << [JUNIT, SPOCK]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
package org.springframework.cloud.contract.verifier.util
|
||||||
|
|
||||||
|
import spock.lang.Specification
|
||||||
|
/**
|
||||||
|
* @author Marcin Grzejszczak
|
||||||
|
*/
|
||||||
|
class NamesUtilSpec extends Specification {
|
||||||
|
def "should return the whole string before the last one"() {
|
||||||
|
given:
|
||||||
|
String string = "a.b.c.d.e"
|
||||||
|
expect:
|
||||||
|
"a.b.c.d" == NamesUtil.beforeLast(string, ".")
|
||||||
|
}
|
||||||
|
|
||||||
|
def "should return empty string when no token was found for before last"() {
|
||||||
|
given:
|
||||||
|
String string = "a.b.c.d.e"
|
||||||
|
expect:
|
||||||
|
"" == NamesUtil.beforeLast(string, "/")
|
||||||
|
}
|
||||||
|
|
||||||
|
def "should return first token after the last one"() {
|
||||||
|
given:
|
||||||
|
String string = "a.b.c.d.e"
|
||||||
|
expect:
|
||||||
|
"e" == NamesUtil.afterLast(string, ".")
|
||||||
|
}
|
||||||
|
|
||||||
|
def "should return the input string when no token was found for after last"() {
|
||||||
|
given:
|
||||||
|
String string = "a.b.c.d.e"
|
||||||
|
expect:
|
||||||
|
string == NamesUtil.afterLast(string, "/")
|
||||||
|
}
|
||||||
|
|
||||||
|
def "should return first token after the last dot"() {
|
||||||
|
given:
|
||||||
|
String string = "a.b.c.d.e"
|
||||||
|
expect:
|
||||||
|
"e" == NamesUtil.afterLastDot(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
def "should return the input string when no token was found for after last dot"() {
|
||||||
|
given:
|
||||||
|
String string = "abcde"
|
||||||
|
expect:
|
||||||
|
string == NamesUtil.afterLastDot(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
def "should return camel case version of a string"() {
|
||||||
|
given:
|
||||||
|
String string = "BlaBlaBla"
|
||||||
|
expect:
|
||||||
|
"blaBlaBla" == NamesUtil.camelCase(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
def "should return capitalized version of a string"() {
|
||||||
|
given:
|
||||||
|
String string = "blaBlaBla"
|
||||||
|
expect:
|
||||||
|
"BlaBlaBla" == NamesUtil.capitalize(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
def "should return all text to last dot"() {
|
||||||
|
given:
|
||||||
|
String string = "a.b.c.d.e"
|
||||||
|
expect:
|
||||||
|
"a.b.c.d" == NamesUtil.toLastDot(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
def "should return the input string when no token was found for to last dot"() {
|
||||||
|
given:
|
||||||
|
String string = "abcde"
|
||||||
|
expect:
|
||||||
|
string == NamesUtil.toLastDot(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
def "should convert a package notation to directory"() {
|
||||||
|
given:
|
||||||
|
String string = "a.b.c.d.e"
|
||||||
|
expect:
|
||||||
|
"a/b/c/d/e".replace("/", File.separator) == NamesUtil.packageToDirectory(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
def "should convert a directory notation to package"() {
|
||||||
|
given:
|
||||||
|
String string = "a/b/c/d/e".replace("/", File.separator)
|
||||||
|
expect:
|
||||||
|
"a.b.c.d.e" == NamesUtil.directoryToPackage(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
def "should convert all illegal package chars to legal ones"() {
|
||||||
|
given:
|
||||||
|
String string = "a-b c"
|
||||||
|
expect:
|
||||||
|
"a_b_c" == NamesUtil.convertIllegalPackageChars(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user