diff --git a/README.md b/README.md index 43e94094cd..7cead077d6 100644 --- a/README.md +++ b/README.md @@ -1,239 +1,14 @@ Accurate REST ============= + +[![Build Status](https://travis-ci.org/Codearte/accurest.svg?branch=master)](https://travis-ci.org/Codearte/accurest) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.codearte.accurest/accurest-gradle-plugin/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.codearte.accurest/accurest-gradle-plugin) + Consumer Driven Contracts verifier for Java -# Introduction +Just to make long story short - AccuREST is a tool for Consumer Driven Contract (CDC) development. AccuREST ships easy DSL for describing REST contracts for JVM-based applications. The contract DSL is used by AccuREST for two things: -We would like to use the Wiremock's JSON stub definitions as a point of entry to our approach of Consumer Driven Contracts (CDC). From these JSON stub definitions we would like to generate Acceptance tests that will allow you to start using CDC as TDD from architecture point of view. +generating Wiremock's JSON stub definitions, allowing rapid development of the consumer side, +generating Spock's acceptance tests for the server - to verify if your API implementation is compliant with the contract. +By using AccuREST you can move TDD to an architecture level. -# Notations - - * __Collaborator__ - a service whom your service can contact - * __Client test__ - since your service is a client of your collaborator then the tests of your service are __client tests__ - * __Server test__ - from a your service's (client) perspective your collaborator is a server that provides a functionality thus tests of your collaborators are __server tests__ - -# Why? - -The main purpose of this approach is to: - - - ensure that our stubs are doing exactly what the actual implementation does - - generate acceptance test cases from stub definitions (ATDD) - - make the stub definitions reusable - -Below we depict the idea behind client and server side testing. Let's assume that for the sake -of this description that there is a _service X_ calling a _service Y_. - -## Client side (service X) - -During the tests you want to have a Wiremock instance up and running that simulates the service Y. -You would like to feed that instance with a proper stub definition. That stub definition would need -to be valid from the Wiremock's perspective but should also be reusable on the server side. - -__Summing it up:__ On this side, in the stub definition, you can use patterns for request stubbing and you need exact -values for responses. - -## Server side (service Y) - -Being a service Y since you are developing your stub, you need to be sure that it's actually resembling your -concrete implementation. You can't have a situation where your stub acts in one way and your application on -production behaves in a different way. - -That's why from the provided stub acceptance tests will be generated that will ensure -that your application behaves in the same way as you define in your stub. - -__Summing it up:__ On this side, in the stub definition, you need exact values as request and can use patterns/methods -for response verification. - -# Description - -To achieve that we needed to tweak the standard Wiremock stub definitions by providing a possibility of entering -two values for one field. This is done via the following pattern: - -``` -${VALUE_FOR_CLIENT_TESTS:VALUE_FOR_SERVER_TESTS} -``` - -That means that depending on the need you can take either value for the client test or server test. - -## Example - -Let's take a look at the following example - -``` -{ - "request": { - "method": "GET", - "urlPattern": "${/[0-9]{2}:/12}" - }, - "response": { - "status": 200, - "body": "{\"date\":\"${\"2015-01-14\":$anyInt($it)}\"}}", - "headers": { - "Content-Type": "text/plain" - } - } -} -``` - -### Client side - -From the client's perspective, in this particular scenario, you want a regexp matching a URL on which you send -a request (`[/0-9]{2}`) and a concrete value returned (`2015-01-14`). That way we will change your stub definition to: - -``` -{ - "request": { - "method": "GET", - "urlPattern": "/[0-9]{2}" - }, - "response": { - "status": 200, - "body": { - "date" : "2015-01-14" - }, - "headers": { - "Content-Type": "text/plain" - } - } -} -``` - -### Server side - -On the server side we need to generate acceptance tests. So we need to check that for given input (request) -we receive some matching output (response). - -In this case we want to send a request to an endpoint `/12` and check if in the body of the response -we will receive the current date (`isCurrentDate(it.date)`). - -The latter value will be checked if it's a method (if it contains parentheses) and then a method will be -called with the corresponding field's (status, body, headers etc.) value as input. - -`VALUE_FOR_SERVER_TESTS` can use `$it` notation to pass body as method argument. The method in the generated Spec can be access also with `$` prefix - if you want to call a method `isPersonalIdValid(String requestBody)` you can do it as follows: - -``` -personaId : "${123456789:$isPersonalIdValid($it)}" -``` - -#### Example of generated specification - -``` -def responseBody = new JsonSlurper().parseText(response.body.asString()) -isPersonalIdValid(responseBody.personaId) - -``` - -### Full example - -Below you can see sample stub and code of the test generated for this definition. - -Stub definition: - -``` -{ - "request": { - "method": "POST", - "url": "/loanApplication", - "headers": { - "Content-Type": {"equalTo": "application/vnd.loanapplicationservice.v1+json"} - }, - "bodyPatterns": [{"matches": "\\{\"clientSsn\":\"1234567890\",\"loanAmount\":123.123\\}"}] - }, - "response": { - "status": 200, - "body": "{\"loanApplicationStatus\":\"LOAN_APPLIED\",\"loanApplicationId\":\"${3245:$greaterThan($it, 1000)}\"}", - "headers": {"Content-Type": "application/vnd.loanapplicationservice.v1+json"} - } -} -``` - -and the code: - -``` -class AcceptanceSpec extends AssurestSpec { - - def shouldApplyForLoan() { - given: - def request = given() - .header('Content-Type', 'application/vnd.loanapplicationservice.v1+json') - .body('{"clientSsn":"1234567890","loanAmount":123.123}') - - when: - def response = given().spec(request) - .post("/loanApplication") - - then: - response.statusCode == 200 - response.header('Content-Type') == 'application/vnd.loanapplicationservice.v1+json' - def responseBody = new JsonSlurper().parseText(response.body.asString()) - greaterThan(responseBody.loanApplicationId, 1000) - responseBody.loanApplicationStatus == "LOAN_APPLIED" - } - -} - -``` - -# Using in your project - -## Add gradle plugin - -``` -buildscript { - repositories { - mavenCentral() - } - dependencies { - classpath 'io.codearte.accurest:accurest-gradle-plugin:0.4.4' - } -} - -apply plugin: 'accurest' - -dependecies { - testCompile 'org.spockframework:spock-core:0.7-groovy-2.0' - testCompile 'com.jayway.restassured:rest-assured:2.4.0' - testCompile 'com.jayway.restassured:spring-mock-mvc:2.4.0' // needed if you're going to use Spring MockMvc -} -``` - -## Add stubs - -By default Accurest is looking for stubs in src/test/resources/stubs directory. -Directory containing stub definitions is treated as a class name, and each stub definition is treated as a single test. -We assume that it contains at least one directory which will be used as test class name. If there is more than one level of nested directories all except the last one will be used as package name. -So with following structure - -src/test/resources/stubs/myservice/shouldCreateUser.json -src/test/resources/stubs/myservice/shouldReturnUser.json - -Accurest will create test class `defaultBasePackage.MyService` with two methods - - shouldCreateUser() - - shouldReturnUser() - -## Run plugin - -Plugin registers itself to be invoked before `compileTestGroovy` task. You have nothing to do as long as you want it to be part of your build process. If you just want to generate tests please invoke `generateAccurest` task. - -## Configure plugin - -To change default configuration just add `accurest` snippet to your Gradle config - -``` -accurest { - testMode = 'MockMvc' - baseClassForTests = 'org.mycompany.tests' - generatedTestSourcesDir = 'src/accurest' -} -``` - -### Configuration options - - - testMode - default 'MockMvc' uses Spring MockMvc to invoke tests. Can be changed to 'Direct' to support HTTP requests - - stubsBaseDirectory - where to look for stub definitions. Default 'src/test/resources/stubs' - - basePackageForTests - base package for test classes. Default 'io.codearte.accurest.tests' - - baseClassForTests - base class which will be extended by all generated tests. By default Accurest is using base framework class (for Spock it's `Specification`) - - ruleClassForTests - you can specify qualified name of rule which should be included in generated test - - generatedTestSourcesDir - target directory for generated tests. By default 'build/generated-sources/accurest' - - imports - array with imports that should be included in generated tests (for example ['org.myorg.Matchers']). By default empty array [] - - staticImports - array with static imports that should be included in generated tests(for example ['org.myorg.Matchers.*']). By default empty array [] +For more information please follow to the [Wiki](https://github.com/Codearte/accurest/wiki/1.-Introduction) diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/ConversionAccurestException.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/ConversionAccurestException.groovy index 050853b02d..d4b35175a8 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/ConversionAccurestException.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/ConversionAccurestException.groovy @@ -1,7 +1,7 @@ package io.codearte.accurest.wiremock import groovy.transform.CompileStatic -import io.coderate.accurest.AccurestException +import io.codearte.accurest.AccurestException @CompileStatic class ConversionAccurestException extends AccurestException { diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockClientConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockClientConverter.groovy index 7b2b3054e7..8156f17cf6 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockClientConverter.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockClientConverter.groovy @@ -1,7 +1,7 @@ package io.codearte.accurest.wiremock import groovy.transform.CompileStatic -import io.coderate.accurest.dsl.WiremockStubStrategy +import io.codearte.accurest.dsl.WiremockStubStrategy @CompileStatic class DslToWiremockClientConverter extends DslToWiremockConverter { diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockConverter.groovy index c44d8b40f1..5804010090 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockConverter.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockConverter.groovy @@ -1,7 +1,7 @@ package io.codearte.accurest.wiremock import groovy.transform.CompileStatic -import io.coderate.accurest.dsl.GroovyDsl +import io.codearte.accurest.dsl.GroovyDsl @CompileStatic abstract class DslToWiremockConverter implements SingleFileConverter { diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy index d6da45bef5..bfc58cc17d 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy @@ -3,6 +3,7 @@ import groovy.io.FileType import groovy.json.JsonOutput import groovy.json.JsonSlurper import groovy.xml.XmlUtil +import io.codearte.accurest.dsl.GroovyDsl import static org.apache.commons.lang3.StringEscapeUtils.escapeJava @@ -139,14 +140,23 @@ class WiremockToDslConverter { if (!it.name.endsWith('json')) { return } - String wiremockStub = fromWiremockStub(it.text) + String dslFromWiremockStub = fromWiremockStub(it.text) + String dslWrappedWithFactoryMethod = wrapWithFactoryMethod(dslFromWiremockStub) File newGroovyFile = new File(it.parent, it.name.replaceAll('json', 'groovy')) println("Creating new groovy file [$newGroovyFile.path]") - newGroovyFile.text = wiremockStub + newGroovyFile.text = dslWrappedWithFactoryMethod } catch (Exception e) { System.err.println(e) } } } + + static String wrapWithFactoryMethod(String dslFromWiremockStub) { + return """\ +${GroovyDsl.name}.make { + $dslFromWiremockStub +} +""" + } } diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockClientConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockClientConverterSpec.groovy index f753cc6bf4..2f20546014 100755 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockClientConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockClientConverterSpec.groovy @@ -10,7 +10,7 @@ class DslToWiremockClientConverterSpec extends Specification { def converter = new DslToWiremockClientConverter() and: String dslBody = """ - io.coderate.accurest.dsl.GroovyDsl.make { + io.codearte.accurest.dsl.GroovyDsl.make { request { method('PUT') url \$(client(~/\\/[0-9]{2}/), server('/12')) @@ -33,7 +33,7 @@ class DslToWiremockClientConverterSpec extends Specification { def converter = new DslToWiremockClientConverter() and: String dslBody = """ - io.coderate.accurest.dsl.GroovyDsl.make { + io.codearte.accurest.dsl.GroovyDsl.make { request { method 'PUT' url '/api/12' @@ -84,9 +84,9 @@ class DslToWiremockClientConverterSpec extends Specification { "request":{ "method":"PUT", "url":"/api/12", - "bodyPatterns": { - "equalTo": "[{\\"created_at\\":\\"Sat Jul 26 09:38:57 +0000 2014\\",\\"id\\":492967299297845248,\\"id_str\\":\\"492967299297845248\\",\\"place\\":{\\"attributes\\":{},\\"bounding_box\\":{\\"coordinates\\":[[[-77.119759,38.791645],[-76.909393,38.791645],[-76.909393,38.995548],[-77.119759,38.995548]]],\\"type\\":\\"Polygon\\"},\\"country\\":\\"United States\\",\\"country_code\\":\\"US\\",\\"full_name\\":\\"Washington, DC\\",\\"id\\":\\"01fbe706f872cb32\\",\\"name\\":\\"Washington\\",\\"place_type\\":\\"city\\",\\"url\\":\\"http://api.twitter.com/1/geo/id/01fbe706f872cb32.json\\"},\\"text\\":\\"Gonna see you at Warsaw\\"}]" - }, + "bodyPatterns": [ + { "equalTo": "[{\\"created_at\\":\\"Sat Jul 26 09:38:57 +0000 2014\\",\\"id\\":492967299297845248,\\"id_str\\":\\"492967299297845248\\",\\"place\\":{\\"attributes\\":{},\\"bounding_box\\":{\\"coordinates\\":[[[-77.119759,38.791645],[-76.909393,38.791645],[-76.909393,38.995548],[-77.119759,38.995548]]],\\"type\\":\\"Polygon\\"},\\"country\\":\\"United States\\",\\"country_code\\":\\"US\\",\\"full_name\\":\\"Washington, DC\\",\\"id\\":\\"01fbe706f872cb32\\",\\"name\\":\\"Washington\\",\\"place_type\\":\\"city\\",\\"url\\":\\"http://api.twitter.com/1/geo/id/01fbe706f872cb32.json\\"},\\"text\\":\\"Gonna see you at Warsaw\\"}]" } + ], "headers": { "Content-Type": { "equalTo": "application/vnd.com.ofg.twitter-places-analyzer.v1+json" diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy old mode 100644 new mode 100755 index 35a5c88caf..7466b2e7f5 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy @@ -1,6 +1,6 @@ package io.codearte.accurest.wiremock -import io.coderate.accurest.dsl.GroovyDsl +import io.codearte.accurest.dsl.GroovyDsl import spock.lang.Specification class WiremockToDslConverterSpec extends Specification { @@ -23,14 +23,7 @@ class WiremockToDslConverterSpec extends Specification { }, "response": { "status": 200, - "body": { - "id": { - "value": "132" - }, - "surname": "Kowalsky", - "name": "Jan", - "created" : "2014-02-02 12:23:43" - }, + "body": "{ \\"id\\": { \\"value\\": \\"132\\" }, \\"surname\\": \\"Kowalsky\\", \\"name\\": \\"Jan\\", \\"created\\": \\"2014-02-02 12:23:43\\" }", "headers": { "Content-Type": "text/plain", } @@ -72,7 +65,7 @@ class WiremockToDslConverterSpec extends Specification { String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) then: new GroovyShell(this.class.classLoader).evaluate( - """ io.coderate.accurest.dsl.GroovyDsl.make { + """ io.codearte.accurest.dsl.GroovyDsl.make { $groovyDsl }""") == expectedGroovyDsl } @@ -124,7 +117,7 @@ class WiremockToDslConverterSpec extends Specification { String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) then: new GroovyShell(this.class.classLoader).evaluate( - """ io.coderate.accurest.dsl.GroovyDsl.make { + """ io.codearte.accurest.dsl.GroovyDsl.make { $groovyDsl }""") == expectedGroovyDsl } @@ -173,7 +166,7 @@ class WiremockToDslConverterSpec extends Specification { String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) then: new GroovyShell(this.class.classLoader).evaluate( - """ io.coderate.accurest.dsl.GroovyDsl.make { + """ io.codearte.accurest.dsl.GroovyDsl.make { $groovyDsl }""") == expectedGroovyDsl } @@ -193,11 +186,7 @@ class WiremockToDslConverterSpec extends Specification { }, "response": { "status": 200, - "body": [ - {"a":1, "c":"3"}, - "b", - "a" - ], + "body": "[ {\\"a\\":1, \\"c\\":\\"3\\"}, \\"b\\", \\"a\\" ]", "headers": { "Content-Type": "application/json" } @@ -229,7 +218,7 @@ class WiremockToDslConverterSpec extends Specification { String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) then: new GroovyShell(this.class.classLoader).evaluate( - """ io.coderate.accurest.dsl.GroovyDsl.make { + """ io.codearte.accurest.dsl.GroovyDsl.make { $groovyDsl }""") == expectedGroovyDsl } @@ -293,7 +282,7 @@ class WiremockToDslConverterSpec extends Specification { String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) then: new GroovyShell(this.class.classLoader).evaluate( - """ io.coderate.accurest.dsl.GroovyDsl.make { + """ io.codearte.accurest.dsl.GroovyDsl.make { $groovyDsl }""") == expectedGroovyDsl } diff --git a/accurest-converters/src/test/resources/converter/source/dir1/dsl1.groovy b/accurest-converters/src/test/resources/converter/source/dir1/dsl1.groovy index be45f92092..d72463cde2 100644 --- a/accurest-converters/src/test/resources/converter/source/dir1/dsl1.groovy +++ b/accurest-converters/src/test/resources/converter/source/dir1/dsl1.groovy @@ -1,4 +1,4 @@ -io.coderate.accurest.dsl.GroovyDsl.make { +io.codearte.accurest.dsl.GroovyDsl.make { request { method('PUT') headers { diff --git a/accurest-converters/src/test/resources/converter/source/dir1/dsl1b.groovy b/accurest-converters/src/test/resources/converter/source/dir1/dsl1b.groovy index be45f92092..d72463cde2 100644 --- a/accurest-converters/src/test/resources/converter/source/dir1/dsl1b.groovy +++ b/accurest-converters/src/test/resources/converter/source/dir1/dsl1b.groovy @@ -1,4 +1,4 @@ -io.coderate.accurest.dsl.GroovyDsl.make { +io.codearte.accurest.dsl.GroovyDsl.make { request { method('PUT') headers { diff --git a/accurest-converters/src/test/resources/converter/source/dir2/dsl2.groovy b/accurest-converters/src/test/resources/converter/source/dir2/dsl2.groovy index be45f92092..d72463cde2 100644 --- a/accurest-converters/src/test/resources/converter/source/dir2/dsl2.groovy +++ b/accurest-converters/src/test/resources/converter/source/dir2/dsl2.groovy @@ -1,4 +1,4 @@ -io.coderate.accurest.dsl.GroovyDsl.make { +io.codearte.accurest.dsl.GroovyDsl.make { request { method('PUT') headers { diff --git a/accurest-converters/src/test/resources/converter/source/dslRoot.groovy b/accurest-converters/src/test/resources/converter/source/dslRoot.groovy index be45f92092..d72463cde2 100644 --- a/accurest-converters/src/test/resources/converter/source/dslRoot.groovy +++ b/accurest-converters/src/test/resources/converter/source/dslRoot.groovy @@ -1,4 +1,4 @@ -io.coderate.accurest.dsl.GroovyDsl.make { +io.codearte.accurest.dsl.GroovyDsl.make { request { method('PUT') headers { diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/AccurestException.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/AccurestException.groovy similarity index 88% rename from accurest-core/src/main/groovy/io/coderate/accurest/AccurestException.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/AccurestException.groovy index 740e13e620..b9fac01145 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/AccurestException.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/AccurestException.groovy @@ -1,4 +1,4 @@ -package io.coderate.accurest +package io.codearte.accurest /** * @author Jakub Kubrynski diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/FileSaver.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/FileSaver.groovy similarity index 83% rename from accurest-core/src/main/groovy/io/coderate/accurest/FileSaver.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/FileSaver.groovy index 2d20399d8a..a77aca416f 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/FileSaver.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/FileSaver.groovy @@ -1,16 +1,16 @@ -package io.coderate.accurest +package io.codearte.accurest import groovy.transform.CompileStatic import groovy.util.logging.Slf4j -import io.coderate.accurest.config.TestFramework -import io.coderate.accurest.util.NamesUtil +import io.codearte.accurest.config.TestFramework +import io.codearte.accurest.util.NamesUtil import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths import java.nio.file.StandardOpenOption -import static io.coderate.accurest.util.NamesUtil.capitalize +import static io.codearte.accurest.util.NamesUtil.capitalize @CompileStatic @Slf4j diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/SingleTestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy similarity index 75% rename from accurest-core/src/main/groovy/io/coderate/accurest/SingleTestGenerator.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy index 80f7276a68..bc6f35adde 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/SingleTestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy @@ -1,14 +1,14 @@ -package io.coderate.accurest +package io.codearte.accurest import groovy.transform.PackageScope -import io.coderate.accurest.builder.ClassBuilder -import io.coderate.accurest.config.AccurestConfigProperties -import io.coderate.accurest.config.TestFramework -import io.coderate.accurest.config.TestMode +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 static io.coderate.accurest.builder.ClassBuilder.createClass -import static io.coderate.accurest.builder.MethodBuilder.createTestMethod -import static io.coderate.accurest.util.NamesUtil.capitalize +import static io.codearte.accurest.builder.ClassBuilder.createClass +import static io.codearte.accurest.builder.MethodBuilder.createTestMethod +import static io.codearte.accurest.util.NamesUtil.capitalize class SingleTestGenerator { private final AccurestConfigProperties configProperties diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy similarity index 94% rename from accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy index 45ba0ff497..fb612cebd1 100755 --- a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy @@ -1,12 +1,12 @@ -package io.coderate.accurest +package io.codearte.accurest import groovy.transform.PackageScope -import io.coderate.accurest.config.AccurestConfigProperties +import io.codearte.accurest.config.AccurestConfigProperties import org.apache.commons.io.FilenameUtils import org.codehaus.plexus.util.DirectoryScanner import java.util.concurrent.atomic.AtomicInteger -import static io.coderate.accurest.util.NamesUtil.afterLast +import static io.codearte.accurest.util.NamesUtil.afterLast /** * @author Jakub Kubrynski */ diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/builder/BlockBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/BlockBuilder.groovy similarity index 96% rename from accurest-core/src/main/groovy/io/coderate/accurest/builder/BlockBuilder.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/builder/BlockBuilder.groovy index 31e8a05aac..62d97fdda7 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/builder/BlockBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/BlockBuilder.groovy @@ -1,4 +1,4 @@ -package io.coderate.accurest.builder +package io.codearte.accurest.builder import groovy.transform.PackageScope diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/ClassBuilder.groovy similarity index 92% rename from accurest-core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/builder/ClassBuilder.groovy index 912740b83f..29f4fc2c14 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/ClassBuilder.groovy @@ -1,8 +1,8 @@ -package io.coderate.accurest.builder +package io.codearte.accurest.builder -import io.coderate.accurest.config.AccurestConfigProperties -import io.coderate.accurest.config.TestFramework -import io.coderate.accurest.util.NamesUtil +import io.codearte.accurest.config.AccurestConfigProperties +import io.codearte.accurest.config.TestFramework +import io.codearte.accurest.util.NamesUtil /** * @author Jakub Kubrynski diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/builder/JUnitMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy similarity index 90% rename from accurest-core/src/main/groovy/io/coderate/accurest/builder/JUnitMethodBodyBuilder.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy index b81628533b..0f31ff8eb8 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/builder/JUnitMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy @@ -1,4 +1,4 @@ -package io.coderate.accurest.builder +package io.codearte.accurest.builder /** * @author Jakub Kubrynski diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy similarity index 86% rename from accurest-core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy index 1695856b27..dd791fb666 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy @@ -1,9 +1,9 @@ -package io.coderate.accurest.builder +package io.codearte.accurest.builder import groovy.util.logging.Slf4j -import io.coderate.accurest.config.TestFramework -import io.coderate.accurest.dsl.GroovyDsl -import io.coderate.accurest.util.NamesUtil +import io.codearte.accurest.config.TestFramework +import io.codearte.accurest.dsl.GroovyDsl +import io.codearte.accurest.util.NamesUtil /** * @author Jakub Kubrynski diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy similarity index 70% rename from accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index fc7abc910f..25ebd02b99 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -1,8 +1,9 @@ -package io.coderate.accurest.builder +package io.codearte.accurest.builder + import groovy.json.JsonOutput import groovy.transform.PackageScope -import io.coderate.accurest.dsl.GroovyDsl -import io.coderate.accurest.dsl.internal.Header +import io.codearte.accurest.dsl.GroovyDsl +import io.codearte.accurest.dsl.internal.Header /** * @author Jakub Kubrynski @@ -46,8 +47,11 @@ class SpockMethodBodyBuilder { blockBuilder.endBlock() blockBuilder.addLine('and:').startBlock() blockBuilder.addLine('def responseBody = new JsonSlurper().parseText(response.body.asString())') - stubDefinition.response.body.serverValue.each { - processBodyElement(blockBuilder, "", it) + def responseBody = stubDefinition.response.body.serverValue + if (responseBody instanceof List) { + processArrayElements(responseBody, "", blockBuilder) + } else { + processMapElement(responseBody, blockBuilder, "") } } blockBuilder.endBlock() @@ -66,9 +70,24 @@ class SpockMethodBodyBuilder { blockBuilder.addLine("responseBody$property == \"${value}\"") } } else if (value instanceof Map) { - value.each { entry -> processBodyElement(blockBuilder, property, entry) } + processMapElement(value, blockBuilder, property) + } else if (value instanceof List) { + processArrayElements(value, property, blockBuilder) } else { blockBuilder.addLine("responseBody$property == ${value}") } } + + private void processMapElement(def value, BlockBuilder blockBuilder, String property) { + value.each { entry -> processBodyElement(blockBuilder, property, entry) } + } + + private void processArrayElements(List responseBody, String property, BlockBuilder blockBuilder) { + responseBody.eachWithIndex { + listElement, listIndex -> + listElement.each { + entry -> processBodyElement(blockBuilder, property + "[$listIndex]", entry) + } + } + } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy similarity index 95% rename from accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy index ec95b667b1..965f3bf84a 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy @@ -1,4 +1,4 @@ -package io.coderate.accurest.config +package io.codearte.accurest.config /** * @author Jakub Kubrynski */ diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/config/TestFramework.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/config/TestFramework.groovy similarity index 96% rename from accurest-core/src/main/groovy/io/coderate/accurest/config/TestFramework.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/config/TestFramework.groovy index af5af4a47c..79758327f3 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/config/TestFramework.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/config/TestFramework.groovy @@ -1,4 +1,4 @@ -package io.coderate.accurest.config +package io.codearte.accurest.config /** * @author Jakub Kubrynski diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/config/TestMode.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/config/TestMode.groovy similarity index 66% rename from accurest-core/src/main/groovy/io/coderate/accurest/config/TestMode.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/config/TestMode.groovy index f5a7b86389..e8a232e37c 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/config/TestMode.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/config/TestMode.groovy @@ -1,4 +1,4 @@ -package io.coderate.accurest.config +package io.codearte.accurest.config /** * @author Jakub Kubrynski diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWiremockStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWiremockStubStrategy.groovy new file mode 100755 index 0000000000..77866f1437 --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWiremockStubStrategy.groovy @@ -0,0 +1,67 @@ +package io.codearte.accurest.dsl +import groovy.json.JsonOutput +import groovy.json.JsonSlurper +import groovy.transform.TypeChecked +import groovy.xml.XmlUtil +import io.codearte.accurest.dsl.internal.Header +import io.codearte.accurest.dsl.internal.Headers + +import java.util.regex.Pattern + +import static groovy.json.StringEscapeUtils.escapeJava + +@TypeChecked +abstract class BaseWiremockStubStrategy { + protected Map buildClientRequestHeadersSection(Headers headers) { + if (!headers) { + return null + } + return headers.entries.collectEntries { Header entry -> + parseHeader(entry.name, entry.clientValue) + } + } + + protected Map buildClientResponseHeadersSection(Headers headers) { + if (!headers) { + return null + } + return headers.entries.collectEntries { Header entry -> + [(entry.name) : entry.clientValue] + } + } + + protected Map parseHeader(String entryKey, Object entry) { + return [(entryKey): [equalTo : entry]] + } + + protected Map parseHeader(String entryKey, String entry) { + return [(entryKey): [equalTo : entry]] + } + + protected Map parseHeader(String entryKey, Pattern entry) { + return [(entryKey): [matches : entry.pattern()]] + } + + protected String parseBody(Object body) { + String bodyAsString = body as String + try { + def json = new JsonSlurper().parseText(bodyAsString) + return escapeJava(JsonOutput.toJson(bodyAsString)) + } catch (Exception jsonException) { + try { + def xml = new XmlSlurper().parseText(bodyAsString) + return escapeJava(XmlUtil.serialize(bodyAsString)) + } catch (Exception xmlException) { + return escapeJava(bodyAsString) + } + } + } + + protected String parseBody(List body) { + return JsonOutput.toJson(body) + } + + protected String parseBody(Map body) { + return JsonOutput.toJson(body) + } +} diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/GroovyDsl.groovy similarity index 84% rename from accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/dsl/GroovyDsl.groovy index 6b2e9bbbc6..717047341d 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/GroovyDsl.groovy @@ -1,10 +1,10 @@ -package io.coderate.accurest.dsl +package io.codearte.accurest.dsl import groovy.transform.EqualsAndHashCode import groovy.transform.ToString import groovy.transform.TypeChecked -import io.coderate.accurest.dsl.internal.Request -import io.coderate.accurest.dsl.internal.Response +import io.codearte.accurest.dsl.internal.Request +import io.codearte.accurest.dsl.internal.Response @TypeChecked @EqualsAndHashCode(includeFields = true) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy similarity index 62% rename from accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy index 6d20d5d7f1..c0dfe0c43c 100755 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -1,11 +1,9 @@ -package io.coderate.accurest.dsl -import groovy.json.JsonOutput -import groovy.json.JsonSlurper +package io.codearte.accurest.dsl + import groovy.transform.PackageScope import groovy.transform.TypeChecked -import groovy.xml.XmlUtil -import io.coderate.accurest.dsl.internal.ClientRequest -import io.coderate.accurest.dsl.internal.Request +import io.codearte.accurest.dsl.internal.ClientRequest +import io.codearte.accurest.dsl.internal.Request import java.util.regex.Pattern @@ -54,27 +52,4 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { return (bodyString =~ /\^.*\$/).find() } - private String parseBody(Object bodyObject) { - String responseBody = bodyObject as String - try { - def json = new JsonSlurper().parseText(responseBody) - return escapeJava(JsonOutput.toJson(responseBody)) - } catch (Exception jsonException) { - try { - def xml = new XmlSlurper().parseText(responseBody) - return escapeJava(XmlUtil.serialize(responseBody)) - } catch (Exception xmlException) { - return escapeJava(responseBody) - } - } - } - - private String parseBody(List responseBody) { - return JsonOutput.toJson(responseBody) - } - - private String parseBody(Map responseBody) { - return JsonOutput.toJson(responseBody) - } - } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockResponseStubStrategy.groovy old mode 100644 new mode 100755 similarity index 51% rename from accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockResponseStubStrategy.groovy index a1d9f2eb68..e0b7556547 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockResponseStubStrategy.groovy @@ -1,10 +1,10 @@ -package io.coderate.accurest.dsl -import groovy.transform.CompileStatic +package io.codearte.accurest.dsl import groovy.transform.PackageScope -import io.coderate.accurest.dsl.internal.ClientResponse -import io.coderate.accurest.dsl.internal.Response +import groovy.transform.TypeChecked +import io.codearte.accurest.dsl.internal.ClientResponse +import io.codearte.accurest.dsl.internal.Response -@CompileStatic +@TypeChecked @PackageScope class WiremockResponseStubStrategy extends BaseWiremockStubStrategy { @@ -20,8 +20,13 @@ class WiremockResponseStubStrategy extends BaseWiremockStubStrategy { } private Map buildResponseContent(ClientResponse response) { - return [status : response?.status?.clientValue, - body : response?.body?.clientValue, - headers: buildClientResponseHeadersSection(response.headers)].findAll { it.value } + return ([status : response?.status?.clientValue, + headers: buildClientResponseHeadersSection(response.headers) + ] << appendBody(response)).findAll { it.value } } + + private Map appendBody(ClientResponse response) { + Object body = response?.body?.clientValue + return body != null ? [body: parseBody(body)] : [:] + } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockStubStrategy.groovy similarity index 95% rename from accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockStubStrategy.groovy index b6f1bcdf4b..a4bf3ee9c4 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockStubStrategy.groovy @@ -1,4 +1,4 @@ -package io.coderate.accurest.dsl +package io.codearte.accurest.dsl import groovy.json.JsonOutput import groovy.transform.CompileStatic diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy similarity index 97% rename from accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy index e5ec6a36f2..5e8d46ed98 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy @@ -1,4 +1,4 @@ -package io.coderate.accurest.dsl.internal +package io.codearte.accurest.dsl.internal import groovy.json.JsonSlurper import groovy.transform.EqualsAndHashCode diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ClientDslProperty.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/ClientDslProperty.groovy similarity index 80% rename from accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ClientDslProperty.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/ClientDslProperty.groovy index 7b8525a078..007550b890 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ClientDslProperty.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/ClientDslProperty.groovy @@ -1,4 +1,4 @@ -package io.coderate.accurest.dsl.internal +package io.codearte.accurest.dsl.internal import groovy.transform.CompileStatic diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy similarity index 97% rename from accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy index 934f98c2f5..f6eb65ab9e 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy @@ -1,4 +1,4 @@ -package io.coderate.accurest.dsl.internal +package io.codearte.accurest.dsl.internal import groovy.transform.PackageScope import groovy.transform.TypeChecked diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DslProperty.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/DslProperty.groovy similarity index 92% rename from accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DslProperty.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/DslProperty.groovy index 6887ffc88c..f9da9227e5 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DslProperty.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/DslProperty.groovy @@ -1,4 +1,4 @@ -package io.coderate.accurest.dsl.internal +package io.codearte.accurest.dsl.internal import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Header.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Header.groovy similarity index 93% rename from accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Header.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Header.groovy index 90de0873f8..a7eefa180a 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Header.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Header.groovy @@ -1,4 +1,4 @@ -package io.coderate.accurest.dsl.internal +package io.codearte.accurest.dsl.internal import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode import groovy.transform.ToString diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Headers.groovy similarity index 94% rename from accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Headers.groovy index be6f90c66f..d9c1bc85b7 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Headers.groovy @@ -1,4 +1,4 @@ -package io.coderate.accurest.dsl.internal +package io.codearte.accurest.dsl.internal import groovy.transform.EqualsAndHashCode import groovy.transform.ToString diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/JSONCompareMode.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/JSONCompareMode.groovy similarity index 63% rename from accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/JSONCompareMode.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/JSONCompareMode.groovy index d4e7e3e15f..8929aa9bdc 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/JSONCompareMode.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/JSONCompareMode.groovy @@ -1,4 +1,4 @@ -package io.coderate.accurest.dsl.internal +package io.codearte.accurest.dsl.internal enum JSONCompareMode { STRICT, LENIENT, NON_EXTENSIBLE, STRICT_ORDER diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy similarity index 97% rename from accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy index fc1a4a58d9..77652a9396 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy @@ -1,4 +1,4 @@ -package io.coderate.accurest.dsl.internal +package io.codearte.accurest.dsl.internal import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode import groovy.transform.ToString diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Response.groovy similarity index 97% rename from accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Response.groovy index bb9a224de8..ce8a7b3b7d 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Response.groovy @@ -1,4 +1,4 @@ -package io.coderate.accurest.dsl.internal +package io.codearte.accurest.dsl.internal import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ServerDslProperty.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/ServerDslProperty.groovy similarity index 88% rename from accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ServerDslProperty.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/ServerDslProperty.groovy index 3045736f1b..659fba901e 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ServerDslProperty.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/ServerDslProperty.groovy @@ -1,4 +1,4 @@ -package io.coderate.accurest.dsl.internal +package io.codearte.accurest.dsl.internal import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Url.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Url.groovy similarity index 89% rename from accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Url.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Url.groovy index a5c49944e3..da91b4a248 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Url.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Url.groovy @@ -1,4 +1,4 @@ -package io.coderate.accurest.dsl.internal +package io.codearte.accurest.dsl.internal import groovy.transform.EqualsAndHashCode import groovy.transform.ToString diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/util/NamesUtil.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy similarity index 96% rename from accurest-core/src/main/groovy/io/coderate/accurest/util/NamesUtil.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy index f40034e002..4817cc4816 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/util/NamesUtil.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy @@ -1,4 +1,4 @@ -package io.coderate.accurest.util +package io.codearte.accurest.util /** * @author Jakub Kubrynski diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/util/StubMappingConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/StubMappingConverter.groovy similarity index 97% rename from accurest-core/src/main/groovy/io/coderate/accurest/util/StubMappingConverter.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/util/StubMappingConverter.groovy index 439224eccd..f1ce59959f 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/util/StubMappingConverter.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/StubMappingConverter.groovy @@ -1,4 +1,4 @@ -package io.coderate.accurest.util +package io.codearte.accurest.util import groovy.json.JsonException import groovy.json.JsonSlurper diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy deleted file mode 100644 index 5e89c3d3bc..0000000000 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy +++ /dev/null @@ -1,41 +0,0 @@ -package io.coderate.accurest.dsl - -import groovy.transform.TypeChecked -import io.coderate.accurest.dsl.internal.Header -import io.coderate.accurest.dsl.internal.Headers - -import java.util.regex.Pattern - -@TypeChecked -abstract class BaseWiremockStubStrategy { - protected Map buildClientRequestHeadersSection(Headers headers) { - if (!headers) { - return null - } - return headers.entries.collectEntries { Header entry -> - parseHeader(entry.name, entry.clientValue) - } - } - - protected Map buildClientResponseHeadersSection(Headers headers) { - if (!headers) { - return null - } - return headers.entries.collectEntries { Header entry -> - [(entry.name) : entry.clientValue] - } - } - - protected Map parseHeader(String entryKey, Object entry) { - return [(entryKey): [equalTo : entry]] - } - - protected Map parseHeader(String entryKey, String entry) { - return [(entryKey): [equalTo : entry]] - } - - protected Map parseHeader(String entryKey, Pattern entry) { - return [(entryKey): [matches : entry.pattern()]] - } - -} diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy similarity index 88% rename from accurest-core/src/test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy rename to accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy index 84eb77ab58..6a478e3d92 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy @@ -1,12 +1,9 @@ package io.codearte.accurest -import io.coderate.accurest.FileSaver -import io.coderate.accurest.SingleTestGenerator -import io.coderate.accurest.TestGenerator -import io.coderate.accurest.config.AccurestConfigProperties +import io.codearte.accurest.config.AccurestConfigProperties import spock.lang.Specification -class TestGeneratorSpec extends Specification { +class GeneratorScannerSpec extends Specification { private SingleTestGenerator classGenerator = Mock(SingleTestGenerator) diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/MainTest.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/MainTest.groovy index 4f16ddde86..4bdc8e9cc8 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/MainTest.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/MainTest.groovy @@ -1,9 +1,8 @@ package io.codearte.accurest -import io.coderate.accurest.TestGenerator -import io.coderate.accurest.config.AccurestConfigProperties -import io.coderate.accurest.config.TestFramework -import io.coderate.accurest.config.TestMode +import io.codearte.accurest.config.AccurestConfigProperties +import io.codearte.accurest.config.TestFramework +import io.codearte.accurest.config.TestMode class MainTest { public static void main(String[] args) { diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy new file mode 100644 index 0000000000..c68a96a1e6 --- /dev/null +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy @@ -0,0 +1,113 @@ +package io.codearte.accurest.builder + +import io.codearte.accurest.dsl.GroovyDsl +import spock.lang.Specification + +/** + * @author Jakub Kubrynski + */ +class SpockMethodBuilderSpec extends Specification { + + def "should generate assertions for simple response body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body """{ + "property1": "a", + "property2": "b" +}""" + } + } + SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("responseBody.property1 == \"a\"") + blockBuilder.toString().contains("responseBody.property2 == \"b\"") + } + + def "should generate assertions for array in response body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body """[ +{ + "property1": "a" +}, +{ + "property2": "b" +}]""" + } + } + SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("responseBody[0].property1 == \"a\"") + blockBuilder.toString().contains("responseBody[1].property2 == \"b\"") + } + + def "should generate assertions for array inside response body element"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body """{ + "property1": [ + { "property2": "test1"}, + { "property3": "test2"} + ] +}""" + } + } + SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("responseBody.property1[0].property2 == \"test1\"") + blockBuilder.toString().contains("responseBody.property1[1].property3 == \"test2\"") + } + + def "should generate assertions for nested objects in response body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body '''\ +{ + "property1": "a", + "property2": {"property3": "b"} +} +''' + } + } + SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("responseBody.property1 == \"a\"") + blockBuilder.toString().contains("responseBody.property2.property3 == \"b\"") + } +} diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslResponseSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslResponseSpec.groovy index ae33f3ccdc..13299ceebe 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslResponseSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslResponseSpec.groovy @@ -1,8 +1,6 @@ package io.codearte.accurest.dsl import groovy.json.JsonSlurper -import io.coderate.accurest.dsl.GroovyDsl -import io.coderate.accurest.dsl.WiremockResponseStubStrategy import spock.lang.Specification class WiremockGroovyDslResponseSpec extends Specification { diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy index 7112e6c6e1..5f1684ec7d 100755 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy @@ -1,8 +1,5 @@ package io.codearte.accurest.dsl import groovy.json.JsonSlurper -import io.coderate.accurest.dsl.GroovyDsl -import io.coderate.accurest.dsl.WiremockRequestStubStrategy -import io.coderate.accurest.dsl.WiremockStubStrategy import spock.lang.Specification class WiremockGroovyDslSpec extends Specification { @@ -44,12 +41,7 @@ class WiremockGroovyDslSpec extends Specification { }, "response": { "status": 200, - "body": { - "id": "123", - "surname": "Kowalsky", - "name": "Jan", - "created" : "2014-02-02 12:23:43" - }, + "body": "{\\"id\\":\\"123\\",\\"surname\\":\\"Kowalsky\\",\\"name\\":\\"Jan\\",\\"created\\":\\"2014-02-02 12:23:43\\"}", "headers": { "Content-Type": "text/plain" } @@ -92,12 +84,7 @@ class WiremockGroovyDslSpec extends Specification { }, "response": { "status": 200, - "body": { - "id": "123", - "surname": "Kowalsky", - "name": "Jan", - "created" : "2014-02-02 12:23:43" - }, + "body": "{\\"created\\":\\"2014-02-02 12:23:43\\",\\"id\\":\\"123\\",\\"name\\":\\"Jan\\",\\"surname\\":\\"Kowalsky\\"}", "headers": { "Content-Type": "text/plain" } @@ -139,15 +126,15 @@ class WiremockGroovyDslSpec extends Specification { "request": { "method": "GET", "urlPattern": "/[0-9]{2}", - "bodyPatterns": { - "equalTo":"{\\"name\\":\\"Jan\\"}" - } + "bodyPatterns": [ + { + "equalTo":"{\\"name\\":\\"Jan\\"}" + } + ] }, "response": { "status": 200, - "body": { - "name": "Jan" - }, + "body": "{\\"name\\":\\"Jan\\"}", "headers": { "Content-Type": "text/plain" } diff --git a/accurest-core/src/test/resources/dsl/basic/sampleDsl.groovy b/accurest-core/src/test/resources/dsl/basic/sampleDsl.groovy index 7200a71dae..95d19e6b87 100644 --- a/accurest-core/src/test/resources/dsl/basic/sampleDsl.groovy +++ b/accurest-core/src/test/resources/dsl/basic/sampleDsl.groovy @@ -1,4 +1,4 @@ -io.coderate.accurest.dsl.GroovyDsl.make { +io.codearte.accurest.dsl.GroovyDsl.make { request { method('PUT') headers { diff --git a/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestGradlePlugin.groovy b/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestGradlePlugin.groovy index 1e90009be0..cee3f48357 100644 --- a/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestGradlePlugin.groovy +++ b/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestGradlePlugin.groovy @@ -1,6 +1,6 @@ package io.codearte.accurest.plugin -import io.coderate.accurest.config.AccurestConfigProperties +import io.codearte.accurest.config.AccurestConfigProperties import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.Task diff --git a/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateServerTestsTask.groovy b/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateServerTestsTask.groovy index 9cf7c64a2e..d6fe06a9fd 100644 --- a/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateServerTestsTask.groovy +++ b/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateServerTestsTask.groovy @@ -1,8 +1,8 @@ package io.codearte.accurest.plugin -import io.coderate.accurest.AccurestException -import io.coderate.accurest.TestGenerator -import io.coderate.accurest.config.AccurestConfigProperties +import io.codearte.accurest.AccurestException +import io.codearte.accurest.TestGenerator +import io.codearte.accurest.config.AccurestConfigProperties import org.gradle.api.GradleException import org.gradle.api.internal.ConventionTask import org.gradle.api.tasks.InputDirectory diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/BasicFunctionalSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/BasicFunctionalSpec.groovy index d1b3d976bd..e2ee36959d 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/BasicFunctionalSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/BasicFunctionalSpec.groovy @@ -51,9 +51,9 @@ class BasicFunctionalSpec extends IntegrationSpec { } }, "url": "/api/12", - "bodyPatterns": { - "equalTo": "[{\\"text\\":\\"Gonna see you at Warsaw\\"}]" - } + "bodyPatterns": [ + { "equalTo": "[{\\"text\\":\\"Gonna see you at Warsaw\\"}]" } + ] }, "response": { "status": 200 diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/colleratePlacesFromTweet.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/colleratePlacesFromTweet.groovy index 767b51797e..08b137a054 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/colleratePlacesFromTweet.groovy +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/colleratePlacesFromTweet.groovy @@ -1,4 +1,4 @@ -io.coderate.accurest.dsl.GroovyDsl.make { +io.codearte.accurest.dsl.GroovyDsl.make { request { method 'PUT' url '/api/12'