From 6c60e0dc82798e84f21818ea0f1c20256f829b80 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Fri, 13 Feb 2015 12:31:14 +0100 Subject: [PATCH 1/5] [#10] Fixed header creation for requests --- .../wiremock/WiremockToDslConverter.groovy | 21 ++++++++++++++++--- .../WiremockToDslConverterSpec.groovy | 21 +++++++++++++++++-- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy index cdd09eee72..4e08b51d5f 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy @@ -1,4 +1,5 @@ package io.codearte.accurest.wiremock + import groovy.json.JsonSlurper import io.coderate.accurest.dsl.GroovyDsl @@ -17,21 +18,35 @@ class WiremockToDslConverter { wiremockRequest.headers.each { def assertion = it.value String headerName = it.key as String - header(headerName)."$assertion.key"(assertion.value) + def entry = assertion.entrySet().first() + header(headerName)."$entry.key"(entry.value) } } : null } response { status wiremockResponse.status ? wiremockResponse.status as Integer : null - wiremockResponse.body ? body ( + wiremockResponse.body ? body( wiremockResponse.body as Map ) : null wiremockResponse.headers ? headers { wiremockResponse.headers.each { - header([(it.key) : it.value]) + header([(it.key): it.value]) } } : null } } } + + static int main(String[] args) { + String rootOfFolderWithStubs = args[0] + new File(rootOfFolderWithStubs).eachFileRecurse { + try { + GroovyDsl stub = fromWiremockStub(it.text) + new File(it.parent, it.name.replaceAll('json', 'groovy')).text + } catch (Exception e) { + System.err.println(e) + } + + } + } } diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy index 6a4534a20b..444c4a3d4f 100644 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy @@ -11,7 +11,18 @@ class WiremockToDslConverterSpec extends Specification { { "request": { "method": "GET", - "urlPattern": "/[0-9]{2}" + "urlPattern": "/[0-9]{2}", + "headers" : { + "Accept": { + "matches": "text/.*" + }, + "etag": { + "doesNotMatch": "abcd.*" + }, + "X-Custom-Header": { + "contains": "2134" + } + } }, "response": { "status": 200, @@ -22,7 +33,7 @@ class WiremockToDslConverterSpec extends Specification { "created" : "2014-02-02 12:23:43" }, "headers": { - "Content-Type": "text/plain" + "Content-Type": "text/plain", } } } @@ -32,6 +43,11 @@ class WiremockToDslConverterSpec extends Specification { request { method 'GET' urlPattern '/[0-9]{2}' + headers { + header('Accept').matches('text/.*') + header('etag').doesNotMatch('abcd.*') + header('X-Custom-Header').contains('2134') + } } response { status 200 @@ -43,6 +59,7 @@ class WiremockToDslConverterSpec extends Specification { ) headers { header 'Content-Type': 'text/plain' + } } } From a6b1cef2e88b28f4e987fe96da877fc9f5f18426 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Fri, 13 Feb 2015 15:18:28 +0100 Subject: [PATCH 2/5] [#10] Working Wiremock To Dsl Converter --- .../wiremock/WiremockToDslConverter.groovy | 77 +++++++++++++------ .../WiremockToDslConverterSpec.groovy | 57 +++++++------- .../dsl/BaseWiremockStubStrategy.groovy | 2 +- .../io/coderate/accurest/dsl/GroovyDsl.groovy | 3 +- .../accurest/dsl/internal/Headers.groovy | 3 +- 5 files changed, 88 insertions(+), 54 deletions(-) diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy index 4e08b51d5f..f7d2311d75 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy @@ -4,37 +4,64 @@ import groovy.json.JsonSlurper import io.coderate.accurest.dsl.GroovyDsl class WiremockToDslConverter { - static GroovyDsl fromWiremockStub(String wiremockStringStub) { + static String fromWiremockStub(String wiremockStringStub) { + return new WiremockToDslConverter().convertFromWiremockStub(wiremockStringStub) + } + + private String convertFromWiremockStub(String wiremockStringStub) { Object wiremockStub = new JsonSlurper().parseText(wiremockStringStub) - def wiremockRequest = wiremockStub.request - def wiremockResponse = wiremockStub.response - return GroovyDsl.make { + def request = wiremockStub.request + def response = wiremockStub.response + return """\ request { - wiremockRequest.method ? method(wiremockRequest.method as String) : null - wiremockRequest.url ? url(wiremockRequest.url as String) : null - wiremockRequest.urlPattern ? urlPattern(wiremockRequest.urlPattern as String) : null - wiremockRequest.urlPath ? urlPath(wiremockRequest.urlPath as String) : null - wiremockRequest.headers ? headers { - wiremockRequest.headers.each { - def assertion = it.value - String headerName = it.key as String - def entry = assertion.entrySet().first() - header(headerName)."$entry.key"(entry.value) - } - } : null + ${request.method ? "method '$request.method'" : ""} + ${request.url ? "url '$request.url'" : ""} + ${request.urlPattern ? "urlPattern '$request.urlPattern'" : ""} + ${request.urlPath ? "urlPath '$request.urlPath'" : ""} + ${request.headers ? """headers { + ${request.headers.collect { + def assertion = it.value + String headerName = it.key as String + def entry = assertion.entrySet().first() + """header('$headerName').$entry.key('$entry.value')\n""" + }.join('') + } + } + """ : ""} } response { - status wiremockResponse.status ? wiremockResponse.status as Integer : null - wiremockResponse.body ? body( - wiremockResponse.body as Map - ) : null - wiremockResponse.headers ? headers { - wiremockResponse.headers.each { - header([(it.key): it.value]) + ${response.status ? "status $response.status" : ""} + ${response.body ? "body( ${response.body.entrySet().collectAll(withQuotedStringElements()).inject([:], appendToMap())})" : ""} + ${response.headers ? """headers { + ${response.headers.collect { "header('$it.key': '${it.value}')\n" }.join('')} } - } : null + """ : ""} } - } + """ + } + + private Closure withQuotedStringElements() { + return { [(it.key): convert(it.value)] } + } + + private Closure appendToMap() { + return { acc, el -> acc << el } + } + + private Object convert(Object element) { + return element + } + + private Object convert(String element) { + return """ "$element" """ + } + + private Object convert(List element) { + return element.collect { convert(it) } + } + + private Object convert(Map element) { + return element.collectEntries { [(it.key) : convert(it.value)] } } static int main(String[] args) { diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy index 444c4a3d4f..099d0fb621 100644 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy @@ -7,7 +7,7 @@ class WiremockToDslConverterSpec extends Specification { def 'should produce a Groovy DSL from Wiremock stub'() { given: - String wiremockStub = ''' + String wiremockStub = '''\ { "request": { "method": "GET", @@ -27,7 +27,9 @@ class WiremockToDslConverterSpec extends Specification { "response": { "status": 200, "body": { - "id": "123", + "id": { + "value": "132" + }, "surname": "Kowalsky", "name": "Jan", "created" : "2014-02-02 12:23:43" @@ -40,32 +42,35 @@ class WiremockToDslConverterSpec extends Specification { ''' and: GroovyDsl expectedGroovyDsl = GroovyDsl.make { - request { - method 'GET' - urlPattern '/[0-9]{2}' - headers { - header('Accept').matches('text/.*') - header('etag').doesNotMatch('abcd.*') - header('X-Custom-Header').contains('2134') - } - } - response { - status 200 - body ( - id : '123', - surname : 'Kowalsky', - name: 'Jan', - created : '2014-02-02 12:23:43' - ) - headers { - header 'Content-Type': 'text/plain' + request { + method 'GET' + urlPattern '/[0-9]{2}' + headers { + header('Accept').matches('text/.*') + header('etag').doesNotMatch('abcd.*') + header('X-Custom-Header').contains('2134') + } + } + response { + status 200 + body ( + id : [value: '132'], + surname : 'Kowalsky', + name: 'Jan', + created : '2014-02-02 12:23:43' + ) + headers { + header 'Content-Type': 'text/plain' - } - } - } + } + } + } when: - GroovyDsl groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) then: - groovyDsl == expectedGroovyDsl + new GroovyShell(this.class.classLoader).evaluate( + """ io.coderate.accurest.dsl.GroovyDsl.make { + $groovyDsl + }""") == expectedGroovyDsl } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy index 3925ada9f3..e02c2a62ce 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy @@ -12,7 +12,7 @@ abstract class BaseWiremockStubStrategy { } return withAssertionHeaders(headers) { Map.Entry entry -> [(entry.key): buildClientHeaderFromValuePattern(entry.value)] - } << headers?.valueHeaders() + } << headers.valueHeaders() } protected Map buildServerHeadersSection(Headers headers) { diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy index 9ea3348dbd..225d5dce52 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy @@ -8,7 +8,7 @@ import io.coderate.accurest.dsl.internal.Response @TypeChecked @EqualsAndHashCode(includeFields = true) -@ToString(includePackage = false) +@ToString(includeFields = true, includePackage = false) class GroovyDsl { Request request @@ -32,4 +32,5 @@ class GroovyDsl { closure.delegate = response closure() } + } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy index 5487b10b53..f2b5a5649b 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy @@ -4,7 +4,7 @@ import groovy.transform.EqualsAndHashCode import groovy.transform.ToString @EqualsAndHashCode(includeFields = true) -@ToString(includePackage = false) +@ToString(includePackage = false, includeFields = true, ignoreNulls = true) class Headers { private Map assertionHeaders = [:] @@ -28,4 +28,5 @@ class Headers { Set> assertionEntries() { return Collections.unmodifiableSet(assertionHeaders.entrySet()) } + } From e0f72ab6ab5c413d5294e5a2ab9fd7cd32d059e1 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Fri, 13 Feb 2015 17:34:13 +0100 Subject: [PATCH 3/5] [#10] Working Wiremock To Dsl Converter - fixed character escaping and other minor bugs Still we have to know how to escape special characters that JSON doesn't recognize --- .../wiremock/WiremockToDslConverter.groovy | 90 ++++++-- .../WiremockToDslConverterSpec.groovy | 215 ++++++++++++++++++ .../accurest/dsl/internal/Body.groovy | 33 ++- .../accurest/dsl/internal/Common.groovy | 18 ++ .../accurest/dsl/internal/Response.groovy | 8 + 5 files changed, 337 insertions(+), 27 deletions(-) diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy index f7d2311d75..36cde449f6 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy @@ -1,7 +1,7 @@ package io.codearte.accurest.wiremock +import groovy.io.FileType import groovy.json.JsonSlurper -import io.coderate.accurest.dsl.GroovyDsl class WiremockToDslConverter { static String fromWiremockStub(String wiremockStringStub) { @@ -14,24 +14,24 @@ class WiremockToDslConverter { def response = wiremockStub.response return """\ request { - ${request.method ? "method '$request.method'" : ""} - ${request.url ? "url '$request.url'" : ""} - ${request.urlPattern ? "urlPattern '$request.urlPattern'" : ""} - ${request.urlPath ? "urlPath '$request.urlPath'" : ""} + ${request.method ? "method '''$request.method'''" : ""} + ${request.url ? "url '''$request.url'''" : ""} + ${request.urlPattern ? "urlPattern '''$request.urlPattern'''" : ""} + ${request.urlPath ? "urlPath '''$request.urlPath'''" : ""} ${request.headers ? """headers { ${request.headers.collect { - def assertion = it.value - String headerName = it.key as String - def entry = assertion.entrySet().first() - """header('$headerName').$entry.key('$entry.value')\n""" - }.join('') + def assertion = it.value + String headerName = it.key as String + def entry = assertion.entrySet().first() + """header('''$headerName''').$entry.key('''$entry.value''')\n""" + }.join('') } } """ : ""} } response { ${response.status ? "status $response.status" : ""} - ${response.body ? "body( ${response.body.entrySet().collectAll(withQuotedStringElements()).inject([:], appendToMap())})" : ""} + ${response.body ? "body( ${buildBody(response.body)})" : ""} ${response.headers ? """headers { ${response.headers.collect { "header('$it.key': '${it.value}')\n" }.join('')} } @@ -40,12 +40,42 @@ class WiremockToDslConverter { """ } - private Closure withQuotedStringElements() { - return { [(it.key): convert(it.value)] } + private Object buildBody(Map responseBody) { + return responseBody.entrySet().collectAll(withQuotedMapStringElements()).inject([:], appendToIterable()) } - private Closure appendToMap() { - return { acc, el -> acc << el } + private Object buildBody(List responseBody) { + return responseBody.collectAll(withQuotedStringElements()).inject([], appendToIterable()) + } + + private Object buildBody(Integer responseBody) { + return responseBody + } + + private Object buildBody(String responseBody) { + try { + return buildBody(new JsonSlurper().parseText(responseBody)) + } catch (Exception e) { + return """'''$responseBody'''""" + } + } + + private Closure withQuotedMapStringElements() { + return { + [(it.key): convert(it.value)] + } + } + + private Closure withQuotedStringElements() { + return { + convert(it) + } + } + + private Closure appendToIterable() { + return { + acc, el -> acc << el + } } private Object convert(Object element) { @@ -53,23 +83,39 @@ class WiremockToDslConverter { } private Object convert(String element) { - return """ "$element" """ + return quoteString(element) + } + + private String quoteString(String element) { + if (element =~ /^".*"$/) { + return element + } + return """'''$element'''""" } private Object convert(List element) { - return element.collect { convert(it) } + return element.collect { + convert(it) + } } private Object convert(Map element) { - return element.collectEntries { [(it.key) : convert(it.value)] } + return element.collectEntries { + [(it.key) : convert(it.value)] + } } - static int main(String[] args) { + static void main(String[] args) { String rootOfFolderWithStubs = args[0] - new File(rootOfFolderWithStubs).eachFileRecurse { + new File(rootOfFolderWithStubs).eachFileRecurse(FileType.FILES) { try { - GroovyDsl stub = fromWiremockStub(it.text) - new File(it.parent, it.name.replaceAll('json', 'groovy')).text + if(!it.name.endsWith('json')) { + return + } + String wiremockStub = fromWiremockStub(it.text) + File newGroovyFile = new File(it.parent, it.name.replaceAll('json', 'groovy')) + println("Creating new groovy file [$newGroovyFile.path]") + newGroovyFile.text = wiremockStub } catch (Exception e) { System.err.println(e) } diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy index 099d0fb621..8128727d49 100644 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy @@ -73,4 +73,219 @@ class WiremockToDslConverterSpec extends Specification { $groovyDsl }""") == expectedGroovyDsl } + + + def 'should convert Wiremock stub with body containing simple JSON'() { + given: + String wiremockStub = '''\ +{ + "request": { + "method": "DELETE", + "urlPattern": "/credit-card-verification-data/[0-9]+", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.mymoid-adapter.v2+json; charset=UTF-8" + } + } + }, + "response": { + "status": 200, + "body": "{\"status\": \"OK\"}", + "headers": { + "Content-Type": "application/json" + } + } +} +''' + and: + GroovyDsl expectedGroovyDsl = GroovyDsl.make { + request { + method 'DELETE' + urlPattern '/credit-card-verification-data/[0-9]+' + headers { + header('Content-Type').equalTo('application/vnd.mymoid-adapter.v2+json; charset=UTF-8') + } + } + response { + status 200 + body ( + status : "OK" + ) + headers { + header 'Content-Type': 'application/json' + + } + } + } + when: + String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + then: + new GroovyShell(this.class.classLoader).evaluate( + """ io.coderate.accurest.dsl.GroovyDsl.make { + $groovyDsl + }""") == expectedGroovyDsl + } + + def 'should convert Wiremock stub with body containing integer'() { + given: + String wiremockStub = '''\ +{ + "request": { + "method": "POST", + "url": "/charge/count", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.creditcard-reporter.v1+json" + } + } + }, + "response": { + "status": 200, + "body": 200, + "headers": { + "Content-Type": "application/json" + } + } +} +''' + and: + GroovyDsl expectedGroovyDsl = GroovyDsl.make { + request { + method 'POST' + url '/charge/count' + headers { + header('Content-Type').equalTo('application/vnd.creditcard-reporter.v1+json') + } + } + response { + status 200 + body ( 200 ) + headers { + header 'Content-Type': 'application/json' + + } + } + } + when: + String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + then: + new GroovyShell(this.class.classLoader).evaluate( + """ io.coderate.accurest.dsl.GroovyDsl.make { + $groovyDsl + }""") == expectedGroovyDsl + } + + def 'should convert Wiremock stub with body as a list'() { + given: + String wiremockStub = '''\ +{ + "request": { + "method": "POST", + "url": "/charge/count", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.creditcard-reporter.v1+json" + } + } + }, + "response": { + "status": 200, + "body": [ + {"a":1, "c":"3"}, + "b", + "a" + ], + "headers": { + "Content-Type": "application/json" + } + } +} +''' + and: + GroovyDsl expectedGroovyDsl = GroovyDsl.make { + request { + method 'POST' + url '/charge/count' + headers { + header('Content-Type').equalTo('application/vnd.creditcard-reporter.v1+json') + } + } + response { + status 200 + body ([ + [a: 1, c: '3'], + 'b', + 'c' + ]) + headers { + header 'Content-Type': 'application/json' + + } + } + } + when: + String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + then: + new GroovyShell(this.class.classLoader).evaluate( + """ io.coderate.accurest.dsl.GroovyDsl.make { + $groovyDsl + }""") == expectedGroovyDsl + } + + + def 'should convert Wiremock stub with body containing a nested list'() { + given: + String wiremockStub = '''\ +{ + "request": { + "method": "POST", + "url": "/charge/search?pageNumber=0&size=2147483647", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.creditcard-reporter.v1+json" + } + } + }, + "response": { + "status": 200, + "body":"[{\\"amount\\":1.01,\\"name\\":\\"Name\\",\\"info\\":{\\"title\\":\\"title1\\",\\"payload\\":null},\\"booleanvalue\\":true,\\"user\\":null},{\\"amount\\":2.01,\\"name\\":\\"Name2\\",\\"info\\":{\\"title\\":\\"title2\\",\\"payload\\":null},\\"booleanvalue\\":true,\\"user\\":null}]" + } +} +''' + and: + GroovyDsl expectedGroovyDsl = GroovyDsl.make { + request { + method 'POST' + url '/charge/search?pageNumber=0&size=2147483647' + headers { + header('Content-Type').equalTo('application/vnd.creditcard-reporter.v1+json') + } + } + response { + status 200 + body ([ + [amount:1.01, + name: "Name" , + info: [title:"title1", + payload:null], + booleanvalue:true, + user:null], + [amount:2.01, + name: "Name2" , + info: [title:"title2", + payload:null], + booleanvalue:true, + user:null] + ]) + } + } + when: + String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + then: + new GroovyShell(this.class.classLoader).evaluate( + """ io.coderate.accurest.dsl.GroovyDsl.make { + $groovyDsl + }""") == expectedGroovyDsl + } + } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy index e3b75c9eb4..1a3b331bb3 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy @@ -1,14 +1,15 @@ package io.coderate.accurest.dsl.internal -import groovy.transform.CompileStatic + import groovy.transform.EqualsAndHashCode import groovy.transform.ToString -@CompileStatic @ToString(includePackage = false, includeFields = true) @EqualsAndHashCode(includeFields = true) class Body { - private final Map body + private Map body + private DslProperty bodyAsValue + private List bodyAsList Body() { this.body = [:] @@ -18,13 +19,35 @@ class Body { this.body = body } - Map forClientSide() { + Body(List bodyAsList) { + this.bodyAsList = bodyAsList + } + + Body(Object bodyAsValue) { + this.bodyAsValue = new DslProperty(bodyAsValue) + } + + Body(DslProperty bodyAsValue) { + this.bodyAsValue = bodyAsValue + } + + Object forClientSide() { + if(bodyAsValue) { + return bodyAsValue.clientValue + } else if(bodyAsList) { + bodyAsList.collect { it.clientValue } + } return body.collectEntries { Map.Entry entry -> [(entry.key) : entry.value.clientValue] } as Map } - Map forServerSide() { + Object forServerSide() { + if(bodyAsValue) { + return bodyAsValue.serverValue + } else if(bodyAsList) { + bodyAsList.collect { it.serverValue } + } return body.collectEntries { Map.Entry entry -> [(entry.key) : entry.value.serverValue] } as Map diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy index fc5135af33..9afb7e115c 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy @@ -18,10 +18,28 @@ class Common { } as Map } + List convertObjectsToDslProperties(List body) { + return body.collect { + Object element -> toDslProperty(element) + } as List + } + DslProperty toDslProperty(Object property) { return new DslProperty(property) } + DslProperty toDslProperty(Map property) { + return new DslProperty(property.collectEntries { + [(it.key) : toDslProperty(it.value)] + }) + } + + DslProperty toDslProperty(List property) { + return new DslProperty(property.collect { + toDslProperty(it) + }) + } + DslProperty toDslProperty(DslProperty property) { return property } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy index 660863c1b0..46827b9875 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy @@ -41,6 +41,14 @@ class Response extends Common { this.body = new Body(convertObjectsToDslProperties(body)) } + void body(List body) { + this.body = new Body(convertObjectsToDslProperties(body)) + } + + void body(Object bodyAsValue) { + this.body = new Body(bodyAsValue) + } + Body getBody() { return body } From ca4cceaa5b4b877eda6684605e61fb4b14f7fe06 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 16 Feb 2015 10:24:06 +0100 Subject: [PATCH 4/5] [#5] Added possibility of providing a GString as Body with Client / Server values --- .../accurest/dsl/internal/Body.groovy | 18 ++++ .../accurest/dsl/WiremockGroovyDslSpec.groovy | 96 +++++++++++++++++++ 2 files changed, 114 insertions(+) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy index 1a3b331bb3..502e18a2ca 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy @@ -1,7 +1,9 @@ package io.coderate.accurest.dsl.internal +import groovy.json.JsonSlurper import groovy.transform.EqualsAndHashCode import groovy.transform.ToString +import org.codehaus.groovy.runtime.GStringImpl @ToString(includePackage = false, includeFields = true) @EqualsAndHashCode(includeFields = true) @@ -27,6 +29,22 @@ class Body { this.bodyAsValue = new DslProperty(bodyAsValue) } + Body(GString bodyAsValue) { + this.bodyAsValue = new DslProperty(getClientValue(bodyAsValue), getServerValue(bodyAsValue)) + } + + private Map getClientValue(GString bodyAsValue) { + GString clientGString = new GStringImpl(bodyAsValue.values.clone(), bodyAsValue.strings.clone()) + Object[] clientValues = bodyAsValue.values.collect { it instanceof DslProperty ? it.clientValue : it } as Object[] + return new JsonSlurper().parseText(new GStringImpl(clientValues, clientGString.strings).toString()) + } + + private Map getServerValue(GString bodyAsValue) { + GString clientGString = new GStringImpl(bodyAsValue.values.clone(), bodyAsValue.strings.clone()) + Object[] serverValues = bodyAsValue.values.collect { it instanceof DslProperty ? it.serverValue: it } as Object[] + return new JsonSlurper().parseText(new GStringImpl(serverValues, clientGString.strings).toString()) + } + Body(DslProperty bodyAsValue) { this.bodyAsValue = bodyAsValue } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy index 3ee9cd7f11..9740c6f40e 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy @@ -60,6 +60,102 @@ class WiremockGroovyDslSpec extends Specification { ''') } + def 'should convert groovy dsl stub with Body as String to wiremock stub for the client side'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method('GET') + urlPattern $(client('/[0-9]{2}'), server('/12')) + } + response { + status 200 + body ("""\ + { + "id": "${value(client('123'),server('321'))}", + "surname": "${value(client('Kowalsky'),server('Lewandowski'))}", + "name": "Jan", + "created" : "${$(client('2014-02-02 12:23:43'), server('2999-09-09 01:23:45'))}" + } + """ + ) + headers { + header 'Content-Type': 'text/plain' + } + } + } + when: + String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + then: + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' +{ + "request": { + "method": "GET", + "urlPattern": "/[0-9]{2}" + }, + "response": { + "status": 200, + "body": { + "id": "123", + "surname": "Kowalsky", + "name": "Jan", + "created" : "2014-02-02 12:23:43" + }, + "headers": { + "Content-Type": "text/plain" + } + } +} +''') + } + + def 'should convert groovy dsl stub with Body as String to wiremock stub for the server side'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method('GET') + urlPattern $(client('/[0-9]{2}'), server('/12')) + } + response { + status 200 + body ("""\ + { + "id": "${value(client('123'),server('321'))}", + "surname": "${value(client('Kowalsky'),server('Lewandowski'))}", + "name": "Jan", + "created" : "${$(client('2014-02-02 12:23:43'), server('2999-09-09 01:23:45'))}" + } + """ + ) + headers { + header 'Content-Type': 'text/plain' + } + } + } + when: + String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockServerStub() + then: + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' +{ + "request": { + "method": "GET", + "urlPattern": "/12" + }, + "response": { + "status": 200, + "body": { + "id": "321", + "surname": "Lewandowski", + "name": "Jan", + "created" : "2999-09-09 01:23:45" + }, + "headers": { + "Content-Type": "text/plain" + } + } +} +''') + } + def 'should convert groovy dsl stub to wiremock stub for the server side'() { given: GroovyDsl groovyDsl = GroovyDsl.make { From 36280bab7d301a3d87b60dda9fa343780c94c86b Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 16 Feb 2015 11:32:05 +0100 Subject: [PATCH 5/5] [#10] Added conversion from Wiremock Stub to Groovy DSL --- .../wiremock/WiremockToDslConverter.groovy | 33 +++++++++---- .../WiremockToDslConverterSpec.groovy | 46 +++++++++++-------- build.gradle | 1 + 3 files changed, 51 insertions(+), 29 deletions(-) diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy index 36cde449f6..101260ac3a 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy @@ -1,7 +1,10 @@ package io.codearte.accurest.wiremock - import groovy.io.FileType +import groovy.json.JsonOutput import groovy.json.JsonSlurper +import groovy.xml.XmlUtil + +import static org.apache.commons.lang3.StringEscapeUtils.escapeJava class WiremockToDslConverter { static String fromWiremockStub(String wiremockStringStub) { @@ -14,16 +17,16 @@ class WiremockToDslConverter { def response = wiremockStub.response return """\ request { - ${request.method ? "method '''$request.method'''" : ""} - ${request.url ? "url '''$request.url'''" : ""} - ${request.urlPattern ? "urlPattern '''$request.urlPattern'''" : ""} - ${request.urlPath ? "urlPath '''$request.urlPath'''" : ""} + ${request.method ? "method \"\"\"$request.method\"\"\"" : ""} + ${request.url ? "url \"\"\"$request.url\"\"\"" : ""} + ${request.urlPattern ? "urlPattern \"\"\"${escapeJava(request.urlPattern)}\"\"\"" : ""} + ${request.urlPath ? "urlPath \"\"\"$request.urlPath\"\"\"" : ""} ${request.headers ? """headers { ${request.headers.collect { def assertion = it.value String headerName = it.key as String def entry = assertion.entrySet().first() - """header('''$headerName''').$entry.key('''$entry.value''')\n""" + """header(\"\"\"$headerName\"\"\").$entry.key(\"\"\"${escapeJava(entry.value)}\"\"\")\n""" }.join('') } } @@ -54,12 +57,22 @@ class WiremockToDslConverter { private Object buildBody(String responseBody) { try { - return buildBody(new JsonSlurper().parseText(responseBody)) - } catch (Exception e) { - return """'''$responseBody'''""" + def json = new JsonSlurper().parseText(responseBody) + return wrapWithMultilineGString(JsonOutput.prettyPrint(responseBody)) + } catch (Exception jsonException) { + try { + def xml = new XmlSlurper().parseText(responseBody) + return wrapWithMultilineGString(XmlUtil.serialize(responseBody)) + } catch (Exception xmlException) { + return wrapWithMultilineGString(responseBody) + } } } + private String wrapWithMultilineGString(String string) { + return """\"\"\"$string\"\"\"""" + } + private Closure withQuotedMapStringElements() { return { [(it.key): convert(it.value)] @@ -90,7 +103,7 @@ class WiremockToDslConverter { if (element =~ /^".*"$/) { return element } - return """'''$element'''""" + return """\"\"\"${escapeJava(element)}\"\"\"""" } private Object convert(List element) { diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy index 8128727d49..aac2bbb12f 100644 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy @@ -90,7 +90,7 @@ class WiremockToDslConverterSpec extends Specification { }, "response": { "status": 200, - "body": "{\"status\": \"OK\"}", + "body": "{\\"status\\": \\"OK\\"}", "headers": { "Content-Type": "application/json" } @@ -108,9 +108,9 @@ class WiremockToDslConverterSpec extends Specification { } response { status 200 - body ( - status : "OK" - ) + body ("""{ + "status": "OK" +}""") headers { header 'Content-Type': 'application/json' @@ -215,7 +215,7 @@ class WiremockToDslConverterSpec extends Specification { body ([ [a: 1, c: '3'], 'b', - 'c' + 'a' ]) headers { header 'Content-Type': 'application/json' @@ -263,20 +263,28 @@ class WiremockToDslConverterSpec extends Specification { } response { status 200 - body ([ - [amount:1.01, - name: "Name" , - info: [title:"title1", - payload:null], - booleanvalue:true, - user:null], - [amount:2.01, - name: "Name2" , - info: [title:"title2", - payload:null], - booleanvalue:true, - user:null] - ]) + body ("""[ + { + "amount": 1.01, + "name": "Name", + "info": { + "title": "title1", + "payload": null + }, + "booleanvalue": true, + "user": null + }, + { + "amount": 2.01, + "name": "Name2", + "info": { + "title": "title2", + "payload": null + }, + "booleanvalue": true, + "user": null + } +]""") } } when: diff --git a/build.gradle b/build.gradle index a74ec2a59f..8a123cd670 100644 --- a/build.gradle +++ b/build.gradle @@ -47,6 +47,7 @@ project(':accurest-core') { project(':accurest-converters') { dependencies { compile project(':accurest-core') + compile 'org.apache.commons:commons-lang3:3.3.2' } }