[#42] Optional parameter

This commit is contained in:
Marcin Grzejszczak
2015-10-04 22:16:25 +02:00
parent 41658b774b
commit 9550a9ff08
5 changed files with 121 additions and 7 deletions

View File

@@ -16,16 +16,20 @@ class Common {
@Delegate private final RegexPatterns regexPatterns = new RegexPatterns()
Map<String, DslProperty> convertObjectsToDslProperties(Map<String, Object> body) {
return body.collectEntries {
return (body.collectEntries {
Map.Entry<String, Object> entry ->
[(entry.key): toDslProperty(entry.value)]
} as Map<String, DslProperty>
} as Map<String, DslProperty>).findAll {
!(it.value.clientValue instanceof Optional || it.value.serverValue instanceof Optional)
}
}
List convertObjectsToDslProperties(List body) {
return body.collect {
Collection convertObjectsToDslProperties(List body) {
return (body.collect {
Object element -> toDslProperty(element)
} as List
} as List).findAll {
!(it instanceof Optional)
}
}
DslProperty toDslProperty(Object property) {
@@ -53,6 +57,10 @@ class Common {
return new DslProperty(client.clientValue, server.serverValue)
}
DslProperty value(Object value) {
return new DslProperty(value)
}
DslProperty value(ServerDslProperty server, ClientDslProperty client) {
assertThatSidesMatch(client.clientValue, server.serverValue)
return new DslProperty(client.clientValue, server.serverValue)
@@ -90,6 +98,10 @@ class Common {
return new ServerDslProperty(serverValue)
}
Optional optional() {
return new Optional()
}
void assertThatSidesMatch(Pattern pattern, String value) {
assert value ==~ pattern
}

View File

@@ -0,0 +1,7 @@
package io.codearte.accurest.dsl.internal
/**
* Marker class to show that an element of message is optional
*/
class Optional {
}

View File

@@ -8,6 +8,7 @@ import io.codearte.accurest.dsl.internal.DslProperty
import io.codearte.accurest.dsl.internal.ExecutionProperty
import io.codearte.accurest.dsl.internal.Headers
import io.codearte.accurest.dsl.internal.MatchingStrategy
import io.codearte.accurest.dsl.internal.Optional
import org.codehaus.groovy.runtime.GStringImpl
import java.util.regex.Matcher
@@ -24,9 +25,11 @@ class ContentUtils {
it instanceof DslProperty ? it.clientValue : it
}
private static final Pattern TEMPORARY_PATTERN_HOLDER = Pattern.compile('REGEXP>>(.*)<<')
private static final Pattern TEMPORARY_PATTERN_HOLDER = Pattern.compile('.*REGEXP>>(.*)<<.*')
private static final Pattern TEMPORARY_EXECUTION_PATTERN_HOLDER = Pattern.compile('EXECUTION>>(.*)<<')
private static final String JSON_VALUE_PATTERN_FOR_REGEX = 'REGEXP>>%s<<'
private static final String JSON_VALUE_OPTIONAL = 'OPTIONAL>><<'
private static final Pattern OPTIONAL_PATTERN_HOLDER = Pattern.compile(JSON_VALUE_OPTIONAL)
private static final String JSON_VALUE_PATTERN_FOR_EXECUTION = '"EXECUTION>>%s<<"'
/**
@@ -157,6 +160,10 @@ class ContentUtils {
return String.format(JSON_VALUE_PATTERN_FOR_REGEX, pattern.pattern())
}
private static String transformJSONStringValue(Optional optional, Closure valueProvider) {
return JSON_VALUE_OPTIONAL
}
private static String transformJSONStringValue(ExecutionProperty property, Closure valueProvider) {
return String.format(JSON_VALUE_PATTERN_FOR_EXECUTION, property.executionCommand)
}
@@ -216,6 +223,10 @@ class ContentUtils {
String pattern = val[1]
return new ExecutionProperty(pattern)
}
Matcher optionalMatcher = OPTIONAL_PATTERN_HOLDER.matcher(string.trim())
if (optionalMatcher.matches()) {
return new Optional()
}
return string
}

View File

@@ -30,7 +30,7 @@ class JsonToJsonPathsConverter {
JsonPaths pathsAndValues = [] as Set
Object convertedJson = MapConverter.getClientOrServerSideValues(json, clientSide)
traverseRecursivelyForKey(convertedJson, ROOT_JSON_PATH_ELEMENT) { String key, Object value ->
if (value instanceof ExecutionProperty) {
if (value instanceof ExecutionProperty || value instanceof io.codearte.accurest.dsl.internal.Optional) {
return
}
JsonPathEntry entry = getValueToInsert(key, value)

View File

@@ -552,6 +552,90 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu
spockTest.contains('''$[?(@.message =~ /User not found by email = \\\\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,4}\\\\]/)]''')
}
def "should omit an optional field from body resolution"() {
given:
GroovyDsl contractDsl = GroovyDsl.make {
priority 1
request {
method 'POST'
url '/users/password'
headers {
header 'Content-Type': 'application/json'
}
body(
email: optional(),
callback_url: $(client(regex(hostname())), server('http://partners.com'))
)
}
response {
status 404
headers {
header 'Content-Type': 'application/json'
}
body(
code: optional(),
message: "User not found by email = [${value(server(regex(email())), client('not.existing@user.com'))}]"
)
}
}
MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
BlockBuilder blockBuilder = new BlockBuilder(" ")
when:
builder.appendTo(blockBuilder)
def spockTest = blockBuilder.toString()
then:
!spockTest.contains('''body('{"email":''')
!spockTest.contains('''parsedJson.read(\'\'\'$[?(@.email''')
!spockTest.contains('''REGEXP''')
!spockTest.contains('''OPTIONAL''')
!spockTest.contains('''Optional''')
}
def "should omit an optional field from body resolution with GString"() {
given:
GroovyDsl contractDsl = GroovyDsl.make {
priority 1
request {
method 'POST'
url '/users/password'
headers {
header 'Content-Type': 'application/json'
}
body(
""" {
"email" : "${value(optional())}",
"callback_url" : "${value(client(regex(hostname())), server('http://partners.com'))}"
}
"""
)
}
response {
status 404
headers {
header 'Content-Type': 'application/json'
}
body(
""" {
"code" : "${value(optional())}",
"message" : "User not found by email = [${value(server(regex(email())), client('not.existing@user.com'))}]"
}
"""
)
}
}
MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
BlockBuilder blockBuilder = new BlockBuilder(" ")
when:
builder.appendTo(blockBuilder)
def spockTest = blockBuilder.toString()
then:
!spockTest.contains('''body('{"email":''')
!spockTest.contains('''parsedJson.read(\'\'\'$[?(@.code''')
!spockTest.contains('''REGEXP''')
!spockTest.contains('''OPTIONAL''')
!spockTest.contains('''Optional''')
}
@Issue('72')
def "should make the execute method work"() {
given: