From f70c1dbfdda7010e61894c6afd9eae0c70e992f9 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 21 Mar 2018 10:54:24 +0100 Subject: [PATCH] Added support for patterns inside GStrings in URL related to gh-589 fixes gh-588 --- .../cloud/contract/spec/internal/Url.groovy | 23 ++++++++++++- .../builder/MethodBodyBuilderSpec.groovy | 33 +++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Url.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Url.groovy index e94d952a7a..be464280a2 100644 --- a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Url.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Url.groovy @@ -16,9 +16,13 @@ package org.springframework.cloud.contract.spec.internal +import java.util.regex.Pattern + import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode import groovy.transform.ToString +import org.codehaus.groovy.runtime.GStringImpl +import repackaged.nl.flotsam.xeger.Xeger import static org.springframework.cloud.contract.spec.util.ValidateUtils.validateServerValueIsAvailable @@ -40,10 +44,27 @@ class Url extends DslProperty { } Url(Object url) { - super(url) + super(url, testUrl(url)) validateServerValueIsAvailable(url, "Url") } + private static Object testUrl(Object url) { + if (url instanceof GString) { + boolean anyPattern = url.values.any { it instanceof Pattern } + if (!anyPattern) { + return url + } + String newUrl = new GStringImpl( + url.values.collect { it instanceof Pattern ? + new Xeger(it.pattern()).generate() : it + } as String[], + url.strings.clone() as String[] + ).toString() + return new Url(newUrl) + } + return url + } + void queryParameters(@DelegatesTo(QueryParameters) Closure closure) { this.queryParameters = new QueryParameters() closure.delegate = queryParameters diff --git a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilderSpec.groovy b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilderSpec.groovy index 7c8d31a9de..dcb113d825 100644 --- a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilderSpec.groovy +++ b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilderSpec.groovy @@ -108,6 +108,39 @@ DocumentContext parsedJson = JsonPath.parse(json); "JaxRsClientJUnitMethodBodyBuilder" | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } } + @Issue('#588') + def "should work patterns in GString [#methodBuilderName]"() { + given: + Contract contractDsl = Contract.make { + request { + method GET() + url("/${regex('\\d+')}") + } + response { + status 200 + body([ + ok: true + ]) + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + !test.contains('d+') + !test.contains('REGEXP>>') + and: + SyntaxChecker.tryToCompile(methodBuilderName, blockBuilder.toString()) + where: + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "JaxRsClientJUnitMethodBodyBuilder" | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } + } + @Issue('#269') def "should work with execute and keys with dots [#methodBuilderName]"() { given: