3
.gitignore
vendored
3
.gitignore
vendored
@@ -7,4 +7,5 @@ target/
|
||||
build/
|
||||
|
||||
hs_err_pid*
|
||||
.DS_Store
|
||||
.DS_Store
|
||||
*.log
|
||||
@@ -35,11 +35,14 @@ class RecursiveFilesConverter {
|
||||
return
|
||||
}
|
||||
String convertedContent = singleFileConverter.convertContent(entry.key.last().toString(), contract)
|
||||
if (!convertedContent) {
|
||||
return
|
||||
}
|
||||
Path absoluteTargetPath = createAndReturnTargetDirectory(sourceFile)
|
||||
File newGroovyFile = createTargetFileWithProperName(absoluteTargetPath, sourceFile)
|
||||
newGroovyFile.setText(convertedContent, StandardCharsets.UTF_8.toString())
|
||||
} catch (Exception e) {
|
||||
throw new ConversionAccurestException("Unable to make convertion of ${sourceFile.name}", e)
|
||||
throw new ConversionAccurestException("Unable to make conversion of ${sourceFile.name}", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,12 +52,12 @@ class RecursiveFilesConverter {
|
||||
Path relativePath = Paths.get(properties.contractsDslDir.toURI()).relativize(sourceFile.parentFile.toPath())
|
||||
Path absoluteTargetPath = properties.stubsOutputDir.toPath().resolve(relativePath)
|
||||
Files.createDirectories(absoluteTargetPath)
|
||||
absoluteTargetPath
|
||||
return absoluteTargetPath
|
||||
}
|
||||
|
||||
private File createTargetFileWithProperName(Path absoluteTargetPath, File sourceFile) {
|
||||
File newGroovyFile = new File(absoluteTargetPath.toFile(), singleFileConverter.generateOutputFileNameForInput(sourceFile.name))
|
||||
log.info("Creating new json [$newGroovyFile.path]")
|
||||
newGroovyFile
|
||||
return newGroovyFile
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ class RecursiveFilesConverterSpec extends Specification {
|
||||
and:
|
||||
def singleFileConverterStub = Stub(SingleFileConverter)
|
||||
singleFileConverterStub.canHandleFileName(_) >> { String fileName -> fileName.endsWith(".groovy") }
|
||||
singleFileConverterStub.convertContent(_) >> { "converted" }
|
||||
singleFileConverterStub.convertContent(_, _) >> { "converted" }
|
||||
singleFileConverterStub.generateOutputFileNameForInput(_) >> { String inputFileName -> inputFileName.replaceAll('.groovy', '.json') }
|
||||
|
||||
RecursiveFilesConverter recursiveFilesConverter = new RecursiveFilesConverter(singleFileConverterStub, properties)
|
||||
@@ -53,7 +53,7 @@ class RecursiveFilesConverterSpec extends Specification {
|
||||
and:
|
||||
def singleFileConverterStub = Stub(SingleFileConverter)
|
||||
singleFileConverterStub.canHandleFileName(_) >> { String fileName -> fileName.endsWith(".groovy") }
|
||||
singleFileConverterStub.convertContent(_) >> { "converted" }
|
||||
singleFileConverterStub.convertContent(_, _) >> { "converted" }
|
||||
singleFileConverterStub.generateOutputFileNameForInput(_) >> { String inputFileName -> inputFileName.replaceAll('.groovy', '.json') }
|
||||
|
||||
RecursiveFilesConverter recursiveFilesConverter = new RecursiveFilesConverter(singleFileConverterStub, properties)
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
package io.codearte.accurest
|
||||
|
||||
import groovy.transform.Canonical
|
||||
import groovy.transform.PackageScope
|
||||
import groovy.util.logging.Slf4j
|
||||
import io.codearte.accurest.builder.ClassBuilder
|
||||
import io.codearte.accurest.config.AccurestConfigProperties
|
||||
import io.codearte.accurest.config.TestFramework
|
||||
import io.codearte.accurest.config.TestMode
|
||||
import io.codearte.accurest.dsl.GroovyDsl
|
||||
import io.codearte.accurest.file.Contract
|
||||
import org.codehaus.groovy.control.CompilerConfiguration
|
||||
|
||||
import static io.codearte.accurest.builder.ClassBuilder.createClass
|
||||
import static io.codearte.accurest.builder.MethodBuilder.createTestMethod
|
||||
@@ -49,50 +52,88 @@ class SingleTestGenerator {
|
||||
clazz.addClassLevelAnnotation(configProperties.targetFramework.getOrderAnnotation())
|
||||
}
|
||||
|
||||
if (configProperties.testMode == TestMode.JAXRSCLIENT) {
|
||||
clazz.addStaticImport('javax.ws.rs.client.Entity.*')
|
||||
if (configProperties.targetFramework == TestFramework.JUNIT) {
|
||||
clazz.addImport('javax.ws.rs.core.Response')
|
||||
}
|
||||
} else if (configProperties.testMode == TestMode.MOCKMVC) {
|
||||
clazz.addStaticImport('com.jayway.restassured.module.mockmvc.RestAssuredMockMvc.*')
|
||||
} else {
|
||||
clazz.addStaticImport('com.jayway.restassured.RestAssured.*')
|
||||
}
|
||||
|
||||
if (configProperties.targetFramework == TestFramework.JUNIT) {
|
||||
if (configProperties.testMode == TestMode.MOCKMVC) {
|
||||
clazz.addImport('com.jayway.restassured.module.mockmvc.specification.MockMvcRequestSpecification')
|
||||
clazz.addImport('com.jayway.restassured.response.ResponseOptions')
|
||||
}
|
||||
clazz.addImport('org.junit.Test')
|
||||
clazz.addStaticImport('org.assertj.core.api.Assertions.assertThat')
|
||||
}
|
||||
|
||||
if (configProperties.ruleClassForTests) {
|
||||
clazz.addImport('org.junit.Rule').addRule(configProperties.ruleClassForTests)
|
||||
}
|
||||
|
||||
addJsonPathRelatedImports(clazz)
|
||||
|
||||
listOfFiles.each {
|
||||
clazz.addMethod(createTestMethod(it, configProperties))
|
||||
Map<ParsedDsl, TestType> contracts = listOfFiles.collectEntries {
|
||||
File stubsFile = it.path.toFile()
|
||||
log.debug("Stub content from file [${stubsFile.text}]")
|
||||
GroovyDsl stubContent = new GroovyShell(delegate.class.classLoader, new Binding(), new CompilerConfiguration(sourceEncoding:'UTF-8')).evaluate(stubsFile)
|
||||
TestType testType = (stubContent.inputMessage || stubContent.outputMessage) ? TestType.MESSAGING : TestType.HTTP
|
||||
return [(new ParsedDsl(it, stubContent, stubsFile)) : testType]
|
||||
}
|
||||
|
||||
boolean conditionalImportsAdded = false
|
||||
contracts.each { ParsedDsl key, TestType value ->
|
||||
if (!conditionalImportsAdded) {
|
||||
if (value == TestType.HTTP) {
|
||||
if (configProperties.testMode == TestMode.JAXRSCLIENT) {
|
||||
clazz.addStaticImport('javax.ws.rs.client.Entity.*')
|
||||
if (configProperties.targetFramework == TestFramework.JUNIT) {
|
||||
clazz.addImport('javax.ws.rs.core.Response')
|
||||
}
|
||||
} else if (configProperties.testMode == TestMode.MOCKMVC) {
|
||||
clazz.addStaticImport('com.jayway.restassured.module.mockmvc.RestAssuredMockMvc.*')
|
||||
} else {
|
||||
clazz.addStaticImport('com.jayway.restassured.RestAssured.*')
|
||||
}
|
||||
}
|
||||
if (configProperties.targetFramework == TestFramework.JUNIT) {
|
||||
if (value == TestType.HTTP && configProperties.testMode == TestMode.MOCKMVC) {
|
||||
clazz.addImport('com.jayway.restassured.module.mockmvc.specification.MockMvcRequestSpecification')
|
||||
clazz.addImport('com.jayway.restassured.response.ResponseOptions')
|
||||
}
|
||||
clazz.addImport('org.junit.Test')
|
||||
clazz.addStaticImport('org.assertj.core.api.Assertions.assertThat')
|
||||
}
|
||||
if (configProperties.ruleClassForTests) {
|
||||
clazz.addImport('org.junit.Rule').addRule(configProperties.ruleClassForTests)
|
||||
}
|
||||
if (value == TestType.MESSAGING) {
|
||||
addMessagingRelatedEntries(clazz)
|
||||
}
|
||||
conditionalImportsAdded = true
|
||||
}
|
||||
clazz.addMethod(createTestMethod(key.contract, key.stubsFile, key.groovyDsl, configProperties))
|
||||
}
|
||||
return clazz.build()
|
||||
}
|
||||
|
||||
@Canonical
|
||||
private static class ParsedDsl {
|
||||
Contract contract
|
||||
GroovyDsl groovyDsl
|
||||
File stubsFile
|
||||
}
|
||||
|
||||
private static enum TestType {
|
||||
MESSAGING, HTTP
|
||||
}
|
||||
|
||||
private boolean isScenarioClass(Collection<Contract> listOfFiles) {
|
||||
listOfFiles.find({ it.order != null }) != null
|
||||
}
|
||||
|
||||
private ClassBuilder addJsonPathRelatedImports(ClassBuilder clazz) {
|
||||
clazz.addImport(['com.jayway.jsonpath.DocumentContext',
|
||||
'com.jayway.jsonpath.JsonPath'])
|
||||
'com.jayway.jsonpath.JsonPath',
|
||||
])
|
||||
if (jsonAssertPresent()) {
|
||||
clazz.addStaticImport(JSON_ASSERT_STATIC_IMPORT)
|
||||
}
|
||||
}
|
||||
|
||||
private ClassBuilder addMessagingRelatedEntries(ClassBuilder clazz) {
|
||||
clazz.addField(['@Inject AccurestMessaging accurestMessaging',
|
||||
'ObjectMapper accurestObjectMapper = new ObjectMapper()'
|
||||
])
|
||||
clazz.addImport([ 'javax.inject.Inject',
|
||||
'com.fasterxml.jackson.databind.ObjectMapper',
|
||||
'io.codearte.accurest.messaging.AccurestMessage',
|
||||
'io.codearte.accurest.messaging.AccurestMessaging',
|
||||
])
|
||||
clazz.addStaticImport('io.codearte.accurest.messaging.AccurestMessagingUtil.headers')
|
||||
}
|
||||
|
||||
private static boolean jsonAssertPresent() {
|
||||
try {
|
||||
Class.forName(JSON_ASSERT_CLASS)
|
||||
|
||||
@@ -3,7 +3,6 @@ package io.codearte.accurest.builder
|
||||
import io.codearte.accurest.config.AccurestConfigProperties
|
||||
import io.codearte.accurest.config.TestFramework
|
||||
import io.codearte.accurest.util.NamesUtil
|
||||
|
||||
/**
|
||||
* @author Jakub Kubrynski
|
||||
*/
|
||||
@@ -15,6 +14,7 @@ class ClassBuilder {
|
||||
private final List<String> imports = []
|
||||
private final List<String> staticImports = []
|
||||
private final List<String> rules = []
|
||||
private final List<String> fields = []
|
||||
private final List<MethodBuilder> methods = []
|
||||
private final List<String> classLevelAnnotations = []
|
||||
private final TestFramework lang
|
||||
@@ -49,6 +49,7 @@ class ClassBuilder {
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
ClassBuilder addStaticImport(String importToAdd) {
|
||||
staticImports << importToAdd
|
||||
return this
|
||||
@@ -59,6 +60,23 @@ class ClassBuilder {
|
||||
return this
|
||||
}
|
||||
|
||||
ClassBuilder addField(String fieldToAdd) {
|
||||
fields << appendColonIfJUniTest(fieldToAdd)
|
||||
return this
|
||||
}
|
||||
|
||||
private String appendColonIfJUniTest(String field) {
|
||||
if (lang == TestFramework.JUNIT && !field.endsWith(';')) {
|
||||
return "$field;"
|
||||
}
|
||||
return field
|
||||
}
|
||||
|
||||
ClassBuilder addField(List<String> fieldsToAdd) {
|
||||
fields.addAll(fieldsToAdd.collect { appendColonIfJUniTest(it) })
|
||||
return this
|
||||
}
|
||||
|
||||
ClassBuilder addRule(String ruleClass) {
|
||||
imports << ruleClass
|
||||
rules << NamesUtil.afterLastDot(ruleClass)
|
||||
@@ -105,6 +123,13 @@ class ClassBuilder {
|
||||
clazz.addEmptyLine()
|
||||
}
|
||||
|
||||
fields.sort().each {
|
||||
clazz.addLine(it)
|
||||
}
|
||||
if (!fields.empty) {
|
||||
clazz.addEmptyLine()
|
||||
}
|
||||
|
||||
methods.each {
|
||||
clazz.addBlock(it)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
package io.codearte.accurest.builder
|
||||
|
||||
import groovy.json.StringEscapeUtils
|
||||
import groovy.transform.PackageScope
|
||||
import groovy.transform.TypeChecked
|
||||
import io.codearte.accurest.dsl.GroovyDsl
|
||||
import io.codearte.accurest.dsl.internal.ExecutionProperty
|
||||
import io.codearte.accurest.dsl.internal.Header
|
||||
import io.codearte.accurest.dsl.internal.Input
|
||||
import io.codearte.accurest.dsl.internal.NamedProperty
|
||||
|
||||
import java.util.regex.Pattern
|
||||
|
||||
import static io.codearte.accurest.config.TestFramework.JUNIT
|
||||
/**
|
||||
* @author Jakub Kubrynski
|
||||
*/
|
||||
@PackageScope
|
||||
@TypeChecked
|
||||
class JUnitMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder {
|
||||
|
||||
JUnitMessagingMethodBodyBuilder(GroovyDsl stubDefinition) {
|
||||
super(stubDefinition)
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getInputString(Input request) {
|
||||
if (request.triggeredBy) {
|
||||
return request.triggeredBy.executionCommand
|
||||
}
|
||||
return "accurestMessaging.send(inputMessage, \"${request.messageFrom}\")"
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getResponseBodyPropertyComparisonString(String property, String value) {
|
||||
return "responseBody$property == \"${value}\""
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processBodyElement(BlockBuilder blockBuilder, String property, ExecutionProperty exec) {
|
||||
blockBuilder.addLine("${exec.insertValue("parsedJson.read('\\\$$property')")}")
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processBodyElement(BlockBuilder blockBuilder, String property, Map.Entry entry) {
|
||||
processBodyElement(blockBuilder, property + "." + entry.key, entry.value)
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processHeaderElement(BlockBuilder blockBuilder, String property, String value) {
|
||||
blockBuilder.addLine("assertThat(response.getHeader(\"$property\")).${createHeaderComparison(value)}")
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processHeaderElement(BlockBuilder blockBuilder, String property, Pattern pattern) {
|
||||
blockBuilder.addLine("assertThat(response.getHeader(\"$property\")).${createHeaderComparison(pattern)}")
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processHeaderElement(BlockBuilder blockBuilder, String property, ExecutionProperty exec) {
|
||||
blockBuilder.addLine("${exec.insertValue("response.getHeader(\"$property\")")};")
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateResponseCodeBlock(BlockBuilder bb) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateResponseHeadersBlock(BlockBuilder bb) {
|
||||
bb.addLine("""AccurestMessage response = accurestMessaging.receiveMessage("${outputMessage.sentTo}");""")
|
||||
outputMessage.headers?.collect { Header header ->\
|
||||
processHeaderElement(bb, header.name, header.serverValue)
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getResponseAsString() {
|
||||
return 'accurestObjectMapper.writeValueAsString(response.getPayload())'
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String addCommentSignIfRequired(String baseString) {
|
||||
return "// $baseString"
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockBuilder addColonIfRequired(BlockBuilder blockBuilder) {
|
||||
blockBuilder.addAtTheEnd(JUNIT.lineSuffix)
|
||||
return blockBuilder
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getPropertyInListString(String property, Integer listIndex) {
|
||||
return "$property[$listIndex]" ?: ''
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String convertUnicodeEscapesIfRequired(String json) {
|
||||
return StringEscapeUtils.unescapeJavaScript(json)
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getParsedXmlResponseBodyString(String responseString) {
|
||||
return "Object responseBody = new XmlSlurper().parseText($responseString);"
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getSimpleResponseBodyString(String responseString) {
|
||||
return "Object responseBody = ($responseString);"
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getInputString() {
|
||||
String request = 'AccurestMessage inputMessage = accurestMessaging.create('
|
||||
if (inputMessage.messageBody) {
|
||||
request = "${request}\n\t\t\t\"${StringEscapeUtils.escapeJava(bodyAsString)}\"\n\t\t"
|
||||
}
|
||||
if (inputMessage.messageHeaders) {
|
||||
request = "${request}, headers()\n"
|
||||
}
|
||||
inputMessage.messageHeaders?.collect { Header header ->
|
||||
request = "${request}\t\t\t${getHeaderString(header)}"
|
||||
}
|
||||
return "${request})"
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getHeaderString(Header header) {
|
||||
return ".header(\"${getTestSideValue(header.name)}\", \"${getTestSideValue(header.serverValue)}\")"
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBodyString(String bodyAsString) {
|
||||
return ''
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getMultipartFileParameterContent(String propertyName, NamedProperty propertyValue) {
|
||||
return ""
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getParameterString(Map.Entry<String, Object> parameter) {
|
||||
return ""
|
||||
}
|
||||
|
||||
protected String convertHeaderComparison(String headerValue) {
|
||||
return " == '$headerValue'"
|
||||
}
|
||||
|
||||
protected String convertHeaderComparison(Pattern headerValue) {
|
||||
return "==~ java.util.regex.Pattern.compile('$headerValue')"
|
||||
}
|
||||
|
||||
protected String createHeaderComparison(Object headerValue) {
|
||||
String escapedHeader = convertUnicodeEscapesIfRequired("$headerValue")
|
||||
return "isEqualTo(\"$escapedHeader\");"
|
||||
}
|
||||
|
||||
protected String createHeaderComparison(Pattern headerValue) {
|
||||
String escapedHeader = convertUnicodeEscapesIfRequired("$headerValue")
|
||||
return "matches(\"$escapedHeader\");"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -21,7 +21,7 @@ import static io.codearte.accurest.util.ContentUtils.getJavaMultipartFileParamet
|
||||
*/
|
||||
@TypeChecked
|
||||
@PackageScope
|
||||
abstract class JUnitMethodBodyBuilder extends MethodBodyBuilder {
|
||||
abstract class JUnitMethodBodyBuilder extends RequestProcessingMethodBodyBuilder {
|
||||
|
||||
JUnitMethodBodyBuilder(GroovyDsl stubDefinition) {
|
||||
super(stubDefinition)
|
||||
@@ -87,12 +87,12 @@ abstract class JUnitMethodBodyBuilder extends MethodBodyBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getResponseString(Request request) {
|
||||
protected String getInputString(Request request) {
|
||||
return 'ResponseOptions response = given().spec(request)'
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getRequestString() {
|
||||
protected String getInputString() {
|
||||
return 'MockMvcRequestSpecification request = given()'
|
||||
}
|
||||
|
||||
|
||||
@@ -12,9 +12,9 @@ import java.util.regex.Pattern
|
||||
|
||||
@PackageScope
|
||||
@TypeChecked
|
||||
class JaxRsClientSpockMethodBodyBuilder extends SpockMethodBodyBuilder {
|
||||
class JaxRsClientSpockMethodRequestProcessingBodyBuilder extends SpockMethodRequestProcessingBodyBuilder {
|
||||
|
||||
JaxRsClientSpockMethodBodyBuilder(GroovyDsl stubDefinition) {
|
||||
JaxRsClientSpockMethodRequestProcessingBodyBuilder(GroovyDsl stubDefinition) {
|
||||
super(stubDefinition)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
package io.codearte.accurest.builder
|
||||
|
||||
import groovy.json.JsonOutput
|
||||
import groovy.transform.PackageScope
|
||||
import groovy.transform.TypeChecked
|
||||
import io.codearte.accurest.dsl.GroovyDsl
|
||||
import io.codearte.accurest.dsl.internal.Input
|
||||
import io.codearte.accurest.dsl.internal.OutputMessage
|
||||
import io.codearte.accurest.util.ContentType
|
||||
|
||||
import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromContent
|
||||
import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromHeader
|
||||
/**
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @since 2016-02-17
|
||||
*/
|
||||
@TypeChecked
|
||||
@PackageScope
|
||||
abstract class MessagingMethodBodyBuilder extends MethodBodyBuilder {
|
||||
|
||||
protected final Input inputMessage
|
||||
protected final OutputMessage outputMessage
|
||||
|
||||
MessagingMethodBodyBuilder(GroovyDsl stubDefinition) {
|
||||
this.inputMessage = stubDefinition.inputMessage
|
||||
this.outputMessage = stubDefinition.outputMessage
|
||||
}
|
||||
|
||||
protected abstract String getInputString(Input request)
|
||||
|
||||
@Override
|
||||
protected boolean hasGivenSection() {
|
||||
return !inputMessage.triggeredBy
|
||||
}
|
||||
|
||||
protected void processInput(BlockBuilder bb) {
|
||||
|
||||
}
|
||||
|
||||
protected void when(BlockBuilder bb) {
|
||||
bb.addLine(getInputString(inputMessage))
|
||||
bb.indent()
|
||||
|
||||
addColonIfRequired(bb)
|
||||
bb.unindent()
|
||||
}
|
||||
|
||||
protected void then(BlockBuilder bb) {
|
||||
validateResponseCodeBlock(bb)
|
||||
if (inputMessage.assertThat) {
|
||||
bb.addLine(inputMessage.assertThat.executionCommand)
|
||||
addColonIfRequired(bb)
|
||||
}
|
||||
if (outputMessage) {
|
||||
if (outputMessage.headers) {
|
||||
validateResponseHeadersBlock(bb)
|
||||
}
|
||||
if (outputMessage.body) {
|
||||
bb.endBlock()
|
||||
if (outputMessage.headers) {
|
||||
bb.addLine(addCommentSignIfRequired('and:')).startBlock()
|
||||
}
|
||||
validateResponseBodyBlock(bb, outputMessage.body.serverValue)
|
||||
}
|
||||
if (outputMessage.assertThat) {
|
||||
bb.addLine(outputMessage.assertThat.executionCommand)
|
||||
addColonIfRequired(bb)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected ContentType getResponseContentType() {
|
||||
ContentType contentType = recognizeContentTypeFromHeader(outputMessage.headers)
|
||||
if (contentType == ContentType.UNKNOWN) {
|
||||
contentType = recognizeContentTypeFromContent(outputMessage.body.serverValue)
|
||||
}
|
||||
return contentType
|
||||
}
|
||||
|
||||
protected String getBodyAsString() {
|
||||
Object bodyValue = extractServerValueFromBody(inputMessage.messageBody.serverValue)
|
||||
String json = new JsonOutput().toJson(bodyValue)
|
||||
json = convertUnicodeEscapesIfRequired(json)
|
||||
return trimRepeatedQuotes(json)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,19 +1,8 @@
|
||||
package io.codearte.accurest.builder
|
||||
|
||||
import groovy.json.JsonOutput
|
||||
import groovy.transform.PackageScope
|
||||
import groovy.transform.TypeChecked
|
||||
import groovy.transform.TypeCheckingMode
|
||||
import io.codearte.accurest.dsl.GroovyDsl
|
||||
import io.codearte.accurest.dsl.internal.DslProperty
|
||||
import io.codearte.accurest.dsl.internal.ExecutionProperty
|
||||
import io.codearte.accurest.dsl.internal.Header
|
||||
import io.codearte.accurest.dsl.internal.MatchingStrategy
|
||||
import io.codearte.accurest.dsl.internal.NamedProperty
|
||||
import io.codearte.accurest.dsl.internal.QueryParameter
|
||||
import io.codearte.accurest.dsl.internal.Request
|
||||
import io.codearte.accurest.dsl.internal.Response
|
||||
import io.codearte.accurest.dsl.internal.Url
|
||||
import io.codearte.accurest.dsl.internal.*
|
||||
import io.codearte.accurest.util.ContentType
|
||||
import io.codearte.accurest.util.JsonPaths
|
||||
import io.codearte.accurest.util.JsonToJsonPathsConverter
|
||||
@@ -22,9 +11,6 @@ import io.codearte.accurest.util.MapConverter
|
||||
import java.util.regex.Pattern
|
||||
|
||||
import static io.codearte.accurest.util.ContentUtils.extractValue
|
||||
import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromContent
|
||||
import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromHeader
|
||||
|
||||
/**
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @since 2016-02-17
|
||||
@@ -33,14 +19,6 @@ import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromHea
|
||||
@PackageScope
|
||||
abstract class MethodBodyBuilder {
|
||||
|
||||
protected final Request request
|
||||
protected final Response response
|
||||
|
||||
MethodBodyBuilder(GroovyDsl stubDefinition) {
|
||||
this.request = stubDefinition.request
|
||||
this.response = stubDefinition.response
|
||||
}
|
||||
|
||||
protected abstract void validateResponseCodeBlock(BlockBuilder bb)
|
||||
|
||||
protected abstract void validateResponseHeadersBlock(BlockBuilder bb)
|
||||
@@ -71,9 +49,7 @@ abstract class MethodBodyBuilder {
|
||||
|
||||
protected abstract String getSimpleResponseBodyString(String responseString)
|
||||
|
||||
protected abstract String getResponseString(Request request)
|
||||
|
||||
protected abstract String getRequestString()
|
||||
protected abstract String getInputString()
|
||||
|
||||
protected abstract String getHeaderString(Header header)
|
||||
|
||||
@@ -83,30 +59,30 @@ abstract class MethodBodyBuilder {
|
||||
|
||||
protected abstract String getParameterString(Map.Entry<String, Object> parameter)
|
||||
|
||||
protected abstract void processInput(BlockBuilder bb)
|
||||
|
||||
protected abstract void when(BlockBuilder bb)
|
||||
|
||||
protected abstract void then(BlockBuilder bb)
|
||||
|
||||
protected abstract ContentType getResponseContentType()
|
||||
|
||||
protected abstract String getBodyAsString()
|
||||
|
||||
protected abstract boolean hasGivenSection()
|
||||
|
||||
void appendTo(BlockBuilder blockBuilder) {
|
||||
blockBuilder.startBlock()
|
||||
|
||||
givenBlock(blockBuilder)
|
||||
if (hasGivenSection()) {
|
||||
givenBlock(blockBuilder)
|
||||
}
|
||||
whenBlock(blockBuilder)
|
||||
thenBlock(blockBuilder)
|
||||
|
||||
blockBuilder.endBlock()
|
||||
}
|
||||
|
||||
protected void thenBlock(BlockBuilder bb) {
|
||||
bb.addLine(addCommentSignIfRequired('then:'))
|
||||
bb.startBlock()
|
||||
then(bb)
|
||||
bb.endBlock()
|
||||
}
|
||||
|
||||
protected void whenBlock(BlockBuilder bb) {
|
||||
bb.addLine(addCommentSignIfRequired('when:'))
|
||||
bb.startBlock()
|
||||
when(bb)
|
||||
bb.endBlock().addEmptyLine()
|
||||
}
|
||||
|
||||
protected void givenBlock(BlockBuilder bb) {
|
||||
bb.addLine(addCommentSignIfRequired('given:'))
|
||||
bb.startBlock()
|
||||
@@ -114,48 +90,29 @@ abstract class MethodBodyBuilder {
|
||||
bb.endBlock().addEmptyLine()
|
||||
}
|
||||
|
||||
protected void whenBlock(BlockBuilder bb) {
|
||||
bb.addLine(addCommentSignIfRequired('when:'))
|
||||
bb.startBlock()
|
||||
when(bb)
|
||||
bb.endBlock().addEmptyLine()
|
||||
}
|
||||
|
||||
protected void thenBlock(BlockBuilder bb) {
|
||||
bb.addLine(addCommentSignIfRequired('then:'))
|
||||
bb.startBlock()
|
||||
then(bb)
|
||||
bb.endBlock()
|
||||
}
|
||||
|
||||
protected void given(BlockBuilder bb) {
|
||||
bb.addLine(getRequestString())
|
||||
bb.addLine(getInputString())
|
||||
bb.indent()
|
||||
request.headers?.collect { Header header ->
|
||||
bb.addLine(getHeaderString(header))
|
||||
}
|
||||
if (request.body) {
|
||||
bb.addLine(getBodyString(bodyAsString))
|
||||
}
|
||||
if (request.multipart) {
|
||||
multipartParameters?.each { Map.Entry<String, Object> entry -> bb.addLine(getMultipartParameterLine(entry)) }
|
||||
}
|
||||
processInput(bb)
|
||||
addColonIfRequired(bb)
|
||||
bb.unindent()
|
||||
}
|
||||
|
||||
protected void when(BlockBuilder bb) {
|
||||
bb.addLine(getResponseString(request))
|
||||
bb.indent()
|
||||
|
||||
String url = buildUrl(request)
|
||||
String method = request.method.serverValue.toString().toLowerCase()
|
||||
|
||||
bb.addLine(/.${method}("$url")/)
|
||||
addColonIfRequired(bb)
|
||||
bb.unindent()
|
||||
}
|
||||
|
||||
protected void then(BlockBuilder bb) {
|
||||
validateResponseCodeBlock(bb)
|
||||
if (response.headers) {
|
||||
validateResponseHeadersBlock(bb)
|
||||
}
|
||||
if (response.body) {
|
||||
bb.endBlock()
|
||||
bb.addLine(addCommentSignIfRequired('and:')).startBlock()
|
||||
validateResponseBodyBlock(bb)
|
||||
}
|
||||
}
|
||||
|
||||
private void validateResponseBodyBlock(BlockBuilder bb) {
|
||||
def responseBody = response.body.serverValue
|
||||
protected void validateResponseBodyBlock(BlockBuilder bb, Object responseBody) {
|
||||
ContentType contentType = getResponseContentType()
|
||||
if (responseBody instanceof GString) {
|
||||
responseBody = extractValue(responseBody, contentType, { DslProperty dslProperty -> dslProperty.serverValue })
|
||||
@@ -179,14 +136,6 @@ abstract class MethodBodyBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
private ContentType getResponseContentType() {
|
||||
ContentType contentType = recognizeContentTypeFromHeader(response.headers)
|
||||
if (contentType == ContentType.UNKNOWN) {
|
||||
contentType = recognizeContentTypeFromContent(response.body.serverValue)
|
||||
}
|
||||
return contentType
|
||||
}
|
||||
|
||||
protected void appendJsonPath(BlockBuilder blockBuilder, String json) {
|
||||
blockBuilder.addLine(("DocumentContext parsedJson = JsonPath.parse($json)"))
|
||||
addColonIfRequired(blockBuilder)
|
||||
@@ -212,17 +161,6 @@ abstract class MethodBodyBuilder {
|
||||
protected void processBodyElement(BlockBuilder blockBuilder, String property, Object value) {
|
||||
}
|
||||
|
||||
protected String getBodyAsString() {
|
||||
Object bodyValue = extractServerValueFromBody(request.body.serverValue)
|
||||
String json = new JsonOutput().toJson(bodyValue)
|
||||
json = convertUnicodeEscapesIfRequired(json)
|
||||
return trimRepeatedQuotes(json)
|
||||
}
|
||||
|
||||
protected Map<String, Object> getMultipartParameters() {
|
||||
return (Map<String, Object>) request?.multipart?.serverValue
|
||||
}
|
||||
|
||||
protected String trimRepeatedQuotes(String toTrim) {
|
||||
return toTrim.startsWith('"') ? toTrim.replaceAll('"', '') : toTrim
|
||||
}
|
||||
@@ -236,18 +174,6 @@ abstract class MethodBodyBuilder {
|
||||
return bodyValue
|
||||
}
|
||||
|
||||
protected boolean allowedQueryParameter(QueryParameter param) {
|
||||
return allowedQueryParameter(param.serverValue)
|
||||
}
|
||||
|
||||
protected boolean allowedQueryParameter(MatchingStrategy matchingStrategy) {
|
||||
return matchingStrategy.type != MatchingStrategy.Type.ABSENT
|
||||
}
|
||||
|
||||
protected boolean allowedQueryParameter(Object o) {
|
||||
return true
|
||||
}
|
||||
|
||||
protected String resolveParamValue(QueryParameter param) {
|
||||
return resolveParamValue(param.serverValue)
|
||||
}
|
||||
@@ -260,14 +186,6 @@ abstract class MethodBodyBuilder {
|
||||
return matchingStrategy.serverValue.toString()
|
||||
}
|
||||
|
||||
protected ContentType getRequestContentType() {
|
||||
ContentType contentType = recognizeContentTypeFromHeader(request.headers)
|
||||
if (contentType == ContentType.UNKNOWN) {
|
||||
contentType = recognizeContentTypeFromContent(request.body.serverValue)
|
||||
}
|
||||
return contentType
|
||||
}
|
||||
|
||||
protected String getTestSideValue(Object object) {
|
||||
return MapConverter.getTestSideValues(object).toString()
|
||||
}
|
||||
@@ -285,38 +203,5 @@ abstract class MethodBodyBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
protected String buildUrl(Request request) {
|
||||
if (request.url)
|
||||
return getTestSideValue(buildUrlFromUrlPath(request.url))
|
||||
if (request.urlPath)
|
||||
return getTestSideValue(buildUrlFromUrlPath(request.urlPath))
|
||||
throw new IllegalStateException("URL is not set!")
|
||||
}
|
||||
|
||||
@TypeChecked(TypeCheckingMode.SKIP)
|
||||
protected String buildUrlFromUrlPath(Url url) {
|
||||
if (hasQueryParams(url)) {
|
||||
String params = url.queryParameters.parameters
|
||||
.findAll(this.&allowedQueryParameter)
|
||||
.inject([] as List<String>) { List<String> result, QueryParameter param ->
|
||||
result << "${param.name}=${resolveParamValue(param).toString()}"
|
||||
}
|
||||
.join('&')
|
||||
return "${MapConverter.getTestSideValues(url.serverValue)}?$params"
|
||||
}
|
||||
return MapConverter.getTestSideValues(url.serverValue)
|
||||
}
|
||||
|
||||
protected String getMultipartParameterLine(Map.Entry<String, Object> parameter) {
|
||||
if (parameter.value instanceof NamedProperty) {
|
||||
return ".multiPart(${getMultipartFileParameterContent(parameter.key, (NamedProperty) parameter.value)})"
|
||||
}
|
||||
return getParameterString(parameter)
|
||||
}
|
||||
|
||||
|
||||
private boolean hasQueryParams(Url url) {
|
||||
return url.queryParameters
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,8 +7,6 @@ import io.codearte.accurest.config.TestMode
|
||||
import io.codearte.accurest.dsl.GroovyDsl
|
||||
import io.codearte.accurest.file.Contract
|
||||
import io.codearte.accurest.util.NamesUtil
|
||||
import org.codehaus.groovy.control.CompilerConfiguration
|
||||
|
||||
/**
|
||||
* @author Jakub Kubrynski
|
||||
*/
|
||||
@@ -27,10 +25,7 @@ class MethodBuilder {
|
||||
this.configProperties = configProperties
|
||||
}
|
||||
|
||||
static MethodBuilder createTestMethod(Contract contract, AccurestConfigProperties configProperties) {
|
||||
File stubsFile = contract.path.toFile()
|
||||
log.debug("Stub content from file [${stubsFile.text}]")
|
||||
GroovyDsl stubContent = new GroovyShell(this.classLoader, new Binding(), new CompilerConfiguration(sourceEncoding:'UTF-8')).evaluate(stubsFile)
|
||||
static MethodBuilder createTestMethod(Contract contract, File stubsFile, GroovyDsl stubContent, AccurestConfigProperties configProperties) {
|
||||
log.debug("Stub content Groovy DSL [$stubContent]")
|
||||
String methodName = NamesUtil.camelCase(NamesUtil.toLastDot(NamesUtil.afterLast(stubsFile.path, File.separator)))
|
||||
return new MethodBuilder(methodName, stubContent, configProperties, contract.ignored)
|
||||
@@ -43,12 +38,18 @@ class MethodBuilder {
|
||||
if (ignored) {
|
||||
blockBuilder.addLine('@Ignore')
|
||||
}
|
||||
blockBuilder.addLine(configProperties.targetFramework.methodModifier + "validate_$methodName() {")
|
||||
blockBuilder.addLine(configProperties.targetFramework.methodModifier + "validate_$methodName() throws Exception {")
|
||||
getMethodBodyBuilder().appendTo(blockBuilder)
|
||||
blockBuilder.addLine('}')
|
||||
}
|
||||
|
||||
private MethodBodyBuilder getMethodBodyBuilder() {
|
||||
if (stubContent.inputMessage || stubContent.outputMessage) {
|
||||
if (configProperties.targetFramework == TestFramework.JUNIT){
|
||||
return new JUnitMessagingMethodBodyBuilder(stubContent)
|
||||
}
|
||||
return new SpockMessagingMethodBodyBuilder(stubContent)
|
||||
}
|
||||
if (configProperties.testMode == TestMode.MOCKMVC && configProperties.targetFramework == TestFramework.JUNIT){
|
||||
return new MockMvcJUnitMethodBodyBuilder(stubContent)
|
||||
}
|
||||
@@ -56,9 +57,9 @@ class MethodBuilder {
|
||||
if (configProperties.targetFramework == TestFramework.JUNIT){
|
||||
return new JaxRsClientJUnitMethodBodyBuilder(stubContent)
|
||||
}
|
||||
return new JaxRsClientSpockMethodBodyBuilder(stubContent)
|
||||
return new JaxRsClientSpockMethodRequestProcessingBodyBuilder(stubContent)
|
||||
}
|
||||
return new MockMvcSpockMethodBodyBuilder(stubContent)
|
||||
return new MockMvcSpockMethodRequestProcessingBodyBuilder(stubContent)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,9 +10,9 @@ import java.util.regex.Pattern
|
||||
|
||||
@PackageScope
|
||||
@TypeChecked
|
||||
class MockMvcSpockMethodBodyBuilder extends SpockMethodBodyBuilder {
|
||||
class MockMvcSpockMethodRequestProcessingBodyBuilder extends SpockMethodRequestProcessingBodyBuilder {
|
||||
|
||||
MockMvcSpockMethodBodyBuilder(GroovyDsl stubDefinition) {
|
||||
MockMvcSpockMethodRequestProcessingBodyBuilder(GroovyDsl stubDefinition) {
|
||||
super(stubDefinition)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
package io.codearte.accurest.builder
|
||||
|
||||
import groovy.json.JsonOutput
|
||||
import groovy.transform.PackageScope
|
||||
import groovy.transform.TypeChecked
|
||||
import groovy.transform.TypeCheckingMode
|
||||
import io.codearte.accurest.dsl.GroovyDsl
|
||||
import io.codearte.accurest.dsl.internal.Header
|
||||
import io.codearte.accurest.dsl.internal.MatchingStrategy
|
||||
import io.codearte.accurest.dsl.internal.NamedProperty
|
||||
import io.codearte.accurest.dsl.internal.QueryParameter
|
||||
import io.codearte.accurest.dsl.internal.Request
|
||||
import io.codearte.accurest.dsl.internal.Response
|
||||
import io.codearte.accurest.dsl.internal.Url
|
||||
import io.codearte.accurest.util.ContentType
|
||||
import io.codearte.accurest.util.MapConverter
|
||||
|
||||
import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromContent
|
||||
import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromHeader
|
||||
|
||||
/**
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @since 2016-02-17
|
||||
*/
|
||||
@TypeChecked
|
||||
@PackageScope
|
||||
abstract class RequestProcessingMethodBodyBuilder extends MethodBodyBuilder {
|
||||
|
||||
protected final Request request
|
||||
protected final Response response
|
||||
|
||||
RequestProcessingMethodBodyBuilder(GroovyDsl stubDefinition) {
|
||||
this.request = stubDefinition.request
|
||||
this.response = stubDefinition.response
|
||||
}
|
||||
|
||||
protected abstract String getInputString(Request request)
|
||||
|
||||
@Override
|
||||
protected boolean hasGivenSection() {
|
||||
return request.headers || request.body
|
||||
}
|
||||
|
||||
protected boolean allowedQueryParameter(QueryParameter param) {
|
||||
return allowedQueryParameter(param.serverValue)
|
||||
}
|
||||
|
||||
protected boolean allowedQueryParameter(MatchingStrategy matchingStrategy) {
|
||||
return matchingStrategy.type != MatchingStrategy.Type.ABSENT
|
||||
}
|
||||
|
||||
protected boolean allowedQueryParameter(Object o) {
|
||||
return true
|
||||
}
|
||||
|
||||
protected void processInput(BlockBuilder bb) {
|
||||
request.headers?.collect { Header header ->
|
||||
bb.addLine(getHeaderString(header))
|
||||
}
|
||||
if (request.body) {
|
||||
bb.addLine(getBodyString(bodyAsString))
|
||||
}
|
||||
if (request.multipart) {
|
||||
multipartParameters?.each { Map.Entry<String, Object> entry -> bb.addLine(getMultipartParameterLine(entry)) }
|
||||
}
|
||||
}
|
||||
|
||||
protected void when(BlockBuilder bb) {
|
||||
bb.addLine(getInputString(request))
|
||||
bb.indent()
|
||||
|
||||
String url = buildUrl(request)
|
||||
String method = request.method.serverValue.toString().toLowerCase()
|
||||
|
||||
bb.addLine(/.${method}("$url")/)
|
||||
addColonIfRequired(bb)
|
||||
bb.unindent()
|
||||
}
|
||||
|
||||
protected void then(BlockBuilder bb) {
|
||||
validateResponseCodeBlock(bb)
|
||||
if (response.headers) {
|
||||
validateResponseHeadersBlock(bb)
|
||||
}
|
||||
if (response.body) {
|
||||
bb.endBlock()
|
||||
bb.addLine(addCommentSignIfRequired('and:')).startBlock()
|
||||
validateResponseBodyBlock(bb, response.body.serverValue)
|
||||
}
|
||||
}
|
||||
|
||||
protected ContentType getResponseContentType() {
|
||||
ContentType contentType = recognizeContentTypeFromHeader(response.headers)
|
||||
if (contentType == ContentType.UNKNOWN) {
|
||||
contentType = recognizeContentTypeFromContent(response.body.serverValue)
|
||||
}
|
||||
return contentType
|
||||
}
|
||||
|
||||
protected String getBodyAsString() {
|
||||
Object bodyValue = extractServerValueFromBody(request.body.serverValue)
|
||||
String json = new JsonOutput().toJson(bodyValue)
|
||||
json = convertUnicodeEscapesIfRequired(json)
|
||||
return trimRepeatedQuotes(json)
|
||||
}
|
||||
|
||||
protected Map<String, Object> getMultipartParameters() {
|
||||
return (Map<String, Object>) request?.multipart?.serverValue
|
||||
}
|
||||
|
||||
protected ContentType getRequestContentType() {
|
||||
ContentType contentType = recognizeContentTypeFromHeader(request.headers)
|
||||
if (contentType == ContentType.UNKNOWN) {
|
||||
contentType = recognizeContentTypeFromContent(request.body.serverValue)
|
||||
}
|
||||
return contentType
|
||||
}
|
||||
|
||||
protected String buildUrl(Request request) {
|
||||
if (request.url)
|
||||
return getTestSideValue(buildUrlFromUrlPath(request.url))
|
||||
if (request.urlPath)
|
||||
return getTestSideValue(buildUrlFromUrlPath(request.urlPath))
|
||||
throw new IllegalStateException("URL is not set!")
|
||||
}
|
||||
|
||||
@TypeChecked(TypeCheckingMode.SKIP)
|
||||
protected String buildUrlFromUrlPath(Url url) {
|
||||
if (hasQueryParams(url)) {
|
||||
String params = url.queryParameters.parameters
|
||||
.findAll(this.&allowedQueryParameter)
|
||||
.inject([] as List<String>) { List<String> result, QueryParameter param ->
|
||||
result << "${param.name}=${resolveParamValue(param).toString()}"
|
||||
}
|
||||
.join('&')
|
||||
return "${MapConverter.getTestSideValues(url.serverValue)}?$params"
|
||||
}
|
||||
return MapConverter.getTestSideValues(url.serverValue)
|
||||
}
|
||||
|
||||
protected String getMultipartParameterLine(Map.Entry<String, Object> parameter) {
|
||||
if (parameter.value instanceof NamedProperty) {
|
||||
return ".multiPart(${getMultipartFileParameterContent(parameter.key, (NamedProperty) parameter.value)})"
|
||||
}
|
||||
return getParameterString(parameter)
|
||||
}
|
||||
|
||||
|
||||
private boolean hasQueryParams(Url url) {
|
||||
return url.queryParameters
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
package io.codearte.accurest.builder
|
||||
|
||||
import groovy.json.StringEscapeUtils
|
||||
import groovy.transform.PackageScope
|
||||
import groovy.transform.TypeChecked
|
||||
import io.codearte.accurest.dsl.GroovyDsl
|
||||
import io.codearte.accurest.dsl.internal.ExecutionProperty
|
||||
import io.codearte.accurest.dsl.internal.Header
|
||||
import io.codearte.accurest.dsl.internal.Input
|
||||
import io.codearte.accurest.dsl.internal.NamedProperty
|
||||
|
||||
import java.util.regex.Pattern
|
||||
/**
|
||||
* @author Jakub Kubrynski
|
||||
*/
|
||||
@PackageScope
|
||||
@TypeChecked
|
||||
class SpockMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder {
|
||||
|
||||
SpockMessagingMethodBodyBuilder(GroovyDsl stubDefinition) {
|
||||
super(stubDefinition)
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getInputString(Input request) {
|
||||
if (request.triggeredBy) {
|
||||
return request.triggeredBy.executionCommand
|
||||
}
|
||||
return "accurestMessaging.send(inputMessage, '${request.messageFrom}')"
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getResponseBodyPropertyComparisonString(String property, String value) {
|
||||
return "responseBody$property == \"${value}\""
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processBodyElement(BlockBuilder blockBuilder, String property, ExecutionProperty exec) {
|
||||
blockBuilder.addLine("${exec.insertValue("parsedJson.read('\\\$$property')")}")
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processBodyElement(BlockBuilder blockBuilder, String property, Map.Entry entry) {
|
||||
processBodyElement(blockBuilder, property + "." + entry.key, entry.value)
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processHeaderElement(BlockBuilder blockBuilder, String property, ExecutionProperty exec) {
|
||||
blockBuilder.addLine("${exec.insertValue("response.getHeader(\'$property\')")}")
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processHeaderElement(BlockBuilder blockBuilder, String property, String value) {
|
||||
blockBuilder.addLine("response.getHeader('$property') ${convertHeaderComparison(value)}")
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processHeaderElement(BlockBuilder blockBuilder, String property, Pattern value) {
|
||||
blockBuilder.addLine("response.getHeader('$property') ${convertHeaderComparison(value)}")
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateResponseCodeBlock(BlockBuilder bb) {
|
||||
if (outputMessage) {
|
||||
bb.addLine("""def response = accurestMessaging.receiveMessage('${outputMessage.sentTo}')""")
|
||||
} else {
|
||||
bb.addLine('noExceptionThrown()')
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void validateResponseHeadersBlock(BlockBuilder bb) {
|
||||
outputMessage.headers?.collect { Header header ->
|
||||
processHeaderElement(bb, header.name, header.serverValue)
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getResponseAsString() {
|
||||
return 'accurestObjectMapper.writeValueAsString(response.payload)'
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String addCommentSignIfRequired(String baseString) {
|
||||
return baseString
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockBuilder addColonIfRequired(BlockBuilder blockBuilder) {
|
||||
return blockBuilder
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getPropertyInListString(String property, Integer listIndex) {
|
||||
"$property[$listIndex]" ?: ''
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String convertUnicodeEscapesIfRequired(String json) {
|
||||
return StringEscapeUtils.unescapeJavaScript(json)
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getParsedXmlResponseBodyString(String responseString) {
|
||||
return "def responseBody = new XmlSlurper().parseText($responseString)"
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getSimpleResponseBodyString(String responseString) {
|
||||
return "def responseBody = ($responseString)"
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getInputString() {
|
||||
String request = 'def inputMessage = accurestMessaging.create('
|
||||
if (inputMessage.messageBody) {
|
||||
request = "${request}'''${bodyAsString}'''\n\t\t"
|
||||
}
|
||||
if (inputMessage.messageHeaders) {
|
||||
request = "${request},[\n"
|
||||
}
|
||||
def headers = []
|
||||
inputMessage.messageHeaders?.collect { Header header ->
|
||||
headers << "\t\t\t${getHeaderString(header)}"
|
||||
}
|
||||
request = "${request}${headers.join(',\n')}"
|
||||
if (inputMessage.messageHeaders) {
|
||||
request = "${request}\n\t\t]"
|
||||
}
|
||||
return "${request})"
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getHeaderString(Header header) {
|
||||
return "'${getTestSideValue(header.name)}': '${getTestSideValue(header.serverValue)}'"
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBodyString(String bodyAsString) {
|
||||
return ''
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getMultipartFileParameterContent(String propertyName, NamedProperty propertyValue) {
|
||||
return ''
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getParameterString(Map.Entry<String, Object> parameter) {
|
||||
return ''
|
||||
}
|
||||
|
||||
protected String convertHeaderComparison(String headerValue) {
|
||||
return " == '$headerValue'"
|
||||
}
|
||||
|
||||
protected String convertHeaderComparison(Pattern headerValue) {
|
||||
return "==~ java.util.regex.Pattern.compile('$headerValue')"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,9 +18,9 @@ import static io.codearte.accurest.util.ContentUtils.getGroovyMultipartFileParam
|
||||
*/
|
||||
@PackageScope
|
||||
@TypeChecked
|
||||
abstract class SpockMethodBodyBuilder extends MethodBodyBuilder {
|
||||
abstract class SpockMethodRequestProcessingBodyBuilder extends RequestProcessingMethodBodyBuilder {
|
||||
|
||||
SpockMethodBodyBuilder(GroovyDsl stubDefinition) {
|
||||
SpockMethodRequestProcessingBodyBuilder(GroovyDsl stubDefinition) {
|
||||
super(stubDefinition)
|
||||
}
|
||||
|
||||
@@ -70,12 +70,12 @@ abstract class SpockMethodBodyBuilder extends MethodBodyBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getResponseString(Request request) {
|
||||
protected String getInputString(Request request) {
|
||||
return 'def response = given().spec(request)'
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getRequestString() {
|
||||
protected String getInputString() {
|
||||
return 'def request = given()'
|
||||
}
|
||||
|
||||
@@ -74,4 +74,9 @@ class AccurestConfigProperties {
|
||||
* You can then mention them in your packaging task to create jar with stubs
|
||||
*/
|
||||
File stubsOutputDir
|
||||
|
||||
/**
|
||||
* Which version of Accurest Messaging Core to use
|
||||
*/
|
||||
String accurestMessagingCoreVersion = "+"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package io.codearte.accurest.dsl
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.ToString
|
||||
import groovy.transform.TypeChecked
|
||||
import io.codearte.accurest.dsl.internal.Input
|
||||
import io.codearte.accurest.dsl.internal.OutputMessage
|
||||
import io.codearte.accurest.dsl.internal.Request
|
||||
import io.codearte.accurest.dsl.internal.Response
|
||||
|
||||
@@ -14,6 +16,9 @@ class GroovyDsl {
|
||||
Integer priority
|
||||
Request request
|
||||
Response response
|
||||
String label
|
||||
Input inputMessage
|
||||
OutputMessage outputMessage
|
||||
|
||||
static GroovyDsl make(Closure closure) {
|
||||
GroovyDsl dsl = new GroovyDsl()
|
||||
@@ -26,6 +31,10 @@ class GroovyDsl {
|
||||
this.priority = priority
|
||||
}
|
||||
|
||||
void label(String label) {
|
||||
this.label = label
|
||||
}
|
||||
|
||||
void request(@DelegatesTo(Request) Closure closure) {
|
||||
this.request = new Request()
|
||||
closure.delegate = request
|
||||
@@ -38,4 +47,16 @@ class GroovyDsl {
|
||||
closure()
|
||||
}
|
||||
|
||||
void input(@DelegatesTo(Input) Closure closure) {
|
||||
this.inputMessage = new Input()
|
||||
closure.delegate = inputMessage
|
||||
closure()
|
||||
}
|
||||
|
||||
void outputMessage(@DelegatesTo(OutputMessage) Closure closure) {
|
||||
this.outputMessage = new OutputMessage()
|
||||
closure.delegate = outputMessage
|
||||
closure()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -40,6 +40,9 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy {
|
||||
|
||||
@PackageScope
|
||||
RequestPattern buildClientRequestContent() {
|
||||
if(!request) {
|
||||
return null
|
||||
}
|
||||
RequestPattern requestPattern = new RequestPattern()
|
||||
appendMethod(requestPattern)
|
||||
appendHeaders(requestPattern)
|
||||
|
||||
@@ -27,6 +27,9 @@ class WireMockResponseStubStrategy extends BaseWireMockStubStrategy {
|
||||
|
||||
@PackageScope
|
||||
ResponseDefinition buildClientResponseContent() {
|
||||
if(!response) {
|
||||
return null
|
||||
}
|
||||
ResponseDefinitionBuilder builder = new ResponseDefinitionBuilder()
|
||||
.withStatus(response.status.clientValue as Integer)
|
||||
appendHeaders(builder)
|
||||
|
||||
@@ -29,14 +29,20 @@ class WireMockStubStrategy {
|
||||
@CompileDynamic
|
||||
String toWireMockClientStub() {
|
||||
StubMapping stubMapping = new StubMapping()
|
||||
|
||||
RequestPattern request = wireMockRequestStubStrategy.buildClientRequestContent()
|
||||
ResponseDefinition response = wireMockResponseStubStrategy.buildClientResponseContent()
|
||||
if (priority) {
|
||||
stubMapping.priority = priority
|
||||
}
|
||||
|
||||
stubMapping.request = request
|
||||
stubMapping.response = response
|
||||
|
||||
if (!request || !response) {
|
||||
return ''
|
||||
}
|
||||
|
||||
if (contract.order != null) {
|
||||
stubMapping.scenarioName = "Scenario_" + rootName
|
||||
stubMapping.requiredScenarioState = contract.order == 0 ? STEP_START : STEP_PREFIX + contract.order
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
package io.codearte.accurest.dsl.internal
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.ToString
|
||||
import groovy.transform.TypeChecked
|
||||
|
||||
@TypeChecked
|
||||
@EqualsAndHashCode
|
||||
@ToString(includePackage = false, includeNames = true)
|
||||
class Input extends Common {
|
||||
|
||||
String messageFrom
|
||||
ExecutionProperty triggeredBy
|
||||
Headers messageHeaders
|
||||
BodyType messageBody
|
||||
ExecutionProperty assertThat
|
||||
|
||||
Input() {}
|
||||
|
||||
Input(Input input) {
|
||||
this.messageFrom = input.messageFrom
|
||||
this.messageHeaders = input.messageHeaders
|
||||
this.messageBody = input.messageBody
|
||||
}
|
||||
|
||||
void messageFrom(String messageFrom) {
|
||||
this.messageFrom = messageFrom
|
||||
}
|
||||
|
||||
void triggeredBy(String triggeredBy) {
|
||||
this.triggeredBy = new ExecutionProperty(triggeredBy)
|
||||
}
|
||||
|
||||
BodyType messageBody(Object bodyAsValue) {
|
||||
this.messageBody = new BodyType(bodyAsValue)
|
||||
}
|
||||
|
||||
void messageHeaders(@DelegatesTo(Headers) Closure closure) {
|
||||
this.messageHeaders = new Headers()
|
||||
closure.delegate = messageHeaders
|
||||
closure()
|
||||
}
|
||||
|
||||
public static class BodyType extends DslProperty {
|
||||
|
||||
BodyType(Object clientValue, Object serverValue) {
|
||||
super(clientValue, serverValue)
|
||||
}
|
||||
|
||||
BodyType(Object singleValue) {
|
||||
super(singleValue)
|
||||
}
|
||||
}
|
||||
|
||||
void assertThat(String assertThat) {
|
||||
this.assertThat = new ExecutionProperty(assertThat)
|
||||
}
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
@EqualsAndHashCode
|
||||
@ToString(includePackage = false)
|
||||
class ServerInput extends Input {
|
||||
ServerInput(Input request) {
|
||||
super(request)
|
||||
}
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
@EqualsAndHashCode
|
||||
@ToString(includePackage = false)
|
||||
class ClientInput extends Input {
|
||||
ClientInput(Input request) {
|
||||
super(request)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package io.codearte.accurest.dsl.internal
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.ToString
|
||||
import groovy.transform.TypeChecked
|
||||
|
||||
@TypeChecked
|
||||
@EqualsAndHashCode
|
||||
@ToString(includePackage = false, includeNames = true)
|
||||
class OutputMessage extends Common {
|
||||
|
||||
String sentTo
|
||||
Headers headers
|
||||
DslProperty body
|
||||
ExecutionProperty assertThat
|
||||
|
||||
OutputMessage() {}
|
||||
|
||||
OutputMessage(OutputMessage outputMessage) {
|
||||
this.sentTo = outputMessage.sentTo
|
||||
this.headers = outputMessage.headers
|
||||
this.body = outputMessage.body
|
||||
}
|
||||
|
||||
void sentTo(String sentTo) {
|
||||
this.sentTo = sentTo
|
||||
}
|
||||
|
||||
void body(Object bodyAsValue) {
|
||||
this.body = new DslProperty(bodyAsValue)
|
||||
}
|
||||
|
||||
void body(DslProperty bodyAsValue) {
|
||||
this.body = bodyAsValue
|
||||
}
|
||||
|
||||
void headers(@DelegatesTo(Headers) Closure closure) {
|
||||
this.headers = new Headers()
|
||||
closure.delegate = headers
|
||||
closure()
|
||||
}
|
||||
|
||||
void assertThat(String assertThat) {
|
||||
this.assertThat = new ExecutionProperty(assertThat)
|
||||
}
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
@EqualsAndHashCode
|
||||
@ToString(includePackage = false)
|
||||
class ServerOutputMessage extends OutputMessage {
|
||||
ServerOutputMessage(OutputMessage request) {
|
||||
super(request)
|
||||
}
|
||||
}
|
||||
|
||||
@CompileStatic
|
||||
@EqualsAndHashCode
|
||||
@ToString(includePackage = false)
|
||||
class ClientOutputMessage extends OutputMessage {
|
||||
ClientOutputMessage(OutputMessage request) {
|
||||
super(request)
|
||||
}
|
||||
}
|
||||
@@ -287,6 +287,15 @@ class ContentUtils {
|
||||
return ContentType.JSON
|
||||
}
|
||||
|
||||
public static ContentType recognizeContentTypeFromContent(String string) {
|
||||
try {
|
||||
new JsonSlurper().parseText(string)
|
||||
return ContentType.JSON
|
||||
} catch (Exception e){
|
||||
return ContentType.UNKNOWN
|
||||
}
|
||||
}
|
||||
|
||||
public static ContentType recognizeContentTypeFromContent(Object gstring) {
|
||||
return ContentType.UNKNOWN
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package io.codearte.accurest.builder
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
@CompileStatic
|
||||
class BookReturned implements Serializable {
|
||||
final String bookName
|
||||
|
||||
@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
|
||||
BookReturned(String bookName) {
|
||||
this.bookName = bookName
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,7 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"JaxRsClientSpockMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodBodyBuilder(dsl) }
|
||||
"JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) }
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
|
||||
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"JaxRsClientSpockMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodBodyBuilder(dsl) }
|
||||
"JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) }
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
|
||||
stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub())
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"JaxRsClientSpockMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodBodyBuilder(dsl) }
|
||||
"JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) }
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
@@ -136,9 +136,9 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder | bodyString
|
||||
"JaxRsClientSpockMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodBodyBuilder(dsl) } | """entity('{\"items\":[\"HOP\"]}', 'application/json')"""
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'entity("{\\"items\\":[\\"HOP\\"]}", "application/json")'
|
||||
methodBuilderName | methodBuilder | bodyString
|
||||
"JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | """entity('{\"items\":[\"HOP\"]}', 'application/json')"""
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'entity("{\\"items\\":[\\"HOP\\"]}", "application/json")'
|
||||
}
|
||||
|
||||
@Issue("#88")
|
||||
@@ -166,9 +166,9 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder | bodyString
|
||||
"JaxRsClientSpockMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodBodyBuilder(dsl) } | """entity('property1=VAL1', 'application/octet-stream')"""
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'entity("\\"property1=VAL1\\"", "application/octet-stream")'
|
||||
methodBuilderName | methodBuilder | bodyString
|
||||
"JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | """entity('property1=VAL1', 'application/octet-stream')"""
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'entity("\\"property1=VAL1\\"", "application/octet-stream")'
|
||||
}
|
||||
|
||||
@Unroll
|
||||
@@ -201,7 +201,7 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"JaxRsClientSpockMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodBodyBuilder(dsl) }
|
||||
"JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) }
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
@@ -234,7 +234,7 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"JaxRsClientSpockMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodBodyBuilder(dsl) }
|
||||
"JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) }
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
@@ -267,7 +267,7 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"JaxRsClientSpockMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodBodyBuilder(dsl) }
|
||||
"JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) }
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
@@ -306,7 +306,7 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"JaxRsClientSpockMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodBodyBuilder(dsl) }
|
||||
"JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) }
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
@@ -339,7 +339,7 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"JaxRsClientSpockMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodBodyBuilder(dsl) }
|
||||
"JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) }
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
@@ -367,9 +367,9 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder | requestString
|
||||
"JaxRsClientSpockMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodBodyBuilder(dsl) } | "request('text/plain')"
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'request("text/plain")'
|
||||
methodBuilderName | methodBuilder | requestString
|
||||
"JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | "request('text/plain')"
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'request("text/plain")'
|
||||
}
|
||||
|
||||
@Unroll
|
||||
@@ -401,9 +401,9 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder | requestStrings
|
||||
"JaxRsClientSpockMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodBodyBuilder(dsl) } | ["""entity('', 'text/plain')""", """header('Timer', '123')"""]
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | ['entity("\\"\\"", "text/plain")', 'header("Timer", "123")']
|
||||
methodBuilderName | methodBuilder | requestStrings
|
||||
"JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | ["""entity('', 'text/plain')""", """header('Timer', '123')"""]
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | ['entity("\\"\\"", "text/plain")', 'header("Timer", "123")']
|
||||
}
|
||||
|
||||
@Unroll
|
||||
@@ -456,9 +456,9 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder | modifyStringIfRequired
|
||||
"JaxRsClientSpockMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodBodyBuilder(dsl) } | { String paramString -> paramString }
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | { String paramString -> paramString.replace("'", "\"") }
|
||||
methodBuilderName | methodBuilder | modifyStringIfRequired
|
||||
"JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | { String paramString -> paramString }
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | { String paramString -> paramString.replace("'", "\"") }
|
||||
}
|
||||
|
||||
@Issue('#169')
|
||||
@@ -512,9 +512,9 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder | modifyStringIfRequired
|
||||
"JaxRsClientSpockMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodBodyBuilder(dsl) } | { String paramString -> paramString }
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | { String paramString -> paramString.replace("'", "\"") }
|
||||
methodBuilderName | methodBuilder | modifyStringIfRequired
|
||||
"JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | { String paramString -> paramString }
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | { String paramString -> paramString.replace("'", "\"") }
|
||||
}
|
||||
|
||||
@Unroll
|
||||
@@ -541,9 +541,9 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder | bodyString
|
||||
"JaxRsClientSpockMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodBodyBuilder(dsl) } | "entity('', 'application/octet-stream')"
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'entity("\\"\\"", "application/octet-stream"'
|
||||
methodBuilderName | methodBuilder | bodyString
|
||||
"JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | "entity('', 'application/octet-stream')"
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'entity("\\"\\"", "application/octet-stream"'
|
||||
}
|
||||
|
||||
@Unroll
|
||||
@@ -570,9 +570,9 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder | bodyDefinitionString | bodyEvaluationString
|
||||
"JaxRsClientSpockMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodBodyBuilder(dsl) } | "String responseAsString = response.readEntity(String)" | 'responseBody == "test"'
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'Object responseBody = (responseAsString);' | 'assertThat(responseBody).isEqualTo("test");'
|
||||
methodBuilderName | methodBuilder | bodyDefinitionString | bodyEvaluationString
|
||||
"JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | "String responseAsString = response.readEntity(String)" | 'responseBody == "test"'
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'Object responseBody = (responseAsString);' | 'assertThat(responseBody).isEqualTo("test");'
|
||||
}
|
||||
|
||||
@Issue('#171')
|
||||
@@ -604,9 +604,9 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder | methodString
|
||||
"JaxRsClientSpockMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodBodyBuilder(dsl) } | ".method('GET')"
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'method("GET")'
|
||||
methodBuilderName | methodBuilder | methodString
|
||||
"JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | ".method('GET')"
|
||||
"JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'method("GET")'
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,252 @@
|
||||
package io.codearte.accurest.builder
|
||||
|
||||
import io.codearte.accurest.dsl.GroovyDsl
|
||||
import spock.lang.Specification
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
class MessagingMethodBodyBuilderSpec extends Specification {
|
||||
|
||||
def "should work for triggered based messaging with Spock"() {
|
||||
given:
|
||||
def contractDsl = GroovyDsl.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
triggeredBy('bookReturnedTriggered()')
|
||||
}
|
||||
outputMessage {
|
||||
sentTo('activemq:output')
|
||||
body('''{ "bookName" : "foo" }''')
|
||||
headers {
|
||||
header('BOOK-NAME', 'foo')
|
||||
}
|
||||
}
|
||||
}
|
||||
MethodBodyBuilder builder = new SpockMessagingMethodBodyBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
def test = blockBuilder.toString()
|
||||
then:
|
||||
stripped(test) == stripped('''
|
||||
when:
|
||||
bookReturnedTriggered()
|
||||
|
||||
then:
|
||||
def response = accurestMessaging.receiveMessage('activemq:output')
|
||||
response.getHeader('BOOK-NAME') == 'foo'
|
||||
and:
|
||||
DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload))
|
||||
assertThatJson(parsedJson).field("bookName").isEqualTo("foo")
|
||||
''')
|
||||
}
|
||||
|
||||
def "should work for triggered based messaging with JUnit"() {
|
||||
given:
|
||||
def contractDsl = GroovyDsl.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
triggeredBy('bookReturnedTriggered()')
|
||||
}
|
||||
outputMessage {
|
||||
sentTo('activemq:output')
|
||||
body('''{ "bookName" : "foo" }''')
|
||||
headers {
|
||||
header('BOOK-NAME', 'foo')
|
||||
}
|
||||
}
|
||||
}
|
||||
MethodBodyBuilder builder = new JUnitMessagingMethodBodyBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
def test = blockBuilder.toString()
|
||||
then:
|
||||
stripped(test) == stripped('''
|
||||
// when:
|
||||
bookReturnedTriggered();
|
||||
|
||||
// then:
|
||||
AccurestMessage response = accurestMessaging.receiveMessage("activemq:output");
|
||||
assertThat(response.getHeader("BOOK-NAME")).isEqualTo("foo");
|
||||
// and:
|
||||
DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.getPayload()));
|
||||
assertThatJson(parsedJson).field("bookName").isEqualTo("foo");
|
||||
''')
|
||||
}
|
||||
|
||||
private String stripped(String text) {
|
||||
return text.stripIndent().stripMargin().replace('\t', '').replace('\n', '')
|
||||
}
|
||||
|
||||
def "should generate tests triggered by a message for Spock"() {
|
||||
given:
|
||||
def contractDsl = GroovyDsl.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
messageFrom('jms:input')
|
||||
messageBody([
|
||||
bookName: 'foo'
|
||||
])
|
||||
messageHeaders {
|
||||
header('sample', 'header')
|
||||
}
|
||||
}
|
||||
outputMessage {
|
||||
sentTo('jms:output')
|
||||
body([
|
||||
bookName: 'foo'
|
||||
])
|
||||
headers {
|
||||
header('BOOK-NAME', 'foo')
|
||||
}
|
||||
}
|
||||
}
|
||||
MethodBodyBuilder builder = new SpockMessagingMethodBodyBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
def test = blockBuilder.toString()
|
||||
then:
|
||||
stripped(test) == stripped('''
|
||||
given:
|
||||
def inputMessage = accurestMessaging.create(
|
||||
\'\'\'{"bookName":"foo"}\'\'\',
|
||||
['sample': 'header']
|
||||
)
|
||||
|
||||
when:
|
||||
accurestMessaging.send(inputMessage, 'jms:input')
|
||||
|
||||
then:
|
||||
def response = accurestMessaging.receiveMessage('jms:output')
|
||||
response.getHeader('BOOK-NAME') == 'foo'
|
||||
and:
|
||||
DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload))
|
||||
assertThatJson(parsedJson).field("bookName").isEqualTo("foo")
|
||||
''')
|
||||
}
|
||||
|
||||
def "should generate tests triggered by a message for JUnit"() {
|
||||
given:
|
||||
def contractDsl = GroovyDsl.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
messageFrom('jms:input')
|
||||
messageBody([
|
||||
bookName: 'foo'
|
||||
])
|
||||
messageHeaders {
|
||||
header('sample', 'header')
|
||||
}
|
||||
}
|
||||
outputMessage {
|
||||
sentTo('jms:output')
|
||||
body([
|
||||
bookName: 'foo'
|
||||
])
|
||||
headers {
|
||||
header('BOOK-NAME', 'foo')
|
||||
}
|
||||
}
|
||||
}
|
||||
MethodBodyBuilder builder = new JUnitMessagingMethodBodyBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
def test = blockBuilder.toString()
|
||||
then:
|
||||
stripped(test) == stripped('''
|
||||
// given:
|
||||
AccurestMessage inputMessage = accurestMessaging.create(
|
||||
"{\\"bookName\\":\\"foo\\"}"
|
||||
, headers()
|
||||
.header("sample", "header"));
|
||||
|
||||
// when:
|
||||
accurestMessaging.send(inputMessage, "jms:input");
|
||||
|
||||
// then:
|
||||
AccurestMessage response = accurestMessaging.receiveMessage("jms:output");
|
||||
assertThat(response.getHeader("BOOK-NAME")).isEqualTo("foo");
|
||||
// and:
|
||||
DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.getPayload()));
|
||||
assertThatJson(parsedJson).field("bookName").isEqualTo("foo");
|
||||
|
||||
''')
|
||||
}
|
||||
|
||||
def "should generate tests without destination, triggered by a message"() {
|
||||
given:
|
||||
def contractDsl = GroovyDsl.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
messageFrom('jms:delete')
|
||||
messageBody([
|
||||
bookName: 'foo'
|
||||
])
|
||||
messageHeaders {
|
||||
header('sample', 'header')
|
||||
}
|
||||
assertThat('bookWasDeleted()')
|
||||
}
|
||||
}
|
||||
MethodBodyBuilder builder = new SpockMessagingMethodBodyBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
def test = blockBuilder.toString()
|
||||
then:
|
||||
stripped(test) == stripped('''
|
||||
given:
|
||||
def inputMessage = accurestMessaging.create(
|
||||
\'\'\'{"bookName":"foo"}\'\'\',
|
||||
['sample': 'header']
|
||||
)
|
||||
|
||||
when:
|
||||
accurestMessaging.send(inputMessage, 'jms:delete')
|
||||
|
||||
then:
|
||||
noExceptionThrown()
|
||||
bookWasDeleted()
|
||||
''')
|
||||
}
|
||||
|
||||
def "should generate tests without destination, triggered by a message for JUnit"() {
|
||||
given:
|
||||
def contractDsl = GroovyDsl.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
messageFrom('jms:delete')
|
||||
messageBody([
|
||||
bookName: 'foo'
|
||||
])
|
||||
messageHeaders {
|
||||
header('sample', 'header')
|
||||
}
|
||||
assertThat('bookWasDeleted()')
|
||||
}
|
||||
}
|
||||
MethodBodyBuilder builder = new JUnitMessagingMethodBodyBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
def test = blockBuilder.toString()
|
||||
then:
|
||||
stripped(test) == stripped('''
|
||||
// given:
|
||||
AccurestMessage inputMessage = accurestMessaging.create(
|
||||
"{\\"bookName\\":\\"foo\\"}"
|
||||
, headers()
|
||||
.header("sample", "header"));
|
||||
|
||||
// when:
|
||||
accurestMessaging.send(inputMessage, "jms:delete");
|
||||
|
||||
// then:
|
||||
bookWasDeleted();
|
||||
''')
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
package io.codearte.accurest.builder
|
||||
|
||||
import io.codearte.accurest.dsl.GroovyDsl
|
||||
import spock.lang.Specification
|
||||
|
||||
/**
|
||||
|
||||
# TO CONSIDER
|
||||
|
||||
- multiple messages can be sent out (for now let's focus on a single one)
|
||||
- tests thanks to stream-test-binder will get executed in single threaded mode (no need for awaitility)
|
||||
- do we need an explicit assertion of an input message (the one that enters the source?) or will
|
||||
it be done in the processor
|
||||
|
||||
- let's support only JSON payload and headers taken from message ATM
|
||||
|
||||
|
||||
# TRIGGERING MESSAGES
|
||||
|
||||
Triggering for the client side might be done via stub runner messaging module.
|
||||
|
||||
## JUNIT
|
||||
|
||||
@ClassRule public static AccurestRule stubFinder = new AccurestRule()
|
||||
.repoRoot(repoRoot())
|
||||
.downloadStub("io.codearte.accurest.stubs", "loanIssuance")
|
||||
.downloadStub("io.codearte.accurest.stubs:fraudDetectionServer");
|
||||
|
||||
## SPRING
|
||||
|
||||
@Autowired StubFinder stubFinder
|
||||
|
||||
## TRIGGERING EXAMPLES
|
||||
|
||||
//test:
|
||||
|
||||
// execute all triggers for all artifacts
|
||||
stubFinder.trigger()
|
||||
// execute all triggers named 'some_label' for all artifacts
|
||||
stubFinder.trigger("some_label")
|
||||
// execute all triggers named 'some_label' for the artifact in Ivy notation
|
||||
stubFinder.trigger("io.codearte.accurest.stubs:fraudDetectionServer", "some_label")
|
||||
// execute all triggers named 'some_label' for the artifact with id ...
|
||||
stubFinder.trigger("fraudDetectionServer", "some_label")
|
||||
|
||||
if no label is provided then all triggers will get executed
|
||||
|
||||
# CLIENT SIDE TEST EXAMPLE
|
||||
|
||||
## DSL
|
||||
|
||||
GroovyDsl.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
triggeredBy(execute('method()'))
|
||||
}
|
||||
outputMessage {
|
||||
onChannel('messageFrom')
|
||||
messageBody("book returned")
|
||||
}
|
||||
}
|
||||
|
||||
## TEST
|
||||
|
||||
@Test
|
||||
public void run_some_test() {
|
||||
// given
|
||||
client.borrowABook();
|
||||
|
||||
// when - sends a message to the messageFrom provided in the "outputMessage" section of the DSL
|
||||
stubFinder.trigger("client_returned_a_book");
|
||||
|
||||
// then
|
||||
then(client).hasNoBooksBorrowed();
|
||||
}
|
||||
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
class MessagingSpec extends Specification {
|
||||
|
||||
// client side: must have a possibility to "trigger" sending of a message to the given messageFrom
|
||||
// server side: will run the method and await upon receiving message on the output messageFrom
|
||||
def "should generate tests triggered by a method"() {
|
||||
expect:
|
||||
GroovyDsl.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
triggeredBy('bookReturnedTriggered()')
|
||||
}
|
||||
outputMessage {
|
||||
sentTo('channel')
|
||||
body('''{ "bookName" : "foo" }''')
|
||||
headers {
|
||||
header('BOOK-NAME', 'foo')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// client side: if sends a message to input.messageFrom then message will be sent to output.messageFrom
|
||||
// server side: will send a message to input, verify the message contents and await upon receiving message on the output messageFrom
|
||||
def "should generate tests triggered by a message"() {
|
||||
expect:
|
||||
GroovyDsl.make {
|
||||
input {
|
||||
messageFrom('input')
|
||||
messageBody("some message")
|
||||
messageHeaders {
|
||||
header('key', 'value')
|
||||
}
|
||||
}
|
||||
outputMessage {
|
||||
sentTo('output')
|
||||
body('message')
|
||||
headers {
|
||||
header('anotherkey', 'anothervalue')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// client side: if sends a message to input.messageFrom then message if matches will get consumed
|
||||
// server side: will send a message to input and verify the message contents
|
||||
def "should generate tests without destination, triggered by a message"() {
|
||||
expect:
|
||||
GroovyDsl.make {
|
||||
input {
|
||||
messageFrom('input')
|
||||
messageBody("some message")
|
||||
messageHeaders {
|
||||
header('key', 'value')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -100,7 +100,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) }
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) }
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) }
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) }
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) }
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) }
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
@@ -199,9 +199,9 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder | bodyString
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | """.body('''{\"items\":[\"HOP\"]}''')"""
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '.body("{\\"items\\":[\\"HOP\\"]}")'
|
||||
methodBuilderName | methodBuilder | bodyString
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | """.body('''{\"items\":[\"HOP\"]}''')"""
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '.body("{\\"items\\":[\\"HOP\\"]}")'
|
||||
}
|
||||
|
||||
@Issue("#88")
|
||||
@@ -229,9 +229,9 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder | bodyString
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | """.body('''property1=VAL1''')"""
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '.body("\\"property1=VAL1\\"")'
|
||||
methodBuilderName | methodBuilder | bodyString
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | """.body('''property1=VAL1''')"""
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '.body("\\"property1=VAL1\\"")'
|
||||
}
|
||||
|
||||
@Issue("185")
|
||||
@@ -264,7 +264,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) }
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) }
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
@@ -298,7 +298,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) }
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) }
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
@@ -331,7 +331,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) }
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) }
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
@@ -364,7 +364,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) }
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) }
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
@@ -401,7 +401,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) }
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) }
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
@@ -432,7 +432,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) }
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) }
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
@@ -463,7 +463,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) }
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) }
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
@@ -511,7 +511,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) }
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) }
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
@@ -560,7 +560,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) }
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) }
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
@@ -587,9 +587,9 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder | bodyString
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | ".body('''''')"
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | ".body(\"\\\"\\\"\")"
|
||||
methodBuilderName | methodBuilder | bodyString
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | ".body('''''')"
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | ".body(\"\\\"\\\"\")"
|
||||
}
|
||||
|
||||
@Unroll
|
||||
@@ -616,9 +616,9 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder | bodyDefinitionString | bodyEvaluationString
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | 'def responseBody = (response.body.asString())' | 'responseBody == "test"'
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | 'Object responseBody = (response.getBody().asString());' | 'assertThat(responseBody).isEqualTo("test");'
|
||||
methodBuilderName | methodBuilder | bodyDefinitionString | bodyEvaluationString
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | 'def responseBody = (response.body.asString())' | 'responseBody == "test"'
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | 'Object responseBody = (response.getBody().asString());' | 'assertThat(responseBody).isEqualTo("test");'
|
||||
}
|
||||
|
||||
@Issue('113')
|
||||
@@ -656,9 +656,9 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder | headerEvaluationString
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | '''response.header('Location') ==~ java.util.regex.Pattern.compile('http://localhost/partners/[0-9]+/users/[0-9]+')'''
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | 'assertThat(response.header("Location")).matches("http://localhost/partners/[0-9]+/users/[0-9]+");'
|
||||
methodBuilderName | methodBuilder | headerEvaluationString
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | '''response.header('Location') ==~ java.util.regex.Pattern.compile('http://localhost/partners/[0-9]+/users/[0-9]+')'''
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | 'assertThat(response.header("Location")).matches("http://localhost/partners/[0-9]+/users/[0-9]+");'
|
||||
}
|
||||
|
||||
@Issue('115')
|
||||
@@ -696,9 +696,9 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
and:
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder | headerEvaluationString
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | '''response.header('Location') ==~ java.util.regex.Pattern.compile('^((http[s]?|ftp):\\/)\\/?([^:\\/\\s]+)(:[0-9]{1,5})?/partners/[0-9]+/users/[0-9]+')'''
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | 'assertThat(response.header("Location")).matches("^((http[s]?|ftp):/)/?([^:/s]+)(:[0-9]{1,5})?/partners/[0-9]+/users/[0-9]+");'
|
||||
methodBuilderName | methodBuilder | headerEvaluationString
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | '''response.header('Location') ==~ java.util.regex.Pattern.compile('^((http[s]?|ftp):\\/)\\/?([^:\\/\\s]+)(:[0-9]{1,5})?/partners/[0-9]+/users/[0-9]+')'''
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | 'assertThat(response.header("Location")).matches("^((http[s]?|ftp):/)/?([^:/s]+)(:[0-9]{1,5})?/partners/[0-9]+/users/[0-9]+");'
|
||||
}
|
||||
|
||||
@Unroll
|
||||
@@ -739,7 +739,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) }
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) }
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
@@ -773,7 +773,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
stubMappingIsValidWireMockStub(contractDsl)
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) }
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) }
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
@@ -813,7 +813,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
test.contains("""assertThatJson(parsedJson).field("message").matches("User not found by email = \\\\\\\\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\\\\\.[a-zA-Z]{2,4}\\\\\\\\]")""")
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) }
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) }
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
@@ -821,7 +821,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
@Unroll
|
||||
def "should not omit the optional field in the test creation with MockMvcSpockMethodBodyBuilder"() {
|
||||
given:
|
||||
MethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl)
|
||||
MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl)
|
||||
BlockBuilder blockBuilder = new BlockBuilder(" ")
|
||||
when:
|
||||
builder.appendTo(blockBuilder)
|
||||
@@ -900,9 +900,9 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
assert test.contains(assertionString)
|
||||
}
|
||||
where:
|
||||
methodBuilderName | methodBuilder | assertionStrings
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | ['''assertThatRejectionReasonIsNull(parsedJson.read('$.rejectionReason'))''', '''assertThatLocationIsNull(response.header('Location'))''']
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | ['''assertThatRejectionReasonIsNull(parsedJson.read("$.rejectionReason"))''', '''assertThatLocationIsNull(response.header("Location"))''']
|
||||
methodBuilderName | methodBuilder | assertionStrings
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | ['''assertThatRejectionReasonIsNull(parsedJson.read('$.rejectionReason'))''', '''assertThatLocationIsNull(response.header('Location'))''']
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | ['''assertThatRejectionReasonIsNull(parsedJson.read("$.rejectionReason"))''', '''assertThatLocationIsNull(response.header("Location"))''']
|
||||
}
|
||||
|
||||
@Unroll
|
||||
@@ -968,9 +968,9 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
!test.contains("clientValue")
|
||||
!test.contains("cursor")
|
||||
where:
|
||||
methodBuilderName | methodBuilder | bodyString
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | '"street":"Light Street"'
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '\\"street\\":\\"Light Street\\"'
|
||||
methodBuilderName | methodBuilder | bodyString
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | '"street":"Light Street"'
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '\\"street\\":\\"Light Street\\"'
|
||||
|
||||
}
|
||||
|
||||
@@ -1009,7 +1009,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub
|
||||
!test.contains("\\u041f")
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) }
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) }
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
@@ -1036,10 +1036,10 @@ World.''')
|
||||
then:
|
||||
test.contains(bodyString)
|
||||
where:
|
||||
methodBuilderName | methodBuilder | bodyString
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | """'''hello,
|
||||
methodBuilderName | methodBuilder | bodyString
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | """'''hello,
|
||||
World.'''"""
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '\\"hello,\\nWorld.\\"'
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '\\"hello,\\nWorld.\\"'
|
||||
}
|
||||
|
||||
@Issue('180')
|
||||
@@ -1073,12 +1073,12 @@ World.'''"""
|
||||
test.contains(requestString)
|
||||
}
|
||||
where:
|
||||
methodBuilderName | methodBuilder | requestStrings
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | ["""'content-type', 'multipart/form-data;boundary=AaB03x'""",
|
||||
""".param('formParameter', '"formParameterValue"'""",
|
||||
""".param('someBooleanParameter', 'true')""",
|
||||
""".multiPart('file', 'filename.csv', 'file content'.bytes)"""]
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | ['"content-type", "multipart/form-data;boundary=AaB03x"',
|
||||
methodBuilderName | methodBuilder | requestStrings
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | ["""'content-type', 'multipart/form-data;boundary=AaB03x'""",
|
||||
""".param('formParameter', '"formParameterValue"'""",
|
||||
""".param('someBooleanParameter', 'true')""",
|
||||
""".multiPart('file', 'filename.csv', 'file content'.bytes)"""]
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | ['"content-type", "multipart/form-data;boundary=AaB03x"',
|
||||
'.param("formParameter", "\\"formParameterValue\\"")',
|
||||
'.param("someBooleanParameter", "true")',
|
||||
'.multiPart("file", "filename.csv", "file content".getBytes());']
|
||||
@@ -1113,7 +1113,7 @@ World.'''"""
|
||||
test.contains('.multiPart')
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) }
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) }
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
@@ -1152,7 +1152,7 @@ World.'''"""
|
||||
test.contains('''assertThatJson(parsedJson).array("authorities").matches("^[a-zA-Z0-9_\\\\- ]+\\$").value()''')
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) }
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) }
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
@@ -1183,7 +1183,7 @@ World.'''"""
|
||||
test.contains('''assertThatRejectionReasonIsNull(''')
|
||||
where:
|
||||
methodBuilderName | methodBuilder
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) }
|
||||
"MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) }
|
||||
"MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) }
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ class AccurestGradlePlugin implements Plugin<Project> {
|
||||
project.dependencies.add("testCompile", "com.github.tomakehurst:wiremock:2.0.5-beta")
|
||||
project.dependencies.add("testCompile", "com.toomuchcoding.jsonassert:jsonassert:${extension.getJsonAssertVersion()}")
|
||||
project.dependencies.add("testCompile", "org.assertj:assertj-core:2.3.0")
|
||||
project.dependencies.add("testCompile", "io.codearte.accurest:accurest-messaging-core:${extension.getAccurestMessagingCoreVersion()}")
|
||||
|
||||
project.afterEvaluate {
|
||||
def hasIdea = project.plugins.findPlugin(IDEA_PLUGIN_CLASS)
|
||||
|
||||
@@ -24,9 +24,13 @@ class AccurestIntegrationSpec extends IntegrationSpec {
|
||||
}
|
||||
|
||||
protected void switchToJunitTestFramework() {
|
||||
switchToJunitTestFramework(MVC_SPEC, MVC_TEST)
|
||||
}
|
||||
|
||||
protected void switchToJunitTestFramework(String from, String to) {
|
||||
Path path = buildFile.toPath()
|
||||
String content = new StringBuilder(new String(Files.readAllBytes(path), UTF_8)).replaceAll(SPOCK, JUNIT)
|
||||
.replaceAll(MVC_SPEC, MVC_TEST)
|
||||
.replaceAll(from, to)
|
||||
Files.write(path, content.getBytes(UTF_8))
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package io.codearte.accurest.plugin
|
||||
|
||||
import spock.lang.Stepwise
|
||||
|
||||
@Stepwise
|
||||
class MessagingProjectSpec extends AccurestIntegrationSpec {
|
||||
|
||||
void setup() {
|
||||
copyResources("functionalTest/messagingProject", "")
|
||||
runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it
|
||||
}
|
||||
|
||||
def "should pass basic flow for Spock"() {
|
||||
given:
|
||||
assert fileExists('build.gradle')
|
||||
expect:
|
||||
runTasksSuccessfully('check')
|
||||
}
|
||||
|
||||
def "should pass basic flow for JUnit"() {
|
||||
given:
|
||||
runTasksSuccessfully('clean')
|
||||
assert fileExists('build.gradle')
|
||||
expect:
|
||||
switchToJunitTestFramework('io.codearte.accurest.samples.book.MessagingBaseSpec', 'io.codearte.accurest.samples.book.MessagingBaseTest')
|
||||
runTasksSuccessfully('check')
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
// will be passed via classpath
|
||||
// classpath "io.codearte.accurest:accurest-gradle-plugin:+"
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'groovy'
|
||||
apply plugin: 'accurest'
|
||||
apply plugin: 'maven-publish'
|
||||
|
||||
ext {
|
||||
contractsDir = file("${project.rootDir}/repository/mappings/")
|
||||
stubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/")
|
||||
wireMockStubsOutputDir = new File(stubsOutputDirRoot, 'repository/mappings/')
|
||||
contractsOutputDir = new File(stubsOutputDirRoot, 'repository/accurest/')
|
||||
}
|
||||
|
||||
configurations {
|
||||
all {
|
||||
resolutionStrategy {
|
||||
eachDependency { DependencyResolveDetails details ->
|
||||
// To prevent an accidental usage of groovy-all.jar and groovy.jar in different versions
|
||||
// all modularized Groovy jars are replaced with groovy-all.jar by default.
|
||||
if (details.requested.group == 'org.codehaus.groovy' && details.requested.name != "groovy-all") {
|
||||
details.useTarget("org.codehaus.groovy:groovy-all:${details.requested.version}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
mavenLocal()
|
||||
maven {
|
||||
url "http://repo.spring.io/snapshot"
|
||||
}
|
||||
maven {
|
||||
url "http://repo.spring.io/milestone"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile "org.codehaus.groovy:groovy-all:2.4.5"
|
||||
compile 'org.springframework.boot:spring-boot-starter-web:1.3.3.RELEASE'
|
||||
compile 'org.springframework.boot:spring-boot-starter-actuator:1.3.3.RELEASE'
|
||||
compile 'org.springframework.boot:spring-boot-starter-integration:1.3.3.RELEASE'
|
||||
// will be passed via classpath (I have issues with doing that quite frankly)
|
||||
compile 'io.codearte.accurest:accurest-messaging-integration:+'
|
||||
|
||||
testCompile "org.spockframework:spock-spring:1.0-groovy-2.4"
|
||||
testCompile 'org.springframework.boot:spring-boot-starter-test:1.3.3.RELEASE'
|
||||
testCompile "ch.qos.logback:logback-classic:1.1.2"
|
||||
}
|
||||
|
||||
accurest {
|
||||
//baseClassForTests = 'io.codearte.accurest.samples.book.MessagingBaseTest'
|
||||
baseClassForTests = 'io.codearte.accurest.samples.book.MessagingBaseSpec'
|
||||
basePackageForTests = 'accurest'
|
||||
//targetFramework = 'JUnit'
|
||||
targetFramework = 'Spock'
|
||||
contractsDslDir = contractsDir
|
||||
// generatedTestSourcesDir = file("${project.rootDir}/src/test/groovy/")
|
||||
stubsOutputDir = wireMockStubsOutputDir
|
||||
}
|
||||
|
||||
//TODO: Put it into the plugin
|
||||
task createWireMockStubsOutputDir << {
|
||||
wireMockStubsOutputDir.mkdirs()
|
||||
}
|
||||
|
||||
generateWireMockClientStubs.dependsOn { createWireMockStubsOutputDir }
|
||||
generateAccurest.dependsOn generateWireMockClientStubs
|
||||
|
||||
wrapper {
|
||||
gradleVersion '2.12'
|
||||
}
|
||||
|
||||
task copyContracts(type: Copy) {
|
||||
from contractsDir
|
||||
into contractsOutputDir
|
||||
}
|
||||
|
||||
task stubsJar(type: Jar, dependsOn: ["generateWireMockClientStubs", copyContracts]) {
|
||||
baseName = "${project.name}-stubs"
|
||||
from stubsOutputDirRoot
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives stubsJar
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
stubs(MavenPublication) {
|
||||
artifactId "${project.name}-stubs"
|
||||
artifact stubsJar
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
groupId=io.codearte
|
||||
jacksonMapper=1.9.13
|
||||
restAssuredVersion=2.9.0
|
||||
springVersion=4.2.3.RELEASE
|
||||
BIN
accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle/wrapper/gradle-wrapper.jar
vendored
Executable file
BIN
accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle/wrapper/gradle-wrapper.jar
vendored
Executable file
Binary file not shown.
@@ -0,0 +1,6 @@
|
||||
#Sun Apr 17 20:31:11 CEST 2016
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.12-bin.zip
|
||||
160
accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradlew
vendored
Executable file
160
accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradlew
vendored
Executable file
@@ -0,0 +1,160 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
90
accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradlew.bat
vendored
Executable file
90
accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradlew.bat
vendored
Executable file
@@ -0,0 +1,90 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@@ -0,0 +1,13 @@
|
||||
io.codearte.accurest.dsl.GroovyDsl.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
messageFrom('delete')
|
||||
messageBody([
|
||||
bookName: 'foo'
|
||||
])
|
||||
messageHeaders {
|
||||
header('sample', 'header')
|
||||
}
|
||||
assertThat('bookWasDeleted()')
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
io.codearte.accurest.dsl.GroovyDsl.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
triggeredBy('bookReturnedTriggered()')
|
||||
}
|
||||
outputMessage {
|
||||
sentTo('output')
|
||||
body('''{ "bookName" : "foo" }''')
|
||||
headers {
|
||||
header('BOOK-NAME', 'foo')
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
io.codearte.accurest.dsl.GroovyDsl.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
messageFrom('input')
|
||||
messageBody([
|
||||
bookName: 'foo'
|
||||
])
|
||||
messageHeaders {
|
||||
header('sample', 'header')
|
||||
}
|
||||
}
|
||||
outputMessage {
|
||||
sentTo('output')
|
||||
body([
|
||||
bookName: 'foo'
|
||||
])
|
||||
headers {
|
||||
header('BOOK-NAME', 'foo')
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
rootProject.name='bootSimple'
|
||||
@@ -0,0 +1,14 @@
|
||||
package io.codearte.accurest.samples.book
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
@CompileStatic
|
||||
class BookDeleted {
|
||||
final String bookName
|
||||
|
||||
@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
|
||||
BookDeleted(String bookName) {
|
||||
this.bookName = bookName
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package io.codearte.accurest.samples.book
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import groovy.util.logging.Slf4j
|
||||
import org.springframework.messaging.Message
|
||||
import org.springframework.messaging.MessageHeaders
|
||||
import org.springframework.messaging.support.MessageBuilder
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
@CompileStatic
|
||||
@Slf4j
|
||||
class BookListener {
|
||||
|
||||
/**
|
||||
Scenario for "should generate tests triggered by a message":
|
||||
client side: if sends a message to input.messageFrom then message will be sent to output.messageFrom
|
||||
server side: will send a message to input, verify the message contents and await upon receiving message on the output messageFrom
|
||||
*/
|
||||
Message returnBook(BookReturned bookReturned) {
|
||||
log.info("Returning book [$bookReturned]")
|
||||
return MessageBuilder.createMessage(bookReturned, new MessageHeaders([
|
||||
'BOOK-NAME': bookReturned.bookName as Object
|
||||
]))
|
||||
}
|
||||
|
||||
/**
|
||||
Scenario for "should generate tests triggered by a message":
|
||||
client side: if sends a message to input.messageFrom then message will be sent to output.messageFrom
|
||||
server side: will send a message to input, verify the message contents and await upon receiving message on the output messageFrom
|
||||
*/
|
||||
void bookDeleted(BookDeleted bookDeleted) {
|
||||
log.info("Deleting book [$bookDeleted]")
|
||||
bookSuccessfulyDeleted.set(true)
|
||||
}
|
||||
|
||||
AtomicBoolean bookSuccessfulyDeleted = new AtomicBoolean(false)
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package io.codearte.accurest.samples.book
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
@CompileStatic
|
||||
class BookReturned {
|
||||
final String bookName
|
||||
|
||||
@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
|
||||
BookReturned(String bookName) {
|
||||
this.bookName = bookName
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package io.codearte.accurest.samples.book
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import groovy.util.logging.Slf4j
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.beans.factory.annotation.Qualifier
|
||||
import org.springframework.messaging.MessageChannel
|
||||
import org.springframework.messaging.MessageHeaders
|
||||
import org.springframework.messaging.support.MessageBuilder
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
@CompileStatic
|
||||
@Slf4j
|
||||
class BookService {
|
||||
|
||||
@Autowired @Qualifier("outputChannel") MessageChannel outputChannel
|
||||
|
||||
/**
|
||||
Scenario for "should generate tests triggered by a method":
|
||||
client side: must have a possibility to "trigger" sending of a message to the given messageFrom
|
||||
server side: will run the method and await upon receiving message on the output messageFrom
|
||||
|
||||
Method triggers sending a message to a source
|
||||
*/
|
||||
void returnBook(BookReturned bookReturned) {
|
||||
log.info("Returning book [$bookReturned]")
|
||||
outputChannel.send(MessageBuilder.createMessage(bookReturned, new MessageHeaders([
|
||||
'BOOK-NAME': bookReturned.bookName as Object
|
||||
])))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package io.codearte.accurest.samples.book
|
||||
|
||||
import org.springframework.boot.SpringApplication
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
import org.springframework.context.annotation.ImportResource
|
||||
|
||||
@SpringBootApplication
|
||||
@ImportResource("classpath*:integration-context.xml")
|
||||
class IntegrationMessagingApplication {
|
||||
|
||||
static void main(String[] args) {
|
||||
SpringApplication.run(IntegrationMessagingApplication.class, args)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="input"/>
|
||||
<channel id="delete"/>
|
||||
<channel id="outputChannel"/>
|
||||
|
||||
<service-activator input-channel="inputChannel"
|
||||
output-channel="outputChannel"
|
||||
ref="bookListener"
|
||||
method="returnBook"/>
|
||||
|
||||
<json-to-object-transformer input-channel="input" type="io.codearte.accurest.samples.book.BookReturned"
|
||||
output-channel="inputChannel"/>
|
||||
|
||||
<service-activator input-channel="deleteChannel"
|
||||
ref="bookListener"
|
||||
method="bookDeleted"/>
|
||||
|
||||
<json-to-object-transformer input-channel="delete" type="io.codearte.accurest.samples.book.BookDeleted"
|
||||
output-channel="deleteChannel"/>
|
||||
|
||||
<beans:bean id="bookListener" class="io.codearte.accurest.samples.book.BookListener"/>
|
||||
|
||||
|
||||
<!-- REQUIRED FOR TESTING -->
|
||||
<bridge input-channel="outputChannel"
|
||||
output-channel="output"/>
|
||||
|
||||
<channel id="output">
|
||||
<queue/>
|
||||
</channel>
|
||||
|
||||
</beans:beans>
|
||||
@@ -0,0 +1,25 @@
|
||||
package io.codearte.accurest.samples.book
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.test.SpringApplicationContextLoader
|
||||
import org.springframework.test.context.ContextConfiguration
|
||||
import spock.lang.Specification
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
@ContextConfiguration(classes = [IntegrationMessagingApplication], loader = SpringApplicationContextLoader)
|
||||
abstract class MessagingBaseSpec extends Specification {
|
||||
|
||||
// BASE CLASS WOULD HAVE THIS:
|
||||
|
||||
@Autowired BookService bookService
|
||||
@Autowired BookListener bookListener
|
||||
|
||||
void bookReturnedTriggered() {
|
||||
bookService.returnBook(new BookReturned("foo"))
|
||||
}
|
||||
|
||||
void bookWasDeleted() {
|
||||
assert bookListener.bookSuccessfulyDeleted.get()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package io.codearte.accurest.samples.book;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.SpringApplicationContextLoader;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = {IntegrationMessagingApplication.class}, loader = SpringApplicationContextLoader.class)
|
||||
public abstract class MessagingBaseTest {
|
||||
|
||||
// BASE CLASS WOULD HAVE THIS:
|
||||
|
||||
@Autowired BookService bookService;
|
||||
@Autowired BookListener bookListener;
|
||||
|
||||
public void bookReturnedTriggered() {
|
||||
bookService.returnBook(new BookReturned("foo"));
|
||||
}
|
||||
|
||||
public void bookWasDeleted() {
|
||||
Assertions.assertThat(bookListener.getBookSuccessfulyDeleted().get()).isTrue();
|
||||
}
|
||||
}
|
||||
16
accurest-messaging/accurest-messaging-camel/build.gradle
Normal file
16
accurest-messaging/accurest-messaging-camel/build.gradle
Normal file
@@ -0,0 +1,16 @@
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
maven {
|
||||
url "http://repo.spring.io/snapshot"
|
||||
}
|
||||
maven {
|
||||
url "http://repo.spring.io/milestone"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':accurest-messaging-root:accurest-messaging-core')
|
||||
compile 'org.apache.camel:camel-spring:[2.9.0,)'
|
||||
compile 'org.slf4j:slf4j-api:[1.6.0,)'
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package io.codearte.accurest.messaging.camel;
|
||||
|
||||
import io.codearte.accurest.messaging.AccurestMessageBuilder;
|
||||
import io.codearte.accurest.messaging.AccurestMessaging;
|
||||
import org.apache.camel.CamelContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public class AccurestCamelConfiguration {
|
||||
|
||||
@Bean
|
||||
AccurestMessaging accurestMessaging(CamelContext context, AccurestMessageBuilder builder) {
|
||||
return new AccurestCamelMessaging(context, builder);
|
||||
}
|
||||
|
||||
@Bean
|
||||
AccurestMessageBuilder accurestMessageBuilder() {
|
||||
return new AccurestCamelMessageBuilder();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package io.codearte.accurest.messaging.camel;
|
||||
|
||||
import io.codearte.accurest.messaging.AccurestMessage;
|
||||
import io.codearte.accurest.messaging.AccurestMessageBuilder;
|
||||
import org.apache.camel.Message;
|
||||
import org.apache.camel.impl.DefaultMessage;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public class AccurestCamelMessageBuilder<T> implements AccurestMessageBuilder<T, Message> {
|
||||
|
||||
@Override
|
||||
public AccurestMessage<T, Message> create(T payload, Map<String, Object> headers) {
|
||||
DefaultMessage message = new DefaultMessage();
|
||||
message.setBody(payload);
|
||||
message.setHeaders(headers);
|
||||
return new CamelMessage<>(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccurestMessage<T, Message> create(Message message) {
|
||||
return new CamelMessage<>(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package io.codearte.accurest.messaging.camel;
|
||||
|
||||
import io.codearte.accurest.messaging.AccurestMessage;
|
||||
import io.codearte.accurest.messaging.AccurestMessageBuilder;
|
||||
import io.codearte.accurest.messaging.AccurestMessaging;
|
||||
import org.apache.camel.CamelContext;
|
||||
import org.apache.camel.ConsumerTemplate;
|
||||
import org.apache.camel.Exchange;
|
||||
import org.apache.camel.Message;
|
||||
import org.apache.camel.ProducerTemplate;
|
||||
import org.apache.camel.impl.DefaultExchange;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
@Component
|
||||
public class AccurestCamelMessaging<T> implements AccurestMessaging<T, Message> {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(AccurestCamelMessaging.class);
|
||||
|
||||
private final CamelContext context;
|
||||
private final AccurestMessageBuilder builder;
|
||||
|
||||
@Autowired
|
||||
@SuppressWarnings("unchecked")
|
||||
public AccurestCamelMessaging(CamelContext context, AccurestMessageBuilder accurestMessageBuilder) {
|
||||
this.context = context;
|
||||
this.builder = accurestMessageBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(AccurestMessage<T, Message> message, String destination) {
|
||||
try {
|
||||
ProducerTemplate producerTemplate = context.createProducerTemplate();
|
||||
Exchange exchange = new DefaultExchange(context);
|
||||
exchange.setIn(message.convert());
|
||||
producerTemplate.send(destination, exchange);
|
||||
} catch (Exception e) {
|
||||
log.error("Exception occurred while trying to send a message [" + message + "] " +
|
||||
"to a channel with name [" + destination + "]", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public AccurestMessage<T, Message> receiveMessage(String destination, long timeout, TimeUnit timeUnit) {
|
||||
try {
|
||||
ConsumerTemplate consumerTemplate = context.createConsumerTemplate();
|
||||
Exchange exchange = consumerTemplate.receive(destination, timeUnit.toMillis(timeout));
|
||||
return builder.create(exchange.getIn());
|
||||
} catch (Exception e) {
|
||||
log.error("Exception occurred while trying to read a message from " +
|
||||
" a channel with name [" + destination + "]", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccurestMessage<T, Message> receiveMessage(String destination) {
|
||||
return receiveMessage(destination, 5, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public AccurestMessage<T, Message> create(T t, Map<String, Object> headers) {
|
||||
return builder.create(t, headers);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public AccurestMessage<T, Message> create(Message message) {
|
||||
return builder.create(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package io.codearte.accurest.messaging.camel;
|
||||
|
||||
import io.codearte.accurest.messaging.AccurestMessage;
|
||||
import org.apache.camel.Message;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public class CamelMessage<T> implements AccurestMessage<T, Message> {
|
||||
|
||||
private final Message delegate;
|
||||
|
||||
public CamelMessage(Message delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public T getPayload() {
|
||||
return (T) delegate.getBody();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getHeaders() {
|
||||
return delegate.getHeaders();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getHeader(String key) {
|
||||
return getHeaders().get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message convert() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
# Auto Configuration
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
io.codearte.accurest.messaging.camel.AccurestCamelConfiguration
|
||||
8
accurest-messaging/accurest-messaging-core/build.gradle
Normal file
8
accurest-messaging/accurest-messaging-core/build.gradle
Normal file
@@ -0,0 +1,8 @@
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile 'com.fasterxml.jackson.core:jackson-databind:[2.4.4,)'
|
||||
compile 'javax.inject:javax.inject:1'
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package io.codearte.accurest.messaging;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Describes a message. Contains payload and headers. A message can be converted
|
||||
* to another type (e.g. Spring Messaging Message)
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public interface AccurestMessage<PAYLOAD, TYPE_TO_CONVERT_INTO> {
|
||||
|
||||
/**
|
||||
* Returns a payload of type {@code PAYLOAD}
|
||||
*/
|
||||
PAYLOAD getPayload();
|
||||
|
||||
/**
|
||||
* Returns a map of headers
|
||||
*/
|
||||
Map<String, Object> getHeaders();
|
||||
|
||||
/**
|
||||
* Returns a header for a given key
|
||||
*/
|
||||
Object getHeader(String key);
|
||||
|
||||
/**
|
||||
* Converts the message to {@code TYPE_TO_CONVERT_INTO} type
|
||||
*/
|
||||
TYPE_TO_CONVERT_INTO convert();
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package io.codearte.accurest.messaging;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Contract for creation of (@link AccurestMessage}. You can create a message from
|
||||
* payload and headers or from some type (e.g. Spring Messaging Message).
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public interface AccurestMessageBuilder<PAYLOAD, TYPE_TO_CONVERT_INTO> {
|
||||
|
||||
/**
|
||||
* Creates a {@link AccurestMessage} from payload and headers
|
||||
*/
|
||||
AccurestMessage<PAYLOAD, TYPE_TO_CONVERT_INTO> create(PAYLOAD payload, Map<String, Object> headers);
|
||||
|
||||
/**
|
||||
* Creates a {@link AccurestMessage} from the {@code TYPE_TO_CONVERT_INTO} type
|
||||
*/
|
||||
AccurestMessage<PAYLOAD, TYPE_TO_CONVERT_INTO> create(TYPE_TO_CONVERT_INTO typeToConvertInto);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package io.codearte.accurest.messaging;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Core interface that allows you to build, send and receive messages.
|
||||
*
|
||||
* Destination is relevant to the underlaying implementation. Might be a channel, queue, topic etc.
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public interface AccurestMessaging<PAYLOAD, TYPE_TO_CONVERT_INTO> extends AccurestMessageBuilder<PAYLOAD, TYPE_TO_CONVERT_INTO> {
|
||||
/**
|
||||
* Sends the {@link AccurestMessage} to the given destination.
|
||||
*/
|
||||
void send(AccurestMessage<PAYLOAD, TYPE_TO_CONVERT_INTO> message, String destination);
|
||||
|
||||
/**
|
||||
* Receives the {@link AccurestMessage} from the given destination. You can provide the timeout
|
||||
* for receiving that message.
|
||||
*/
|
||||
AccurestMessage<PAYLOAD, TYPE_TO_CONVERT_INTO> receiveMessage(String destination, long timeout, TimeUnit timeUnit);
|
||||
|
||||
/**
|
||||
* Receives the {@link AccurestMessage} from the given destination. A default timeout will be applied.
|
||||
*/
|
||||
AccurestMessage<PAYLOAD, TYPE_TO_CONVERT_INTO> receiveMessage(String destination);
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package io.codearte.accurest.messaging;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Helper class that allows to build headers in a nice way
|
||||
*
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public class AccurestMessagingUtil {
|
||||
|
||||
public static AccurestHeaders headers() {
|
||||
return new AccurestHeaders();
|
||||
}
|
||||
|
||||
public static class AccurestHeaders implements Map<String, Object> {
|
||||
|
||||
private final Map<String, Object> delegate = new HashMap<>();
|
||||
|
||||
public AccurestHeaders header(String key, Object value) {
|
||||
put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return delegate.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return delegate.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(Object key) {
|
||||
return delegate.containsKey(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsValue(Object value) {
|
||||
return delegate.containsValue(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(Object key) {
|
||||
return delegate.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object put(String key, Object value) {
|
||||
return delegate.put(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object remove(Object key) {
|
||||
return delegate.remove(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(Map<? extends String, ?> m) {
|
||||
delegate.putAll(m);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
delegate.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> keySet() {
|
||||
return delegate.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Object> values() {
|
||||
return delegate.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Entry<String, Object>> entrySet() {
|
||||
return delegate.entrySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return delegate.equals(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return delegate.hashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package io.codearte.accurest.messaging.noop;
|
||||
|
||||
import io.codearte.accurest.messaging.AccurestMessage;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public class NoOpAccurestMessage implements AccurestMessage {
|
||||
@Override
|
||||
public Object getPayload() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getHeaders() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getHeader(String key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object convert() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package io.codearte.accurest.messaging.noop;
|
||||
|
||||
import io.codearte.accurest.messaging.AccurestMessage;
|
||||
import io.codearte.accurest.messaging.AccurestMessageBuilder;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public class NoOpAccurestMessageBuilder implements AccurestMessageBuilder {
|
||||
@Override
|
||||
public AccurestMessage create(Object o, Map headers) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccurestMessage create(Object o) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package io.codearte.accurest.messaging.noop;
|
||||
|
||||
import io.codearte.accurest.messaging.AccurestMessage;
|
||||
import io.codearte.accurest.messaging.AccurestMessaging;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public class NoOpAccurestMessaging implements AccurestMessaging {
|
||||
@Override
|
||||
public void send(AccurestMessage message, String destination) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccurestMessage receiveMessage(String destination, long timeout, TimeUnit timeUnit) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccurestMessage receiveMessage(String destination) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccurestMessage create(Object o, Map headers) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccurestMessage create(Object o) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
maven {
|
||||
url "http://repo.spring.io/snapshot"
|
||||
}
|
||||
maven {
|
||||
url "http://repo.spring.io/milestone"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':accurest-messaging-root:accurest-messaging-core')
|
||||
compile 'org.springframework:spring-messaging:[4.0.0.RELEASE,)'
|
||||
compile 'org.slf4j:slf4j-api:[1.6.0,)'
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package io.codearte.accurest.messaging.integration;
|
||||
|
||||
import io.codearte.accurest.messaging.AccurestMessageBuilder;
|
||||
import io.codearte.accurest.messaging.AccurestMessaging;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public class AccurestIntegrationConfiguration {
|
||||
|
||||
@Bean
|
||||
AccurestMessaging accurestMessaging(ApplicationContext applicationContext, AccurestMessageBuilder accurestMessageBuilder) {
|
||||
return new AccurestIntegrationMessaging(applicationContext, accurestMessageBuilder);
|
||||
}
|
||||
|
||||
@Bean
|
||||
AccurestMessageBuilder accurestMessageBuilder() {
|
||||
return new AccurestIntegrationMessageBuilder();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package io.codearte.accurest.messaging.integration;
|
||||
|
||||
import io.codearte.accurest.messaging.AccurestMessage;
|
||||
import io.codearte.accurest.messaging.AccurestMessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public class AccurestIntegrationMessageBuilder<T> implements AccurestMessageBuilder<T, Message<T>> {
|
||||
|
||||
@Override
|
||||
public AccurestMessage<T, Message<T>> create(T payload, Map<String, Object> headers) {
|
||||
return new IntegrationMessage<>(MessageBuilder.createMessage(payload, new MessageHeaders(headers)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccurestMessage<T, Message<T>> create(Message<T> message) {
|
||||
return new IntegrationMessage<>(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package io.codearte.accurest.messaging.integration;
|
||||
|
||||
import io.codearte.accurest.messaging.AccurestMessage;
|
||||
import io.codearte.accurest.messaging.AccurestMessageBuilder;
|
||||
import io.codearte.accurest.messaging.AccurestMessaging;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.PollableChannel;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
@Component
|
||||
public class AccurestIntegrationMessaging<T> implements AccurestMessaging<T, Message<T>> {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(AccurestIntegrationMessaging.class);
|
||||
|
||||
private final ApplicationContext context;
|
||||
private final AccurestMessageBuilder builder;
|
||||
|
||||
@Autowired
|
||||
@SuppressWarnings("unchecked")
|
||||
public AccurestIntegrationMessaging(ApplicationContext context, AccurestMessageBuilder accurestMessageBuilder) {
|
||||
this.context = context;
|
||||
this.builder = accurestMessageBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(AccurestMessage<T, Message<T>> message, String destination) {
|
||||
try {
|
||||
MessageChannel messageChannel = context.getBean(destination, MessageChannel.class);
|
||||
messageChannel.send(message.convert());
|
||||
} catch (Exception e) {
|
||||
log.error("Exception occurred while trying to send a message [" + message + "] " +
|
||||
"to a channel with name [" + destination + "]", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public AccurestMessage<T, Message<T>> receiveMessage(String destination, long timeout, TimeUnit timeUnit) {
|
||||
try {
|
||||
PollableChannel messageChannel = context.getBean(destination, PollableChannel.class);
|
||||
return builder.create(messageChannel.receive(timeUnit.toMillis(timeout)));
|
||||
} catch (Exception e) {
|
||||
log.error("Exception occurred while trying to read a message from " +
|
||||
" a channel with name [" + destination + "]", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccurestMessage<T, Message<T>> receiveMessage(String destination) {
|
||||
return receiveMessage(destination, 5, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public AccurestMessage<T, Message<T>> create(T t, Map<String, Object> headers) {
|
||||
return builder.create(t, headers);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public AccurestMessage<T, Message<T>> create(Message<T> message) {
|
||||
return builder.create(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package io.codearte.accurest.messaging.integration;
|
||||
|
||||
import io.codearte.accurest.messaging.AccurestMessage;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public class IntegrationMessage<T> implements AccurestMessage<T, Message<T>> {
|
||||
|
||||
private final Message<T> delegate;
|
||||
|
||||
public IntegrationMessage(Message<T> delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getPayload() {
|
||||
return delegate.getPayload();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageHeaders getHeaders() {
|
||||
return delegate.getHeaders();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getHeader(String key) {
|
||||
return getHeaders().get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message<T> convert() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
# Auto Configuration
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
io.codearte.accurest.messaging.integration.AccurestIntegrationConfiguration
|
||||
16
accurest-messaging/accurest-messaging-stream/build.gradle
Normal file
16
accurest-messaging/accurest-messaging-stream/build.gradle
Normal file
@@ -0,0 +1,16 @@
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
maven {
|
||||
url "http://repo.spring.io/snapshot"
|
||||
}
|
||||
maven {
|
||||
url "http://repo.spring.io/milestone"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':accurest-messaging-root:accurest-messaging-core')
|
||||
compile 'org.springframework:spring-messaging:[4.0.0.RELEASE,)'
|
||||
compile 'org.springframework.cloud:spring-cloud-stream-test-support:[1.0.0.RC2,)'
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package io.codearte.accurest.messaging.stream;
|
||||
|
||||
import io.codearte.accurest.messaging.AccurestMessageBuilder;
|
||||
import io.codearte.accurest.messaging.AccurestMessaging;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
@Configuration
|
||||
public class AccurestStreamAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
AccurestMessaging accurestMessaging(ApplicationContext applicationContext, AccurestMessageBuilder accurestMessageBuilder) {
|
||||
return new AccurestStreamMessaging(applicationContext, accurestMessageBuilder);
|
||||
}
|
||||
|
||||
@Bean
|
||||
AccurestMessageBuilder accurestMessageBuilder() {
|
||||
return new AccurestStreamMessageBuilder();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package io.codearte.accurest.messaging.stream;
|
||||
|
||||
import io.codearte.accurest.messaging.AccurestMessage;
|
||||
import io.codearte.accurest.messaging.AccurestMessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public class AccurestStreamMessageBuilder<T> implements AccurestMessageBuilder<T, Message<T>> {
|
||||
|
||||
@Override
|
||||
public AccurestMessage<T, Message<T>> create(T payload, Map<String, Object> headers) {
|
||||
return new StreamMessage<>(MessageBuilder.createMessage(payload, new MessageHeaders(headers)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccurestMessage<T, Message<T>> create(Message<T> message) {
|
||||
return new StreamMessage<>(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package io.codearte.accurest.messaging.stream;
|
||||
|
||||
import io.codearte.accurest.messaging.AccurestMessage;
|
||||
import io.codearte.accurest.messaging.AccurestMessageBuilder;
|
||||
import io.codearte.accurest.messaging.AccurestMessaging;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.stream.test.binder.MessageCollector;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public class AccurestStreamMessaging<T> implements AccurestMessaging<T, Message<T>> {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(AccurestStreamMessaging.class);
|
||||
|
||||
private final ApplicationContext context;
|
||||
private final MessageCollector messageCollector;
|
||||
private final AccurestMessageBuilder builder;
|
||||
|
||||
@Autowired
|
||||
@SuppressWarnings("unchecked")
|
||||
public AccurestStreamMessaging(ApplicationContext context, AccurestMessageBuilder builder) {
|
||||
this.context = context;
|
||||
this.messageCollector = context.getBean(MessageCollector.class);
|
||||
this.builder = builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(AccurestMessage<T, Message<T>> message, String destination) {
|
||||
try {
|
||||
MessageChannel messageChannel = context.getBean(destination, MessageChannel.class);
|
||||
messageChannel.send(message.convert());
|
||||
} catch (Exception e) {
|
||||
log.error("Exception occurred while trying to send a message [" + message + "] " +
|
||||
"to a channel with name [" + destination + "]", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public AccurestMessage<T, Message<T>> receiveMessage(String destination, long timeout, TimeUnit timeUnit) {
|
||||
try {
|
||||
MessageChannel messageChannel = context.getBean(destination, MessageChannel.class);
|
||||
return builder.create(messageCollector.forChannel(messageChannel).poll(timeout, timeUnit));
|
||||
} catch (Exception e) {
|
||||
log.error("Exception occurred while trying to read a message from " +
|
||||
" a channel with name [" + destination + "]", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccurestMessage<T, Message<T>> receiveMessage(String destination) {
|
||||
return receiveMessage(destination, 5, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public AccurestMessage<T, Message<T>> create(T t, Map<String, Object> headers) {
|
||||
return builder.create(t, headers);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public AccurestMessage<T, Message<T>> create(Message<T> message) {
|
||||
return builder.create(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package io.codearte.accurest.messaging.stream;
|
||||
|
||||
import io.codearte.accurest.messaging.AccurestMessage;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public class StreamMessage<T> implements AccurestMessage<T, Message<T>> {
|
||||
|
||||
private final Message<T> delegate;
|
||||
|
||||
public StreamMessage(Message<T> delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getPayload() {
|
||||
return delegate.getPayload();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageHeaders getHeaders() {
|
||||
return delegate.getHeaders();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getHeader(String key) {
|
||||
return getHeaders().get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message<T> convert() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
# Auto Configuration
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
io.codearte.accurest.messaging.stream.AccurestStreamAutoConfiguration
|
||||
@@ -9,7 +9,6 @@ buildscript {
|
||||
classpath "com.bmuschko:gradle-nexus-plugin:2.3"
|
||||
classpath "io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.5.3"
|
||||
if (project.hasProperty('fatJar')) classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.3'
|
||||
classpath "io.spring.gradle:dependency-management-plugin:0.5.6.RELEASE"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,7 +97,7 @@ project(':accurest-core') {
|
||||
compile "com.github.tomakehurst:wiremock:$wiremockVersion"
|
||||
compile "com.toomuchcoding.jsonassert:jsonassert:$jsonassertVersion"
|
||||
compile 'org.assertj:assertj-core:2.3.0'
|
||||
compile 'org.codehaus.groovy:groovy-all:2.4.4'
|
||||
compile localGroovy()
|
||||
testCompile 'cglib:cglib-nodep:2.2'
|
||||
testCompile 'org.objenesis:objenesis:2.1'
|
||||
testCompile project(':accurest-testing-utils')
|
||||
@@ -129,8 +128,8 @@ project(':accurest-gradle-plugin') {
|
||||
dependencies {
|
||||
compile project(':accurest-core')
|
||||
compile project(':accurest-converters')
|
||||
|
||||
compile gradleApi()
|
||||
|
||||
testCompile('com.netflix.nebula:nebula-test:4.0.0') {
|
||||
exclude(group: 'org.spockframework')
|
||||
}
|
||||
@@ -148,6 +147,10 @@ project(':accurest-gradle-plugin') {
|
||||
}
|
||||
}
|
||||
|
||||
// Hack for reusing this in the plugin test
|
||||
test.dependsOn(':accurest-core:install')
|
||||
test.dependsOn(':accurest-messaging-root:accurest-messaging-core:install')
|
||||
test.dependsOn(':accurest-messaging-root:accurest-messaging-integration:install')
|
||||
uploadArchives.dependsOn { funcTest }
|
||||
}
|
||||
|
||||
|
||||
@@ -2,4 +2,6 @@ nexusUsername =
|
||||
nexusPassword =
|
||||
|
||||
wiremockVersion = 2.0.5-beta
|
||||
jsonassertVersion = 0.2.2
|
||||
jsonassertVersion = 0.2.2
|
||||
|
||||
BOM_VERSION=Brixton-1.0.0.RC1
|
||||
26
samples/messaging-camel/build.gradle
Normal file
26
samples/messaging-camel/build.gradle
Normal file
@@ -0,0 +1,26 @@
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
maven {
|
||||
url "http://repo.spring.io/snapshot"
|
||||
}
|
||||
maven {
|
||||
url "http://repo.spring.io/milestone"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':accurest-core')
|
||||
compile 'org.springframework.boot:spring-boot-starter-actuator:1.3.3.RELEASE'
|
||||
compile 'org.apache.camel:camel-spring-boot-starter:2.17.0'
|
||||
compile 'org.apache.camel:camel-jms:2.17.0'
|
||||
compile 'org.apache.activemq:activemq-camel:5.12.1'
|
||||
compile 'org.apache.activemq:activemq-pool:5.12.1'
|
||||
compile 'org.apache.camel:camel-jackson:2.17.0'
|
||||
|
||||
testCompile project(':accurest-messaging-root:accurest-messaging-camel')
|
||||
testCompile 'org.springframework.boot:spring-boot-starter-test:1.3.3.RELEASE'
|
||||
testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') {
|
||||
exclude(group: 'org.codehaus.groovy')
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package io.codearte.accurest.samples.camel
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
@CompileStatic
|
||||
class BookDeleted implements Serializable {
|
||||
final String bookName
|
||||
|
||||
@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
|
||||
BookDeleted(String bookName) {
|
||||
this.bookName = bookName
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package io.codearte.accurest.samples.camel
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import groovy.util.logging.Slf4j
|
||||
import org.apache.camel.Exchange
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
@CompileStatic
|
||||
@Slf4j
|
||||
@Component
|
||||
class BookDeleter {
|
||||
|
||||
/**
|
||||
Scenario for "should generate tests triggered by a message":
|
||||
client side: if sends a message to input.messageFrom then message will be sent to output.messageFrom
|
||||
server side: will send a message to input, verify the message contents and await upon receiving message on the output messageFrom
|
||||
*/
|
||||
void bookDeleted(Exchange exchange) {
|
||||
BookDeleted bookDeleted = exchange.in.getBody(BookDeleted)
|
||||
log.info("Deleting book [$bookDeleted]")
|
||||
bookSuccessfulyDeleted.set(true)
|
||||
log.info("Book successfuly deleted [$bookSuccessfulyDeleted]")
|
||||
}
|
||||
|
||||
AtomicBoolean bookSuccessfulyDeleted = new AtomicBoolean(false)
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package io.codearte.accurest.samples.camel
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
@CompileStatic
|
||||
class BookReturned implements Serializable {
|
||||
final String bookName
|
||||
|
||||
@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
|
||||
BookReturned(String bookName) {
|
||||
this.bookName = bookName
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package io.codearte.accurest.samples.camel
|
||||
|
||||
import org.apache.activemq.camel.component.ActiveMQComponent
|
||||
import org.apache.camel.RoutesBuilder
|
||||
import org.apache.camel.model.dataformat.JsonLibrary
|
||||
import org.apache.camel.spring.SpringRouteBuilder
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
@Configuration
|
||||
class BookRouteConfiguration {
|
||||
|
||||
@Bean
|
||||
ActiveMQComponent activeMQComponent(@Value('${activemq.url:vm://localhost?broker.persistent=false}') String url) {
|
||||
return new ActiveMQComponent(brokerURL: url)
|
||||
}
|
||||
|
||||
@Bean
|
||||
RoutesBuilder myRouter(BookService bookService, BookDeleter bookDeleter) {
|
||||
return new SpringRouteBuilder() {
|
||||
|
||||
@Override
|
||||
public void configure() throws Exception {
|
||||
// scenario 1 - from bean to output
|
||||
from("direct:start").unmarshal().json(JsonLibrary.Jackson, BookReturned).bean(bookService).to("jms:output")
|
||||
// scenario 2 - from input to output
|
||||
from("jms:input").unmarshal().json(JsonLibrary.Jackson, BookReturned).bean(bookService).to("jms:output")
|
||||
// scenario 3 - from input to no output
|
||||
from("jms:delete").unmarshal().json(JsonLibrary.Jackson, BookDeleted).bean(bookDeleter)
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package io.codearte.accurest.samples.camel
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import groovy.util.logging.Slf4j
|
||||
import org.apache.camel.Exchange
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
@CompileStatic
|
||||
@Slf4j
|
||||
class BookService {
|
||||
|
||||
/**
|
||||
Scenario for "should generate tests triggered by a method":
|
||||
client side: must have a possibility to "trigger" sending of a message to the given messageFrom
|
||||
server side: will run the method and await upon receiving message on the output messageFrom
|
||||
|
||||
Method triggers sending a message to a source
|
||||
*/
|
||||
void returnBook(Exchange exchange) {
|
||||
BookReturned bookReturned = exchange.in.getBody(BookReturned)
|
||||
log.info("Returning book [$bookReturned]")
|
||||
exchange.out.with {
|
||||
body = bookReturned
|
||||
setHeader('BOOK-NAME', bookReturned.bookName)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package io.codearte.accurest.samples.camel
|
||||
|
||||
import org.springframework.boot.SpringApplication
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
|
||||
@SpringBootApplication
|
||||
class CamelMessagingApplication {
|
||||
|
||||
static void main(String[] args) {
|
||||
SpringApplication.run(CamelMessagingApplication.class, args)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
package io.codearte.accurest.samples.camel
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.jayway.jsonpath.DocumentContext
|
||||
import com.jayway.jsonpath.JsonPath
|
||||
import com.toomuchcoding.jsonassert.JsonAssertion
|
||||
import io.codearte.accurest.dsl.GroovyDsl
|
||||
import io.codearte.accurest.messaging.AccurestMessage
|
||||
import io.codearte.accurest.messaging.AccurestMessaging
|
||||
import org.apache.camel.model.ModelCamelContext
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.test.SpringApplicationContextLoader
|
||||
import org.springframework.test.context.ContextConfiguration
|
||||
import spock.lang.Specification
|
||||
import spock.util.concurrent.PollingConditions
|
||||
|
||||
import javax.inject.Inject
|
||||
/**
|
||||
* SPIKE ON TESTS FROM NOTES IN MessagingSpec
|
||||
*/
|
||||
// Context configuration would end up in base class
|
||||
@ContextConfiguration(classes = [CamelMessagingApplication], loader = SpringApplicationContextLoader)
|
||||
public class CamelMessagingApplicationSpec extends Specification {
|
||||
|
||||
// ALL CASES
|
||||
@Inject AccurestMessaging accurestMessaging
|
||||
ObjectMapper accurestObjectMapper = new ObjectMapper()
|
||||
|
||||
def "should work for triggered based messaging"() {
|
||||
given:
|
||||
def dsl = GroovyDsl.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
triggeredBy('bookReturnedTriggered()')
|
||||
}
|
||||
outputMessage {
|
||||
sentTo('activemq:output')
|
||||
body('''{ "bookName" : "foo" }''')
|
||||
headers {
|
||||
header('BOOK-NAME', 'foo')
|
||||
}
|
||||
}
|
||||
}
|
||||
// generated test should look like this:
|
||||
when:
|
||||
bookReturnedTriggered()
|
||||
then:
|
||||
def response = accurestMessaging.receiveMessage('activemq:output')
|
||||
response.headers.get('BOOK-NAME') == 'foo'
|
||||
and:
|
||||
DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload))
|
||||
JsonAssertion.assertThat(parsedJson).field('bookName').isEqualTo('foo')
|
||||
}
|
||||
|
||||
def "should generate tests triggered by a message"() {
|
||||
given:
|
||||
def dsl = GroovyDsl.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
messageFrom('jms:input')
|
||||
messageBody([
|
||||
bookName: 'foo'
|
||||
])
|
||||
messageHeaders {
|
||||
header('sample', 'header')
|
||||
header('Content-Type', 'application/json')
|
||||
}
|
||||
}
|
||||
outputMessage {
|
||||
sentTo('jms:output')
|
||||
body([
|
||||
bookName: 'foo'
|
||||
])
|
||||
headers {
|
||||
header('BOOK-NAME', 'foo')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// generated test should look like this:
|
||||
|
||||
//given:
|
||||
AccurestMessage inputMessage = accurestMessaging.create(
|
||||
accurestObjectMapper.writeValueAsString([bookName: 'foo']),
|
||||
[sample: 'header']
|
||||
)
|
||||
when:
|
||||
accurestMessaging.send(inputMessage, 'jms:input')
|
||||
then:
|
||||
def response = accurestMessaging.receiveMessage('jms:output')
|
||||
response.headers.get('BOOK-NAME') == 'foo'
|
||||
and:
|
||||
DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload))
|
||||
JsonAssertion.assertThat(parsedJson).field('bookName').isEqualTo('foo')
|
||||
}
|
||||
|
||||
def "should generate tests without destination, triggered by a message"() {
|
||||
given:
|
||||
def dsl = GroovyDsl.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
messageFrom('jms:delete')
|
||||
messageBody([
|
||||
bookName: 'foo'
|
||||
])
|
||||
messageHeaders {
|
||||
header('sample', 'header')
|
||||
}
|
||||
assertThat('bookWasDeleted()')
|
||||
}
|
||||
}
|
||||
|
||||
// generated test should look like this:
|
||||
|
||||
//given:
|
||||
AccurestMessage inputMessage = accurestMessaging.create(
|
||||
accurestObjectMapper.writeValueAsString([bookName: 'foo']),
|
||||
[sample: 'header']
|
||||
)
|
||||
when:
|
||||
accurestMessaging.send(inputMessage, 'jms:delete')
|
||||
then:
|
||||
noExceptionThrown()
|
||||
bookWasDeleted()
|
||||
}
|
||||
|
||||
// BASE CLASS WOULD HAVE THIS:
|
||||
|
||||
@Autowired ModelCamelContext camelContext
|
||||
@Autowired BookDeleter bookDeleter
|
||||
|
||||
void bookReturnedTriggered() {
|
||||
camelContext.createProducerTemplate().sendBody('direct:start', '''{"bookName" : "foo" }''')
|
||||
}
|
||||
|
||||
PollingConditions pollingConditions = new PollingConditions()
|
||||
|
||||
void bookWasDeleted() {
|
||||
pollingConditions.eventually {
|
||||
assert bookDeleter.bookSuccessfulyDeleted.get()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
23
samples/messaging-integration/build.gradle
Normal file
23
samples/messaging-integration/build.gradle
Normal file
@@ -0,0 +1,23 @@
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
maven {
|
||||
url "http://repo.spring.io/snapshot"
|
||||
}
|
||||
maven {
|
||||
url "http://repo.spring.io/milestone"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':accurest-core')
|
||||
compile 'org.springframework.boot:spring-boot-starter-actuator:1.3.3.RELEASE'
|
||||
compile 'org.springframework.boot:spring-boot-starter-integration:1.3.3.RELEASE'
|
||||
compile 'org.springframework:spring-messaging:[4.0.0.RELEASE,)'
|
||||
|
||||
testCompile project(':accurest-messaging-root:accurest-messaging-integration')
|
||||
testCompile 'org.springframework.boot:spring-boot-starter-test:1.3.3.RELEASE'
|
||||
testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') {
|
||||
exclude(group: 'org.codehaus.groovy')
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package io.codearte.accurest.samples.messaging
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
@CompileStatic
|
||||
class BookDeleted {
|
||||
final String bookName
|
||||
|
||||
@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
|
||||
BookDeleted(String bookName) {
|
||||
this.bookName = bookName
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package io.codearte.accurest.samples.messaging
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import groovy.util.logging.Slf4j
|
||||
import org.springframework.messaging.Message
|
||||
import org.springframework.messaging.MessageHeaders
|
||||
import org.springframework.messaging.support.MessageBuilder
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
@CompileStatic
|
||||
@Slf4j
|
||||
class BookListener {
|
||||
|
||||
/**
|
||||
Scenario for "should generate tests triggered by a message":
|
||||
client side: if sends a message to input.messageFrom then message will be sent to output.messageFrom
|
||||
server side: will send a message to input, verify the message contents and await upon receiving message on the output messageFrom
|
||||
*/
|
||||
Message returnBook(BookReturned bookReturned) {
|
||||
log.info("Returning book [$bookReturned]")
|
||||
return MessageBuilder.createMessage(bookReturned, new MessageHeaders([
|
||||
'BOOK-NAME': bookReturned.bookName as Object
|
||||
]))
|
||||
}
|
||||
|
||||
/**
|
||||
Scenario for "should generate tests triggered by a message":
|
||||
client side: if sends a message to input.messageFrom then message will be sent to output.messageFrom
|
||||
server side: will send a message to input, verify the message contents and await upon receiving message on the output messageFrom
|
||||
*/
|
||||
void bookDeleted(BookDeleted bookDeleted) {
|
||||
log.info("Deleting book [$bookDeleted]")
|
||||
bookSuccessfulyDeleted.set(true)
|
||||
}
|
||||
|
||||
AtomicBoolean bookSuccessfulyDeleted = new AtomicBoolean(false)
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package io.codearte.accurest.samples.messaging
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
@CompileStatic
|
||||
class BookReturned {
|
||||
final String bookName
|
||||
|
||||
@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
|
||||
BookReturned(String bookName) {
|
||||
this.bookName = bookName
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package io.codearte.accurest.samples.messaging
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import groovy.util.logging.Slf4j
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.beans.factory.annotation.Qualifier
|
||||
import org.springframework.messaging.MessageChannel
|
||||
import org.springframework.messaging.MessageHeaders
|
||||
import org.springframework.messaging.support.MessageBuilder
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
@Service
|
||||
@CompileStatic
|
||||
@Slf4j
|
||||
class BookService {
|
||||
|
||||
@Autowired @Qualifier("outputChannel") MessageChannel outputChannel
|
||||
|
||||
/**
|
||||
Scenario for "should generate tests triggered by a method":
|
||||
client side: must have a possibility to "trigger" sending of a message to the given messageFrom
|
||||
server side: will run the method and await upon receiving message on the output messageFrom
|
||||
|
||||
Method triggers sending a message to a source
|
||||
*/
|
||||
void returnBook(BookReturned bookReturned) {
|
||||
log.info("Returning book [$bookReturned]")
|
||||
outputChannel.send(MessageBuilder.createMessage(bookReturned, new MessageHeaders([
|
||||
'BOOK-NAME': bookReturned.bookName as Object
|
||||
])))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package io.codearte.accurest.samples.messaging
|
||||
|
||||
import org.springframework.boot.SpringApplication
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
import org.springframework.context.annotation.ImportResource
|
||||
|
||||
@SpringBootApplication
|
||||
@ImportResource("classpath*:integration-context.xml")
|
||||
class IntegrationMessagingApplication {
|
||||
|
||||
static void main(String[] args) {
|
||||
SpringApplication.run(IntegrationMessagingApplication.class, args)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="input"/>
|
||||
<channel id="delete"/>
|
||||
<channel id="outputChannel"/>
|
||||
|
||||
<service-activator input-channel="inputChannel"
|
||||
output-channel="outputChannel"
|
||||
ref="bookListener"
|
||||
method="returnBook"/>
|
||||
|
||||
<json-to-object-transformer input-channel="input" type="io.codearte.accurest.samples.messaging.BookReturned"
|
||||
output-channel="inputChannel"/>
|
||||
|
||||
<service-activator input-channel="deleteChannel"
|
||||
ref="bookListener"
|
||||
method="bookDeleted"/>
|
||||
|
||||
<json-to-object-transformer input-channel="delete" type="io.codearte.accurest.samples.messaging.BookDeleted"
|
||||
output-channel="deleteChannel"/>
|
||||
|
||||
<beans:bean id="bookListener" class="io.codearte.accurest.samples.messaging.BookListener"/>
|
||||
|
||||
|
||||
<!-- REQUIRED FOR TESTING -->
|
||||
<bridge input-channel="outputChannel"
|
||||
output-channel="output"/>
|
||||
|
||||
<channel id="output">
|
||||
<queue/>
|
||||
</channel>
|
||||
|
||||
</beans:beans>
|
||||
@@ -0,0 +1,138 @@
|
||||
package io.codearte.accurest.samples.messaging
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.jayway.jsonpath.DocumentContext
|
||||
import com.jayway.jsonpath.JsonPath
|
||||
import com.toomuchcoding.jsonassert.JsonAssertion
|
||||
import io.codearte.accurest.dsl.GroovyDsl
|
||||
import io.codearte.accurest.messaging.AccurestMessage
|
||||
import io.codearte.accurest.messaging.AccurestMessaging
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.test.SpringApplicationContextLoader
|
||||
import org.springframework.test.context.ContextConfiguration
|
||||
import spock.lang.Specification
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* SPIKE ON TESTS FROM NOTES IN MessagingSpec
|
||||
*/
|
||||
// Context configuration would end up in base class
|
||||
@ContextConfiguration(classes = [IntegrationMessagingApplication], loader = SpringApplicationContextLoader)
|
||||
public class IntegrationMessagingApplicationSpec extends Specification {
|
||||
|
||||
// ALL CASES
|
||||
@Inject AccurestMessaging accurestMessaging
|
||||
ObjectMapper accurestObjectMapper = new ObjectMapper()
|
||||
|
||||
def "should work for triggered based messaging"() {
|
||||
given:
|
||||
def dsl = GroovyDsl.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
triggeredBy('bookReturnedTriggered()')
|
||||
}
|
||||
outputMessage {
|
||||
sentTo('output')
|
||||
body('''{ "bookName" : "foo" }''')
|
||||
headers {
|
||||
header('BOOK-NAME', 'foo')
|
||||
}
|
||||
}
|
||||
}
|
||||
// generated test should look like this:
|
||||
when:
|
||||
bookReturnedTriggered()
|
||||
then:
|
||||
def response = accurestMessaging.receiveMessage('output')
|
||||
response.headers.get('BOOK-NAME') == 'foo'
|
||||
and:
|
||||
DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload))
|
||||
JsonAssertion.assertThat(parsedJson).field('bookName').isEqualTo('foo')
|
||||
}
|
||||
|
||||
def "should generate tests triggered by a message"() {
|
||||
given:
|
||||
def dsl = GroovyDsl.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
messageFrom('input')
|
||||
messageBody([
|
||||
bookName: 'foo'
|
||||
])
|
||||
messageHeaders {
|
||||
header('sample', 'header')
|
||||
}
|
||||
}
|
||||
outputMessage {
|
||||
sentTo('output')
|
||||
body([
|
||||
bookName: 'foo'
|
||||
])
|
||||
headers {
|
||||
header('BOOK-NAME', 'foo')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// generated test should look like this:
|
||||
|
||||
//given:
|
||||
AccurestMessage inputMessage = accurestMessaging.create(
|
||||
accurestObjectMapper.writeValueAsString([bookName: 'foo']),
|
||||
[sample: 'header']
|
||||
)
|
||||
when:
|
||||
accurestMessaging.send(inputMessage, 'input')
|
||||
then:
|
||||
def response = accurestMessaging.receiveMessage('output')
|
||||
response.headers.get('BOOK-NAME') == 'foo'
|
||||
and:
|
||||
DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload))
|
||||
JsonAssertion.assertThat(parsedJson).field('bookName').isEqualTo('foo')
|
||||
}
|
||||
|
||||
def "should generate tests without destination, triggered by a message"() {
|
||||
given:
|
||||
def dsl = GroovyDsl.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
messageFrom('delete')
|
||||
messageBody([
|
||||
bookName: 'foo'
|
||||
])
|
||||
messageHeaders {
|
||||
header('sample', 'header')
|
||||
}
|
||||
assertThat('bookWasDeleted()')
|
||||
}
|
||||
}
|
||||
|
||||
// generated test should look like this:
|
||||
|
||||
//given:
|
||||
AccurestMessage inputMessage = accurestMessaging.create(
|
||||
accurestObjectMapper.writeValueAsString([bookName: 'foo']),
|
||||
[sample: 'header']
|
||||
)
|
||||
when:
|
||||
accurestMessaging.send(inputMessage, 'delete')
|
||||
then:
|
||||
noExceptionThrown()
|
||||
bookWasDeleted()
|
||||
}
|
||||
|
||||
// BASE CLASS WOULD HAVE THIS:
|
||||
|
||||
@Autowired BookService bookService
|
||||
@Autowired BookListener bookListener
|
||||
|
||||
void bookReturnedTriggered() {
|
||||
bookService.returnBook(new BookReturned("foo"))
|
||||
}
|
||||
|
||||
void bookWasDeleted() {
|
||||
assert bookListener.bookSuccessfulyDeleted.get()
|
||||
}
|
||||
|
||||
}
|
||||
25
samples/messaging-spring/build.gradle
Normal file
25
samples/messaging-spring/build.gradle
Normal file
@@ -0,0 +1,25 @@
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
maven {
|
||||
url "http://repo.spring.io/snapshot"
|
||||
}
|
||||
maven {
|
||||
url "http://repo.spring.io/milestone"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':accurest-core')
|
||||
compile 'org.springframework.boot:spring-boot-starter-actuator:1.3.3.RELEASE'
|
||||
compile 'org.springframework:spring-jms:4.2.3.RELEASE'
|
||||
|
||||
compile 'org.apache.activemq:activemq-broker:5.12.1'
|
||||
compile 'org.apache.activemq:activemq-pool:5.12.1'
|
||||
|
||||
testCompile project(':accurest-messaging-root:accurest-messaging-core')
|
||||
testCompile 'org.springframework.boot:spring-boot-starter-test:1.3.3.RELEASE'
|
||||
testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') {
|
||||
exclude(group: 'org.codehaus.groovy')
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package io.codearte.accurest.samples.spring
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
@CompileStatic
|
||||
class BookDeleted implements Serializable {
|
||||
final String bookName
|
||||
|
||||
@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
|
||||
BookDeleted(String bookName) {
|
||||
this.bookName = bookName
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package io.codearte.accurest.samples.spring
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import groovy.transform.CompileStatic
|
||||
import groovy.util.logging.Slf4j
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.jms.annotation.JmsListener
|
||||
import org.springframework.jms.core.JmsTemplate
|
||||
import org.springframework.jms.core.MessageCreator
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
import javax.jms.JMSException
|
||||
import javax.jms.Message
|
||||
import javax.jms.Session
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
@CompileStatic
|
||||
@Slf4j
|
||||
@Service
|
||||
class BookListener {
|
||||
|
||||
@Autowired JmsTemplate jmsTemplate
|
||||
ObjectMapper objectMapper = new ObjectMapper()
|
||||
|
||||
/**
|
||||
Scenario for "should generate tests triggered by a message":
|
||||
client side: if sends a message to input.messageFrom then message will be sent to output.messageFrom
|
||||
server side: will send a message to input, verify the message contents and await upon receiving message on the output messageFrom
|
||||
*/
|
||||
@JmsListener(destination = "input")
|
||||
void returnBook(String messageAsString) {
|
||||
BookReturned bookReturned = objectMapper.readerFor(BookReturned).readValue(messageAsString) as BookReturned
|
||||
log.info("Returning book [$bookReturned]")
|
||||
MessageCreator messageCreator = new MessageCreator() {
|
||||
@Override
|
||||
public Message createMessage(Session session) throws JMSException {
|
||||
Message message = session.createObjectMessage(bookReturned);
|
||||
message.setStringProperty('BOOK-NAME', bookReturned.bookName)
|
||||
return message
|
||||
}
|
||||
};
|
||||
jmsTemplate.send('output', messageCreator)
|
||||
}
|
||||
|
||||
/**
|
||||
Scenario for "should generate tests triggered by a message":
|
||||
client side: if sends a message to input.messageFrom then message will be sent to output.messageFrom
|
||||
server side: will send a message to input, verify the message contents and await upon receiving message on the output messageFrom
|
||||
*/
|
||||
@JmsListener(destination = "delete")
|
||||
void bookDeleted(String bookDeletedAsString) {
|
||||
BookDeleted bookDeleted = objectMapper.readerFor(BookDeleted).readValue(bookDeletedAsString) as BookDeleted
|
||||
log.info("Deleting book [$bookDeleted]")
|
||||
bookSuccessfulyDeleted.set(true)
|
||||
}
|
||||
|
||||
AtomicBoolean bookSuccessfulyDeleted = new AtomicBoolean(false)
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package io.codearte.accurest.samples.spring
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator
|
||||
import groovy.transform.CompileStatic
|
||||
|
||||
@CompileStatic
|
||||
class BookReturned implements Serializable {
|
||||
String bookName
|
||||
|
||||
@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
|
||||
BookReturned(String bookName) {
|
||||
this.bookName = bookName
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package io.codearte.accurest.samples.spring
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import groovy.util.logging.Slf4j
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.jms.core.JmsTemplate
|
||||
import org.springframework.jms.core.MessageCreator
|
||||
import org.springframework.stereotype.Service
|
||||
|
||||
import javax.jms.JMSException
|
||||
import javax.jms.Message
|
||||
import javax.jms.Session
|
||||
|
||||
@Service
|
||||
@CompileStatic
|
||||
@Slf4j
|
||||
class BookService {
|
||||
|
||||
@Autowired JmsTemplate jmsTemplate
|
||||
|
||||
/**
|
||||
Scenario for "should generate tests triggered by a method":
|
||||
client side: must have a possibility to "trigger" sending of a message to the given messageFrom
|
||||
server side: will run the method and await upon receiving message on the output messageFrom
|
||||
|
||||
Method triggers sending a message to a source
|
||||
*/
|
||||
void returnBook(BookReturned bookReturned ) {
|
||||
log.info("Returning book [$bookReturned]")
|
||||
MessageCreator messageCreator = new MessageCreator() {
|
||||
@Override
|
||||
public Message createMessage(Session session) throws JMSException {
|
||||
Message message = session.createObjectMessage(bookReturned);
|
||||
message.setStringProperty('BOOK-NAME', bookReturned.bookName)
|
||||
return message
|
||||
}
|
||||
};
|
||||
jmsTemplate.send('output', messageCreator)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package io.codearte.accurest.samples.spring
|
||||
|
||||
import org.springframework.boot.SpringApplication
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication
|
||||
import org.springframework.jms.annotation.EnableJms
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableJms
|
||||
class SpringMessagingApplication {
|
||||
|
||||
static void main(String[] args) {
|
||||
SpringApplication.run(SpringMessagingApplication.class, args)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
package io.codearte.accurest.samples.spring
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper
|
||||
import com.jayway.jsonpath.DocumentContext
|
||||
import com.jayway.jsonpath.JsonPath
|
||||
import com.toomuchcoding.jsonassert.JsonAssertion
|
||||
import io.codearte.accurest.dsl.GroovyDsl
|
||||
import io.codearte.accurest.messaging.AccurestMessage
|
||||
import io.codearte.accurest.messaging.AccurestMessaging
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.boot.test.SpringApplicationContextLoader
|
||||
import org.springframework.test.context.ContextConfiguration
|
||||
import spock.lang.Specification
|
||||
import spock.util.concurrent.PollingConditions
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* SPIKE ON TESTS FROM NOTES IN MessagingSpec
|
||||
*/
|
||||
// Context configuration would end up in base class
|
||||
@ContextConfiguration(classes = [SpringMessagingApplication], loader = SpringApplicationContextLoader)
|
||||
public class SpringApplicationSpec extends Specification {
|
||||
|
||||
// ALL CASES
|
||||
@Inject AccurestMessaging accurestMessaging
|
||||
ObjectMapper accurestObjectMapper = new ObjectMapper()
|
||||
|
||||
def "should work for triggered based messaging"() {
|
||||
given:
|
||||
def dsl = GroovyDsl.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
triggeredBy('bookReturnedTriggered()')
|
||||
}
|
||||
outputMessage {
|
||||
sentTo('output')
|
||||
body('''{ "bookName" : "foo" }''')
|
||||
headers {
|
||||
header('BOOK-NAME', 'foo')
|
||||
}
|
||||
}
|
||||
}
|
||||
// generated test should look like this:
|
||||
when:
|
||||
bookReturnedTriggered()
|
||||
then:
|
||||
def response = accurestMessaging.receiveMessage('output')
|
||||
response.headers.get('BOOK-NAME') == 'foo'
|
||||
and:
|
||||
DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload))
|
||||
JsonAssertion.assertThat(parsedJson).field('bookName').isEqualTo('foo')
|
||||
}
|
||||
|
||||
def "should generate tests triggered by a message"() {
|
||||
given:
|
||||
def dsl = GroovyDsl.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
messageFrom('input')
|
||||
messageBody([
|
||||
bookName: 'foo'
|
||||
])
|
||||
messageHeaders {
|
||||
header('sample', 'header')
|
||||
}
|
||||
}
|
||||
outputMessage {
|
||||
sentTo('output')
|
||||
body([
|
||||
bookName: 'foo'
|
||||
])
|
||||
headers {
|
||||
header('BOOK-NAME', 'foo')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// generated test should look like this:
|
||||
|
||||
//given:
|
||||
AccurestMessage inputMessage = accurestMessaging.create(
|
||||
accurestObjectMapper.writeValueAsString([bookName: 'foo']),
|
||||
[sample: 'header']
|
||||
)
|
||||
when:
|
||||
accurestMessaging.send(inputMessage, 'input')
|
||||
then:
|
||||
def response = accurestMessaging.receiveMessage('output')
|
||||
response.headers.get('BOOK-NAME') == 'foo'
|
||||
and:
|
||||
DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload))
|
||||
JsonAssertion.assertThat(parsedJson).field('bookName').isEqualTo('foo')
|
||||
}
|
||||
|
||||
def "should generate tests without destination, triggered by a message"() {
|
||||
given:
|
||||
def dsl = GroovyDsl.make {
|
||||
label 'some_label'
|
||||
input {
|
||||
messageFrom('delete')
|
||||
messageBody([
|
||||
bookName: 'foo'
|
||||
])
|
||||
messageHeaders {
|
||||
header('sample', 'header')
|
||||
}
|
||||
assertThat('bookWasDeleted()')
|
||||
}
|
||||
}
|
||||
|
||||
// generated test should look like this:
|
||||
|
||||
//given:
|
||||
AccurestMessage inputMessage = accurestMessaging.create(
|
||||
accurestObjectMapper.writeValueAsString([bookName: 'foo']),
|
||||
[sample: 'header']
|
||||
)
|
||||
when:
|
||||
accurestMessaging.send(inputMessage, 'delete')
|
||||
then:
|
||||
noExceptionThrown()
|
||||
bookWasDeleted()
|
||||
}
|
||||
|
||||
// BASE CLASS WOULD HAVE THIS:
|
||||
|
||||
@Autowired BookService bookService
|
||||
@Autowired BookListener bookListener
|
||||
|
||||
void bookReturnedTriggered() {
|
||||
bookService.returnBook(new BookReturned("foo"))
|
||||
}
|
||||
|
||||
PollingConditions pollingConditions = new PollingConditions()
|
||||
|
||||
void bookWasDeleted() {
|
||||
pollingConditions.eventually {
|
||||
assert bookListener.bookSuccessfulyDeleted.get()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user