Assert size of collections on the request side; fixes gh-824
This commit is contained in:
@@ -821,7 +821,7 @@ match the regex for an ISO DateTime value.
|
||||
the regex for an ISO Time value.
|
||||
** `byType()`: 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.
|
||||
`byType` can take a closure, in which you can set `minOccurrence` and `maxOccurrence`.
|
||||
`byType` can take a closure, in which you can set `minOccurrence` and `maxOccurrence`. 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 `byCommand(...)` testMatcher.
|
||||
** `byCommand(...)`: The value taken from the producer's response via the provided JSON Path is
|
||||
@@ -869,6 +869,8 @@ Below you can find the allowed list of `type`s.
|
||||
** `by_date`
|
||||
** `by_timestamp`
|
||||
** `by_time`
|
||||
** `by_type`
|
||||
*** there are 2 additional fields accepted: `minOccurrence` and `maxOccurrence`.
|
||||
* For `testMatchers`:
|
||||
** `by_equality`
|
||||
** `by_regex`
|
||||
|
||||
@@ -56,10 +56,6 @@ test {
|
||||
}
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
gradleVersion = '4.0.2'
|
||||
}
|
||||
|
||||
task resolveDependencies {
|
||||
doLast {
|
||||
project.rootProject.allprojects.each { subProject ->
|
||||
|
||||
@@ -27,7 +27,7 @@ repositories {
|
||||
}
|
||||
// end::deps_repos[]
|
||||
|
||||
apply plugin: 'groovy'
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'org.springframework.boot'
|
||||
apply plugin: 'io.spring.dependency-management'
|
||||
apply plugin: 'spring-cloud-contract'
|
||||
@@ -65,10 +65,6 @@ test {
|
||||
}
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
gradleVersion = '4.0.2'
|
||||
}
|
||||
|
||||
clean.doFirst {
|
||||
delete "~/.m2/repository/com/example/http-server-dsl-gradle"
|
||||
}
|
||||
|
||||
@@ -69,8 +69,4 @@ task resolveDependencies {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
gradleVersion = '4.0.2'
|
||||
}
|
||||
@@ -110,8 +110,4 @@ task resolveDependencies {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
gradleVersion = '4.0.2'
|
||||
}
|
||||
@@ -58,10 +58,6 @@ test {
|
||||
}
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
gradleVersion = '4.0.2'
|
||||
}
|
||||
|
||||
task resolveDependencies {
|
||||
doLast {
|
||||
project.rootProject.allprojects.each { subProject ->
|
||||
|
||||
@@ -64,10 +64,6 @@ test {
|
||||
}
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
gradleVersion = '4.0.2'
|
||||
}
|
||||
|
||||
clean.doFirst {
|
||||
delete "~/.m2/repository/com/example/http-server-pact-gradle"
|
||||
}
|
||||
|
||||
@@ -60,10 +60,6 @@ test {
|
||||
}
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
gradleVersion = '4.0.2'
|
||||
}
|
||||
|
||||
task resolveDependencies {
|
||||
doLast {
|
||||
project.rootProject.allprojects.each { subProject ->
|
||||
|
||||
@@ -60,10 +60,6 @@ test {
|
||||
}
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
gradleVersion = '4.0.2'
|
||||
}
|
||||
|
||||
task resolveDependencies {
|
||||
doLast {
|
||||
project.rootProject.allprojects.each { subProject ->
|
||||
|
||||
@@ -62,10 +62,6 @@ test {
|
||||
}
|
||||
}
|
||||
|
||||
task wrapper(type: Wrapper) {
|
||||
gradleVersion = '4.0.2'
|
||||
}
|
||||
|
||||
task stubsJar(type: Jar, dependsOn: ['copySnippets', 'copySources', 'copyClasses']) {
|
||||
baseName = project.name
|
||||
classifier = 'stubs'
|
||||
|
||||
@@ -73,6 +73,13 @@ class BodyMatchers {
|
||||
return new MatchingTypeValue(MatchingType.EQUALITY, null)
|
||||
}
|
||||
|
||||
MatchingTypeValue byType(@DelegatesTo(MatchingTypeValueHolder) Closure closure) {
|
||||
MatchingTypeValueHolder matchingTypeValue = new MatchingTypeValueHolder()
|
||||
closure.delegate = matchingTypeValue
|
||||
closure()
|
||||
return matchingTypeValue.matchingTypeValue
|
||||
}
|
||||
|
||||
boolean equals(o) {
|
||||
if (this.is(o)) return true
|
||||
if (this.getClass() != o.class) return false
|
||||
@@ -147,3 +154,26 @@ class MatchingTypeValue {
|
||||
*/
|
||||
Integer maxTypeOccurrence
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
@ToString(includePackage = false)
|
||||
@EqualsAndHashCode
|
||||
class MatchingTypeValueHolder {
|
||||
MatchingTypeValue matchingTypeValue = new MatchingTypeValue(type: MatchingType.TYPE)
|
||||
|
||||
MatchingTypeValue minOccurrence(int number) {
|
||||
this.matchingTypeValue.minTypeOccurrence = number
|
||||
return this.matchingTypeValue
|
||||
}
|
||||
|
||||
MatchingTypeValue maxOccurrence(int number) {
|
||||
this.matchingTypeValue.maxTypeOccurrence = number
|
||||
return this.matchingTypeValue
|
||||
}
|
||||
|
||||
MatchingTypeValue occurrence(int number) {
|
||||
this.matchingTypeValue.minTypeOccurrence = number
|
||||
this.matchingTypeValue.maxTypeOccurrence = number
|
||||
return this.matchingTypeValue
|
||||
}
|
||||
}
|
||||
@@ -16,9 +16,7 @@
|
||||
package org.springframework.cloud.contract.spec.internal
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.ToString
|
||||
|
||||
/**
|
||||
* Body matchers for the response side (output message, REST response)
|
||||
*
|
||||
@@ -38,31 +36,7 @@ class ResponseBodyMatchers extends BodyMatchers {
|
||||
return new MatchingTypeValue(MatchingType.COMMAND, new ExecutionProperty(execute))
|
||||
}
|
||||
|
||||
MatchingTypeValue byType(@DelegatesTo(MatchingTypeValueHolder) Closure closure) {
|
||||
MatchingTypeValueHolder matchingTypeValue = new MatchingTypeValueHolder()
|
||||
closure.delegate = matchingTypeValue
|
||||
closure()
|
||||
return matchingTypeValue.matchingTypeValue
|
||||
}
|
||||
|
||||
MatchingTypeValue byNull() {
|
||||
return new MatchingTypeValue(MatchingType.NULL, null)
|
||||
}
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
@ToString(includePackage = false)
|
||||
@EqualsAndHashCode
|
||||
class MatchingTypeValueHolder {
|
||||
MatchingTypeValue matchingTypeValue = new MatchingTypeValue(type: MatchingType.TYPE)
|
||||
|
||||
MatchingTypeValue minOccurrence(int number) {
|
||||
this.matchingTypeValue.minTypeOccurrence = number
|
||||
return this.matchingTypeValue
|
||||
}
|
||||
|
||||
MatchingTypeValue maxOccurrence(int number) {
|
||||
this.matchingTypeValue.maxTypeOccurrence = number
|
||||
return this.matchingTypeValue
|
||||
}
|
||||
}
|
||||
|
||||
@@ -581,6 +581,15 @@ class DslToWireMockClientConverterSpec extends Specification {
|
||||
anothervalue: 4
|
||||
]
|
||||
]
|
||||
],
|
||||
valueWithMin: [
|
||||
1,2,3
|
||||
],
|
||||
valueWithMax: [
|
||||
1,2,3
|
||||
],
|
||||
valueWithMinMax: [
|
||||
1,2,3
|
||||
]
|
||||
])
|
||||
bodyMatchers {
|
||||
@@ -594,6 +603,23 @@ class DslToWireMockClientConverterSpec extends Specification {
|
||||
jsonPath('$.dateTime', byTimestamp())
|
||||
jsonPath('$.time', byTime())
|
||||
jsonPath('$.list.some.nested.json', byRegex(".*"))
|
||||
jsonPath('$.valueWithMin', byType {
|
||||
// results in verification of size of array (min 1)
|
||||
minOccurrence(1)
|
||||
})
|
||||
jsonPath('$.valueWithMax', byType {
|
||||
// results in verification of size of array (max 3)
|
||||
maxOccurrence(3)
|
||||
})
|
||||
jsonPath('$.valueWithMinMax', byType {
|
||||
// results in verification of size of array (min 1 & max 3)
|
||||
minOccurrence(1)
|
||||
maxOccurrence(3)
|
||||
})
|
||||
jsonPath('$.valueWithOccurrence', byType {
|
||||
// results in verification of size of array (min 4 & max 4)
|
||||
occurrence(4)
|
||||
})
|
||||
}
|
||||
headers {
|
||||
contentType(applicationJson())
|
||||
@@ -620,6 +646,9 @@ class DslToWireMockClientConverterSpec extends Specification {
|
||||
valueWithMinMax: [
|
||||
1,2,3
|
||||
],
|
||||
valueWithOccurrence: [
|
||||
1,2,3,4
|
||||
],
|
||||
])
|
||||
bodyMatchers {
|
||||
// asserts the jsonpath value against manual regex
|
||||
@@ -649,6 +678,10 @@ class DslToWireMockClientConverterSpec extends Specification {
|
||||
minOccurrence(1)
|
||||
maxOccurrence(3)
|
||||
})
|
||||
jsonPath('$.valueWithOccurrence', byType {
|
||||
// results in verification of size of array (min 4 & max 4)
|
||||
occurrence(4)
|
||||
})
|
||||
}
|
||||
headers {
|
||||
contentType(applicationJson())
|
||||
@@ -664,51 +697,60 @@ class DslToWireMockClientConverterSpec extends Specification {
|
||||
'''
|
||||
{
|
||||
"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" ]
|
||||
}
|
||||
}
|
||||
'''
|
||||
@@ -744,6 +786,18 @@ class DslToWireMockClientConverterSpec extends Specification {
|
||||
anothervalue: 4
|
||||
]
|
||||
]
|
||||
],
|
||||
valueWithMin: [
|
||||
1,2,3
|
||||
],
|
||||
valueWithMax: [
|
||||
1,2,3
|
||||
],
|
||||
valueWithMinMax: [
|
||||
1,2,3
|
||||
],
|
||||
valueWithOccurrence: [
|
||||
1,2,3,4
|
||||
]
|
||||
]))
|
||||
, String)
|
||||
@@ -768,6 +822,9 @@ class DslToWireMockClientConverterSpec extends Specification {
|
||||
valueWithMinMax: [
|
||||
1,2,3
|
||||
],
|
||||
valueWithOccurrence: [
|
||||
1,2,3,4
|
||||
],
|
||||
]), response.body, false)
|
||||
}
|
||||
|
||||
|
||||
@@ -128,7 +128,9 @@ class ContractsToYaml {
|
||||
request.matchers.body << new YamlContract.BodyStubMatcher(
|
||||
path: matcher.path(),
|
||||
type: stubMatcherType(matcher.matchingType()),
|
||||
value: matcher.value()?.toString()
|
||||
value: matcher.value()?.toString(),
|
||||
minOccurrence: matcher.minTypeOccurrence(),
|
||||
maxOccurrence: matcher.maxTypeOccurrence(),
|
||||
)
|
||||
}
|
||||
Object url = contract.request.url?.clientValue
|
||||
|
||||
@@ -104,6 +104,8 @@ class YamlContract {
|
||||
public StubMatcherType type
|
||||
public String value
|
||||
public PredefinedRegex predefined
|
||||
public Integer minOccurrence
|
||||
public Integer maxOccurrence
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
@@ -199,7 +201,7 @@ class YamlContract {
|
||||
|
||||
@CompileStatic
|
||||
static enum StubMatcherType {
|
||||
by_date, by_time, by_timestamp, by_regex, by_equality, by_null
|
||||
by_date, by_time, by_timestamp, by_regex, by_equality, by_type, by_null
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
|
||||
@@ -199,6 +199,12 @@ class YamlToContracts {
|
||||
case YamlContract.StubMatcherType.by_equality:
|
||||
value = byEquality()
|
||||
break
|
||||
case YamlContract.StubMatcherType.by_type:
|
||||
value = byType {
|
||||
if (matcher.minOccurrence != null) minOccurrence(matcher.minOccurrence)
|
||||
if (matcher.maxOccurrence != null) maxOccurrence(matcher.maxOccurrence)
|
||||
}
|
||||
break
|
||||
case YamlContract.StubMatcherType.by_null:
|
||||
// do nothing
|
||||
break
|
||||
|
||||
@@ -142,14 +142,16 @@ class JsonToJsonPathsConverter {
|
||||
static String convertJsonPathAndRegexToAJsonPath(BodyMatcher bodyMatcher, def body = null) {
|
||||
String path = bodyMatcher.path()
|
||||
Object value = bodyMatcher.value()
|
||||
if (value == null && bodyMatcher.matchingType() != MatchingType.EQUALITY) {
|
||||
if (value == null && bodyMatcher.matchingType() != MatchingType.EQUALITY &&
|
||||
bodyMatcher.matchingType() != MatchingType.TYPE) {
|
||||
return path
|
||||
}
|
||||
int lastIndexOfDot = lastIndexOfDot(path)
|
||||
String toLastDot = path.substring(0, lastIndexOfDot)
|
||||
String fromLastDot = path.substring(lastIndexOfDot + 1)
|
||||
String comparison = createComparison(bodyMatcher, value, body)
|
||||
return "${toLastDot}[?(@.${fromLastDot} ${comparison})]"
|
||||
String propertyName = "@.${fromLastDot}"
|
||||
String comparison = createComparison(propertyName, bodyMatcher, value, body)
|
||||
return "${toLastDot}[?(${comparison})]"
|
||||
}
|
||||
|
||||
private static int lastIndexOfDot(String path) {
|
||||
@@ -173,7 +175,7 @@ class JsonToJsonPathsConverter {
|
||||
return value
|
||||
}
|
||||
|
||||
private static String createComparison(BodyMatcher bodyMatcher, Object value, def body) {
|
||||
private static String createComparison(String propertyName, BodyMatcher bodyMatcher, Object value, def body) {
|
||||
if (bodyMatcher.matchingType() == MatchingType.EQUALITY) {
|
||||
Object convertedBody = body
|
||||
if (!body) {
|
||||
@@ -185,13 +187,25 @@ class JsonToJsonPathsConverter {
|
||||
}
|
||||
Object retrievedValue = JsonPath.parse(convertedBody).read(bodyMatcher.path())
|
||||
String wrappedValue = retrievedValue instanceof Number ? retrievedValue : "'${retrievedValue.toString()}'"
|
||||
return "== ${wrappedValue}"
|
||||
return "${propertyName} == ${wrappedValue}"
|
||||
} catch (PathNotFoundException e) {
|
||||
throw new IllegalStateException("Value [${bodyMatcher.path()}] not found in JSON [${JsonOutput.toJson(convertedBody)}]", e)
|
||||
}
|
||||
} else if (bodyMatcher.matchingType() == MatchingType.TYPE) {
|
||||
Integer min = bodyMatcher.minTypeOccurrence()
|
||||
Integer max = bodyMatcher.maxTypeOccurrence()
|
||||
String result = ""
|
||||
if (min != null) {
|
||||
result = "${propertyName}.size() >= ${min}"
|
||||
}
|
||||
if (max != null) {
|
||||
String maxResult = "${propertyName}.size() <= ${max}"
|
||||
result = result ? "${result} && ${maxResult}" : maxResult
|
||||
}
|
||||
return result
|
||||
} else {
|
||||
String convertedValue = value.toString().replace('/', '\\\\/')
|
||||
return "=~ /(${convertedValue})/"
|
||||
return "${propertyName} =~ /(${convertedValue})/"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1192,7 +1192,7 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
|
||||
where:
|
||||
methodBuilderName | methodBuilder | endOfLineRegexSymbol
|
||||
"JaxRsClientSpockMethodRequestProcessingBodyBuilder"| { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties, generatedClassDataForMethod) } | '\\$'
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties, generatedClassDataForMethod) } | '$'
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties, generatedClassDataForMethod) }| '$'
|
||||
}
|
||||
|
||||
private String stripped(String string) {
|
||||
|
||||
@@ -475,7 +475,7 @@ class MockMvcMethodBodyBuilderWithMatchersSpec extends Specification implements
|
||||
bodyMatchers {
|
||||
jsonPath('$.items[*].id', byRegex(nonBlank()))
|
||||
jsonPath('$.items[*].title', byRegex(nonBlank()))
|
||||
jsonPath('$.items[*]', byType { minOccurrence(2); maxOccurrence(2) })
|
||||
jsonPath('$.items[*]', byType { occurrence(2) })
|
||||
}
|
||||
headers { header 'content-type', 'application/...json;charset=UTF-8' }
|
||||
}
|
||||
|
||||
@@ -239,6 +239,16 @@ class YamlContractConverterSpec extends Specification {
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[8].value() == patterns.isoTime()
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[9].path() == "\$.['key'].['complex.key']"
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[9].matchingType() == MatchingType.EQUALITY
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[10].path() == '$.valueWithMin'
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[10].matchingType() == MatchingType.TYPE
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[10].minTypeOccurrence() == 1
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[11].path() == '$.valueWithMax'
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[11].matchingType() == MatchingType.TYPE
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[11].maxTypeOccurrence() == 3
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[12].path() == '$.valueWithMinMax'
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[12].matchingType() == MatchingType.TYPE
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[12].minTypeOccurrence() == 1
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[12].maxTypeOccurrence() == 3
|
||||
contract.request.cookies.entries.find { it.key == "foo" }.clientValue instanceof Pattern
|
||||
contract.request.cookies.entries.find { it.key == "bar" }.serverValue == new ExecutionProperty('equals($it)')
|
||||
and:
|
||||
|
||||
@@ -28,6 +28,20 @@ request:
|
||||
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]
|
||||
@@ -90,6 +104,16 @@ request:
|
||||
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:
|
||||
|
||||
Reference in New Issue
Block a user