From 428dcf19d2eee46b71296fa2ececa9298908ac1a Mon Sep 17 00:00:00 2001 From: Alexander-Miller Date: Fri, 8 Oct 2021 11:22:58 +0200 Subject: [PATCH] Fix kotlin spec contracts not falling back on the file name when no name is set. (#1719) Fallback rules are implemented analogous to the ContractVerifierDslConverter. Co-authored-by: Sebastian Letzel Co-authored-by: Stefan Ludwig Co-authored-by: Sebastian Letzel Co-authored-by: Stefan Ludwig --- .../spec/internal/KotlinContractConverter.kt | 22 +++++++++++- .../cloud/contract/spec/ContractTests.kt | 25 ++++++++++++++ .../resources/contracts/unnamed_multiple.kts | 34 +++++++++++++++++++ .../resources/contracts/unnamed_single.kts | 26 ++++++++++++++ 4 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 specs/spring-cloud-contract-spec-kotlin/src/test/resources/contracts/unnamed_multiple.kts create mode 100644 specs/spring-cloud-contract-spec-kotlin/src/test/resources/contracts/unnamed_single.kts diff --git a/specs/spring-cloud-contract-spec-kotlin/src/main/kotlin/org/springframework/cloud/contract/spec/internal/KotlinContractConverter.kt b/specs/spring-cloud-contract-spec-kotlin/src/main/kotlin/org/springframework/cloud/contract/spec/internal/KotlinContractConverter.kt index 6ac7f1be91..6be6784243 100644 --- a/specs/spring-cloud-contract-spec-kotlin/src/main/kotlin/org/springframework/cloud/contract/spec/internal/KotlinContractConverter.kt +++ b/specs/spring-cloud-contract-spec-kotlin/src/main/kotlin/org/springframework/cloud/contract/spec/internal/KotlinContractConverter.kt @@ -16,10 +16,12 @@ package org.springframework.cloud.contract.spec.internal +import org.apache.commons.lang3.ObjectUtils import org.springframework.cloud.contract.spec.Contract import org.springframework.cloud.contract.spec.ContractConverter import java.io.File import java.net.URLClassLoader.newInstance +import java.util.concurrent.atomic.AtomicInteger import javax.script.ScriptEngineManager /** @@ -50,12 +52,30 @@ class KotlinContractConverter : ContractConverter> { ScriptEngineManager().getEngineByExtension(ext).eval(it) } } - return when (eval) { + val contracts = when (eval) { is Contract -> listOf(eval) is Iterable<*> -> eval.filterIsInstance(Contract::class.java) is Array<*> -> eval.filterIsInstance(Contract::class.java) else -> emptyList() } + + return withName(file, contracts) + } + + private fun withName(file: File, contracts: Collection): Collection { + val counter = AtomicInteger(0) + return contracts.onEach { contract -> + if (ObjectUtils.isEmpty(contract.name)) { + contract.name = defaultContractName(file, contracts, counter.get()) + } + counter.incrementAndGet() + } + } + + private fun defaultContractName(file: File, contracts: Collection<*>, counter: Int): String { + val lastIndexOfDot = file.name.lastIndexOf(".") + val tillExtension = file.name.substring(0, lastIndexOfDot) + return tillExtension + if (counter > 0 || contracts.size > 1) "_$counter" else "" } override fun convertTo(contract: Collection) = contract.toList() diff --git a/specs/spring-cloud-contract-spec-kotlin/src/test/kotlin/org/springframework/cloud/contract/spec/ContractTests.kt b/specs/spring-cloud-contract-spec-kotlin/src/test/kotlin/org/springframework/cloud/contract/spec/ContractTests.kt index ff7bdbea68..7949174a99 100644 --- a/specs/spring-cloud-contract-spec-kotlin/src/test/kotlin/org/springframework/cloud/contract/spec/ContractTests.kt +++ b/specs/spring-cloud-contract-spec-kotlin/src/test/kotlin/org/springframework/cloud/contract/spec/ContractTests.kt @@ -825,6 +825,31 @@ then: } } + @Test + fun `should use filename as fallback for single unnamed contract`() { + val contract = KotlinContractConverter() + .convertFrom(File(javaClass.classLoader.getResource("contracts/unnamed_single.kts")!!.toURI())) + .single() + assertDoesNotThrow { + Contract.assertContract(contract) + }.also { + assertThat(contract.name).isEqualTo("unnamed_single") + } + } + + @Test + fun `should use filename with index as fallback for multiple unnamed contracts`() { + val contracts = KotlinContractConverter() + .convertFrom(File(javaClass.classLoader.getResource("contracts/unnamed_multiple.kts")!!.toURI())) + .toList() + assertDoesNotThrow { + contracts.forEach(Contract::assertContract) + }.also { + assertThat(contracts[0].name).isEqualTo("unnamed_multiple_0") + assertThat(contracts[1].name).isEqualTo("unnamed_multiple_1") + } + } + @Test /** * See issue https://github.com/spring-cloud/spring-cloud-contract/issues/1668 diff --git a/specs/spring-cloud-contract-spec-kotlin/src/test/resources/contracts/unnamed_multiple.kts b/specs/spring-cloud-contract-spec-kotlin/src/test/resources/contracts/unnamed_multiple.kts new file mode 100644 index 0000000000..97cea5e5d3 --- /dev/null +++ b/specs/spring-cloud-contract-spec-kotlin/src/test/resources/contracts/unnamed_multiple.kts @@ -0,0 +1,34 @@ +/* + * Copyright 2013-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package contracts + +import org.springframework.cloud.contract.spec.ContractDsl.Companion.contract + +arrayOf( + contract { + request { + method = GET + url = url("/test1") + } + }, + contract { + request { + method = GET + url = url("/test2") + } + } +) diff --git a/specs/spring-cloud-contract-spec-kotlin/src/test/resources/contracts/unnamed_single.kts b/specs/spring-cloud-contract-spec-kotlin/src/test/resources/contracts/unnamed_single.kts new file mode 100644 index 0000000000..6c95a681bd --- /dev/null +++ b/specs/spring-cloud-contract-spec-kotlin/src/test/resources/contracts/unnamed_single.kts @@ -0,0 +1,26 @@ +/* + * Copyright 2013-2020 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package contracts + +import org.springframework.cloud.contract.spec.ContractDsl.Companion.contract + +contract { + request { + method = GET + url = url("/test") + } +}