Fixed missing support for predefined matchers for messages; fixes #604

This commit is contained in:
Marcin Grzejszczak
2018-04-03 20:58:10 +02:00
parent 8c87ed16bf
commit 7652bcff48
3 changed files with 227 additions and 2 deletions

View File

@@ -280,7 +280,11 @@ class YamlContractConverter implements ContractConverter<List<YamlContract>> {
value = byTimestamp()
break
case StubMatcherType.by_regex:
value = byRegex(matcher.value)
String regex = matcher.value
if (matcher.predefined) {
regex = predefinedToPattern(matcher.predefined).pattern()
}
value = byRegex(regex)
break
case StubMatcherType.by_equality:
value = byEquality()
@@ -320,7 +324,11 @@ class YamlContractConverter implements ContractConverter<List<YamlContract>> {
value = byTimestamp()
break
case TestMatcherType.by_regex:
value = byRegex(testMatcher.value)
String regex = testMatcher.value
if (testMatcher.predefined) {
regex = predefinedToPattern(testMatcher.predefined).pattern()
}
value = byRegex(regex)
break
case TestMatcherType.by_equality:
value = byEquality()

View File

@@ -16,6 +16,8 @@
package org.springframework.cloud.contract.verifier.converter
import spock.lang.Issue
import java.util.regex.Pattern
import spock.lang.Shared
@@ -54,6 +56,8 @@ class YamlContractConverterSpec extends Specification {
File ymlMatchers = new File(ymlMatchersFile.toURI())
URL ymlMultipleFile = YamlContractConverterSpec.getResource("/yml/multiple_contracts.yml")
File ymlMultiple = new File(ymlMultipleFile.toURI())
URL ymlMessagingMatchersFile = YamlContractConverterSpec.getResource("/yml/contract_message_matchers.yml")
File ymlMessagingMatchers = new File(ymlMessagingMatchersFile.toURI())
YamlContractConverter converter = new YamlContractConverter()
def "should convert YAML with REST to DSL for [#yamlFile]"() {
@@ -228,6 +232,94 @@ class YamlContractConverterSpec extends Specification {
contract.response.matchers.jsonPathRegexMatchers[15].value() == new ExecutionProperty('assertThatValueIsANumber($it)')
}
@Issue("#604")
def "should convert YAML with Message matchers to DSL"() {
given:
assert converter.isAccepted(ymlMessagingMatchers)
when:
Collection<Contract> contracts = converter.convertFrom(ymlMessagingMatchers)
then:
contracts.size() == 1
Contract contract = contracts.first()
RegexPatterns patterns = new RegexPatterns()
contract.input.messageHeaders.entries.find { it.name == "contentType" &&
((Pattern) it.clientValue).pattern == "application/json.*" && it.serverValue == "application/json" }
contract.input.matchers.jsonPathRegexMatchers[0].path() == '$.duck'
contract.input.matchers.jsonPathRegexMatchers[0].matchingType() == MatchingType.REGEX
contract.input.matchers.jsonPathRegexMatchers[0].value() == '[0-9]{3}'
contract.input.matchers.jsonPathRegexMatchers[1].path() == '$.duck'
contract.input.matchers.jsonPathRegexMatchers[1].matchingType() == MatchingType.EQUALITY
contract.input.matchers.jsonPathRegexMatchers[2].path() == '$.alpha'
contract.input.matchers.jsonPathRegexMatchers[2].matchingType() == MatchingType.REGEX
contract.input.matchers.jsonPathRegexMatchers[2].value() == patterns.onlyAlphaUnicode()
contract.input.matchers.jsonPathRegexMatchers[3].path() == '$.alpha'
contract.input.matchers.jsonPathRegexMatchers[3].matchingType() == MatchingType.EQUALITY
contract.input.matchers.jsonPathRegexMatchers[4].path() == '$.number'
contract.input.matchers.jsonPathRegexMatchers[4].matchingType() == MatchingType.REGEX
contract.input.matchers.jsonPathRegexMatchers[4].value() == patterns.number()
contract.input.matchers.jsonPathRegexMatchers[5].path() == '$.aBoolean'
contract.input.matchers.jsonPathRegexMatchers[5].matchingType() == MatchingType.REGEX
contract.input.matchers.jsonPathRegexMatchers[5].value() == patterns.anyBoolean()
contract.input.matchers.jsonPathRegexMatchers[6].path() == '$.date'
contract.input.matchers.jsonPathRegexMatchers[6].matchingType() == MatchingType.DATE
contract.input.matchers.jsonPathRegexMatchers[6].value() == patterns.isoDate()
contract.input.matchers.jsonPathRegexMatchers[7].path() == '$.dateTime'
contract.input.matchers.jsonPathRegexMatchers[7].matchingType() == MatchingType.TIMESTAMP
contract.input.matchers.jsonPathRegexMatchers[7].value() == patterns.isoDateTime()
contract.input.matchers.jsonPathRegexMatchers[8].path() == '$.time'
contract.input.matchers.jsonPathRegexMatchers[8].matchingType() == MatchingType.TIME
contract.input.matchers.jsonPathRegexMatchers[8].value() == patterns.isoTime()
contract.input.matchers.jsonPathRegexMatchers[9].path() == "\$.['key'].['complex.key']"
contract.input.matchers.jsonPathRegexMatchers[9].matchingType() == MatchingType.EQUALITY
and:
contract.outputMessage.matchers.jsonPathRegexMatchers[0].path() == '$.duck'
contract.outputMessage.matchers.jsonPathRegexMatchers[0].matchingType() == MatchingType.REGEX
contract.outputMessage.matchers.jsonPathRegexMatchers[0].value() == '[0-9]{3}'
contract.outputMessage.matchers.jsonPathRegexMatchers[1].path() == '$.duck'
contract.outputMessage.matchers.jsonPathRegexMatchers[1].matchingType() == MatchingType.EQUALITY
contract.outputMessage.matchers.jsonPathRegexMatchers[2].path() == '$.alpha'
contract.outputMessage.matchers.jsonPathRegexMatchers[2].matchingType() == MatchingType.REGEX
contract.outputMessage.matchers.jsonPathRegexMatchers[2].value() == patterns.onlyAlphaUnicode()
contract.outputMessage.matchers.jsonPathRegexMatchers[3].path() == '$.alpha'
contract.outputMessage.matchers.jsonPathRegexMatchers[3].matchingType() == MatchingType.EQUALITY
contract.outputMessage.matchers.jsonPathRegexMatchers[4].path() == '$.number'
contract.outputMessage.matchers.jsonPathRegexMatchers[4].matchingType() == MatchingType.REGEX
contract.outputMessage.matchers.jsonPathRegexMatchers[4].value() == patterns.number()
contract.outputMessage.matchers.jsonPathRegexMatchers[5].path() == '$.aBoolean'
contract.outputMessage.matchers.jsonPathRegexMatchers[5].matchingType() == MatchingType.REGEX
contract.outputMessage.matchers.jsonPathRegexMatchers[5].value() == patterns.anyBoolean()
contract.outputMessage.matchers.jsonPathRegexMatchers[6].path() == '$.date'
contract.outputMessage.matchers.jsonPathRegexMatchers[6].matchingType() == MatchingType.DATE
contract.outputMessage.matchers.jsonPathRegexMatchers[6].value() == patterns.isoDate()
contract.outputMessage.matchers.jsonPathRegexMatchers[7].path() == '$.dateTime'
contract.outputMessage.matchers.jsonPathRegexMatchers[7].matchingType() == MatchingType.TIMESTAMP
contract.outputMessage.matchers.jsonPathRegexMatchers[7].value() == patterns.isoDateTime()
contract.outputMessage.matchers.jsonPathRegexMatchers[8].path() == '$.time'
contract.outputMessage.matchers.jsonPathRegexMatchers[8].matchingType() == MatchingType.TIME
contract.outputMessage.matchers.jsonPathRegexMatchers[8].value() == patterns.isoTime()
contract.outputMessage.matchers.jsonPathRegexMatchers[9].path() == '$.valueWithTypeMatch'
contract.outputMessage.matchers.jsonPathRegexMatchers[9].matchingType() == MatchingType.TYPE
contract.outputMessage.matchers.jsonPathRegexMatchers[10].path() == '$.valueWithMin'
contract.outputMessage.matchers.jsonPathRegexMatchers[10].matchingType() == MatchingType.TYPE
contract.outputMessage.matchers.jsonPathRegexMatchers[10].minTypeOccurrence() == 1
contract.outputMessage.matchers.jsonPathRegexMatchers[11].path() == '$.valueWithMax'
contract.outputMessage.matchers.jsonPathRegexMatchers[11].matchingType() == MatchingType.TYPE
contract.outputMessage.matchers.jsonPathRegexMatchers[11].maxTypeOccurrence() == 3
contract.outputMessage.matchers.jsonPathRegexMatchers[12].path() == '$.valueWithMinMax'
contract.outputMessage.matchers.jsonPathRegexMatchers[12].matchingType() == MatchingType.TYPE
contract.outputMessage.matchers.jsonPathRegexMatchers[12].minTypeOccurrence() == 1
contract.outputMessage.matchers.jsonPathRegexMatchers[12].maxTypeOccurrence() == 3
contract.outputMessage.matchers.jsonPathRegexMatchers[13].path() == '$.valueWithMinEmpty'
contract.outputMessage.matchers.jsonPathRegexMatchers[13].matchingType() == MatchingType.TYPE
contract.outputMessage.matchers.jsonPathRegexMatchers[13].minTypeOccurrence() == 0
contract.outputMessage.matchers.jsonPathRegexMatchers[14].path() == '$.valueWithMaxEmpty'
contract.outputMessage.matchers.jsonPathRegexMatchers[14].matchingType() == MatchingType.TYPE
contract.outputMessage.matchers.jsonPathRegexMatchers[14].maxTypeOccurrence() == 0
contract.outputMessage.matchers.jsonPathRegexMatchers[15].path() == '$.duck'
contract.outputMessage.matchers.jsonPathRegexMatchers[15].matchingType() == MatchingType.COMMAND
contract.outputMessage.matchers.jsonPathRegexMatchers[15].value() == new ExecutionProperty('assertThatValueIsANumber($it)')
}
def "should convert YAML with REST with response from request"() {
given:
assert converter.isAccepted(ymlBody)

View File

@@ -0,0 +1,125 @@
label: card_rejected
input:
messageFrom: input
messageBody:
duck: 123
alpha: "abc"
number: 123
aBoolean: true
date: "2017-01-01"
dateTime: "2017-01-01T01:23:45"
time: "01:02:34"
valueWithoutAMatcher: "foo"
valueWithTypeMatch: "string"
key:
"complex.key": 'foo'
messageHeaders:
sample: 'header'
contentType: application/json
matchers:
headers:
- key: contentType
regex: "application/json.*"
body:
- path: $.duck
type: by_regex
value: "[0-9]{3}"
- path: $.duck
type: by_equality
- path: $.alpha
type: by_regex
predefined: only_alpha_unicode
- path: $.alpha
type: by_equality
- path: $.number
type: by_regex
predefined: number
- path: $.aBoolean
type: by_regex
predefined: any_boolean
- path: $.date
type: by_date
- path: $.dateTime
type: by_timestamp
- path: $.time
type: by_time
- path: "$.['key'].['complex.key']"
type: by_equality
outputMessage:
sentTo: channel
body:
duck: 123
alpha: "abc"
number: 123
aBoolean: true
date: "2017-01-01"
dateTime: "2017-01-01T01:23:45"
time: "01:02:34"
valueWithoutAMatcher: "foo"
valueWithTypeMatch: "string"
valueWithMin:
- 1
- 2
- 3
valueWithMax:
- 1
- 2
- 3
valueWithMinMax:
- 1
- 2
- 3
valueWithMinEmpty: []
valueWithMaxEmpty: []
key:
'complex.key' : 'foo'
matchers:
headers:
- key: Content-Type
regex: "application/json.*"
body:
- path: $.duck
type: by_regex
value: "[0-9]{3}"
- path: $.duck
type: by_equality
- path: $.alpha
type: by_regex
predefined: only_alpha_unicode
- path: $.alpha
type: by_equality
- path: $.number
type: by_regex
predefined: number
- path: $.aBoolean
type: by_regex
predefined: any_boolean
- path: $.date
type: by_date
- path: $.dateTime
type: by_timestamp
- path: $.time
type: by_time
- path: $.valueWithTypeMatch
type: by_type
- path: $.valueWithMin
type: by_type
minOccurrence: 1
- path: $.valueWithMax
type: by_type
maxOccurrence: 3
- path: $.valueWithMinMax
type: by_type
minOccurrence: 1
maxOccurrence: 3
- path: $.valueWithMinEmpty
type: by_type
minOccurrence: 0
- path: $.valueWithMaxEmpty
type: by_type
maxOccurrence: 0
- path: $.duck
type: by_command
value: assertThatValueIsANumber($it)
headers:
contentType: application/json