Allows passing of regex type (#832)
without this change if one does $(regex("[0-9]")) we have no knowledge of whether the result should be text or a number. What we do ATM is we always generate a String
with this change once can pass the type of regular expression and we will generate the concrete value of that given type
fixes gh-768
This commit is contained in:
committed by
GitHub
parent
58bf533462
commit
56fbc11f62
@@ -30,6 +30,7 @@ import org.springframework.cloud.contract.spec.internal.Header
|
||||
import org.springframework.cloud.contract.spec.internal.Input
|
||||
import org.springframework.cloud.contract.spec.internal.NamedProperty
|
||||
import org.springframework.cloud.contract.spec.internal.NotToEscapePattern
|
||||
import org.springframework.cloud.contract.spec.internal.RegexProperty
|
||||
import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties
|
||||
import org.springframework.cloud.contract.verifier.util.MapConverter
|
||||
|
||||
@@ -264,6 +265,10 @@ class JUnitMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder {
|
||||
return ""
|
||||
}
|
||||
|
||||
protected String convertHeaderComparison(RegexProperty headerValue) {
|
||||
return convertHeaderComparison(headerValue.pattern)
|
||||
}
|
||||
|
||||
protected String createHeaderComparison(Object headerValue) {
|
||||
String escapedHeader = convertUnicodeEscapesIfRequired("$headerValue")
|
||||
return "isEqualTo(\"$escapedHeader\");"
|
||||
|
||||
@@ -41,6 +41,7 @@ import org.springframework.cloud.contract.spec.internal.MatchingType
|
||||
import org.springframework.cloud.contract.spec.internal.NamedProperty
|
||||
import org.springframework.cloud.contract.spec.internal.OptionalProperty
|
||||
import org.springframework.cloud.contract.spec.internal.QueryParameter
|
||||
import org.springframework.cloud.contract.spec.internal.RegexProperty
|
||||
import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties
|
||||
import org.springframework.cloud.contract.verifier.template.HandlebarsTemplateProcessor
|
||||
import org.springframework.cloud.contract.verifier.template.TemplateProcessor
|
||||
@@ -197,6 +198,13 @@ abstract class MethodBodyBuilder {
|
||||
*/
|
||||
protected abstract void processHeaderElement(BlockBuilder blockBuilder, String property, Pattern pattern)
|
||||
|
||||
/**
|
||||
* Appends to the {@link BlockBuilder} the assertion for the given header path
|
||||
*/
|
||||
protected void processHeaderElement(BlockBuilder blockBuilder, String property, RegexProperty regexProperty) {
|
||||
processHeaderElement(blockBuilder, property, regexProperty.pattern)
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends to the {@link BlockBuilder} the assertion for the given header path
|
||||
*/
|
||||
@@ -522,7 +530,7 @@ abstract class MethodBodyBuilder {
|
||||
protected void methodForEqualityCheck(BodyMatcher bodyMatcher, BlockBuilder bb, Object copiedBody) {
|
||||
String path = quotedAndEscaped(bodyMatcher.path())
|
||||
Object retrievedValue = value(copiedBody, bodyMatcher)
|
||||
retrievedValue = retrievedValue instanceof Pattern ? ((Pattern) retrievedValue).pattern() : retrievedValue
|
||||
retrievedValue = retrievedValue instanceof RegexProperty ? ((RegexProperty) retrievedValue).getPattern().pattern() : retrievedValue
|
||||
String valueAsParam = retrievedValue instanceof String ? quotedAndEscaped(retrievedValue.toString()) : retrievedValue.toString()
|
||||
if (arrayRelated(path) && MatchingType.regexRelated(bodyMatcher.matchingType())) {
|
||||
buildCustomMatchingConditionForEachElement(bb, path, valueAsParam)
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.springframework.cloud.contract.spec.internal.Header
|
||||
import org.springframework.cloud.contract.spec.internal.Input
|
||||
import org.springframework.cloud.contract.spec.internal.NamedProperty
|
||||
import org.springframework.cloud.contract.spec.internal.NotToEscapePattern
|
||||
import org.springframework.cloud.contract.spec.internal.RegexProperty
|
||||
import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties
|
||||
import org.springframework.cloud.contract.verifier.util.MapConverter
|
||||
|
||||
@@ -251,6 +252,10 @@ class SpockMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder {
|
||||
return " == '$headerValue'"
|
||||
}
|
||||
|
||||
protected String convertHeaderComparison(RegexProperty headerValue) {
|
||||
return convertHeaderComparison(headerValue.pattern)
|
||||
}
|
||||
|
||||
protected String convertHeaderComparison(Pattern headerValue) {
|
||||
String converted = escapeJava(convertUnicodeEscapesIfRequired(headerValue.pattern()))
|
||||
return "==~ java.util.regex.Pattern.compile('${converted}')"
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.springframework.cloud.contract.spec.internal.Cookie
|
||||
import org.springframework.cloud.contract.spec.internal.FromFileProperty
|
||||
import org.springframework.cloud.contract.spec.internal.Header
|
||||
import org.springframework.cloud.contract.spec.internal.NamedProperty
|
||||
import org.springframework.cloud.contract.spec.internal.RegexProperty
|
||||
import org.springframework.cloud.contract.spec.internal.Request
|
||||
import org.springframework.cloud.contract.spec.internal.ExecutionProperty
|
||||
import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties
|
||||
@@ -187,10 +188,18 @@ abstract class SpockMethodRequestProcessingBodyBuilder extends RequestProcessing
|
||||
return patternComparison(headerValue)
|
||||
}
|
||||
|
||||
protected String convertHeaderComparison(RegexProperty headerValue) {
|
||||
return convertHeaderComparison(headerValue.pattern)
|
||||
}
|
||||
|
||||
protected String convertCookieComparison(String cookieValue) {
|
||||
return "== '$cookieValue'"
|
||||
}
|
||||
|
||||
protected String createBodyComparison(RegexProperty bodyValue) {
|
||||
return createBodyComparison(bodyValue.pattern)
|
||||
}
|
||||
|
||||
protected String createBodyComparison(Pattern bodyValue) {
|
||||
String patternAsString = bodyValue.pattern()
|
||||
return patternComparison(RegexpBuilders.buildGStringRegexpForTestSide(patternAsString)) + ";"
|
||||
|
||||
@@ -16,6 +16,8 @@ import org.springframework.cloud.contract.spec.internal.MatchingType
|
||||
import org.springframework.cloud.contract.spec.internal.Multipart
|
||||
import org.springframework.cloud.contract.spec.internal.NamedProperty
|
||||
import org.springframework.cloud.contract.spec.internal.NotToEscapePattern
|
||||
import org.springframework.cloud.contract.spec.internal.RegexProperty
|
||||
import org.springframework.cloud.contract.verifier.converter.YamlContract.RegexType
|
||||
import org.springframework.cloud.contract.verifier.util.JsonPaths
|
||||
import org.springframework.cloud.contract.verifier.util.JsonToJsonPathsConverter
|
||||
import org.springframework.cloud.contract.verifier.util.MapConverter
|
||||
@@ -141,12 +143,12 @@ class ContractsToYaml {
|
||||
)
|
||||
}
|
||||
Object url = contract.request.url?.clientValue
|
||||
request.matchers.url = url instanceof Pattern ?
|
||||
request.matchers.url = url instanceof RegexProperty ?
|
||||
new YamlContract.KeyValueMatcher(regex: url.pattern()) :
|
||||
url instanceof ExecutionProperty ?
|
||||
new YamlContract.KeyValueMatcher(command: url.toString()) : null
|
||||
Object urlPath = contract.request.urlPath?.clientValue
|
||||
request.matchers.url = urlPath instanceof Pattern ?
|
||||
request.matchers.url = urlPath instanceof RegexProperty ?
|
||||
new YamlContract.KeyValueMatcher(regex: urlPath.pattern()) :
|
||||
urlPath instanceof ExecutionProperty ?
|
||||
new YamlContract.KeyValueMatcher(command: urlPath.toString()) : null
|
||||
@@ -158,9 +160,9 @@ class ContractsToYaml {
|
||||
Object fileName = value.name?.clientValue
|
||||
Object fileContent = value.value?.clientValue
|
||||
Object contentType = value.contentType?.clientValue
|
||||
if (fileName instanceof Pattern ||
|
||||
fileContent instanceof Pattern ||
|
||||
contentType instanceof Pattern) {
|
||||
if (fileName instanceof RegexProperty ||
|
||||
fileContent instanceof RegexProperty ||
|
||||
contentType instanceof RegexProperty) {
|
||||
request.matchers.multipart.named << new YamlContract.MultipartNamedStubMatcher(
|
||||
paramName: key,
|
||||
fileName: valueMatcher(fileName),
|
||||
@@ -168,10 +170,12 @@ class ContractsToYaml {
|
||||
contentType: valueMatcher(contentType),
|
||||
)
|
||||
}
|
||||
} else if (value instanceof Pattern) {
|
||||
} else if (value instanceof RegexProperty || value instanceof Pattern) {
|
||||
RegexProperty property = new RegexProperty(value)
|
||||
request.matchers.multipart.params.add(new YamlContract.KeyValueMatcher(
|
||||
key: key,
|
||||
regex: value.pattern()
|
||||
regex: property.pattern(),
|
||||
regexType: regexType(property.clazz())
|
||||
))
|
||||
}
|
||||
}
|
||||
@@ -191,27 +195,56 @@ class ContractsToYaml {
|
||||
}
|
||||
|
||||
protected YamlContract.ValueMatcher valueMatcher(Object o) {
|
||||
return o instanceof Pattern ? new YamlContract.ValueMatcher(regex: o.pattern()) : null
|
||||
return o instanceof RegexProperty ? new YamlContract.ValueMatcher(regex: o.pattern()) : null
|
||||
}
|
||||
|
||||
protected void setInputBodyMatchers(DslProperty body, List<YamlContract.BodyStubMatcher> bodyMatchers) {
|
||||
def testSideValues = MapConverter.getTestSideValues(body)
|
||||
JsonPaths paths = new JsonToJsonPathsConverter().transformToJsonPathWithStubsSideValues(body)
|
||||
paths?.findAll { it.valueBeforeChecking() instanceof Pattern }?.each {
|
||||
Object element = JsonToJsonPathsConverter.readElement(testSideValues, it.keyBeforeChecking())
|
||||
bodyMatchers << new YamlContract.BodyStubMatcher(
|
||||
path: it.keyBeforeChecking(),
|
||||
type: YamlContract.StubMatcherType.by_regex,
|
||||
value: (it.valueBeforeChecking() as Pattern).pattern()
|
||||
value: (it.valueBeforeChecking() as Pattern).pattern(),
|
||||
regexType: regexType(element)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
protected RegexType regexType(Object from) {
|
||||
return regexType(from.class)
|
||||
}
|
||||
|
||||
protected RegexType regexType(Class clazz) {
|
||||
switch(clazz) {
|
||||
case Boolean:
|
||||
return RegexType.as_boolean
|
||||
case Long:
|
||||
return RegexType.as_long
|
||||
case Short:
|
||||
return RegexType.as_short
|
||||
case Integer:
|
||||
return RegexType.as_integer
|
||||
case Float:
|
||||
return RegexType.as_float
|
||||
case Double:
|
||||
return RegexType.as_double
|
||||
default:
|
||||
return RegexType.as_string
|
||||
}
|
||||
}
|
||||
|
||||
protected void setOutputBodyMatchers(DslProperty body, List<YamlContract.BodyTestMatcher> bodyMatchers) {
|
||||
def testSideValues = MapConverter.getTestSideValues(body)
|
||||
JsonPaths paths = new JsonToJsonPathsConverter().transformToJsonPathWithTestsSideValues(body)
|
||||
paths?.findAll { it.valueBeforeChecking() instanceof Pattern }?.each {
|
||||
Object element = JsonToJsonPathsConverter.readElement(testSideValues, it.keyBeforeChecking())
|
||||
bodyMatchers << new YamlContract.BodyTestMatcher(
|
||||
path: it.keyBeforeChecking(),
|
||||
type: YamlContract.TestMatcherType.by_regex,
|
||||
value: (it.valueBeforeChecking() as Pattern).pattern()
|
||||
value: (it.valueBeforeChecking() as Pattern).pattern(),
|
||||
regexType: regexType(element)
|
||||
)
|
||||
}
|
||||
if (body?.serverValue instanceof Pattern) {
|
||||
@@ -259,10 +292,12 @@ class ContractsToYaml {
|
||||
|
||||
protected void setInputHeadersMatchers(Headers headers, List<YamlContract.KeyValueMatcher> headerMatchers) {
|
||||
headers?.asStubSideMap()?.each { String key, Object value ->
|
||||
if (value instanceof Pattern) {
|
||||
if (value instanceof RegexProperty || value instanceof Pattern) {
|
||||
RegexProperty property = new RegexProperty(value)
|
||||
headerMatchers << new YamlContract.KeyValueMatcher(
|
||||
key: key,
|
||||
regex: value.pattern(),
|
||||
regex: property.pattern(),
|
||||
regexType: regexType(property.clazz())
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -270,10 +305,12 @@ class ContractsToYaml {
|
||||
|
||||
protected void setOutputHeadersMatchers(Headers headers, List<YamlContract.TestHeaderMatcher> headerMatchers) {
|
||||
headers?.asTestSideMap()?.each { String key, Object value ->
|
||||
if (value instanceof Pattern) {
|
||||
if (value instanceof RegexProperty || value instanceof Pattern) {
|
||||
RegexProperty property = new RegexProperty(value)
|
||||
headerMatchers << new YamlContract.TestHeaderMatcher(
|
||||
key: key,
|
||||
regex: value.pattern(),
|
||||
regex: property.pattern(),
|
||||
regexType: regexType(property.clazz())
|
||||
)
|
||||
} else if (value instanceof ExecutionProperty) {
|
||||
headerMatchers << new YamlContract.TestHeaderMatcher(
|
||||
@@ -283,7 +320,7 @@ class ContractsToYaml {
|
||||
} else if (value instanceof NotToEscapePattern) {
|
||||
headerMatchers << new YamlContract.TestHeaderMatcher(
|
||||
key: key,
|
||||
regex: value.serverValue.pattern(),
|
||||
regex: ((Pattern) value.serverValue).pattern(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,6 +107,12 @@ class YamlContract {
|
||||
public PredefinedRegex predefined
|
||||
public Integer minOccurrence
|
||||
public Integer maxOccurrence
|
||||
public RegexType regexType
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
enum RegexType {
|
||||
as_integer, as_double, as_float, as_long, as_short, as_boolean, as_string
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
@@ -145,6 +151,7 @@ class YamlContract {
|
||||
public Integer minOccurrence
|
||||
public Integer maxOccurrence
|
||||
public PredefinedRegex predefined
|
||||
public RegexType regexType
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
@@ -155,6 +162,7 @@ class YamlContract {
|
||||
public String regex
|
||||
public PredefinedRegex predefined
|
||||
public String command
|
||||
public RegexType regexType
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
@@ -181,6 +189,7 @@ class YamlContract {
|
||||
public String regex
|
||||
public String command
|
||||
public PredefinedRegex predefined
|
||||
public RegexType regexType
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
@@ -191,6 +200,7 @@ class YamlContract {
|
||||
public String regex
|
||||
public String command
|
||||
public PredefinedRegex predefined
|
||||
public RegexType regexType
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
|
||||
@@ -535,35 +535,35 @@ class YamlToContracts {
|
||||
RegexPatterns patterns = new RegexPatterns()
|
||||
switch (predefinedRegex) {
|
||||
case YamlContract.PredefinedRegex.only_alpha_unicode:
|
||||
return patterns.onlyAlphaUnicode()
|
||||
return patterns.onlyAlphaUnicode().pattern
|
||||
case YamlContract.PredefinedRegex.number:
|
||||
return patterns.number()
|
||||
return patterns.number().pattern
|
||||
case YamlContract.PredefinedRegex.any_double:
|
||||
return patterns.aDouble()
|
||||
return patterns.aDouble().pattern
|
||||
case YamlContract.PredefinedRegex.any_boolean:
|
||||
return patterns.anyBoolean()
|
||||
return patterns.anyBoolean().pattern
|
||||
case YamlContract.PredefinedRegex.ip_address:
|
||||
return patterns.ipAddress()
|
||||
return patterns.ipAddress().pattern
|
||||
case YamlContract.PredefinedRegex.hostname:
|
||||
return patterns.hostname()
|
||||
return patterns.hostname().pattern
|
||||
case YamlContract.PredefinedRegex.email:
|
||||
return patterns.email()
|
||||
return patterns.email().pattern
|
||||
case YamlContract.PredefinedRegex.url:
|
||||
return patterns.url()
|
||||
return patterns.url().pattern
|
||||
case YamlContract.PredefinedRegex.uuid:
|
||||
return patterns.uuid()
|
||||
return patterns.uuid().pattern
|
||||
case YamlContract.PredefinedRegex.iso_date:
|
||||
return patterns.isoDate()
|
||||
return patterns.isoDate().pattern
|
||||
case YamlContract.PredefinedRegex.iso_date_time:
|
||||
return patterns.isoDateTime()
|
||||
return patterns.isoDateTime().pattern
|
||||
case YamlContract.PredefinedRegex.iso_time:
|
||||
return patterns.isoTime()
|
||||
return patterns.isoTime().pattern
|
||||
case YamlContract.PredefinedRegex.iso_8601_with_offset:
|
||||
return patterns.iso8601WithOffset()
|
||||
return patterns.iso8601WithOffset().pattern
|
||||
case YamlContract.PredefinedRegex.non_empty:
|
||||
return patterns.nonEmpty()
|
||||
return patterns.nonEmpty().pattern
|
||||
case YamlContract.PredefinedRegex.non_blank:
|
||||
return patterns.nonBlank()
|
||||
return patterns.nonBlank().pattern
|
||||
default:
|
||||
throw new UnsupportedOperationException("The predefined regex [" + predefinedRegex + "] is unsupported. Use on of " + YamlContract.PredefinedRegex.values())
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ import com.github.tomakehurst.wiremock.matching.StringValuePattern
|
||||
import com.github.tomakehurst.wiremock.matching.UrlPattern
|
||||
import groovy.json.JsonOutput
|
||||
import groovy.json.StringEscapeUtils
|
||||
import groovy.transform.CompileDynamic
|
||||
import groovy.transform.PackageScope
|
||||
import groovy.transform.TypeChecked
|
||||
import groovy.transform.TypeCheckingMode
|
||||
@@ -42,6 +41,7 @@ import org.springframework.cloud.contract.spec.internal.NamedProperty
|
||||
import org.springframework.cloud.contract.spec.internal.OptionalProperty
|
||||
import org.springframework.cloud.contract.spec.internal.QueryParameters
|
||||
import org.springframework.cloud.contract.spec.internal.RegexPatterns
|
||||
import org.springframework.cloud.contract.spec.internal.RegexProperty
|
||||
import org.springframework.cloud.contract.spec.internal.Request
|
||||
import org.springframework.cloud.contract.verifier.util.ContentType
|
||||
import org.springframework.cloud.contract.verifier.util.ContentUtils
|
||||
@@ -51,7 +51,6 @@ import org.springframework.cloud.contract.verifier.util.MapConverter
|
||||
|
||||
import static org.springframework.cloud.contract.verifier.util.RegexpBuilders.buildGStringRegexpForStubSide
|
||||
import static org.springframework.cloud.contract.verifier.util.RegexpBuilders.buildJSONRegexpMatch
|
||||
|
||||
/**
|
||||
* Converts a {@link Request} into {@link RequestPattern}
|
||||
*
|
||||
@@ -174,8 +173,8 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy {
|
||||
private UrlPattern urlPattern() {
|
||||
Object urlPath = urlPathOrUrlIfQueryPresent()
|
||||
if (urlPath) {
|
||||
if(urlPath instanceof Pattern) {
|
||||
return WireMock.urlPathMatching(getStubSideValue(urlPath.toString()) as String)
|
||||
if(urlPath instanceof Pattern || urlPath instanceof RegexProperty) {
|
||||
return WireMock.urlPathMatching(getStubSideValue(new RegexProperty(urlPath).pattern()) as String)
|
||||
} else {
|
||||
return WireMock.urlPathEqualTo(getStubSideValue(urlPath.toString()) as String)
|
||||
}
|
||||
@@ -184,8 +183,8 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy {
|
||||
throw new IllegalStateException("URL is required!")
|
||||
}
|
||||
Object url = getUrlIfGstring(request?.url?.clientValue)
|
||||
if (url instanceof Pattern) {
|
||||
return WireMock.urlMatching((url as Pattern).pattern())
|
||||
if (url instanceof Pattern || url instanceof RegexProperty) {
|
||||
return WireMock.urlMatching(new RegexProperty(url).pattern())
|
||||
}
|
||||
return WireMock.urlEqualTo(url.toString())
|
||||
}
|
||||
@@ -204,8 +203,12 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy {
|
||||
|
||||
private Object getUrlIfGstring(Object clientSide) {
|
||||
if (clientSide instanceof GString) {
|
||||
if (clientSide.values.any { getStubSideValue(it) instanceof Pattern }) {
|
||||
return Pattern.compile(getStubSideValue(clientSide).toString())
|
||||
if (clientSide.values.any {
|
||||
def value = getStubSideValue(it)
|
||||
return value instanceof Pattern || value instanceof RegexProperty
|
||||
}) {
|
||||
String string = getStubSideValue(clientSide).toString()
|
||||
return new RegexProperty(Pattern.compile(string))
|
||||
} else {
|
||||
return getStubSideValue(clientSide).toString()
|
||||
}
|
||||
@@ -224,8 +227,8 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy {
|
||||
private static ContentPattern convertToValuePattern(Object object, ContentType contentType) {
|
||||
switch (object) {
|
||||
case Pattern:
|
||||
Pattern value = object as Pattern
|
||||
return WireMock.matching(value.pattern())
|
||||
case RegexProperty:
|
||||
return WireMock.matching(new RegexProperty(object).pattern())
|
||||
case OptionalProperty:
|
||||
OptionalProperty value = object as OptionalProperty
|
||||
return WireMock.matching(value.optionalPattern())
|
||||
@@ -339,9 +342,8 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy {
|
||||
return containsPattern(map.entrySet())
|
||||
}
|
||||
|
||||
@CompileDynamic
|
||||
private boolean containsPattern(Collection collection) {
|
||||
return collection.collect(this.&containsPattern).inject('') { a, b -> a || b }
|
||||
return collection.collect(this.&containsPattern).inject(false) { a, b -> a || b }
|
||||
}
|
||||
|
||||
private boolean containsPattern(Object[] objects) {
|
||||
@@ -360,6 +362,10 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy {
|
||||
return true
|
||||
}
|
||||
|
||||
private boolean containsPattern(RegexProperty pattern) {
|
||||
return true
|
||||
}
|
||||
|
||||
private boolean containsPattern(Object o) {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -215,7 +215,7 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable {
|
||||
return readyToCheck;
|
||||
}
|
||||
|
||||
@Override public JsonVerifiable isInstanceOf(Class clazz)
|
||||
@Override public MethodBufferingJsonVerifiable isInstanceOf(Class clazz)
|
||||
throws IllegalStateException {
|
||||
DelegatingJsonVerifiable readyToCheck = new FinishedDelegatingJsonVerifiable(
|
||||
this.delegate.jsonPath(), this.delegate.isInstanceOf(clazz), this.methodsBuffer);
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.cloud.contract.verifier.util
|
||||
|
||||
import java.util.regex.Pattern
|
||||
|
||||
import com.jayway.jsonpath.DocumentContext
|
||||
import com.jayway.jsonpath.JsonPath
|
||||
import com.jayway.jsonpath.PathNotFoundException
|
||||
@@ -24,17 +26,15 @@ import groovy.json.JsonOutput
|
||||
import groovy.json.JsonSlurper
|
||||
import groovy.transform.CompileStatic
|
||||
import groovy.util.logging.Commons
|
||||
import org.apache.commons.lang3.StringEscapeUtils
|
||||
|
||||
import org.springframework.cloud.contract.spec.internal.BodyMatcher
|
||||
import org.springframework.cloud.contract.spec.internal.BodyMatchers
|
||||
import org.springframework.cloud.contract.spec.internal.ExecutionProperty
|
||||
import org.springframework.cloud.contract.spec.internal.MatchingType
|
||||
import org.springframework.cloud.contract.spec.internal.OptionalProperty
|
||||
import org.springframework.cloud.contract.spec.internal.RegexProperty
|
||||
import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties
|
||||
import org.springframework.util.SerializationUtils
|
||||
import repackaged.nl.flotsam.xeger.Xeger
|
||||
|
||||
import java.util.regex.Pattern
|
||||
/**
|
||||
* I would like to apologize to anyone who is reading this class. Since JSON is a hectic structure
|
||||
* this class is also hectic. The idea is to traverse the JSON structure and build a set of
|
||||
@@ -96,6 +96,18 @@ class JsonToJsonPathsConverter {
|
||||
return jsonCopy
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the value from JSON via json path
|
||||
*
|
||||
* @param json - parsed JSON
|
||||
* @param jsonPath - json path
|
||||
* @return matching part of the json
|
||||
*/
|
||||
static def readElement(def json, String jsonPath) {
|
||||
DocumentContext context = JsonPath.parse(json)
|
||||
return context.read(jsonPath)
|
||||
}
|
||||
|
||||
/**
|
||||
* Related to #391. The converted body looks different when done via the String notation than
|
||||
* it does when done via a map notation. When working with String body and when matchers
|
||||
@@ -169,8 +181,8 @@ class JsonToJsonPathsConverter {
|
||||
|
||||
@CompileStatic
|
||||
static Object generatedValueIfNeeded(Object value) {
|
||||
if (value instanceof Pattern) {
|
||||
return StringEscapeUtils.escapeJava(new Xeger(((Pattern) value).pattern()).generate())
|
||||
if (value instanceof RegexProperty) {
|
||||
return ((RegexProperty) value).generateAndEscapeJavaStringIfNeeded()
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
@@ -65,6 +65,9 @@ public interface MethodBufferingJsonVerifiable
|
||||
@Override
|
||||
MethodBufferingJsonVerifiable matches(String value);
|
||||
|
||||
@Override
|
||||
MethodBufferingJsonVerifiable isInstanceOf(Class clazz);
|
||||
|
||||
@Override
|
||||
MethodBufferingJsonVerifiable isEqualTo(Boolean value);
|
||||
|
||||
|
||||
@@ -1333,7 +1333,8 @@ DATA
|
||||
builder.appendTo(blockBuilder)
|
||||
def test = blockBuilder.toString()
|
||||
then:
|
||||
test.contains('''.cookie("cookie-key", "[A-Za-z]+")''')
|
||||
!test.contains('''.cookie("cookie-key", "[A-Za-z]+")''')
|
||||
test.contains('''.cookie("cookie-key", "''')
|
||||
test.contains('''assertThat(response.getCookies().get("cookie-key")).isNotNull();''')
|
||||
test.contains('''assertThat(response.getCookies().get("cookie-key").getValue()).matches("[A-Za-z]+");''')
|
||||
and:
|
||||
@@ -1376,7 +1377,8 @@ DATA
|
||||
builder.appendTo(blockBuilder)
|
||||
def test = blockBuilder.toString()
|
||||
then:
|
||||
test.contains('''.cookie('cookie-key', '[A-Za-z]+')''')
|
||||
!test.contains('''.cookie('cookie-key', '[A-Za-z]+')''')
|
||||
test.contains('''.cookie('cookie-key', ''')
|
||||
test.contains('''response.getCookies().get('cookie-key') != null''')
|
||||
test.contains('''response.getCookies().get('cookie-key').getValue() ==~ java.util.regex.Pattern.compile('[A-Za-z]+')''')
|
||||
and:
|
||||
|
||||
@@ -528,7 +528,7 @@ DocumentContext parsedJson = JsonPath.parse(json);
|
||||
body(
|
||||
[
|
||||
"name" : $(consumer(~/.+/), producer('string-1')),
|
||||
"updatedTs" : $(consumer(~/\d{13}/), producer(1531916906000L)),
|
||||
"updatedTs" : $(consumer(regex(~/1531916906000/).asLong())),
|
||||
"isDisabled": $(consumer(regex(anyBoolean())), producer(true))
|
||||
]
|
||||
)
|
||||
@@ -557,6 +557,7 @@ DocumentContext parsedJson = JsonPath.parse(json);
|
||||
String test = blockBuilder.toString()
|
||||
SyntaxChecker.tryToCompileWithoutCompileStatic(methodBuilderName, test)
|
||||
test.contains('''assertThatJson(parsedJson).field("['updatedTs']").isEqualTo(1531916906000L)''')
|
||||
!test.contains('''"updatedTs":"1531916906000"''')
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
|
||||
@@ -62,12 +62,12 @@ class MockMvcMethodBodyBuilderWithMatchersSpec extends Specification implements
|
||||
]
|
||||
])
|
||||
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())
|
||||
@@ -111,18 +111,18 @@ class MockMvcMethodBodyBuilderWithMatchersSpec extends Specification implements
|
||||
])
|
||||
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())
|
||||
|
||||
@@ -2794,7 +2794,8 @@ DocumentContext parsedJson = JsonPath.parse(json);
|
||||
builder.appendTo(blockBuilder)
|
||||
def test = blockBuilder.toString()
|
||||
then:
|
||||
test.contains('''.cookie("cookie-key", "[A-Za-z]+")''')
|
||||
!test.contains('''.cookie("cookie-key", "[A-Za-z]+")''')
|
||||
test.contains('''.cookie("cookie-key", "''')
|
||||
test.contains('''assertThat(response.getCookie("cookie-key")).isNotNull();''')
|
||||
test.contains('''assertThat(response.getCookie("cookie-key")).matches("[A-Za-z]+");''')
|
||||
and:
|
||||
@@ -2845,7 +2846,8 @@ DocumentContext parsedJson = JsonPath.parse(json);
|
||||
builder.appendTo(blockBuilder)
|
||||
def test = blockBuilder.toString()
|
||||
then:
|
||||
test.contains('''.cookie("cookie-key", "[A-Za-z]+")''')
|
||||
!test.contains('''.cookie("cookie-key", "[A-Za-z]+")''')
|
||||
test.contains('''.cookie("cookie-key", "''')
|
||||
test.contains('''response.cookie('cookie-key') != null''')
|
||||
test.contains('''response.cookie('cookie-key') ==~ java.util.regex.Pattern.compile('[A-Za-z]+')''')
|
||||
and:
|
||||
|
||||
@@ -540,6 +540,7 @@ response:
|
||||
- path: $.property2
|
||||
type: by_regex
|
||||
value: "[0-9]{3}"
|
||||
regexType: as_integer
|
||||
'''
|
||||
Contract contractDsl = fromYaml(contract)
|
||||
MethodBodyBuilder builder = methodBuilder(contractDsl)
|
||||
@@ -929,10 +930,12 @@ request:
|
||||
headers:
|
||||
- key: 'Content-Type'
|
||||
regex: 'application/json.*'
|
||||
regexType: as_string
|
||||
body:
|
||||
- path: $.first_name
|
||||
type: by_regex
|
||||
value: '[\\p{L}]*'
|
||||
regexType: as_string
|
||||
- path: $.last_name
|
||||
type: by_regex
|
||||
value: '[\\p{L}]*'
|
||||
@@ -1127,8 +1130,10 @@ request:
|
||||
params:
|
||||
- key: formParameter
|
||||
regex: ".+"
|
||||
regexType: as_string
|
||||
- key: someBooleanParameter
|
||||
predefined: any_boolean
|
||||
regexType: as_boolean
|
||||
named:
|
||||
- paramName: file
|
||||
fileName:
|
||||
@@ -1191,6 +1196,7 @@ response:
|
||||
- path: $.authorities[0]
|
||||
type: by_regex
|
||||
value: '^[a-zA-Z0-9_\\- ]+$'
|
||||
regexType: as_string
|
||||
'''
|
||||
Contract contractDsl = fromYaml(contract)
|
||||
MethodBodyBuilder builder = new HttpSpockMethodRequestProcessingBodyBuilder(contractDsl, properties, generatedClassDataForMethod)
|
||||
|
||||
@@ -33,7 +33,6 @@ import org.springframework.cloud.contract.spec.internal.RegexPatterns
|
||||
import org.springframework.cloud.contract.spec.internal.Url
|
||||
import org.springframework.cloud.contract.verifier.util.ContractVerifierDslConverter
|
||||
import org.springframework.cloud.contract.verifier.util.MapConverter
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
* @author Tim Ysewyn
|
||||
@@ -125,7 +124,7 @@ class YamlContractConverterSpec extends Specification {
|
||||
contract.request.body.clientValue == [foo: "bar"]
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[0].path() == '$.foo'
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[0].matchingType() == MatchingType.REGEX
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[0].value() == 'bar'
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[0].value().pattern() == 'bar'
|
||||
and:
|
||||
contract.response.status.clientValue == 200
|
||||
if (yamlFile == ymlWithRest) contract.response.delay.clientValue == 1000 else !contract.response.delay
|
||||
@@ -138,7 +137,7 @@ class YamlContractConverterSpec extends Specification {
|
||||
contract.response.body.clientValue == [foo2: "bar", foo3: "baz", nullValue: null]
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[0].path() == '$.foo2'
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[0].matchingType() == MatchingType.REGEX
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[0].value() == 'bar'
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[0].value().pattern() == 'bar'
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[1].path() == '$.foo3'
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[1].matchingType() == MatchingType.COMMAND
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[1].value() == new ExecutionProperty('executeMe($it)')
|
||||
@@ -217,29 +216,29 @@ class YamlContractConverterSpec extends Specification {
|
||||
MatchingStrategy.Type.ABSENT, null)
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[0].path() == '$.duck'
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[0].matchingType() == MatchingType.REGEX
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[0].value() == '[0-9]{3}'
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[0].value().pattern() == '[0-9]{3}'
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[1].path() == '$.duck'
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[1].matchingType() == MatchingType.EQUALITY
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[2].path() == '$.alpha'
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[2].matchingType() == MatchingType.REGEX
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[2].value() == patterns.onlyAlphaUnicode().pattern()
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[2].value().pattern() == patterns.onlyAlphaUnicode().pattern()
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[3].path() == '$.alpha'
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[3].matchingType() == MatchingType.EQUALITY
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[4].path() == '$.number'
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[4].matchingType() == MatchingType.REGEX
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[4].value() == patterns.number().pattern()
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[4].value().pattern() == patterns.number().pattern()
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[5].path() == '$.aBoolean'
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[5].matchingType() == MatchingType.REGEX
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[5].value() == patterns.anyBoolean().pattern()
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[5].value().pattern() == patterns.anyBoolean().pattern()
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[6].path() == '$.date'
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[6].matchingType() == MatchingType.DATE
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[6].value() == patterns.isoDate()
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[6].value().pattern() == patterns.isoDate().pattern()
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[7].path() == '$.dateTime'
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[7].matchingType() == MatchingType.TIMESTAMP
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[7].value() == patterns.isoDateTime()
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[7].value().pattern() == patterns.isoDateTime().pattern()
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[8].path() == '$.time'
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[8].matchingType() == MatchingType.TIME
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[8].value() == patterns.isoTime()
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[8].value().pattern() == patterns.isoTime().pattern()
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[9].path() == "\$.['key'].['complex.key']"
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[9].matchingType() == MatchingType.EQUALITY
|
||||
contract.request.bodyMatchers.jsonPathRegexMatchers[10].path() == '$.valueWithMin'
|
||||
@@ -258,29 +257,29 @@ class YamlContractConverterSpec extends Specification {
|
||||
contract.response.status.clientValue == 200
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[0].path() == '$.duck'
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[0].matchingType() == MatchingType.REGEX
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[0].value() == '[0-9]{3}'
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[0].value().pattern() == '[0-9]{3}'
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[1].path() == '$.duck'
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[1].matchingType() == MatchingType.EQUALITY
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[2].path() == '$.alpha'
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[2].matchingType() == MatchingType.REGEX
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[2].value() == patterns.onlyAlphaUnicode().pattern()
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[2].value().pattern() == patterns.onlyAlphaUnicode().pattern()
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[3].path() == '$.alpha'
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[3].matchingType() == MatchingType.EQUALITY
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[4].path() == '$.number'
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[4].matchingType() == MatchingType.REGEX
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[4].value() == patterns.number().pattern()
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[4].value().pattern() == patterns.number().pattern()
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[5].path() == '$.aBoolean'
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[5].matchingType() == MatchingType.REGEX
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[5].value() == patterns.anyBoolean().pattern()
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[5].value().pattern() == patterns.anyBoolean().pattern()
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[6].path() == '$.date'
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[6].matchingType() == MatchingType.DATE
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[6].value() == patterns.isoDate()
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[6].value().pattern() == patterns.isoDate().pattern()
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[7].path() == '$.dateTime'
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[7].matchingType() == MatchingType.TIMESTAMP
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[7].value() == patterns.isoDateTime()
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[7].value().pattern() == patterns.isoDateTime().pattern()
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[8].path() == '$.time'
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[8].matchingType() == MatchingType.TIME
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[8].value() == patterns.isoTime()
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[8].value().pattern() == patterns.isoTime().pattern()
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[9].path() == '$.valueWithTypeMatch'
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[9].matchingType() == MatchingType.TYPE
|
||||
contract.response.bodyMatchers.jsonPathRegexMatchers[10].path() == '$.valueWithMin'
|
||||
@@ -329,57 +328,57 @@ class YamlContractConverterSpec extends Specification {
|
||||
((Pattern) it.clientValue).pattern == "application/json.*" && it.serverValue == "application/json" }
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[0].path() == '$.duck'
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[0].matchingType() == MatchingType.REGEX
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[0].value() == '[0-9]{3}'
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[0].value().pattern() == '[0-9]{3}'
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[1].path() == '$.duck'
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[1].matchingType() == MatchingType.EQUALITY
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[2].path() == '$.alpha'
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[2].matchingType() == MatchingType.REGEX
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[2].value() == patterns.onlyAlphaUnicode().pattern()
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[2].value().pattern() == patterns.onlyAlphaUnicode().pattern()
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[3].path() == '$.alpha'
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[3].matchingType() == MatchingType.EQUALITY
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[4].path() == '$.number'
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[4].matchingType() == MatchingType.REGEX
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[4].value() == patterns.number().pattern()
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[4].value().pattern() == patterns.number().pattern()
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[5].path() == '$.aBoolean'
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[5].matchingType() == MatchingType.REGEX
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[5].value() == patterns.anyBoolean().pattern()
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[5].value().pattern() == patterns.anyBoolean().pattern()
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[6].path() == '$.date'
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[6].matchingType() == MatchingType.DATE
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[6].value() == patterns.isoDate()
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[6].value().pattern() == patterns.isoDate().pattern()
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[7].path() == '$.dateTime'
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[7].matchingType() == MatchingType.TIMESTAMP
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[7].value() == patterns.isoDateTime()
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[7].value().pattern() == patterns.isoDateTime().pattern()
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[8].path() == '$.time'
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[8].matchingType() == MatchingType.TIME
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[8].value() == patterns.isoTime()
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[8].value().pattern() == patterns.isoTime().pattern()
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[9].path() == "\$.['key'].['complex.key']"
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[9].matchingType() == MatchingType.EQUALITY
|
||||
and:
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[0].path() == '$.duck'
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[0].matchingType() == MatchingType.REGEX
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[0].value() == '[0-9]{3}'
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[0].value().pattern() == '[0-9]{3}'
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[1].path() == '$.duck'
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[1].matchingType() == MatchingType.EQUALITY
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[2].path() == '$.alpha'
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[2].matchingType() == MatchingType.REGEX
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[2].value() == patterns.onlyAlphaUnicode().pattern()
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[2].value().pattern() == patterns.onlyAlphaUnicode().pattern()
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[3].path() == '$.alpha'
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[3].matchingType() == MatchingType.EQUALITY
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[4].path() == '$.number'
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[4].matchingType() == MatchingType.REGEX
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[4].value() == patterns.number().pattern()
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[4].value().pattern() == patterns.number().pattern()
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[5].path() == '$.aBoolean'
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[5].matchingType() == MatchingType.REGEX
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[5].value() == patterns.anyBoolean().pattern()
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[5].value().pattern() == patterns.anyBoolean().pattern()
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[6].path() == '$.date'
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[6].matchingType() == MatchingType.DATE
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[6].value() == patterns.isoDate()
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[6].value().pattern() == patterns.isoDate().pattern()
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[7].path() == '$.dateTime'
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[7].matchingType() == MatchingType.TIMESTAMP
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[7].value() == patterns.isoDateTime()
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[7].value().pattern() == patterns.isoDateTime().pattern()
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[8].path() == '$.time'
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[8].matchingType() == MatchingType.TIME
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[8].value() == patterns.isoTime()
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[8].value().pattern() == patterns.isoTime().pattern()
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[9].path() == '$.valueWithTypeMatch'
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[9].matchingType() == MatchingType.TYPE
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[10].path() == '$.valueWithMin'
|
||||
@@ -462,7 +461,7 @@ class YamlContractConverterSpec extends Specification {
|
||||
contract.input.messageBody.clientValue == [foo: "bar"]
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[0].path() == '$.bar'
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[0].matchingType() == MatchingType.REGEX
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[0].value() == 'bar'
|
||||
contract.input.bodyMatchers.jsonPathRegexMatchers[0].value().pattern() == 'bar'
|
||||
and:
|
||||
contract.outputMessage.assertThat.toString() == "baz()"
|
||||
contract.outputMessage.headers.entries.find { it.name == "foo2" &&
|
||||
@@ -474,7 +473,7 @@ class YamlContractConverterSpec extends Specification {
|
||||
contract.outputMessage.body.clientValue == [foo2: "bar", foo3: "baz"]
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[0].path() == '$.foo2'
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[0].matchingType() == MatchingType.REGEX
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[0].value() == 'bar'
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[0].value().pattern() == 'bar'
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[1].path() == '$.foo3'
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[1].matchingType() == MatchingType.COMMAND
|
||||
contract.outputMessage.bodyMatchers.jsonPathRegexMatchers[1].value() == new ExecutionProperty('executeMe($it)')
|
||||
|
||||
@@ -906,7 +906,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
|
||||
stubMappingIsValidWireMockStub(json)
|
||||
}
|
||||
|
||||
def "should not allow regexp in url for server value"() {
|
||||
def "should not allow not matching query param for server value"() {
|
||||
when:
|
||||
org.springframework.cloud.contract.spec.Contract.make {
|
||||
request {
|
||||
@@ -924,7 +924,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie
|
||||
}
|
||||
then:
|
||||
def e = thrown(IllegalStateException)
|
||||
e.message.contains "Url can't be a pattern for the server side"
|
||||
e.message.contains "Query parameter 'age' can't be of a matching type: NOT_MATCHING for the server side"
|
||||
}
|
||||
|
||||
def "should not allow regexp in query parameter for server value"() {
|
||||
|
||||
Reference in New Issue
Block a user