[#5] Changed the approach to use $(), value() instead of closures with client and server

This commit is contained in:
Marcin Grzejszczak
2015-02-12 15:48:55 +01:00
parent 4898470613
commit 88537c139e
14 changed files with 342 additions and 193 deletions

View File

@@ -1,7 +1,6 @@
package io.coderate.accurest.dsl
import groovy.transform.CompileStatic
import io.coderate.accurest.dsl.internal.CustomizableProperty
import io.coderate.accurest.dsl.internal.DslProperty
import io.coderate.accurest.dsl.internal.Headers
import io.coderate.accurest.dsl.internal.WithValuePattern
@@ -32,16 +31,16 @@ abstract class BaseWiremockStubStrategy {
private Map buildClientHeaderFromValuePattern(WithValuePattern valuePattern) {
return getValuePatternSection(valuePattern)
.findAll { it.value }
.collectEntries { [(it.key): it.value.toClientSide()] }
.collectEntries { [(it.key): it.value.clientValue] }
}
private Map buildServerHeaderFromValuePattern(WithValuePattern valuePattern) {
return getValuePatternSection(valuePattern)
.findAll { it.value }
.collectEntries { [(it.key): it.value.toServerSide()] }
.collectEntries { [(it.key): it.value.serverValue] }
}
private Map<String, CustomizableProperty> getValuePatternSection(WithValuePattern valuePattern) {
private Map<String, DslProperty> getValuePatternSection(WithValuePattern valuePattern) {
return [equalToJson : valuePattern.equalToJson,
equalToXml : valuePattern.equalToXml,
matchesXPath : valuePattern.matchesXPath,

View File

@@ -2,7 +2,9 @@ package io.coderate.accurest.dsl
import groovy.transform.CompileStatic
import groovy.transform.PackageScope
import io.coderate.accurest.dsl.internal.ClientRequest
import io.coderate.accurest.dsl.internal.Request
import io.coderate.accurest.dsl.internal.ServerRequest
@CompileStatic
@PackageScope
@@ -15,22 +17,26 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy {
}
@PackageScope Map buildClientRequestContent() {
return buildRequestContent(request,
{ request.urlPattern?.toClientSide() },
{ buildClientHeadersSection(request.headers) })
return buildRequestContent(new ClientRequest(request))
}
@PackageScope Map buildServerRequestContent() {
return buildRequestContent(request,
{ request.urlPattern?.toServerSide() },
{ buildServerHeadersSection(request.headers) })
return buildRequestContent(new ServerRequest(request))
}
private Map<String, Object> buildRequestContent(Request request, Closure<String> buildUrlPattern, Closure<Map> buildHeaders) {
return [method : request.method,
url : request.url,
urlPattern: buildUrlPattern(),
urlPath : request.urlPath,
headers : buildHeaders()].findAll { it.value }
private Map<String, Object> buildRequestContent(ClientRequest request) {
return [method : request?.method?.clientValue,
url : request?.url?.clientValue,
urlPattern: request?.urlPattern?.clientValue,
urlPath : request?.urlPath?.clientValue,
headers : buildClientHeadersSection(request.headers)].findAll { it.value }
}
private Map<String, Object> buildRequestContent(ServerRequest request) {
return [method : request?.method?.serverValue,
url : request?.url?.serverValue,
urlPattern: request?.urlPattern?.serverValue,
urlPath : request?.urlPath?.serverValue,
headers : buildServerHeadersSection(request.headers)].findAll { it.value }
}
}

View File

@@ -2,7 +2,9 @@ package io.coderate.accurest.dsl
import groovy.transform.CompileStatic
import groovy.transform.PackageScope
import io.coderate.accurest.dsl.internal.ClientResponse
import io.coderate.accurest.dsl.internal.Response
import io.coderate.accurest.dsl.internal.ServerResponse
@CompileStatic
@PackageScope
@@ -15,21 +17,23 @@ class WiremockResponseStubStrategy extends BaseWiremockStubStrategy {
}
@PackageScope Map buildClientResponseContent() {
return buildResponseContent(response,
{ response.getBody().forClientSide() },
{ buildClientHeadersSection(response.headers) })
return buildResponseContent(new ClientResponse(response))
}
@PackageScope Map buildServerResponseContent() {
return buildResponseContent(response,
{ response.getBody().forServerSide() },
{ buildServerHeadersSection(response.headers) })
return buildResponseContent(new ServerResponse(response))
}
private Map<String, Object> buildResponseContent(Response response, Closure<Map<String, Object>> buildBody, Closure<Map> buildHeaders) {
return [status : response.status,
body : buildBody(),
headers: buildHeaders()].findAll { it.value }
private Map<String, Object> buildResponseContent(ClientResponse response) {
return [status : response?.status?.clientValue,
body : response?.getBody()?.forClientSide(),
headers: buildClientHeadersSection(response.headers)].findAll { it.value }
}
private Map<String, Object> buildResponseContent(ServerResponse response) {
return [status : response?.status?.serverValue,
body : response?.getBody()?.forServerSide(),
headers: buildServerHeadersSection(response.headers)].findAll { it.value }
}
}

View File

@@ -0,0 +1,13 @@
package io.coderate.accurest.dsl.internal
import groovy.transform.CompileStatic
@CompileStatic
class ClientDslProperty extends DslProperty {
ClientDslProperty(Object clientValue, Object serverValue) {
super(clientValue, serverValue) }
ClientDslProperty(Object singleValue) {
super(singleValue)
}
}

View File

@@ -0,0 +1,53 @@
package io.coderate.accurest.dsl.internal
import groovy.transform.PackageScope
import groovy.transform.TypeChecked
/**
* @TypeChecked instead of @CompileStatic due to usage of double dispatch.
* Double dispatch doesn't work if you're using @CompileStatic
*/
@TypeChecked
@PackageScope
class Common {
Map<String, DslProperty> convertObjectsToDslProperties(Map<String, Object> body) {
return body.collectEntries {
Map.Entry<String, Object> entry ->
[(entry.key): toDslProperty(entry.value)]
} as Map<String, DslProperty>
}
DslProperty toDslProperty(Object property) {
return new DslProperty(property)
}
DslProperty toDslProperty(DslProperty property) {
return property
}
DslProperty value(ClientDslProperty client, ServerDslProperty server) {
return new DslProperty(client.clientValue, server.serverValue)
}
DslProperty value(ServerDslProperty server, ClientDslProperty client) {
return new DslProperty(client.clientValue, server.serverValue)
}
DslProperty $(ClientDslProperty client, ServerDslProperty server) {
return value(client, server)
}
DslProperty $(ServerDslProperty server, ClientDslProperty client) {
return value(client, server)
}
ClientDslProperty client(Object clientValue) {
return new ClientDslProperty(clientValue)
}
ServerDslProperty server(Object serverValue) {
return new ServerDslProperty(serverValue)
}
}

View File

@@ -1,39 +0,0 @@
package io.coderate.accurest.dsl.internal
//TODO: Can we have different types for Client/Server (client: pattern(String), server: value(Boolean/Int)) ?
class CustomizableProperty<T, V> {
private T client
private V server
void client(T client) {
this.client = client
}
void server(V server) {
this.server = server
}
T toClientSide() {
return client
}
V toServerSide() {
return server
}
}
class StringCustomizableProperty extends CustomizableProperty<String, String> {
}
class SingleTypeCustomizableProperty<T> extends CustomizableProperty<T, T> {
SingleTypeCustomizableProperty(T value) {
client(value)
server(value)
}
@Override
public String toString() {
return toClientSide()
}
}

View File

@@ -2,17 +2,17 @@ package io.coderate.accurest.dsl.internal
import groovy.transform.CompileStatic
@CompileStatic
class DslProperty {
class DslProperty<T> {
final Object clientValue
final Object serverValue
final T clientValue
final T serverValue
DslProperty(Object clientValue, Object serverValue) {
DslProperty(T clientValue, T serverValue) {
this.clientValue = clientValue
this.serverValue = serverValue
}
DslProperty(Object singleValue) {
DslProperty(T singleValue) {
this.clientValue = singleValue
this.serverValue = singleValue
}

View File

@@ -1,5 +1,5 @@
package io.coderate.accurest.dsl.internal
enum JSONCompareMode {
STRICT, LENIENT, NON_EXTENSIBLE, STRICT_ORDER;
STRICT, LENIENT, NON_EXTENSIBLE, STRICT_ORDER
}

View File

@@ -1,32 +1,51 @@
package io.coderate.accurest.dsl.internal
import groovy.transform.CompileStatic
import groovy.transform.TypeChecked
import io.coderate.accurest.dsl.internal.Headers
import io.coderate.accurest.dsl.internal.StringCustomizableProperty
import static io.coderate.accurest.dsl.internal.DelegateHelper.delegateToClosure
@TypeChecked
class Request {
class Request extends Common {
String method
String url
StringCustomizableProperty urlPattern
String urlPath
DslProperty method
DslProperty url
DslProperty urlPattern
DslProperty urlPath
Headers headers
Request() {
}
Request(Request request) {
this.method = request.method
this.url = request.url
this.urlPattern = request.urlPattern
this.urlPath = request.urlPath
this.headers = request.headers
}
void method(String method) {
this.method = method
this.method = toDslProperty(method)
}
void method(DslProperty method) {
this.method = toDslProperty(method)
}
void url(String url) {
this.url = url
this.url = toDslProperty(url)
}
void urlPattern(@DelegatesTo(StringCustomizableProperty) Closure closure) {
StringCustomizableProperty urlPattern = new StringCustomizableProperty()
this.urlPattern = urlPattern
delegateToClosure(closure, urlPattern)
void url(DslProperty url) {
this.url = toDslProperty(url)
}
void urlPattern(String urlPattern) {
this.urlPattern = toDslProperty(urlPattern)
}
void urlPattern(DslProperty urlPattern) {
this.urlPattern = toDslProperty(urlPattern)
}
void headers(@DelegatesTo(Headers) Closure closure) {
@@ -36,6 +55,24 @@ class Request {
}
void urlPath(String urlPath) {
this.urlPath = urlPath
this.urlPath = toDslProperty(urlPath)
}
void urlPath(DslProperty urlPath) {
this.urlPath = toDslProperty(urlPath)
}
}
@CompileStatic
class ServerRequest extends Request {
ServerRequest(Request request) {
super(request)
}
}
@CompileStatic
class ClientRequest extends Request {
ClientRequest(Request request) {
super(request)
}
}

View File

@@ -1,21 +1,32 @@
package io.coderate.accurest.dsl.internal
import groovy.transform.CompileStatic
import groovy.transform.TypeChecked
import static io.coderate.accurest.dsl.internal.DelegateHelper.delegateToClosure
@TypeChecked
class Response {
class Response extends Common {
private static final String CLIENT_PROP_KEY = 'client'
private static final String SERVER_PROP_KEY = 'server'
private int status
private DslProperty status
private Headers headers
private Body body = new Body()
Response() {
}
Response(Response response) {
this.status = response.status
this.headers = response.headers
this.body = response.body
}
void status(int status) {
this.status = status
this.status = toDslProperty(status)
}
void status(DslProperty status) {
this.status = toDslProperty(status)
}
void headers(@DelegatesTo(Headers) Closure closure) {
@@ -27,26 +38,11 @@ class Response {
this.body = new Body(convertObjectsToDslProperties(body))
}
private Map<String, DslProperty> convertObjectsToDslProperties(Map<String, Object> body) {
return body.collectEntries {
Map.Entry<String, Object> entry ->
[(entry.key): entry.value instanceof DslProperty ? entry.value : new DslProperty(entry.value)]
} as Map<String, DslProperty>
}
DslProperty property(Map<String, Object> properties) {
return new DslProperty(properties[CLIENT_PROP_KEY], properties[SERVER_PROP_KEY])
}
DslProperty $(Map<String, Object> properties) {
return property(properties)
}
Body getBody() {
return body
}
int getStatus() {
DslProperty getStatus() {
return status
}
@@ -54,3 +50,17 @@ class Response {
return headers
}
}
@CompileStatic
class ServerResponse extends Response {
ServerResponse(Response request) {
super(request)
}
}
@CompileStatic
class ClientResponse extends Response {
ClientResponse(Response request) {
super(request)
}
}

View File

@@ -0,0 +1,13 @@
package io.coderate.accurest.dsl.internal
import groovy.transform.CompileStatic
@CompileStatic
class ServerDslProperty extends DslProperty {
ServerDslProperty(Object clientValue, Object serverValue) {
super(clientValue, serverValue) }
ServerDslProperty(Object singleValue) {
super(singleValue)
}
}

View File

@@ -1,51 +1,99 @@
package io.coderate.accurest.dsl.internal
import groovy.transform.TypeChecked
import static io.coderate.accurest.dsl.internal.DelegateHelper.delegateToClosure
@TypeChecked
class WithValuePattern {
SingleTypeCustomizableProperty<String> equalToJson
SingleTypeCustomizableProperty<String> equalToXml
StringCustomizableProperty matchesXPath
SingleTypeCustomizableProperty<JSONCompareMode> jsonCompareMode
SingleTypeCustomizableProperty<String> equalTo
StringCustomizableProperty contains
StringCustomizableProperty matches
StringCustomizableProperty doesNotMatch
CustomizableProperty<Boolean, Boolean> absent
StringCustomizableProperty matchesJsonPath
DslProperty<String> equalTo
DslProperty<String> equalToJson
DslProperty<String> equalToXml
DslProperty<String> matchesXPath
DslProperty<JSONCompareMode> jsonCompareMode
DslProperty<String> contains
DslProperty<String> matches
DslProperty<String> doesNotMatch
DslProperty<String> absent
DslProperty<String> matchesJsonPath
// void equalToJson(String equalToJson) {
// this.equalToJson = equalToJson
// }
//
void equalTo(String equalTo) {
this.equalTo = new SingleTypeCustomizableProperty(equalTo)
this.equalTo = new DslProperty<String>(equalTo)
}
// void equalToXml(String equalToXml) {
// this.equalToXml = equalToXml
// }
void matches(@DelegatesTo(StringCustomizableProperty) Closure closure) {
StringCustomizableProperty placeholderHaving = new StringCustomizableProperty()
this.matches = placeholderHaving
delegateToClosure(closure, placeholderHaving)
void equalTo(DslProperty equalTo) {
this.equalTo = equalTo
}
void doesNotMatch(@DelegatesTo(StringCustomizableProperty) Closure closure) {
StringCustomizableProperty placeholderHaving = new StringCustomizableProperty()
this.doesNotMatch = placeholderHaving
delegateToClosure(closure, placeholderHaving)
void equalToJson(String equalToJson) {
this.equalToJson = new DslProperty<String>(equalToJson)
}
void contains(@DelegatesTo(StringCustomizableProperty) Closure closure) {
StringCustomizableProperty placeholderHaving = new StringCustomizableProperty()
this.contains = placeholderHaving
delegateToClosure(closure, placeholderHaving)
void equalToJson(DslProperty equalToJson) {
this.equalToJson = equalToJson
}
// void jsonCompareMode(JSONCompareMode jsonCompareMode) {
// this.jsonCompareMode = jsonCompareMode
// }
void equalToXml(String equalToXml) {
this.equalToXml = new DslProperty<String>(equalToXml)
}
void equalToXml(DslProperty equalToXml) {
this.equalToXml = equalToXml
}
void matchesXPath(String matchesXPath) {
this.matchesXPath = new DslProperty<String>(matchesXPath)
}
void matchesXPath(DslProperty matchesXPath) {
this.matchesXPath = matchesXPath
}
void jsonCompareMode(JSONCompareMode jsonCompareMode) {
this.jsonCompareMode = new DslProperty<JSONCompareMode>(jsonCompareMode)
}
void jsonCompareMode(DslProperty jsonCompareMode) {
this.jsonCompareMode = jsonCompareMode
}
void contains(String contains) {
this.contains = new DslProperty<String>(contains)
}
void contains(DslProperty contains) {
this.contains = contains
}
void matches(String matches) {
this.matches = new DslProperty<String>(matches)
}
void matches(DslProperty matches) {
this.matches = matches
}
void doesNotMatch(String doesNotMatch) {
this.doesNotMatch = new DslProperty<String>(doesNotMatch)
}
void doesNotMatch(DslProperty doesNotMatch) {
this.doesNotMatch = doesNotMatch
}
void absent(String absent) {
this.absent = new DslProperty<String>(absent)
}
void absent(DslProperty absent) {
this.absent = absent
}
void matchesJsonPath(String matchesJsonPath) {
this.matchesJsonPath = new DslProperty<String>(matchesJsonPath)
}
void matchesJsonPath(DslProperty matchesJsonPath) {
this.matchesJsonPath = matchesJsonPath
}
}

View File

@@ -36,10 +36,7 @@ class WiremockGroovyDslResponseSpec extends Specification {
GroovyDsl dsl = GroovyDsl.make {
response {
headers {
header('Content-Type').matches {
client('text/xml')
server('text/*')
}
header('Content-Type').matches $(client('text/xml'), server('text/*'))
}
status 200
}
@@ -63,10 +60,7 @@ class WiremockGroovyDslResponseSpec extends Specification {
response {
status 200
headers {
header('Content-Type').matches {
client('text/xml')
server('text/*')
}
header('Content-Type').matches $(client('text/xml'), server('text/*'))
}
}
}

View File

@@ -14,20 +14,24 @@ class WiremockGroovyDslSpec extends Specification {
GroovyDsl groovyDsl = GroovyDsl.make {
request {
method('GET')
urlPattern {
client('/[0-9]{2}')
server('/12')
}
urlPattern $(client('/[0-9]{2}'), server('/12'))
}
response {
status(200)
status 200
body (
id : property(client: '123', server: { regex('[0-9]+') } ),
id : value(
client('123'),
server({ regex('[0-9]+') })
),
surname : $(
client('Kowalsky'),
server('Lewandowski')
),
name: 'Jan',
created : $(client: '2014-02-02 12:23:43', server: { currentDate(it) })
created : $(client('2014-02-02 12:23:43'), server({ currentDate(it) }))
)
headers {
header('Content-Type': 'text/plain')
header 'Content-Type': 'text/plain'
}
}
}
@@ -44,6 +48,7 @@ class WiremockGroovyDslSpec extends Specification {
"status": 200,
"body": {
"id": "123",
"surname": "Kowalsky",
"name": "Jan",
"created" : "2014-02-02 12:23:43"
},
@@ -60,17 +65,21 @@ class WiremockGroovyDslSpec extends Specification {
GroovyDsl groovyDsl = GroovyDsl.make {
request {
method('GET')
urlPattern {
client('/[0-9]{2}')
server('/12')
}
urlPattern $(client('/[0-9]{2}'), server('/12'))
}
response {
status(200)
body (
id : property(client: '123', server: '321' ),
name: 'Jan',
created : $(client: '2014-02-02 12:23:43', server: '1999-01-01 01:23:45')
id : value(
client('123'),
server('321')
),
surname : $(
client('Kowalsky'),
server('Lewandowski')
),
name: 'Jan',
created : $(client('2014-02-02 12:23:43'), server('1999-01-01 01:23:45'))
)
headers {
header('Content-Type': 'text/plain')
@@ -90,6 +99,7 @@ class WiremockGroovyDslSpec extends Specification {
"status": 200,
"body": {
"id": "321",
"surname": "Lewandowski",
"name": "Jan",
"created" : "1999-01-01 01:23:45"
},
@@ -137,9 +147,10 @@ class WiremockGroovyDslSpec extends Specification {
given:
GroovyDsl groovyDsl = GroovyDsl.make {
request {
urlPattern {
client('/^[0-9]{2}$')
}
urlPattern $(
client('/^[0-9]{2}$'),
server('/12')
)
}
}
expect:
@@ -154,10 +165,10 @@ class WiremockGroovyDslSpec extends Specification {
given:
GroovyDsl groovyDsl = GroovyDsl.make {
request {
urlPattern {
client('/^[0-9]{2}$')
server('/12')
}
urlPattern $(
client('/[0-9]{2}'),
server('/12')
)
}
}
expect:
@@ -204,18 +215,18 @@ class WiremockGroovyDslSpec extends Specification {
request {
headers {
header('Content-Type').equalTo('text/xml')
header('Accept').matches {
client('text/.*')
header('Accept').matches $(
client('text/.*'),
server('text/plain')
}
header('etag').doesNotMatch {
client('abcd.*')
)
header('etag').doesNotMatch $(
client('abcd.*'),
server('abcdef')
}
header('X-Custom-Header').contains {
client('2134')
)
header('X-Custom-Header').contains $(
client('2134'),
server('121345')
}
)
}
}
}
@@ -246,18 +257,18 @@ class WiremockGroovyDslSpec extends Specification {
request {
headers {
header('Content-Type').equalTo('text/xml')
header('Accept').matches {
client('text/.*')
header('Accept').matches $(
client('text/.*'),
server('text/plain')
}
header('etag').doesNotMatch {
client('abcd.*')
)
header('etag').doesNotMatch $(
client('abcd.*'),
server('abcdef')
}
header('X-Custom-Header').contains {
client('2134')
)
header('X-Custom-Header').contains $(
client('2134'),
server('121345')
}
)
}
}
}