From d2fe5f6bee45acadd895a18bb9463f1eac06fe8e Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 6 Nov 2019 14:09:38 +0100 Subject: [PATCH] Ensures that non java.lang classes have a fqn class reference without this change BigDecimal wasn't properly imported in the assertion. Also, even if it would, assertj has a string comparison of the big decimal value with this change we're providing a fqn class for non java.lang classes and for BigDecimal comparison we're using the String [isEqualTo] method fixes gh-1139 --- .../JsonBodyVerificationBuilder.groovy | 17 +++++-- .../SpringTestMethodBodyBuildersSpec.groovy | 48 ++++++++++++++++++- 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JsonBodyVerificationBuilder.groovy b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JsonBodyVerificationBuilder.groovy index f316a7267b..9a5905f1dd 100644 --- a/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JsonBodyVerificationBuilder.groovy +++ b/spring-cloud-contract-verifier/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JsonBodyVerificationBuilder.groovy @@ -159,16 +159,27 @@ class JsonBodyVerificationBuilder implements BodyMethodGeneration, ClassVerifier else { String comparisonMethod = bodyMatcher. matchingType() == MatchingType.EQUALITY ? "isEqualTo" : "matches" - String classToCastTo = "${retrievedValue.class.simpleName}.class" + String classToCastTo = "${className(retrievedValue)}" + ".class" String method = "assertThat(parsedJson.read(${path}, ${classToCastTo})).${comparisonMethod}(${valueAsParam})" bb.addLine(postProcessJsonPathCall(method)) } addColonIfRequired(lineSuffix, bb) } + private String className(Object retrievedValue) { + return retrievedValue.class.name.startsWith("java.lang") ? + retrievedValue.class.simpleName : retrievedValue.class.name + } + private String objectToString(Object value) { - return value instanceof Long - ? String.valueOf(value).concat("L") : String.valueOf(value) + if (value instanceof Long) { + return String.valueOf(value).concat("L") + } else if (value instanceof Double) { + return String.valueOf(value).concat("D") + } else if (value instanceof BigDecimal) { + return quotedAndEscaped(value.toString()) + } + return String.valueOf(value) } protected String processIfTemplateIsPresent(String method, DocumentContext parsedRequestBody) { diff --git a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SpringTestMethodBodyBuildersSpec.groovy b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SpringTestMethodBodyBuildersSpec.groovy index d2b1456b71..9d85ceb17e 100644 --- a/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SpringTestMethodBodyBuildersSpec.groovy +++ b/spring-cloud-contract-verifier/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SpringTestMethodBodyBuildersSpec.groovy @@ -30,7 +30,6 @@ import org.springframework.cloud.contract.spec.Contract import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties import org.springframework.cloud.contract.verifier.dsl.wiremock.WireMockStubVerifier import org.springframework.cloud.contract.verifier.util.SyntaxChecker - /** * @author Jakub Kubrynski, codearte.io * @author Tim Ysewyn @@ -2917,4 +2916,51 @@ DocumentContext parsedJson = JsonPath.parse(json); JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties, generatedClassDataForMethod) } WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties, generatedClassDataForMethod) } } + + @Issue('#1139') + def 'should have a big decimal import for [#methodBuilderName]'() { + given: + Contract contractDsl = Contract.make { + request { + method 'POST' + url '/crystals/create' + headers { + header 'Content-Type' : 'application/json' + } + body( + amount: 200 + ) + bodyMatchers { + jsonPath('$.amount', byRegex('^[0-9]{1,3}$')) + } + } + response { + status 201 + body( + amount: fromRequest().body('$.amount'), + price: 10100.0 + ) + bodyMatchers { + jsonPath('$.amount', byRegex('^\\d*$')) + jsonPath('$.price', byEquality()) + } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + and: + builder.appendTo(blockBuilder) + String test = blockBuilder.toString() + when: + SyntaxChecker.tryToRun(methodBuilderName, test.join("\n")) + then: + test.contains('''$.price", java.math.BigDecimal.class)).isEqualTo("10100.0")''') + where: + methodBuilderName | methodBuilder + HttpSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new HttpSpockMethodRequestProcessingBodyBuilder(dsl, properties, generatedClassDataForMethod) } + MockMvcJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties, generatedClassDataForMethod) } + JaxRsClientSpockMethodRequestProcessingBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties, generatedClassDataForMethod) } + JaxRsClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties, generatedClassDataForMethod) } + WebTestClientJUnitMethodBodyBuilder.simpleName | { Contract dsl -> new WebTestClientJUnitMethodBodyBuilder(dsl, properties, generatedClassDataForMethod) } + } }