From 2ebe11e2a58f56f85afcf6f54f8dc4fbe649864c Mon Sep 17 00:00:00 2001 From: Tim Ysewyn Date: Wed, 7 Aug 2019 23:05:02 +0200 Subject: [PATCH] Additional functionality --- .../cloud/contract/spec/internal/CommonDsl.kt | 40 +++++++ .../spec/internal/KotlinContractConverter.kt | 22 +++- .../contract/spec/internal/RequestDsl.kt | 67 ++++------- .../contract/spec/internal/ResponseDsl.kt | 39 +++---- .../cloud/contract/spec/ContractTests.kt | 108 +++++++++--------- .../internal/KotlinContractConverterTest.kt | 11 +- .../contracts/multipleDefinitions.kts | 4 +- .../src/test/resources/contracts/request.pdf | Bin 0 -> 14631 bytes .../src/test/resources/contracts/response.pdf | Bin 0 -> 15767 bytes .../contracts/shouldWorkWithBinaryPayload.kts | 38 ++++++ .../resources/contracts/singleDefinition.kts | 2 +- 11 files changed, 195 insertions(+), 136 deletions(-) create mode 100644 specs/spring-cloud-contract-spec-kotlin/src/test/resources/contracts/request.pdf create mode 100644 specs/spring-cloud-contract-spec-kotlin/src/test/resources/contracts/response.pdf create mode 100644 specs/spring-cloud-contract-spec-kotlin/src/test/resources/contracts/shouldWorkWithBinaryPayload.kts diff --git a/specs/spring-cloud-contract-spec-kotlin/src/main/kotlin/org/springframework/cloud/contract/spec/internal/CommonDsl.kt b/specs/spring-cloud-contract-spec-kotlin/src/main/kotlin/org/springframework/cloud/contract/spec/internal/CommonDsl.kt index d4e5536533..5f4f7eb7dd 100644 --- a/specs/spring-cloud-contract-spec-kotlin/src/main/kotlin/org/springframework/cloud/contract/spec/internal/CommonDsl.kt +++ b/specs/spring-cloud-contract-spec-kotlin/src/main/kotlin/org/springframework/cloud/contract/spec/internal/CommonDsl.kt @@ -16,6 +16,9 @@ package org.springframework.cloud.contract.spec.internal +import java.io.File +import java.net.URISyntaxException +import java.nio.charset.Charset import java.util.regex.Pattern /** @@ -85,6 +88,43 @@ open class CommonDsl { fun execute(commandToExecute: String) = ExecutionProperty(commandToExecute) + /** + * Read file contents as String. + * @param relativePath of the file to read + * @return String file contents + */ + fun file(relativePath: String) = file(relativePath, Charset.defaultCharset()) + + /** + * Read file contents as String with the given Charset. + * @param relativePath of the file to read + * @param charset to use for converting the bytes to String + * @return String file contents + */ + fun file(relativePath: String, charset: Charset) = Body(FromFileProperty(fileLocation(relativePath), String::class.java, charset)) + + /** + * Read file contents as bytes[]. + * @param relativePath of the file to read + * @return String file contents + */ + fun fileAsBytes(relativePath: String) = Body(FromFileProperty(fileLocation(relativePath), ByteArray::class.java)) + + /** + * Read file contents as array of bytes. + * @param relativePath of the file to read + * @return file contents as an array of bytes + */ + private fun fileLocation(relativePath: String): File { + val resource = Thread.currentThread().contextClassLoader + .getResource(relativePath) ?: throw IllegalStateException("File [$relativePath] is not present") + try { + return File(resource.toURI()) + } catch (ex: URISyntaxException) { + throw IllegalStateException(ex) + } + } + /* REGEX */ fun regexProperty(value: Any) = RegexProperty(value) 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 98285809fc..ee63ced2ce 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 @@ -19,6 +19,7 @@ package org.springframework.cloud.contract.spec.internal import org.springframework.cloud.contract.spec.Contract import org.springframework.cloud.contract.spec.ContractConverter import java.io.File +import java.net.URLClassLoader.newInstance import javax.script.ScriptEngineManager /** @@ -39,10 +40,12 @@ class KotlinContractConverter: ContractConverter> { } override fun convertFrom(file: File): Collection { - val eval = file.reader().use { - // Get a new engine every time we need to process a file. - // Reusing the script engine could leak context and will fail subsequent evals - ScriptEngineManager().getEngineByExtension(ext).eval(it) + val eval = withUpdatedClassloader(file) { + file.reader().use { + // Get a new engine every time we need to process a file. + // Reusing the script engine could leak context and will fail subsequent evals + ScriptEngineManager().getEngineByExtension(ext).eval(it) + } } return when (eval) { is Contract -> listOf(eval) @@ -53,4 +56,15 @@ class KotlinContractConverter: ContractConverter> { } override fun convertTo(contract: Collection) = contract.toList() + + private fun withUpdatedClassloader(file: File, block: ClassLoader.() -> Any): Any { + val currentClassLoader = Thread.currentThread().contextClassLoader + try { + val tempClassLoader = newInstance(arrayOf(file.parentFile.toURI().toURL()), currentClassLoader) + Thread.currentThread().contextClassLoader = tempClassLoader + return tempClassLoader.block() + } finally { + Thread.currentThread().contextClassLoader = currentClassLoader + } + } } \ No newline at end of file diff --git a/specs/spring-cloud-contract-spec-kotlin/src/main/kotlin/org/springframework/cloud/contract/spec/internal/RequestDsl.kt b/specs/spring-cloud-contract-spec-kotlin/src/main/kotlin/org/springframework/cloud/contract/spec/internal/RequestDsl.kt index bf7de2fea8..cbaaab54f4 100644 --- a/specs/spring-cloud-contract-spec-kotlin/src/main/kotlin/org/springframework/cloud/contract/spec/internal/RequestDsl.kt +++ b/specs/spring-cloud-contract-spec-kotlin/src/main/kotlin/org/springframework/cloud/contract/spec/internal/RequestDsl.kt @@ -17,6 +17,7 @@ package org.springframework.cloud.contract.spec.internal import org.springframework.cloud.contract.spec.toDslProperties +import org.springframework.cloud.contract.spec.toDslProperty import java.util.regex.Pattern /** @@ -36,73 +37,45 @@ open class RequestDsl : CommonDsl(), RegexCreatingProperty { var multipart: Multipart? = null var bodyMatchers: BodyMatchers? = null - fun method(method: String) { - this.method = DslProperty(method) - } + fun method(method: String) = method.toDslProperty() - fun method(method: HttpMethods.HttpMethod) { - this.method(method.toString()) - } + fun method(method: HttpMethods.HttpMethod) = this.method(method.toString()) - fun url(url: String) { - this.url = Url(url) - } + fun url(url: String) = Url(url) - fun url(url: DslProperty) { - this.url = Url(url) - } + fun url(url: DslProperty) = Url(url) - fun urlPath(url: String) { - this.urlPath = UrlPath(url) - } + fun path(path: String) = UrlPath(path) - fun urlPath(url: DslProperty) { - this.urlPath = UrlPath(url) - } + fun path(path: DslProperty) = UrlPath(path) fun headers(headers: Headers.() -> Unit) { - this.headers = Headers().apply(headers) + this.headers = Request.RequestHeaders().apply(headers) } fun cookies(cookies: Cookies.() -> Unit) { - this.cookies = Cookies().apply(cookies) + this.cookies = Request.RequestCookies().apply(cookies) } - fun body(body: Map) { - this.body = Body(body.toDslProperties()) - } + fun body(body: Map) = Body(body.toDslProperties()) - fun body(vararg body: Pair) { - this.body = Body(body.toMap().toDslProperties()) - } + fun body(vararg body: Pair) = Body(body.toMap().toDslProperties()) - fun body(body: Pair) { - this.body = Body(mapOf(body).toDslProperties()) - } + fun body(body: Pair) = Body(mapOf(body).toDslProperties()) - fun body(body: List) { - this.body = Body(body.toDslProperties()) - } + fun body(body: List) = Body(body.toDslProperties()) - fun body(body: DslProperty) { - this.body = Body(body) - } + fun body(body: DslProperty) = Body(body) - fun multipart(multipart: Map) { - this.multipart = Multipart(multipart.toDslProperties()) - } + fun body(body: Any) = Body(body) - fun multipart(multipart: List) { - this.multipart = Multipart(multipart.toDslProperties()) - } + fun multipart(multipart: Map) = Multipart(multipart.toDslProperties()) - fun multipart(multipart: DslProperty) { - this.multipart = Multipart(multipart) - } + fun multipart(multipart: List) = Multipart(multipart.toDslProperties()) - fun multipart(multipart: Any) { - this.multipart = Multipart(multipart) - } + fun multipart(multipart: DslProperty) = Multipart(multipart) + + fun multipart(multipart: Any) = Multipart(multipart) fun bodyMatchers(block: BodyMatchers.() -> Unit) { bodyMatchers = BodyMatchers().apply(block) diff --git a/specs/spring-cloud-contract-spec-kotlin/src/main/kotlin/org/springframework/cloud/contract/spec/internal/ResponseDsl.kt b/specs/spring-cloud-contract-spec-kotlin/src/main/kotlin/org/springframework/cloud/contract/spec/internal/ResponseDsl.kt index 2f5d06b189..e9816fc999 100644 --- a/specs/spring-cloud-contract-spec-kotlin/src/main/kotlin/org/springframework/cloud/contract/spec/internal/ResponseDsl.kt +++ b/specs/spring-cloud-contract-spec-kotlin/src/main/kotlin/org/springframework/cloud/contract/spec/internal/ResponseDsl.kt @@ -36,45 +36,29 @@ class ResponseDsl : CommonDsl(), RegexCreatingProperty { var async: Boolean = false var bodyMatchers: ResponseBodyMatchers? = null - fun status(code: Int) { - this.status = DslProperty(code) - } + fun code(code: Int): DslProperty = code.toDslProperty() - fun fixedDelayMilliseconds(delay: Long) { - this.delay = delay.toDslProperty() - } + fun fixedMilliseconds(delay: Long) = delay.toDslProperty() fun headers(headers: Headers.() -> Unit) { - this.headers = Headers().apply(headers) + this.headers = Response.ResponseHeaders().apply(headers) } fun cookies(cookies: Cookies.() -> Unit) { - this.cookies = Cookies().apply(cookies) + this.cookies = Response.ResponseCookies().apply(cookies) } - fun body(body: Map) { - this.body = Body(body.toDslProperties()) - } + fun body(body: Map) = Body(body.toDslProperties()) - fun body(vararg body: Pair) { - this.body = Body(body.toMap().toDslProperties()) - } + fun body(vararg body: Pair) = Body(body.toMap().toDslProperties()) - fun body(body: Pair) { - this.body = Body(mapOf(body).toDslProperties()) - } + fun body(body: Pair) = Body(mapOf(body).toDslProperties()) - fun body(body: List) { - this.body = Body(body.toDslProperties()) - } + fun body(body: List) = Body(body.toDslProperties()) - fun body(body: DslProperty) { - this.body = Body(body.toDslProperty()) - } + fun body(body: DslProperty) = Body(body.toDslProperty()) - fun body(body: Any) { - this.body = Body(body) - } + fun body(body: Any) = Body(body) fun bodyMatchers(bodyMatchers: ResponseBodyMatchers.() -> Unit) { this.bodyMatchers = ResponseBodyMatchers().apply(bodyMatchers) @@ -124,6 +108,9 @@ class ResponseDsl : CommonDsl(), RegexCreatingProperty { fun `$`(server: ServerDslProperty, client: ClientDslProperty) = delegate.value(client, server) +// TODO, needs to be reworked - no lazy string interpolation like in Groovy +// fun fromRequest() = FromRequest() + override fun anyAlphaUnicode() = delegate.anyAlphaUnicode() override fun anyAlphaNumeric() = delegate.anyAlphaNumeric() 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 37f195eccf..f7686d7008 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 @@ -24,8 +24,6 @@ import org.springframework.cloud.contract.spec.ContractDsl.Companion.contract import org.springframework.cloud.contract.spec.internal.HttpMethods import org.springframework.cloud.contract.spec.internal.HttpStatus import org.springframework.cloud.contract.spec.internal.RegexProperty -import org.springframework.cloud.contract.spec.internal.Url -import org.springframework.cloud.contract.spec.internal.UrlPath /** * Tests written based on the Java contract tests written in Groovy @@ -38,19 +36,19 @@ class ContractTests { fun `should work for http`() { val contract = contract { request { - url = Url("/foo") - method(HttpMethods.HttpMethod.PUT) + url = url("/foo") + method = method(HttpMethods.HttpMethod.PUT) headers { header("foo", "bar") } - body("foo" to "bar") + body = body("foo" to "bar") } response { - status(200) + status = code(200) headers { header("foo2", "bar") } - body("foo2" to "bar") + body = body("foo2" to "bar") } } @@ -87,10 +85,10 @@ class ContractTests { fun `should fail when no method is present`() { val contract = contract { request { - url = Url("/foo") + url = url("/foo") } response { - status(200) + status = code(200) } } @@ -105,10 +103,10 @@ class ContractTests { fun `should fail when no url is present`() { val contract = contract { request { - method("GET") + method = method("GET") } response { - status(200) + status = code(200) } } @@ -123,8 +121,8 @@ class ContractTests { fun `should fail when no status is present`() { val contract = contract { request { - url = Url("/foo") - method("GET") + url = url("/foo") + method = method("GET") } response { } @@ -264,14 +262,14 @@ then: fun `should make equals and hashcode work properly for URL`() { val a: Contract = contract { request { - method("GET") - url = Url("/1") + method = method("GET") + url = url("/1") } } val b: Contract = contract { request { - method("GET") - url = Url("/1") + method = method("GET") + url = url("/1") } } @@ -287,14 +285,14 @@ then: fun `should make equals and hashcode work properly for URL with consumer producer`() { val a: Contract = contract { request { - method("GET") - url = Url(value(c("/1"), p("/1"))) + method = method("GET") + url = url(value(c("/1"), p("/1"))) } } val b: Contract = contract { request { - method("GET") - url = Url(value(c("/1"), p("/1"))) + method = method("GET") + url = url(value(c("/1"), p("/1"))) } } @@ -311,26 +309,26 @@ then: val index = 1 val a: Contract = contract { request { - method(HttpMethods.HttpMethod.PUT) + method = method(HttpMethods.HttpMethod.PUT) headers { contentType(applicationJson()) } - url = Url("/$index") + url = url("/$index") } response { - status(HttpStatus.OK()) + status = code(HttpStatus.OK()) } } val b: Contract = contract { request { - method(HttpMethods.HttpMethod.PUT) + method = method(HttpMethods.HttpMethod.PUT) headers { contentType(applicationJson()) } - url = Url("/$index") + url = url("/$index") } response { - status(HttpStatus.OK()) + status = code(HttpStatus.OK()) } } @@ -347,27 +345,27 @@ then: var index = 1 val a: Contract = contract { request { - method(HttpMethods.HttpMethod.PUT) + method = method(HttpMethods.HttpMethod.PUT) headers { contentType(applicationJson()) } - url = Url("/$index") + url = url("/$index") } response { - status(HttpStatus.OK()) + status = code(HttpStatus.OK()) } } index = 2 val b: Contract = contract { request { - method(HttpMethods.HttpMethod.PUT) + method = method(HttpMethods.HttpMethod.PUT) headers { contentType(applicationJson()) } - url = Url("/$index") + url = url("/$index") } response { - status(HttpStatus.OK()) + status = code(HttpStatus.OK()) } } @@ -383,8 +381,8 @@ then: fun `should return true when comparing two equal complex contracts`() { val a: Contract = contract { request { - method(HttpMethods.HttpMethod.GET) - url = Url("/path") + method = method(HttpMethods.HttpMethod.GET) + url = url("/path") headers { header("Accept", value( consumer(regex("text/.*")), @@ -397,8 +395,8 @@ then: } } response { - status(HttpStatus.OK()) - body("id" to mapOf("value" to "132"), + status = code(HttpStatus.OK()) + body = body("id" to mapOf("value" to "132"), "surname" to "Kowalsky", "name" to "Jan", "created" to "2014-02-02 12:23:43" @@ -410,8 +408,8 @@ then: } val b: Contract = contract { request { - method(HttpMethods.HttpMethod.GET) - url = Url("/path") + method = method(HttpMethods.HttpMethod.GET) + url = url("/path") headers { header("Accept", value( consumer(regex("text/.*")), @@ -424,8 +422,8 @@ then: } } response { - status(HttpStatus.OK()) - body("id" to mapOf("value" to "132"), + status = code(HttpStatus.OK()) + body = body("id" to mapOf("value" to "132"), "surname" to "Kowalsky", "name" to "Jan", "created" to "2014-02-02 12:23:43" @@ -482,15 +480,15 @@ then: fun `should support bodyMatchers`() { val contract = contract { request { - method(HttpMethods.HttpMethod.GET) - url = Url("/path") + method = method(HttpMethods.HttpMethod.GET) + url = url("/path") body("id" to mapOf("value" to "132")) bodyMatchers { jsonPath("$.id.value", byRegex(anInteger())) } } response { - status(HttpStatus.OK()) + status = code(HttpStatus.OK()) body("id" to mapOf("value" to "132"), "surname" to "Kowalsky", "name" to "Jan", @@ -526,13 +524,13 @@ then: fun `should support query parameters for url`() { val contract = contract { request { - method(HttpMethods.HttpMethod.GET) - url = Url("/path") withQueryParameters { + method = method(HttpMethods.HttpMethod.GET) + url = url("/path") withQueryParameters { parameter("foo", "bar") } } response { - status(HttpStatus.OK()) + status = code(HttpStatus.OK()) } } @@ -559,13 +557,13 @@ then: fun `should support query parameters for url path`() { val contract = contract { request { - method(HttpMethods.HttpMethod.GET) - urlPath = UrlPath("/path") withQueryParameters { + method = method(HttpMethods.HttpMethod.GET) + urlPath = path("/path") withQueryParameters { parameter("foo", "bar") } } response { - status(HttpStatus.OK()) + status = code(HttpStatus.OK()) } } @@ -592,13 +590,13 @@ then: fun `should work with list as body`() { val contract = contract { request { - method(HttpMethods.HttpMethod.PUT) - url = Url("/path") - body(listOf("foo", "bar")) + method = method(HttpMethods.HttpMethod.PUT) + url = url("/path") + body = body(listOf("foo", "bar")) } response { - status(HttpStatus.OK()) - body(listOf("foo2", "bar2")) + status = code(HttpStatus.OK()) + body = body(listOf("foo2", "bar2")) } } diff --git a/specs/spring-cloud-contract-spec-kotlin/src/test/kotlin/org/springframework/cloud/contract/spec/internal/KotlinContractConverterTest.kt b/specs/spring-cloud-contract-spec-kotlin/src/test/kotlin/org/springframework/cloud/contract/spec/internal/KotlinContractConverterTest.kt index 4d2cd56536..10382879d8 100644 --- a/specs/spring-cloud-contract-spec-kotlin/src/test/kotlin/org/springframework/cloud/contract/spec/internal/KotlinContractConverterTest.kt +++ b/specs/spring-cloud-contract-spec-kotlin/src/test/kotlin/org/springframework/cloud/contract/spec/internal/KotlinContractConverterTest.kt @@ -16,7 +16,8 @@ package org.springframework.cloud.contract.spec.internal -import org.junit.Test +import org.junit.jupiter.api.Test +import org.springframework.cloud.contract.spec.Contract import java.io.File import kotlin.test.assertEquals import kotlin.test.assertTrue @@ -42,5 +43,13 @@ class KotlinContractConverterTest { assertEquals(2, contracts.size) } + @Test + fun `should work with binary payload`() { + val converter = KotlinContractConverter() + val contracts = converter.convertFrom(file("contracts/shouldWorkWithBinaryPayload.kts")) + assertEquals(1, contracts.size) + Contract.assertContract(contracts.elementAt(0)) + } + private fun file(filename: String) = File(javaClass.classLoader.getResource(filename)!!.toURI()) } \ No newline at end of file diff --git a/specs/spring-cloud-contract-spec-kotlin/src/test/resources/contracts/multipleDefinitions.kts b/specs/spring-cloud-contract-spec-kotlin/src/test/resources/contracts/multipleDefinitions.kts index 8838386cd8..39f8977658 100644 --- a/specs/spring-cloud-contract-spec-kotlin/src/test/resources/contracts/multipleDefinitions.kts +++ b/specs/spring-cloud-contract-spec-kotlin/src/test/resources/contracts/multipleDefinitions.kts @@ -25,7 +25,7 @@ arrayOf( url("/frauds") } response { - status(200) + code(200) body("count" to 200) headers { contentType("application/vnd.fraud.v1+json") @@ -38,7 +38,7 @@ arrayOf( url("/drunks") } response { - status(200) + code(200) body("count" to 100) headers { contentType("application/vnd.fraud.v1+json") diff --git a/specs/spring-cloud-contract-spec-kotlin/src/test/resources/contracts/request.pdf b/specs/spring-cloud-contract-spec-kotlin/src/test/resources/contracts/request.pdf new file mode 100644 index 0000000000000000000000000000000000000000..69503635d87cbdfa660d5cd8be66d3e74b3b20e8 GIT binary patch literal 14631 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 literal 0 HcmV?d00001 diff --git a/specs/spring-cloud-contract-spec-kotlin/src/test/resources/contracts/response.pdf b/specs/spring-cloud-contract-spec-kotlin/src/test/resources/contracts/response.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c3b233056b758d1cc9bf3176e99a95add89ba607 GIT binary patch literal 15767 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